From d9e27bfaf1a13f92220362edb7fe2f896e08aac9 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 29 Jul 2021 13:53:50 +0530 Subject: [PATCH 0001/1531] Temporarily fixes CORS header issue while logging in --- src/client/action/auth.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/client/action/auth.js b/src/client/action/auth.js index 170fb4b72..0403ec9f4 100644 --- a/src/client/action/auth.js +++ b/src/client/action/auth.js @@ -3,7 +3,12 @@ import cons from '../state/cons'; import { getBaseUrl } from '../../util/matrixUtil'; async function login(username, homeserver, password) { - const baseUrl = await getBaseUrl(homeserver); + let baseUrl = null; + try { + baseUrl = await getBaseUrl(homeserver); + } catch (e) { + baseUrl = `https://${homeserver}`; + } if (typeof baseUrl === 'undefined') throw new Error('Homeserver not found'); From c29515db388936a6267af56613605fdf7a891390 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 29 Jul 2021 13:58:15 +0530 Subject: [PATCH 0002/1531] Increased pass length to 127 char --- src/app/templates/auth/Auth.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/templates/auth/Auth.jsx b/src/app/templates/auth/Auth.jsx index d66617b81..6392fb31f 100644 --- a/src/app/templates/auth/Auth.jsx +++ b/src/app/templates/auth/Auth.jsx @@ -21,8 +21,8 @@ const BAD_LOCALPART_ERROR = 'Username must contain only a-z, 0-9, ., _, =, -, an const USER_ID_TOO_LONG_ERROR = 'Your user ID, including the hostname, can\'t be more than 255 characters long.'; const PASSWORD_REGEX = /.+/; -const PASSWORD_STRENGHT_REGEX = /^(?=.*\d)(?=.*[A-Z])(?=.*[a-z])(?=.*[^\w\d\s:])([^\s]){8,16}$/; -const BAD_PASSWORD_ERROR = 'Password must contain 1 number, 1 uppercase letters, 1 lowercase letters, 1 non-alpha numeric number, 8-16 characters with no space.'; +const PASSWORD_STRENGHT_REGEX = /^(?=.*\d)(?=.*[A-Z])(?=.*[a-z])(?=.*[^\w\d\s:])([^\s]){8,127}$/; +const BAD_PASSWORD_ERROR = 'Password must contain 1 number, 1 uppercase letters, 1 lowercase letters, 1 non-alpha numeric number, 8-127 characters with no space.'; const CONFIRM_PASSWORD_ERROR = 'Password don\'t match.'; const EMAIL_REGEX = /([a-z0-9]+[_a-z0-9.-][a-z0-9]+)@([a-z0-9-]+(?:.[a-z0-9-]+).[a-z]{2,4})/; From 8cf030585f8de9def779af47bbd127455e453799 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 29 Jul 2021 15:31:35 +0530 Subject: [PATCH 0003/1531] Fixed homeserver delegation issue --- src/client/action/auth.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/client/action/auth.js b/src/client/action/auth.js index 0403ec9f4..e7b7c635e 100644 --- a/src/client/action/auth.js +++ b/src/client/action/auth.js @@ -23,7 +23,7 @@ async function login(username, homeserver, password) { localStorage.setItem(cons.secretKey.ACCESS_TOKEN, response.access_token); localStorage.setItem(cons.secretKey.DEVICE_ID, response.device_id); localStorage.setItem(cons.secretKey.USER_ID, response.user_id); - localStorage.setItem(cons.secretKey.BASE_URL, response.well_known['m.homeserver'].base_url); + localStorage.setItem(cons.secretKey.BASE_URL, response?.well_known?.['m.homeserver']?.base_url || baseUrl); } async function getAdditionalInfo(baseUrl, content) { @@ -90,7 +90,6 @@ async function register(username, homeserver, password, email, recaptchaValue, t } else if (verified !== true) { session = null; clientSecret = client.generateClientSecret(); - console.log(clientSecret); const verifyData = await verifyEmail(baseUrl, { email, client_secret: clientSecret, From d08d727917cf3aba977a233c263f1580375bd217 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 31 Jul 2021 08:21:57 +0530 Subject: [PATCH 0004/1531] added authorship --- package.json | 2 +- public/index.html | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 286ed4722..bda13d942 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "build": "webpack --config ./webpack.prod.js" }, "keywords": [], - "author": "", + "author": "Ajay Bura", "license": "ISC", "dependencies": { "@tippyjs/react": "^4.2.5", diff --git a/public/index.html b/public/index.html index 280e6dc9a..67a6a6a1e 100644 --- a/public/index.html +++ b/public/index.html @@ -7,6 +7,7 @@ Cinny + From 2218f9781be4d1ffcfc3fb815332550e6e3b6080 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 31 Jul 2021 08:24:07 +0530 Subject: [PATCH 0005/1531] Removed dist from gitignore --- .gitignore | 1 - ...-user.d87fd7bdbcd69110487cade29b6cdab6.svg | 12 ++ dist/assets/android-chrome-144x144.png | Bin 0 -> 4499 bytes dist/assets/android-chrome-192x192.png | Bin 0 -> 6264 bytes dist/assets/android-chrome-256x256.png | Bin 0 -> 8384 bytes dist/assets/android-chrome-36x36.png | Bin 0 -> 1073 bytes dist/assets/android-chrome-384x384.png | Bin 0 -> 13069 bytes dist/assets/android-chrome-48x48.png | Bin 0 -> 1487 bytes dist/assets/android-chrome-512x512.png | Bin 0 -> 17829 bytes dist/assets/android-chrome-72x72.png | Bin 0 -> 2216 bytes dist/assets/android-chrome-96x96.png | Bin 0 -> 2991 bytes dist/assets/apple-touch-icon-1024x1024.png | Bin 0 -> 51825 bytes dist/assets/apple-touch-icon-114x114.png | Bin 0 -> 4902 bytes dist/assets/apple-touch-icon-120x120.png | Bin 0 -> 5100 bytes dist/assets/apple-touch-icon-144x144.png | Bin 0 -> 6075 bytes dist/assets/apple-touch-icon-152x152.png | Bin 0 -> 6665 bytes dist/assets/apple-touch-icon-167x167.png | Bin 0 -> 7325 bytes dist/assets/apple-touch-icon-180x180.png | Bin 0 -> 7889 bytes dist/assets/apple-touch-icon-57x57.png | Bin 0 -> 2347 bytes dist/assets/apple-touch-icon-60x60.png | Bin 0 -> 2482 bytes dist/assets/apple-touch-icon-72x72.png | Bin 0 -> 2951 bytes dist/assets/apple-touch-icon-76x76.png | Bin 0 -> 3124 bytes dist/assets/apple-touch-icon-precomposed.png | Bin 0 -> 7889 bytes dist/assets/apple-touch-icon.png | Bin 0 -> 7889 bytes .../ball.d64e4e7685f6563c60790ede65f2e420.svg | 12 ++ dist/assets/browserconfig.xml | 15 ++ .../bulb.ec7fff230a9158e7a61a3526d851ebb0.svg | 10 ++ ...ottom.8fba8942b34b3f8d54820d2dfde94cc2.svg | 9 ++ ...-left.af75452474340d13e5a890bfee1328c2.svg | 9 ++ ...cinny.1d68e14fd73c8b58ee0f56e0441d13aa.svg | 19 +++ ...-plus.d6fd1e875f585a026f8196da8e1a7b64.svg | 11 ++ ...cross.5745f0df2f96e79157985c990c3b6c40.svg | 7 + .../cup.1f535a372aeb6b1d0125212ce50cf733.svg | 9 ++ .../dog.5eb5c0a8666085e3485d44e93df471fb.svg | 18 +++ ...nload.ab30aec19573b4189334338c801b4180.svg | 12 ++ ...emoji.c38fa1f5cad58bfdc4819433e8b0db91.svg | 13 ++ ...ernal.c37f42201429884adc1da8fc5ee65b88.svg | 12 ++ dist/assets/favicon-16x16.png | Bin 0 -> 762 bytes dist/assets/favicon-32x32.png | Bin 0 -> 1028 bytes dist/assets/favicon-48x48.png | Bin 0 -> 1487 bytes dist/assets/favicon.ico | Bin 0 -> 33310 bytes .../file.71d04d960aa446d4672fc1f60cd462dc.svg | 7 + dist/assets/firefox_app_128x128.png | Bin 0 -> 4288 bytes dist/assets/firefox_app_512x512.png | Bin 0 -> 20107 bytes dist/assets/firefox_app_60x60.png | Bin 0 -> 1882 bytes .../flag.a3cef985a409ca05e544734d3acda439.svg | 8 + ...-lock.5fc3f6871813a605ef0a1b07f0272176.svg | 12 ++ ...-plus.60e5def51051413b7e6ef2fda40475bc.svg | 13 ++ ...earch.2c279449d5bb4495ea7775e690826fb7.svg | 12 ++ .../hash.3bccb5a751524cfc69b43d8962cea627.svg | 7 + .../home.25f584ca53422e4a3e85d3f1cdd7b122.svg | 10 ++ ...arrow.c4e5f226cbbfab22c6fb8eff6f26d9b5.svg | 11 ++ ...arrow.3113613517f3605743e09e1016eec0d8.svg | 11 ++ ...nvite.254774e653e2b009d11d79c0b07ae538.svg | 11 ++ ...arrow.b158dd9a6d19e393ac5e419c8cec4949.svg | 8 + ...arrow.a14d056eec03951908412ec70d2601b2.svg | 8 + dist/assets/manifest.json | 59 ++++++++ dist/assets/manifest.webapp | 14 ++ dist/assets/mstile-144x144.png | Bin 0 -> 4499 bytes dist/assets/mstile-150x150.png | Bin 0 -> 4739 bytes dist/assets/mstile-310x150.png | Bin 0 -> 9582 bytes dist/assets/mstile-310x310.png | Bin 0 -> 10291 bytes dist/assets/mstile-70x70.png | Bin 0 -> 2174 bytes ...peace.6b673eb6c7ea027fdde9fd8262fda828.svg | 9 ++ ...photo.7b243761b447ef50835e8a2455a1438c.svg | 11 ++ .../play.8838e717b724f8097895aae1dad87e92.svg | 11 ++ .../plus.6ba97826d509c8c6b7189fe492a504a9.svg | 7 + ...power.f0b0240b3ec31ce3f04f1aa7b175b02d.svg | 11 ++ ...arrow.4652dfc3651a804bb60877d388196c95.svg | 7 + ...earch.062efbb79fafd84810e946829b5b6115.svg | 8 + .../send.507da28d5579add6eccc11cba4870a69.svg | 7 + ...tings.63c73133e69b9475120089774abfbaf1.svg | 22 +++ ...hield.498420bdf2ec5957adc2646fa892026d.svg | 10 ++ ...-lock.2efa7b53ab33a849560b10cddf5f2ad0.svg | 13 ++ ...space.05c198da2fedc28c7a57d8c86a588e82.svg | 10 ++ ...-mark.9737a73dcc44eb0e793759bd547a71a0.svg | 11 ++ .../user.fb26a2eef540a21e7f9ffefd2321927b.svg | 10 ++ ...-menu.180cbca47512a24456ba0a74e64a5405.svg | 11 ++ .../vlc.12ce0b57b1b136a0150c3c5f147ef08f.svg | 8 + ...-full.a74609ebaadf79cabc7fee7590f52793.svg | 13 ++ dist/index.html | 1 + dist/main.7e67114cb989c8c9f008.bundle.css | 1 + dist/main.b16695b6316dfd5b68d4.bundle.js | 2 + ...b16695b6316dfd5b68d4.bundle.js.LICENSE.txt | 140 ++++++++++++++++++ dist/polyfill.1b01f0f1fe35ab48e585.bundle.js | 1 + 85 files changed, 683 insertions(+), 1 deletion(-) create mode 100644 dist/assets/add-user.d87fd7bdbcd69110487cade29b6cdab6.svg create mode 100644 dist/assets/android-chrome-144x144.png create mode 100644 dist/assets/android-chrome-192x192.png create mode 100644 dist/assets/android-chrome-256x256.png create mode 100644 dist/assets/android-chrome-36x36.png create mode 100644 dist/assets/android-chrome-384x384.png create mode 100644 dist/assets/android-chrome-48x48.png create mode 100644 dist/assets/android-chrome-512x512.png create mode 100644 dist/assets/android-chrome-72x72.png create mode 100644 dist/assets/android-chrome-96x96.png create mode 100644 dist/assets/apple-touch-icon-1024x1024.png create mode 100644 dist/assets/apple-touch-icon-114x114.png create mode 100644 dist/assets/apple-touch-icon-120x120.png create mode 100644 dist/assets/apple-touch-icon-144x144.png create mode 100644 dist/assets/apple-touch-icon-152x152.png create mode 100644 dist/assets/apple-touch-icon-167x167.png create mode 100644 dist/assets/apple-touch-icon-180x180.png create mode 100644 dist/assets/apple-touch-icon-57x57.png create mode 100644 dist/assets/apple-touch-icon-60x60.png create mode 100644 dist/assets/apple-touch-icon-72x72.png create mode 100644 dist/assets/apple-touch-icon-76x76.png create mode 100644 dist/assets/apple-touch-icon-precomposed.png create mode 100644 dist/assets/apple-touch-icon.png create mode 100644 dist/assets/ball.d64e4e7685f6563c60790ede65f2e420.svg create mode 100644 dist/assets/browserconfig.xml create mode 100644 dist/assets/bulb.ec7fff230a9158e7a61a3526d851ebb0.svg create mode 100644 dist/assets/chevron-bottom.8fba8942b34b3f8d54820d2dfde94cc2.svg create mode 100644 dist/assets/chevron-left.af75452474340d13e5a890bfee1328c2.svg create mode 100644 dist/assets/cinny.1d68e14fd73c8b58ee0f56e0441d13aa.svg create mode 100644 dist/assets/circle-plus.d6fd1e875f585a026f8196da8e1a7b64.svg create mode 100644 dist/assets/cross.5745f0df2f96e79157985c990c3b6c40.svg create mode 100644 dist/assets/cup.1f535a372aeb6b1d0125212ce50cf733.svg create mode 100644 dist/assets/dog.5eb5c0a8666085e3485d44e93df471fb.svg create mode 100644 dist/assets/download.ab30aec19573b4189334338c801b4180.svg create mode 100644 dist/assets/emoji.c38fa1f5cad58bfdc4819433e8b0db91.svg create mode 100644 dist/assets/external.c37f42201429884adc1da8fc5ee65b88.svg create mode 100644 dist/assets/favicon-16x16.png create mode 100644 dist/assets/favicon-32x32.png create mode 100644 dist/assets/favicon-48x48.png create mode 100644 dist/assets/favicon.ico create mode 100644 dist/assets/file.71d04d960aa446d4672fc1f60cd462dc.svg create mode 100644 dist/assets/firefox_app_128x128.png create mode 100644 dist/assets/firefox_app_512x512.png create mode 100644 dist/assets/firefox_app_60x60.png create mode 100644 dist/assets/flag.a3cef985a409ca05e544734d3acda439.svg create mode 100644 dist/assets/hash-lock.5fc3f6871813a605ef0a1b07f0272176.svg create mode 100644 dist/assets/hash-plus.60e5def51051413b7e6ef2fda40475bc.svg create mode 100644 dist/assets/hash-search.2c279449d5bb4495ea7775e690826fb7.svg create mode 100644 dist/assets/hash.3bccb5a751524cfc69b43d8962cea627.svg create mode 100644 dist/assets/home.25f584ca53422e4a3e85d3f1cdd7b122.svg create mode 100644 dist/assets/invite-arrow.c4e5f226cbbfab22c6fb8eff6f26d9b5.svg create mode 100644 dist/assets/invite-cancel-arrow.3113613517f3605743e09e1016eec0d8.svg create mode 100644 dist/assets/invite.254774e653e2b009d11d79c0b07ae538.svg create mode 100644 dist/assets/join-arrow.b158dd9a6d19e393ac5e419c8cec4949.svg create mode 100644 dist/assets/leave-arrow.a14d056eec03951908412ec70d2601b2.svg create mode 100644 dist/assets/manifest.json create mode 100644 dist/assets/manifest.webapp create mode 100644 dist/assets/mstile-144x144.png create mode 100644 dist/assets/mstile-150x150.png create mode 100644 dist/assets/mstile-310x150.png create mode 100644 dist/assets/mstile-310x310.png create mode 100644 dist/assets/mstile-70x70.png create mode 100644 dist/assets/peace.6b673eb6c7ea027fdde9fd8262fda828.svg create mode 100644 dist/assets/photo.7b243761b447ef50835e8a2455a1438c.svg create mode 100644 dist/assets/play.8838e717b724f8097895aae1dad87e92.svg create mode 100644 dist/assets/plus.6ba97826d509c8c6b7189fe492a504a9.svg create mode 100644 dist/assets/power.f0b0240b3ec31ce3f04f1aa7b175b02d.svg create mode 100644 dist/assets/reply-arrow.4652dfc3651a804bb60877d388196c95.svg create mode 100644 dist/assets/search.062efbb79fafd84810e946829b5b6115.svg create mode 100644 dist/assets/send.507da28d5579add6eccc11cba4870a69.svg create mode 100644 dist/assets/settings.63c73133e69b9475120089774abfbaf1.svg create mode 100644 dist/assets/shield.498420bdf2ec5957adc2646fa892026d.svg create mode 100644 dist/assets/space-lock.2efa7b53ab33a849560b10cddf5f2ad0.svg create mode 100644 dist/assets/space.05c198da2fedc28c7a57d8c86a588e82.svg create mode 100644 dist/assets/tick-mark.9737a73dcc44eb0e793759bd547a71a0.svg create mode 100644 dist/assets/user.fb26a2eef540a21e7f9ffefd2321927b.svg create mode 100644 dist/assets/vertical-menu.180cbca47512a24456ba0a74e64a5405.svg create mode 100644 dist/assets/vlc.12ce0b57b1b136a0150c3c5f147ef08f.svg create mode 100644 dist/assets/volume-full.a74609ebaadf79cabc7fee7590f52793.svg create mode 100644 dist/index.html create mode 100644 dist/main.7e67114cb989c8c9f008.bundle.css create mode 100644 dist/main.b16695b6316dfd5b68d4.bundle.js create mode 100644 dist/main.b16695b6316dfd5b68d4.bundle.js.LICENSE.txt create mode 100644 dist/polyfill.1b01f0f1fe35ab48e585.bundle.js diff --git a/.gitignore b/.gitignore index f7efb6018..9ae00ff0f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,4 @@ experiment package-lock.json -dist node_modules devAssets \ No newline at end of file diff --git a/dist/assets/add-user.d87fd7bdbcd69110487cade29b6cdab6.svg b/dist/assets/add-user.d87fd7bdbcd69110487cade29b6cdab6.svg new file mode 100644 index 000000000..c3803d80a --- /dev/null +++ b/dist/assets/add-user.d87fd7bdbcd69110487cade29b6cdab6.svg @@ -0,0 +1,12 @@ + + + + + + + + + + diff --git a/dist/assets/android-chrome-144x144.png b/dist/assets/android-chrome-144x144.png new file mode 100644 index 0000000000000000000000000000000000000000..8c8c2668b3259748889da147c356e654e3606e58 GIT binary patch literal 4499 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 literal 0 HcmV?d00001 diff --git a/dist/assets/android-chrome-256x256.png b/dist/assets/android-chrome-256x256.png new file mode 100644 index 0000000000000000000000000000000000000000..57378b413191cabc6c5f86714ffdff47a60ad16c GIT binary patch literal 8384 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 z zA$U@>ln8_OA=bXvAt>S~!o(70L4*qvmvYftUq;&s{dgL1dhONhYKT09c2}5dUbvT% z!yLTPj%_ztja{Oo+f*l-{cfk;ejSk#Nr-t8$P`xPCTLnRBimM*_R6SIMcauDl`+a> z?sola9($h1m{Qv7wY1ldl?jmw;1xULl9Xphf)rC2Ot2~0h8Jq}-z#=X@QNMAY?pt7 zOo^Zx@uIq;83_is|K85aeq(c_E~pNN&5S6$sBXQq4-Fi+_460a&v>VXCQ1aeScSQ) zYWz2@DJOYB_k<|3fY|;@GFEm12&($<3QzgvtlwMt**fr_3D;B}YbumIvO@hIlr1g9 literal 0 HcmV?d00001 diff --git a/dist/assets/android-chrome-36x36.png b/dist/assets/android-chrome-36x36.png new file mode 100644 index 0000000000000000000000000000000000000000..507c443941225e2c73003d85eeac2fba6cc78285 GIT binary patch literal 1073 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 KSv3!_dhkEtONq1q literal 0 HcmV?d00001 diff --git a/dist/assets/android-chrome-48x48.png b/dist/assets/android-chrome-48x48.png new file mode 100644 index 0000000000000000000000000000000000000000..489cfd32175ddeaba504eee8aba83de8bb97811a GIT binary patch literal 1487 zcmV;=1u*)FP)un^=@nsT7@BBf`Cv<9e@_OyQ)-xr9+FYzi~ z#4~sT*?2^odeq_+zQF*F5I>+YuFXft)lIQj%+{@2O`0@G zR|*OWtXZ?hfB^%%^2#fwOqpW$?%i&A>ZzxU7%@V2cDDNZdN*#|kcJ%mCB#TPFAcM2 z&sJDis5=sggj*7cgj>Qew15A8@pxQERaI5W%gdFQmpgm*tS*eh@Hl>h-%7*g&70-q zf3L>b?n$N=gyszmzQVZ!iDnl^Bp~U)Rik& zbRxi^5HCu@m@#9F9XnQcjT$w|s8OSIbo%sZYuBz-QBmQ-g$p_g!_afjJts3W)Aj4u zb>gKEPfNr2@#FPYNlA%St5#`fXwaFKmKH~j9MOfRLp&)BIXO9cW97<~ii?Xyh*+adELlix%mL%a<=(x^$_C4GML`%$YNlmX^xN z$^VVB$>5ZD28lQdknLcnW#1#zHK~YhWl9Ccb zhYr$>uNI8H0yt1+~Q8|A6xIXY#T#^!V+gdb9dGEdVR99DvLS<#8h&AE^?P6~G z9&4psyLQdu#fv4ANxjkB-0aYyLn8J*&S)2Nw_==-vUBH7t5>hq8x<858XFr$=omh5 zhq$}7;0r83zc0W1Qf_Xp7hZTlPrUQaJ5HTCB_d6D1Lxc!?&mJy3}ztMwQHA=BS#uH zZk%+SIB~+e@4hRUOo~7f^RY(*!oos95a^D1^XB>PyYEEg z_xRX7#C7fP(w9O(K!dOAT0nGWQYJwJL1Gt9bOsAAhuC#||4eZglhJ zO?i2FGBPsU(%RZ;)~s0$9z3X*j^TCuQx^i=mx1M2feh{X_wR4=40}Hub2%X?%kN*ozB#>3^cO!d3`W4xRu2002ovPDHLkV1hnv;Qasq literal 0 HcmV?d00001 diff --git a/dist/assets/android-chrome-512x512.png b/dist/assets/android-chrome-512x512.png new file mode 100644 index 0000000000000000000000000000000000000000..d312b532c57b74fa511e6045500d9a83bb5deec4 GIT binary patch literal 17829 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 literal 0 HcmV?d00001 diff --git a/dist/assets/apple-touch-icon-1024x1024.png b/dist/assets/apple-touch-icon-1024x1024.png new file mode 100644 index 0000000000000000000000000000000000000000..e525b30a65618439504e89db92c8ba8562918df2 GIT binary patch literal 51825 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 ZJnZO!)h54{{-)wTgZmG6$#n9I`hT?CnVbLs literal 0 HcmV?d00001 diff --git a/dist/assets/apple-touch-icon-114x114.png b/dist/assets/apple-touch-icon-114x114.png new file mode 100644 index 0000000000000000000000000000000000000000..418f883395b22e4d4368fe4ca0769d76c98eec5c GIT binary patch literal 4902 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℞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

@dAFv$W*lSH4*UY=@f4kiK%3hgn5lQ&UsC z!lEy_zM-KyWYgXGLslg5FQre`H(=oW?&-8QZ`AYh@+go~v{q*!cfs-3*4A26AD<8B z!!9l?NO++6w2OK_J<*{pw`>Yg6cQ3r$%dX3xT>XfM~fp>vaPMn(tmA6TL4;tH~F-< zcnnxe%-y^8{U9433>O!dO3i}@Y-FTc;jlXikoL^r@+L&>jO)_Ul8-sSHsub@k$S_T zcvJ#{mUb|0X~`Y1$rt_l=2W{WEj_(hf@n~Dm@JU9M<97JUaZ>kG?vn?{vfPGhN6J9cK)oI7(&loed)?>5C}*n5Z}_GS^1X2bcWq65|wb;vg(ir(BAm? zI4X6}wWz+H2V3LVi^P}~Nr+k)WutLh>+5aV%F|&SP_Q9RPR>tbWA}(_8ygPoF^raC z_PUQ`tYd)9%R#ua`+ugfZofk`lINpY&$ssWGJ0Uh4!_2#V`5`(^e+vU_4f7Y;HcL{ z&z*Z*Rdtq(ou@g!x26NFb_Sl5QU3Ydi3zKRtuSK!{%I-@31imn{bgG`TPpp}udiiS zn|EbK9%g3BJ9JS)^c%35ojkz@ai3cjCa*YpcDLA|Z+L9PBEhA~8LSE#$8Pn1Wv~XZ z*A_)9Um-HYB$Z*HZ(@QiHoMWECSlm~{(Za66u>DAQ4fua%|Hk&*I^2=(k{xNW9Dgv zh;b>Wt}PoKpMKKBK4s|hXBgQ~Q*pu(C|03!StCe11F*8Bl$1eN0<7L9V%sSpA)!jy zWAueC$tHaBG9Jc)!>ro#C%ne0w5j_TF}JXw3>nIr!V_=$w7mIP)t^pc14;_+e3%tC ze`5b{w&;;V zb}_xRg-5pbhTSQ`C#9v276afoIy=kTwH^W(7h_^!kp%29<*Z)Z*<4QKQ%rzudpgaw z$5K%+zOV--RR(6}c~h8pX4yAar-e;SOjM<%4O< z7BSC9URd`5%;5zf<%5}Z;#jyE14vOel|Ld5wg+zektbF4lK5f`iVK?v{mv1)U#HEk zUX4dqz#xdo>P4K?JPnvGg6w^!8D*1dvDW_U5(#c1C?41HY?o>slTlgzVmw)O6~mbU?2KDcef#8UrjymS3yC+9awn5plk4T z5GGZJsQCPRVO3RCDzelqa!$u6Es{vRze%4@ojH@yva=)|Nna1$%dg})GyU&CIhyX+ z1>)cu>iq661yDg!8U}-TkdYA!0JG9|s+n=6wX-u8EQb;7mGUG1whS1gk7mv3|IE!h zx{~|D@>Eg?`R&?#u;cNtb$UAg_THRuqL7AFK`wPN z&V{I=>?~J8zI<$l{()cZ0O>mn@{r!Z*lfC~!f?jmQQ1T-<<`gH;f(rv z6(H^fA&n4*fJ53hFVIV!IkV8OJnaa0bdE_`Ss8|UUR6JFutG;Tde|eG+;0DtB&be3 z4uCuU)Q_4(@Q=Or7KV`w<~acZR9ZM}jpoLU8)H#1Nr}7)cc=Fjl^q=&*&u`){D1g} z!^q+Sf~Ss5IAopZ4V^-ie8gTbR1RxlalG%5?4uN6O_>5aXe`jD-2We8sEaThcIZmH z0i@mzX$4@H`iDFv4PtxP3Ol)Xj{!gN(yjfzZ1X*h)GDfZJI?o{MnS{C5zWfi*Xil$ zIyyQ>wlHjnyR5=8Cb?=EFo`j_zp`p&!Hu1|a^*@_itqr80u5o?@@l!s|A(K?UcBf! zJ~=hDFf(Hp6&)Q5lT66(pC{~oh;tUW4CHlmbg*%7M0eWH{u-|ZkS!ctR>f0_!WQ0h zMF!45BGV%f3@1*UfQ+Sjz!OFT(I;mMQIM{K?yow!x`r^+!>y{S2awW0ee)EG-xClG z#47OHv$8TG&~0O*8riIDSVdKJohZD|kff&r`z8$%>47=?^3R9IMC|X#`OIiF2Cd2z c`23@95(&yCI&J)hQ@lesU1Q9P3wBZe15=6F-T(jq literal 0 HcmV?d00001 diff --git a/dist/assets/apple-touch-icon-144x144.png b/dist/assets/apple-touch-icon-144x144.png new file mode 100644 index 0000000000000000000000000000000000000000..b6a731eba6e00ff3a70fd3d660c9ec3857200284 GIT binary patch literal 6075 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 Wvb$fUaT12|$F$WkYR^<{!u}66`NA&% literal 0 HcmV?d00001 diff --git a/dist/assets/apple-touch-icon-152x152.png b/dist/assets/apple-touch-icon-152x152.png new file mode 100644 index 0000000000000000000000000000000000000000..968ae2f01e93c14da064c885111549a06f4c4a9a GIT binary patch literal 6665 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 dUG@*xy6@Y=+Ev%5@DIr$R3fsi|j(#L{=oT z_kRBW_j+B|;d0J1zR&%=@6S3RTAE6iNf=1ZojZ3~MOj`4{uUrFB0~7>LZ`lQ?i{0q zio7hw{rs<1a>K!c`M*08$IjBHoej~fVS$fQ4jb!JI4!$|29_#B0w>Kx!cE(k`5Kw~ zGj4l3?1~w9OerrK$Lu|5^R7P0eiq&fd=@;-dZd@EK{dBsKgbHQuu&`E$% zS%S5-b#8usOmed7#FV{esm6eDsA3JSLO_HwO9^1qCXP3ynI@rKW+Y{o7J6Cr{{5B4t!6f9>GXR+WKKtW*7mIK!K$jN%9@&-;^L3w z6%?Fe6B4eZNj%S1OAy%Gn4)%bbF+&Gz07^{CidUi>Be-u?&jBOHFgdT(>2Wu>A|&; zf{@_gAAz@@ejR%IP;jc?KFe^uvz3bklW3aiWvob&va<4Z35n#@RUFiY=bTTxgvTyB z*Zp*w-^+tJ_A?ECkB;V7R+P48KWOX4CoAU#);rGOt&hJmpL&nY&CA=7l)W62lA>l| z!5$qQjj|b4CcAb!TsucG#BwlMJGOB29A|9EJA+y(Iyyx|Lq;7{I|WP2{6tAN0p$8t zpVPzXZv{>md0tk~E_da9pk6l7Us%XZNk!ELE3d%nsJd>=4sOmgT922|FLXy)E%rp; zk(4xlhbhrAHDwK>yEz{w*i2DhUynQ6*qEwRPZaW*sNQnx@8JDjZ`a_3Is$B%cjxJlk4PTN0Z>;K!gnOk2E;}{}H z$YP+6P!z}Z(Fj`(TqPkPxsYt*{Ohae&X)JT6x)f?-UMT>N8F)u&vl9vVRbS17s+Tm z4>lFd#pUkZ>zr#3nkqNNk6;kZZs5km{{8FzwdQI6><7!G1KVA1!c*s(1+g2HmJ3iS5(wt!Z6?9;i$A6G#f8@ge&oDH8GhiH$8#-n=cO} z5wW`KW0^pKK}`?Q+8MivGghbx)*T5U@& zWOA;vvoj{>ZdNEQE$z$|aGi&t84zE(hJXz2F-KK5X924@rb zq|p_s(!akxQKU+u*I^>mBR1>q_wx8pR*}b_%^9^8uhXIR{TSYCEdo_FHF^;XB1yMR zd0l6?)6Q~=LugD4Rk3dyK4+dqM=+(llF}uV=`AcMEoFXDr5x;_i zgH2#x&^QwEA+hf-+6ywgLc9J9Bntb%HZ!vaTx5rNhtlR$JYiFcTpY@}hvp_Bzx&_; z-PzgM7Zah(iYNblNI#EH*b^R3%6uW<*aF3n*U};bMa7F4?CR^-3fMCZ|XH(0}w1`8R}xh0PYa zBBn0|sP+vGV%z+QsUo`6&ATJxAC?+sy{F-|{*tR=*yOIAIh@GD$ET*ACK2DKQ|J#} zGG6*5Oi}j{--D7LJ<)8KK;I;FPHL7H+di-iC2CIf*I1zh-=yY~T{W+h9VH({=O{83 zY5wN3Bin&Ilfdlk8`5Wg%|jHOGx9Z3x?uB!gF@-g_RGAZVZr5;k&%(;!^PMtyQvuX zJbPrVPNi%DFjL9POB$fqu+GuvmenT{k)$CEzm!zk_O>IZW~#CRhF42pzvtxeH^=qD ztkl%h)#03rf*c}0{|CP)YXyw`t_~WdH<&#%I&t>rlGjaD7Q9X z&8A`=p4uD!xi5KYz6^@mH2>}Y?EKN{=W)6}QKVZyc2Mm4>#Mt`=fbaFgNefC&|Cmn zK`^A0OiUWGvgea!kc#;S1PH@?ZYnMbK)VuMzMRMD^z7M<>(^g}P;-5Gk5w!7_4C7T zZf*u>rea`F)z`loc14g=Qu5lM0}ScXWQBP^Y%KMXc6}JY%rj@_B4Qc^)77D@fpn>q zZf4K$pw6+e_$ZmPM7ZAjXG^MZx!(T%_HnG0RTy+6@-VXEm_AdHB>gHJrKoJm?WfSf znSgVcD^^xkv)=z+o}8RqmGMGf6SMCaf4S3n<%Wa74sXtK)qvOQUm`PbUtf64a8{Cr!@({J0qf49>?)7`jn z16KSk?#&x2N=hG5o8fE%fVw=Vg)WR(&TtR#2SScAG8v7-Yc2p?yM26RCSh=vP?Gwz z=F;usgDoy8DJI+BJ#10s9=|Oa#O&3dUm_>B>I$bvbb;T84^lopKK_A$^NWieX?O12 z+5T1g9l46*>JY1)3g{7HVq%xg=_CW5X-)|V2HTusUMP09-rEP5+Ir^|DjFJjO-(W} zdQ!r+wl;U@BH<+UxbCT`q=;)`^UKSD?+`Su)vZ&ow&sBoWAu~mOCS0JUFyyV7}k9R zzT^3vF69{<8ai*!AZpXm7tdEAIy^l5zN#wDplEvjqYpmPaV829t{XkwEZ*T9&^#9b zY#Ku%BCtc5veSbyXFKG0czAzz`vsj`U16kdqin~+yCSaTaFb|iYTl8Mc%}E43JQ17hePd-+?R3MTh*?yn`(o{K(3d~B)K>Gcz~SMc z-S_4+c!mn+6-^kfa+*fhUsSBDtkb!>jj-sLn3!_9YTF4*peB7PV`F3HmwVdpD=T?E z2UD^YY6=JlkTRnaq1}+tM-b_apz$Y|qC)$SkPy&#!{w&;>=BYxS63%BsIhB(9L_A2 z46K5$X6E2<9~q>OkgVKX|8E)@(rEzs<~)pyjH{CsY&l9%`EFaY(2KAJIgpQI2<#y8 z@S002mb=oTmx_v-x`Hq?yWD<8;^+9gusmz%S0F16KE5#E1$+0+`W5|hlk@0K-ukWMn?CtIMetk>0hVe>(J*i%Wp&3jO>(;4;`v70^hxA(9 zkda||`0(LozSrr|g^L$|&w6g{9Ij+ggMI^qBJYQXuUE-ahqmP5;n5ERrpZ36g!_Zw zIfUcHotH_iKBdk9lG4!8>FDbR591a&6|^0loLWD9A`=r6L!;5SFS*3b%*^PszYA5i z6Oje!|AoSNLLR#o`S&wEf#8NV$5byaT9g{r`@Vh4$BP992(NZ@bj&nv@tTx?;e;`s zthT)Zo4c@*;oW5jDwFSFspCCY*V_e}Y4fhtHe=aP9Q5%c!|h z1I0eo=;n~6!znCGX*&m6EiCL(4X?O((%9RF)b#W!a2dTN5EdQX-P9~BpR*Oh99>-C zpCI7wWKe_J@vs{Th$!ZXjf-PH??byfU4N?vRComaElXsJa^ui;AQXUicZ5KVtK2P& zQ&Cl=(kFIsaIjOcw-@+#;Qg;Vl$KA3A!5=u!|O;zOL1&{e;4!@rG5zTgef1ClpgIa z)N*#jR|A(I08unHI*I{1P)-s< z0EJz&hA0)hPI z&<0wuO$W1{sZySFgT_lMD{9qsb^0c)%-$zX58gfQ>=$fN*LZK*PB{L~AZYm$JVP-& zHx*B4+woS*XP{FAq&R!~`piZPwQ+p~6YBvsLRZUCHy>A-j1}v-{Q4T7yxLAK!wzk( zarnQd>l7CEE%wGHi92(Gd>EDA+1V*Es3jYm0pP_*N=m|EWA6YpN*+}PT4lU^liX(^ zB5Xf>CpQka`3cx+3|@Y%cb`{ORxbFFOPc_C0N88AKAo37Z*?Z!c1zWqeHsTfByU_ z1oXK9)*&bl`VUq@C@3gs*9*-b+4TZGk^=)#df|fJKyPnI(k&|y7$z`zHSEyS{{9zG z%WsWaq>EEhQZhq7{GAUgG5V0qmGOegpz6ipGgQ1T_|H)gE82QLM~m81#hr;rNaToo zZhl$c2j0srVgy7ORg7Rzxx4)eG)pWk--DqlYhAl3a+#C6(96kvPHt{WPrp|2kjKCz zLF1W&RUu+6e-0ohtLu@To?ZwqH22G+JytZDk(`_ybv@7GTg_7(@77K?i_-qy-l7-G zUX(%@-OjjyL)KwCz^d~7`%1bVPSx!+Z@(z4*378mk1$)s)s3^!;T;D?s#=q+Y7{r*_+1Y8; zIl9p7p%!m%S%Tf&-N~A#*OGT>uUyFy&VU~+ngGx}UEja6IP*VgpwT!iHEw}k24lDA zN>U3m*xKIi7Ygf%%FSg*xw)PmJx49?Km-H*Kdm`;J2YF!tb=Hv0;mz?&5^eVq8m4G z3*PdlfRD-W@bR^20zzSsBl{Bsa}FyZ@CgkI8^)*;wQkR~*HZ^bZf|dADn&747LWGV zL3L*xR$jUykSTn>%;*C`QEu5J?5kium_7J)v8NG2lRES6J4j!4#n zW)npH-MadE6~uff<8a)`-vQ^d>Kh3!GxV_D3sl~en-c&tl8Ca7`A7<3#|>bC%aBh% zC-Ug#6DcVvwLam-m`v9>p~3gXkO2I{UI)EvbXlVUDJHMm9C-O!UuNcY@UTA6vO9A@ zEF=RISFUu!VHH>|&D6WjZct8I2tP3Lt)zh0Ak)CE z?fc7zW`qQ{AbkP<#OOosb-Mo$=sNP<5nOaA&S7)99>gHYK&DAPEPeZ+<=+#tKn}Gx z<>uXFb{g8+luD6|vd&hZ^N~=Y!;r+1O0FC%sSkZ_TsWh63~Z9Q8X4oAS4L$@zaPpG z(cOIPPl4ymgYm7c6?14gy}jJi(_^x?Iy@P()$)&dFf9V46%aZJuWVKf_#W%Y@~jS0 z@TDdC6?g`e*RF*vmrc*iV3n1L;`6jrN=r-mjhggL@Ue79c%i(PH#Y?mZW?gbfnn|eqlFj||BsB_Q7kKIZnLcxBHANJPa~an=ttrE ze0@Bm;raTrGMdeHzOtsaT$NaM%f~HVQd=Jmm_-MnsfSOdlvrM}H$GqQI@PMX4{9|V zU?`CfKnXH3U0p~w-(&mfP~NNK@2>p=vqNy8GACVBtctHuKIR+H&dUj4u0I2TeWUy=i-|fk?G&B_8ik8IyQz6^X zZSi{9il4dt3hZko#7P4%a5+)ZW?!qU_1^*=yw1poS{9?Eq(lG?i7$p;v))S-wWW&} zhHmlo^##wQAA550LQYO@=wumeo;lbHv@!|#B#hHl=@)n6DVdo+0aEe^2y{Ij$dJiE zrq&1IHh`8czx?f2#H{+&Hngw}F{)r_+P-~D0WHJ-#L|)zYAKI@dVF97nIwiFfH!kw zEjTuwI+{e-SoN{Q1wgOsbgJ z*u$T1%eH|N5J;(o2=Tq^ug7+eAcO+X5DmJ-mpA{Cz&+ZLH5apwug>3q@B*|2?*cqe ziE&GMYAR!c%bG9j;TS7uHt1t$;Tm2cq1RyPH#RmdkoySKk&^plbAvA+2LlGFT~P_l z02O3xK|vQm_|2Qf=X!dsbs&D@`#dDBOpuj4guRj0|DGY!6 zu#Ad{Y4Ggycn$muXwel@$SOF1-3=Ch{P>8Za+0q6v|nxmjMJ28iKc#Ku!Y^u^!mWwFLm+Ts4@7rQ6x@Ll7XR zO;e1NgD&$?rDgb4VL1@F57H%`t2#zOMUiKlo15F1X-t6HjWl^UWAr)=Wlpy7&!0b! zR3)ILrDeMLWuyDgqJnZ7=pub0E-tQ<(^CZqImI1+yyEBQrS}&}v zg=BNbtxVTDHy!*IIDFOsrOO@(FVWaEK*49=FOG^@zWsz}9 zb1G0IBvMU|&z`kCF4U(4O)U&L*6e@lH$mSe%6K<7xva(9byfn|_*yq#of4?7ZEA|% zHpeW$W~{g~jz<>>w6wLgAv6gB>xpVX{51rcSTGW8y}iV?d1jqp);r2g+pj_t{H@jj zft!u5)t7iUY9Q+~dbzI$!H-{AnV=j|34FPd$xVWggTwb`B$I+D4s1dD;qR5AHMEoz z;>p+)!#{$=NtVwGgtU|xXw?EPz|PK20db&@`c=l&7?`AL?fW45qh(@bk z&f_LYlXS}mxyi3zewPvL{u*+T9uT7;fC(iUAnYIzOV}7Gh}!=12Q--0NYUgu1?_DR zRo&f6{{H^2m-=X_sHl`xRp-Go?SdhuD!8A~g+u9#0n8u(29)+5UfB>}>;_yhq5$fh zmNW6gpz0bL=HY7ys1Wu7He4|W?S0mytf9dnDjE+46vR`{;Na5#|9TD)M36U#At8c} zj&E`CXz7!bYv4}q{rXxB0b&kl)6sVZSK#X}s3xewj*$_NRmsYr@6Qu?u??Mg|08$1 YmO1|=A>%K6?RZW_K~ug|&cyeB0DR9&6#xJL literal 0 HcmV?d00001 diff --git a/dist/assets/apple-touch-icon-180x180.png b/dist/assets/apple-touch-icon-180x180.png new file mode 100644 index 0000000000000000000000000000000000000000..a651cd1c8b2d26a4af969c22b43f7076f6f9bf2c GIT binary patch literal 7889 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 REPwz2002ovPDHLkV1hplh-Lr) literal 0 HcmV?d00001 diff --git a/dist/assets/apple-touch-icon-60x60.png b/dist/assets/apple-touch-icon-60x60.png new file mode 100644 index 0000000000000000000000000000000000000000..47fafb07aacb8c427095194e8c4cee18e2268e5a GIT binary patch literal 2482 zcmV;j2~GBiP)_A_ONl| zMr=i8m86uEmX>nj#0jokxq_4uE5RyEOiWN+T`j7stNHTFF9{D1CnY6C#>B)3R!Li0RaIVIdTL|(^x5$75Mkxe>rsM5T&K1IMU6VH`%>= zH=3rAm6gTj&6`;+m1R0}=8QBL4C2wFNBmzYDJh}6yqv78ED{qFSq_yY8X6iRDJe-_ zxNt%63>Y09B`GP1ii!%ElanJ{TwGWRl_luu=|R&pX)>7v&zQWtJYhDQ6G?`C*-n1v`TAUQc%-nemt=S^*Gtw>Bvlq^8u z3C^53BlGg|1kb4p7cPi%=g#pY3iGtIv|un81kbrchYn$}SeQ>?9)rQaqeqW;-i?lq zVlWt(PhpOtq9RI4O8EbxxVV^-k`m@pnIWYlJv|*;@$&Lw-@bi>hldjw7|8nd>zSIG zqOY%y=H_OuU%$@9ix;V`uEw4+GBTv5X@VIlGfGQKxpnIntL5(QPG)8%Nl8hpUAvaK z6h*<)(-TimPlAJkNl8h;WHRyDXP;p*nXretx;jx-RwkpOq6AiJ(yg#cPEN*Rv9KCD zcI@Ey-+w1OJRDV3S&EGtH}dhvA0vd|+O=!gLuY5F*tc&V(-f@k-@nh5D_2;J@bGZT z%gb56emzU^`0-=P%F1YMZADQO($mxV_Sj7D_;{Lg&w)=jE4Q zW;w23zs|IQfdT&h`)@XE*ub=7$Bq#nAJ5jUTXA=HXWIDqI2|1wG&eU>QBgr|ZY~y! zh2)6B)l!4|tmT`g)<7&1P0guh-+@ z;ejn#EEeM97|#jmEPW7G)<$uy&Ze$=;#p2;NT!D;q2_pyYIe>tt2NWW3gDUr@_HN)RB=9 zmg}vz-s0T3bLjPYY@xWgn1X@=>}_~>7?ovkb#>+IufHZaIT;}YwlF$6%7Ft1a1>Ri z(=j$S#$tBu+Qr$kXW6uA6Snl@k3Z7U(SaklxVWIYxw+BT*T+IUJUlpl{5T(d^btY` zY)MMVH{X1Nqqw=bq5Amv$h&v%3Z6jIG;(rs@b&e@9{&9EPZ}E=ag=rI)=Aah-(S?! z)G(KahX+TG9_5oyKEa+YU%reZ>GgV{>h*f&djI|RId$q3K0ZF!TSY|$j`Z4Vuc2() zwoNieW@aWnK0Y|YojZ4Mr0v_cOC=;EL^wG)F{`Mk2uJDc?8H%=oSX;=2@#5`t1H{L zZFL2ygb*YoBrr|E%GcMIu&^*@oj!e3|2fq{X{I(qadot>T7%O8LI zfg=P21P~b+DVU)!M@B{lvwC}b`SjCIu@{rcgd=?Q)mKso!7PP2G)+U(G-h4Ac#%t& zE@5j^Q&ZH|)?#n5v9ZL�ch4m?tYMix*#fky!^09N_lt+t`xPXk=hu0DE$FcIM>C zlgy_u&*sgW$;!%N)`JHRh>nh?tE&rJ`R=>#u(#8vPqS&$CgxLkg2co`_U_#)nbFeH zLR?%Nqobp&R(E$dMMXu})BgSY`S8OJc@l*MFHrLva_=p z8ymx3f`fx)c6K%kQCNVBiwmWtrDDsLEzGK_s$$2E9hl8#R^q?^{^QuOW7x~9uf9rA zQ4!A0&MZXXDZISAC@U+&-`}5EEiEmCgoJSE(j}Jbi!Z)lWMl+;*s^5{moHz&+uK|4 z6l>D0cnWuScjDvYWkp2=ZEbA=tA`ICQczGpLqh}ayz>q&E-ozQ>eZ`!{`u$FLvV1g zG#ZU!-MV!wW=*;ki_qzGA|W9`+`D&A{`J>if*FmCjeP(8_Xr`_x^*jS*RJJBdV70` zj*ezvU;ta&zkfdk1qH(0-JPXalWxTlyzs&c#Kpx4KR-Wy`|UR-CMK9RIy#EcXe2v3 zn}LA=UVr^{TwPt6H90xS2OoSuU0ofvl9MM-^6Rg^($mv}mzNirnVIC~=3+~+v9bL8^Us8ahO%5jTCqYU zB_*V#rE%lN4ICjTC`cYTa)jvUXu%4ptb(R#XqrY@S(!Y3{J1b0jYui6B}Gw)h=}0u z;lpy*u3dsvQn7)ks3;K?6-8@nEBX2P6c!fB+S*z%K0eM$I5{~H6ci-m;^IU?LIN8$ zY`{uj11dJ;>+4HuYAUIzsbY9|n99mZSzli-nwy*X=bwLMS67$l>+9p;!-q`M>2!E_ wc;MsXBlUW{(ChUC1_sKIkPxBM=>&H0KRpG-3*k<+?f?J)07*qoM6N<$g5_W982|tP literal 0 HcmV?d00001 diff --git a/dist/assets/apple-touch-icon-72x72.png b/dist/assets/apple-touch-icon-72x72.png new file mode 100644 index 0000000000000000000000000000000000000000..6e5b13c4f30392f082696c2eab12cc127fdc7b02 GIT binary patch literal 2951 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 x3`!r4(82pQQqB@$(a$jZtrWXmCY@AbQ$ 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 x3`!r4(8 + + + + + diff --git a/dist/assets/browserconfig.xml b/dist/assets/browserconfig.xml new file mode 100644 index 000000000..e36bce5bc --- /dev/null +++ b/dist/assets/browserconfig.xml @@ -0,0 +1,15 @@ + + + + + + + + + #fff + + + + + + diff --git a/dist/assets/bulb.ec7fff230a9158e7a61a3526d851ebb0.svg b/dist/assets/bulb.ec7fff230a9158e7a61a3526d851ebb0.svg new file mode 100644 index 000000000..00e808861 --- /dev/null +++ b/dist/assets/bulb.ec7fff230a9158e7a61a3526d851ebb0.svg @@ -0,0 +1,10 @@ + + + + + + diff --git a/dist/assets/chevron-bottom.8fba8942b34b3f8d54820d2dfde94cc2.svg b/dist/assets/chevron-bottom.8fba8942b34b3f8d54820d2dfde94cc2.svg new file mode 100644 index 000000000..5562b7aaf --- /dev/null +++ b/dist/assets/chevron-bottom.8fba8942b34b3f8d54820d2dfde94cc2.svg @@ -0,0 +1,9 @@ + + + + + + + + diff --git a/dist/assets/chevron-left.af75452474340d13e5a890bfee1328c2.svg b/dist/assets/chevron-left.af75452474340d13e5a890bfee1328c2.svg new file mode 100644 index 000000000..ba9e12cca --- /dev/null +++ b/dist/assets/chevron-left.af75452474340d13e5a890bfee1328c2.svg @@ -0,0 +1,9 @@ + + + + + + + + diff --git a/dist/assets/cinny.1d68e14fd73c8b58ee0f56e0441d13aa.svg b/dist/assets/cinny.1d68e14fd73c8b58ee0f56e0441d13aa.svg new file mode 100644 index 000000000..8701d67b7 --- /dev/null +++ b/dist/assets/cinny.1d68e14fd73c8b58ee0f56e0441d13aa.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dist/assets/circle-plus.d6fd1e875f585a026f8196da8e1a7b64.svg b/dist/assets/circle-plus.d6fd1e875f585a026f8196da8e1a7b64.svg new file mode 100644 index 000000000..41690a08a --- /dev/null +++ b/dist/assets/circle-plus.d6fd1e875f585a026f8196da8e1a7b64.svg @@ -0,0 +1,11 @@ + + + + + + + + + diff --git a/dist/assets/cross.5745f0df2f96e79157985c990c3b6c40.svg b/dist/assets/cross.5745f0df2f96e79157985c990c3b6c40.svg new file mode 100644 index 000000000..0acda8842 --- /dev/null +++ b/dist/assets/cross.5745f0df2f96e79157985c990c3b6c40.svg @@ -0,0 +1,7 @@ + + + + + + diff --git a/dist/assets/cup.1f535a372aeb6b1d0125212ce50cf733.svg b/dist/assets/cup.1f535a372aeb6b1d0125212ce50cf733.svg new file mode 100644 index 000000000..8921e2c9a --- /dev/null +++ b/dist/assets/cup.1f535a372aeb6b1d0125212ce50cf733.svg @@ -0,0 +1,9 @@ + + + + + + diff --git a/dist/assets/dog.5eb5c0a8666085e3485d44e93df471fb.svg b/dist/assets/dog.5eb5c0a8666085e3485d44e93df471fb.svg new file mode 100644 index 000000000..3b252956f --- /dev/null +++ b/dist/assets/dog.5eb5c0a8666085e3485d44e93df471fb.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + diff --git a/dist/assets/download.ab30aec19573b4189334338c801b4180.svg b/dist/assets/download.ab30aec19573b4189334338c801b4180.svg new file mode 100644 index 000000000..677014f36 --- /dev/null +++ b/dist/assets/download.ab30aec19573b4189334338c801b4180.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + diff --git a/dist/assets/emoji.c38fa1f5cad58bfdc4819433e8b0db91.svg b/dist/assets/emoji.c38fa1f5cad58bfdc4819433e8b0db91.svg new file mode 100644 index 000000000..0daac8796 --- /dev/null +++ b/dist/assets/emoji.c38fa1f5cad58bfdc4819433e8b0db91.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + diff --git a/dist/assets/external.c37f42201429884adc1da8fc5ee65b88.svg b/dist/assets/external.c37f42201429884adc1da8fc5ee65b88.svg new file mode 100644 index 000000000..92b007cc9 --- /dev/null +++ b/dist/assets/external.c37f42201429884adc1da8fc5ee65b88.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + diff --git a/dist/assets/favicon-16x16.png b/dist/assets/favicon-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..0a501a1ef2ab1a9056db6c2e199df3f52acd5ec9 GIT binary patch literal 762 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 literal 0 HcmV?d00001 diff --git a/dist/assets/favicon.ico b/dist/assets/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..916713065b069f0e59a63d520178ea8101818913 GIT binary patch literal 33310 zcmds=39uDKmWD41Zh#;vi?Te&jSgf)fe5#7iEs_K7-bc0ca0fVQQL(<(1~z#P}xOo zffki;3)exq8(Txi1sUl<9R+3_z%4`&ci_Dz@8N_@)vbGhJ`v|--mH`7 zoII6#o~&0Wv?{bIbnIAASXb!Xx=2=oYpw6#Dh^e;-mP z{JBS=aPrCiZ-rYY~UjHYwh?%PzZ^Hf`E0QrzRAupr%Lj~h3Ry!A~@O{Srt zf&Au^Pd+J%ug!1u*a{C{53=_kFkrwokvDGJwyg*%ZqXce*kLwbm`@{R!5*^J%sF%B zAg<`kEeiN;(B+IX&an9j;Xz1Q3^v_opMBQNm@xx#FB6#s{Py75Yp?b4OP1vm=)rrD z&FgpFbyqWV=+NSqUw-LjR2hur@xlu)*nH?~sB*r)F{)hUq5s3!3P&* zdoRCVuV#^7_VjFW=9y;}*RNk6$euQBnpwPfvAOQL>&&gU-da5R=%dlWqupbVJ-j-} zyHHvKc2HP6<&;y34?XmddFrXB%-wh2ZQ8bN>!tHdNZfmW3cdQQ=d-C3`n}cXVd)9I zI5PZqZtD+vTWCj}^z94pCSegfDcuW2h|UeA^;hjIXg{*cY-ETo5_yKMdfu%4gm@Gr zbAamAEZ&P`H-NsKBik?igu0r7x)ZPeQBWwT&q)bAML$Zimgt?Vkqx(i#Fh3(JsT

2R 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 j*?{u}e9Z0;a@O`|A?J>z-vJ + + + + + diff --git a/dist/assets/firefox_app_128x128.png b/dist/assets/firefox_app_128x128.png new file mode 100644 index 0000000000000000000000000000000000000000..dacde611cacda06ef1ea4e842ceb8f30e285c734 GIT binary patch literal 4288 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 literal 0 HcmV?d00001 diff --git a/dist/assets/firefox_app_512x512.png b/dist/assets/firefox_app_512x512.png new file mode 100644 index 0000000000000000000000000000000000000000..b1ce752e52e8964a70f4cb8cecdf2304226b6e32 GIT binary patch literal 20107 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 Urvw%=WB>pF07*qoM6N<$f}@>|eE + + + + + diff --git a/dist/assets/hash-lock.5fc3f6871813a605ef0a1b07f0272176.svg b/dist/assets/hash-lock.5fc3f6871813a605ef0a1b07f0272176.svg new file mode 100644 index 000000000..ae263ced5 --- /dev/null +++ b/dist/assets/hash-lock.5fc3f6871813a605ef0a1b07f0272176.svg @@ -0,0 +1,12 @@ + + + + + + + + + diff --git a/dist/assets/hash-plus.60e5def51051413b7e6ef2fda40475bc.svg b/dist/assets/hash-plus.60e5def51051413b7e6ef2fda40475bc.svg new file mode 100644 index 000000000..69737fd55 --- /dev/null +++ b/dist/assets/hash-plus.60e5def51051413b7e6ef2fda40475bc.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + diff --git a/dist/assets/hash-search.2c279449d5bb4495ea7775e690826fb7.svg b/dist/assets/hash-search.2c279449d5bb4495ea7775e690826fb7.svg new file mode 100644 index 000000000..f135e8986 --- /dev/null +++ b/dist/assets/hash-search.2c279449d5bb4495ea7775e690826fb7.svg @@ -0,0 +1,12 @@ + + + + + + + + + diff --git a/dist/assets/hash.3bccb5a751524cfc69b43d8962cea627.svg b/dist/assets/hash.3bccb5a751524cfc69b43d8962cea627.svg new file mode 100644 index 000000000..dcb8b9647 --- /dev/null +++ b/dist/assets/hash.3bccb5a751524cfc69b43d8962cea627.svg @@ -0,0 +1,7 @@ + + + + + + diff --git a/dist/assets/home.25f584ca53422e4a3e85d3f1cdd7b122.svg b/dist/assets/home.25f584ca53422e4a3e85d3f1cdd7b122.svg new file mode 100644 index 000000000..3c7a02df4 --- /dev/null +++ b/dist/assets/home.25f584ca53422e4a3e85d3f1cdd7b122.svg @@ -0,0 +1,10 @@ + + + + + + + + + diff --git a/dist/assets/invite-arrow.c4e5f226cbbfab22c6fb8eff6f26d9b5.svg b/dist/assets/invite-arrow.c4e5f226cbbfab22c6fb8eff6f26d9b5.svg new file mode 100644 index 000000000..370bf8e8c --- /dev/null +++ b/dist/assets/invite-arrow.c4e5f226cbbfab22c6fb8eff6f26d9b5.svg @@ -0,0 +1,11 @@ + + + + + + + + + diff --git a/dist/assets/invite-cancel-arrow.3113613517f3605743e09e1016eec0d8.svg b/dist/assets/invite-cancel-arrow.3113613517f3605743e09e1016eec0d8.svg new file mode 100644 index 000000000..795a773a6 --- /dev/null +++ b/dist/assets/invite-cancel-arrow.3113613517f3605743e09e1016eec0d8.svg @@ -0,0 +1,11 @@ + + + + + + + + + diff --git a/dist/assets/invite.254774e653e2b009d11d79c0b07ae538.svg b/dist/assets/invite.254774e653e2b009d11d79c0b07ae538.svg new file mode 100644 index 000000000..3896e15e8 --- /dev/null +++ b/dist/assets/invite.254774e653e2b009d11d79c0b07ae538.svg @@ -0,0 +1,11 @@ + + + + + + + + + diff --git a/dist/assets/join-arrow.b158dd9a6d19e393ac5e419c8cec4949.svg b/dist/assets/join-arrow.b158dd9a6d19e393ac5e419c8cec4949.svg new file mode 100644 index 000000000..90cfa6517 --- /dev/null +++ b/dist/assets/join-arrow.b158dd9a6d19e393ac5e419c8cec4949.svg @@ -0,0 +1,8 @@ + + + + + + diff --git a/dist/assets/leave-arrow.a14d056eec03951908412ec70d2601b2.svg b/dist/assets/leave-arrow.a14d056eec03951908412ec70d2601b2.svg new file mode 100644 index 000000000..a51ac1d12 --- /dev/null +++ b/dist/assets/leave-arrow.a14d056eec03951908412ec70d2601b2.svg @@ -0,0 +1,8 @@ + + + + + + diff --git a/dist/assets/manifest.json b/dist/assets/manifest.json new file mode 100644 index 000000000..6c1e87140 --- /dev/null +++ b/dist/assets/manifest.json @@ -0,0 +1,59 @@ +{ + "name": "Cinny", + "short_name": "Cinny", + "description": "A matrix client", + "dir": "auto", + "lang": "en-US", + "display": "standalone", + "orientation": "any", + "start_url": "/?homescreen=1", + "background_color": "#fff", + "theme_color": "#fff", + "icons": [ + { + "src": "android-chrome-36x36.png", + "sizes": "36x36", + "type": "image/png" + }, + { + "src": "android-chrome-48x48.png", + "sizes": "48x48", + "type": "image/png" + }, + { + "src": "android-chrome-72x72.png", + "sizes": "72x72", + "type": "image/png" + }, + { + "src": "android-chrome-96x96.png", + "sizes": "96x96", + "type": "image/png" + }, + { + "src": "android-chrome-144x144.png", + "sizes": "144x144", + "type": "image/png" + }, + { + "src": "android-chrome-192x192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "android-chrome-256x256.png", + "sizes": "256x256", + "type": "image/png" + }, + { + "src": "android-chrome-384x384.png", + "sizes": "384x384", + "type": "image/png" + }, + { + "src": "android-chrome-512x512.png", + "sizes": "512x512", + "type": "image/png" + } + ] +} \ No newline at end of file diff --git a/dist/assets/manifest.webapp b/dist/assets/manifest.webapp new file mode 100644 index 000000000..c8840fad8 --- /dev/null +++ b/dist/assets/manifest.webapp @@ -0,0 +1,14 @@ +{ + "version": "1.0.0", + "name": "Cinny", + "description": "A matrix client", + "icons": { + "60": "firefox_app_60x60.png", + "128": "firefox_app_128x128.png", + "512": "firefox_app_512x512.png" + }, + "developer": { + "name": "ajbura, 1997kB", + "url": null + } +} \ No newline at end of file diff --git a/dist/assets/mstile-144x144.png b/dist/assets/mstile-144x144.png new file mode 100644 index 0000000000000000000000000000000000000000..8c8c2668b3259748889da147c356e654e3606e58 GIT binary patch literal 4499 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 literal 0 HcmV?d00001 diff --git a/dist/assets/mstile-310x150.png b/dist/assets/mstile-310x150.png new file mode 100644 index 0000000000000000000000000000000000000000..e81f250416e345c471e2ae9bc76366a6473aaa54 GIT binary patch literal 9582 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 literal 0 HcmV?d00001 diff --git a/dist/assets/mstile-310x310.png b/dist/assets/mstile-310x310.png new file mode 100644 index 0000000000000000000000000000000000000000..3b17552fe45d2ffea767493e9d7f7c00d0b103e6 GIT binary patch literal 10291 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 literal 0 HcmV?d00001 diff --git a/dist/assets/mstile-70x70.png b/dist/assets/mstile-70x70.png new file mode 100644 index 0000000000000000000000000000000000000000..89e2471eef231fae93567154db6c6bc5ebed4d72 GIT binary patch literal 2174 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 AkpKVy literal 0 HcmV?d00001 diff --git a/dist/assets/peace.6b673eb6c7ea027fdde9fd8262fda828.svg b/dist/assets/peace.6b673eb6c7ea027fdde9fd8262fda828.svg new file mode 100644 index 000000000..8a7c81a3c --- /dev/null +++ b/dist/assets/peace.6b673eb6c7ea027fdde9fd8262fda828.svg @@ -0,0 +1,9 @@ + + + + + + diff --git a/dist/assets/photo.7b243761b447ef50835e8a2455a1438c.svg b/dist/assets/photo.7b243761b447ef50835e8a2455a1438c.svg new file mode 100644 index 000000000..af01a3305 --- /dev/null +++ b/dist/assets/photo.7b243761b447ef50835e8a2455a1438c.svg @@ -0,0 +1,11 @@ + + + + + + + + + diff --git a/dist/assets/play.8838e717b724f8097895aae1dad87e92.svg b/dist/assets/play.8838e717b724f8097895aae1dad87e92.svg new file mode 100644 index 000000000..87b3a8f61 --- /dev/null +++ b/dist/assets/play.8838e717b724f8097895aae1dad87e92.svg @@ -0,0 +1,11 @@ + + + + + + + + + diff --git a/dist/assets/plus.6ba97826d509c8c6b7189fe492a504a9.svg b/dist/assets/plus.6ba97826d509c8c6b7189fe492a504a9.svg new file mode 100644 index 000000000..ce37594e8 --- /dev/null +++ b/dist/assets/plus.6ba97826d509c8c6b7189fe492a504a9.svg @@ -0,0 +1,7 @@ + + + + + + diff --git a/dist/assets/power.f0b0240b3ec31ce3f04f1aa7b175b02d.svg b/dist/assets/power.f0b0240b3ec31ce3f04f1aa7b175b02d.svg new file mode 100644 index 000000000..8aeb6db83 --- /dev/null +++ b/dist/assets/power.f0b0240b3ec31ce3f04f1aa7b175b02d.svg @@ -0,0 +1,11 @@ + + + + + + + + + diff --git a/dist/assets/reply-arrow.4652dfc3651a804bb60877d388196c95.svg b/dist/assets/reply-arrow.4652dfc3651a804bb60877d388196c95.svg new file mode 100644 index 000000000..3cda01cde --- /dev/null +++ b/dist/assets/reply-arrow.4652dfc3651a804bb60877d388196c95.svg @@ -0,0 +1,7 @@ + + + + + + diff --git a/dist/assets/search.062efbb79fafd84810e946829b5b6115.svg b/dist/assets/search.062efbb79fafd84810e946829b5b6115.svg new file mode 100644 index 000000000..75dd63207 --- /dev/null +++ b/dist/assets/search.062efbb79fafd84810e946829b5b6115.svg @@ -0,0 +1,8 @@ + + + + + + diff --git a/dist/assets/send.507da28d5579add6eccc11cba4870a69.svg b/dist/assets/send.507da28d5579add6eccc11cba4870a69.svg new file mode 100644 index 000000000..aa4871325 --- /dev/null +++ b/dist/assets/send.507da28d5579add6eccc11cba4870a69.svg @@ -0,0 +1,7 @@ + + + + + + diff --git a/dist/assets/settings.63c73133e69b9475120089774abfbaf1.svg b/dist/assets/settings.63c73133e69b9475120089774abfbaf1.svg new file mode 100644 index 000000000..ee640b393 --- /dev/null +++ b/dist/assets/settings.63c73133e69b9475120089774abfbaf1.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + diff --git a/dist/assets/shield.498420bdf2ec5957adc2646fa892026d.svg b/dist/assets/shield.498420bdf2ec5957adc2646fa892026d.svg new file mode 100644 index 000000000..9bb46fa10 --- /dev/null +++ b/dist/assets/shield.498420bdf2ec5957adc2646fa892026d.svg @@ -0,0 +1,10 @@ + + + + + + + + + diff --git a/dist/assets/space-lock.2efa7b53ab33a849560b10cddf5f2ad0.svg b/dist/assets/space-lock.2efa7b53ab33a849560b10cddf5f2ad0.svg new file mode 100644 index 000000000..b15705caa --- /dev/null +++ b/dist/assets/space-lock.2efa7b53ab33a849560b10cddf5f2ad0.svg @@ -0,0 +1,13 @@ + + + + + + + + + diff --git a/dist/assets/space.05c198da2fedc28c7a57d8c86a588e82.svg b/dist/assets/space.05c198da2fedc28c7a57d8c86a588e82.svg new file mode 100644 index 000000000..a4b54b3e7 --- /dev/null +++ b/dist/assets/space.05c198da2fedc28c7a57d8c86a588e82.svg @@ -0,0 +1,10 @@ + + + + + + diff --git a/dist/assets/tick-mark.9737a73dcc44eb0e793759bd547a71a0.svg b/dist/assets/tick-mark.9737a73dcc44eb0e793759bd547a71a0.svg new file mode 100644 index 000000000..8e76ed555 --- /dev/null +++ b/dist/assets/tick-mark.9737a73dcc44eb0e793759bd547a71a0.svg @@ -0,0 +1,11 @@ + + + + + + + + + + diff --git a/dist/assets/user.fb26a2eef540a21e7f9ffefd2321927b.svg b/dist/assets/user.fb26a2eef540a21e7f9ffefd2321927b.svg new file mode 100644 index 000000000..6756a1b2f --- /dev/null +++ b/dist/assets/user.fb26a2eef540a21e7f9ffefd2321927b.svg @@ -0,0 +1,10 @@ + + + + + + + + + diff --git a/dist/assets/vertical-menu.180cbca47512a24456ba0a74e64a5405.svg b/dist/assets/vertical-menu.180cbca47512a24456ba0a74e64a5405.svg new file mode 100644 index 000000000..ec5c544c8 --- /dev/null +++ b/dist/assets/vertical-menu.180cbca47512a24456ba0a74e64a5405.svg @@ -0,0 +1,11 @@ + + + + + + + + + + diff --git a/dist/assets/vlc.12ce0b57b1b136a0150c3c5f147ef08f.svg b/dist/assets/vlc.12ce0b57b1b136a0150c3c5f147ef08f.svg new file mode 100644 index 000000000..8a2b844f1 --- /dev/null +++ b/dist/assets/vlc.12ce0b57b1b136a0150c3c5f147ef08f.svg @@ -0,0 +1,8 @@ + + + + + + diff --git a/dist/assets/volume-full.a74609ebaadf79cabc7fee7590f52793.svg b/dist/assets/volume-full.a74609ebaadf79cabc7fee7590f52793.svg new file mode 100644 index 000000000..20419e728 --- /dev/null +++ b/dist/assets/volume-full.a74609ebaadf79cabc7fee7590f52793.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + diff --git a/dist/index.html b/dist/index.html new file mode 100644 index 000000000..9d7e23faf --- /dev/null +++ b/dist/index.html @@ -0,0 +1 @@ +Cinny
    \ No newline at end of file diff --git a/dist/main.7e67114cb989c8c9f008.bundle.css b/dist/main.7e67114cb989c8c9f008.bundle.css new file mode 100644 index 000000000..d549aee6f --- /dev/null +++ b/dist/main.7e67114cb989c8c9f008.bundle.css @@ -0,0 +1 @@ +@import url(https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,300;0,400;0,500;0,700;1,300;1,400;1,500;1,700&display=swap);:root{--bg-surface:#fff;--bg-surface-low:#f6f6f6;--bg-surface-hover:rgba(0,0,0,3%);--bg-surface-active:rgba(0,0,0,5%);--bg-surface-border:rgba(0,0,0,6%);--bg-primary:#536eea;--bg-primary-hover:rgba(83,110,234,80%);--bg-primary-active:rgba(83,110,234,70%);--bg-primary-border:rgba(83,110,234,38%);--bg-positive:#45b83b;--bg-caution:#ffb300;--bg-caution-hover:rgba(255,179,0,8%);--bg-caution-active:rgba(255,179,0,15%);--bg-caution-border:rgba(255,179,0,40%);--bg-danger:#f04747;--bg-danger-hover:rgba(240,71,71,5%);--bg-danger-active:rgba(240,71,71,10%);--bg-danger-border:rgba(240,71,71,20%);--bg-tooltip:#353535;--tc-surface-high:#000;--tc-surface-normal:rgba(0,0,0,68%);--tc-surface-low:rgba(0,0,0,38%);--tc-primary-high:#fff;--tc-primary-normal:rgba(255,255,255,68%);--tc-primary-low:rgba(255,255,255,40%);--tc-caution-high:var(--bg-caution);--tc-caution-normal:rgb(255,179,0,80%);--tc-caution-low:rgb(255,179,0,60%);--tc-danger-high:var(--bg-danger);--tc-danger-normal:rgba(240,71,71,88%);--tc-danger-low:rgba(240,71,71,60%);--tc-code:#e62498;--tc-tooltip:#fff;--ic-surface-normal:#626262;--ic-primary-normal:#fff;--ic-caution-normal:rgba(255,179,0,80%);--ic-danger-normal:rgba(240,71,71,0.7);--ic-large:38px;--ic-normal:24px;--ic-small:20px;--ic-extra-small:18px;--av-large:80px;--av-normal:42px;--av-small:36px;--av-extra-small:24px;--bg-overlay:rgba(0,0,0,20%);--bs-popup:0 0 16px rgba(0,0,0,10%);--bs-surface-border:inset 0 0 0 1px var(--bg-surface-border);--bs-surface-outline:0 0 0 2px var(--bg-surface-border);--bs-primary-border:inset 0 0 0 1px var(--bg-primary-border);--bs-primary-outline:0 0 0 2px var(--bg-primary-border);--bs-caution-border:inset 0 0 0 1px var(--bg-caution-border);--bs-caution-outline:0 0 0 2px var(--bg-caution-border);--bs-danger-border:inset 0 0 0 1px var(--bg-danger-border);--bs-danger-outline:0 0 0 2px var(--bg-danger-border);--bo-radius:8px;--fs-h1:36px;--ls-h1:-1.5px;--lh-h1:38px;--fs-h2:24px;--ls-h2:-0.5px;--lh-h2:30px;--fs-s1:18px;--ls-s1:-0.2px;--lh-s1:24px;--fs-b1:16px;--ls-b1:0.1px;--lh-b1:24px;--fs-b2:14px;--ls-b2:0.2px;--lh-b2:20px;--fs-b3:12px;--ls-b3:0px;--lh-b3:16px;--sp-none:0px;--sp-ultra-tight:4px;--sp-extra-tight:8px;--sp-tight:12px;--sp-normal:16px;--sp-loose:20px;--sp-extra-loose:32px;--border-width:1px;--header-height:54px;--navigation-sidebar-width:calc(64px + var(--border-width));--navigation-drawer-width:calc(280px + var(--border-width));--navigation-width:calc(var(--navigation-sidebar-width) + var(--navigation-drawer-width));--people-drawer-width:calc(268px - var(--border-width));--font-family:"Roboto","Supreme",sans-serif}.silver-theme{--bg-surface:#f2f2f2;--bg-surface-low:#e8e8e8}.butter-theme,.dark-theme{--bg-surface:#2f3337;--bg-surface-low:#26292c;--bg-surface-hover:rgba(255,255,255,3%);--bg-surface-active:rgba(255,255,255,5%);--bg-surface-border:rgba(0,0,0,20%);--bg-primary:#3b77bf;--bg-primary-hover:rgba(59,119,191,80%);--bg-primary-active:rgba(59,119,191,70%);--bg-primary-border:rgba(59,119,191,38%);--bg-tooltip:#000;--tc-surface-high:rgba(255,255,255,94%);--tc-surface-normal:rgba(255,255,255,74%);--tc-surface-low:rgba(255,255,255,38%);--tc-primary-high:#fff;--tc-primary-normal:hsla(0,0%,100%,0.68);--tc-primary-low:hsla(0,0%,100%,0.4);--tc-code:#e565b1;--ic-surface-normal:rgba(255,255,255,68%);--ic-primary-normal:#fff;--bg-overlay:rgba(0,0,0,50%);--bs-popup:0 0 16px rgba(0,0,0,25%);--bs-surface-border:inset 0 0 0 1px var(--bg-surface-border);--bs-surface-outline:0 0 0 2px var(--bg-surface-border);--bs-primary-border:inset 0 0 0 1px var(--bg-primary-border);--bs-primary-outline:0 0 0 2px var(--bg-primary-border);--font-family:"Supreme","Roboto",sans-serif}.butter-theme{--bg-surface:#262622;--bg-surface-low:#1b1b18;--tc-surface-high:rgb(255,251,222,94%);--tc-surface-normal:rgba(255,251,222,74%);--tc-surface-low:rgba(255,251,222,38%);--ic-surface-normal:rgb(255 251 222/68%)}body,html{height:100%}body{margin:0;padding:0;font-family:var(--font-family);font-size:16px;background-color:var(--bg-surface-low)}#root{width:100%;height:100%}*,:after,:before{box-sizing:border-box;-webkit-tap-highlight-color:rgba(0,0,0,0);-webkit-tap-highlight-color:transparent}a{color:var(--bg-primary);text-decoration:none}b{font-weight:500}button,label,textarea{margin:0;padding:0}button,textarea{background-color:transparent;font-family:inherit;font-size:inherit;font-weight:inherit;line-height:inherit;letter-spacing:inherit;border:none}button{max-width:100%;text-transform:none;text-align:inherit;overflow:visible;-webkit-appearance:button}textarea{color:inherit;word-spacing:inherit}.noselect{-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.flex,.flex--center,.flex--center-baseline,.flex--end,.flex--end-center,.flex--spaceBetween,.flex--spaceBetween-center,.inline-flex--center{display:flex}.flex-v,.flex-v--center,.flex-v--end{display:flex;flex-direction:column}.flex--center,.flex--center-baseline,.flex--end-center,.flex--spaceBetween-center,.inline-flex--center{justify-content:center;align-items:center}.flex--spaceBetween,.flex--spaceBetween-center{justify-content:space-between}.flex--end,.flex--end-center{justify-content:flex-end}.inline-flex--center{display:inline-flex}.flex--center-baseline{align-items:baseline}.flex-v--center{justify-content:center}.flex-v--end{justify-content:flex-end}.auth__wrapper{min-height:100vh;padding:var(--sp-loose);background-color:var(--bg-surface-low);background-image:url(https://images.unsplash.com/photo-1562619371-b67725b6fde2?auto=format&fit=crop&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&q=80&w=1950);background-size:cover;background-repeat:no-repeat;background-position:50%}.auth__wrapper .auth-card{width:462px;min-height:644px;background-color:var(--bg-surface-low);border-radius:var(--bo-radius);box-shadow:var(--bs-popup);overflow:hidden;display:flex;flex-flow:row nowrap}.auth__wrapper .auth-card__interactive{flex:1;min-width:0;padding:calc(var(--sp-normal) + var(--sp-extra-loose));padding-bottom:var(--sp-extra-loose);background-color:var(--bg-surface)}.app-ident{margin-bottom:var(--sp-extra-loose)}.app-ident__logo{width:60px;height:60px}.app-ident__text{margin-left:calc(var(--sp-loose) + var(--sp-ultra-tight))}.app-ident__text .text-s1{margin-top:var(--sp-tight);color:var(--tc-surface-normal)}[dir=rtl] .app-ident__text{margin-left:0;margin-right:calc(var(--sp-loose) + var(--sp-ultra-tight))}.auth-form>.text{margin-bottom:var(--sp-loose);margin-top:var(--sp-loose)}.auth-form>.input-container{margin-top:var(--sp-tight)}.auth-form .submit-btn__wrapper{margin-top:var(--sp-extra-loose);margin-bottom:var(--sp-loose);align-items:flex-start}.auth-form .submit-btn__wrapper>.error-message{display:none;flex:1;color:var(--tc-danger-normal);margin-right:var(--sp-normal);word-break:break}[dir=rtl] .auth-form .submit-btn__wrapper>.error-message{margin-right:0;margin-left:var(--sp-normal)}.auth-form__wrapper{height:100%}.username__wrapper{display:flex;align-items:flex-end}.username__wrapper>:first-child{flex:1}.username__wrapper>:first-child .input{border-radius:var(--bo-radius) 0 0 var(--bo-radius)}[dir=rtl] .username__wrapper>:first-child .input{border-radius:0 var(--bo-radius) var(--bo-radius) 0}.username__wrapper>:last-child{width:110px}.username__wrapper>:last-child .input{border-left-width:0;background-color:var(--bg-surface);border-radius:0 var(--bo-radius) var(--bo-radius) 0}[dir=rtl] .username__wrapper>:last-child .input{border-left-width:1px;border-right-width:0;border-radius:var(--bo-radius) 0 0 var(--bo-radius)}@media(max-width:462px){.auth__wrapper{padding:0;background-image:none;background-color:var(--bg-surface)}.auth__wrapper .auth-card{border-radius:0;box-shadow:none}.auth__wrapper .auth-card__interactive{padding:var(--sp-extra-loose)}}.process-wrapper{display:flex;flex-direction:column;justify-content:center;align-items:center;min-height:100%;width:100%;background-color:var(--bg-surface-low);opacity:.96;position:fixed;top:0;left:0;z-index:999}.text-b1,.text-b2,.text-b3,.text-h1,.text-h2,.text-s1{margin:0;padding:0;color:var(--tc-surface-high)}.text-h1{font-size:var(--fs-h1);font-weight:500;letter-spacing:var(--ls-h1);line-height:var(--lh-h1)}.text-h2{font-size:var(--fs-h2);font-weight:500;letter-spacing:var(--ls-h2);line-height:var(--lh-h2)}.text-s1{font-size:var(--fs-s1);font-weight:400;letter-spacing:var(--ls-s1);line-height:var(--lh-s1)}.text-b1{font-size:var(--fs-b1);letter-spacing:var(--ls-b1);line-height:var(--lh-b1)}.text-b1,.text-b2{font-weight:400;color:var(--tc-surface-normal)}.text-b2{font-size:var(--fs-b2);letter-spacing:var(--ls-b2);line-height:var(--lh-b2)}.text-b3{font-size:var(--fs-b3);font-weight:400;letter-spacing:var(--ls-b3);line-height:var(--lh-b3);color:var(--tc-surface-low)}.btn-caution,.btn-danger,.btn-primary,.btn-surface{display:inline-flex;align-items:center;justify-content:center;min-width:80px;padding:var(--sp-extra-tight) var(--sp-normal);background-color:transparent;border:none;border-radius:var(--bo-radius);cursor:pointer}.btn-caution:disabled,.btn-danger:disabled,.btn-primary:disabled,.btn-surface:disabled{opacity:.4;cursor:no-drop}.btn-caution--icon,.btn-danger--icon,.btn-primary--icon,.btn-surface--icon{padding-left:var(--sp-tight);padding-right:var(--sp-loose)}[dir=rtl] .btn-caution--icon,[dir=rtl] .btn-danger--icon,[dir=rtl] .btn-primary--icon,[dir=rtl] .btn-surface--icon{padding-left:var(--sp-loose);padding-right:var(--sp-tight)}.btn-caution--icon .ic-raw,.btn-danger--icon .ic-raw,.btn-primary--icon .ic-raw,.btn-surface--icon .ic-raw{margin-right:var(--sp-extra-tight)}[dir=rtl] .btn-caution--icon .ic-raw,[dir=rtl] .btn-danger--icon .ic-raw,[dir=rtl] .btn-primary--icon .ic-raw,[dir=rtl] .btn-surface--icon .ic-raw{margin-right:0;margin-left:var(--sp-extra-tight)}.btn-surface{box-shadow:var(--bs-surface-border)}.btn-surface .text{color:var(--tc-surface-high)}.btn-surface .ic-raw{background-color:var(--ic-surface-normal)}@media(hover:hover){.btn-surface:hover{background-color:var(--bg-surface-hover)}}.btn-surface:focus{outline:none;box-shadow:var(--bs-surface-outline)}.btn-surface:active{background-color:var(--bg-surface-active)!important}.btn-primary{background-color:var(--bg-primary)}.btn-primary .text{color:var(--tc-primary-high)}.btn-primary .ic-raw{background-color:var(--ic-primary-normal)}@media(hover:hover){.btn-primary:hover{background-color:var(--bg-primary-hover)}}.btn-primary:focus{outline:none;box-shadow:var(--bs-primary-outline)}.btn-primary:active{background-color:var(--bg-primary-active)!important}.btn-caution{box-shadow:var(--bs-caution-border)}.btn-caution .text{color:var(--tc-caution-high)}.btn-caution .ic-raw{background-color:var(--ic-caution-normal)}@media(hover:hover){.btn-caution:hover{background-color:var(--bg-caution-hover)}}.btn-caution:focus{outline:none;box-shadow:var(--bs-caution-outline)}.btn-caution:active{background-color:var(--bg-caution-active)!important}.btn-danger{box-shadow:var(--bs-danger-border)}.btn-danger .text{color:var(--tc-danger-high)}.btn-danger .ic-raw{background-color:var(--ic-danger-normal)}@media(hover:hover){.btn-danger:hover{background-color:var(--bg-danger-hover)}}.btn-danger:focus{outline:none;box-shadow:var(--bs-danger-outline)}.btn-danger:active{background-color:var(--bg-danger-active)!important}.ic-raw{display:inline-block;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:cover;mask-size:cover;background-color:var(--ic-surface-normal)}.ic-raw-large{width:var(--ic-large);height:var(--ic-large)}.ic-raw-normal{width:var(--ic-normal);height:var(--ic-normal)}.ic-raw-small{width:var(--ic-small);height:var(--ic-small)}.ic-raw-extra-small{width:var(--ic-extra-small);height:var(--ic-extra-small)}.input{display:block;width:100%;min-width:0;padding:var(--sp-tight) var(--sp-normal);background-color:var(--bg-surface-low);color:var(--tc-surface-normal);box-shadow:none;border-radius:var(--bo-radius);border:1px solid var(--bg-surface-border);font-size:var(--fs-b2);letter-spacing:var(--ls-b2);line-height:var(--lh-b2)}.input__label{display:inline-block;margin-bottom:var(--sp-ultra-tight);color:var(--tc-surface-low)}.input--resizable{resize:vertical!important}.input--success{border:1px solid var(--bg-positive);box-shadow:none!important}.input--error{border:1px solid var(--bg-danger);box-shadow:none!important}.input:focus{outline:none;box-shadow:var(--bs-primary-border)}.input::placeholder{color:var(--tc-surface-low)}.donut-spinner{display:inline-block;border:4px solid var(--bg-surface-border);border-left-color:var(--tc-surface-normal);border-radius:50%;animation:donut-spin 1.2s cubic-bezier(.73,.32,.67,.86) infinite}.donut-spinner--normal{width:40px;height:40px}.donut-spinner--small{width:28px;height:28px}@keyframes donut-spin{to{transform:rotate(1turn)}}.client-container{display:flex;height:100%}.navigation__wrapper{width:var(--navigation-width)}.channel__wrapper{flex:1;min-width:0;background-color:var(--bg-surface)}.loading-display{position:absolute;top:0;left:0;width:100vw;height:100vh;display:flex;flex-direction:column;justify-content:center;align-items:center}.loading__message{margin-top:var(--sp-normal)}.loading__appname{position:absolute;bottom:var(--sp-normal)}.navigation{width:100%;height:100%;background-color:var(--bg-surface-low);display:flex}.featured-container,.sidebar,.sidebar__flexBox,.space-container,.sticky-container{display:flex;flex-direction:column;justify-content:flex-start;align-items:center}.sidebar{width:var(--navigation-sidebar-width);height:100%;border-right:1px solid var(--bg-surface-border)}[dir=rtl] .sidebar{border-right:none;border-left:1px solid var(--bg-surface-border)}.sidebar__scrollable,.sidebar__sticky{width:100%}.sidebar__scrollable{flex:1;min-height:0}.sidebar__sticky{align-items:center}.scrollable-content:after{content:"";display:block;width:100%;height:8px;background:transparent;position:sticky;bottom:0;left:0}.featured-container,.space-container,.sticky-container{padding:var(--sp-ultra-tight) 0}.featured-container>.avatar-container,.featured-container>.sidebar-avatar,.space-container>.avatar-container,.space-container>.sidebar-avatar,.sticky-container>.avatar-container,.sticky-container>.sidebar-avatar{margin:calc(var(--sp-tight)/2) 0}.sidebar-divider{margin:auto;width:24px;height:1px;background-color:var(--bg-surface-border)}.firefox-scrollbar,.scrollbar,.scrollbar--auto-hide:hover{scrollbar-width:thin;scrollbar-color:var(--bg-surface-hover) transparent}.firefox-scrollbar--transparent,.scrollbar--auto-hide{scrollbar-color:transparent transparent}.scrollbar::-webkit-scrollbar,.webkit-scrollbar::-webkit-scrollbar{width:8px;height:8px}.scrollbar::-webkit-scrollbar-track,.webkit-scrollbar-track::-webkit-scrollbar-track{background-color:transparent}.scrollbar--auto-hide:hover::-webkit-scrollbar-thumb,.scrollbar::-webkit-scrollbar-thumb,.webkit-scrollbar-thumb::-webkit-scrollbar-thumb{background-color:var(--bg-surface-hover)}.scrollbar--auto-hide::-webkit-scrollbar-thumb:hover,.scrollbar::-webkit-scrollbar-thumb:hover,.webkit-scrollbar-thumb::-webkit-scrollbar-thumb:hover{background-color:var(--bg-surface-active)}.scrollbar--auto-hide::-webkit-scrollbar-thumb,.webkit-scrollbar-thumb--transparent::-webkit-scrollbar-thumb{background-color:transparent}.scrollbar{width:100%;height:100%;overflow:hidden}.scrollbar__h{overflow-x:scroll}.scrollbar__v{overflow-y:scroll}.scrollbar--invisible{-ms-overflow-style:none;scrollbar-width:none}.scrollbar--invisible::-webkit-scrollbar{display:none}.sidebar-avatar-tippy{padding:var(--sp-extra-tight) var(--sp-normal);background-color:var(--bg-tooltip);border-radius:var(--bo-radius);box-shadow:var(--bs-popup)}.sidebar-avatar-tippy .text{color:var(--tc-tooltip)}.sidebar-avatar{position:relative;display:flex;justify-content:center;align-items:center;width:100%;cursor:pointer}.sidebar-avatar .notification-badge{position:absolute;right:var(--sp-extra-tight);top:calc(var(--sp-ultra-tight)*-1);box-shadow:0 0 0 2px var(--bg-surface-low)}.sidebar-avatar:focus{outline:none}.sidebar-avatar:active .avatar-container{box-shadow:var(--bs-surface-outline)}.sidebar-avatar--active:before,.sidebar-avatar:focus:before,.sidebar-avatar:hover:before{content:"";display:block;position:absolute;left:0;top:50%;transform:translateY(-50%);width:3px;height:12px;background-color:var(--ic-surface-normal);border-radius:0 4px 4px 0;transition:height .2s linear}[dir=rtl] .sidebar-avatar--active:before,[dir=rtl] .sidebar-avatar:focus:before,[dir=rtl] .sidebar-avatar:hover:before{right:0;border-radius:4px 0 0 4px}.sidebar-avatar--active:before,.sidebar-avatar--active:focus:before,.sidebar-avatar--active:hover:before{height:28px}.sidebar-avatar--active .avatar-container{background-color:var(--bg-surface)}.avatar-container{display:inline-flex;width:42px;height:42px;border-radius:var(--bo-radius);position:relative}.avatar-container__large{width:var(--av-large);height:var(--av-large)}.avatar-container__normal{width:var(--av-normal);height:var(--av-normal)}.avatar-container__small{width:var(--av-small);height:var(--av-small)}.avatar-container__extra-small{width:var(--av-extra-small);height:var(--av-extra-small)}.avatar-container img{width:100%;height:100%;object-fit:cover;border-radius:inherit}.avatar-container .avatar__bordered{box-shadow:var(--bs-surface-border)}.avatar-container .avatar__border{position:absolute;top:0;left:0;width:100%;height:100%;border-radius:inherit}.avatar-container .avatar__border .text{color:var(--tc-primary-high)}.notification-badge{min-width:18px;padding:1px var(--sp-ultra-tight);background-color:var(--tc-surface-low);border-radius:9px}.notification-badge .text{color:var(--bg-surface-low);text-align:center}.notification-badge--alert{background-color:var(--bg-positive)}.notification-badge--alert .text{color:#fff}.context-menu{background-color:var(--bg-surface);box-shadow:var(--bs-popup);border-radius:var(--bo-radius);overflow:hidden}.context-menu:focus{outline:none}.context-menu .tippy-content>div>.scrollbar{max-height:90vh}.context-menu__click-wrapper{display:inline-flex}.context-menu__click-wrapper:focus{outline:none}.context-menu__header{height:34px;padding:0 var(--sp-tight);margin-bottom:var(--sp-ultra-tight);display:flex;align-items:center;border-bottom:1px solid var(--bg-surface-border)}.context-menu__header .text{color:var(--tc-surface-low)}.context-menu__header:not(:first-child){margin-top:var(--sp-normal);border-top:1px solid var(--bg-surface-border)}.context-menu__item button[class^=btn]{width:100%;justify-content:start;border-radius:0;box-shadow:none}.context-menu__item button[class^=btn] .text:first-child{margin-left:calc(var(--ic-small) + var(--sp-ultra-tight));margin-right:var(--sp-extra-tight)}[dir=rtl] .context-menu__item button[class^=btn] .text:first-child{margin-left:var(--sp-extra-tight);margin-right:calc(var(--ic-small) + var(--sp-ultra-tight))}.context-menu__item .btn-surface:focus{background-color:var(--bg-surface-hover)}.context-menu__item .btn-caution:focus{background-color:var(--bg-caution-hover)}.context-menu__item .btn-danger:focus{background-color:var(--bg-danger-hover)}.tippy-box[data-animation=scale-extreme][data-placement^=top]{transform-origin:bottom}.tippy-box[data-animation=scale-extreme][data-placement^=bottom]{transform-origin:top}.tippy-box[data-animation=scale-extreme][data-placement^=left]{transform-origin:right}.tippy-box[data-animation=scale-extreme][data-placement^=right]{transform-origin:left}.tippy-box[data-animation=scale-extreme][data-state=hidden]{transform:scale(0);opacity:.25}.drawer,.drawer-flexBox,.drawer__content-wrapper{display:flex;flex-direction:column}.channels__wrapper,.drawer,.drawer-flexItem,.drawer__content-wrapper{flex:1;min-height:0}.drawer{min-width:0;border-right:1px solid var(--bg-surface-border)}[dir=rtl] .drawer{border-right:none;border-left:1px solid var(--bg-surface-border)}.breadcrumb__wrapper{display:none;height:var(--header-height)}.channels-container{padding-bottom:var(--sp-extra-loose)}.channels-container>.channel-selector__button-wrapper:first-child{margin-top:var(--sp-extra-tight)}.channels-container .cat-header{margin:var(--sp-normal);margin-bottom:var(--sp-extra-tight);text-transform:uppercase;font-weight:600}.header{padding-left:var(--sp-normal);padding-right:var(--sp-extra-tight);width:100%;height:var(--header-height);border-bottom:1px solid var(--bg-surface-border);display:flex;align-items:center}[dir=rtl] .header{padding-left:var(--sp-extra-tight);padding-right:var(--sp-normal)}.header__title-wrapper{flex:1;min-width:0;display:flex;align-items:center;margin:0 var(--sp-tight)}.header__title-wrapper:first-child{margin-left:0}[dir=rtl] .header__title-wrapper:first-child{margin-right:0}.header__title-wrapper>.text:first-child{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.header__title-wrapper>.text-b3{flex:1;min-width:0;margin-top:var(--sp-ultra-tight);margin-left:var(--sp-tight);padding-left:var(--sp-tight);border-left:1px solid var(--bg-surface-border);max-height:calc(var(--lh-b3)*2);overflow:hidden;-webkit-box-orient:vertical;-webkit-line-clamp:2;display:-webkit-box}[dir=rtl] .header__title-wrapper>.text-b3{margin-left:0;padding-left:0;border-left:none;margin-right:var(--sp-tight);padding-right:var(--sp-tight);border-right:1px solid var(--bg-surface-border)}.ic-btn-caution,.ic-btn-danger,.ic-btn-primary,.ic-btn-surface{padding:var(--sp-extra-tight);border:none;border-radius:var(--bo-radius);background-color:transparent;font-size:0;line-height:0;cursor:pointer}.ic-btn-caution:disabled,.ic-btn-danger:disabled,.ic-btn-primary:disabled,.ic-btn-surface:disabled{opacity:.4;cursor:no-drop}.ic-btn-surface .ic-raw{background-color:var(--ic-surface-normal)}@media(hover:hover){.ic-btn-surface:hover{background-color:var(--bg-surface-hover)}}.ic-btn-surface:focus{outline:none;background-color:var(--bg-surface-hover)}.ic-btn-surface:active{background-color:var(--bg-surface-active)!important}.ic-btn-tippy{padding:var(--sp-extra-tight) var(--sp-normal);background-color:var(--bg-tooltip);border-radius:var(--bo-radius);box-shadow:var(--bs-popup)}.ic-btn-tippy .text{color:var(--tc-tooltip)}.channel-selector__button-wrapper{display:block;width:calc(100% - var(--sp-extra-tight));margin-left:auto;padding:var(--sp-extra-tight) var(--sp-extra-tight);border:1px solid transparent;border-radius:var(--bo-radius);cursor:pointer}[dir=rtl] .channel-selector__button-wrapper{margin-left:0;margin-right:auto}@media(hover:hover){.channel-selector__button-wrapper:hover{background-color:var(--bg-surface-hover)}}.channel-selector__button-wrapper:focus{outline:none;background-color:var(--bg-surface-hover)}.channel-selector__button-wrapper:active{background-color:var(--bg-surface-active)}.channel-selector{display:flex;align-items:center}.channel-selector__icon{width:24px;height:24px}.channel-selector__icon .avatar__border{box-shadow:none}.channel-selector__text-container{flex:1;min-width:0;margin:0 var(--sp-extra-tight)}.channel-selector__text-container .text{color:var(--tc-surface-normal);overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.channel-selector--unread{margin:0 var(--sp-ultra-tight);height:8px;width:8px;background-color:var(--tc-surface-low);border-radius:50%;opacity:.4}.channel-selector--selected{background-color:var(--bg-surface);border-color:var(--bg-surface-border)}.channel-container{display:flex;height:100%}.app-welcome{width:100%;height:100%}.app-welcome>div{max-width:600px;align-items:center}.app-welcome__logo{width:64px;height:64px}.app-welcome__heading{margin:var(--sp-extra-loose) 0 var(--sp-tight);color:var(--tc-surface-high)}.app-welcome__subheading{color:var(--tc-surface-normal)}.channel-view,.channel-view-flexBox,.channel-view__content-wrapper{display:flex;flex-direction:column}.channel-view,.channel-view-flexItem,.channel-view__content-wrapper,.channel-view__scrollable{flex:1;min-height:0;min-width:0}.channel-view__scrollable{position:relative}.channel-view__content{min-height:100%;display:flex;flex-direction:column;justify-content:flex-end}.channel-view__content .timeline__wrapper{--typing-noti-height:28px;min-height:0;min-width:0;padding-bottom:var(--typing-noti-height)}.channel-view__typing{display:flex;padding:var(--sp-ultra-tight) var(--sp-normal);background:var(--bg-surface);transition:transform .2s ease-in-out}.channel-view__typing b{color:var(--tc-surface-high)}.channel-view__typing--open{transform:translateY(-99%)}.channel-view__typing .text{flex:1;min-width:0;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;margin:0 var(--sp-tight)}.channel-view .bouncingLoader{transform:translateY(2px);margin:0 calc(var(--sp-ultra-tight)/2)}.channel-view .bouncingLoader:after,.channel-view .bouncingLoader:before,.channel-view .bouncingLoader>div{display:inline-block;width:8px;height:8px;background:var(--tc-surface-high);border-radius:50%;animation:bouncing-loader .6s infinite alternate}.channel-view .bouncingLoader:after,.channel-view .bouncingLoader:before{content:""}.channel-view .bouncingLoader>div{margin:0 4px;animation-delay:.2s}.channel-view .bouncingLoader:after{animation-delay:.4s}@keyframes bouncing-loader{to{opacity:.1;transform:translate3d(0,-4px,0)}}.channel-view__STB{position:absolute;right:var(--sp-normal);bottom:0;border-radius:var(--bo-radius);box-shadow:var(--bs-surface-border);background-color:var(--bg-surface-low);transition:transform .2s ease-in-out;transform:translateY(100%) scale(0)}[dir=rtl] .channel-view__STB{right:unset;left:var(--sp-normal)}.channel-view__STB--open{transform:translateY(-28px) scale(1)}.channel-view__sticky{min-height:85px;position:relative;background:var(--bg-surface);border-top:1px solid var(--bg-surface-border)}.channel-input{padding:var(--sp-extra-tight) calc(var(--sp-normal) - 2px);display:flex;min-height:48px}.channel-input__space{min-width:0;align-self:center;margin:auto;padding:0 var(--sp-tight)}.channel-input__input-container{flex:1;min-width:0;display:flex;align-items:center;margin:0 calc(var(--sp-tight) - 2px);background-color:var(--bg-surface-low);box-shadow:var(--bs-surface-border);border-radius:var(--bo-radius)}.channel-input__input-container>.ic-raw{transform:scale(.8);margin-left:var(--sp-extra-tight)}[dir=rtl] .channel-input__input-container>.ic-raw{margin-left:0;margin-right:var(--sp-extra-tight)}.channel-input__input-container .scrollbar{max-height:50vh}.channel-input__textarea-wrapper{min-height:40px;display:flex;align-items:center}.channel-input__textarea-wrapper textarea{resize:none;width:100%;min-width:0;min-height:100%;padding:var(--sp-ultra-tight) calc(var(--sp-tight) - 2px)}.channel-input__textarea-wrapper textarea::placeholder{color:var(--tc-surface-low)}.channel-input__textarea-wrapper textarea:focus{outline:none}.channel-cmd-bar{--cmd-bar-height:28px;min-height:var(--cmd-bar-height)}.channel-cmd-bar .timeline-change{justify-content:flex-end;padding:var(--sp-ultra-tight) var(--sp-normal)}.channel-cmd-bar .timeline-change__content{margin:0;flex:unset}.channel-cmd-bar .timeline-change__content>.text{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.channel-cmd-bar .timeline-change__content>.text b{color:var(--tc-surface-normal)}.channel-attachment{--side-spacing:calc(var(--sp-normal) + var(--av-small) + var(--sp-tight));display:flex;align-items:center;margin-left:var(--side-spacing);margin-top:var(--sp-extra-tight);line-height:0}[dir=rtl] .channel-attachment{margin-left:0;margin-right:var(--side-spacing)}.channel-attachment__preview>img{max-height:40px;border-radius:var(--bo-radius)}.channel-attachment__icon{padding:var(--sp-extra-tight);background-color:var(--bg-surface-low);box-shadow:var(--bs-surface-border);border-radius:var(--bo-radius)}.channel-attachment__info{flex:1;min-width:0;margin:0 var(--sp-tight)}.channel-attachment__option button{transition:transform .2s ease-in-out;transform:translateY(-48px)}.channel-attachment__option button .ic-raw{transition:transform .2s ease-in-out;transform:rotate(45deg);background-color:var(--bg-caution)}.divider{--local-divider-color:var(--bg-surface-border);margin:var(--sp-extra-tight) var(--sp-normal);margin-right:var(--sp-extra-tight);display:flex;align-items:center;position:relative}.divider:before{content:"";display:inline-block;flex:1;margin-left:calc(var(--av-small) + var(--sp-tight));border-bottom:1px solid var(--local-divider-color);opacity:.18}[dir=rtl] .divider:before{margin-left:0;margin-right:calc(var(--av-small) + var(--sp-tight))}.divider__text{margin-left:var(--sp-normal)}[dir=rtl] .divider{margin-left:var(--sp-extra-tight);margin-right:var(--sp-normal)}[dir=rtl] .divider__text{margin-left:0;margin-right:var(--sp-normal)}.divider--surface{--local-divider-color:var(--tc-surface-low)}.divider--surface .divider__text{color:var(--tc-surface-low)}.divider--primary{--local-divider-color:var(--bg-primary)}.divider--primary .divider__text{color:var(--bg-primary)}.divider--danger{--local-divider-color:var(--bg-danger)}.divider--danger .divider__text{color:var(--bg-danger)}.divider--caution{--local-divider-color:var(--bg-caution)}.divider--caution .divider__text{color:var(--bg-caution)}.firefox-scrollbar,.message code,.message code:hover{scrollbar-width:thin;scrollbar-color:var(--bg-surface-hover) transparent}.firefox-scrollbar--transparent,.message code{scrollbar-color:transparent transparent}.message code::-webkit-scrollbar,.webkit-scrollbar::-webkit-scrollbar{width:8px;height:8px}.message code::-webkit-scrollbar-track,.webkit-scrollbar-track::-webkit-scrollbar-track{background-color:transparent}.message code::-webkit-scrollbar-thumb,.message code:hover::-webkit-scrollbar-thumb,.webkit-scrollbar-thumb::-webkit-scrollbar-thumb{background-color:var(--bg-surface-hover)}.message code::-webkit-scrollbar-thumb:hover,.webkit-scrollbar-thumb::-webkit-scrollbar-thumb:hover{background-color:var(--bg-surface-active)}.message code::-webkit-scrollbar-thumb,.webkit-scrollbar-thumb--transparent::-webkit-scrollbar-thumb{background-color:transparent}.message,.ph-msg{padding:var(--sp-ultra-tight) var(--sp-normal);padding-right:var(--sp-extra-tight);display:flex}.message:hover,.ph-msg:hover{background-color:var(--bg-surface-hover)}[dir=rtl] .message,[dir=rtl] .ph-msg{padding-left:var(--sp-extra-tight);padding-right:var(--sp-normal)}.message__avatar-container,.ph-msg__avatar-container{padding-top:6px}.message__avatar-container,.message__profile,.ph-msg__avatar-container,.ph-msg__profile{margin-right:var(--sp-tight)}[dir=rtl] .message__avatar-container,[dir=rtl] .message__profile,[dir=rtl] .ph-msg__avatar-container,[dir=rtl] .ph-msg__profile{margin-left:var(--sp-tight);margin-right:0}.message__main-container,.ph-msg__main-container{flex:1;min-width:0}.message+.timeline-change,.message--content-only+.message--full,.message--full+.message--full,.timeline-change+.message{margin-top:var(--sp-normal)}.message__avatar-container{width:var(--av-small)}.message__reply-content .text{color:var(--tc-surface-low);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.message__reply-content .ic-raw{width:16px;height:14px}.message__edited{color:var(--tc-surface-low)}.message__reactions{margin-top:var(--sp-ultra-tight)}.ph-msg__avatar{width:var(--av-small);height:var(--av-small);background-color:var(--bg-surface-hover);border-radius:var(--bo-radius)}.ph-msg__content>div,.ph-msg__header{margin:var(--sp-ultra-tight) 0;margin-right:var(--sp-extra-tight);height:var(--fs-b1);width:100%;max-width:100px;background-color:var(--bg-surface-hover);border-radius:calc(var(--bo-radius)/2)}[dir=rtl] .ph-msg__content>div,[dir=rtl] .ph-msg__header{margin-right:0;margin-left:var(--sp-extra-tight)}.ph-msg__content{display:flex;flex-wrap:wrap}.ph-msg__content>div:nth-child(1n){max-width:10%}.ph-msg__content>div:nth-child(2n){max-width:50%}.message__header{display:flex;align-items:baseline}.message__header .message__profile{flex:1;min-width:0;color:var(--tc-surface-high)}.message__header .message__profile>.text{color:inherit;font-weight:500;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.message__header .message__time>.text{color:var(--tc-surface-low)}.message__content{max-width:640px;word-break:break-word}.message__content>.text>*{white-space:pre-wrap}.message__content a{word-break:break-all}.msg__reaction{--reaction-height:24px;--reaction-padding:6px;--reaction-radius:calc(var(--bo-radius)/2);display:inline-flex;align-items:center;color:var(--tc-surface-normal);border:1px solid var(--bg-surface-border);padding:0 var(--reaction-padding);border-radius:var(--reaction-radius);cursor:pointer;height:var(--reaction-height);margin-right:var(--sp-extra-tight)}[dir=rtl] .msg__reaction{margin-right:0;margin-left:var(--sp-extra-tight)}@media(hover:hover){.msg__reaction:hover{background-color:var(--bg-surface-hover)}}.msg__reaction:active{background-color:var(--bg-surface-active)}.msg__reaction--active{background-color:var(--bg-caution-active)}@media(hover:hover){.msg__reaction--active:hover{background-color:var(--bg-caution-hover)}}.msg__reaction--active:active{background-color:var(--bg-caution-active)}.message h1,.message h2{color:var(--tc-surface-high);margin:var(--sp-extra-loose) 0 var(--sp-normal);line-height:var(--lh-h1)}.message h3,.message h4{color:var(--tc-surface-high);margin:var(--sp-loose) 0 var(--sp-tight);line-height:var(--lh-h2)}.message h5,.message h6{color:var(--tc-surface-high);margin:var(--sp-normal) 0 var(--sp-extra-tight);line-height:var(--lh-s1)}.message hr{border-color:var(--bg-surface-border)}.message .text img{margin:var(--sp-ultra-tight) 0;max-width:296px;border-radius:calc(var(--bo-radius)/2)}.message blockquote,.message p,.message pre{margin:0;padding:0}.message blockquote,.message pre{margin:var(--sp-ultra-tight) 0;padding:var(--sp-extra-tight);background-color:var(--bg-surface-hover)!important;border-radius:calc(var(--bo-radius)/2)}.message pre div{margin:0!important}.message pre div,.message pre span{background:none!important}.message pre .linenumber{min-width:2.25em!important}.message code{padding:0!important;color:var(--tc-code)!important;white-space:pre-wrap;overflow:hidden;overflow-x:scroll}.message pre code{color:var(--tc-surface-normal)!important}.message blockquote{padding-left:var(--sp-extra-tight);border-left:4px solid var(--bg-surface-active);white-space:normal!important}.message blockquote>*{white-space:pre-wrap}[dir=rtl] .message blockquote{padding-left:0;padding-right:var(--sp-extra-tight);border-left:none;border-right:4px solid var(--bg-surface-active)}.message ol,.message ul{margin:var(--sp-ultra-tight) 0;padding-left:24px;white-space:normal!important}.message ol>*,.message ul>*{white-space:pre-wrap}[dir=rtl] .message ol,[dir=rtl] .message ul{padding-left:0;padding-right:24px}.file-header{display:flex;align-items:center;padding:var(--sp-ultra-tight) var(--sp-tight);min-height:42px}.file-header .file-name{flex:1;color:var(--tc-surface-low);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.file-container{--media-max-width:296px;background-color:var(--bg-surface-hover);border-radius:calc(var(--bo-radius)/2);overflow:hidden;max-width:var(--media-max-width);white-space:normal}.audio-container,.image-container,.video-container{font-size:0;line-height:0;display:flex;justify-content:center;align-items:center;background-position:50%;background-repeat:no-repeat;background-size:cover}.image-container img{max-width:unset!important;width:100%!important;border-radius:0!important;margin:0!important}.video-container .ic-btn-surface{background-color:var(--bg-surface-low)}.audio-container audio,.video-container video{width:100%}.timeline-change{padding:var(--sp-ultra-tight) var(--sp-normal);padding-right:var(--sp-extra-tight);display:flex;align-items:center}.timeline-change:hover{background-color:var(--bg-surface-hover)}[dir=rtl] .timeline-change{padding-left:var(--sp-extra-tight);padding-right:var(--sp-normal)}.timeline-change__avatar-container{width:var(--av-small);display:inline-flex;justify-content:center;align-items:center;opacity:.38}.timeline-change__avatar-container .ic-raw{background-color:var(--tc-surface-low)}.timeline-change .text{color:var(--tc-surface-low)}.timeline-change__content{flex:1;min-width:0;margin:0 var(--sp-tight)}.channel-intro{margin-top:calc(var(--sp-extra-loose)*2);margin-bottom:var(--sp-extra-loose);padding-left:calc(var(--sp-normal) + var(--av-small) + var(--sp-tight));padding-right:var(--sp-extra-tight)}[dir=rtl] .channel-intro{padding-left:var(--sp-extra-tight);padding-right:calc(var(--sp-normal) + var(--av-small) + var(--sp-tight))}.channel-intro .channel-intro__content{margin-top:var(--sp-extra-loose);max-width:640px}.channel-intro__name{color:var(--tc-surface-high)}.channel-intro__desc{color:var(--tc-surface-normal);margin:var(--sp-tight) 0 var(--sp-extra-tight)}.channel-intro__desc a{word-break:break-all}.channel-intro__time{color:var(--tc-surface-low)}.emoji-board-flexBoxV,.emoji-board__content,.emoji-board__nav{display:flex;flex-direction:column}.emoji-board-flexItem,.emoji-board__content,.emoji-board__emojis,.emoji-board__search .input-container{flex:1;min-height:0;min-width:0}.emoji-board{display:flex}.emoji-board__content{height:360px}.emoji-board__nav{padding:4px 6px;background-color:var(--bg-surface-low);border-left:1px solid var(--bg-surface-border)}[dir=rtl] .emoji-board__nav{border-left:none;border-right:1px solid var(--bg-surface-border)}.emoji-board__nav>.ic-btn-surface{margin:calc(var(--sp-ultra-tight)/2) 0}.emoji-board__search{display:flex;align-items:center;padding:calc(var(--sp-ultra-tight)/2) var(--sp-normal)}.emoji-board__search .input-container .input{min-width:100%;width:0;background-color:transparent;border:none!important;box-shadow:none!important}.emoji-group{--emoji-padding:6px;position:relative;margin-bottom:var(--sp-normal)}.emoji-group__header{position:sticky;top:0;z-index:99;background-color:var(--bg-surface);padding:var(--sp-tight) var(--sp-normal);text-transform:uppercase;font-weight:600}.emoji-group .emoji-set{margin:0 calc(var(--sp-normal) - var(--emoji-padding));margin-right:calc(var(--sp-extra-tight) - var(--emoji-padding))}[dir=rtl] .emoji-group .emoji-set{margin-right:calc(var(--sp-normal) - var(--emoji-padding));margin-left:calc(var(--sp-extra-tight) - var(--emoji-padding))}.emoji-group .emoji{width:38px;padding:var(--emoji-padding);cursor:pointer}.emoji-group .emoji:hover{background-color:var(--bg-surface-hover);border-radius:var(--bo-radius)}.people-drawer,.people-drawer-flexBox,.people-drawer__content-wrapper{display:flex;flex-direction:column}.people-drawer-flexItem,.people-drawer__content-wrapper,.people-drawer__scrollable{flex:1;min-height:0;min-width:0}.people-drawer{width:var(--people-drawer-width);background-color:var(--bg-surface-low);border-left:1px solid var(--bg-surface-border)}[dir=rtl] .people-drawer{border-left:none;border-right:1px solid var(--bg-surface-hover)}.people-drawer__member-count{color:var(--tc-surface-low)}.people-drawer__sticky{display:none}.people-drawer__sticky .people-search{min-height:48px;margin:0 var(--sp-normal);position:relative;bottom:var(--sp-normal)}.people-drawer__sticky .people-search .input{height:48px}.people-drawer__content{padding-top:var(--sp-extra-tight);padding-bottom:calc(var(--sp-extra-tight) + var(--sp-normal))}.people-drawer__load-more{padding:var(--sp-normal);padding-bottom:0;padding-right:var(--sp-extra-tight)}[dir=rtl] .people-drawer__load-more{padding-right:var(--sp-normal);padding-left:var(--sp-extra-tight)}.people-drawer__load-more .btn-surface{width:100%}.people-selector{width:100%;padding:var(--sp-extra-tight);padding-left:var(--sp-normal);display:flex;align-items:center;cursor:pointer}[dir=rtl] .people-selector{padding-left:var(--sp-extra-tight);padding-right:var(--sp-normal)}@media(hover:hover){.people-selector:hover{background-color:var(--bg-surface-hover)}}.people-selector:focus{outline:none;background-color:var(--bg-surface-hover)}.people-selector:active{background-color:var(--bg-surface-active)}.people-selector__name{flex:1;min-width:0;margin:0 var(--sp-tight);color:var(--tc-surface-normal);overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.people-selector__role{color:var(--tc-surface-low)}.invites-content{margin:0 var(--sp-normal);margin-right:var(--sp-extra-tight)}.invites-content__subheading{margin-top:var(--sp-extra-loose)}.invites-content__subheading .text{text-transform:uppercase;font-weight:600}.invites-content__subheading:first-child{margin-top:var(--sp-tight)}.invites-content .channel-tile{margin-top:var(--sp-normal)}.invites-content .channel-tile__options{align-self:flex-end}.invites-content .invite-btn__container .btn-surface{margin-right:var(--sp-normal)}[dir=rtl] .invites-content .invite-btn__container .btn-surface{margin-right:0;margin-left:var(--sp-normal)}[dir=rtl] .invites-content{margin-left:var(--sp-extra-tight);margin-right:var(--sp-normal)}.pw-model{--modal-height:656px;max-height:var(--modal-height)!important;height:100%}.pw{--popup-window-drawer-width:312px;width:100%;height:100%;background-color:var(--bg-surface);display:flex}.pw__drawer{width:var(--popup-window-drawer-width);background-color:var(--bg-surface-low);border-right:1px solid var(--bg-surface-border)}[dir=rtl] .pw__drawer{border-right:none;border-left:1px solid var(--bg-surface-border)}.pw__content{flex:1;min-width:0}.pw__content,.pw__drawer{display:flex;flex-direction:column}.pw__content-container,.pw__drawer__content{padding-top:var(--sp-extra-tight);padding-bottom:var(--sp-extra-loose)}.pw__content__wrapper,.pw__drawer__content__wrapper{flex:1;min-height:0}.pw__drawer .header{padding-left:var(--sp-extra-tight)}.pw__drawer .header .ic-btn-surface:first-child{margin-right:var(--sp-ultra-tight)}[dir=rtl] .pw__drawer .header{padding-right:var(--sp-extra-tight)}[dir=rtl] .pw__drawer .header .ic-btn-surface:first-child{margin-right:0;margin-left:var(--sp-ultra-tight)}.pw-content-selector--selected{border:1px solid var(--bg-surface-border);border-width:1px 0;background-color:var(--bg-surface)}.pw-content-selector--selected .context-menu__item>button:hover{background-color:transparent}.pw-content-selector .context-menu__item>button{padding-left:var(--sp-normal)}.pw-content-selector .context-menu__item>button .text{color:var(--tc-surface-normal)}.pw-content-selector .context-menu__item>button .ic-raw{margin-right:var(--sp-tight)}[dir=rtl] .pw-content-selector .context-menu__item>button{padding-right:var(--sp-normal)}[dir=rtl] .pw-content-selector .context-menu__item>button .ic-raw{margin-right:0;margin-left:var(--sp-tight)}.ReactModal__Overlay{opacity:0;transition:opacity .2s cubic-bezier(.13,.56,.25,.99)}.ReactModal__Overlay--after-open{opacity:1}.ReactModal__Overlay--before-close{opacity:0}.ReactModal__Content{transform:translateY(100%);transition:transform .2s cubic-bezier(.13,.56,.25,.99)}.ReactModal__Content--after-open{transform:translateY(0)}.ReactModal__Content--before-close{transform:translateY(100%)}.raw-modal{--small-modal-width:525px;--medium-modal-width:712px;--large-modal-width:1024px;width:100%;max-height:100%;border-radius:var(--bo-radius);box-shadow:var(--bs-popup);outline:none;overflow:hidden}.raw-modal__small{max-width:var(--small-modal-width)}.raw-modal__medium{max-width:var(--medium-modal-width)}.raw-modal__large{max-width:var(--large-modal-width)}.raw-modal__overlay{position:fixed;top:0;left:0;z-index:999;display:flex;justify-content:center;align-items:center;padding:var(--sp-normal);width:100%;height:100%;background-color:var(--bg-overlay)}.channel-tile{display:flex}.channel-tile__content{flex:1;min-width:0;margin:0 var(--sp-normal)}.channel-tile__content__desc{white-space:pre-wrap}.channel-tile__content__desc a{white-space:wrap}.channel-tile__content .text:not(:first-child){margin-top:var(--sp-ultra-tight)}.public-channels{margin:0 var(--sp-normal);margin-right:var(--sp-extra-tight);margin-top:var(--sp-extra-tight)}.public-channels__form{display:flex;align-items:flex-end}.public-channels__form .btn-primary{padding-top:11px;padding-bottom:11px}.public-channels__input-wrapper{flex:1;min-width:0;display:flex;margin-right:var(--sp-normal)}[dir=rtl] .public-channels__input-wrapper{margin-right:0;margin-left:var(--sp-normal)}.public-channels__input-wrapper>div:first-child{flex:1;min-width:0}.public-channels__input-wrapper>div:first-child .input{border-radius:var(--bo-radius) 0 0 var(--bo-radius)}[dir=rtl] .public-channels__input-wrapper>div:first-child .input{border-radius:0 var(--bo-radius) var(--bo-radius) 0}.public-channels__input-wrapper>div:last-child .input{width:120px;border-left-width:0;border-radius:0 var(--bo-radius) var(--bo-radius) 0}[dir=rtl] .public-channels__input-wrapper>div:last-child .input{border-left-width:1px;border-right-width:0;border-radius:var(--bo-radius) 0 0 var(--bo-radius)}.public-channels__search-status{margin-top:var(--sp-extra-loose);margin-bottom:var(--sp-tight)}.public-channels__search-status .donut-spinner{margin:0 var(--sp-tight)}.public-channels__search-error{color:var(--bg-danger)}.public-channels__content{border-top:1px solid var(--bg-surface-border)}.public-channels__view-more{margin-top:var(--sp-loose);margin-left:calc(var(--av-normal) + var(--sp-normal))}[dir=rtl] .public-channels__view-more{margin-left:0;margin-right:calc(var(--av-normal) + var(--sp-normal))}.public-channels .channel-tile{margin-top:var(--sp-normal)}.public-channels .channel-tile__options{align-self:flex-end}[dir=rtl] .public-channels{margin-left:var(--sp-extra-tight);margin-right:var(--sp-normal)}.create-channel{margin:0 var(--sp-normal);margin-right:var(--sp-extra-tight)}.create-channel__form>*{margin-top:var(--sp-normal)}.create-channel__form>:first-child{margin-top:var(--sp-extra-tight)}.create-channel__address{display:flex}.create-channel__address__label{color:var(--tc-surface-low);margin-bottom:var(--sp-ultra-tight)}.create-channel__address__tip{margin-left:46px;margin-top:var(--sp-ultra-tight)}[dir=rtl] .create-channel__address__tip{margin-left:0;margin-right:46px}.create-channel__address .text{display:flex;align-items:center;padding:0 var(--sp-normal);border:1px solid var(--bg-surface-border);border-radius:var(--bo-radius);color:var(--tc-surface-low)}.create-channel__address :nth-child(2){flex:1;min-width:0}.create-channel__address :nth-child(2) .input{border-radius:0}.create-channel__address .text:first-child{border-right-width:0;border-radius:var(--bo-radius) 0 0 var(--bo-radius)}.create-channel__address .text:last-child{border-left-width:0;border-radius:0 var(--bo-radius) var(--bo-radius) 0}[dir=rtl] .create-channel__address .text:first-child{border-left-width:0;border-right-width:1px;border-radius:0 var(--bo-radius) var(--bo-radius) 0}[dir=rtl] .create-channel__address .text:last-child{border-right-width:0;border-left-width:1px;border-radius:var(--bo-radius) 0 0 var(--bo-radius)}.create-channel__name-wrapper{display:flex;align-items:flex-end}.create-channel__name-wrapper .input-container{flex:1;min-width:0;margin-right:var(--sp-normal)}[dir=rtl] .create-channel__name-wrapper .input-container{margin-right:0;margin-left:var(--sp-normal)}.create-channel__name-wrapper .btn-primary{padding-top:11px;padding-bottom:11px}.create-channel__loading{display:flex;justify-content:center;align-items:center}.create-channel__loading .text{margin-left:var(--sp-normal)}[dir=rtl] .create-channel__loading .text{margin-left:0;margin-right:var(--sp-normal)}.create-channel__error{text-align:center;color:var(--bg-danger)!important}[dir=rtl] .create-channel{margin-right:var(--sp-normal);margin-left:var(--sp-extra-tight)}.toggle{width:44px;height:24px;padding:0 var(--sp-ultra-tight);display:flex;align-items:center;border-radius:var(--bo-radius);box-shadow:var(--bs-surface-border);cursor:pointer;background-color:var(--bg-surface-low);transition:background .2s ease-in-out}.toggle:before{content:"";display:inline-block;width:16px;height:16px;background-color:var(--tc-surface-low);border-radius:calc(var(--bo-radius)/2);transition:transform .2s ease-in-out,opacity .2s ease-in-out;opacity:.6}.toggle--active{background-color:var(--bg-positive)}.toggle--active:before{background-color:#fff;transform:translateX(125%);opacity:1}[dir=rtl] .toggle--active:before{transform:translateX(-125%)}.setting-tile__title__wrapper{display:flex;align-items:center}.setting-tile__title{flex:1;min-width:0;margin-right:var(--sp-normal)}[dir=rtl] .setting-tile__title{margin-right:0;margin-left:var(--sp-normal)}.invite-user{margin:0 var(--sp-normal);margin-right:var(--sp-extra-tight);margin-top:var(--sp-extra-tight)}.invite-user__form{display:flex;align-items:flex-end}.invite-user__form .input-container{flex:1;min-width:0;margin-right:var(--sp-normal)}[dir=rtl] .invite-user__form .input-container{margin-right:0;margin-left:var(--sp-normal)}.invite-user__form .btn-primary{padding-top:11px;padding-bottom:11px}.invite-user__search-status{margin-top:var(--sp-extra-loose);margin-bottom:var(--sp-tight)}.invite-user__search-status .donut-spinner{margin:0 var(--sp-tight)}.invite-user__search-error{color:var(--bg-danger)}.invite-user__content{border-top:1px solid var(--bg-surface-border)}.invite-user .channel-tile{margin-top:var(--sp-normal)}.invite-user .channel-tile__options{align-self:flex-end}[dir=rtl] .invite-user{margin-left:var(--sp-extra-tight);margin-right:var(--sp-normal)}.settings-window .pw__content-container{height:100%}.settings-content{margin:0 var(--sp-normal);margin-right:var(--sp-extra-tight);display:flex;flex-direction:column;height:100%}[dir=rtl] .settings-content{margin-left:var(--sp-extra-tight);margin-right:var(--sp-normal)}.settings__about{text-align:center}.segmented-controls{background-color:var(--bg-surface-low);border-radius:var(--bo-radius);border:1px solid var(--bg-surface-border);display:inline-flex;overflow:hidden}.segment-btn{padding:var(--sp-extra-tight) 0;cursor:pointer}@media(hover:hover){.segment-btn:hover{background-color:var(--bg-surface-hover)}}.segment-btn:active{background-color:var(--bg-surface-active)!important}.segment-btn__base{padding:0 var(--sp-normal);display:flex;align-items:center;justify-content:center;border-left:1px solid var(--bg-surface-border)}[dir=rtl] .segment-btn__base{border-left:none;border-right:1px solid var(--bg-surface-border)}.segment-btn__base .text:nth-child(2){margin:0 var(--sp-extra-tight)}.segment-btn:first-child .segment-btn__base{border:none}.segment-btn--active{background-color:var(--bg-surface);border:1px solid var(--bg-surface-border);border-width:0 1px}.segment-btn--active+.segment-btn .segment-btn__base,.segment-btn--active .segment-btn__base{border:none}.segment-btn--active:first-child{border-left:none}.segment-btn--active:last-child{border-right:none}[dir=rtl] .segment-btn--active{border-left:1px solid var(--bg-surface-border);border-right:1px solid var(--bg-surface-border)}[dir=rtl] .segment-btn--active:first-child{border-right:none}[dir=rtl] .segment-btn--active:last-child{border-left:none} \ No newline at end of file diff --git a/dist/main.b16695b6316dfd5b68d4.bundle.js b/dist/main.b16695b6316dfd5b68d4.bundle.js new file mode 100644 index 000000000..09b1de102 --- /dev/null +++ b/dist/main.b16695b6316dfd5b68d4.bundle.js @@ -0,0 +1,2 @@ +/*! For license information please see main.b16695b6316dfd5b68d4.bundle.js.LICENSE.txt */ +(()=>{var e={59713:e=>{e.exports=function(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e},e.exports.default=e.exports,e.exports.__esModule=!0},95318:e=>{e.exports=function(e){return e&&e.__esModule?e:{default:e}},e.exports.default=e.exports,e.exports.__esModule=!0},20862:(e,t,n)=>{var o=n(50008).default;function r(){if("function"!=typeof WeakMap)return null;var e=new WeakMap;return r=function(){return e},e}e.exports=function(e){if(e&&e.__esModule)return e;if(null===e||"object"!==o(e)&&"function"!=typeof e)return{default:e};var t=r();if(t&&t.has(e))return t.get(e);var n={},i=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in e)if(Object.prototype.hasOwnProperty.call(e,a)){var s=i?Object.getOwnPropertyDescriptor(e,a):null;s&&(s.get||s.set)?Object.defineProperty(n,a,s):n[a]=e[a]}return n.default=e,t&&t.set(e,n),n},e.exports.default=e.exports,e.exports.__esModule=!0},50008:e=>{function t(n){return"function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?(e.exports=t=function(e){return typeof e},e.exports.default=e.exports,e.exports.__esModule=!0):(e.exports=t=function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},e.exports.default=e.exports,e.exports.__esModule=!0),t(n)}e.exports=t,e.exports.default=e.exports,e.exports.__esModule=!0},18508:e=>{function t(e){this._db=e,this._operations=[],this._written=!1}t.prototype._checkWritten=function(){if(this._written)throw new Error("write() already called on this batch")},t.prototype.put=function(e,t){this._checkWritten();var n=this._db._checkKeyValue(e,"key",this._db._isBuffer);if(n)throw n;if(n=this._db._checkKeyValue(t,"value",this._db._isBuffer))throw n;return this._db._isBuffer(e)||(e=String(e)),this._db._isBuffer(t)||(t=String(t)),"function"==typeof this._put?this._put(e,t):this._operations.push({type:"put",key:e,value:t}),this},t.prototype.del=function(e){this._checkWritten();var t=this._db._checkKeyValue(e,"key",this._db._isBuffer);if(t)throw t;return this._db._isBuffer(e)||(e=String(e)),"function"==typeof this._del?this._del(e):this._operations.push({type:"del",key:e}),this},t.prototype.clear=function(){return this._checkWritten(),this._operations=[],"function"==typeof this._clear&&this._clear(),this},t.prototype.write=function(e,t){if(this._checkWritten(),"function"==typeof e&&(t=e),"function"!=typeof t)throw new Error("write() requires a callback argument");return"object"!=typeof e&&(e={}),this._written=!0,"function"==typeof this._write?this._write(t):"function"==typeof this._db._batch?this._db._batch(this._operations,e,t):void process.nextTick(t)},e.exports=t},43538:e=>{function t(e){this.db=e,this._ended=!1,this._nexting=!1}t.prototype.next=function(e){var t=this;if("function"!=typeof e)throw new Error("next() requires a callback argument");return t._ended?e(new Error("cannot call next() after end()")):t._nexting?e(new Error("cannot call next() before previous next() has completed")):(t._nexting=!0,"function"==typeof t._next?t._next((function(){t._nexting=!1,e.apply(null,arguments)})):void process.nextTick((function(){t._nexting=!1,e()})))},t.prototype.end=function(e){if("function"!=typeof e)throw new Error("end() requires a callback argument");return this._ended?e(new Error("end() already called on iterator")):(this._ended=!0,"function"==typeof this._end?this._end(e):void process.nextTick(e))},e.exports=t},32554:(e,t,n)=>{var o=n(77915),r=n(43538),i=n(18508);function a(e){if(!arguments.length||void 0===e)throw new Error("constructor requires at least a location argument");if("string"!=typeof e)throw new Error("constructor requires a location string argument");this.location=e}a.prototype.open=function(e,t){if("function"==typeof e&&(t=e),"function"!=typeof t)throw new Error("open() requires a callback argument");if("object"!=typeof e&&(e={}),"function"==typeof this._open)return this._open(e,t);process.nextTick(t)},a.prototype.close=function(e){if("function"!=typeof e)throw new Error("close() requires a callback argument");if("function"==typeof this._close)return this._close(e);process.nextTick(e)},a.prototype.get=function(e,t,n){var o;if("function"==typeof t&&(n=t),"function"!=typeof n)throw new Error("get() requires a callback argument");return(o=this._checkKeyValue(e,"key",this._isBuffer))?n(o):(this._isBuffer(e)||(e=String(e)),"object"!=typeof t&&(t={}),"function"==typeof this._get?this._get(e,t,n):void process.nextTick((function(){n(new Error("NotFound"))})))},a.prototype.put=function(e,t,n,o){var r;if("function"==typeof n&&(o=n),"function"!=typeof o)throw new Error("put() requires a callback argument");return(r=this._checkKeyValue(e,"key",this._isBuffer))||(r=this._checkKeyValue(t,"value",this._isBuffer))?o(r):(this._isBuffer(e)||(e=String(e)),this._isBuffer(t)||process.browser||(t=String(t)),"object"!=typeof n&&(n={}),"function"==typeof this._put?this._put(e,t,n,o):void process.nextTick(o))},a.prototype.del=function(e,t,n){var o;if("function"==typeof t&&(n=t),"function"!=typeof n)throw new Error("del() requires a callback argument");return(o=this._checkKeyValue(e,"key",this._isBuffer))?n(o):(this._isBuffer(e)||(e=String(e)),"object"!=typeof t&&(t={}),"function"==typeof this._del?this._del(e,t,n):void process.nextTick(n))},a.prototype.batch=function(e,t,n){if(!arguments.length)return this._chainedBatch();if("function"==typeof t&&(n=t),"function"!=typeof n)throw new Error("batch(array) requires a callback argument");if(!Array.isArray(e))return n(new Error("batch(array) requires an array argument"));"object"!=typeof t&&(t={});for(var o,r,i=0,a=e.length;i{e.exports=function(){for(var e={},t=0;t{"use strict";for(var t=/[\\\"\x00-\x1F]/g,n={},o=0;o<32;++o)n[String.fromCharCode(o)]="\\U"+("0000"+o.toString(16)).slice(-4).toUpperCase();function r(e){return t.lastIndex=0,e.replace(t,(function(e){return n[e]}))}n["\b"]="\\b",n["\t"]="\\t",n["\n"]="\\n",n["\f"]="\\f",n["\r"]="\\r",n['"']='\\"',n["\\"]="\\\\",e.exports={stringify:function e(t){switch(typeof t){case"string":return'"'+r(t)+'"';case"number":return isFinite(t)?t:"null";case"boolean":return t;case"object":return null===t?"null":Array.isArray(t)?function(t){for(var n="[",o="",r=0;r{e.exports=function(e,n,o){if(e.filter)return e.filter(n,o);if(null==e)throw new TypeError;if("function"!=typeof n)throw new TypeError;for(var r=[],i=0;i{"use strict";const o=t;o.bignum=n(4590),o.define=n(22500).define,o.base=n(71979),o.constants=n(36826),o.decoders=n(78307),o.encoders=n(56579)},22500:(e,t,n)=>{"use strict";const o=n(56579),r=n(78307),i=n(35717);function a(e,t){this.name=e,this.body=t,this.decoders={},this.encoders={}}t.define=function(e,t){return new a(e,t)},a.prototype._createNamed=function(e){const t=this.name;function n(e){this._initNamed(e,t)}return i(n,e),n.prototype._initNamed=function(t,n){e.call(this,t,n)},new n(this)},a.prototype._getDecoder=function(e){return e=e||"der",this.decoders.hasOwnProperty(e)||(this.decoders[e]=this._createNamed(r[e])),this.decoders[e]},a.prototype.decode=function(e,t,n){return this._getDecoder(t).decode(e,n)},a.prototype._getEncoder=function(e){return e=e||"der",this.encoders.hasOwnProperty(e)||(this.encoders[e]=this._createNamed(o[e])),this.encoders[e]},a.prototype.encode=function(e,t,n){return this._getEncoder(t).encode(e,n)}},36625:(e,t,n)=>{"use strict";const o=n(35717),r=n(98465).b,i=n(2399).Buffer;function a(e,t){r.call(this,t),i.isBuffer(e)?(this.base=e,this.offset=0,this.length=e.length):this.error("Input not Buffer")}function s(e,t){if(Array.isArray(e))this.length=0,this.value=e.map((function(e){return s.isEncoderBuffer(e)||(e=new s(e,t)),this.length+=e.length,e}),this);else if("number"==typeof e){if(!(0<=e&&e<=255))return t.error("non-byte EncoderBuffer value");this.value=e,this.length=1}else if("string"==typeof e)this.value=e,this.length=i.byteLength(e);else{if(!i.isBuffer(e))return t.error("Unsupported type: "+typeof e);this.value=e,this.length=e.length}}o(a,r),t.C=a,a.isDecoderBuffer=function(e){return e instanceof a||"object"==typeof e&&i.isBuffer(e.base)&&"DecoderBuffer"===e.constructor.name&&"number"==typeof e.offset&&"number"==typeof e.length&&"function"==typeof e.save&&"function"==typeof e.restore&&"function"==typeof e.isEmpty&&"function"==typeof e.readUInt8&&"function"==typeof e.skip&&"function"==typeof e.raw},a.prototype.save=function(){return{offset:this.offset,reporter:r.prototype.save.call(this)}},a.prototype.restore=function(e){const t=new a(this.base);return t.offset=e.offset,t.length=this.offset,this.offset=e.offset,r.prototype.restore.call(this,e.reporter),t},a.prototype.isEmpty=function(){return this.offset===this.length},a.prototype.readUInt8=function(e){return this.offset+1<=this.length?this.base.readUInt8(this.offset++,!0):this.error(e||"DecoderBuffer overrun")},a.prototype.skip=function(e,t){if(!(this.offset+e<=this.length))return this.error(t||"DecoderBuffer overrun");const n=new a(this.base);return n._reporterState=this._reporterState,n.offset=this.offset,n.length=this.offset+e,this.offset+=e,n},a.prototype.raw=function(e){return this.base.slice(e?e.offset:this.offset,this.length)},t.R=s,s.isEncoderBuffer=function(e){return e instanceof s||"object"==typeof e&&"EncoderBuffer"===e.constructor.name&&"number"==typeof e.length&&"function"==typeof e.join},s.prototype.join=function(e,t){return e||(e=i.alloc(this.length)),t||(t=0),0===this.length||(Array.isArray(this.value)?this.value.forEach((function(n){n.join(e,t),t+=n.length})):("number"==typeof this.value?e[t]=this.value:"string"==typeof this.value?e.write(this.value,t):i.isBuffer(this.value)&&this.value.copy(e,t),t+=this.length)),e}},71979:(e,t,n)=>{"use strict";const o=t;o.Reporter=n(98465).b,o.DecoderBuffer=n(36625).C,o.EncoderBuffer=n(36625).R,o.Node=n(41949)},41949:(e,t,n)=>{"use strict";const o=n(98465).b,r=n(36625).R,i=n(36625).C,a=n(79746),s=["seq","seqof","set","setof","objid","bool","gentime","utctime","null_","enum","int","objDesc","bitstr","bmpstr","charstr","genstr","graphstr","ia5str","iso646str","numstr","octstr","printstr","t61str","unistr","utf8str","videostr"],u=["key","obj","use","optional","explicit","implicit","def","choice","any","contains"].concat(s);function c(e,t,n){const o={};this._baseState=o,o.name=n,o.enc=e,o.parent=t||null,o.children=null,o.tag=null,o.args=null,o.reverseArgs=null,o.choice=null,o.optional=!1,o.any=!1,o.obj=!1,o.use=null,o.useDecoder=null,o.key=null,o.default=null,o.explicit=null,o.implicit=null,o.contains=null,o.parent||(o.children=[],this._wrap())}e.exports=c;const l=["enc","parent","children","tag","args","reverseArgs","choice","optional","any","obj","use","alteredUse","key","default","explicit","implicit","contains"];c.prototype.clone=function(){const e=this._baseState,t={};l.forEach((function(n){t[n]=e[n]}));const n=new this.constructor(t.parent);return n._baseState=t,n},c.prototype._wrap=function(){const e=this._baseState;u.forEach((function(t){this[t]=function(){const n=new this.constructor(this);return e.children.push(n),n[t].apply(n,arguments)}}),this)},c.prototype._init=function(e){const t=this._baseState;a(null===t.parent),e.call(this),t.children=t.children.filter((function(e){return e._baseState.parent===this}),this),a.equal(t.children.length,1,"Root node can have only one child")},c.prototype._useArgs=function(e){const t=this._baseState,n=e.filter((function(e){return e instanceof this.constructor}),this);e=e.filter((function(e){return!(e instanceof this.constructor)}),this),0!==n.length&&(a(null===t.children),t.children=n,n.forEach((function(e){e._baseState.parent=this}),this)),0!==e.length&&(a(null===t.args),t.args=e,t.reverseArgs=e.map((function(e){if("object"!=typeof e||e.constructor!==Object)return e;const t={};return Object.keys(e).forEach((function(n){n==(0|n)&&(n|=0);const o=e[n];t[o]=n})),t})))},["_peekTag","_decodeTag","_use","_decodeStr","_decodeObjid","_decodeTime","_decodeNull","_decodeInt","_decodeBool","_decodeList","_encodeComposite","_encodeStr","_encodeObjid","_encodeTime","_encodeNull","_encodeInt","_encodeBool"].forEach((function(e){c.prototype[e]=function(){const t=this._baseState;throw new Error(e+" not implemented for encoding: "+t.enc)}})),s.forEach((function(e){c.prototype[e]=function(){const t=this._baseState,n=Array.prototype.slice.call(arguments);return a(null===t.tag),t.tag=e,this._useArgs(n),this}})),c.prototype.use=function(e){a(e);const t=this._baseState;return a(null===t.use),t.use=e,this},c.prototype.optional=function(){return this._baseState.optional=!0,this},c.prototype.def=function(e){const t=this._baseState;return a(null===t.default),t.default=e,t.optional=!0,this},c.prototype.explicit=function(e){const t=this._baseState;return a(null===t.explicit&&null===t.implicit),t.explicit=e,this},c.prototype.implicit=function(e){const t=this._baseState;return a(null===t.explicit&&null===t.implicit),t.implicit=e,this},c.prototype.obj=function(){const e=this._baseState,t=Array.prototype.slice.call(arguments);return e.obj=!0,0!==t.length&&this._useArgs(t),this},c.prototype.key=function(e){const t=this._baseState;return a(null===t.key),t.key=e,this},c.prototype.any=function(){return this._baseState.any=!0,this},c.prototype.choice=function(e){const t=this._baseState;return a(null===t.choice),t.choice=e,this._useArgs(Object.keys(e).map((function(t){return e[t]}))),this},c.prototype.contains=function(e){const t=this._baseState;return a(null===t.use),t.contains=e,this},c.prototype._decode=function(e,t){const n=this._baseState;if(null===n.parent)return e.wrapResult(n.children[0]._decode(e,t));let o,r=n.default,a=!0,s=null;if(null!==n.key&&(s=e.enterKey(n.key)),n.optional){let o=null;if(null!==n.explicit?o=n.explicit:null!==n.implicit?o=n.implicit:null!==n.tag&&(o=n.tag),null!==o||n.any){if(a=this._peekTag(e,o,n.any),e.isError(a))return a}else{const o=e.save();try{null===n.choice?this._decodeGeneric(n.tag,e,t):this._decodeChoice(e,t),a=!0}catch(e){a=!1}e.restore(o)}}if(n.obj&&a&&(o=e.enterObject()),a){if(null!==n.explicit){const t=this._decodeTag(e,n.explicit);if(e.isError(t))return t;e=t}const o=e.offset;if(null===n.use&&null===n.choice){let t;n.any&&(t=e.save());const o=this._decodeTag(e,null!==n.implicit?n.implicit:n.tag,n.any);if(e.isError(o))return o;n.any?r=e.raw(t):e=o}if(t&&t.track&&null!==n.tag&&t.track(e.path(),o,e.length,"tagged"),t&&t.track&&null!==n.tag&&t.track(e.path(),e.offset,e.length,"content"),n.any||(r=null===n.choice?this._decodeGeneric(n.tag,e,t):this._decodeChoice(e,t)),e.isError(r))return r;if(n.any||null!==n.choice||null===n.children||n.children.forEach((function(n){n._decode(e,t)})),n.contains&&("octstr"===n.tag||"bitstr"===n.tag)){const o=new i(r);r=this._getUse(n.contains,e._reporterState.obj)._decode(o,t)}}return n.obj&&a&&(r=e.leaveObject(o)),null===n.key||null===r&&!0!==a?null!==s&&e.exitKey(s):e.leaveKey(s,n.key,r),r},c.prototype._decodeGeneric=function(e,t,n){const o=this._baseState;return"seq"===e||"set"===e?null:"seqof"===e||"setof"===e?this._decodeList(t,e,o.args[0],n):/str$/.test(e)?this._decodeStr(t,e,n):"objid"===e&&o.args?this._decodeObjid(t,o.args[0],o.args[1],n):"objid"===e?this._decodeObjid(t,null,null,n):"gentime"===e||"utctime"===e?this._decodeTime(t,e,n):"null_"===e?this._decodeNull(t,n):"bool"===e?this._decodeBool(t,n):"objDesc"===e?this._decodeStr(t,e,n):"int"===e||"enum"===e?this._decodeInt(t,o.args&&o.args[0],n):null!==o.use?this._getUse(o.use,t._reporterState.obj)._decode(t,n):t.error("unknown tag: "+e)},c.prototype._getUse=function(e,t){const n=this._baseState;return n.useDecoder=this._use(e,t),a(null===n.useDecoder._baseState.parent),n.useDecoder=n.useDecoder._baseState.children[0],n.implicit!==n.useDecoder._baseState.implicit&&(n.useDecoder=n.useDecoder.clone(),n.useDecoder._baseState.implicit=n.implicit),n.useDecoder},c.prototype._decodeChoice=function(e,t){const n=this._baseState;let o=null,r=!1;return Object.keys(n.choice).some((function(i){const a=e.save(),s=n.choice[i];try{const n=s._decode(e,t);if(e.isError(n))return!1;o={type:i,value:n},r=!0}catch(t){return e.restore(a),!1}return!0}),this),r?o:e.error("Choice not matched")},c.prototype._createEncoderBuffer=function(e){return new r(e,this.reporter)},c.prototype._encode=function(e,t,n){const o=this._baseState;if(null!==o.default&&o.default===e)return;const r=this._encodeValue(e,t,n);return void 0===r||this._skipDefault(r,t,n)?void 0:r},c.prototype._encodeValue=function(e,t,n){const r=this._baseState;if(null===r.parent)return r.children[0]._encode(e,t||new o);let i=null;if(this.reporter=t,r.optional&&void 0===e){if(null===r.default)return;e=r.default}let a=null,s=!1;if(r.any)i=this._createEncoderBuffer(e);else if(r.choice)i=this._encodeChoice(e,t);else if(r.contains)a=this._getUse(r.contains,n)._encode(e,t),s=!0;else if(r.children)a=r.children.map((function(n){if("null_"===n._baseState.tag)return n._encode(null,t,e);if(null===n._baseState.key)return t.error("Child should have a key");const o=t.enterKey(n._baseState.key);if("object"!=typeof e)return t.error("Child expected, but input is not object");const r=n._encode(e[n._baseState.key],t,e);return t.leaveKey(o),r}),this).filter((function(e){return e})),a=this._createEncoderBuffer(a);else if("seqof"===r.tag||"setof"===r.tag){if(!r.args||1!==r.args.length)return t.error("Too many args for : "+r.tag);if(!Array.isArray(e))return t.error("seqof/setof, but data is not Array");const n=this.clone();n._baseState.implicit=null,a=this._createEncoderBuffer(e.map((function(n){const o=this._baseState;return this._getUse(o.args[0],e)._encode(n,t)}),n))}else null!==r.use?i=this._getUse(r.use,n)._encode(e,t):(a=this._encodePrimitive(r.tag,e),s=!0);if(!r.any&&null===r.choice){const e=null!==r.implicit?r.implicit:r.tag,n=null===r.implicit?"universal":"context";null===e?null===r.use&&t.error("Tag could be omitted only for .use()"):null===r.use&&(i=this._encodeComposite(e,s,n,a))}return null!==r.explicit&&(i=this._encodeComposite(r.explicit,!1,"context",i)),i},c.prototype._encodeChoice=function(e,t){const n=this._baseState,o=n.choice[e.type];return o||a(!1,e.type+" not found in "+JSON.stringify(Object.keys(n.choice))),o._encode(e.value,t)},c.prototype._encodePrimitive=function(e,t){const n=this._baseState;if(/str$/.test(e))return this._encodeStr(t,e);if("objid"===e&&n.args)return this._encodeObjid(t,n.reverseArgs[0],n.args[1]);if("objid"===e)return this._encodeObjid(t,null,null);if("gentime"===e||"utctime"===e)return this._encodeTime(t,e);if("null_"===e)return this._encodeNull();if("int"===e||"enum"===e)return this._encodeInt(t,n.args&&n.reverseArgs[0]);if("bool"===e)return this._encodeBool(t);if("objDesc"===e)return this._encodeStr(t,e);throw new Error("Unsupported tag: "+e)},c.prototype._isNumstr=function(e){return/^[0-9 ]*$/.test(e)},c.prototype._isPrintstr=function(e){return/^[A-Za-z0-9 '()+,-./:=?]*$/.test(e)}},98465:(e,t,n)=>{"use strict";const o=n(35717);function r(e){this._reporterState={obj:null,path:[],options:e||{},errors:[]}}function i(e,t){this.path=e,this.rethrow(t)}t.b=r,r.prototype.isError=function(e){return e instanceof i},r.prototype.save=function(){const e=this._reporterState;return{obj:e.obj,pathLen:e.path.length}},r.prototype.restore=function(e){const t=this._reporterState;t.obj=e.obj,t.path=t.path.slice(0,e.pathLen)},r.prototype.enterKey=function(e){return this._reporterState.path.push(e)},r.prototype.exitKey=function(e){const t=this._reporterState;t.path=t.path.slice(0,e-1)},r.prototype.leaveKey=function(e,t,n){const o=this._reporterState;this.exitKey(e),null!==o.obj&&(o.obj[t]=n)},r.prototype.path=function(){return this._reporterState.path.join("/")},r.prototype.enterObject=function(){const e=this._reporterState,t=e.obj;return e.obj={},t},r.prototype.leaveObject=function(e){const t=this._reporterState,n=t.obj;return t.obj=e,n},r.prototype.error=function(e){let t;const n=this._reporterState,o=e instanceof i;if(t=o?e:new i(n.path.map((function(e){return"["+JSON.stringify(e)+"]"})).join(""),e.message||e,e.stack),!n.options.partial)throw t;return o||n.errors.push(t),t},r.prototype.wrapResult=function(e){const t=this._reporterState;return t.options.partial?{result:this.isError(e)?null:e,errors:t.errors}:e},o(i,Error),i.prototype.rethrow=function(e){if(this.message=e+" at: "+(this.path||"(shallow)"),Error.captureStackTrace&&Error.captureStackTrace(this,i),!this.stack)try{throw new Error(this.message)}catch(e){this.stack=e.stack}return this}},70160:(e,t)=>{"use strict";function n(e){const t={};return Object.keys(e).forEach((function(n){(0|n)==n&&(n|=0);const o=e[n];t[o]=n})),t}t.tagClass={0:"universal",1:"application",2:"context",3:"private"},t.tagClassByName=n(t.tagClass),t.tag={0:"end",1:"bool",2:"int",3:"bitstr",4:"octstr",5:"null_",6:"objid",7:"objDesc",8:"external",9:"real",10:"enum",11:"embed",12:"utf8str",13:"relativeOid",16:"seq",17:"set",18:"numstr",19:"printstr",20:"t61str",21:"videostr",22:"ia5str",23:"utctime",24:"gentime",25:"graphstr",26:"iso646str",27:"genstr",28:"unistr",29:"charstr",30:"bmpstr"},t.tagByName=n(t.tag)},36826:(e,t,n)=>{"use strict";const o=t;o._reverse=function(e){const t={};return Object.keys(e).forEach((function(n){(0|n)==n&&(n|=0);const o=e[n];t[o]=n})),t},o.der=n(70160)},41671:(e,t,n)=>{"use strict";const o=n(35717),r=n(4590),i=n(36625).C,a=n(41949),s=n(70160);function u(e){this.enc="der",this.name=e.name,this.entity=e,this.tree=new c,this.tree._init(e.body)}function c(e){a.call(this,"der",e)}function l(e,t){let n=e.readUInt8(t);if(e.isError(n))return n;const o=s.tagClass[n>>6],r=0==(32&n);if(31==(31&n)){let o=n;for(n=0;128==(128&o);){if(o=e.readUInt8(t),e.isError(o))return o;n<<=7,n|=127&o}}else n&=31;return{cls:o,primitive:r,tag:n,tagStr:s.tag[n]}}function d(e,t,n){let o=e.readUInt8(n);if(e.isError(o))return o;if(!t&&128===o)return null;if(0==(128&o))return o;const r=127&o;if(r>4)return e.error("length octect is too long");o=0;for(let t=0;t{"use strict";const o=t;o.der=n(41671),o.pem=n(59631)},59631:(e,t,n)=>{"use strict";const o=n(35717),r=n(2399).Buffer,i=n(41671);function a(e){i.call(this,e),this.enc="pem"}o(a,i),e.exports=a,a.prototype.decode=function(e,t){const n=e.toString().split(/[\r\n]+/g),o=t.label.toUpperCase(),a=/^-----(BEGIN|END) ([^-]+)-----$/;let s=-1,u=-1;for(let e=0;e{"use strict";const o=n(35717),r=n(2399).Buffer,i=n(41949),a=n(70160);function s(e){this.enc="der",this.name=e.name,this.entity=e,this.tree=new u,this.tree._init(e.body)}function u(e){i.call(this,"der",e)}function c(e){return e<10?"0"+e:e}e.exports=s,s.prototype.encode=function(e,t){return this.tree._encode(e,t).join()},o(u,i),u.prototype._encodeComposite=function(e,t,n,o){const i=function(e,t,n,o){let r;if("seqof"===e?e="seq":"setof"===e&&(e="set"),a.tagByName.hasOwnProperty(e))r=a.tagByName[e];else{if("number"!=typeof e||(0|e)!==e)return o.error("Unknown tag: "+e);r=e}return r>=31?o.error("Multi-octet tag encoding unsupported"):(t||(r|=32),r|=a.tagClassByName[n||"universal"]<<6,r)}(e,t,n,this.reporter);if(o.length<128){const e=r.alloc(2);return e[0]=i,e[1]=o.length,this._createEncoderBuffer([e,o])}let s=1;for(let e=o.length;e>=256;e>>=8)s++;const u=r.alloc(2+s);u[0]=i,u[1]=128|s;for(let e=1+s,t=o.length;t>0;e--,t>>=8)u[e]=255&t;return this._createEncoderBuffer([u,o])},u.prototype._encodeStr=function(e,t){if("bitstr"===t)return this._createEncoderBuffer([0|e.unused,e.data]);if("bmpstr"===t){const t=r.alloc(2*e.length);for(let n=0;n=40)return this.reporter.error("Second objid identifier OOB");e.splice(0,2,40*e[0]+e[1])}let o=0;for(let t=0;t=128;n>>=7)o++}const i=r.alloc(o);let a=i.length-1;for(let t=e.length-1;t>=0;t--){let n=e[t];for(i[a--]=127&n;(n>>=7)>0;)i[a--]=128|127&n}return this._createEncoderBuffer(i)},u.prototype._encodeTime=function(e,t){let n;const o=new Date(e);return"gentime"===t?n=[c(o.getUTCFullYear()),c(o.getUTCMonth()+1),c(o.getUTCDate()),c(o.getUTCHours()),c(o.getUTCMinutes()),c(o.getUTCSeconds()),"Z"].join(""):"utctime"===t?n=[c(o.getUTCFullYear()%100),c(o.getUTCMonth()+1),c(o.getUTCDate()),c(o.getUTCHours()),c(o.getUTCMinutes()),c(o.getUTCSeconds()),"Z"].join(""):this.reporter.error("Encoding "+t+" time is not supported yet"),this._encodeStr(n,"octstr")},u.prototype._encodeNull=function(){return this._createEncoderBuffer("")},u.prototype._encodeInt=function(e,t){if("string"==typeof e){if(!t)return this.reporter.error("String int or enum given, but no values map");if(!t.hasOwnProperty(e))return this.reporter.error("Values map doesn't contain: "+JSON.stringify(e));e=t[e]}if("number"!=typeof e&&!r.isBuffer(e)){const t=e.toArray();!e.sign&&128&t[0]&&t.unshift(0),e=r.from(t)}if(r.isBuffer(e)){let t=e.length;0===e.length&&t++;const n=r.alloc(t);return e.copy(n),0===e.length&&(n[0]=0),this._createEncoderBuffer(n)}if(e<128)return this._createEncoderBuffer(e);if(e<256)return this._createEncoderBuffer([0,e]);let n=1;for(let t=e;t>=256;t>>=8)n++;const o=new Array(n);for(let t=o.length-1;t>=0;t--)o[t]=255&e,e>>=8;return 128&o[0]&&o.unshift(0),this._createEncoderBuffer(r.from(o))},u.prototype._encodeBool=function(e){return this._createEncoderBuffer(e?255:0)},u.prototype._use=function(e,t){return"function"==typeof e&&(e=e(t)),e._getEncoder("der").tree},u.prototype._skipDefault=function(e,t,n){const o=this._baseState;let r;if(null===o.default)return!1;const i=e.join();if(void 0===o.defaultBuffer&&(o.defaultBuffer=this._encodeValue(o.default,t,n).join()),i.length!==o.defaultBuffer.length)return!1;for(r=0;r{"use strict";const o=t;o.der=n(66984),o.pem=n(2883)},2883:(e,t,n)=>{"use strict";const o=n(35717),r=n(66984);function i(e){r.call(this,e),this.enc="pem"}o(i,r),e.exports=i,i.prototype.encode=function(e,t){const n=r.prototype.encode.call(this,e).toString("base64"),o=["-----BEGIN "+t.label+"-----"];for(let e=0;e=65&&n<=70?n-55:n>=97&&n<=102?n-87:n-48&15}function u(e,t,n){var o=s(e,n);return n-1>=t&&(o|=s(e,n-1)<<4),o}function c(e,t,n,o){for(var r=0,i=Math.min(e.length,n),a=t;a=49?s-49+10:s>=17?s-17+10:s}return r}i.isBN=function(e){return e instanceof i||null!==e&&"object"==typeof e&&e.constructor.wordSize===i.wordSize&&Array.isArray(e.words)},i.max=function(e,t){return e.cmp(t)>0?e:t},i.min=function(e,t){return e.cmp(t)<0?e:t},i.prototype._init=function(e,t,n){if("number"==typeof e)return this._initNumber(e,t,n);if("object"==typeof e)return this._initArray(e,t,n);"hex"===t&&(t=16),o(t===(0|t)&&t>=2&&t<=36);var r=0;"-"===(e=e.toString().replace(/\s+/g,""))[0]&&(r++,this.negative=1),r=0;r-=3)a=e[r]|e[r-1]<<8|e[r-2]<<16,this.words[i]|=a<>>26-s&67108863,(s+=24)>=26&&(s-=26,i++);else if("le"===n)for(r=0,i=0;r>>26-s&67108863,(s+=24)>=26&&(s-=26,i++);return this.strip()},i.prototype._parseHex=function(e,t,n){this.length=Math.ceil((e.length-t)/6),this.words=new Array(this.length);for(var o=0;o=t;o-=2)r=u(e,t,o)<=18?(i-=18,a+=1,this.words[a]|=r>>>26):i+=8;else for(o=(e.length-t)%2==0?t+1:t;o=18?(i-=18,a+=1,this.words[a]|=r>>>26):i+=8;this.strip()},i.prototype._parseBase=function(e,t,n){this.words=[0],this.length=1;for(var o=0,r=1;r<=67108863;r*=t)o++;o--,r=r/t|0;for(var i=e.length-n,a=i%o,s=Math.min(i,i-a)+n,u=0,l=n;l1&&0===this.words[this.length-1];)this.length--;return this._normSign()},i.prototype._normSign=function(){return 1===this.length&&0===this.words[0]&&(this.negative=0),this},i.prototype.inspect=function(){return(this.red?""};var l=["","0","00","000","0000","00000","000000","0000000","00000000","000000000","0000000000","00000000000","000000000000","0000000000000","00000000000000","000000000000000","0000000000000000","00000000000000000","000000000000000000","0000000000000000000","00000000000000000000","000000000000000000000","0000000000000000000000","00000000000000000000000","000000000000000000000000","0000000000000000000000000"],d=[0,0,25,16,12,11,10,9,8,8,7,7,7,7,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5],h=[0,0,33554432,43046721,16777216,48828125,60466176,40353607,16777216,43046721,1e7,19487171,35831808,62748517,7529536,11390625,16777216,24137569,34012224,47045881,64e6,4084101,5153632,6436343,7962624,9765625,11881376,14348907,17210368,20511149,243e5,28629151,33554432,39135393,45435424,52521875,60466176];function p(e,t,n){n.negative=t.negative^e.negative;var o=e.length+t.length|0;n.length=o,o=o-1|0;var r=0|e.words[0],i=0|t.words[0],a=r*i,s=67108863&a,u=a/67108864|0;n.words[0]=s;for(var c=1;c>>26,d=67108863&u,h=Math.min(c,t.length-1),p=Math.max(0,c-e.length+1);p<=h;p++){var f=c-p|0;l+=(a=(r=0|e.words[f])*(i=0|t.words[p])+d)/67108864|0,d=67108863&a}n.words[c]=0|d,u=0|l}return 0!==u?n.words[c]=0|u:n.length--,n.strip()}i.prototype.toString=function(e,t){var n;if(t=0|t||1,16===(e=e||10)||"hex"===e){n="";for(var r=0,i=0,a=0;a>>24-r&16777215)||a!==this.length-1?l[6-u.length]+u+n:u+n,(r+=2)>=26&&(r-=26,a--)}for(0!==i&&(n=i.toString(16)+n);n.length%t!=0;)n="0"+n;return 0!==this.negative&&(n="-"+n),n}if(e===(0|e)&&e>=2&&e<=36){var c=d[e],p=h[e];n="";var f=this.clone();for(f.negative=0;!f.isZero();){var g=f.modn(p).toString(e);n=(f=f.idivn(p)).isZero()?g+n:l[c-g.length]+g+n}for(this.isZero()&&(n="0"+n);n.length%t!=0;)n="0"+n;return 0!==this.negative&&(n="-"+n),n}o(!1,"Base should be between 2 and 36")},i.prototype.toNumber=function(){var e=this.words[0];return 2===this.length?e+=67108864*this.words[1]:3===this.length&&1===this.words[2]?e+=4503599627370496+67108864*this.words[1]:this.length>2&&o(!1,"Number can only safely store up to 53 bits"),0!==this.negative?-e:e},i.prototype.toJSON=function(){return this.toString(16)},i.prototype.toBuffer=function(e,t){return o(void 0!==a),this.toArrayLike(a,e,t)},i.prototype.toArray=function(e,t){return this.toArrayLike(Array,e,t)},i.prototype.toArrayLike=function(e,t,n){var r=this.byteLength(),i=n||Math.max(1,r);o(r<=i,"byte array longer than desired length"),o(i>0,"Requested array length <= 0"),this.strip();var a,s,u="le"===t,c=new e(i),l=this.clone();if(u){for(s=0;!l.isZero();s++)a=l.andln(255),l.iushrn(8),c[s]=a;for(;s=4096&&(n+=13,t>>>=13),t>=64&&(n+=7,t>>>=7),t>=8&&(n+=4,t>>>=4),t>=2&&(n+=2,t>>>=2),n+t},i.prototype._zeroBits=function(e){if(0===e)return 26;var t=e,n=0;return 0==(8191&t)&&(n+=13,t>>>=13),0==(127&t)&&(n+=7,t>>>=7),0==(15&t)&&(n+=4,t>>>=4),0==(3&t)&&(n+=2,t>>>=2),0==(1&t)&&n++,n},i.prototype.bitLength=function(){var e=this.words[this.length-1],t=this._countBits(e);return 26*(this.length-1)+t},i.prototype.zeroBits=function(){if(this.isZero())return 0;for(var e=0,t=0;te.length?this.clone().ior(e):e.clone().ior(this)},i.prototype.uor=function(e){return this.length>e.length?this.clone().iuor(e):e.clone().iuor(this)},i.prototype.iuand=function(e){var t;t=this.length>e.length?e:this;for(var n=0;ne.length?this.clone().iand(e):e.clone().iand(this)},i.prototype.uand=function(e){return this.length>e.length?this.clone().iuand(e):e.clone().iuand(this)},i.prototype.iuxor=function(e){var t,n;this.length>e.length?(t=this,n=e):(t=e,n=this);for(var o=0;oe.length?this.clone().ixor(e):e.clone().ixor(this)},i.prototype.uxor=function(e){return this.length>e.length?this.clone().iuxor(e):e.clone().iuxor(this)},i.prototype.inotn=function(e){o("number"==typeof e&&e>=0);var t=0|Math.ceil(e/26),n=e%26;this._expand(t),n>0&&t--;for(var r=0;r0&&(this.words[r]=~this.words[r]&67108863>>26-n),this.strip()},i.prototype.notn=function(e){return this.clone().inotn(e)},i.prototype.setn=function(e,t){o("number"==typeof e&&e>=0);var n=e/26|0,r=e%26;return this._expand(n+1),this.words[n]=t?this.words[n]|1<e.length?(n=this,o=e):(n=e,o=this);for(var r=0,i=0;i>>26;for(;0!==r&&i>>26;if(this.length=n.length,0!==r)this.words[this.length]=r,this.length++;else if(n!==this)for(;ie.length?this.clone().iadd(e):e.clone().iadd(this)},i.prototype.isub=function(e){if(0!==e.negative){e.negative=0;var t=this.iadd(e);return e.negative=1,t._normSign()}if(0!==this.negative)return this.negative=0,this.iadd(e),this.negative=1,this._normSign();var n,o,r=this.cmp(e);if(0===r)return this.negative=0,this.length=1,this.words[0]=0,this;r>0?(n=this,o=e):(n=e,o=this);for(var i=0,a=0;a>26,this.words[a]=67108863&t;for(;0!==i&&a>26,this.words[a]=67108863&t;if(0===i&&a>>13,p=0|a[1],f=8191&p,g=p>>>13,m=0|a[2],_=8191&m,F=m>>>13,y=0|a[3],b=8191&y,v=y>>>13,w=0|a[4],E=8191&w,k=w>>>13,D=0|a[5],S=8191&D,x=D>>>13,C=0|a[6],A=8191&C,T=C>>>13,R=0|a[7],I=8191&R,M=R>>>13,O=0|a[8],B=8191&O,N=O>>>13,L=0|a[9],P=8191&L,U=L>>>13,j=0|s[0],q=8191&j,z=j>>>13,K=0|s[1],G=8191&K,$=K>>>13,H=0|s[2],V=8191&H,W=H>>>13,Y=0|s[3],Z=8191&Y,X=Y>>>13,J=0|s[4],Q=8191&J,ee=J>>>13,te=0|s[5],ne=8191&te,oe=te>>>13,re=0|s[6],ie=8191&re,ae=re>>>13,se=0|s[7],ue=8191&se,ce=se>>>13,le=0|s[8],de=8191&le,he=le>>>13,pe=0|s[9],fe=8191&pe,ge=pe>>>13;n.negative=e.negative^t.negative,n.length=19;var me=(c+(o=Math.imul(d,q))|0)+((8191&(r=(r=Math.imul(d,z))+Math.imul(h,q)|0))<<13)|0;c=((i=Math.imul(h,z))+(r>>>13)|0)+(me>>>26)|0,me&=67108863,o=Math.imul(f,q),r=(r=Math.imul(f,z))+Math.imul(g,q)|0,i=Math.imul(g,z);var _e=(c+(o=o+Math.imul(d,G)|0)|0)+((8191&(r=(r=r+Math.imul(d,$)|0)+Math.imul(h,G)|0))<<13)|0;c=((i=i+Math.imul(h,$)|0)+(r>>>13)|0)+(_e>>>26)|0,_e&=67108863,o=Math.imul(_,q),r=(r=Math.imul(_,z))+Math.imul(F,q)|0,i=Math.imul(F,z),o=o+Math.imul(f,G)|0,r=(r=r+Math.imul(f,$)|0)+Math.imul(g,G)|0,i=i+Math.imul(g,$)|0;var Fe=(c+(o=o+Math.imul(d,V)|0)|0)+((8191&(r=(r=r+Math.imul(d,W)|0)+Math.imul(h,V)|0))<<13)|0;c=((i=i+Math.imul(h,W)|0)+(r>>>13)|0)+(Fe>>>26)|0,Fe&=67108863,o=Math.imul(b,q),r=(r=Math.imul(b,z))+Math.imul(v,q)|0,i=Math.imul(v,z),o=o+Math.imul(_,G)|0,r=(r=r+Math.imul(_,$)|0)+Math.imul(F,G)|0,i=i+Math.imul(F,$)|0,o=o+Math.imul(f,V)|0,r=(r=r+Math.imul(f,W)|0)+Math.imul(g,V)|0,i=i+Math.imul(g,W)|0;var ye=(c+(o=o+Math.imul(d,Z)|0)|0)+((8191&(r=(r=r+Math.imul(d,X)|0)+Math.imul(h,Z)|0))<<13)|0;c=((i=i+Math.imul(h,X)|0)+(r>>>13)|0)+(ye>>>26)|0,ye&=67108863,o=Math.imul(E,q),r=(r=Math.imul(E,z))+Math.imul(k,q)|0,i=Math.imul(k,z),o=o+Math.imul(b,G)|0,r=(r=r+Math.imul(b,$)|0)+Math.imul(v,G)|0,i=i+Math.imul(v,$)|0,o=o+Math.imul(_,V)|0,r=(r=r+Math.imul(_,W)|0)+Math.imul(F,V)|0,i=i+Math.imul(F,W)|0,o=o+Math.imul(f,Z)|0,r=(r=r+Math.imul(f,X)|0)+Math.imul(g,Z)|0,i=i+Math.imul(g,X)|0;var be=(c+(o=o+Math.imul(d,Q)|0)|0)+((8191&(r=(r=r+Math.imul(d,ee)|0)+Math.imul(h,Q)|0))<<13)|0;c=((i=i+Math.imul(h,ee)|0)+(r>>>13)|0)+(be>>>26)|0,be&=67108863,o=Math.imul(S,q),r=(r=Math.imul(S,z))+Math.imul(x,q)|0,i=Math.imul(x,z),o=o+Math.imul(E,G)|0,r=(r=r+Math.imul(E,$)|0)+Math.imul(k,G)|0,i=i+Math.imul(k,$)|0,o=o+Math.imul(b,V)|0,r=(r=r+Math.imul(b,W)|0)+Math.imul(v,V)|0,i=i+Math.imul(v,W)|0,o=o+Math.imul(_,Z)|0,r=(r=r+Math.imul(_,X)|0)+Math.imul(F,Z)|0,i=i+Math.imul(F,X)|0,o=o+Math.imul(f,Q)|0,r=(r=r+Math.imul(f,ee)|0)+Math.imul(g,Q)|0,i=i+Math.imul(g,ee)|0;var ve=(c+(o=o+Math.imul(d,ne)|0)|0)+((8191&(r=(r=r+Math.imul(d,oe)|0)+Math.imul(h,ne)|0))<<13)|0;c=((i=i+Math.imul(h,oe)|0)+(r>>>13)|0)+(ve>>>26)|0,ve&=67108863,o=Math.imul(A,q),r=(r=Math.imul(A,z))+Math.imul(T,q)|0,i=Math.imul(T,z),o=o+Math.imul(S,G)|0,r=(r=r+Math.imul(S,$)|0)+Math.imul(x,G)|0,i=i+Math.imul(x,$)|0,o=o+Math.imul(E,V)|0,r=(r=r+Math.imul(E,W)|0)+Math.imul(k,V)|0,i=i+Math.imul(k,W)|0,o=o+Math.imul(b,Z)|0,r=(r=r+Math.imul(b,X)|0)+Math.imul(v,Z)|0,i=i+Math.imul(v,X)|0,o=o+Math.imul(_,Q)|0,r=(r=r+Math.imul(_,ee)|0)+Math.imul(F,Q)|0,i=i+Math.imul(F,ee)|0,o=o+Math.imul(f,ne)|0,r=(r=r+Math.imul(f,oe)|0)+Math.imul(g,ne)|0,i=i+Math.imul(g,oe)|0;var we=(c+(o=o+Math.imul(d,ie)|0)|0)+((8191&(r=(r=r+Math.imul(d,ae)|0)+Math.imul(h,ie)|0))<<13)|0;c=((i=i+Math.imul(h,ae)|0)+(r>>>13)|0)+(we>>>26)|0,we&=67108863,o=Math.imul(I,q),r=(r=Math.imul(I,z))+Math.imul(M,q)|0,i=Math.imul(M,z),o=o+Math.imul(A,G)|0,r=(r=r+Math.imul(A,$)|0)+Math.imul(T,G)|0,i=i+Math.imul(T,$)|0,o=o+Math.imul(S,V)|0,r=(r=r+Math.imul(S,W)|0)+Math.imul(x,V)|0,i=i+Math.imul(x,W)|0,o=o+Math.imul(E,Z)|0,r=(r=r+Math.imul(E,X)|0)+Math.imul(k,Z)|0,i=i+Math.imul(k,X)|0,o=o+Math.imul(b,Q)|0,r=(r=r+Math.imul(b,ee)|0)+Math.imul(v,Q)|0,i=i+Math.imul(v,ee)|0,o=o+Math.imul(_,ne)|0,r=(r=r+Math.imul(_,oe)|0)+Math.imul(F,ne)|0,i=i+Math.imul(F,oe)|0,o=o+Math.imul(f,ie)|0,r=(r=r+Math.imul(f,ae)|0)+Math.imul(g,ie)|0,i=i+Math.imul(g,ae)|0;var Ee=(c+(o=o+Math.imul(d,ue)|0)|0)+((8191&(r=(r=r+Math.imul(d,ce)|0)+Math.imul(h,ue)|0))<<13)|0;c=((i=i+Math.imul(h,ce)|0)+(r>>>13)|0)+(Ee>>>26)|0,Ee&=67108863,o=Math.imul(B,q),r=(r=Math.imul(B,z))+Math.imul(N,q)|0,i=Math.imul(N,z),o=o+Math.imul(I,G)|0,r=(r=r+Math.imul(I,$)|0)+Math.imul(M,G)|0,i=i+Math.imul(M,$)|0,o=o+Math.imul(A,V)|0,r=(r=r+Math.imul(A,W)|0)+Math.imul(T,V)|0,i=i+Math.imul(T,W)|0,o=o+Math.imul(S,Z)|0,r=(r=r+Math.imul(S,X)|0)+Math.imul(x,Z)|0,i=i+Math.imul(x,X)|0,o=o+Math.imul(E,Q)|0,r=(r=r+Math.imul(E,ee)|0)+Math.imul(k,Q)|0,i=i+Math.imul(k,ee)|0,o=o+Math.imul(b,ne)|0,r=(r=r+Math.imul(b,oe)|0)+Math.imul(v,ne)|0,i=i+Math.imul(v,oe)|0,o=o+Math.imul(_,ie)|0,r=(r=r+Math.imul(_,ae)|0)+Math.imul(F,ie)|0,i=i+Math.imul(F,ae)|0,o=o+Math.imul(f,ue)|0,r=(r=r+Math.imul(f,ce)|0)+Math.imul(g,ue)|0,i=i+Math.imul(g,ce)|0;var ke=(c+(o=o+Math.imul(d,de)|0)|0)+((8191&(r=(r=r+Math.imul(d,he)|0)+Math.imul(h,de)|0))<<13)|0;c=((i=i+Math.imul(h,he)|0)+(r>>>13)|0)+(ke>>>26)|0,ke&=67108863,o=Math.imul(P,q),r=(r=Math.imul(P,z))+Math.imul(U,q)|0,i=Math.imul(U,z),o=o+Math.imul(B,G)|0,r=(r=r+Math.imul(B,$)|0)+Math.imul(N,G)|0,i=i+Math.imul(N,$)|0,o=o+Math.imul(I,V)|0,r=(r=r+Math.imul(I,W)|0)+Math.imul(M,V)|0,i=i+Math.imul(M,W)|0,o=o+Math.imul(A,Z)|0,r=(r=r+Math.imul(A,X)|0)+Math.imul(T,Z)|0,i=i+Math.imul(T,X)|0,o=o+Math.imul(S,Q)|0,r=(r=r+Math.imul(S,ee)|0)+Math.imul(x,Q)|0,i=i+Math.imul(x,ee)|0,o=o+Math.imul(E,ne)|0,r=(r=r+Math.imul(E,oe)|0)+Math.imul(k,ne)|0,i=i+Math.imul(k,oe)|0,o=o+Math.imul(b,ie)|0,r=(r=r+Math.imul(b,ae)|0)+Math.imul(v,ie)|0,i=i+Math.imul(v,ae)|0,o=o+Math.imul(_,ue)|0,r=(r=r+Math.imul(_,ce)|0)+Math.imul(F,ue)|0,i=i+Math.imul(F,ce)|0,o=o+Math.imul(f,de)|0,r=(r=r+Math.imul(f,he)|0)+Math.imul(g,de)|0,i=i+Math.imul(g,he)|0;var De=(c+(o=o+Math.imul(d,fe)|0)|0)+((8191&(r=(r=r+Math.imul(d,ge)|0)+Math.imul(h,fe)|0))<<13)|0;c=((i=i+Math.imul(h,ge)|0)+(r>>>13)|0)+(De>>>26)|0,De&=67108863,o=Math.imul(P,G),r=(r=Math.imul(P,$))+Math.imul(U,G)|0,i=Math.imul(U,$),o=o+Math.imul(B,V)|0,r=(r=r+Math.imul(B,W)|0)+Math.imul(N,V)|0,i=i+Math.imul(N,W)|0,o=o+Math.imul(I,Z)|0,r=(r=r+Math.imul(I,X)|0)+Math.imul(M,Z)|0,i=i+Math.imul(M,X)|0,o=o+Math.imul(A,Q)|0,r=(r=r+Math.imul(A,ee)|0)+Math.imul(T,Q)|0,i=i+Math.imul(T,ee)|0,o=o+Math.imul(S,ne)|0,r=(r=r+Math.imul(S,oe)|0)+Math.imul(x,ne)|0,i=i+Math.imul(x,oe)|0,o=o+Math.imul(E,ie)|0,r=(r=r+Math.imul(E,ae)|0)+Math.imul(k,ie)|0,i=i+Math.imul(k,ae)|0,o=o+Math.imul(b,ue)|0,r=(r=r+Math.imul(b,ce)|0)+Math.imul(v,ue)|0,i=i+Math.imul(v,ce)|0,o=o+Math.imul(_,de)|0,r=(r=r+Math.imul(_,he)|0)+Math.imul(F,de)|0,i=i+Math.imul(F,he)|0;var Se=(c+(o=o+Math.imul(f,fe)|0)|0)+((8191&(r=(r=r+Math.imul(f,ge)|0)+Math.imul(g,fe)|0))<<13)|0;c=((i=i+Math.imul(g,ge)|0)+(r>>>13)|0)+(Se>>>26)|0,Se&=67108863,o=Math.imul(P,V),r=(r=Math.imul(P,W))+Math.imul(U,V)|0,i=Math.imul(U,W),o=o+Math.imul(B,Z)|0,r=(r=r+Math.imul(B,X)|0)+Math.imul(N,Z)|0,i=i+Math.imul(N,X)|0,o=o+Math.imul(I,Q)|0,r=(r=r+Math.imul(I,ee)|0)+Math.imul(M,Q)|0,i=i+Math.imul(M,ee)|0,o=o+Math.imul(A,ne)|0,r=(r=r+Math.imul(A,oe)|0)+Math.imul(T,ne)|0,i=i+Math.imul(T,oe)|0,o=o+Math.imul(S,ie)|0,r=(r=r+Math.imul(S,ae)|0)+Math.imul(x,ie)|0,i=i+Math.imul(x,ae)|0,o=o+Math.imul(E,ue)|0,r=(r=r+Math.imul(E,ce)|0)+Math.imul(k,ue)|0,i=i+Math.imul(k,ce)|0,o=o+Math.imul(b,de)|0,r=(r=r+Math.imul(b,he)|0)+Math.imul(v,de)|0,i=i+Math.imul(v,he)|0;var xe=(c+(o=o+Math.imul(_,fe)|0)|0)+((8191&(r=(r=r+Math.imul(_,ge)|0)+Math.imul(F,fe)|0))<<13)|0;c=((i=i+Math.imul(F,ge)|0)+(r>>>13)|0)+(xe>>>26)|0,xe&=67108863,o=Math.imul(P,Z),r=(r=Math.imul(P,X))+Math.imul(U,Z)|0,i=Math.imul(U,X),o=o+Math.imul(B,Q)|0,r=(r=r+Math.imul(B,ee)|0)+Math.imul(N,Q)|0,i=i+Math.imul(N,ee)|0,o=o+Math.imul(I,ne)|0,r=(r=r+Math.imul(I,oe)|0)+Math.imul(M,ne)|0,i=i+Math.imul(M,oe)|0,o=o+Math.imul(A,ie)|0,r=(r=r+Math.imul(A,ae)|0)+Math.imul(T,ie)|0,i=i+Math.imul(T,ae)|0,o=o+Math.imul(S,ue)|0,r=(r=r+Math.imul(S,ce)|0)+Math.imul(x,ue)|0,i=i+Math.imul(x,ce)|0,o=o+Math.imul(E,de)|0,r=(r=r+Math.imul(E,he)|0)+Math.imul(k,de)|0,i=i+Math.imul(k,he)|0;var Ce=(c+(o=o+Math.imul(b,fe)|0)|0)+((8191&(r=(r=r+Math.imul(b,ge)|0)+Math.imul(v,fe)|0))<<13)|0;c=((i=i+Math.imul(v,ge)|0)+(r>>>13)|0)+(Ce>>>26)|0,Ce&=67108863,o=Math.imul(P,Q),r=(r=Math.imul(P,ee))+Math.imul(U,Q)|0,i=Math.imul(U,ee),o=o+Math.imul(B,ne)|0,r=(r=r+Math.imul(B,oe)|0)+Math.imul(N,ne)|0,i=i+Math.imul(N,oe)|0,o=o+Math.imul(I,ie)|0,r=(r=r+Math.imul(I,ae)|0)+Math.imul(M,ie)|0,i=i+Math.imul(M,ae)|0,o=o+Math.imul(A,ue)|0,r=(r=r+Math.imul(A,ce)|0)+Math.imul(T,ue)|0,i=i+Math.imul(T,ce)|0,o=o+Math.imul(S,de)|0,r=(r=r+Math.imul(S,he)|0)+Math.imul(x,de)|0,i=i+Math.imul(x,he)|0;var Ae=(c+(o=o+Math.imul(E,fe)|0)|0)+((8191&(r=(r=r+Math.imul(E,ge)|0)+Math.imul(k,fe)|0))<<13)|0;c=((i=i+Math.imul(k,ge)|0)+(r>>>13)|0)+(Ae>>>26)|0,Ae&=67108863,o=Math.imul(P,ne),r=(r=Math.imul(P,oe))+Math.imul(U,ne)|0,i=Math.imul(U,oe),o=o+Math.imul(B,ie)|0,r=(r=r+Math.imul(B,ae)|0)+Math.imul(N,ie)|0,i=i+Math.imul(N,ae)|0,o=o+Math.imul(I,ue)|0,r=(r=r+Math.imul(I,ce)|0)+Math.imul(M,ue)|0,i=i+Math.imul(M,ce)|0,o=o+Math.imul(A,de)|0,r=(r=r+Math.imul(A,he)|0)+Math.imul(T,de)|0,i=i+Math.imul(T,he)|0;var Te=(c+(o=o+Math.imul(S,fe)|0)|0)+((8191&(r=(r=r+Math.imul(S,ge)|0)+Math.imul(x,fe)|0))<<13)|0;c=((i=i+Math.imul(x,ge)|0)+(r>>>13)|0)+(Te>>>26)|0,Te&=67108863,o=Math.imul(P,ie),r=(r=Math.imul(P,ae))+Math.imul(U,ie)|0,i=Math.imul(U,ae),o=o+Math.imul(B,ue)|0,r=(r=r+Math.imul(B,ce)|0)+Math.imul(N,ue)|0,i=i+Math.imul(N,ce)|0,o=o+Math.imul(I,de)|0,r=(r=r+Math.imul(I,he)|0)+Math.imul(M,de)|0,i=i+Math.imul(M,he)|0;var Re=(c+(o=o+Math.imul(A,fe)|0)|0)+((8191&(r=(r=r+Math.imul(A,ge)|0)+Math.imul(T,fe)|0))<<13)|0;c=((i=i+Math.imul(T,ge)|0)+(r>>>13)|0)+(Re>>>26)|0,Re&=67108863,o=Math.imul(P,ue),r=(r=Math.imul(P,ce))+Math.imul(U,ue)|0,i=Math.imul(U,ce),o=o+Math.imul(B,de)|0,r=(r=r+Math.imul(B,he)|0)+Math.imul(N,de)|0,i=i+Math.imul(N,he)|0;var Ie=(c+(o=o+Math.imul(I,fe)|0)|0)+((8191&(r=(r=r+Math.imul(I,ge)|0)+Math.imul(M,fe)|0))<<13)|0;c=((i=i+Math.imul(M,ge)|0)+(r>>>13)|0)+(Ie>>>26)|0,Ie&=67108863,o=Math.imul(P,de),r=(r=Math.imul(P,he))+Math.imul(U,de)|0,i=Math.imul(U,he);var Me=(c+(o=o+Math.imul(B,fe)|0)|0)+((8191&(r=(r=r+Math.imul(B,ge)|0)+Math.imul(N,fe)|0))<<13)|0;c=((i=i+Math.imul(N,ge)|0)+(r>>>13)|0)+(Me>>>26)|0,Me&=67108863;var Oe=(c+(o=Math.imul(P,fe))|0)+((8191&(r=(r=Math.imul(P,ge))+Math.imul(U,fe)|0))<<13)|0;return c=((i=Math.imul(U,ge))+(r>>>13)|0)+(Oe>>>26)|0,Oe&=67108863,u[0]=me,u[1]=_e,u[2]=Fe,u[3]=ye,u[4]=be,u[5]=ve,u[6]=we,u[7]=Ee,u[8]=ke,u[9]=De,u[10]=Se,u[11]=xe,u[12]=Ce,u[13]=Ae,u[14]=Te,u[15]=Re,u[16]=Ie,u[17]=Me,u[18]=Oe,0!==c&&(u[19]=c,n.length++),n};function g(e,t,n){return(new m).mulp(e,t,n)}function m(e,t){this.x=e,this.y=t}Math.imul||(f=p),i.prototype.mulTo=function(e,t){var n=this.length+e.length;return 10===this.length&&10===e.length?f(this,e,t):n<63?p(this,e,t):n<1024?function(e,t,n){n.negative=t.negative^e.negative,n.length=e.length+t.length;for(var o=0,r=0,i=0;i>>26)|0)>>>26,a&=67108863}n.words[i]=s,o=a,a=r}return 0!==o?n.words[i]=o:n.length--,n.strip()}(this,e,t):g(this,e,t)},m.prototype.makeRBT=function(e){for(var t=new Array(e),n=i.prototype._countBits(e)-1,o=0;o>=1;return o},m.prototype.permute=function(e,t,n,o,r,i){for(var a=0;a>>=1)r++;return 1<>>=13,n[2*a+1]=8191&i,i>>>=13;for(a=2*t;a>=26,t+=r/67108864|0,t+=i>>>26,this.words[n]=67108863&i}return 0!==t&&(this.words[n]=t,this.length++),this},i.prototype.muln=function(e){return this.clone().imuln(e)},i.prototype.sqr=function(){return this.mul(this)},i.prototype.isqr=function(){return this.imul(this.clone())},i.prototype.pow=function(e){var t=function(e){for(var t=new Array(e.bitLength()),n=0;n>>r}return t}(e);if(0===t.length)return new i(1);for(var n=this,o=0;o=0);var t,n=e%26,r=(e-n)/26,i=67108863>>>26-n<<26-n;if(0!==n){var a=0;for(t=0;t>>26-n}a&&(this.words[t]=a,this.length++)}if(0!==r){for(t=this.length-1;t>=0;t--)this.words[t+r]=this.words[t];for(t=0;t=0),r=t?(t-t%26)/26:0;var i=e%26,a=Math.min((e-i)/26,this.length),s=67108863^67108863>>>i<a)for(this.length-=a,c=0;c=0&&(0!==l||c>=r);c--){var d=0|this.words[c];this.words[c]=l<<26-i|d>>>i,l=d&s}return u&&0!==l&&(u.words[u.length++]=l),0===this.length&&(this.words[0]=0,this.length=1),this.strip()},i.prototype.ishrn=function(e,t,n){return o(0===this.negative),this.iushrn(e,t,n)},i.prototype.shln=function(e){return this.clone().ishln(e)},i.prototype.ushln=function(e){return this.clone().iushln(e)},i.prototype.shrn=function(e){return this.clone().ishrn(e)},i.prototype.ushrn=function(e){return this.clone().iushrn(e)},i.prototype.testn=function(e){o("number"==typeof e&&e>=0);var t=e%26,n=(e-t)/26,r=1<=0);var t=e%26,n=(e-t)/26;if(o(0===this.negative,"imaskn works only with positive numbers"),this.length<=n)return this;if(0!==t&&n++,this.length=Math.min(n,this.length),0!==t){var r=67108863^67108863>>>t<=67108864;t++)this.words[t]-=67108864,t===this.length-1?this.words[t+1]=1:this.words[t+1]++;return this.length=Math.max(this.length,t+1),this},i.prototype.isubn=function(e){if(o("number"==typeof e),o(e<67108864),e<0)return this.iaddn(-e);if(0!==this.negative)return this.negative=0,this.iaddn(e),this.negative=1,this;if(this.words[0]-=e,1===this.length&&this.words[0]<0)this.words[0]=-this.words[0],this.negative=1;else for(var t=0;t>26)-(u/67108864|0),this.words[r+n]=67108863&i}for(;r>26,this.words[r+n]=67108863&i;if(0===s)return this.strip();for(o(-1===s),s=0,r=0;r>26,this.words[r]=67108863&i;return this.negative=1,this.strip()},i.prototype._wordDiv=function(e,t){var n=(this.length,e.length),o=this.clone(),r=e,a=0|r.words[r.length-1];0!=(n=26-this._countBits(a))&&(r=r.ushln(n),o.iushln(n),a=0|r.words[r.length-1]);var s,u=o.length-r.length;if("mod"!==t){(s=new i(null)).length=u+1,s.words=new Array(s.length);for(var c=0;c=0;d--){var h=67108864*(0|o.words[r.length+d])+(0|o.words[r.length+d-1]);for(h=Math.min(h/a|0,67108863),o._ishlnsubmul(r,h,d);0!==o.negative;)h--,o.negative=0,o._ishlnsubmul(r,1,d),o.isZero()||(o.negative^=1);s&&(s.words[d]=h)}return s&&s.strip(),o.strip(),"div"!==t&&0!==n&&o.iushrn(n),{div:s||null,mod:o}},i.prototype.divmod=function(e,t,n){return o(!e.isZero()),this.isZero()?{div:new i(0),mod:new i(0)}:0!==this.negative&&0===e.negative?(s=this.neg().divmod(e,t),"mod"!==t&&(r=s.div.neg()),"div"!==t&&(a=s.mod.neg(),n&&0!==a.negative&&a.iadd(e)),{div:r,mod:a}):0===this.negative&&0!==e.negative?(s=this.divmod(e.neg(),t),"mod"!==t&&(r=s.div.neg()),{div:r,mod:s.mod}):0!=(this.negative&e.negative)?(s=this.neg().divmod(e.neg(),t),"div"!==t&&(a=s.mod.neg(),n&&0!==a.negative&&a.isub(e)),{div:s.div,mod:a}):e.length>this.length||this.cmp(e)<0?{div:new i(0),mod:this}:1===e.length?"div"===t?{div:this.divn(e.words[0]),mod:null}:"mod"===t?{div:null,mod:new i(this.modn(e.words[0]))}:{div:this.divn(e.words[0]),mod:new i(this.modn(e.words[0]))}:this._wordDiv(e,t);var r,a,s},i.prototype.div=function(e){return this.divmod(e,"div",!1).div},i.prototype.mod=function(e){return this.divmod(e,"mod",!1).mod},i.prototype.umod=function(e){return this.divmod(e,"mod",!0).mod},i.prototype.divRound=function(e){var t=this.divmod(e);if(t.mod.isZero())return t.div;var n=0!==t.div.negative?t.mod.isub(e):t.mod,o=e.ushrn(1),r=e.andln(1),i=n.cmp(o);return i<0||1===r&&0===i?t.div:0!==t.div.negative?t.div.isubn(1):t.div.iaddn(1)},i.prototype.modn=function(e){o(e<=67108863);for(var t=(1<<26)%e,n=0,r=this.length-1;r>=0;r--)n=(t*n+(0|this.words[r]))%e;return n},i.prototype.idivn=function(e){o(e<=67108863);for(var t=0,n=this.length-1;n>=0;n--){var r=(0|this.words[n])+67108864*t;this.words[n]=r/e|0,t=r%e}return this.strip()},i.prototype.divn=function(e){return this.clone().idivn(e)},i.prototype.egcd=function(e){o(0===e.negative),o(!e.isZero());var t=this,n=e.clone();t=0!==t.negative?t.umod(e):t.clone();for(var r=new i(1),a=new i(0),s=new i(0),u=new i(1),c=0;t.isEven()&&n.isEven();)t.iushrn(1),n.iushrn(1),++c;for(var l=n.clone(),d=t.clone();!t.isZero();){for(var h=0,p=1;0==(t.words[0]&p)&&h<26;++h,p<<=1);if(h>0)for(t.iushrn(h);h-- >0;)(r.isOdd()||a.isOdd())&&(r.iadd(l),a.isub(d)),r.iushrn(1),a.iushrn(1);for(var f=0,g=1;0==(n.words[0]&g)&&f<26;++f,g<<=1);if(f>0)for(n.iushrn(f);f-- >0;)(s.isOdd()||u.isOdd())&&(s.iadd(l),u.isub(d)),s.iushrn(1),u.iushrn(1);t.cmp(n)>=0?(t.isub(n),r.isub(s),a.isub(u)):(n.isub(t),s.isub(r),u.isub(a))}return{a:s,b:u,gcd:n.iushln(c)}},i.prototype._invmp=function(e){o(0===e.negative),o(!e.isZero());var t=this,n=e.clone();t=0!==t.negative?t.umod(e):t.clone();for(var r,a=new i(1),s=new i(0),u=n.clone();t.cmpn(1)>0&&n.cmpn(1)>0;){for(var c=0,l=1;0==(t.words[0]&l)&&c<26;++c,l<<=1);if(c>0)for(t.iushrn(c);c-- >0;)a.isOdd()&&a.iadd(u),a.iushrn(1);for(var d=0,h=1;0==(n.words[0]&h)&&d<26;++d,h<<=1);if(d>0)for(n.iushrn(d);d-- >0;)s.isOdd()&&s.iadd(u),s.iushrn(1);t.cmp(n)>=0?(t.isub(n),a.isub(s)):(n.isub(t),s.isub(a))}return(r=0===t.cmpn(1)?a:s).cmpn(0)<0&&r.iadd(e),r},i.prototype.gcd=function(e){if(this.isZero())return e.abs();if(e.isZero())return this.abs();var t=this.clone(),n=e.clone();t.negative=0,n.negative=0;for(var o=0;t.isEven()&&n.isEven();o++)t.iushrn(1),n.iushrn(1);for(;;){for(;t.isEven();)t.iushrn(1);for(;n.isEven();)n.iushrn(1);var r=t.cmp(n);if(r<0){var i=t;t=n,n=i}else if(0===r||0===n.cmpn(1))break;t.isub(n)}return n.iushln(o)},i.prototype.invm=function(e){return this.egcd(e).a.umod(e)},i.prototype.isEven=function(){return 0==(1&this.words[0])},i.prototype.isOdd=function(){return 1==(1&this.words[0])},i.prototype.andln=function(e){return this.words[0]&e},i.prototype.bincn=function(e){o("number"==typeof e);var t=e%26,n=(e-t)/26,r=1<>>26,s&=67108863,this.words[a]=s}return 0!==i&&(this.words[a]=i,this.length++),this},i.prototype.isZero=function(){return 1===this.length&&0===this.words[0]},i.prototype.cmpn=function(e){var t,n=e<0;if(0!==this.negative&&!n)return-1;if(0===this.negative&&n)return 1;if(this.strip(),this.length>1)t=1;else{n&&(e=-e),o(e<=67108863,"Number is too big");var r=0|this.words[0];t=r===e?0:re.length)return 1;if(this.length=0;n--){var o=0|this.words[n],r=0|e.words[n];if(o!==r){or&&(t=1);break}}return t},i.prototype.gtn=function(e){return 1===this.cmpn(e)},i.prototype.gt=function(e){return 1===this.cmp(e)},i.prototype.gten=function(e){return this.cmpn(e)>=0},i.prototype.gte=function(e){return this.cmp(e)>=0},i.prototype.ltn=function(e){return-1===this.cmpn(e)},i.prototype.lt=function(e){return-1===this.cmp(e)},i.prototype.lten=function(e){return this.cmpn(e)<=0},i.prototype.lte=function(e){return this.cmp(e)<=0},i.prototype.eqn=function(e){return 0===this.cmpn(e)},i.prototype.eq=function(e){return 0===this.cmp(e)},i.red=function(e){return new E(e)},i.prototype.toRed=function(e){return o(!this.red,"Already a number in reduction context"),o(0===this.negative,"red works only with positives"),e.convertTo(this)._forceRed(e)},i.prototype.fromRed=function(){return o(this.red,"fromRed works only with numbers in reduction context"),this.red.convertFrom(this)},i.prototype._forceRed=function(e){return this.red=e,this},i.prototype.forceRed=function(e){return o(!this.red,"Already a number in reduction context"),this._forceRed(e)},i.prototype.redAdd=function(e){return o(this.red,"redAdd works only with red numbers"),this.red.add(this,e)},i.prototype.redIAdd=function(e){return o(this.red,"redIAdd works only with red numbers"),this.red.iadd(this,e)},i.prototype.redSub=function(e){return o(this.red,"redSub works only with red numbers"),this.red.sub(this,e)},i.prototype.redISub=function(e){return o(this.red,"redISub works only with red numbers"),this.red.isub(this,e)},i.prototype.redShl=function(e){return o(this.red,"redShl works only with red numbers"),this.red.shl(this,e)},i.prototype.redMul=function(e){return o(this.red,"redMul works only with red numbers"),this.red._verify2(this,e),this.red.mul(this,e)},i.prototype.redIMul=function(e){return o(this.red,"redMul works only with red numbers"),this.red._verify2(this,e),this.red.imul(this,e)},i.prototype.redSqr=function(){return o(this.red,"redSqr works only with red numbers"),this.red._verify1(this),this.red.sqr(this)},i.prototype.redISqr=function(){return o(this.red,"redISqr works only with red numbers"),this.red._verify1(this),this.red.isqr(this)},i.prototype.redSqrt=function(){return o(this.red,"redSqrt works only with red numbers"),this.red._verify1(this),this.red.sqrt(this)},i.prototype.redInvm=function(){return o(this.red,"redInvm works only with red numbers"),this.red._verify1(this),this.red.invm(this)},i.prototype.redNeg=function(){return o(this.red,"redNeg works only with red numbers"),this.red._verify1(this),this.red.neg(this)},i.prototype.redPow=function(e){return o(this.red&&!e.red,"redPow(normalNum)"),this.red._verify1(this),this.red.pow(this,e)};var _={k256:null,p224:null,p192:null,p25519:null};function F(e,t){this.name=e,this.p=new i(t,16),this.n=this.p.bitLength(),this.k=new i(1).iushln(this.n).isub(this.p),this.tmp=this._tmp()}function y(){F.call(this,"k256","ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f")}function b(){F.call(this,"p224","ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001")}function v(){F.call(this,"p192","ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff")}function w(){F.call(this,"25519","7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed")}function E(e){if("string"==typeof e){var t=i._prime(e);this.m=t.p,this.prime=t}else o(e.gtn(1),"modulus must be greater than 1"),this.m=e,this.prime=null}function k(e){E.call(this,e),this.shift=this.m.bitLength(),this.shift%26!=0&&(this.shift+=26-this.shift%26),this.r=new i(1).iushln(this.shift),this.r2=this.imod(this.r.sqr()),this.rinv=this.r._invmp(this.m),this.minv=this.rinv.mul(this.r).isubn(1).div(this.m),this.minv=this.minv.umod(this.r),this.minv=this.r.sub(this.minv)}F.prototype._tmp=function(){var e=new i(null);return e.words=new Array(Math.ceil(this.n/13)),e},F.prototype.ireduce=function(e){var t,n=e;do{this.split(n,this.tmp),t=(n=(n=this.imulK(n)).iadd(this.tmp)).bitLength()}while(t>this.n);var o=t0?n.isub(this.p):void 0!==n.strip?n.strip():n._strip(),n},F.prototype.split=function(e,t){e.iushrn(this.n,0,t)},F.prototype.imulK=function(e){return e.imul(this.k)},r(y,F),y.prototype.split=function(e,t){for(var n=4194303,o=Math.min(e.length,9),r=0;r>>22,i=a}i>>>=22,e.words[r-10]=i,0===i&&e.length>10?e.length-=10:e.length-=9},y.prototype.imulK=function(e){e.words[e.length]=0,e.words[e.length+1]=0,e.length+=2;for(var t=0,n=0;n>>=26,e.words[n]=r,t=o}return 0!==t&&(e.words[e.length++]=t),e},i._prime=function(e){if(_[e])return _[e];var t;if("k256"===e)t=new y;else if("p224"===e)t=new b;else if("p192"===e)t=new v;else{if("p25519"!==e)throw new Error("Unknown prime "+e);t=new w}return _[e]=t,t},E.prototype._verify1=function(e){o(0===e.negative,"red works only with positives"),o(e.red,"red works only with red numbers")},E.prototype._verify2=function(e,t){o(0==(e.negative|t.negative),"red works only with positives"),o(e.red&&e.red===t.red,"red works only with red numbers")},E.prototype.imod=function(e){return this.prime?this.prime.ireduce(e)._forceRed(this):e.umod(this.m)._forceRed(this)},E.prototype.neg=function(e){return e.isZero()?e.clone():this.m.sub(e)._forceRed(this)},E.prototype.add=function(e,t){this._verify2(e,t);var n=e.add(t);return n.cmp(this.m)>=0&&n.isub(this.m),n._forceRed(this)},E.prototype.iadd=function(e,t){this._verify2(e,t);var n=e.iadd(t);return n.cmp(this.m)>=0&&n.isub(this.m),n},E.prototype.sub=function(e,t){this._verify2(e,t);var n=e.sub(t);return n.cmpn(0)<0&&n.iadd(this.m),n._forceRed(this)},E.prototype.isub=function(e,t){this._verify2(e,t);var n=e.isub(t);return n.cmpn(0)<0&&n.iadd(this.m),n},E.prototype.shl=function(e,t){return this._verify1(e),this.imod(e.ushln(t))},E.prototype.imul=function(e,t){return this._verify2(e,t),this.imod(e.imul(t))},E.prototype.mul=function(e,t){return this._verify2(e,t),this.imod(e.mul(t))},E.prototype.isqr=function(e){return this.imul(e,e.clone())},E.prototype.sqr=function(e){return this.mul(e,e)},E.prototype.sqrt=function(e){if(e.isZero())return e.clone();var t=this.m.andln(3);if(o(t%2==1),3===t){var n=this.m.add(new i(1)).iushrn(2);return this.pow(e,n)}for(var r=this.m.subn(1),a=0;!r.isZero()&&0===r.andln(1);)a++,r.iushrn(1);o(!r.isZero());var s=new i(1).toRed(this),u=s.redNeg(),c=this.m.subn(1).iushrn(1),l=this.m.bitLength();for(l=new i(2*l*l).toRed(this);0!==this.pow(l,c).cmp(u);)l.redIAdd(u);for(var d=this.pow(l,r),h=this.pow(e,r.addn(1).iushrn(1)),p=this.pow(e,r),f=a;0!==p.cmp(s);){for(var g=p,m=0;0!==g.cmp(s);m++)g=g.redSqr();o(m=0;o--){for(var c=t.words[o],l=u-1;l>=0;l--){var d=c>>l&1;r!==n[0]&&(r=this.sqr(r)),0!==d||0!==a?(a<<=1,a|=d,(4==++s||0===o&&0===l)&&(r=this.mul(r,n[a]),s=0,a=0)):s=0}u=26}return r},E.prototype.convertTo=function(e){var t=e.umod(this.m);return t===e?t.clone():t},E.prototype.convertFrom=function(e){var t=e.clone();return t.red=null,t},i.mont=function(e){return new k(e)},r(k,E),k.prototype.convertTo=function(e){return this.imod(e.ushln(this.shift))},k.prototype.convertFrom=function(e){var t=this.imod(e.mul(this.rinv));return t.red=null,t},k.prototype.imul=function(e,t){if(e.isZero()||t.isZero())return e.words[0]=0,e.length=1,e;var n=e.imul(t),o=n.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m),r=n.isub(o).iushrn(this.shift),i=r;return r.cmp(this.m)>=0?i=r.isub(this.m):r.cmpn(0)<0&&(i=r.iadd(this.m)),i._forceRed(this)},k.prototype.mul=function(e,t){if(e.isZero()||t.isZero())return new i(0)._forceRed(this);var n=e.mul(t),o=n.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m),r=n.isub(o).iushrn(this.shift),a=r;return r.cmp(this.m)>=0?a=r.isub(this.m):r.cmpn(0)<0&&(a=r.iadd(this.m)),a._forceRed(this)},k.prototype.invm=function(e){return this.imod(e._invmp(this.m).mul(this.r2))._forceRed(this)}}(e=n.nmd(e),this)},79367:function(e,t){var n,o;void 0===(o="function"==typeof(n=function(e,t){"use strict";var n,o,r="function"==typeof Map?new Map:(n=[],o=[],{has:function(e){return n.indexOf(e)>-1},get:function(e){return o[n.indexOf(e)]},set:function(e,t){-1===n.indexOf(e)&&(n.push(e),o.push(t))},delete:function(e){var t=n.indexOf(e);t>-1&&(n.splice(t,1),o.splice(t,1))}}),i=function(e){return new Event(e,{bubbles:!0})};try{new Event("test")}catch(e){i=function(e){var t=document.createEvent("Event");return t.initEvent(e,!0,!1),t}}function a(e){if(e&&e.nodeName&&"TEXTAREA"===e.nodeName&&!r.has(e)){var t=null,n=null,o=null,a=function(){e.clientWidth!==n&&d()},s=function(t){window.removeEventListener("resize",a,!1),e.removeEventListener("input",d,!1),e.removeEventListener("keyup",d,!1),e.removeEventListener("autosize:destroy",s,!1),e.removeEventListener("autosize:update",d,!1),Object.keys(t).forEach((function(n){e.style[n]=t[n]})),r.delete(e)}.bind(e,{height:e.style.height,resize:e.style.resize,overflowY:e.style.overflowY,overflowX:e.style.overflowX,wordWrap:e.style.wordWrap});e.addEventListener("autosize:destroy",s,!1),"onpropertychange"in e&&"oninput"in e&&e.addEventListener("keyup",d,!1),window.addEventListener("resize",a,!1),e.addEventListener("input",d,!1),e.addEventListener("autosize:update",d,!1),e.style.overflowX="hidden",e.style.wordWrap="break-word",r.set(e,{destroy:s,update:d}),"vertical"===(u=window.getComputedStyle(e,null)).resize?e.style.resize="none":"both"===u.resize&&(e.style.resize="horizontal"),t="content-box"===u.boxSizing?-(parseFloat(u.paddingTop)+parseFloat(u.paddingBottom)):parseFloat(u.borderTopWidth)+parseFloat(u.borderBottomWidth),isNaN(t)&&(t=0),d()}var u;function c(t){var n=e.style.width;e.style.width="0px",e.offsetWidth,e.style.width=n,e.style.overflowY=t}function l(){if(0!==e.scrollHeight){var o=function(e){for(var t=[];e&&e.parentNode&&e.parentNode instanceof Element;)e.parentNode.scrollTop&&t.push({node:e.parentNode,scrollTop:e.parentNode.scrollTop}),e=e.parentNode;return t}(e),r=document.documentElement&&document.documentElement.scrollTop;e.style.height="",e.style.height=e.scrollHeight+t+"px",n=e.clientWidth,o.forEach((function(e){e.node.scrollTop=e.scrollTop})),r&&(document.documentElement.scrollTop=r)}}function d(){l();var t=Math.round(parseFloat(e.style.height)),n=window.getComputedStyle(e,null),r="content-box"===n.boxSizing?Math.round(parseFloat(n.height)):e.offsetHeight;if(r{"use strict";var o=n(2190);e.exports=function(){return o(["BigInt64Array","BigUint64Array","Float32Array","Float64Array","Int16Array","Int32Array","Int8Array","Uint16Array","Uint32Array","Uint8Array","Uint8ClampedArray"],(function(e){return"function"==typeof n.g[e]}))}},79456:(e,t,n)=>{"use strict";var o=n(67294),r=n(73935);function i(e,t){for(var n=0;n=0;l--){var d=r[l];"."===d?p(r,l):".."===d?(p(r,l),c++):c&&(p(r,l),c--)}if(!s)for(;c--;c)r.unshift("..");!s||""===r[0]||r[0]&&h(r[0])||r.unshift("");var f=r.join("/");return n&&"/"!==f.substr(-1)&&(f+="/"),f}(r.pathname,o.pathname)):r.pathname=o.pathname:r.pathname||(r.pathname="/"),r}function w(){var e=null,t=[];return{setPrompt:function(t){return e=t,function(){e===t&&(e=null)}},confirmTransitionTo:function(t,n,o,r){if(null!=e){var i="function"==typeof e?e(t,n):e;"string"==typeof i?"function"==typeof o?o(i,r):r(!0):r(!1!==i)}else r(!0)},appendListener:function(e){var n=!0;function o(){n&&e.apply(void 0,arguments)}return t.push(o),function(){n=!1,t=t.filter((function(e){return e!==o}))}},notifyListeners:function(){for(var e=arguments.length,n=new Array(e),o=0;o=0||(r[n]=e[n]);return r}n(59864);var N=n(8679),L=n.n(N),P=function(e){var t=I();return t.displayName="Router-History",t}(),U=function(e){var t=I();return t.displayName="Router",t}(),j=function(e){function t(t){var n;return(n=e.call(this,t)||this).state={location:t.history.location},n._isMounted=!1,n._pendingLocation=null,t.staticContext||(n.unlisten=t.history.listen((function(e){n._isMounted?n.setState({location:e}):n._pendingLocation=e}))),n}u(t,e),t.computeRootMatch=function(e){return{path:"/",url:"/",params:{},isExact:"/"===e}};var n=t.prototype;return n.componentDidMount=function(){this._isMounted=!0,this._pendingLocation&&this.setState({location:this._pendingLocation})},n.componentWillUnmount=function(){this.unlisten&&this.unlisten()},n.render=function(){return o.createElement(U.Provider,{value:{history:this.props.history,location:this.state.location,match:t.computeRootMatch(this.state.location.pathname),staticContext:this.props.staticContext}},o.createElement(P.Provider,{children:this.props.children||null,value:this.props.history}))},t}(o.Component);o.Component;var q=function(e){function t(){return e.apply(this,arguments)||this}u(t,e);var n=t.prototype;return n.componentDidMount=function(){this.props.onMount&&this.props.onMount.call(this,this)},n.componentDidUpdate=function(e){this.props.onUpdate&&this.props.onUpdate.call(this,this,e)},n.componentWillUnmount=function(){this.props.onUnmount&&this.props.onUnmount.call(this,this)},n.render=function(){return null},t}(o.Component),z={},K=0;function G(e,t){return void 0===e&&(e="/"),void 0===t&&(t={}),"/"===e?e:function(e){if(z[e])return z[e];var t=O().compile(e);return K<1e4&&(z[e]=t,K++),t}(e)(t,{pretty:!0})}function $(e){var t=e.computedMatch,n=e.to,r=e.push,i=void 0!==r&&r;return o.createElement(U.Consumer,null,(function(e){e||m(!1);var r=e.history,a=e.staticContext,s=i?r.push:r.replace,u=v(t?"string"==typeof n?G(n,t.params):d({},n,{pathname:G(n.pathname,t.params)}):n);return a?(s(u),null):o.createElement(q,{onMount:function(){s(u)},onUpdate:function(e,t){var n,o,r=v(t.to);n=r,o=d({},u,{key:r.key}),n.pathname===o.pathname&&n.search===o.search&&n.hash===o.hash&&n.key===o.key&&g(n.state,o.state)||s(u)},to:n})}))}var H={},V=0;function W(e,t){void 0===t&&(t={}),("string"==typeof t||Array.isArray(t))&&(t={path:t});var n=t,o=n.path,r=n.exact,i=void 0!==r&&r,a=n.strict,s=void 0!==a&&a,u=n.sensitive,c=void 0!==u&&u;return[].concat(o).reduce((function(t,n){if(!n&&""!==n)return null;if(t)return t;var o=function(e,t){var n=""+t.end+t.strict+t.sensitive,o=H[n]||(H[n]={});if(o[e])return o[e];var r=[],i={regexp:O()(e,r,t),keys:r};return V<1e4&&(o[e]=i,V++),i}(n,{end:i,strict:s,sensitive:c}),r=o.regexp,a=o.keys,u=r.exec(e);if(!u)return null;var l=u[0],d=u.slice(1),h=e===l;return i&&!h?null:{path:n,url:"/"===n&&""===l?"/":l,isExact:h,params:a.reduce((function(e,t,n){return e[t.name]=d[n],e}),{})}}),null)}var Y=function(e){function t(){return e.apply(this,arguments)||this}return u(t,e),t.prototype.render=function(){var e=this;return o.createElement(U.Consumer,null,(function(t){t||m(!1);var n=e.props.location||t.location,r=d({},t,{location:n,match:e.props.computedMatch?e.props.computedMatch:e.props.path?W(n.pathname,e.props):t.match}),i=e.props,a=i.children,s=i.component,u=i.render;return Array.isArray(a)&&0===a.length&&(a=null),o.createElement(U.Provider,{value:r},r.match?a?"function"==typeof a?a(r):a:s?o.createElement(s,r):u?u(r):null:"function"==typeof a?a(r):null)}))},t}(o.Component);o.Component;var Z=function(e){function t(){return e.apply(this,arguments)||this}return u(t,e),t.prototype.render=function(){var e=this;return o.createElement(U.Consumer,null,(function(t){t||m(!1);var n,r,i=e.props.location||t.location;return o.Children.forEach(e.props.children,(function(e){if(null==r&&o.isValidElement(e)){n=e;var a=e.props.path||e.props.from;r=a?W(i.pathname,d({},e.props,{path:a})):t.match}})),r?o.cloneElement(n,{location:i,computedMatch:r}):null}))},t}(o.Component);o.useContext;var X=function(e){function t(){for(var t,n=arguments.length,o=new Array(n),r=0;r=0||(r[n]=e[n]);return r}(e,["sitekey","onChange","theme","type","tabindex","onExpired","onErrored","size","stoken","grecaptcha","badge","hl"]));return o.createElement("div",de({},t,{ref:this.handleRecaptchaRef}))},r}(o.Component);function fe(){return(fe=Object.assign||function(e){for(var t=1;t-1&&t[n].parentNode&&t[n].parentNode.removeChild(t[n]);var o=_e[e];o&&(delete o.observers[this.asyncScriptLoaderGetScriptLoaderID()],!0===me.removeOnUnmount&&delete _e[e])},a.render=function(){var t=me.globalName,n=this.props,r=(n.asyncScriptOnLoad,n.forwardedRef),i=function(e,t){if(null==e)return{};var n,o,r={},i=Object.keys(e);for(o=0;o=0||(r[n]=e[n]);return r}(n,["asyncScriptOnLoad","forwardedRef"]);return t&&"undefined"!=typeof window&&(i[t]=void 0!==window[t]?window[t]:void 0),i.ref=r,(0,o.createElement)(e,i)},i}(o.Component),r=(0,o.forwardRef)((function(e,t){return(0,o.createElement)(n,fe({},e,{forwardedRef:t}))}));return r.displayName="AsyncScriptLoader("+t+")",r.propTypes={asyncScriptOnLoad:l().func},L()(r,e)})(pe);var ve=n(8743),we=n(17187),Ee=n.n(we);const ke=new(n(65203).Dispatcher);function De(e){return(De="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function Se(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function xe(e,t){for(var n=0;n600&&(i=Math.floor(i*(600/a)),a=600),i>800&&(a=Math.floor(a*(800/i)),i=800);var s=document.createElement("canvas");s.width=i,s.height=a,s.getContext("2d").drawImage(e,0,0,i,a),s.toBlob((function(e){r({thumbnail:e,info:{w:i,h:a,mimetype:e.type,size:e.size}})}),o)}))}const Ge=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&Ne(e,t)}(c,e);var t,n,o,r,i,a,s,u=(a=c,s=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,t=Pe(a);if(s){var n=Pe(this).constructor;e=Reflect.construct(t,arguments,n)}else e=t.apply(this,arguments);return Le(this,e)});function c(e){var t;return function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,c),(t=u.call(this)).matrixClient=e,t.roomIdToInput=new Map,t}return t=c,(n=[{key:"cleanEmptyEntry",value:function(e){var t=this.getInput(e);void 0===t.attachment&&(void 0===t.message||""===t.message)&&this.roomIdToInput.delete(e)}},{key:"getInput",value:function(e){return this.roomIdToInput.get(e)||{}}},{key:"setMessage",value:function(e,t){var n=this.getInput(e);n.message=t,this.roomIdToInput.set(e,n),""===t&&this.cleanEmptyEntry(e)}},{key:"getMessage",value:function(e){var t=this.getInput(e);return void 0===t.message?"":t.message}},{key:"setAttachment",value:function(e,t){var n=this.getInput(e);n.attachment={file:t},this.roomIdToInput.set(e,n)}},{key:"getAttachment",value:function(e){var t=this.getInput(e);return void 0===t.attachment?null:t.attachment.file}},{key:"cancelAttachment",value:function(e){var t=this.getInput(e);if(void 0!==t.attachment){var n=t.attachment.uploadingPromise;n&&(this.matrixClient.cancelUpload(n),delete t.attachment.uploadingPromise),t.message?(delete t.attachment,delete t.isSending,this.roomIdToInput.set(e,t)):this.roomIdToInput.delete(e),this.emit(se.events.roomsInput.ATTACHMENT_CANCELED,e)}}},{key:"isSending",value:function(e){var t;return(null===(t=this.roomIdToInput.get(e))||void 0===t?void 0:t.isSending)||!1}},{key:"sendInput",value:(i=je(regeneratorRuntime.mark((function e(t){var n,o;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if((n=this.getInput(t)).isSending=!0,this.roomIdToInput.set(t,n),!n.attachment){e.next=6;break}return e.next=6,this.sendFile(t,n.attachment.file);case 6:""!==this.getMessage(t).trim()&&(o={body:n.message,msgtype:"m.text"},this.matrixClient.sendMessage(t,o)),this.isSending(t)&&this.roomIdToInput.delete(t),this.emit(se.events.roomsInput.MESSAGE_SENT,t);case 9:case"end":return e.stop()}}),e,this)}))),function(e){return i.apply(this,arguments)})},{key:"sendFile",value:(r=je(regeneratorRuntime.mark((function e(t,n){var o,r,i,a,s,u,c,l,d=this;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(o=n.type.slice(0,n.type.indexOf("/")),r={mimetype:n.type,size:n.size},i={info:r},a=null,"image"!==o){e.next=14;break}return e.next=7,qe(n);case 7:s=e.sent,r.w=s.w,r.h=s.h,i.msgtype="m.image",i.body=n.name||"Image",e.next=40;break;case 14:if("video"!==o){e.next=39;break}return i.msgtype="m.video",i.body=n.name||"Video",e.prev=17,e.next=20,ze(n);case 20:return u=e.sent,r.w=u.videoWidth,r.h=u.videoHeight,e.next=25,Ke(u,u.videoWidth,u.videoHeight,"image/jpeg");case 25:return c=e.sent,e.next=28,this.uploadFile(t,c.thumbnail);case 28:l=e.sent,r.thumbnail_info=c.info,this.matrixClient.isRoomEncrypted(t)?r.thumbnail_file=l.file:r.thumbnail_url=l.url,e.next=37;break;case 33:return e.prev=33,e.t0=e.catch(17),this.emit(se.events.roomsInput.FILE_UPLOAD_CANCELED,t),e.abrupt("return");case 37:e.next=40;break;case 39:"audio"===o?(i.msgtype="m.audio",i.body=n.name||"Audio"):(i.msgtype="m.file",i.body=n.name||"File");case 40:return e.prev=40,e.next=43,this.uploadFile(t,n,(function(e){d.emit(se.events.roomsInput.UPLOAD_PROGRESS_CHANGES,t,e)}));case 43:a=e.sent,this.emit(se.events.roomsInput.FILE_UPLOADED,t),e.next=51;break;case 47:return e.prev=47,e.t1=e.catch(40),this.emit(se.events.roomsInput.FILE_UPLOAD_CANCELED,t),e.abrupt("return");case 51:if(!this.matrixClient.isRoomEncrypted(t)){e.next=57;break}return i.file=a.file,e.next=55,this.matrixClient.sendMessage(t,i);case 55:e.next=60;break;case 57:return i.url=a.url,e.next=60,this.matrixClient.sendMessage(t,i);case 60:case"end":return e.stop()}}),e,this,[[17,33],[40,47]])}))),function(e,t){return r.apply(this,arguments)})},{key:"uploadFile",value:(o=je(regeneratorRuntime.mark((function e(t,n,o){var r,i,a,s,u,c,l,d;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(r=this.matrixClient.isRoomEncrypted(t),i=null,a=null,!r){e.next=16;break}return e.next=6,n.arrayBuffer();case 6:if(s=e.sent,void 0!==this.getInput(t).attachment){e.next=9;break}throw new Error("Attachment canceled");case 9:return e.next=11,Me.encryptAttachment(s);case 11:if(u=e.sent,void 0!==this.getInput(t).attachment){e.next=14;break}throw new Error("Attachment canceled");case 14:i=u.info,a=new Blob([u.data]);case 16:return c=this.matrixClient.uploadContent(r?a:n,{includeFilename:!r,progressHandler:o}),(l=this.getInput(t)).attachment.uploadingPromise=c,this.roomIdToInput.set(t,l),e.next=22,c;case 22:if(d=e.sent,delete l.attachment.uploadingPromise,this.roomIdToInput.set(t,l),!r){e.next=29;break}return i.url=d,n.type&&(i.mimetype=n.type),e.abrupt("return",{file:i});case 29:return e.abrupt("return",{url:d});case 30:case"end":return e.stop()}}),e,this)}))),function(e,t,n){return o.apply(this,arguments)})}])&&Be(t.prototype,n),c}(Ee());function $e(e){return($e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function He(e,t,n,o,r,i,a){try{var s=e[i](a),u=s.value}catch(e){return void n(e)}s.done?t(u):Promise.resolve(u).then(o,r)}function Ve(e){return function(){var t=this,n=arguments;return new Promise((function(o,r){var i=e.apply(t,n);function a(e){He(i,o,r,a,s,"next",e)}function s(e){He(i,o,r,a,s,"throw",e)}a(void 0)}))}}function We(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function Ye(e,t){for(var n=0;n=0;o-=1)return e.timeline[o].getId()!==n;return!0}function ct(e,t,n,o,r,i,a){try{var s=e[i](a),u=s.value}catch(e){return void n(e)}s.done?t(u):Promise.resolve(u).then(o,r)}function lt(e){return function(){var t=this,n=arguments;return new Promise((function(o,r){var i=e.apply(t,n);function a(e){ct(i,o,r,a,s,"next",e)}function s(e){ct(i,o,r,a,s,"throw",e)}a(void 0)}))}}function dt(){return(dt=lt(regeneratorRuntime.mark((function e(t,n,o){var r,i,a,s,u;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return a=null,e.prev=1,e.next=4,ot(n);case 4:a=e.sent,e.next=10;break;case 7:e.prev=7,e.t0=e.catch(1),a="https://".concat(n);case 10:if(void 0!==a){e.next=12;break}throw new Error("Homeserver not found");case 12:return s=ve.createClient({baseUrl:a}),e.next=15,s.login("m.login.password",{user:"@".concat(t,":").concat(n),password:o,initial_device_display_name:se.DEVICE_DISPLAY_NAME});case 15:u=e.sent,localStorage.setItem(se.secretKey.ACCESS_TOKEN,u.access_token),localStorage.setItem(se.secretKey.DEVICE_ID,u.device_id),localStorage.setItem(se.secretKey.USER_ID,u.user_id),localStorage.setItem(se.secretKey.BASE_URL,(null==u||null===(r=u.well_known)||void 0===r||null===(i=r["m.homeserver"])||void 0===i?void 0:i.base_url)||a);case 20:case"end":return e.stop()}}),e,null,[[1,7]])})))).apply(this,arguments)}function ht(e,t){return pt.apply(this,arguments)}function pt(){return(pt=lt(regeneratorRuntime.mark((function e(t,n){var o,r;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.prev=0,e.next=3,fetch("".concat(t,"/_matrix/client/r0/register"),{method:"POST",body:JSON.stringify(n),headers:{"Content-Type":"application/json; charset=utf-8"},credentials:"same-origin"});case 3:return o=e.sent,e.next=6,o.json();case 6:return r=e.sent,e.abrupt("return",r);case 10:throw e.prev=10,e.t0=e.catch(0),new Error(e.t0);case 13:case"end":return e.stop()}}),e,null,[[0,10]])})))).apply(this,arguments)}function ft(e,t){return gt.apply(this,arguments)}function gt(){return(gt=lt(regeneratorRuntime.mark((function e(t,n){var o,r;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.prev=0,e.next=3,fetch("".concat(t,"/_matrix/client/r0/register/email/requestToken "),{method:"POST",body:JSON.stringify(n),headers:{"Content-Type":"application/json; charset=utf-8"},credentials:"same-origin"});case 3:return o=e.sent,e.next=6,o.json();case 6:return r=e.sent,e.abrupt("return",r);case 10:throw e.prev=10,e.t0=e.catch(0),new Error(e.t0);case 13:case"end":return e.stop()}}),e,null,[[0,10]])})))).apply(this,arguments)}var mt=null,_t=null,Ft=null;function yt(){return(yt=lt(regeneratorRuntime.mark((function e(t,n,o,r,i,a,s){var u,c,l,d,h,p;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,ot(n);case 2:if(void 0!==(u=e.sent)){e.next=5;break}throw new Error("Homeserver not found");case 5:return c=ve.createClient({baseUrl:u}),e.next=8,c.isUsernameAvailable(t);case 8:if(e.sent){e.next=11;break}throw new Error("Username not available");case 11:if("string"!=typeof i){e.next=16;break}return e.next=14,ht(u,{auth:{type:"m.login.recaptcha",session:mt,response:i}});case 14:e.next=30;break;case 16:if(!0!==a){e.next=21;break}return e.next=19,ht(u,{auth:{type:"m.login.terms",session:mt}});case 19:e.next=30;break;case 21:if(!0===s){e.next=30;break}return mt=null,_t=c.generateClientSecret(),e.next=26,ft(u,{email:r,client_secret:_t,send_attempt:1});case 26:if("string"!=typeof(l=e.sent).error){e.next=29;break}throw new Error(l.error);case 29:Ft=l.sid;case 30:return e.next=32,ht(u,{auth:{session:null!==mt?mt:void 0}});case 32:if(d=e.sent,mt=d.session,void 0!==d.completed&&0!==d.completed.length){e.next=36;break}return e.abrupt("return",{type:"recaptcha",public_key:d.params["m.login.recaptcha"].public_key});case 36:if("m.login.recaptcha"!==d.completed.find((function(e){return"m.login.recaptcha"===e}))||d.completed.find((function(e){return"m.login.terms"===e}))){e.next=38;break}return e.abrupt("return",{type:"terms",en:d.params["m.login.terms"].policies.privacy_policy.en});case 38:if(!s&&"m.login.terms"!==d.completed.find((function(e){return"m.login.terms"===e}))){e.next=50;break}return h={client_secret:_t,sid:Ft},e.next=42,ht(u,{auth:{session:mt,type:"m.login.email.identity",threepidCreds:h,threepid_creds:h},username:t,password:o});case 42:if("M_UNAUTHORIZED"!==(p=e.sent).errcode){e.next=45;break}return e.abrupt("return",{type:"email"});case 45:return localStorage.setItem(se.secretKey.ACCESS_TOKEN,p.access_token),localStorage.setItem(se.secretKey.DEVICE_ID,p.device_id),localStorage.setItem(se.secretKey.USER_ID,p.user_id),localStorage.setItem(se.secretKey.BASE_URL,u),e.abrupt("return",{type:"done"});case 50:return e.abrupt("return",{});case 51:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function bt(e){var t=e.id,n=e.className,r=e.variant,i=e.children,a=""!==n?"".concat(n," "):"";return"h1"===r?o.createElement("h1",{id:""===t?void 0:t,className:"".concat(a,"text text-h1")},i):"h2"===r?o.createElement("h2",{id:""===t?void 0:t,className:"".concat(a,"text text-h2")},i):"s1"===r?o.createElement("h4",{id:""===t?void 0:t,className:"".concat(a,"text text-s1")},i):o.createElement("p",{id:""===t?void 0:t,className:"".concat(a,"text text-").concat(r)},i)}bt.defaultProps={id:"",className:"",variant:"b1"},bt.propTypes={id:l().string,className:l().string,variant:l().oneOf(["h1","h2","s1","b1","b2","b3"]),children:l().node.isRequired};const vt=bt;function wt(e){var t=e.color,n=e.size,r=e.src,i={WebkitMaskImage:"url(".concat(r,")"),maskImage:"url(".concat(r,")")};return null!==t&&(i.backgroundColor=t),o.createElement("span",{className:"ic-raw ic-raw-".concat(n),style:i}," ")}wt.defaultProps={color:null,size:"normal"},wt.propTypes={color:l().string,size:l().oneOf(["large","normal","small","extra-small"]),src:l().string.isRequired};const Et=wt;function kt(e){return(kt="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function Dt(e,t){for(var n=e.nativeEvent.composedPath(),o=function(e){return n[e]===document?(console.warn(Dt,"blurOnBubbling: not found selector in bubbling path"),"break"):n[e].matches(t)?(setTimeout((function(){return n[e].blur()}),50),{v:!0}):void 0},r=0;re.length)&&(t=e.length);for(var n=0,o=new Array(t);n255?Ht(u.current,"Your user ID, including the hostname, can't be more than 255 characters long."):p():Ht(h.current,Kt):Ht(d.current,qt):Ht(l.current,jt):Ht(u.current,Lt)};return o.createElement(o.Fragment,null,"loading"===(null==a?void 0:a.type)&&o.createElement(Zt,{message:a.message}),"recaptcha"===(null==a?void 0:a.type)&&o.createElement(Xt,{message:"Please check the box below to proceed.",sitekey:a.sitekey,onChange:function(e){"string"==typeof e&&p(e)}}),"terms"===(null==a?void 0:a.type)&&o.createElement(Jt,{url:a.en.url,onSubmit:p}),"email"===(null==a?void 0:a.type)&&o.createElement(Qt,null,o.createElement("div",{style:{margin:"var(--sp-normal)",maxWidth:"450px"}},o.createElement(vt,{variant:"h2"},"Verify email"),o.createElement("div",{style:{margin:"var(--sp-normal) 0"}},o.createElement(vt,{variant:"b1"},"Please check your email"," ",o.createElement("b",null,"(".concat(h.current.value,")"))," ","and validate before continuing further.")),o.createElement(xt,{variant:"primary",onClick:function(){return p(void 0,void 0,!0)}},"Continue"))),o.createElement(Yt,null,o.createElement("div",{className:"auth-form__wrapper flex-v--center"},o.createElement("form",{onSubmit:f,className:"auth-form"},o.createElement(vt,{variant:"h2"},"login"===r?"Login":"Register"),o.createElement("div",{className:"username__wrapper"},o.createElement(Tt,{forwardRef:u,onChange:function(e){return Vt(e,"login"===r?Bt:Nt,Lt)},id:"auth_username",label:"Username",required:!0}),o.createElement(Tt,{forwardRef:c,id:"auth_homeserver",placeholder:"Homeserver",value:"matrix.org",required:!0})),o.createElement(Tt,{forwardRef:l,onChange:function(e){return Vt(e,"login"===r?Pt:Ut,jt)},id:"auth_password",type:"password",label:"Password",required:!0}),"register"===r&&o.createElement(o.Fragment,null,o.createElement(Tt,{forwardRef:d,onChange:function(e){return Vt(e,new RegExp("^(".concat(l.current.value,")$")),qt)},id:"auth_confirmPassword",type:"password",label:"Confirm password",required:!0}),o.createElement(Tt,{forwardRef:h,onChange:function(e){return Vt(e,zt,Kt)},id:"auth_email",type:"email",label:"Email",required:!0})),o.createElement("div",{className:"submit-btn__wrapper flex--end"},o.createElement(vt,{id:"auth_error",className:"error-message",variant:"b3"},"Error"),o.createElement(xt,{id:"auth_submit-btn",variant:"primary",type:"submit"},"login"===r?"Login":"Register")))),o.createElement("div",{className:"flex--center"},o.createElement(vt,{variant:"b2"},"".concat("login"===r?"Don't have":"Already have"," an account?"),o.createElement(oe,{to:"login"===r?"/register":"/login"},"login"===r?" Register":" Login")))))}function Yt(e){var t=e.children;return o.createElement("div",{className:"auth__wrapper flex--center"},o.createElement("div",{className:"auth-card"},o.createElement("div",{className:"auth-card__interactive flex-v"},o.createElement("div",{className:"app-ident flex"},o.createElement("img",{className:"app-ident__logo noselect",src:Mt,alt:"Cinny logo"}),o.createElement("div",{className:"app-ident__text flex-v--center"},o.createElement(vt,{variant:"h2"},"Cinny"),o.createElement(vt,{variant:"b2"},"Yet another matrix client."))),t)))}function Zt(e){var t=e.message;return o.createElement(Qt,null,o.createElement(It,null),o.createElement("div",{style:{marginTop:"var(--sp-normal)"}},o.createElement(vt,{variant:"b1"},t)))}function Xt(e){var t=e.message,n=e.sitekey,r=e.onChange;return o.createElement(Qt,null,o.createElement("div",{style:{marginBottom:"var(--sp-normal)"}},o.createElement(vt,{variant:"s1"},t)),o.createElement(be,{sitekey:n,onChange:r}))}function Jt(e){var t=e.url,n=e.onSubmit;return o.createElement(Qt,null,o.createElement("form",{onSubmit:function(){return n(void 0,!0)}},o.createElement("div",{style:{margin:"var(--sp-normal)",maxWidth:"450px"}},o.createElement(vt,{variant:"h2"},"Agree with terms"),o.createElement("div",{style:{marginBottom:"var(--sp-normal)"}}),o.createElement(vt,{variant:"b1"},"In order to complete registration, you need to agree with terms and conditions."),o.createElement("div",{style:{display:"flex",alignItems:"center",margin:"var(--sp-normal) 0"}},o.createElement("input",{id:"termsCheckbox",type:"checkbox",required:!0}),o.createElement(vt,{variant:"b1"},"I accept ",o.createElement("a",{style:{cursor:"pointer"},href:t,rel:"noreferrer",target:"_blank"},"Terms and Conditions"))),o.createElement(xt,{id:"termsBtn",type:"submit",variant:"primary"},"Submit"))))}function Qt(e){var t=e.children;return o.createElement("div",{className:"process-wrapper"},t)}Wt.propTypes={type:l().string.isRequired},Yt.propTypes={children:l().node.isRequired},Zt.propTypes={message:l().string.isRequired},Xt.propTypes={message:l().string.isRequired,sitekey:l().string.isRequired,onChange:l().func.isRequired},Jt.propTypes={url:l().string.isRequired,onSubmit:l().func.isRequired},Qt.propTypes={children:l().node.isRequired};const en=Wt;function tn(e){return(tn="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function nn(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function on(e,t){for(var n=0;n=0?e.ownerDocument.body:En(e)&&An(e)?e:Mn(In(e))}function On(e,t){var n;void 0===t&&(t=[]);var o=Mn(e),r=o===(null==(n=e.ownerDocument)?void 0:n.body),i=bn(o),a=r?[i].concat(i.visualViewport||[],An(o)?o:[]):o,s=t.concat(a);return r?s:s.concat(On(In(a)))}function Bn(e){return["table","td","th"].indexOf(Dn(e))>=0}function Nn(e){return En(e)&&"fixed"!==Cn(e).position?e.offsetParent:null}function Ln(e){for(var t=bn(e),n=Nn(e);n&&Bn(n)&&"static"===Cn(n).position;)n=Nn(n);return n&&("html"===Dn(n)||"body"===Dn(n)&&"static"===Cn(n).position)?t:n||function(e){var t=-1!==navigator.userAgent.toLowerCase().indexOf("firefox");if(-1!==navigator.userAgent.indexOf("Trident")&&En(e)&&"fixed"===Cn(e).position)return null;for(var n=In(e);En(n)&&["html","body"].indexOf(Dn(n))<0;){var o=Cn(n);if("none"!==o.transform||"none"!==o.perspective||"paint"===o.contain||-1!==["transform","perspective"].indexOf(o.willChange)||t&&"filter"===o.willChange||t&&o.filter&&"none"!==o.filter)return n;n=n.parentNode}return null}(e)||t}var Pn="top",Un="bottom",jn="right",qn="left",zn="auto",Kn=[Pn,Un,jn,qn],Gn="start",$n="end",Hn="viewport",Vn="popper",Wn=Kn.reduce((function(e,t){return e.concat([t+"-"+Gn,t+"-"+$n])}),[]),Yn=[].concat(Kn,[zn]).reduce((function(e,t){return e.concat([t,t+"-"+Gn,t+"-"+$n])}),[]),Zn=["beforeRead","read","afterRead","beforeMain","main","afterMain","beforeWrite","write","afterWrite"];function Xn(e){var t=new Map,n=new Set,o=[];function r(e){n.add(e.name),[].concat(e.requires||[],e.requiresIfExists||[]).forEach((function(e){if(!n.has(e)){var o=t.get(e);o&&r(o)}})),o.push(e)}return e.forEach((function(e){t.set(e.name,e)})),e.forEach((function(e){n.has(e.name)||r(e)})),o}var Jn={placement:"bottom",modifiers:[],strategy:"absolute"};function Qn(){for(var e=arguments.length,t=new Array(e),n=0;n=0?"x":"y"}function ao(e){var t,n=e.reference,o=e.element,r=e.placement,i=r?oo(r):null,a=r?ro(r):null,s=n.x+n.width/2-o.width/2,u=n.y+n.height/2-o.height/2;switch(i){case Pn:t={x:s,y:n.y-o.height};break;case Un:t={x:s,y:n.y+n.height};break;case jn:t={x:n.x+n.width,y:u};break;case qn:t={x:n.x-o.width,y:u};break;default:t={x:n.x,y:n.y}}var c=i?io(i):null;if(null!=c){var l="y"===c?"height":"width";switch(a){case Gn:t[c]=t[c]-(n[l]/2-o[l]/2);break;case $n:t[c]=t[c]+(n[l]/2-o[l]/2)}}return t}const so={name:"popperOffsets",enabled:!0,phase:"read",fn:function(e){var t=e.state,n=e.name;t.modifiersData[n]=ao({reference:t.rects.reference,element:t.rects.popper,strategy:"absolute",placement:t.placement})},data:{}};var uo=Math.max,co=Math.min,lo=Math.round,ho={top:"auto",right:"auto",bottom:"auto",left:"auto"};function po(e){var t,n=e.popper,o=e.popperRect,r=e.placement,i=e.offsets,a=e.position,s=e.gpuAcceleration,u=e.adaptive,c=e.roundOffsets,l=!0===c?function(e){var t=e.x,n=e.y,o=window.devicePixelRatio||1;return{x:lo(lo(t*o)/o)||0,y:lo(lo(n*o)/o)||0}}(i):"function"==typeof c?c(i):i,d=l.x,h=void 0===d?0:d,p=l.y,f=void 0===p?0:p,g=i.hasOwnProperty("x"),m=i.hasOwnProperty("y"),_=qn,F=Pn,y=window;if(u){var b=Ln(n),v="clientHeight",w="clientWidth";b===bn(n)&&"static"!==Cn(b=Sn(n)).position&&(v="scrollHeight",w="scrollWidth"),b=b,r===Pn&&(F=Un,f-=b[v]-o.height,f*=s?1:-1),r===qn&&(_=jn,h-=b[w]-o.width,h*=s?1:-1)}var E,k=Object.assign({position:a},u&&ho);return s?Object.assign({},k,((E={})[F]=m?"0":"",E[_]=g?"0":"",E.transform=(y.devicePixelRatio||1)<2?"translate("+h+"px, "+f+"px)":"translate3d("+h+"px, "+f+"px, 0)",E)):Object.assign({},k,((t={})[F]=m?f+"px":"",t[_]=g?h+"px":"",t.transform="",t))}const fo={name:"applyStyles",enabled:!0,phase:"write",fn:function(e){var t=e.state;Object.keys(t.elements).forEach((function(e){var n=t.styles[e]||{},o=t.attributes[e]||{},r=t.elements[e];En(r)&&Dn(r)&&(Object.assign(r.style,n),Object.keys(o).forEach((function(e){var t=o[e];!1===t?r.removeAttribute(e):r.setAttribute(e,!0===t?"":t)})))}))},effect:function(e){var t=e.state,n={popper:{position:t.options.strategy,left:"0",top:"0",margin:"0"},arrow:{position:"absolute"},reference:{}};return Object.assign(t.elements.popper.style,n.popper),t.styles=n,t.elements.arrow&&Object.assign(t.elements.arrow.style,n.arrow),function(){Object.keys(t.elements).forEach((function(e){var o=t.elements[e],r=t.attributes[e]||{},i=Object.keys(t.styles.hasOwnProperty(e)?t.styles[e]:n[e]).reduce((function(e,t){return e[t]="",e}),{});En(o)&&Dn(o)&&(Object.assign(o.style,i),Object.keys(r).forEach((function(e){o.removeAttribute(e)})))}))}},requires:["computeStyles"]};var go={left:"right",right:"left",bottom:"top",top:"bottom"};function mo(e){return e.replace(/left|right|bottom|top/g,(function(e){return go[e]}))}var _o={start:"end",end:"start"};function Fo(e){return e.replace(/start|end/g,(function(e){return _o[e]}))}function yo(e,t){var n=t.getRootNode&&t.getRootNode();if(e.contains(t))return!0;if(n&&kn(n)){var o=t;do{if(o&&e.isSameNode(o))return!0;o=o.parentNode||o.host}while(o)}return!1}function bo(e){return Object.assign({},e,{left:e.x,top:e.y,right:e.x+e.width,bottom:e.y+e.height})}function vo(e,t){return t===Hn?bo(function(e){var t=bn(e),n=Sn(e),o=t.visualViewport,r=n.clientWidth,i=n.clientHeight,a=0,s=0;return o&&(r=o.width,i=o.height,/^((?!chrome|android).)*safari/i.test(navigator.userAgent)||(a=o.offsetLeft,s=o.offsetTop)),{width:r,height:i,x:a+xn(e),y:s}}(e)):En(t)?function(e){var t=yn(e);return t.top=t.top+e.clientTop,t.left=t.left+e.clientLeft,t.bottom=t.top+e.clientHeight,t.right=t.left+e.clientWidth,t.width=e.clientWidth,t.height=e.clientHeight,t.x=t.left,t.y=t.top,t}(t):bo(function(e){var t,n=Sn(e),o=vn(e),r=null==(t=e.ownerDocument)?void 0:t.body,i=uo(n.scrollWidth,n.clientWidth,r?r.scrollWidth:0,r?r.clientWidth:0),a=uo(n.scrollHeight,n.clientHeight,r?r.scrollHeight:0,r?r.clientHeight:0),s=-o.scrollLeft+xn(e),u=-o.scrollTop;return"rtl"===Cn(r||n).direction&&(s+=uo(n.clientWidth,r?r.clientWidth:0)-i),{width:i,height:a,x:s,y:u}}(Sn(e)))}function wo(e){return Object.assign({},{top:0,right:0,bottom:0,left:0},e)}function Eo(e,t){return t.reduce((function(t,n){return t[n]=e,t}),{})}function ko(e,t){void 0===t&&(t={});var n=t,o=n.placement,r=void 0===o?e.placement:o,i=n.boundary,a=void 0===i?"clippingParents":i,s=n.rootBoundary,u=void 0===s?Hn:s,c=n.elementContext,l=void 0===c?Vn:c,d=n.altBoundary,h=void 0!==d&&d,p=n.padding,f=void 0===p?0:p,g=wo("number"!=typeof f?f:Eo(f,Kn)),m=l===Vn?"reference":Vn,_=e.elements.reference,F=e.rects.popper,y=e.elements[h?m:l],b=function(e,t,n){var o="clippingParents"===t?function(e){var t=On(In(e)),n=["absolute","fixed"].indexOf(Cn(e).position)>=0&&En(e)?Ln(e):e;return wn(n)?t.filter((function(e){return wn(e)&&yo(e,n)&&"body"!==Dn(e)})):[]}(e):[].concat(t),r=[].concat(o,[n]),i=r[0],a=r.reduce((function(t,n){var o=vo(e,n);return t.top=uo(o.top,t.top),t.right=co(o.right,t.right),t.bottom=co(o.bottom,t.bottom),t.left=uo(o.left,t.left),t}),vo(e,i));return a.width=a.right-a.left,a.height=a.bottom-a.top,a.x=a.left,a.y=a.top,a}(wn(y)?y:y.contextElement||Sn(e.elements.popper),a,u),v=yn(_),w=ao({reference:v,element:F,strategy:"absolute",placement:r}),E=bo(Object.assign({},F,w)),k=l===Vn?E:v,D={top:b.top-k.top+g.top,bottom:k.bottom-b.bottom+g.bottom,left:b.left-k.left+g.left,right:k.right-b.right+g.right},S=e.modifiersData.offset;if(l===Vn&&S){var x=S[r];Object.keys(D).forEach((function(e){var t=[jn,Un].indexOf(e)>=0?1:-1,n=[Pn,Un].indexOf(e)>=0?"y":"x";D[e]+=x[n]*t}))}return D}function Do(e,t,n){return uo(e,co(t,n))}function So(e,t,n){return void 0===n&&(n={x:0,y:0}),{top:e.top-t.height-n.y,right:e.right-t.width+n.x,bottom:e.bottom-t.height+n.y,left:e.left-t.width-n.x}}function xo(e){return[Pn,jn,Un,qn].some((function(t){return e[t]>=0}))}var Co=eo({defaultModifiers:[no,so,{name:"computeStyles",enabled:!0,phase:"beforeWrite",fn:function(e){var t=e.state,n=e.options,o=n.gpuAcceleration,r=void 0===o||o,i=n.adaptive,a=void 0===i||i,s=n.roundOffsets,u=void 0===s||s,c={placement:oo(t.placement),popper:t.elements.popper,popperRect:t.rects.popper,gpuAcceleration:r};null!=t.modifiersData.popperOffsets&&(t.styles.popper=Object.assign({},t.styles.popper,po(Object.assign({},c,{offsets:t.modifiersData.popperOffsets,position:t.options.strategy,adaptive:a,roundOffsets:u})))),null!=t.modifiersData.arrow&&(t.styles.arrow=Object.assign({},t.styles.arrow,po(Object.assign({},c,{offsets:t.modifiersData.arrow,position:"absolute",adaptive:!1,roundOffsets:u})))),t.attributes.popper=Object.assign({},t.attributes.popper,{"data-popper-placement":t.placement})},data:{}},fo,{name:"offset",enabled:!0,phase:"main",requires:["popperOffsets"],fn:function(e){var t=e.state,n=e.options,o=e.name,r=n.offset,i=void 0===r?[0,0]:r,a=Yn.reduce((function(e,n){return e[n]=function(e,t,n){var o=oo(e),r=[qn,Pn].indexOf(o)>=0?-1:1,i="function"==typeof n?n(Object.assign({},t,{placement:e})):n,a=i[0],s=i[1];return a=a||0,s=(s||0)*r,[qn,jn].indexOf(o)>=0?{x:s,y:a}:{x:a,y:s}}(n,t.rects,i),e}),{}),s=a[t.placement],u=s.x,c=s.y;null!=t.modifiersData.popperOffsets&&(t.modifiersData.popperOffsets.x+=u,t.modifiersData.popperOffsets.y+=c),t.modifiersData[o]=a}},{name:"flip",enabled:!0,phase:"main",fn:function(e){var t=e.state,n=e.options,o=e.name;if(!t.modifiersData[o]._skip){for(var r=n.mainAxis,i=void 0===r||r,a=n.altAxis,s=void 0===a||a,u=n.fallbackPlacements,c=n.padding,l=n.boundary,d=n.rootBoundary,h=n.altBoundary,p=n.flipVariations,f=void 0===p||p,g=n.allowedAutoPlacements,m=t.options.placement,_=oo(m),F=u||(_!==m&&f?function(e){if(oo(e)===zn)return[];var t=mo(e);return[Fo(e),t,Fo(t)]}(m):[mo(m)]),y=[m].concat(F).reduce((function(e,n){return e.concat(oo(n)===zn?function(e,t){void 0===t&&(t={});var n=t,o=n.placement,r=n.boundary,i=n.rootBoundary,a=n.padding,s=n.flipVariations,u=n.allowedAutoPlacements,c=void 0===u?Yn:u,l=ro(o),d=l?s?Wn:Wn.filter((function(e){return ro(e)===l})):Kn,h=d.filter((function(e){return c.indexOf(e)>=0}));0===h.length&&(h=d);var p=h.reduce((function(t,n){return t[n]=ko(e,{placement:n,boundary:r,rootBoundary:i,padding:a})[oo(n)],t}),{});return Object.keys(p).sort((function(e,t){return p[e]-p[t]}))}(t,{placement:n,boundary:l,rootBoundary:d,padding:c,flipVariations:f,allowedAutoPlacements:g}):n)}),[]),b=t.rects.reference,v=t.rects.popper,w=new Map,E=!0,k=y[0],D=0;D=0,T=A?"width":"height",R=ko(t,{placement:S,boundary:l,rootBoundary:d,altBoundary:h,padding:c}),I=A?C?jn:qn:C?Un:Pn;b[T]>v[T]&&(I=mo(I));var M=mo(I),O=[];if(i&&O.push(R[x]<=0),s&&O.push(R[I]<=0,R[M]<=0),O.every((function(e){return e}))){k=S,E=!1;break}w.set(S,O)}if(E)for(var B=function(e){var t=y.find((function(t){var n=w.get(t);if(n)return n.slice(0,e).every((function(e){return e}))}));if(t)return k=t,"break"},N=f?3:1;N>0&&"break"!==B(N);N--);t.placement!==k&&(t.modifiersData[o]._skip=!0,t.placement=k,t.reset=!0)}},requiresIfExists:["offset"],data:{_skip:!1}},{name:"preventOverflow",enabled:!0,phase:"main",fn:function(e){var t=e.state,n=e.options,o=e.name,r=n.mainAxis,i=void 0===r||r,a=n.altAxis,s=void 0!==a&&a,u=n.boundary,c=n.rootBoundary,l=n.altBoundary,d=n.padding,h=n.tether,p=void 0===h||h,f=n.tetherOffset,g=void 0===f?0:f,m=ko(t,{boundary:u,rootBoundary:c,padding:d,altBoundary:l}),_=oo(t.placement),F=ro(t.placement),y=!F,b=io(_),v="x"===b?"y":"x",w=t.modifiersData.popperOffsets,E=t.rects.reference,k=t.rects.popper,D="function"==typeof g?g(Object.assign({},t.rects,{placement:t.placement})):g,S={x:0,y:0};if(w){if(i||s){var x="y"===b?Pn:qn,C="y"===b?Un:jn,A="y"===b?"height":"width",T=w[b],R=w[b]+m[x],I=w[b]-m[C],M=p?-k[A]/2:0,O=F===Gn?E[A]:k[A],B=F===Gn?-k[A]:-E[A],N=t.elements.arrow,L=p&&N?Rn(N):{width:0,height:0},P=t.modifiersData["arrow#persistent"]?t.modifiersData["arrow#persistent"].padding:{top:0,right:0,bottom:0,left:0},U=P[x],j=P[C],q=Do(0,E[A],L[A]),z=y?E[A]/2-M-q-U-D:O-q-U-D,K=y?-E[A]/2+M+q+j+D:B+q+j+D,G=t.elements.arrow&&Ln(t.elements.arrow),$=G?"y"===b?G.clientTop||0:G.clientLeft||0:0,H=t.modifiersData.offset?t.modifiersData.offset[t.placement][b]:0,V=w[b]+z-H-$,W=w[b]+K-H;if(i){var Y=Do(p?co(R,V):R,T,p?uo(I,W):I);w[b]=Y,S[b]=Y-T}if(s){var Z="x"===b?Pn:qn,X="x"===b?Un:jn,J=w[v],Q=J+m[Z],ee=J-m[X],te=Do(p?co(Q,V):Q,J,p?uo(ee,W):ee);w[v]=te,S[v]=te-J}}t.modifiersData[o]=S}},requiresIfExists:["offset"]},{name:"arrow",enabled:!0,phase:"main",fn:function(e){var t,n=e.state,o=e.name,r=e.options,i=n.elements.arrow,a=n.modifiersData.popperOffsets,s=oo(n.placement),u=io(s),c=[qn,jn].indexOf(s)>=0?"height":"width";if(i&&a){var l=function(e,t){return wo("number"!=typeof(e="function"==typeof e?e(Object.assign({},t.rects,{placement:t.placement})):e)?e:Eo(e,Kn))}(r.padding,n),d=Rn(i),h="y"===u?Pn:qn,p="y"===u?Un:jn,f=n.rects.reference[c]+n.rects.reference[u]-a[u]-n.rects.popper[c],g=a[u]-n.rects.reference[u],m=Ln(i),_=m?"y"===u?m.clientHeight||0:m.clientWidth||0:0,F=f/2-g/2,y=l[h],b=_-d[c]-l[p],v=_/2-d[c]/2+F,w=Do(y,v,b),E=u;n.modifiersData[o]=((t={})[E]=w,t.centerOffset=w-v,t)}},effect:function(e){var t=e.state,n=e.options.element,o=void 0===n?"[data-popper-arrow]":n;null!=o&&("string"!=typeof o||(o=t.elements.popper.querySelector(o)))&&yo(t.elements.popper,o)&&(t.elements.arrow=o)},requires:["popperOffsets"],requiresIfExists:["preventOverflow"]},{name:"hide",enabled:!0,phase:"main",requiresIfExists:["preventOverflow"],fn:function(e){var t=e.state,n=e.name,o=t.rects.reference,r=t.rects.popper,i=t.modifiersData.preventOverflow,a=ko(t,{elementContext:"reference"}),s=ko(t,{altBoundary:!0}),u=So(a,o),c=So(s,r,i),l=xo(u),d=xo(c);t.modifiersData[n]={referenceClippingOffsets:u,popperEscapeOffsets:c,isReferenceHidden:l,hasPopperEscaped:d},t.attributes.popper=Object.assign({},t.attributes.popper,{"data-popper-reference-hidden":l,"data-popper-escaped":d})}}]}),Ao="tippy-content",To="tippy-arrow",Ro="tippy-svg-arrow",Io={passive:!0,capture:!0};function Mo(e,t,n){if(Array.isArray(e)){var o=e[t];return null==o?Array.isArray(n)?n[t]:n:o}return e}function Oo(e,t){var n={}.toString.call(e);return 0===n.indexOf("[object")&&n.indexOf(t+"]")>-1}function Bo(e,t){return"function"==typeof e?e.apply(void 0,t):e}function No(e,t){return 0===t?e:function(o){clearTimeout(n),n=setTimeout((function(){e(o)}),t)};var n}function Lo(e){return[].concat(e)}function Po(e,t){-1===e.indexOf(t)&&e.push(t)}function Uo(e){return[].slice.call(e)}function jo(){return document.createElement("div")}function qo(e){return["Element","Fragment"].some((function(t){return Oo(e,t)}))}function zo(e,t){e.forEach((function(e){e&&(e.style.transitionDuration=t+"ms")}))}function Ko(e,t){e.forEach((function(e){e&&e.setAttribute("data-state",t)}))}function Go(e,t,n){var o=t+"EventListener";["transitionend","webkitTransitionEnd"].forEach((function(t){e[o](t,n)}))}var $o={isTouch:!1},Ho=0;function Vo(){$o.isTouch||($o.isTouch=!0,window.performance&&document.addEventListener("mousemove",Wo))}function Wo(){var e=performance.now();e-Ho<20&&($o.isTouch=!1,document.removeEventListener("mousemove",Wo)),Ho=e}function Yo(){var e,t=document.activeElement;if((e=t)&&e._tippy&&e._tippy.reference===e){var n=t._tippy;t.blur&&!n.state.isVisible&&t.blur()}}var Zo="undefined"!=typeof window&&"undefined"!=typeof document?navigator.userAgent:"",Xo=/MSIE |Trident\//.test(Zo),Jo=Object.assign({appendTo:function(){return document.body},aria:{content:"auto",expanded:"auto"},delay:0,duration:[300,250],getReferenceClientRect:null,hideOnClick:!0,ignoreAttributes:!1,interactive:!1,interactiveBorder:2,interactiveDebounce:0,moveTransition:"",offset:[0,10],onAfterUpdate:function(){},onBeforeUpdate:function(){},onCreate:function(){},onDestroy:function(){},onHidden:function(){},onHide:function(){},onMount:function(){},onShow:function(){},onShown:function(){},onTrigger:function(){},onUntrigger:function(){},onClickOutside:function(){},placement:"top",plugins:[],popperOptions:{},render:null,showOnCreate:!1,touch:!0,trigger:"mouseenter focus",triggerTarget:null},{animateFill:!1,followCursor:!1,inlinePositioning:!1,sticky:!1},{},{allowHTML:!1,animation:"fade",arrow:!0,content:"",inertia:!1,maxWidth:350,role:"tooltip",theme:"",zIndex:9999}),Qo=Object.keys(Jo);function er(e){var t=(e.plugins||[]).reduce((function(t,n){var o=n.name,r=n.defaultValue;return o&&(t[o]=void 0!==e[o]?e[o]:r),t}),{});return Object.assign({},e,{},t)}function tr(e,t){var n=Object.assign({},t,{content:Bo(t.content,[e])},t.ignoreAttributes?{}:function(e,t){return(t?Object.keys(er(Object.assign({},Jo,{plugins:t}))):Qo).reduce((function(t,n){var o=(e.getAttribute("data-tippy-"+n)||"").trim();if(!o)return t;if("content"===n)t[n]=o;else try{t[n]=JSON.parse(o)}catch(e){t[n]=o}return t}),{})}(e,t.plugins));return n.aria=Object.assign({},Jo.aria,{},n.aria),n.aria={expanded:"auto"===n.aria.expanded?t.interactive:n.aria.expanded,content:"auto"===n.aria.content?t.interactive?null:"describedby":n.aria.content},n}function nr(e,t){e.innerHTML=t}function or(e){var t=jo();return!0===e?t.className=To:(t.className=Ro,qo(e)?t.appendChild(e):nr(t,e)),t}function rr(e,t){qo(t.content)?(nr(e,""),e.appendChild(t.content)):"function"!=typeof t.content&&(t.allowHTML?nr(e,t.content):e.textContent=t.content)}function ir(e){var t=e.firstElementChild,n=Uo(t.children);return{box:t,content:n.find((function(e){return e.classList.contains(Ao)})),arrow:n.find((function(e){return e.classList.contains(To)||e.classList.contains(Ro)})),backdrop:n.find((function(e){return e.classList.contains("tippy-backdrop")}))}}function ar(e){var t=jo(),n=jo();n.className="tippy-box",n.setAttribute("data-state","hidden"),n.setAttribute("tabindex","-1");var o=jo();function r(n,o){var r=ir(t),i=r.box,a=r.content,s=r.arrow;o.theme?i.setAttribute("data-theme",o.theme):i.removeAttribute("data-theme"),"string"==typeof o.animation?i.setAttribute("data-animation",o.animation):i.removeAttribute("data-animation"),o.inertia?i.setAttribute("data-inertia",""):i.removeAttribute("data-inertia"),i.style.maxWidth="number"==typeof o.maxWidth?o.maxWidth+"px":o.maxWidth,o.role?i.setAttribute("role",o.role):i.removeAttribute("role"),n.content===o.content&&n.allowHTML===o.allowHTML||rr(a,e.props),o.arrow?s?n.arrow!==o.arrow&&(i.removeChild(s),i.appendChild(or(o.arrow))):i.appendChild(or(o.arrow)):s&&i.removeChild(s)}return o.className=Ao,o.setAttribute("data-state","hidden"),rr(o,e.props),t.appendChild(n),n.appendChild(o),r(e.props,e.props),{popper:t,onUpdate:r}}ar.$$tippy=!0;var sr=1,ur=[],cr=[];function lr(e,t){var n,o,r,i,a,s,u,c,l,d=tr(e,Object.assign({},Jo,{},er((n=t,Object.keys(n).reduce((function(e,t){return void 0!==n[t]&&(e[t]=n[t]),e}),{}))))),h=!1,p=!1,f=!1,g=!1,m=[],_=No(W,d.interactiveDebounce),F=sr++,y=(l=d.plugins).filter((function(e,t){return l.indexOf(e)===t})),b={id:F,reference:e,popper:jo(),popperInstance:null,props:d,state:{isEnabled:!0,isVisible:!1,isDestroyed:!1,isMounted:!1,isShown:!1},plugins:y,clearDelayTimeouts:function(){clearTimeout(o),clearTimeout(r),cancelAnimationFrame(i)},setProps:function(t){if(!b.state.isDestroyed){O("onBeforeUpdate",[b,t]),H();var n=b.props,o=tr(e,Object.assign({},b.props,{},t,{ignoreAttributes:!0}));b.props=o,$(),n.interactiveDebounce!==o.interactiveDebounce&&(L(),_=No(W,o.interactiveDebounce)),n.triggerTarget&&!o.triggerTarget?Lo(n.triggerTarget).forEach((function(e){e.removeAttribute("aria-expanded")})):o.triggerTarget&&e.removeAttribute("aria-expanded"),N(),M(),E&&E(n,o),b.popperInstance&&(J(),ee().forEach((function(e){requestAnimationFrame(e._tippy.popperInstance.forceUpdate)}))),O("onAfterUpdate",[b,t])}},setContent:function(e){b.setProps({content:e})},show:function(){var e=b.state.isVisible,t=b.state.isDestroyed,n=!b.state.isEnabled,o=$o.isTouch&&!b.props.touch,r=Mo(b.props.duration,0,Jo.duration);if(!(e||t||n||o||A().hasAttribute("disabled")||(O("onShow",[b],!1),!1===b.props.onShow(b)))){if(b.state.isVisible=!0,C()&&(w.style.visibility="visible"),M(),q(),b.state.isMounted||(w.style.transition="none"),C()){var i=R();zo([i.box,i.content],0)}var a,s,c;u=function(){var e;if(b.state.isVisible&&!g){if(g=!0,w.offsetHeight,w.style.transition=b.props.moveTransition,C()&&b.props.animation){var t=R(),n=t.box,o=t.content;zo([n,o],r),Ko([n,o],"visible")}B(),N(),Po(cr,b),null==(e=b.popperInstance)||e.forceUpdate(),b.state.isMounted=!0,O("onMount",[b]),b.props.animation&&C()&&function(e,t){K(e,(function(){b.state.isShown=!0,O("onShown",[b])}))}(r)}},s=b.props.appendTo,c=A(),(a=b.props.interactive&&s===Jo.appendTo||"parent"===s?c.parentNode:Bo(s,[c])).contains(w)||a.appendChild(w),J()}},hide:function(){var e=!b.state.isVisible,t=b.state.isDestroyed,n=!b.state.isEnabled,o=Mo(b.props.duration,1,Jo.duration);if(!(e||t||n)&&(O("onHide",[b],!1),!1!==b.props.onHide(b))){if(b.state.isVisible=!1,b.state.isShown=!1,g=!1,h=!1,C()&&(w.style.visibility="hidden"),L(),z(),M(),C()){var r=R(),i=r.box,a=r.content;b.props.animation&&(zo([i,a],o),Ko([i,a],"hidden"))}B(),N(),b.props.animation?C()&&function(e,t){K(e,(function(){!b.state.isVisible&&w.parentNode&&w.parentNode.contains(w)&&t()}))}(o,b.unmount):b.unmount()}},hideWithInteractivity:function(e){T().addEventListener("mousemove",_),Po(ur,_),_(e)},enable:function(){b.state.isEnabled=!0},disable:function(){b.hide(),b.state.isEnabled=!1},unmount:function(){b.state.isVisible&&b.hide(),b.state.isMounted&&(Q(),ee().forEach((function(e){e._tippy.unmount()})),w.parentNode&&w.parentNode.removeChild(w),cr=cr.filter((function(e){return e!==b})),b.state.isMounted=!1,O("onHidden",[b]))},destroy:function(){b.state.isDestroyed||(b.clearDelayTimeouts(),b.unmount(),H(),delete e._tippy,b.state.isDestroyed=!0,O("onDestroy",[b]))}};if(!d.render)return b;var v=d.render(b),w=v.popper,E=v.onUpdate;w.setAttribute("data-tippy-root",""),w.id="tippy-"+b.id,b.popper=w,e._tippy=b,w._tippy=b;var k=y.map((function(e){return e.fn(b)})),D=e.hasAttribute("aria-expanded");return $(),N(),M(),O("onCreate",[b]),d.showOnCreate&&te(),w.addEventListener("mouseenter",(function(){b.props.interactive&&b.state.isVisible&&b.clearDelayTimeouts()})),w.addEventListener("mouseleave",(function(e){b.props.interactive&&b.props.trigger.indexOf("mouseenter")>=0&&(T().addEventListener("mousemove",_),_(e))})),b;function S(){var e=b.props.touch;return Array.isArray(e)?e:[e,0]}function x(){return"hold"===S()[0]}function C(){var e;return!!(null==(e=b.props.render)?void 0:e.$$tippy)}function A(){return c||e}function T(){var e,t,n=A().parentNode;return n?(null==(t=Lo(n)[0])||null==(e=t.ownerDocument)?void 0:e.body)?t.ownerDocument:document:document}function R(){return ir(w)}function I(e){return b.state.isMounted&&!b.state.isVisible||$o.isTouch||a&&"focus"===a.type?0:Mo(b.props.delay,e?0:1,Jo.delay)}function M(){w.style.pointerEvents=b.props.interactive&&b.state.isVisible?"":"none",w.style.zIndex=""+b.props.zIndex}function O(e,t,n){var o;void 0===n&&(n=!0),k.forEach((function(n){n[e]&&n[e].apply(void 0,t)})),n&&(o=b.props)[e].apply(o,t)}function B(){var t=b.props.aria;if(t.content){var n="aria-"+t.content,o=w.id;Lo(b.props.triggerTarget||e).forEach((function(e){var t=e.getAttribute(n);if(b.state.isVisible)e.setAttribute(n,t?t+" "+o:o);else{var r=t&&t.replace(o,"").trim();r?e.setAttribute(n,r):e.removeAttribute(n)}}))}}function N(){!D&&b.props.aria.expanded&&Lo(b.props.triggerTarget||e).forEach((function(e){b.props.interactive?e.setAttribute("aria-expanded",b.state.isVisible&&e===A()?"true":"false"):e.removeAttribute("aria-expanded")}))}function L(){T().removeEventListener("mousemove",_),ur=ur.filter((function(e){return e!==_}))}function P(e){if(!($o.isTouch&&(f||"mousedown"===e.type)||b.props.interactive&&w.contains(e.target))){if(A().contains(e.target)){if($o.isTouch)return;if(b.state.isVisible&&b.props.trigger.indexOf("click")>=0)return}else O("onClickOutside",[b,e]);!0===b.props.hideOnClick&&(b.clearDelayTimeouts(),b.hide(),p=!0,setTimeout((function(){p=!1})),b.state.isMounted||z())}}function U(){f=!0}function j(){f=!1}function q(){var e=T();e.addEventListener("mousedown",P,!0),e.addEventListener("touchend",P,Io),e.addEventListener("touchstart",j,Io),e.addEventListener("touchmove",U,Io)}function z(){var e=T();e.removeEventListener("mousedown",P,!0),e.removeEventListener("touchend",P,Io),e.removeEventListener("touchstart",j,Io),e.removeEventListener("touchmove",U,Io)}function K(e,t){var n=R().box;function o(e){e.target===n&&(Go(n,"remove",o),t())}if(0===e)return t();Go(n,"remove",s),Go(n,"add",o),s=o}function G(t,n,o){void 0===o&&(o=!1),Lo(b.props.triggerTarget||e).forEach((function(e){e.addEventListener(t,n,o),m.push({node:e,eventType:t,handler:n,options:o})}))}function $(){var e;x()&&(G("touchstart",V,{passive:!0}),G("touchend",Y,{passive:!0})),(e=b.props.trigger,e.split(/\s+/).filter(Boolean)).forEach((function(e){if("manual"!==e)switch(G(e,V),e){case"mouseenter":G("mouseleave",Y);break;case"focus":G(Xo?"focusout":"blur",Z);break;case"focusin":G("focusout",Z)}}))}function H(){m.forEach((function(e){var t=e.node,n=e.eventType,o=e.handler,r=e.options;t.removeEventListener(n,o,r)})),m=[]}function V(e){var t,n=!1;if(b.state.isEnabled&&!X(e)&&!p){var o="focus"===(null==(t=a)?void 0:t.type);a=e,c=e.currentTarget,N(),!b.state.isVisible&&Oo(e,"MouseEvent")&&ur.forEach((function(t){return t(e)})),"click"===e.type&&(b.props.trigger.indexOf("mouseenter")<0||h)&&!1!==b.props.hideOnClick&&b.state.isVisible?n=!0:te(e),"click"===e.type&&(h=!n),n&&!o&&ne(e)}}function W(e){var t=e.target,n=A().contains(t)||w.contains(t);"mousemove"===e.type&&n||function(e,t){var n=t.clientX,o=t.clientY;return e.every((function(e){var t=e.popperRect,r=e.popperState,i=e.props.interactiveBorder,a=r.placement.split("-")[0],s=r.modifiersData.offset;if(!s)return!0;var u="bottom"===a?s.top.y:0,c="top"===a?s.bottom.y:0,l="right"===a?s.left.x:0,d="left"===a?s.right.x:0,h=t.top-o+u>i,p=o-t.bottom-c>i,f=t.left-n+l>i,g=n-t.right-d>i;return h||p||f||g}))}(ee().concat(w).map((function(e){var t,n=null==(t=e._tippy.popperInstance)?void 0:t.state;return n?{popperRect:e.getBoundingClientRect(),popperState:n,props:d}:null})).filter(Boolean),e)&&(L(),ne(e))}function Y(e){X(e)||b.props.trigger.indexOf("click")>=0&&h||(b.props.interactive?b.hideWithInteractivity(e):ne(e))}function Z(e){b.props.trigger.indexOf("focusin")<0&&e.target!==A()||b.props.interactive&&e.relatedTarget&&w.contains(e.relatedTarget)||ne(e)}function X(e){return!!$o.isTouch&&x()!==e.type.indexOf("touch")>=0}function J(){Q();var t=b.props,n=t.popperOptions,o=t.placement,r=t.offset,i=t.getReferenceClientRect,a=t.moveTransition,s=C()?ir(w).arrow:null,c=i?{getBoundingClientRect:i,contextElement:i.contextElement||A()}:e,l=[{name:"offset",options:{offset:r}},{name:"preventOverflow",options:{padding:{top:2,bottom:2,left:5,right:5}}},{name:"flip",options:{padding:5}},{name:"computeStyles",options:{adaptive:!a}},{name:"$$tippy",enabled:!0,phase:"beforeWrite",requires:["computeStyles"],fn:function(e){var t=e.state;if(C()){var n=R().box;["placement","reference-hidden","escaped"].forEach((function(e){"placement"===e?n.setAttribute("data-placement",t.placement):t.attributes.popper["data-popper-"+e]?n.setAttribute("data-"+e,""):n.removeAttribute("data-"+e)})),t.attributes.popper={}}}}];C()&&s&&l.push({name:"arrow",options:{element:s,padding:3}}),l.push.apply(l,(null==n?void 0:n.modifiers)||[]),b.popperInstance=Co(c,w,Object.assign({},n,{placement:o,onFirstUpdate:u,modifiers:l}))}function Q(){b.popperInstance&&(b.popperInstance.destroy(),b.popperInstance=null)}function ee(){return Uo(w.querySelectorAll("[data-tippy-root]"))}function te(e){b.clearDelayTimeouts(),e&&O("onTrigger",[b,e]),q();var t=I(!0),n=S(),r=n[0],i=n[1];$o.isTouch&&"hold"===r&&i&&(t=i),t?o=setTimeout((function(){b.show()}),t):b.show()}function ne(e){if(b.clearDelayTimeouts(),O("onUntrigger",[b,e]),b.state.isVisible){if(!(b.props.trigger.indexOf("mouseenter")>=0&&b.props.trigger.indexOf("click")>=0&&["mouseleave","mousemove"].indexOf(e.type)>=0&&h)){var t=I(!1);t?r=setTimeout((function(){b.state.isVisible&&b.hide()}),t):i=requestAnimationFrame((function(){b.hide()}))}}else z()}}function dr(e,t){void 0===t&&(t={});var n=Jo.plugins.concat(t.plugins||[]);document.addEventListener("touchstart",Vo,Io),window.addEventListener("blur",Yo);var o,r=Object.assign({},t,{plugins:n}),i=(o=e,qo(o)?[o]:function(e){return Oo(e,"NodeList")}(o)?Uo(o):Array.isArray(o)?o:Uo(document.querySelectorAll(o))).reduce((function(e,t){var n=t&&lr(t,r);return n&&e.push(n),e}),[]);return qo(e)?i[0]:i}dr.defaultProps=Jo,dr.setDefaultProps=function(e){Object.keys(e).forEach((function(t){Jo[t]=e[t]}))},dr.currentInput=$o,Object.assign({},fo,{effect:function(e){var t=e.state,n={popper:{position:t.options.strategy,left:"0",top:"0",margin:"0"},arrow:{position:"absolute"},reference:{}};Object.assign(t.elements.popper.style,n.popper),t.styles=n,t.elements.arrow&&Object.assign(t.elements.arrow.style,n.arrow)}}),dr.setDefaultProps({render:ar});const hr=dr;function pr(e,t){if(null==e)return{};var n,o,r={},i=Object.keys(e);for(o=0;o=0||(r[n]=e[n]);return r}var fr="undefined"!=typeof window&&"undefined"!=typeof document;function gr(e,t){e&&("function"==typeof e&&e(t),{}.hasOwnProperty.call(e,"current")&&(e.current=t))}function mr(){return fr&&document.createElement("div")}function _r(e,t){if(e===t)return!0;if("object"==typeof e&&null!=e&&"object"==typeof t&&null!=t){if(Object.keys(e).length!==Object.keys(t).length)return!1;for(var n in e){if(!t.hasOwnProperty(n))return!1;if(!_r(e[n],t[n]))return!1}return!0}return!1}function Fr(e){var t=[];return e.forEach((function(e){t.find((function(t){return _r(e,t)}))||t.push(e)})),t}var yr=fr?o.useLayoutEffect:o.useEffect;function br(e,t,n){n.split(/\s+/).forEach((function(n){n&&e.classList[t](n)}))}var vr={name:"className",defaultValue:"",fn:function(e){var t=e.popper.firstElementChild,n=function(){var t;return!!(null==(t=e.props.render)?void 0:t.$$tippy)};function o(){e.props.className&&!n()||br(t,"add",e.props.className)}return{onCreate:o,onBeforeUpdate:function(){n()&&br(t,"remove",e.props.className)},onAfterUpdate:o}}};function wr(e){return function(t){var n,i,a=t.children,s=t.content,u=t.visible,c=t.singleton,l=t.render,d=t.reference,h=t.disabled,p=void 0!==h&&h,f=t.ignoreAttributes,g=void 0===f||f,m=(t.__source,t.__self,pr(t,["children","content","visible","singleton","render","reference","disabled","ignoreAttributes","__source","__self"])),_=void 0!==u,F=void 0!==c,y=(0,o.useState)(!1),b=y[0],v=y[1],w=(0,o.useState)({}),E=w[0],k=w[1],D=(0,o.useState)(),S=D[0],x=D[1],C=(n=function(){return{container:mr(),renders:1}},(i=(0,o.useRef)()).current||(i.current="function"==typeof n?n():n),i.current),A=Object.assign({ignoreAttributes:g},m,{content:C.container});_&&(A.trigger="manual",A.hideOnClick=!1),F&&(p=!0);var T=A,R=A.plugins||[];l&&(T=Object.assign({},A,{plugins:F?[].concat(R,[{fn:function(){return{onTrigger:function(e,t){var n=c.data.children.find((function(e){return e.instance.reference===t.currentTarget})).content;x(n)}}}}]):R,render:function(){return{popper:C.container}}}));var I=[d].concat(a?[a.type]:[]);return yr((function(){var t=d;d&&d.hasOwnProperty("current")&&(t=d.current);var n=e(t||C.ref||mr(),Object.assign({},T,{plugins:[vr].concat(A.plugins||[])}));return C.instance=n,p&&n.disable(),u&&n.show(),F&&c.hook({instance:n,content:s,props:T}),v(!0),function(){n.destroy(),null==c||c.cleanup(n)}}),I),yr((function(){var e,t,n,o,r;if(1!==C.renders){var i=C.instance;i.setProps((t=i.props,n=T,Object.assign({},n,{popperOptions:Object.assign({},t.popperOptions,n.popperOptions,{modifiers:Fr([].concat((null==(o=t.popperOptions)?void 0:o.modifiers)||[],(null==(r=n.popperOptions)?void 0:r.modifiers)||[]))})}))),null==(e=i.popperInstance)||e.forceUpdate(),p?i.disable():i.enable(),_&&(u?i.show():i.hide()),F&&c.hook({instance:i,content:s,props:T})}else C.renders++})),yr((function(){var e;if(l){var t=C.instance;t.setProps({popperOptions:Object.assign({},t.props.popperOptions,{modifiers:[].concat(((null==(e=t.props.popperOptions)?void 0:e.modifiers)||[]).filter((function(e){return"$$tippyReact"!==e.name})),[{name:"$$tippyReact",enabled:!0,phase:"beforeWrite",requires:["computeStyles"],fn:function(e){var t,n=e.state,o=null==(t=n.modifiersData)?void 0:t.hide;E.placement===n.placement&&E.referenceHidden===(null==o?void 0:o.isReferenceHidden)&&E.escaped===(null==o?void 0:o.hasPopperEscaped)||k({placement:n.placement,referenceHidden:null==o?void 0:o.isReferenceHidden,escaped:null==o?void 0:o.hasPopperEscaped}),n.attributes.popper={}}}])})})}}),[E.placement,E.referenceHidden,E.escaped].concat(I)),o.createElement(o.Fragment,null,a?(0,o.cloneElement)(a,{ref:function(e){C.ref=e,gr(a.ref,e)}}):null,b&&(0,r.createPortal)(l?l(function(e){var t={"data-placement":e.placement};return e.referenceHidden&&(t["data-reference-hidden"]=""),e.escaped&&(t["data-escaped"]=""),t}(E),S,C.instance):s,C.container))}}const Er=function(e,t){return(0,o.forwardRef)((function(n,r){var i=n.children,a=pr(n,["children"]);return o.createElement(e,Object.assign({},t,a),i?(0,o.cloneElement)(i,{ref:function(e){gr(r,e),gr(i.ref,e)}}):null)}))}(wr(hr));function kr(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,o=new Array(t);ne.length)&&(t=e.length);for(var n=0,o=new Array(t);ne.length)&&(t=e.length);for(var n=0,o=new Array(t);ne.length)&&(t=e.length);for(var n=0,o=new Array(t);no.toLowerCase()?1:0}function ci(e){var t=e.tabId;return o.createElement(Hr,null,o.createElement(Vr,null,o.createElement(vt,{variant:"s1"},"channels"===t?"Home":"Direct messages")),"dm"===t?o.createElement(Yr,{onClick:function(){return pn()},tooltip:"Start DM",src:Jr,size:"normal"}):o.createElement(Ir,{content:function(e){return o.createElement(o.Fragment,null,o.createElement(Mr,null,"Add channel"),o.createElement(Or,{iconSrc:ti,onClick:function(){e(),ke.dispatch({type:se.actions.navigation.OPEN_CREATE_CHANNEL})}},"Create new channel"),o.createElement(Or,{iconSrc:Pr,onClick:function(){e(),hn()}},"Add Public channel"))},render:function(e){return o.createElement(Yr,{onClick:e,tooltip:"Add channel",src:Jr,size:"normal"})}}))}function li(){return o.createElement("div",{className:"breadcrumb__wrapper"},o.createElement(Fn,{horizontal:!0,vertical:!1},o.createElement("div",null)))}function di(e,t,n,r){var i,a=Qe.matrixClient,s=null===(i=e.getAvatarFallbackMember())||void 0===i?void 0:i.getAvatarUrl(a.baseUrl,24,24,"crop");return void 0===s&&(s=null),o.createElement(Xr,{key:t,iconSrc:r?null:e.isSpaceRoom()?"invite"===e.getJoinRule()?oi:ni:"invite"===e.getJoinRule()?ei:Qr,imageSrc:r?s:null,roomId:t,unread:ut(e),onClick:function(){return ln(t)},notificationCount:e.getUnreadNotificationCount("total"),alert:0!==e.getUnreadNotificationCount("highlight"),selected:n},e.name)}function hi(e){var t=e.selectedRoomId,n=Qe.matrixClient;return ii(Qe.roomList.directs).sort(ui).map((function(e){return di(n.getRoom(e),e,t===e,!0)}))}function pi(e){var t=e.selectedRoomId,n=Qe.matrixClient,r=ii(Qe.roomList.spaces).sort(ui),i=ii(Qe.roomList.rooms).sort(ui);return o.createElement(o.Fragment,null,0!==r.length&&o.createElement(vt,{className:"cat-header",variant:"b3"},"Spaces"),r.map((function(e){return di(n.getRoom(e),e,t===e,!1)})),0!==i.length&&o.createElement(vt,{className:"cat-header",variant:"b3"},"Channels"),i.map((function(e){return di(n.getRoom(e),e,t===e,!1)})))}function fi(e){var t=e.tabId,n=ri((0,o.useState)(null),2),r=n[0],i=n[1],a=ri((0,o.useState)(),2)[1],s=function(e){return i(e)},u=function(){return a({})},c=function(){var e=Qe.roomList,t=e.spaces,n=e.rooms,o=e.directs;t.has(r)||n.has(r)||o.has(r)||ln(null)};return(0,o.useEffect)((function(){return cn.on(se.events.navigation.ROOM_SELECTED,s),Qe.roomList.on(se.events.roomList.ROOMLIST_UPDATED,u),function(){cn.removeListener(se.events.navigation.ROOM_SELECTED,s),Qe.roomList.removeListener(se.events.roomList.ROOMLIST_UPDATED,u)}}),[]),(0,o.useEffect)((function(){return Qe.roomList.on(se.events.roomList.ROOMLIST_UPDATED,c),function(){Qe.roomList.removeListener(se.events.roomList.ROOMLIST_UPDATED,c)}}),[r]),o.createElement("div",{className:"channels-container"},"channels"===t?o.createElement(pi,{selectedRoomId:r}):o.createElement(hi,{selectedRoomId:r}))}function gi(e){var t=e.tabId;return o.createElement("div",{className:"drawer"},o.createElement(ci,{tabId:t}),o.createElement("div",{className:"drawer__content-wrapper"},o.createElement(li,null),o.createElement("div",{className:"channels__wrapper"},o.createElement(Fn,{autoHide:!0},o.createElement(fi,{tabId:t})))))}ci.propTypes={tabId:l().string.isRequired},hi.defaultProps={selectedRoomId:null},hi.propTypes={selectedRoomId:l().string},pi.defaultProps={selectedRoomId:null},pi.propTypes={selectedRoomId:l().string},fi.propTypes={tabId:l().string.isRequired},gi.propTypes={tabId:l().string.isRequired};const mi=gi;function _i(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,o=new Array(t);ne.length)&&(t=e.length);for(var n=0,o=new Array(t);n0&&(t.ongoingDecryptionCount-=1),t.timeline=t.room.timeline,0===t.ongoingDecryptionCount&&t.emit(se.events.roomTimeline.EVENT))},t._listenTypingEvent=function(e,n){var o;n.roomId===t.roomId&&(n.typing?t.typingMembers.add(n.userId):t.typingMembers.delete(n.userId),t.emit(se.events.roomTimeline.TYPING_MEMBERS_UPDATED,new Set(function(e){if(Array.isArray(e))return ki(e)}(o=t.typingMembers)||function(e){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(e))return Array.from(e)}(o)||function(e,t){if(e){if("string"==typeof e)return ki(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?ki(e,t):void 0}}(o)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}())))},t._listenReciptEvent=function(e,n){if(n.roomId===t.roomId){var o=e.getContent();if(0!==t.timeline.length){var r=o[t.timeline[t.timeline.length-1].getId()];void 0!==r&&r["m.read"]&&t.emit(se.events.roomTimeline.READ_RECEIPT)}}},t.matrixClient.on("Room.timeline",t._listenRoomTimeline),t.matrixClient.on("Event.decrypted",t._listenDecryptEvent),t.matrixClient.on("RoomMember.typing",t._listenTypingEvent),t.matrixClient.on("Room.receipt",t._listenReciptEvent),window.selectedRoom=Ci(t),t.isEncryptedRoom()&&t.room.decryptAllEvents(),t}return t=a,(n=[{key:"isEncryptedRoom",value:function(){return this.matrixClient.isRoomEncrypted(this.roomId)}},{key:"isEdited",value:function(e){var t;return"m.replace"===(null===(t=e.getRelation())||void 0===t?void 0:t.rel_type)}},{key:"getRelateToId",value:function(e){var t=e.getRelation();return t&&t.event_id}},{key:"addToMap",value:function(e,t){var n=this.getRelateToId(t);return null===n?null:(void 0===e.get(n)&&e.set(n,[]),e.get(n).push(t),t)}},{key:"getEditedTimeline",value:function(){var e=this,t=new Map;return this.timeline.forEach((function(n){e.isEdited(n)&&e.addToMap(t,n)})),t}},{key:"isReaction",value:function(e){return"m.reaction"===e.getType()}},{key:"getReactionTimeline",value:function(){var e=this,t=new Map;return this.timeline.forEach((function(n){e.isReaction(n)&&e.addToMap(t,n)})),t}},{key:"paginateBack",value:function(){var e=this;this.isOngoingPagination||(this.isOngoingPagination=!0,this.matrixClient.scrollback(this.room,30).then(function(){var t,n=(t=regeneratorRuntime.mark((function t(n){return regeneratorRuntime.wrap((function(t){for(;;)switch(t.prev=t.next){case 0:if(null!==n.oldState.paginationToken){t.next=7;break}if(e.isOngoingPagination=!1,!e.isEncryptedRoom()){t.next=5;break}return t.next=5,e.room.decryptAllEvents();case 5:return e.emit(se.events.roomTimeline.PAGINATED,!1),t.abrupt("return");case 7:if(e.editedTimeline=e.getEditedTimeline(),e.reactionTimeline=e.getReactionTimeline(),e.isOngoingPagination=!1,!e.isEncryptedRoom()){t.next=13;break}return t.next=13,e.room.decryptAllEvents();case 13:e.emit(se.events.roomTimeline.PAGINATED,!0);case 14:case"end":return t.stop()}}),t)})),function(){var e=this,n=arguments;return new Promise((function(o,r){var i=t.apply(e,n);function a(e){Ei(i,o,r,a,s,"next",e)}function s(e){Ei(i,o,r,a,s,"throw",e)}a(void 0)}))});return function(e){return n.apply(this,arguments)}}()))}},{key:"removeInternalListeners",value:function(){this.matrixClient.removeListener("Room.timeline",this._listenRoomTimeline),this.matrixClient.removeListener("Event.decrypted",this._listenDecryptEvent),this.matrixClient.removeListener("RoomMember.typing",this._listenTypingEvent),this.matrixClient.removeListener("Room.receipt",this._listenReciptEvent)}}])&&Di(t.prototype,n),a}(Ee());function Ri(e,t,n,o,r,i,a){try{var s=e[i](a),u=s.value}catch(e){return void n(e)}s.done?t(u):Promise.resolve(u).then(o,r)}function Ii(e){return function(){var t=this,n=arguments;return new Promise((function(o,r){var i=e.apply(t,n);function a(e){Ri(i,o,r,a,s,"next",e)}function s(e){Ri(i,o,r,a,s,"throw",e)}a(void 0)}))}}function Mi(e,t){var n=Qe.matrixClient,o=n.getAccountData("m.direct"),r={};if(void 0!==o&&(r=o.getContent()),Object.keys(r).forEach((function(n){var o=r[n];if(n!==t){var i=o.indexOf(e);i>-1&&o.splice(i,1)}})),t){var i=r[t]||[];-1===i.indexOf(e)&&i.push(e),r[t]=i}return n.setAccountData("m.direct",r)}function Oi(e,t){var n,o;return e.getJoinedMembers().forEach((function(e){e.userId!==t&&(void 0===n||e.events.member&&e.events.member.getTs()e.length)&&(t=e.length);for(var n=0,o=new Array(t);n=4?[t[0],t[1],t[2],t[3],"".concat(t[0],".").concat(t[1]),"".concat(t[0],".").concat(t[2]),"".concat(t[0],".").concat(t[3]),"".concat(t[1],".").concat(t[0]),"".concat(t[1],".").concat(t[2]),"".concat(t[1],".").concat(t[3]),"".concat(t[2],".").concat(t[0]),"".concat(t[2],".").concat(t[1]),"".concat(t[2],".").concat(t[3]),"".concat(t[3],".").concat(t[0]),"".concat(t[3],".").concat(t[1]),"".concat(t[3],".").concat(t[2]),"".concat(t[0],".").concat(t[1],".").concat(t[2]),"".concat(t[0],".").concat(t[1],".").concat(t[3]),"".concat(t[0],".").concat(t[2],".").concat(t[1]),"".concat(t[0],".").concat(t[2],".").concat(t[3]),"".concat(t[0],".").concat(t[3],".").concat(t[1]),"".concat(t[0],".").concat(t[3],".").concat(t[2]),"".concat(t[1],".").concat(t[0],".").concat(t[2]),"".concat(t[1],".").concat(t[0],".").concat(t[3]),"".concat(t[1],".").concat(t[2],".").concat(t[0]),"".concat(t[1],".").concat(t[2],".").concat(t[3]),"".concat(t[1],".").concat(t[3],".").concat(t[0]),"".concat(t[1],".").concat(t[3],".").concat(t[2]),"".concat(t[2],".").concat(t[0],".").concat(t[1]),"".concat(t[2],".").concat(t[0],".").concat(t[3]),"".concat(t[2],".").concat(t[1],".").concat(t[0]),"".concat(t[2],".").concat(t[1],".").concat(t[3]),"".concat(t[2],".").concat(t[3],".").concat(t[0]),"".concat(t[2],".").concat(t[3],".").concat(t[1]),"".concat(t[3],".").concat(t[0],".").concat(t[1]),"".concat(t[3],".").concat(t[0],".").concat(t[2]),"".concat(t[3],".").concat(t[1],".").concat(t[0]),"".concat(t[3],".").concat(t[1],".").concat(t[2]),"".concat(t[3],".").concat(t[2],".").concat(t[0]),"".concat(t[3],".").concat(t[2],".").concat(t[1]),"".concat(t[0],".").concat(t[1],".").concat(t[2],".").concat(t[3]),"".concat(t[0],".").concat(t[1],".").concat(t[3],".").concat(t[2]),"".concat(t[0],".").concat(t[2],".").concat(t[1],".").concat(t[3]),"".concat(t[0],".").concat(t[2],".").concat(t[3],".").concat(t[1]),"".concat(t[0],".").concat(t[3],".").concat(t[1],".").concat(t[2]),"".concat(t[0],".").concat(t[3],".").concat(t[2],".").concat(t[1]),"".concat(t[1],".").concat(t[0],".").concat(t[2],".").concat(t[3]),"".concat(t[1],".").concat(t[0],".").concat(t[3],".").concat(t[2]),"".concat(t[1],".").concat(t[2],".").concat(t[0],".").concat(t[3]),"".concat(t[1],".").concat(t[2],".").concat(t[3],".").concat(t[0]),"".concat(t[1],".").concat(t[3],".").concat(t[0],".").concat(t[2]),"".concat(t[1],".").concat(t[3],".").concat(t[2],".").concat(t[0]),"".concat(t[2],".").concat(t[0],".").concat(t[1],".").concat(t[3]),"".concat(t[2],".").concat(t[0],".").concat(t[3],".").concat(t[1]),"".concat(t[2],".").concat(t[1],".").concat(t[0],".").concat(t[3]),"".concat(t[2],".").concat(t[1],".").concat(t[3],".").concat(t[0]),"".concat(t[2],".").concat(t[3],".").concat(t[0],".").concat(t[1]),"".concat(t[2],".").concat(t[3],".").concat(t[1],".").concat(t[0]),"".concat(t[3],".").concat(t[0],".").concat(t[1],".").concat(t[2]),"".concat(t[3],".").concat(t[0],".").concat(t[2],".").concat(t[1]),"".concat(t[3],".").concat(t[1],".").concat(t[0],".").concat(t[2]),"".concat(t[3],".").concat(t[1],".").concat(t[2],".").concat(t[0]),"".concat(t[3],".").concat(t[2],".").concat(t[0],".").concat(t[1]),"".concat(t[3],".").concat(t[2],".").concat(t[1],".").concat(t[0])]:void 0),ea[o]}function na(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=arguments.length>2?arguments[2]:void 0,o=e.filter((function(e){return"token"!==e})),r=ta(o);return r.reduce((function(e,t){return Qi({},e,n[t])}),t)}function oa(e){return e.join(" ")}function ra(e){var t=e.node,n=e.stylesheet,r=e.style,i=void 0===r?{}:r,a=e.useInlineStyles,s=e.key,u=t.properties,c=t.type,l=t.tagName,h=t.value;if("text"===c)return h;if(l){var p,f=function(e,t){var n=0;return function(o){return n+=1,o.map((function(o,r){return ra({node:o,stylesheet:e,useInlineStyles:t,key:"code-segment-".concat(n,"-").concat(r)})}))}}(n,a);if(a){var g=Object.keys(n).reduce((function(e,t){return t.split(".").forEach((function(t){e.includes(t)||e.push(t)})),e}),[]),m=u.className&&u.className.includes("token")?["token"]:[],_=u.className&&m.concat(u.className.filter((function(e){return!g.includes(e)})));p=Qi({},u,{className:oa(_)||void 0,style:na(u.className,Object.assign({},u.style,i),n)})}else p=Qi({},u,{className:oa(u.className)});var F=f(t.children);return o.createElement(l,d({key:s},p),F)}}var ia=/\n/g;function aa(e){var t=e.codeString,n=e.codeStyle,r=e.containerStyle,i=void 0===r?{float:"left",paddingRight:"10px"}:r,a=e.numberStyle,s=void 0===a?{}:a,u=e.startingLineNumber;return o.createElement("code",{style:Object.assign({},n,i)},function(e){var t=e.startingLineNumber,n=e.style;return e.lines.map((function(e,r){var i=r+t;return o.createElement("span",{key:"line-".concat(r),className:"react-syntax-highlighter-line-number",style:"function"==typeof n?n(i):n},"".concat(i,"\n"))}))}({lines:t.replace(/\n$/,"").split("\n"),style:s,startingLineNumber:u}))}function sa(e,t){return{type:"element",tagName:"span",properties:{key:"line-number--".concat(e),className:["comment","linenumber","react-syntax-highlighter-line-number"],style:t},children:[{type:"text",value:e}]}}function ua(e,t,n){var o;return Qi({},{display:"inline-block",minWidth:(o=n,"".concat(o.toString().length,".25em")),paddingRight:"1em",textAlign:"right",userSelect:"none"},"function"==typeof e?e(t):e)}function ca(e){var t=e.children,n=e.lineNumber,o=e.lineNumberStyle,r=e.largestLineNumber,i=e.showInlineLineNumbers,a=e.lineProps,s=void 0===a?{}:a,u=e.className,c=void 0===u?[]:u,l=e.showLineNumbers,d=e.wrapLongLines,h="function"==typeof s?s(n):s;if(h.className=c,n&&i){var p=ua(o,n,r);t.unshift(sa(n,p))}return d&l&&(h.style=Qi({},h.style,{display:"flex"})),{type:"element",tagName:"span",properties:h,children:t}}function la(e){for(var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[],n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[],o=0;o2&&void 0!==arguments[2]?arguments[2]:[];return ca({children:e,lineNumber:t,lineNumberStyle:s,largestLineNumber:a,showInlineLineNumbers:r,lineProps:n,className:i,showLineNumbers:o,wrapLongLines:u})}function g(e,t){if(o&&t&&r){var n=ua(s,t,a);e.unshift(sa(t,n))}return e}function m(e,n){var o=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[];return t||o.length>0?f(e,n,o):g(e,n)}for(var _=function(){var e=l[p],t=e.children[0].value;if(t.match(ia)){var n=t.split("\n");n.forEach((function(t,r){var a=o&&d.length+i,s={type:"text",value:"".concat(t,"\n")};if(0===r){var u=m(l.slice(h+1,p).concat(ca({children:[s],className:e.properties.className})),a);d.push(u)}else if(r===n.length-1)if(l[p+1]&&l[p+1].children&&l[p+1].children[0]){var c=ca({children:[{type:"text",value:"".concat(t)}],className:e.properties.className});l.splice(p+1,0,c)}else{var f=m([s],a,e.properties.className);d.push(f)}else{var g=m([s],a,e.properties.className);d.push(g)}})),h=p}p++};p code[class*="language-"]':{background:"#f5f2f0",padding:".1em",borderRadius:".3em",whiteSpace:"normal"},comment:{color:"slategray"},prolog:{color:"slategray"},doctype:{color:"slategray"},cdata:{color:"slategray"},punctuation:{color:"#999"},namespace:{Opacity:".7"},property:{color:"#905"},tag:{color:"#905"},boolean:{color:"#905"},number:{color:"#905"},constant:{color:"#905"},symbol:{color:"#905"},deleted:{color:"#905"},selector:{color:"#690"},"attr-name":{color:"#690"},string:{color:"#690"},char:{color:"#690"},builtin:{color:"#690"},inserted:{color:"#690"},operator:{color:"#9a6e3a",background:"hsla(0, 0%, 100%, .5)"},entity:{color:"#9a6e3a",background:"hsla(0, 0%, 100%, .5)",cursor:"help"},url:{color:"#9a6e3a",background:"hsla(0, 0%, 100%, .5)"},".language-css .token.string":{color:"#9a6e3a",background:"hsla(0, 0%, 100%, .5)"},".style .token.string":{color:"#9a6e3a",background:"hsla(0, 0%, 100%, .5)"},atrule:{color:"#07a"},"attr-value":{color:"#07a"},keyword:{color:"#07a"},function:{color:"#DD4A68"},"class-name":{color:"#DD4A68"},regex:{color:"#e90"},important:{color:"#e90",fontWeight:"bold"},variable:{color:"#e90"},bold:{fontWeight:"bold"},italic:{fontStyle:"italic"}},function(e){var t=e.language,n=e.children,r=e.style,i=void 0===r?ga:r,a=e.customStyle,s=void 0===a?{}:a,u=e.codeTagProps,c=void 0===u?{className:t?"language-".concat(t):void 0,style:Qi({},i['code[class*="language-"]'],i['code[class*="language-'.concat(t,'"]')])}:u,l=e.useInlineStyles,d=void 0===l||l,h=e.showLineNumbers,p=void 0!==h&&h,f=e.showInlineLineNumbers,g=void 0===f||f,m=e.startingLineNumber,_=void 0===m?1:m,F=e.lineNumberContainerStyle,y=e.lineNumberStyle,b=void 0===y?{}:y,v=e.wrapLines,w=e.wrapLongLines,E=void 0!==w&&w,k=e.lineProps,D=void 0===k?{}:k,S=e.renderer,x=e.PreTag,C=void 0===x?"pre":x,A=e.CodeTag,T=void 0===A?"code":A,R=e.code,I=void 0===R?Array.isArray(n)?n[0]:n:R,M=e.astGenerator,O=function(e,t){if(null==e)return{};var n,o,r=B(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}(e,["language","children","style","customStyle","codeTagProps","useInlineStyles","showLineNumbers","showInlineLineNumbers","startingLineNumber","lineNumberContainerStyle","lineNumberStyle","wrapLines","wrapLongLines","lineProps","renderer","PreTag","CodeTag","code","astGenerator"]);M=M||fa;var N=p?o.createElement(aa,{containerStyle:F,codeStyle:c.style||{},numberStyle:b,startingLineNumber:_,codeString:I}):null,L=i.hljs||i['pre[class*="language-"]']||{backgroundColor:"#fff"},P=pa(M)?"hljs":"prismjs",U=d?Object.assign({},O,{style:Object.assign({},L,s)}):Object.assign({},O,{className:O.className?"".concat(P," ").concat(O.className):P,style:Object.assign({},s)});if(!M)return o.createElement(C,U,N,o.createElement(T,c,I));(void 0===v&&S||E)&&(v=!0),S=S||ha;var j=[{type:"text",value:I}],q=function(e){var t=e.astGenerator,n=e.language,o=e.code,r=e.defaultCodeValue;if(pa(t)){var i=function(e,t){return-1!==e.listLanguages().indexOf(t)}(t,n);return"text"===n?{value:r,language:"text"}:i?t.highlight(n,o):t.highlightAuto(o)}try{return n&&"text"!==n?{value:t.highlight(o,n)}:{value:r}}catch(e){return{value:r}}}({astGenerator:M,language:t,code:I,defaultCodeValue:j});null===q.language&&(q.value=j);var z=da(q,v,D,p,g,_,q.value.length+_,b,E);return c.style=Qi({},c.style,E?{whiteSpace:"pre-wrap"}:{whiteSpace:"pre"}),o.createElement(C,U,o.createElement(T,c,!g&&N,S({rows:z,stylesheet:i,useInlineStyles:d})))});_a.supportedLanguages=["abap","abnf","actionscript","ada","agda","al","antlr4","apacheconf","apl","applescript","aql","arduino","arff","asciidoc","asm6502","aspnet","autohotkey","autoit","bash","basic","batch","bbcode","birb","bison","bnf","brainfuck","brightscript","bro","bsl","c","cil","clike","clojure","cmake","coffeescript","concurnas","cpp","crystal","csharp","csp","css-extras","css","cypher","d","dart","dax","dhall","diff","django","dns-zone-file","docker","ebnf","editorconfig","eiffel","ejs","elixir","elm","erb","erlang","etlua","excel-formula","factor","firestore-security-rules","flow","fortran","fsharp","ftl","gcode","gdscript","gedcom","gherkin","git","glsl","gml","go","graphql","groovy","haml","handlebars","haskell","haxe","hcl","hlsl","hpkp","hsts","http","ichigojam","icon","iecst","ignore","inform7","ini","io","j","java","javadoc","javadoclike","javascript","javastacktrace","jolie","jq","js-extras","js-templates","jsdoc","json","json5","jsonp","jsstacktrace","jsx","julia","keyman","kotlin","latex","latte","less","lilypond","liquid","lisp","livescript","llvm","lolcode","lua","makefile","markdown","markup-templating","markup","matlab","mel","mizar","mongodb","monkey","moonscript","n1ql","n4js","nand2tetris-hdl","naniscript","nasm","neon","nginx","nim","nix","nsis","objectivec","ocaml","opencl","oz","parigp","parser","pascal","pascaligo","pcaxis","peoplecode","perl","php-extras","php","phpdoc","plsql","powerquery","powershell","processing","prolog","properties","protobuf","pug","puppet","pure","purebasic","purescript","python","q","qml","qore","r","racket","reason","regex","renpy","rest","rip","roboconf","robotframework","ruby","rust","sas","sass","scala","scheme","scss","shell-session","smali","smalltalk","smarty","sml","solidity","solution-file","soy","sparql","splunk-spl","sqf","sql","stan","stylus","swift","t4-cs","t4-templating","t4-vb","tap","tcl","textile","toml","tsx","tt2","turtle","twig","typescript","typoscript","unrealscript","vala","vbnet","velocity","verilog","vhdl","vim","visual-basic","warpscript","wasm","wiki","xeora","xml-doc","xojo","xquery","yaml","yang","zig"];const Fa=_a,ya={'code[class*="language-"]':{color:"black",background:"none",fontFamily:"Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace",fontSize:"1em",textAlign:"left",whiteSpace:"pre",wordSpacing:"normal",wordBreak:"normal",wordWrap:"normal",lineHeight:"1.5",MozTabSize:"4",OTabSize:"4",tabSize:"4",WebkitHyphens:"none",MozHyphens:"none",msHyphens:"none",hyphens:"none",maxHeight:"inherit",height:"inherit",padding:"0 1em",display:"block",overflow:"auto"},'pre[class*="language-"]':{color:"black",background:"none",fontFamily:"Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace",fontSize:"1em",textAlign:"left",whiteSpace:"pre",wordSpacing:"normal",wordBreak:"normal",wordWrap:"normal",lineHeight:"1.5",MozTabSize:"4",OTabSize:"4",tabSize:"4",WebkitHyphens:"none",MozHyphens:"none",msHyphens:"none",hyphens:"none",position:"relative",margin:".5em 0",overflow:"visible",padding:"0",backgroundColor:"#fdfdfd",WebkitBoxSizing:"border-box",MozBoxSizing:"border-box",boxSizing:"border-box",marginBottom:"1em"},'pre[class*="language-"]>code':{position:"relative",borderLeft:"10px solid #358ccb",boxShadow:"-1px 0px 0px 0px #358ccb, 0px 0px 0px 1px #dfdfdf",backgroundColor:"#fdfdfd",backgroundImage:"linear-gradient(transparent 50%, rgba(69, 142, 209, 0.04) 50%)",backgroundSize:"3em 3em",backgroundOrigin:"content-box",backgroundAttachment:"local"},':not(pre) > code[class*="language-"]':{backgroundColor:"#fdfdfd",WebkitBoxSizing:"border-box",MozBoxSizing:"border-box",boxSizing:"border-box",marginBottom:"1em",position:"relative",padding:".2em",borderRadius:"0.3em",color:"#c92c2c",border:"1px solid rgba(0, 0, 0, 0.1)",display:"inline",whiteSpace:"normal"},'pre[class*="language-"]:before':{content:"''",zIndex:"-2",display:"block",position:"absolute",bottom:"0.75em",left:"0.18em",width:"40%",height:"20%",maxHeight:"13em",boxShadow:"0px 13px 8px #979797",WebkitTransform:"rotate(-2deg)",MozTransform:"rotate(-2deg)",msTransform:"rotate(-2deg)",OTransform:"rotate(-2deg)",transform:"rotate(-2deg)"},'pre[class*="language-"]:after':{content:"''",zIndex:"-2",display:"block",position:"absolute",bottom:"0.75em",left:"auto",width:"40%",height:"20%",maxHeight:"13em",boxShadow:"0px 13px 8px #979797",WebkitTransform:"rotate(2deg)",MozTransform:"rotate(2deg)",msTransform:"rotate(2deg)",OTransform:"rotate(2deg)",transform:"rotate(2deg)",right:"0.75em"},comment:{color:"#7D8B99"},"block-comment":{color:"#7D8B99"},prolog:{color:"#7D8B99"},doctype:{color:"#7D8B99"},cdata:{color:"#7D8B99"},punctuation:{color:"#5F6364"},property:{color:"#c92c2c"},tag:{color:"#c92c2c"},boolean:{color:"#c92c2c"},number:{color:"#c92c2c"},"function-name":{color:"#c92c2c"},constant:{color:"#c92c2c"},symbol:{color:"#c92c2c"},deleted:{color:"#c92c2c"},selector:{color:"#2f9c0a"},"attr-name":{color:"#2f9c0a"},string:{color:"#2f9c0a"},char:{color:"#2f9c0a"},function:{color:"#2f9c0a"},builtin:{color:"#2f9c0a"},inserted:{color:"#2f9c0a"},operator:{color:"#a67f59",background:"rgba(255, 255, 255, 0.5)"},entity:{color:"#a67f59",background:"rgba(255, 255, 255, 0.5)",cursor:"help"},url:{color:"#a67f59",background:"rgba(255, 255, 255, 0.5)"},variable:{color:"#a67f59",background:"rgba(255, 255, 255, 0.5)"},atrule:{color:"#1990b8"},"attr-value":{color:"#1990b8"},keyword:{color:"#1990b8"},"class-name":{color:"#1990b8"},regex:{color:"#e90"},important:{color:"#e90",fontWeight:"normal"},".language-css .token.string":{color:"#a67f59",background:"rgba(255, 255, 255, 0.5)"},".style .token.string":{color:"#a67f59",background:"rgba(255, 255, 255, 0.5)"},bold:{fontWeight:"bold"},italic:{fontStyle:"italic"},namespace:{Opacity:".7"},'pre[class*="language-"].line-numbers.line-numbers':{paddingLeft:"0"},'pre[class*="language-"].line-numbers.line-numbers code':{paddingLeft:"3.8em"},'pre[class*="language-"].line-numbers.line-numbers .line-numbers-rows':{left:"0"},'pre[class*="language-"][data-line]':{paddingTop:"0",paddingBottom:"0",paddingLeft:"0"},"pre[data-line] code":{position:"relative",paddingLeft:"4em"},"pre .line-highlight":{marginTop:"0"}},ba=n.p+"assets/reply-arrow.4652dfc3651a804bb60877d388196c95.svg";var va={code:function(e){var t=e.inline,n=e.className,r=e.children,i=/language-(\w+)/.exec(n||"");return!t&&i?o.createElement(Fa,{style:ya,language:i[1],PreTag:"div",showLineNumbers:!0},String(r).replace(/\n$/,"")):o.createElement("code",{className:n},String(r))}};function wa(){return o.createElement("div",{className:"ph-msg"},o.createElement("div",{className:"ph-msg__avatar-container"},o.createElement("div",{className:"ph-msg__avatar"})),o.createElement("div",{className:"ph-msg__main-container"},o.createElement("div",{className:"ph-msg__header"}),o.createElement("div",{className:"ph-msg__content"},o.createElement("div",null),o.createElement("div",null),o.createElement("div",null),o.createElement("div",null))))}function Ea(e){var t=e.color,n=e.avatarSrc,r=e.name,i=e.content,a=e.time,s=e.markdown,u=e.contentOnly,c=e.reply,l=e.edited,d=e.reactions,h=u?"message--content-only":"message--full";return o.createElement("div",{className:"message ".concat(h)},o.createElement("div",{className:"message__avatar-container"},!u&&o.createElement(Sr,{imageSrc:n,text:r.slice(0,1),bgColor:t,size:"small"})),o.createElement("div",{className:"message__main-container"},!u&&o.createElement("div",{className:"message__header"},o.createElement("div",{style:{color:t},className:"message__profile"},o.createElement(vt,{variant:"b1"},r)),o.createElement("div",{className:"message__time"},o.createElement(vt,{variant:"b3"},a))),o.createElement("div",{className:"message__content"},null!==c&&o.createElement("div",{className:"message__reply-content"},o.createElement(vt,{variant:"b2"},o.createElement(Et,{color:c.color,size:"extra-small",src:ba}),o.createElement("span",{style:{color:c.color}},c.to),o.createElement(o.Fragment,null," ".concat(c.content)))),o.createElement("div",{className:"text text-b1"},s?function(e){return o.createElement(Vi(),{remarkPlugins:[Yi()],components:va,linkTarget:"_blank"},e)}(i):function(e){return o.createElement($i(),{options:{target:{url:"_blank"}}},e)}(i)),l&&o.createElement(vt,{className:"message__edited",variant:"b3"},"(edited)"),d&&o.createElement("div",{className:"message__reactions text text-b3 noselect"},d.map((function(e){return o.createElement("button",{key:e.id,onClick:function(){return alert("Sending reactions is yet to be implemented.")},type:"button",className:"msg__reaction".concat(e.active?" msg__reaction--active":"")},"".concat(e.key," ").concat(e.count))}))))))}Ea.defaultProps={color:"var(--tc-surface-high)",avatarSrc:null,markdown:!1,contentOnly:!1,reply:null,edited:!1,reactions:null},Ea.propTypes={color:l().string,avatarSrc:l().string,name:l().string.isRequired,content:l().node.isRequired,time:l().string.isRequired,markdown:l().bool,contentOnly:l().bool,reply:l().shape({color:l().string.isRequired,to:l().string.isRequired,content:l().string.isRequired}),edited:l().bool,reactions:l().arrayOf(l().exact({id:l().string,key:l().string,count:l().number,active:l().bool}))};const ka=n.p+"assets/download.ab30aec19573b4189334338c801b4180.svg",Da=n.p+"assets/external.c37f42201429884adc1da8fc5ee65b88.svg",Sa=n.p+"assets/play.8838e717b724f8097895aae1dad87e92.svg";function xa(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(e)){var n=[],o=!0,r=!1,i=void 0;try{for(var a,s=e[Symbol.iterator]();!(o=(a=s.next()).done)&&(n.push(a.value),!t||n.length!==t);o=!0);}catch(e){r=!0,i=e}finally{try{o||null==s.return||s.return()}finally{if(r)throw i}}return n}}(e,t)||function(e,t){if(e){if("string"==typeof e)return Ca(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?Ca(e,t):void 0}}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function Ca(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,o=new Array(t);n>10),56320+(1023&t))},toCodePoint:_},onerror:function(){this.parentNode&&this.parentNode.replaceChild(u(this.alt,!1),this)},parse:function(t,n){return n&&"function"!=typeof n||(n={callback:n}),("string"==typeof t?p:h)(t,{callback:n.callback||c,attributes:"function"==typeof n.attributes?n.attributes:g,base:"string"==typeof n.base?n.base:e.base,ext:n.ext||e.ext,size:n.folder||(o=n.size||e.size,"number"==typeof o?o+"x"+o:o),className:n.className||e.className,onerror:n.onerror||e.onerror});var o},replace:m,test:function(e){n.lastIndex=0;var t=n.test(e);return n.lastIndex=0,t}},t={"&":"&","<":"<",">":">","'":"'",'"':"""},n=/(?:\ud83d\udc68\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffc-\udfff]|\ud83e\uddd1\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb\udffd-\udfff]|\ud83e\uddd1\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb\udffc\udffe\udfff]|\ud83e\uddd1\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb-\udffd\udfff]|\ud83e\uddd1\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb-\udffe]|\ud83d\udc68\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffc-\udfff]|\ud83d\udc68\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffd-\udfff]|\ud83d\udc68\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc68\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffd\udfff]|\ud83d\udc68\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffe]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffc-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffc-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffd-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb\udffd-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc69\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffd\udfff]|\ud83d\udc69\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb-\udffd\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffe]|\ud83d\udc69\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb-\udffe]|\ud83e\uddd1\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffc-\udfff]|\ud83e\uddd1\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb\udffd-\udfff]|\ud83e\uddd1\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb\udffc\udffe\udfff]|\ud83e\uddd1\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb-\udffd\udfff]|\ud83e\uddd1\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb-\udffe]|\ud83e\uddd1\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83d\udc68\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68|\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d[\udc68\udc69]|\ud83d\udc68\u200d\u2764\ufe0f\u200d\ud83d\udc68|\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d[\udc68\udc69]|\ud83e\uddd1\u200d\ud83e\udd1d\u200d\ud83e\uddd1|\ud83d\udc6b\ud83c[\udffb-\udfff]|\ud83d\udc6c\ud83c[\udffb-\udfff]|\ud83d\udc6d\ud83c[\udffb-\udfff]|\ud83d\udc8f\ud83c[\udffb-\udfff]|\ud83d\udc91\ud83c[\udffb-\udfff]|\ud83d[\udc6b-\udc6d\udc8f\udc91])|(?:\ud83d[\udc68\udc69]|\ud83e\uddd1)(?:\ud83c[\udffb-\udfff])?\u200d(?:\u2695\ufe0f|\u2696\ufe0f|\u2708\ufe0f|\ud83c[\udf3e\udf73\udf7c\udf84\udf93\udfa4\udfa8\udfeb\udfed]|\ud83d[\udcbb\udcbc\udd27\udd2c\ude80\ude92]|\ud83e[\uddaf-\uddb3\uddbc\uddbd])|(?:\ud83c[\udfcb\udfcc]|\ud83d[\udd74\udd75]|\u26f9)((?:\ud83c[\udffb-\udfff]|\ufe0f)\u200d[\u2640\u2642]\ufe0f)|(?:\ud83c[\udfc3\udfc4\udfca]|\ud83d[\udc6e\udc70\udc71\udc73\udc77\udc81\udc82\udc86\udc87\ude45-\ude47\ude4b\ude4d\ude4e\udea3\udeb4-\udeb6]|\ud83e[\udd26\udd35\udd37-\udd39\udd3d\udd3e\uddb8\uddb9\uddcd-\uddcf\uddd4\uddd6-\udddd])(?:\ud83c[\udffb-\udfff])?\u200d[\u2640\u2642]\ufe0f|(?:\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83c\udff3\ufe0f\u200d\u26a7\ufe0f|\ud83c\udff3\ufe0f\u200d\ud83c\udf08|\ud83d\ude36\u200d\ud83c\udf2b\ufe0f|\u2764\ufe0f\u200d\ud83d\udd25|\u2764\ufe0f\u200d\ud83e\ude79|\ud83c\udff4\u200d\u2620\ufe0f|\ud83d\udc15\u200d\ud83e\uddba|\ud83d\udc3b\u200d\u2744\ufe0f|\ud83d\udc41\u200d\ud83d\udde8|\ud83d\udc68\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83d\udc6f\u200d\u2640\ufe0f|\ud83d\udc6f\u200d\u2642\ufe0f|\ud83d\ude2e\u200d\ud83d\udca8|\ud83d\ude35\u200d\ud83d\udcab|\ud83e\udd3c\u200d\u2640\ufe0f|\ud83e\udd3c\u200d\u2642\ufe0f|\ud83e\uddde\u200d\u2640\ufe0f|\ud83e\uddde\u200d\u2642\ufe0f|\ud83e\udddf\u200d\u2640\ufe0f|\ud83e\udddf\u200d\u2642\ufe0f|\ud83d\udc08\u200d\u2b1b)|[#*0-9]\ufe0f?\u20e3|(?:[©®\u2122\u265f]\ufe0f)|(?:\ud83c[\udc04\udd70\udd71\udd7e\udd7f\ude02\ude1a\ude2f\ude37\udf21\udf24-\udf2c\udf36\udf7d\udf96\udf97\udf99-\udf9b\udf9e\udf9f\udfcd\udfce\udfd4-\udfdf\udff3\udff5\udff7]|\ud83d[\udc3f\udc41\udcfd\udd49\udd4a\udd6f\udd70\udd73\udd76-\udd79\udd87\udd8a-\udd8d\udda5\udda8\uddb1\uddb2\uddbc\uddc2-\uddc4\uddd1-\uddd3\udddc-\uddde\udde1\udde3\udde8\uddef\uddf3\uddfa\udecb\udecd-\udecf\udee0-\udee5\udee9\udef0\udef3]|[\u203c\u2049\u2139\u2194-\u2199\u21a9\u21aa\u231a\u231b\u2328\u23cf\u23ed-\u23ef\u23f1\u23f2\u23f8-\u23fa\u24c2\u25aa\u25ab\u25b6\u25c0\u25fb-\u25fe\u2600-\u2604\u260e\u2611\u2614\u2615\u2618\u2620\u2622\u2623\u2626\u262a\u262e\u262f\u2638-\u263a\u2640\u2642\u2648-\u2653\u2660\u2663\u2665\u2666\u2668\u267b\u267f\u2692-\u2697\u2699\u269b\u269c\u26a0\u26a1\u26a7\u26aa\u26ab\u26b0\u26b1\u26bd\u26be\u26c4\u26c5\u26c8\u26cf\u26d1\u26d3\u26d4\u26e9\u26ea\u26f0-\u26f5\u26f8\u26fa\u26fd\u2702\u2708\u2709\u270f\u2712\u2714\u2716\u271d\u2721\u2733\u2734\u2744\u2747\u2757\u2763\u2764\u27a1\u2934\u2935\u2b05-\u2b07\u2b1b\u2b1c\u2b50\u2b55\u3030\u303d\u3297\u3299])(?:\ufe0f|(?!\ufe0e))|(?:(?:\ud83c[\udfcb\udfcc]|\ud83d[\udd74\udd75\udd90]|[\u261d\u26f7\u26f9\u270c\u270d])(?:\ufe0f|(?!\ufe0e))|(?:\ud83c[\udf85\udfc2-\udfc4\udfc7\udfca]|\ud83d[\udc42\udc43\udc46-\udc50\udc66-\udc69\udc6e\udc70-\udc78\udc7c\udc81-\udc83\udc85-\udc87\udcaa\udd7a\udd95\udd96\ude45-\ude47\ude4b-\ude4f\udea3\udeb4-\udeb6\udec0\udecc]|\ud83e[\udd0c\udd0f\udd18-\udd1c\udd1e\udd1f\udd26\udd30-\udd39\udd3d\udd3e\udd77\uddb5\uddb6\uddb8\uddb9\uddbb\uddcd-\uddcf\uddd1-\udddd]|[\u270a\u270b]))(?:\ud83c[\udffb-\udfff])?|(?:\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc65\udb40\udc6e\udb40\udc67\udb40\udc7f|\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc73\udb40\udc63\udb40\udc74\udb40\udc7f|\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc77\udb40\udc6c\udb40\udc73\udb40\udc7f|\ud83c\udde6\ud83c[\udde8-\uddec\uddee\uddf1\uddf2\uddf4\uddf6-\uddfa\uddfc\uddfd\uddff]|\ud83c\udde7\ud83c[\udde6\udde7\udde9-\uddef\uddf1-\uddf4\uddf6-\uddf9\uddfb\uddfc\uddfe\uddff]|\ud83c\udde8\ud83c[\udde6\udde8\udde9\uddeb-\uddee\uddf0-\uddf5\uddf7\uddfa-\uddff]|\ud83c\udde9\ud83c[\uddea\uddec\uddef\uddf0\uddf2\uddf4\uddff]|\ud83c\uddea\ud83c[\udde6\udde8\uddea\uddec\udded\uddf7-\uddfa]|\ud83c\uddeb\ud83c[\uddee-\uddf0\uddf2\uddf4\uddf7]|\ud83c\uddec\ud83c[\udde6\udde7\udde9-\uddee\uddf1-\uddf3\uddf5-\uddfa\uddfc\uddfe]|\ud83c\udded\ud83c[\uddf0\uddf2\uddf3\uddf7\uddf9\uddfa]|\ud83c\uddee\ud83c[\udde8-\uddea\uddf1-\uddf4\uddf6-\uddf9]|\ud83c\uddef\ud83c[\uddea\uddf2\uddf4\uddf5]|\ud83c\uddf0\ud83c[\uddea\uddec-\uddee\uddf2\uddf3\uddf5\uddf7\uddfc\uddfe\uddff]|\ud83c\uddf1\ud83c[\udde6-\udde8\uddee\uddf0\uddf7-\uddfb\uddfe]|\ud83c\uddf2\ud83c[\udde6\udde8-\udded\uddf0-\uddff]|\ud83c\uddf3\ud83c[\udde6\udde8\uddea-\uddec\uddee\uddf1\uddf4\uddf5\uddf7\uddfa\uddff]|\ud83c\uddf4\ud83c\uddf2|\ud83c\uddf5\ud83c[\udde6\uddea-\udded\uddf0-\uddf3\uddf7-\uddf9\uddfc\uddfe]|\ud83c\uddf6\ud83c\udde6|\ud83c\uddf7\ud83c[\uddea\uddf4\uddf8\uddfa\uddfc]|\ud83c\uddf8\ud83c[\udde6-\uddea\uddec-\uddf4\uddf7-\uddf9\uddfb\uddfd-\uddff]|\ud83c\uddf9\ud83c[\udde6\udde8\udde9\uddeb-\udded\uddef-\uddf4\uddf7\uddf9\uddfb\uddfc\uddff]|\ud83c\uddfa\ud83c[\udde6\uddec\uddf2\uddf3\uddf8\uddfe\uddff]|\ud83c\uddfb\ud83c[\udde6\udde8\uddea\uddec\uddee\uddf3\uddfa]|\ud83c\uddfc\ud83c[\uddeb\uddf8]|\ud83c\uddfd\ud83c\uddf0|\ud83c\uddfe\ud83c[\uddea\uddf9]|\ud83c\uddff\ud83c[\udde6\uddf2\uddfc]|\ud83c[\udccf\udd8e\udd91-\udd9a\udde6-\uddff\ude01\ude32-\ude36\ude38-\ude3a\ude50\ude51\udf00-\udf20\udf2d-\udf35\udf37-\udf7c\udf7e-\udf84\udf86-\udf93\udfa0-\udfc1\udfc5\udfc6\udfc8\udfc9\udfcf-\udfd3\udfe0-\udff0\udff4\udff8-\udfff]|\ud83d[\udc00-\udc3e\udc40\udc44\udc45\udc51-\udc65\udc6a\udc6f\udc79-\udc7b\udc7d-\udc80\udc84\udc88-\udc8e\udc90\udc92-\udca9\udcab-\udcfc\udcff-\udd3d\udd4b-\udd4e\udd50-\udd67\udda4\uddfb-\ude44\ude48-\ude4a\ude80-\udea2\udea4-\udeb3\udeb7-\udebf\udec1-\udec5\uded0-\uded2\uded5-\uded7\udeeb\udeec\udef4-\udefc\udfe0-\udfeb]|\ud83e[\udd0d\udd0e\udd10-\udd17\udd1d\udd20-\udd25\udd27-\udd2f\udd3a\udd3c\udd3f-\udd45\udd47-\udd76\udd78\udd7a-\uddb4\uddb7\uddba\uddbc-\uddcb\uddd0\uddde-\uddff\ude70-\ude74\ude78-\ude7a\ude80-\ude86\ude90-\udea8\udeb0-\udeb6\udec0-\udec2\uded0-\uded6]|[\u23e9-\u23ec\u23f0\u23f3\u267e\u26ce\u2705\u2728\u274c\u274e\u2753-\u2755\u2795-\u2797\u27b0\u27bf\ue50a])|\ufe0f/g,o=/\uFE0F/g,r=String.fromCharCode(8205),i=/[&<>'"]/g,a=/^(?:iframe|noframes|noscript|script|select|style|textarea)$/,s=String.fromCharCode;return e;function u(e,t){return document.createTextNode(t?e.replace(o,""):e)}function c(e,t){return"".concat(t.base,t.size,"/",e,t.ext)}function l(e,t){for(var n,o,r=e.childNodes,i=r.length;i--;)3===(o=(n=r[i]).nodeType)?t.push(n):1!==o||"ownerSVGElement"in n||a.test(n.nodeName.toLowerCase())||l(n,t);return t}function d(e){return _(e.indexOf(r)<0?e.replace(o,""):e)}function h(e,t){for(var o,r,i,a,s,c,h,p,f,g,m,_,F,y=l(e,[]),b=y.length;b--;){for(i=!1,a=document.createDocumentFragment(),c=(s=y[b]).nodeValue,p=0;h=n.exec(c);){if((f=h.index)!==p&&a.appendChild(u(c.slice(p,f),!0)),_=d(m=h[0]),p=f+m.length,F=t.callback(_,t),_&&F){for(r in(g=new Image).onerror=t.onerror,g.setAttribute("draggable","false"),o=t.attributes(m,_))o.hasOwnProperty(r)&&0!==r.indexOf("on")&&!g.hasAttribute(r)&&g.setAttribute(r,o[r]);g.className=t.className,g.alt=m,g.src=F,i=!0,a.appendChild(g)}g||a.appendChild(u(m,!1)),g=null}i&&(p")}return r}))}function f(e){return t[e]}function g(){return null}function m(e,t){return String(e).replace(n,t)}function _(e,t){for(var n=[],o=0,r=0,i=0;i"},{"annotation":"smiling face with halo","group":0,"hexcode":"1F607","order":13,"tags":["angel","face","fantasy","halo","innocent"],"unicode":"😇","emoticon":"o:)"},{"annotation":"smiling face with hearts","group":0,"hexcode":"1F970","order":14,"tags":["adore","crush","hearts","in love"],"unicode":"🥰"},{"annotation":"smiling face with heart-eyes","group":0,"hexcode":"1F60D","order":15,"tags":["eye","face","love","smile"],"unicode":"😍"},{"annotation":"star-struck","group":0,"hexcode":"1F929","order":16,"tags":["eyes","face","grinning","star"],"unicode":"🤩"},{"annotation":"face blowing a kiss","group":0,"hexcode":"1F618","order":17,"tags":["face","kiss"],"unicode":"😘","emoticon":":x"},{"annotation":"kissing face","group":0,"hexcode":"1F617","order":18,"tags":["face","kiss"],"unicode":"😗"},{"annotation":"smiling face","group":0,"hexcode":"263A","order":20,"tags":["face","outlined","relaxed","smile"],"unicode":"☺️"},{"annotation":"kissing face with closed eyes","group":0,"hexcode":"1F61A","order":21,"tags":["closed","eye","face","kiss"],"unicode":"😚","emoticon":":*"},{"annotation":"kissing face with smiling eyes","group":0,"hexcode":"1F619","order":22,"tags":["eye","face","kiss","smile"],"unicode":"😙"},{"annotation":"smiling face with tear","group":0,"hexcode":"1F972","order":23,"tags":["grateful","proud","relieved","smiling","tear","touched"],"unicode":"🥲"},{"annotation":"face savoring food","group":0,"hexcode":"1F60B","order":24,"tags":["delicious","face","savouring","smile","yum"],"unicode":"😋"},{"annotation":"face with tongue","group":0,"hexcode":"1F61B","order":25,"tags":["face","tongue"],"unicode":"😛","emoticon":":p"},{"annotation":"winking face with tongue","group":0,"hexcode":"1F61C","order":26,"tags":["eye","face","joke","tongue","wink"],"unicode":"😜","emoticon":";p"},{"annotation":"zany face","group":0,"hexcode":"1F92A","order":27,"tags":["eye","goofy","large","small"],"unicode":"🤪"},{"annotation":"squinting face with tongue","group":0,"hexcode":"1F61D","order":28,"tags":["eye","face","horrible","taste","tongue"],"unicode":"😝","emoticon":"xp"},{"annotation":"money-mouth face","group":0,"hexcode":"1F911","order":29,"tags":["face","money","mouth"],"unicode":"🤑"},{"annotation":"hugging face","group":0,"hexcode":"1F917","order":30,"tags":["face","hug","hugging"],"unicode":"🤗"},{"annotation":"face with hand over mouth","group":0,"hexcode":"1F92D","order":31,"tags":["whoops"],"unicode":"🤭"},{"annotation":"shushing face","group":0,"hexcode":"1F92B","order":32,"tags":["quiet","shush"],"unicode":"🤫"},{"annotation":"thinking face","group":0,"hexcode":"1F914","order":33,"tags":["face","thinking"],"unicode":"🤔","emoticon":":l"},{"annotation":"zipper-mouth face","group":0,"hexcode":"1F910","order":34,"tags":["face","mouth","zipper"],"unicode":"🤐","emoticon":":z"},{"annotation":"face with raised eyebrow","group":0,"hexcode":"1F928","order":35,"tags":["distrust","skeptic"],"unicode":"🤨"},{"annotation":"neutral face","group":0,"hexcode":"1F610","order":36,"tags":["deadpan","face","meh","neutral"],"unicode":"😐️","emoticon":":|"},{"annotation":"expressionless face","group":0,"hexcode":"1F611","order":37,"tags":["expressionless","face","inexpressive","meh","unexpressive"],"unicode":"😑"},{"annotation":"face without mouth","group":0,"hexcode":"1F636","order":38,"tags":["face","mouth","quiet","silent"],"unicode":"😶","emoticon":":#"},{"annotation":"face in clouds","group":0,"hexcode":"1F636-200D-1F32B-FE0F","order":39,"tags":["absentminded","face in the fog","head in clouds"],"unicode":"😶‍🌫️"},{"annotation":"smirking face","group":0,"hexcode":"1F60F","order":41,"tags":["face","smirk"],"unicode":"😏","emoticon":":j"},{"annotation":"unamused face","group":0,"hexcode":"1F612","order":42,"tags":["face","unamused","unhappy"],"unicode":"😒","emoticon":":?"},{"annotation":"face with rolling eyes","group":0,"hexcode":"1F644","order":43,"tags":["eyeroll","eyes","face","rolling"],"unicode":"🙄"},{"annotation":"grimacing face","group":0,"hexcode":"1F62C","order":44,"tags":["face","grimace"],"unicode":"😬","emoticon":"8D"},{"annotation":"face exhaling","group":0,"hexcode":"1F62E-200D-1F4A8","order":45,"tags":["exhale","gasp","groan","relief","whisper","whistle"],"unicode":"😮‍💨"},{"annotation":"lying face","group":0,"hexcode":"1F925","order":46,"tags":["face","lie","pinocchio"],"unicode":"🤥"},{"annotation":"relieved face","group":0,"hexcode":"1F60C","order":47,"tags":["face","relieved"],"unicode":"😌"},{"annotation":"pensive face","group":0,"hexcode":"1F614","order":48,"tags":["dejected","face","pensive"],"unicode":"😔"},{"annotation":"sleepy face","group":0,"hexcode":"1F62A","order":49,"tags":["face","sleep"],"unicode":"😪"},{"annotation":"drooling face","group":0,"hexcode":"1F924","order":50,"tags":["drooling","face"],"unicode":"🤤"},{"annotation":"sleeping face","group":0,"hexcode":"1F634","order":51,"tags":["face","sleep","zzz"],"unicode":"😴"},{"annotation":"face with medical mask","group":0,"hexcode":"1F637","order":52,"tags":["cold","doctor","face","mask","sick"],"unicode":"😷"},{"annotation":"face with thermometer","group":0,"hexcode":"1F912","order":53,"tags":["face","ill","sick","thermometer"],"unicode":"🤒"},{"annotation":"face with head-bandage","group":0,"hexcode":"1F915","order":54,"tags":["bandage","face","hurt","injury"],"unicode":"🤕"},{"annotation":"nauseated face","group":0,"hexcode":"1F922","order":55,"tags":["face","nauseated","vomit"],"unicode":"🤢","emoticon":"%("},{"annotation":"face vomiting","group":0,"hexcode":"1F92E","order":56,"tags":["puke","sick","vomit"],"unicode":"🤮"},{"annotation":"sneezing face","group":0,"hexcode":"1F927","order":57,"tags":["face","gesundheit","sneeze"],"unicode":"🤧"},{"annotation":"hot face","group":0,"hexcode":"1F975","order":58,"tags":["feverish","heat stroke","hot","red-faced","sweating"],"unicode":"🥵"},{"annotation":"cold face","group":0,"hexcode":"1F976","order":59,"tags":["blue-faced","cold","freezing","frostbite","icicles"],"unicode":"🥶"},{"annotation":"woozy face","group":0,"hexcode":"1F974","order":60,"tags":["dizzy","intoxicated","tipsy","uneven eyes","wavy mouth"],"unicode":"🥴","emoticon":":&"},{"annotation":"knocked-out face","group":0,"hexcode":"1F635","order":61,"tags":["dead","face","knocked out"],"unicode":"😵","emoticon":"xo"},{"annotation":"face with spiral eyes","group":0,"hexcode":"1F635-200D-1F4AB","order":62,"tags":["dizzy","hypnotized","spiral","trouble","whoa"],"unicode":"😵‍💫"},{"annotation":"exploding head","group":0,"hexcode":"1F92F","order":63,"tags":["mind blown","shocked"],"unicode":"🤯"},{"annotation":"cowboy hat face","group":0,"hexcode":"1F920","order":64,"tags":["cowboy","cowgirl","face","hat"],"unicode":"🤠"},{"annotation":"partying face","group":0,"hexcode":"1F973","order":65,"tags":["celebration","hat","horn","party"],"unicode":"🥳"},{"annotation":"disguised face","group":0,"hexcode":"1F978","order":66,"tags":["disguise","face","glasses","incognito","nose"],"unicode":"🥸"},{"annotation":"smiling face with sunglasses","group":0,"hexcode":"1F60E","order":67,"tags":["bright","cool","face","sun","sunglasses"],"unicode":"😎","emoticon":"8)"},{"annotation":"nerd face","group":0,"hexcode":"1F913","order":68,"tags":["face","geek","nerd"],"unicode":"🤓","emoticon":":B"},{"annotation":"face with monocle","group":0,"hexcode":"1F9D0","order":69,"tags":["stuffy"],"unicode":"🧐"},{"annotation":"confused face","group":0,"hexcode":"1F615","order":70,"tags":["confused","face","meh"],"unicode":"😕","emoticon":":/"},{"annotation":"worried face","group":0,"hexcode":"1F61F","order":71,"tags":["face","worried"],"unicode":"😟"},{"annotation":"slightly frowning face","group":0,"hexcode":"1F641","order":72,"tags":["face","frown"],"unicode":"🙁"},{"annotation":"frowning face","group":0,"hexcode":"2639","order":74,"tags":["face","frown"],"unicode":"☹️","emoticon":":("},{"annotation":"face with open mouth","group":0,"hexcode":"1F62E","order":75,"tags":["face","mouth","open","sympathy"],"unicode":"😮"},{"annotation":"hushed face","group":0,"hexcode":"1F62F","order":76,"tags":["face","hushed","stunned","surprised"],"unicode":"😯"},{"annotation":"astonished face","group":0,"hexcode":"1F632","order":77,"tags":["astonished","face","shocked","totally"],"unicode":"😲","emoticon":":o"},{"annotation":"flushed face","group":0,"hexcode":"1F633","order":78,"tags":["dazed","face","flushed"],"unicode":"😳","emoticon":":$"},{"annotation":"pleading face","group":0,"hexcode":"1F97A","order":79,"tags":["begging","mercy","puppy eyes"],"unicode":"🥺"},{"annotation":"frowning face with open mouth","group":0,"hexcode":"1F626","order":80,"tags":["face","frown","mouth","open"],"unicode":"😦"},{"annotation":"anguished face","group":0,"hexcode":"1F627","order":81,"tags":["anguished","face"],"unicode":"😧","emoticon":":s"},{"annotation":"fearful face","group":0,"hexcode":"1F628","order":82,"tags":["face","fear","fearful","scared"],"unicode":"😨"},{"annotation":"anxious face with sweat","group":0,"hexcode":"1F630","order":83,"tags":["blue","cold","face","rushed","sweat"],"unicode":"😰"},{"annotation":"sad but relieved face","group":0,"hexcode":"1F625","order":84,"tags":["disappointed","face","relieved","whew"],"unicode":"😥"},{"annotation":"crying face","group":0,"hexcode":"1F622","order":85,"tags":["cry","face","sad","tear"],"unicode":"😢","emoticon":":\'("},{"annotation":"loudly crying face","group":0,"hexcode":"1F62D","order":86,"tags":["cry","face","sad","sob","tear"],"unicode":"😭","emoticon":":\'o"},{"annotation":"face screaming in fear","group":0,"hexcode":"1F631","order":87,"tags":["face","fear","munch","scared","scream"],"unicode":"😱","emoticon":"Dx"},{"annotation":"confounded face","group":0,"hexcode":"1F616","order":88,"tags":["confounded","face"],"unicode":"😖","emoticon":"x("},{"annotation":"persevering face","group":0,"hexcode":"1F623","order":89,"tags":["face","persevere"],"unicode":"😣"},{"annotation":"disappointed face","group":0,"hexcode":"1F61E","order":90,"tags":["disappointed","face"],"unicode":"😞"},{"annotation":"downcast face with sweat","group":0,"hexcode":"1F613","order":91,"tags":["cold","face","sweat"],"unicode":"😓","emoticon":":<"},{"annotation":"weary face","group":0,"hexcode":"1F629","order":92,"tags":["face","tired","weary"],"unicode":"😩","emoticon":"D:"},{"annotation":"tired face","group":0,"hexcode":"1F62B","order":93,"tags":["face","tired"],"unicode":"😫","emoticon":":c"},{"annotation":"yawning face","group":0,"hexcode":"1F971","order":94,"tags":["bored","tired","yawn"],"unicode":"🥱"},{"annotation":"face with steam from nose","group":0,"hexcode":"1F624","order":95,"tags":["face","triumph","won"],"unicode":"😤"},{"annotation":"pouting face","group":0,"hexcode":"1F621","order":96,"tags":["angry","face","mad","pouting","rage","red"],"unicode":"😡","emoticon":">:/"},{"annotation":"angry face","group":0,"hexcode":"1F620","order":97,"tags":["anger","angry","face","mad"],"unicode":"😠"},{"annotation":"face with symbols on mouth","group":0,"hexcode":"1F92C","order":98,"tags":["swearing"],"unicode":"🤬","emoticon":":@"},{"annotation":"smiling face with horns","group":0,"hexcode":"1F608","order":99,"tags":["face","fairy tale","fantasy","horns","smile"],"unicode":"😈","emoticon":">:)"},{"annotation":"angry face with horns","group":0,"hexcode":"1F47F","order":100,"tags":["demon","devil","face","fantasy","imp"],"unicode":"👿","emoticon":">:("},{"annotation":"skull","group":0,"hexcode":"1F480","order":101,"tags":["death","face","fairy tale","monster"],"unicode":"💀"},{"annotation":"skull and crossbones","group":0,"hexcode":"2620","order":103,"tags":["crossbones","death","face","monster","skull"],"unicode":"☠️"},{"annotation":"pile of poo","group":0,"hexcode":"1F4A9","order":104,"tags":["dung","face","monster","poo","poop"],"unicode":"💩"},{"annotation":"clown face","group":0,"hexcode":"1F921","order":105,"tags":["clown","face"],"unicode":"🤡"},{"annotation":"ogre","group":0,"hexcode":"1F479","order":106,"tags":["creature","face","fairy tale","fantasy","monster"],"unicode":"👹","emoticon":">0)"},{"annotation":"goblin","group":0,"hexcode":"1F47A","order":107,"tags":["creature","face","fairy tale","fantasy","monster"],"unicode":"👺"},{"annotation":"ghost","group":0,"hexcode":"1F47B","order":108,"tags":["creature","face","fairy tale","fantasy","monster"],"unicode":"👻"},{"annotation":"alien","group":0,"hexcode":"1F47D","order":109,"tags":["creature","extraterrestrial","face","fantasy","ufo"],"unicode":"👽️"},{"annotation":"alien monster","group":0,"hexcode":"1F47E","order":110,"tags":["alien","creature","extraterrestrial","face","monster","ufo"],"unicode":"👾"},{"annotation":"robot","group":0,"hexcode":"1F916","order":111,"tags":["face","monster"],"unicode":"🤖"},{"annotation":"grinning cat","group":0,"hexcode":"1F63A","order":112,"tags":["cat","face","grinning","mouth","open","smile"],"unicode":"😺"},{"annotation":"grinning cat with smiling eyes","group":0,"hexcode":"1F638","order":113,"tags":["cat","eye","face","grin","smile"],"unicode":"😸"},{"annotation":"cat with tears of joy","group":0,"hexcode":"1F639","order":114,"tags":["cat","face","joy","tear"],"unicode":"😹"},{"annotation":"smiling cat with heart-eyes","group":0,"hexcode":"1F63B","order":115,"tags":["cat","eye","face","heart","love","smile"],"unicode":"😻"},{"annotation":"cat with wry smile","group":0,"hexcode":"1F63C","order":116,"tags":["cat","face","ironic","smile","wry"],"unicode":"😼"},{"annotation":"kissing cat","group":0,"hexcode":"1F63D","order":117,"tags":["cat","eye","face","kiss"],"unicode":"😽","emoticon":":3"},{"annotation":"weary cat","group":0,"hexcode":"1F640","order":118,"tags":["cat","face","oh","surprised","weary"],"unicode":"🙀"},{"annotation":"crying cat","group":0,"hexcode":"1F63F","order":119,"tags":["cat","cry","face","sad","tear"],"unicode":"😿"},{"annotation":"pouting cat","group":0,"hexcode":"1F63E","order":120,"tags":["cat","face","pouting"],"unicode":"😾"},{"annotation":"see-no-evil monkey","group":0,"hexcode":"1F648","order":121,"tags":["evil","face","forbidden","monkey","see"],"unicode":"🙈"},{"annotation":"hear-no-evil monkey","group":0,"hexcode":"1F649","order":122,"tags":["evil","face","forbidden","hear","monkey"],"unicode":"🙉"},{"annotation":"speak-no-evil monkey","group":0,"hexcode":"1F64A","order":123,"tags":["evil","face","forbidden","monkey","speak"],"unicode":"🙊"},{"annotation":"kiss mark","group":0,"hexcode":"1F48B","order":124,"tags":["kiss","lips"],"unicode":"💋"},{"annotation":"love letter","group":0,"hexcode":"1F48C","order":125,"tags":["heart","letter","love","mail"],"unicode":"💌"},{"annotation":"heart with arrow","group":0,"hexcode":"1F498","order":126,"tags":["arrow","cupid"],"unicode":"💘"},{"annotation":"heart with ribbon","group":0,"hexcode":"1F49D","order":127,"tags":["ribbon","valentine"],"unicode":"💝"},{"annotation":"sparkling heart","group":0,"hexcode":"1F496","order":128,"tags":["excited","sparkle"],"unicode":"💖"},{"annotation":"growing heart","group":0,"hexcode":"1F497","order":129,"tags":["excited","growing","nervous","pulse"],"unicode":"💗"},{"annotation":"beating heart","group":0,"hexcode":"1F493","order":130,"tags":["beating","heartbeat","pulsating"],"unicode":"💓"},{"annotation":"revolving hearts","group":0,"hexcode":"1F49E","order":131,"tags":["revolving"],"unicode":"💞"},{"annotation":"two hearts","group":0,"hexcode":"1F495","order":132,"tags":["love"],"unicode":"💕"},{"annotation":"heart decoration","group":0,"hexcode":"1F49F","order":133,"tags":["heart"],"unicode":"💟"},{"annotation":"heart exclamation","group":0,"hexcode":"2763","order":135,"tags":["exclamation","mark","punctuation"],"unicode":"❣️"},{"annotation":"broken heart","group":0,"hexcode":"1F494","order":136,"tags":["break","broken"],"unicode":"💔","emoticon":"","skins":[{"annotation":"man mage: light skin tone","group":1,"hexcode":"1F9D9-1F3FB-200D-2642-FE0F","order":1623,"unicode":"🧙🏻‍♂️"},{"annotation":"man mage: medium-light skin tone","group":1,"hexcode":"1F9D9-1F3FC-200D-2642-FE0F","order":1625,"unicode":"🧙🏼‍♂️"},{"annotation":"man mage: medium skin tone","group":1,"hexcode":"1F9D9-1F3FD-200D-2642-FE0F","order":1627,"unicode":"🧙🏽‍♂️"},{"annotation":"man mage: medium-dark skin tone","group":1,"hexcode":"1F9D9-1F3FE-200D-2642-FE0F","order":1629,"unicode":"🧙🏾‍♂️"},{"annotation":"man mage: dark skin tone","group":1,"hexcode":"1F9D9-1F3FF-200D-2642-FE0F","order":1631,"unicode":"🧙🏿‍♂️"}]},{"annotation":"woman mage","group":1,"hexcode":"1F9D9-200D-2640-FE0F","order":1633,"tags":["sorceress","witch"],"unicode":"🧙‍♀️","skins":[{"annotation":"woman mage: light skin tone","group":1,"hexcode":"1F9D9-1F3FB-200D-2640-FE0F","order":1635,"unicode":"🧙🏻‍♀️"},{"annotation":"woman mage: medium-light skin tone","group":1,"hexcode":"1F9D9-1F3FC-200D-2640-FE0F","order":1637,"unicode":"🧙🏼‍♀️"},{"annotation":"woman mage: medium skin tone","group":1,"hexcode":"1F9D9-1F3FD-200D-2640-FE0F","order":1639,"unicode":"🧙🏽‍♀️"},{"annotation":"woman mage: medium-dark skin tone","group":1,"hexcode":"1F9D9-1F3FE-200D-2640-FE0F","order":1641,"unicode":"🧙🏾‍♀️"},{"annotation":"woman mage: dark skin tone","group":1,"hexcode":"1F9D9-1F3FF-200D-2640-FE0F","order":1643,"unicode":"🧙🏿‍♀️"}]},{"annotation":"fairy","group":1,"hexcode":"1F9DA","order":1645,"tags":["oberon","puck","titania"],"unicode":"🧚","skins":[{"annotation":"fairy: light skin tone","group":1,"hexcode":"1F9DA-1F3FB","order":1646,"unicode":"🧚🏻"},{"annotation":"fairy: medium-light skin tone","group":1,"hexcode":"1F9DA-1F3FC","order":1647,"unicode":"🧚🏼"},{"annotation":"fairy: medium skin tone","group":1,"hexcode":"1F9DA-1F3FD","order":1648,"unicode":"🧚🏽"},{"annotation":"fairy: medium-dark skin tone","group":1,"hexcode":"1F9DA-1F3FE","order":1649,"unicode":"🧚🏾"},{"annotation":"fairy: dark skin tone","group":1,"hexcode":"1F9DA-1F3FF","order":1650,"unicode":"🧚🏿"}]},{"annotation":"man fairy","group":1,"hexcode":"1F9DA-200D-2642-FE0F","order":1651,"tags":["oberon","puck"],"unicode":"🧚‍♂️","skins":[{"annotation":"man fairy: light skin tone","group":1,"hexcode":"1F9DA-1F3FB-200D-2642-FE0F","order":1653,"unicode":"🧚🏻‍♂️"},{"annotation":"man fairy: medium-light skin tone","group":1,"hexcode":"1F9DA-1F3FC-200D-2642-FE0F","order":1655,"unicode":"🧚🏼‍♂️"},{"annotation":"man fairy: medium skin tone","group":1,"hexcode":"1F9DA-1F3FD-200D-2642-FE0F","order":1657,"unicode":"🧚🏽‍♂️"},{"annotation":"man fairy: medium-dark skin tone","group":1,"hexcode":"1F9DA-1F3FE-200D-2642-FE0F","order":1659,"unicode":"🧚🏾‍♂️"},{"annotation":"man fairy: dark skin tone","group":1,"hexcode":"1F9DA-1F3FF-200D-2642-FE0F","order":1661,"unicode":"🧚🏿‍♂️"}]},{"annotation":"woman fairy","group":1,"hexcode":"1F9DA-200D-2640-FE0F","order":1663,"tags":["titania"],"unicode":"🧚‍♀️","skins":[{"annotation":"woman fairy: light skin tone","group":1,"hexcode":"1F9DA-1F3FB-200D-2640-FE0F","order":1665,"unicode":"🧚🏻‍♀️"},{"annotation":"woman fairy: medium-light skin tone","group":1,"hexcode":"1F9DA-1F3FC-200D-2640-FE0F","order":1667,"unicode":"🧚🏼‍♀️"},{"annotation":"woman fairy: medium skin tone","group":1,"hexcode":"1F9DA-1F3FD-200D-2640-FE0F","order":1669,"unicode":"🧚🏽‍♀️"},{"annotation":"woman fairy: medium-dark skin tone","group":1,"hexcode":"1F9DA-1F3FE-200D-2640-FE0F","order":1671,"unicode":"🧚🏾‍♀️"},{"annotation":"woman fairy: dark skin tone","group":1,"hexcode":"1F9DA-1F3FF-200D-2640-FE0F","order":1673,"unicode":"🧚🏿‍♀️"}]},{"annotation":"vampire","group":1,"hexcode":"1F9DB","order":1675,"tags":["dracula","undead"],"unicode":"🧛","emoticon":":E","skins":[{"annotation":"vampire: light skin tone","group":1,"hexcode":"1F9DB-1F3FB","order":1676,"unicode":"🧛🏻"},{"annotation":"vampire: medium-light skin tone","group":1,"hexcode":"1F9DB-1F3FC","order":1677,"unicode":"🧛🏼"},{"annotation":"vampire: medium skin tone","group":1,"hexcode":"1F9DB-1F3FD","order":1678,"unicode":"🧛🏽"},{"annotation":"vampire: medium-dark skin tone","group":1,"hexcode":"1F9DB-1F3FE","order":1679,"unicode":"🧛🏾"},{"annotation":"vampire: dark skin tone","group":1,"hexcode":"1F9DB-1F3FF","order":1680,"unicode":"🧛🏿"}]},{"annotation":"man vampire","group":1,"hexcode":"1F9DB-200D-2642-FE0F","order":1681,"tags":["dracula","undead"],"unicode":"🧛‍♂️","skins":[{"annotation":"man vampire: light skin tone","group":1,"hexcode":"1F9DB-1F3FB-200D-2642-FE0F","order":1683,"unicode":"🧛🏻‍♂️"},{"annotation":"man vampire: medium-light skin tone","group":1,"hexcode":"1F9DB-1F3FC-200D-2642-FE0F","order":1685,"unicode":"🧛🏼‍♂️"},{"annotation":"man vampire: medium skin tone","group":1,"hexcode":"1F9DB-1F3FD-200D-2642-FE0F","order":1687,"unicode":"🧛🏽‍♂️"},{"annotation":"man vampire: medium-dark skin tone","group":1,"hexcode":"1F9DB-1F3FE-200D-2642-FE0F","order":1689,"unicode":"🧛🏾‍♂️"},{"annotation":"man vampire: dark skin tone","group":1,"hexcode":"1F9DB-1F3FF-200D-2642-FE0F","order":1691,"unicode":"🧛🏿‍♂️"}]},{"annotation":"woman vampire","group":1,"hexcode":"1F9DB-200D-2640-FE0F","order":1693,"tags":["undead"],"unicode":"🧛‍♀️","skins":[{"annotation":"woman vampire: light skin tone","group":1,"hexcode":"1F9DB-1F3FB-200D-2640-FE0F","order":1695,"unicode":"🧛🏻‍♀️"},{"annotation":"woman vampire: medium-light skin tone","group":1,"hexcode":"1F9DB-1F3FC-200D-2640-FE0F","order":1697,"unicode":"🧛🏼‍♀️"},{"annotation":"woman vampire: medium skin tone","group":1,"hexcode":"1F9DB-1F3FD-200D-2640-FE0F","order":1699,"unicode":"🧛🏽‍♀️"},{"annotation":"woman vampire: medium-dark skin tone","group":1,"hexcode":"1F9DB-1F3FE-200D-2640-FE0F","order":1701,"unicode":"🧛🏾‍♀️"},{"annotation":"woman vampire: dark skin tone","group":1,"hexcode":"1F9DB-1F3FF-200D-2640-FE0F","order":1703,"unicode":"🧛🏿‍♀️"}]},{"annotation":"merperson","group":1,"hexcode":"1F9DC","order":1705,"tags":["mermaid","merman","merwoman"],"unicode":"🧜","skins":[{"annotation":"merperson: light skin tone","group":1,"hexcode":"1F9DC-1F3FB","order":1706,"unicode":"🧜🏻"},{"annotation":"merperson: medium-light skin tone","group":1,"hexcode":"1F9DC-1F3FC","order":1707,"unicode":"🧜🏼"},{"annotation":"merperson: medium skin tone","group":1,"hexcode":"1F9DC-1F3FD","order":1708,"unicode":"🧜🏽"},{"annotation":"merperson: medium-dark skin tone","group":1,"hexcode":"1F9DC-1F3FE","order":1709,"unicode":"🧜🏾"},{"annotation":"merperson: dark skin tone","group":1,"hexcode":"1F9DC-1F3FF","order":1710,"unicode":"🧜🏿"}]},{"annotation":"merman","group":1,"hexcode":"1F9DC-200D-2642-FE0F","order":1711,"tags":["triton"],"unicode":"🧜‍♂️","skins":[{"annotation":"merman: light skin tone","group":1,"hexcode":"1F9DC-1F3FB-200D-2642-FE0F","order":1713,"unicode":"🧜🏻‍♂️"},{"annotation":"merman: medium-light skin tone","group":1,"hexcode":"1F9DC-1F3FC-200D-2642-FE0F","order":1715,"unicode":"🧜🏼‍♂️"},{"annotation":"merman: medium skin tone","group":1,"hexcode":"1F9DC-1F3FD-200D-2642-FE0F","order":1717,"unicode":"🧜🏽‍♂️"},{"annotation":"merman: medium-dark skin tone","group":1,"hexcode":"1F9DC-1F3FE-200D-2642-FE0F","order":1719,"unicode":"🧜🏾‍♂️"},{"annotation":"merman: dark skin tone","group":1,"hexcode":"1F9DC-1F3FF-200D-2642-FE0F","order":1721,"unicode":"🧜🏿‍♂️"}]},{"annotation":"mermaid","group":1,"hexcode":"1F9DC-200D-2640-FE0F","order":1723,"tags":["merwoman"],"unicode":"🧜‍♀️","skins":[{"annotation":"mermaid: light skin tone","group":1,"hexcode":"1F9DC-1F3FB-200D-2640-FE0F","order":1725,"unicode":"🧜🏻‍♀️"},{"annotation":"mermaid: medium-light skin tone","group":1,"hexcode":"1F9DC-1F3FC-200D-2640-FE0F","order":1727,"unicode":"🧜🏼‍♀️"},{"annotation":"mermaid: medium skin tone","group":1,"hexcode":"1F9DC-1F3FD-200D-2640-FE0F","order":1729,"unicode":"🧜🏽‍♀️"},{"annotation":"mermaid: medium-dark skin tone","group":1,"hexcode":"1F9DC-1F3FE-200D-2640-FE0F","order":1731,"unicode":"🧜🏾‍♀️"},{"annotation":"mermaid: dark skin tone","group":1,"hexcode":"1F9DC-1F3FF-200D-2640-FE0F","order":1733,"unicode":"🧜🏿‍♀️"}]},{"annotation":"elf","group":1,"hexcode":"1F9DD","order":1735,"tags":["magical"],"unicode":"🧝","skins":[{"annotation":"elf: light skin tone","group":1,"hexcode":"1F9DD-1F3FB","order":1736,"unicode":"🧝🏻"},{"annotation":"elf: medium-light skin tone","group":1,"hexcode":"1F9DD-1F3FC","order":1737,"unicode":"🧝🏼"},{"annotation":"elf: medium skin tone","group":1,"hexcode":"1F9DD-1F3FD","order":1738,"unicode":"🧝🏽"},{"annotation":"elf: medium-dark skin tone","group":1,"hexcode":"1F9DD-1F3FE","order":1739,"unicode":"🧝🏾"},{"annotation":"elf: dark skin tone","group":1,"hexcode":"1F9DD-1F3FF","order":1740,"unicode":"🧝🏿"}]},{"annotation":"man elf","group":1,"hexcode":"1F9DD-200D-2642-FE0F","order":1741,"tags":["magical"],"unicode":"🧝‍♂️","skins":[{"annotation":"man elf: light skin tone","group":1,"hexcode":"1F9DD-1F3FB-200D-2642-FE0F","order":1743,"unicode":"🧝🏻‍♂️"},{"annotation":"man elf: medium-light skin tone","group":1,"hexcode":"1F9DD-1F3FC-200D-2642-FE0F","order":1745,"unicode":"🧝🏼‍♂️"},{"annotation":"man elf: medium skin tone","group":1,"hexcode":"1F9DD-1F3FD-200D-2642-FE0F","order":1747,"unicode":"🧝🏽‍♂️"},{"annotation":"man elf: medium-dark skin tone","group":1,"hexcode":"1F9DD-1F3FE-200D-2642-FE0F","order":1749,"unicode":"🧝🏾‍♂️"},{"annotation":"man elf: dark skin tone","group":1,"hexcode":"1F9DD-1F3FF-200D-2642-FE0F","order":1751,"unicode":"🧝🏿‍♂️"}]},{"annotation":"woman elf","group":1,"hexcode":"1F9DD-200D-2640-FE0F","order":1753,"tags":["magical"],"unicode":"🧝‍♀️","skins":[{"annotation":"woman elf: light skin tone","group":1,"hexcode":"1F9DD-1F3FB-200D-2640-FE0F","order":1755,"unicode":"🧝🏻‍♀️"},{"annotation":"woman elf: medium-light skin tone","group":1,"hexcode":"1F9DD-1F3FC-200D-2640-FE0F","order":1757,"unicode":"🧝🏼‍♀️"},{"annotation":"woman elf: medium skin tone","group":1,"hexcode":"1F9DD-1F3FD-200D-2640-FE0F","order":1759,"unicode":"🧝🏽‍♀️"},{"annotation":"woman elf: medium-dark skin tone","group":1,"hexcode":"1F9DD-1F3FE-200D-2640-FE0F","order":1761,"unicode":"🧝🏾‍♀️"},{"annotation":"woman elf: dark skin tone","group":1,"hexcode":"1F9DD-1F3FF-200D-2640-FE0F","order":1763,"unicode":"🧝🏿‍♀️"}]},{"annotation":"genie","group":1,"hexcode":"1F9DE","order":1765,"tags":["djinn"],"unicode":"🧞"},{"annotation":"man genie","group":1,"hexcode":"1F9DE-200D-2642-FE0F","order":1766,"tags":["djinn"],"unicode":"🧞‍♂️"},{"annotation":"woman genie","group":1,"hexcode":"1F9DE-200D-2640-FE0F","order":1768,"tags":["djinn"],"unicode":"🧞‍♀️"},{"annotation":"zombie","group":1,"hexcode":"1F9DF","order":1770,"tags":["undead","walking dead"],"unicode":"🧟","emoticon":"8#"},{"annotation":"man zombie","group":1,"hexcode":"1F9DF-200D-2642-FE0F","order":1771,"tags":["undead","walking dead"],"unicode":"🧟‍♂️"},{"annotation":"woman zombie","group":1,"hexcode":"1F9DF-200D-2640-FE0F","order":1773,"tags":["undead","walking dead"],"unicode":"🧟‍♀️"},{"annotation":"person getting massage","group":1,"hexcode":"1F486","order":1775,"tags":["face","massage","salon"],"unicode":"💆","skins":[{"annotation":"person getting massage: light skin tone","group":1,"hexcode":"1F486-1F3FB","order":1776,"unicode":"💆🏻"},{"annotation":"person getting massage: medium-light skin tone","group":1,"hexcode":"1F486-1F3FC","order":1777,"unicode":"💆🏼"},{"annotation":"person getting massage: medium skin tone","group":1,"hexcode":"1F486-1F3FD","order":1778,"unicode":"💆🏽"},{"annotation":"person getting massage: medium-dark skin tone","group":1,"hexcode":"1F486-1F3FE","order":1779,"unicode":"💆🏾"},{"annotation":"person getting massage: dark skin tone","group":1,"hexcode":"1F486-1F3FF","order":1780,"unicode":"💆🏿"}]},{"annotation":"man getting massage","group":1,"hexcode":"1F486-200D-2642-FE0F","order":1781,"tags":["face","man","massage"],"unicode":"💆‍♂️","skins":[{"annotation":"man getting massage: light skin tone","group":1,"hexcode":"1F486-1F3FB-200D-2642-FE0F","order":1783,"unicode":"💆🏻‍♂️"},{"annotation":"man getting massage: medium-light skin tone","group":1,"hexcode":"1F486-1F3FC-200D-2642-FE0F","order":1785,"unicode":"💆🏼‍♂️"},{"annotation":"man getting massage: medium skin tone","group":1,"hexcode":"1F486-1F3FD-200D-2642-FE0F","order":1787,"unicode":"💆🏽‍♂️"},{"annotation":"man getting massage: medium-dark skin tone","group":1,"hexcode":"1F486-1F3FE-200D-2642-FE0F","order":1789,"unicode":"💆🏾‍♂️"},{"annotation":"man getting massage: dark skin tone","group":1,"hexcode":"1F486-1F3FF-200D-2642-FE0F","order":1791,"unicode":"💆🏿‍♂️"}]},{"annotation":"woman getting massage","group":1,"hexcode":"1F486-200D-2640-FE0F","order":1793,"tags":["face","massage","woman"],"unicode":"💆‍♀️","skins":[{"annotation":"woman getting massage: light skin tone","group":1,"hexcode":"1F486-1F3FB-200D-2640-FE0F","order":1795,"unicode":"💆🏻‍♀️"},{"annotation":"woman getting massage: medium-light skin tone","group":1,"hexcode":"1F486-1F3FC-200D-2640-FE0F","order":1797,"unicode":"💆🏼‍♀️"},{"annotation":"woman getting massage: medium skin tone","group":1,"hexcode":"1F486-1F3FD-200D-2640-FE0F","order":1799,"unicode":"💆🏽‍♀️"},{"annotation":"woman getting massage: medium-dark skin tone","group":1,"hexcode":"1F486-1F3FE-200D-2640-FE0F","order":1801,"unicode":"💆🏾‍♀️"},{"annotation":"woman getting massage: dark skin tone","group":1,"hexcode":"1F486-1F3FF-200D-2640-FE0F","order":1803,"unicode":"💆🏿‍♀️"}]},{"annotation":"person getting haircut","group":1,"hexcode":"1F487","order":1805,"tags":["barber","beauty","haircut","parlor"],"unicode":"💇","skins":[{"annotation":"person getting haircut: light skin tone","group":1,"hexcode":"1F487-1F3FB","order":1806,"unicode":"💇🏻"},{"annotation":"person getting haircut: medium-light skin tone","group":1,"hexcode":"1F487-1F3FC","order":1807,"unicode":"💇🏼"},{"annotation":"person getting haircut: medium skin tone","group":1,"hexcode":"1F487-1F3FD","order":1808,"unicode":"💇🏽"},{"annotation":"person getting haircut: medium-dark skin tone","group":1,"hexcode":"1F487-1F3FE","order":1809,"unicode":"💇🏾"},{"annotation":"person getting haircut: dark skin tone","group":1,"hexcode":"1F487-1F3FF","order":1810,"unicode":"💇🏿"}]},{"annotation":"man getting haircut","group":1,"hexcode":"1F487-200D-2642-FE0F","order":1811,"tags":["haircut","man"],"unicode":"💇‍♂️","skins":[{"annotation":"man getting haircut: light skin tone","group":1,"hexcode":"1F487-1F3FB-200D-2642-FE0F","order":1813,"unicode":"💇🏻‍♂️"},{"annotation":"man getting haircut: medium-light skin tone","group":1,"hexcode":"1F487-1F3FC-200D-2642-FE0F","order":1815,"unicode":"💇🏼‍♂️"},{"annotation":"man getting haircut: medium skin tone","group":1,"hexcode":"1F487-1F3FD-200D-2642-FE0F","order":1817,"unicode":"💇🏽‍♂️"},{"annotation":"man getting haircut: medium-dark skin tone","group":1,"hexcode":"1F487-1F3FE-200D-2642-FE0F","order":1819,"unicode":"💇🏾‍♂️"},{"annotation":"man getting haircut: dark skin tone","group":1,"hexcode":"1F487-1F3FF-200D-2642-FE0F","order":1821,"unicode":"💇🏿‍♂️"}]},{"annotation":"woman getting haircut","group":1,"hexcode":"1F487-200D-2640-FE0F","order":1823,"tags":["haircut","woman"],"unicode":"💇‍♀️","skins":[{"annotation":"woman getting haircut: light skin tone","group":1,"hexcode":"1F487-1F3FB-200D-2640-FE0F","order":1825,"unicode":"💇🏻‍♀️"},{"annotation":"woman getting haircut: medium-light skin tone","group":1,"hexcode":"1F487-1F3FC-200D-2640-FE0F","order":1827,"unicode":"💇🏼‍♀️"},{"annotation":"woman getting haircut: medium skin tone","group":1,"hexcode":"1F487-1F3FD-200D-2640-FE0F","order":1829,"unicode":"💇🏽‍♀️"},{"annotation":"woman getting haircut: medium-dark skin tone","group":1,"hexcode":"1F487-1F3FE-200D-2640-FE0F","order":1831,"unicode":"💇🏾‍♀️"},{"annotation":"woman getting haircut: dark skin tone","group":1,"hexcode":"1F487-1F3FF-200D-2640-FE0F","order":1833,"unicode":"💇🏿‍♀️"}]},{"annotation":"person walking","group":1,"hexcode":"1F6B6","order":1835,"tags":["hike","walk","walking"],"unicode":"🚶","skins":[{"annotation":"person walking: light skin tone","group":1,"hexcode":"1F6B6-1F3FB","order":1836,"unicode":"🚶🏻"},{"annotation":"person walking: medium-light skin tone","group":1,"hexcode":"1F6B6-1F3FC","order":1837,"unicode":"🚶🏼"},{"annotation":"person walking: medium skin tone","group":1,"hexcode":"1F6B6-1F3FD","order":1838,"unicode":"🚶🏽"},{"annotation":"person walking: medium-dark skin tone","group":1,"hexcode":"1F6B6-1F3FE","order":1839,"unicode":"🚶🏾"},{"annotation":"person walking: dark skin tone","group":1,"hexcode":"1F6B6-1F3FF","order":1840,"unicode":"🚶🏿"}]},{"annotation":"man walking","group":1,"hexcode":"1F6B6-200D-2642-FE0F","order":1841,"tags":["hike","man","walk"],"unicode":"🚶‍♂️","skins":[{"annotation":"man walking: light skin tone","group":1,"hexcode":"1F6B6-1F3FB-200D-2642-FE0F","order":1843,"unicode":"🚶🏻‍♂️"},{"annotation":"man walking: medium-light skin tone","group":1,"hexcode":"1F6B6-1F3FC-200D-2642-FE0F","order":1845,"unicode":"🚶🏼‍♂️"},{"annotation":"man walking: medium skin tone","group":1,"hexcode":"1F6B6-1F3FD-200D-2642-FE0F","order":1847,"unicode":"🚶🏽‍♂️"},{"annotation":"man walking: medium-dark skin tone","group":1,"hexcode":"1F6B6-1F3FE-200D-2642-FE0F","order":1849,"unicode":"🚶🏾‍♂️"},{"annotation":"man walking: dark skin tone","group":1,"hexcode":"1F6B6-1F3FF-200D-2642-FE0F","order":1851,"unicode":"🚶🏿‍♂️"}]},{"annotation":"woman walking","group":1,"hexcode":"1F6B6-200D-2640-FE0F","order":1853,"tags":["hike","walk","woman"],"unicode":"🚶‍♀️","skins":[{"annotation":"woman walking: light skin tone","group":1,"hexcode":"1F6B6-1F3FB-200D-2640-FE0F","order":1855,"unicode":"🚶🏻‍♀️"},{"annotation":"woman walking: medium-light skin tone","group":1,"hexcode":"1F6B6-1F3FC-200D-2640-FE0F","order":1857,"unicode":"🚶🏼‍♀️"},{"annotation":"woman walking: medium skin tone","group":1,"hexcode":"1F6B6-1F3FD-200D-2640-FE0F","order":1859,"unicode":"🚶🏽‍♀️"},{"annotation":"woman walking: medium-dark skin tone","group":1,"hexcode":"1F6B6-1F3FE-200D-2640-FE0F","order":1861,"unicode":"🚶🏾‍♀️"},{"annotation":"woman walking: dark skin tone","group":1,"hexcode":"1F6B6-1F3FF-200D-2640-FE0F","order":1863,"unicode":"🚶🏿‍♀️"}]},{"annotation":"person standing","group":1,"hexcode":"1F9CD","order":1865,"tags":["stand","standing"],"unicode":"🧍","skins":[{"annotation":"person standing: light skin tone","group":1,"hexcode":"1F9CD-1F3FB","order":1866,"unicode":"🧍🏻"},{"annotation":"person standing: medium-light skin tone","group":1,"hexcode":"1F9CD-1F3FC","order":1867,"unicode":"🧍🏼"},{"annotation":"person standing: medium skin tone","group":1,"hexcode":"1F9CD-1F3FD","order":1868,"unicode":"🧍🏽"},{"annotation":"person standing: medium-dark skin tone","group":1,"hexcode":"1F9CD-1F3FE","order":1869,"unicode":"🧍🏾"},{"annotation":"person standing: dark skin tone","group":1,"hexcode":"1F9CD-1F3FF","order":1870,"unicode":"🧍🏿"}]},{"annotation":"man standing","group":1,"hexcode":"1F9CD-200D-2642-FE0F","order":1871,"tags":["man","standing"],"unicode":"🧍‍♂️","skins":[{"annotation":"man standing: light skin tone","group":1,"hexcode":"1F9CD-1F3FB-200D-2642-FE0F","order":1873,"unicode":"🧍🏻‍♂️"},{"annotation":"man standing: medium-light skin tone","group":1,"hexcode":"1F9CD-1F3FC-200D-2642-FE0F","order":1875,"unicode":"🧍🏼‍♂️"},{"annotation":"man standing: medium skin tone","group":1,"hexcode":"1F9CD-1F3FD-200D-2642-FE0F","order":1877,"unicode":"🧍🏽‍♂️"},{"annotation":"man standing: medium-dark skin tone","group":1,"hexcode":"1F9CD-1F3FE-200D-2642-FE0F","order":1879,"unicode":"🧍🏾‍♂️"},{"annotation":"man standing: dark skin tone","group":1,"hexcode":"1F9CD-1F3FF-200D-2642-FE0F","order":1881,"unicode":"🧍🏿‍♂️"}]},{"annotation":"woman standing","group":1,"hexcode":"1F9CD-200D-2640-FE0F","order":1883,"tags":["standing","woman"],"unicode":"🧍‍♀️","skins":[{"annotation":"woman standing: light skin tone","group":1,"hexcode":"1F9CD-1F3FB-200D-2640-FE0F","order":1885,"unicode":"🧍🏻‍♀️"},{"annotation":"woman standing: medium-light skin tone","group":1,"hexcode":"1F9CD-1F3FC-200D-2640-FE0F","order":1887,"unicode":"🧍🏼‍♀️"},{"annotation":"woman standing: medium skin tone","group":1,"hexcode":"1F9CD-1F3FD-200D-2640-FE0F","order":1889,"unicode":"🧍🏽‍♀️"},{"annotation":"woman standing: medium-dark skin tone","group":1,"hexcode":"1F9CD-1F3FE-200D-2640-FE0F","order":1891,"unicode":"🧍🏾‍♀️"},{"annotation":"woman standing: dark skin tone","group":1,"hexcode":"1F9CD-1F3FF-200D-2640-FE0F","order":1893,"unicode":"🧍🏿‍♀️"}]},{"annotation":"person kneeling","group":1,"hexcode":"1F9CE","order":1895,"tags":["kneel","kneeling"],"unicode":"🧎","skins":[{"annotation":"person kneeling: light skin tone","group":1,"hexcode":"1F9CE-1F3FB","order":1896,"unicode":"🧎🏻"},{"annotation":"person kneeling: medium-light skin tone","group":1,"hexcode":"1F9CE-1F3FC","order":1897,"unicode":"🧎🏼"},{"annotation":"person kneeling: medium skin tone","group":1,"hexcode":"1F9CE-1F3FD","order":1898,"unicode":"🧎🏽"},{"annotation":"person kneeling: medium-dark skin tone","group":1,"hexcode":"1F9CE-1F3FE","order":1899,"unicode":"🧎🏾"},{"annotation":"person kneeling: dark skin tone","group":1,"hexcode":"1F9CE-1F3FF","order":1900,"unicode":"🧎🏿"}]},{"annotation":"man kneeling","group":1,"hexcode":"1F9CE-200D-2642-FE0F","order":1901,"tags":["kneeling","man"],"unicode":"🧎‍♂️","skins":[{"annotation":"man kneeling: light skin tone","group":1,"hexcode":"1F9CE-1F3FB-200D-2642-FE0F","order":1903,"unicode":"🧎🏻‍♂️"},{"annotation":"man kneeling: medium-light skin tone","group":1,"hexcode":"1F9CE-1F3FC-200D-2642-FE0F","order":1905,"unicode":"🧎🏼‍♂️"},{"annotation":"man kneeling: medium skin tone","group":1,"hexcode":"1F9CE-1F3FD-200D-2642-FE0F","order":1907,"unicode":"🧎🏽‍♂️"},{"annotation":"man kneeling: medium-dark skin tone","group":1,"hexcode":"1F9CE-1F3FE-200D-2642-FE0F","order":1909,"unicode":"🧎🏾‍♂️"},{"annotation":"man kneeling: dark skin tone","group":1,"hexcode":"1F9CE-1F3FF-200D-2642-FE0F","order":1911,"unicode":"🧎🏿‍♂️"}]},{"annotation":"woman kneeling","group":1,"hexcode":"1F9CE-200D-2640-FE0F","order":1913,"tags":["kneeling","woman"],"unicode":"🧎‍♀️","skins":[{"annotation":"woman kneeling: light skin tone","group":1,"hexcode":"1F9CE-1F3FB-200D-2640-FE0F","order":1915,"unicode":"🧎🏻‍♀️"},{"annotation":"woman kneeling: medium-light skin tone","group":1,"hexcode":"1F9CE-1F3FC-200D-2640-FE0F","order":1917,"unicode":"🧎🏼‍♀️"},{"annotation":"woman kneeling: medium skin tone","group":1,"hexcode":"1F9CE-1F3FD-200D-2640-FE0F","order":1919,"unicode":"🧎🏽‍♀️"},{"annotation":"woman kneeling: medium-dark skin tone","group":1,"hexcode":"1F9CE-1F3FE-200D-2640-FE0F","order":1921,"unicode":"🧎🏾‍♀️"},{"annotation":"woman kneeling: dark skin tone","group":1,"hexcode":"1F9CE-1F3FF-200D-2640-FE0F","order":1923,"unicode":"🧎🏿‍♀️"}]},{"annotation":"person with white cane","group":1,"hexcode":"1F9D1-200D-1F9AF","order":1925,"tags":["accessibility","blind"],"unicode":"🧑‍🦯","skins":[{"annotation":"person with white cane: light skin tone","group":1,"hexcode":"1F9D1-1F3FB-200D-1F9AF","order":1926,"unicode":"🧑🏻‍🦯"},{"annotation":"person with white cane: medium-light skin tone","group":1,"hexcode":"1F9D1-1F3FC-200D-1F9AF","order":1927,"unicode":"🧑🏼‍🦯"},{"annotation":"person with white cane: medium skin tone","group":1,"hexcode":"1F9D1-1F3FD-200D-1F9AF","order":1928,"unicode":"🧑🏽‍🦯"},{"annotation":"person with white cane: medium-dark skin tone","group":1,"hexcode":"1F9D1-1F3FE-200D-1F9AF","order":1929,"unicode":"🧑🏾‍🦯"},{"annotation":"person with white cane: dark skin tone","group":1,"hexcode":"1F9D1-1F3FF-200D-1F9AF","order":1930,"unicode":"🧑🏿‍🦯"}]},{"annotation":"man with white cane","group":1,"hexcode":"1F468-200D-1F9AF","order":1931,"tags":["accessibility","blind","man"],"unicode":"👨‍🦯","skins":[{"annotation":"man with white cane: light skin tone","group":1,"hexcode":"1F468-1F3FB-200D-1F9AF","order":1932,"unicode":"👨🏻‍🦯"},{"annotation":"man with white cane: medium-light skin tone","group":1,"hexcode":"1F468-1F3FC-200D-1F9AF","order":1933,"unicode":"👨🏼‍🦯"},{"annotation":"man with white cane: medium skin tone","group":1,"hexcode":"1F468-1F3FD-200D-1F9AF","order":1934,"unicode":"👨🏽‍🦯"},{"annotation":"man with white cane: medium-dark skin tone","group":1,"hexcode":"1F468-1F3FE-200D-1F9AF","order":1935,"unicode":"👨🏾‍🦯"},{"annotation":"man with white cane: dark skin tone","group":1,"hexcode":"1F468-1F3FF-200D-1F9AF","order":1936,"unicode":"👨🏿‍🦯"}]},{"annotation":"woman with white cane","group":1,"hexcode":"1F469-200D-1F9AF","order":1937,"tags":["accessibility","blind","woman"],"unicode":"👩‍🦯","skins":[{"annotation":"woman with white cane: light skin tone","group":1,"hexcode":"1F469-1F3FB-200D-1F9AF","order":1938,"unicode":"👩🏻‍🦯"},{"annotation":"woman with white cane: medium-light skin tone","group":1,"hexcode":"1F469-1F3FC-200D-1F9AF","order":1939,"unicode":"👩🏼‍🦯"},{"annotation":"woman with white cane: medium skin tone","group":1,"hexcode":"1F469-1F3FD-200D-1F9AF","order":1940,"unicode":"👩🏽‍🦯"},{"annotation":"woman with white cane: medium-dark skin tone","group":1,"hexcode":"1F469-1F3FE-200D-1F9AF","order":1941,"unicode":"👩🏾‍🦯"},{"annotation":"woman with white cane: dark skin tone","group":1,"hexcode":"1F469-1F3FF-200D-1F9AF","order":1942,"unicode":"👩🏿‍🦯"}]},{"annotation":"person in motorized wheelchair","group":1,"hexcode":"1F9D1-200D-1F9BC","order":1943,"tags":["accessibility","wheelchair"],"unicode":"🧑‍🦼","skins":[{"annotation":"person in motorized wheelchair: light skin tone","group":1,"hexcode":"1F9D1-1F3FB-200D-1F9BC","order":1944,"unicode":"🧑🏻‍🦼"},{"annotation":"person in motorized wheelchair: medium-light skin tone","group":1,"hexcode":"1F9D1-1F3FC-200D-1F9BC","order":1945,"unicode":"🧑🏼‍🦼"},{"annotation":"person in motorized wheelchair: medium skin tone","group":1,"hexcode":"1F9D1-1F3FD-200D-1F9BC","order":1946,"unicode":"🧑🏽‍🦼"},{"annotation":"person in motorized wheelchair: medium-dark skin tone","group":1,"hexcode":"1F9D1-1F3FE-200D-1F9BC","order":1947,"unicode":"🧑🏾‍🦼"},{"annotation":"person in motorized wheelchair: dark skin tone","group":1,"hexcode":"1F9D1-1F3FF-200D-1F9BC","order":1948,"unicode":"🧑🏿‍🦼"}]},{"annotation":"man in motorized wheelchair","group":1,"hexcode":"1F468-200D-1F9BC","order":1949,"tags":["accessibility","man","wheelchair"],"unicode":"👨‍🦼","skins":[{"annotation":"man in motorized wheelchair: light skin tone","group":1,"hexcode":"1F468-1F3FB-200D-1F9BC","order":1950,"unicode":"👨🏻‍🦼"},{"annotation":"man in motorized wheelchair: medium-light skin tone","group":1,"hexcode":"1F468-1F3FC-200D-1F9BC","order":1951,"unicode":"👨🏼‍🦼"},{"annotation":"man in motorized wheelchair: medium skin tone","group":1,"hexcode":"1F468-1F3FD-200D-1F9BC","order":1952,"unicode":"👨🏽‍🦼"},{"annotation":"man in motorized wheelchair: medium-dark skin tone","group":1,"hexcode":"1F468-1F3FE-200D-1F9BC","order":1953,"unicode":"👨🏾‍🦼"},{"annotation":"man in motorized wheelchair: dark skin tone","group":1,"hexcode":"1F468-1F3FF-200D-1F9BC","order":1954,"unicode":"👨🏿‍🦼"}]},{"annotation":"woman in motorized wheelchair","group":1,"hexcode":"1F469-200D-1F9BC","order":1955,"tags":["accessibility","wheelchair","woman"],"unicode":"👩‍🦼","skins":[{"annotation":"woman in motorized wheelchair: light skin tone","group":1,"hexcode":"1F469-1F3FB-200D-1F9BC","order":1956,"unicode":"👩🏻‍🦼"},{"annotation":"woman in motorized wheelchair: medium-light skin tone","group":1,"hexcode":"1F469-1F3FC-200D-1F9BC","order":1957,"unicode":"👩🏼‍🦼"},{"annotation":"woman in motorized wheelchair: medium skin tone","group":1,"hexcode":"1F469-1F3FD-200D-1F9BC","order":1958,"unicode":"👩🏽‍🦼"},{"annotation":"woman in motorized wheelchair: medium-dark skin tone","group":1,"hexcode":"1F469-1F3FE-200D-1F9BC","order":1959,"unicode":"👩🏾‍🦼"},{"annotation":"woman in motorized wheelchair: dark skin tone","group":1,"hexcode":"1F469-1F3FF-200D-1F9BC","order":1960,"unicode":"👩🏿‍🦼"}]},{"annotation":"person in manual wheelchair","group":1,"hexcode":"1F9D1-200D-1F9BD","order":1961,"tags":["accessibility","wheelchair"],"unicode":"🧑‍🦽","skins":[{"annotation":"person in manual wheelchair: light skin tone","group":1,"hexcode":"1F9D1-1F3FB-200D-1F9BD","order":1962,"unicode":"🧑🏻‍🦽"},{"annotation":"person in manual wheelchair: medium-light skin tone","group":1,"hexcode":"1F9D1-1F3FC-200D-1F9BD","order":1963,"unicode":"🧑🏼‍🦽"},{"annotation":"person in manual wheelchair: medium skin tone","group":1,"hexcode":"1F9D1-1F3FD-200D-1F9BD","order":1964,"unicode":"🧑🏽‍🦽"},{"annotation":"person in manual wheelchair: medium-dark skin tone","group":1,"hexcode":"1F9D1-1F3FE-200D-1F9BD","order":1965,"unicode":"🧑🏾‍🦽"},{"annotation":"person in manual wheelchair: dark skin tone","group":1,"hexcode":"1F9D1-1F3FF-200D-1F9BD","order":1966,"unicode":"🧑🏿‍🦽"}]},{"annotation":"man in manual wheelchair","group":1,"hexcode":"1F468-200D-1F9BD","order":1967,"tags":["accessibility","man","wheelchair"],"unicode":"👨‍🦽","skins":[{"annotation":"man in manual wheelchair: light skin tone","group":1,"hexcode":"1F468-1F3FB-200D-1F9BD","order":1968,"unicode":"👨🏻‍🦽"},{"annotation":"man in manual wheelchair: medium-light skin tone","group":1,"hexcode":"1F468-1F3FC-200D-1F9BD","order":1969,"unicode":"👨🏼‍🦽"},{"annotation":"man in manual wheelchair: medium skin tone","group":1,"hexcode":"1F468-1F3FD-200D-1F9BD","order":1970,"unicode":"👨🏽‍🦽"},{"annotation":"man in manual wheelchair: medium-dark skin tone","group":1,"hexcode":"1F468-1F3FE-200D-1F9BD","order":1971,"unicode":"👨🏾‍🦽"},{"annotation":"man in manual wheelchair: dark skin tone","group":1,"hexcode":"1F468-1F3FF-200D-1F9BD","order":1972,"unicode":"👨🏿‍🦽"}]},{"annotation":"woman in manual wheelchair","group":1,"hexcode":"1F469-200D-1F9BD","order":1973,"tags":["accessibility","wheelchair","woman"],"unicode":"👩‍🦽","skins":[{"annotation":"woman in manual wheelchair: light skin tone","group":1,"hexcode":"1F469-1F3FB-200D-1F9BD","order":1974,"unicode":"👩🏻‍🦽"},{"annotation":"woman in manual wheelchair: medium-light skin tone","group":1,"hexcode":"1F469-1F3FC-200D-1F9BD","order":1975,"unicode":"👩🏼‍🦽"},{"annotation":"woman in manual wheelchair: medium skin tone","group":1,"hexcode":"1F469-1F3FD-200D-1F9BD","order":1976,"unicode":"👩🏽‍🦽"},{"annotation":"woman in manual wheelchair: medium-dark skin tone","group":1,"hexcode":"1F469-1F3FE-200D-1F9BD","order":1977,"unicode":"👩🏾‍🦽"},{"annotation":"woman in manual wheelchair: dark skin tone","group":1,"hexcode":"1F469-1F3FF-200D-1F9BD","order":1978,"unicode":"👩🏿‍🦽"}]},{"annotation":"person running","group":1,"hexcode":"1F3C3","order":1979,"tags":["marathon","running"],"unicode":"🏃","skins":[{"annotation":"person running: light skin tone","group":1,"hexcode":"1F3C3-1F3FB","order":1980,"unicode":"🏃🏻"},{"annotation":"person running: medium-light skin tone","group":1,"hexcode":"1F3C3-1F3FC","order":1981,"unicode":"🏃🏼"},{"annotation":"person running: medium skin tone","group":1,"hexcode":"1F3C3-1F3FD","order":1982,"unicode":"🏃🏽"},{"annotation":"person running: medium-dark skin tone","group":1,"hexcode":"1F3C3-1F3FE","order":1983,"unicode":"🏃🏾"},{"annotation":"person running: dark skin tone","group":1,"hexcode":"1F3C3-1F3FF","order":1984,"unicode":"🏃🏿"}]},{"annotation":"man running","group":1,"hexcode":"1F3C3-200D-2642-FE0F","order":1985,"tags":["man","marathon","racing","running"],"unicode":"🏃‍♂️","skins":[{"annotation":"man running: light skin tone","group":1,"hexcode":"1F3C3-1F3FB-200D-2642-FE0F","order":1987,"unicode":"🏃🏻‍♂️"},{"annotation":"man running: medium-light skin tone","group":1,"hexcode":"1F3C3-1F3FC-200D-2642-FE0F","order":1989,"unicode":"🏃🏼‍♂️"},{"annotation":"man running: medium skin tone","group":1,"hexcode":"1F3C3-1F3FD-200D-2642-FE0F","order":1991,"unicode":"🏃🏽‍♂️"},{"annotation":"man running: medium-dark skin tone","group":1,"hexcode":"1F3C3-1F3FE-200D-2642-FE0F","order":1993,"unicode":"🏃🏾‍♂️"},{"annotation":"man running: dark skin tone","group":1,"hexcode":"1F3C3-1F3FF-200D-2642-FE0F","order":1995,"unicode":"🏃🏿‍♂️"}]},{"annotation":"woman running","group":1,"hexcode":"1F3C3-200D-2640-FE0F","order":1997,"tags":["marathon","racing","running","woman"],"unicode":"🏃‍♀️","skins":[{"annotation":"woman running: light skin tone","group":1,"hexcode":"1F3C3-1F3FB-200D-2640-FE0F","order":1999,"unicode":"🏃🏻‍♀️"},{"annotation":"woman running: medium-light skin tone","group":1,"hexcode":"1F3C3-1F3FC-200D-2640-FE0F","order":2001,"unicode":"🏃🏼‍♀️"},{"annotation":"woman running: medium skin tone","group":1,"hexcode":"1F3C3-1F3FD-200D-2640-FE0F","order":2003,"unicode":"🏃🏽‍♀️"},{"annotation":"woman running: medium-dark skin tone","group":1,"hexcode":"1F3C3-1F3FE-200D-2640-FE0F","order":2005,"unicode":"🏃🏾‍♀️"},{"annotation":"woman running: dark skin tone","group":1,"hexcode":"1F3C3-1F3FF-200D-2640-FE0F","order":2007,"unicode":"🏃🏿‍♀️"}]},{"annotation":"woman dancing","group":1,"hexcode":"1F483","order":2009,"tags":["dance","dancing","woman"],"unicode":"💃","skins":[{"annotation":"woman dancing: light skin tone","group":1,"hexcode":"1F483-1F3FB","order":2010,"unicode":"💃🏻"},{"annotation":"woman dancing: medium-light skin tone","group":1,"hexcode":"1F483-1F3FC","order":2011,"unicode":"💃🏼"},{"annotation":"woman dancing: medium skin tone","group":1,"hexcode":"1F483-1F3FD","order":2012,"unicode":"💃🏽"},{"annotation":"woman dancing: medium-dark skin tone","group":1,"hexcode":"1F483-1F3FE","order":2013,"unicode":"💃🏾"},{"annotation":"woman dancing: dark skin tone","group":1,"hexcode":"1F483-1F3FF","order":2014,"unicode":"💃🏿"}]},{"annotation":"man dancing","group":1,"hexcode":"1F57A","order":2015,"tags":["dance","dancing","man"],"unicode":"🕺","skins":[{"annotation":"man dancing: light skin tone","group":1,"hexcode":"1F57A-1F3FB","order":2016,"unicode":"🕺🏻"},{"annotation":"man dancing: medium-light skin tone","group":1,"hexcode":"1F57A-1F3FC","order":2017,"unicode":"🕺🏼"},{"annotation":"man dancing: medium skin tone","group":1,"hexcode":"1F57A-1F3FD","order":2018,"unicode":"🕺🏽"},{"annotation":"man dancing: medium-dark skin tone","group":1,"hexcode":"1F57A-1F3FE","order":2019,"unicode":"🕺🏾"},{"annotation":"man dancing: dark skin tone","group":1,"hexcode":"1F57A-1F3FF","order":2020,"unicode":"🕺🏿"}]},{"annotation":"person in suit levitating","group":1,"hexcode":"1F574","order":2022,"tags":["business","person","suit"],"unicode":"🕴️","skins":[{"annotation":"person in suit levitating: light skin tone","group":1,"hexcode":"1F574-1F3FB","order":2023,"unicode":"🕴🏻"},{"annotation":"person in suit levitating: medium-light skin tone","group":1,"hexcode":"1F574-1F3FC","order":2024,"unicode":"🕴🏼"},{"annotation":"person in suit levitating: medium skin tone","group":1,"hexcode":"1F574-1F3FD","order":2025,"unicode":"🕴🏽"},{"annotation":"person in suit levitating: medium-dark skin tone","group":1,"hexcode":"1F574-1F3FE","order":2026,"unicode":"🕴🏾"},{"annotation":"person in suit levitating: dark skin tone","group":1,"hexcode":"1F574-1F3FF","order":2027,"unicode":"🕴🏿"}]},{"annotation":"people with bunny ears","group":1,"hexcode":"1F46F","order":2028,"tags":["bunny ear","dancer","partying"],"unicode":"👯"},{"annotation":"men with bunny ears","group":1,"hexcode":"1F46F-200D-2642-FE0F","order":2029,"tags":["bunny ear","dancer","men","partying"],"unicode":"👯‍♂️"},{"annotation":"women with bunny ears","group":1,"hexcode":"1F46F-200D-2640-FE0F","order":2031,"tags":["bunny ear","dancer","partying","women"],"unicode":"👯‍♀️"},{"annotation":"person in steamy room","group":1,"hexcode":"1F9D6","order":2033,"tags":["sauna","steam room"],"unicode":"🧖","skins":[{"annotation":"person in steamy room: light skin tone","group":1,"hexcode":"1F9D6-1F3FB","order":2034,"unicode":"🧖🏻"},{"annotation":"person in steamy room: medium-light skin tone","group":1,"hexcode":"1F9D6-1F3FC","order":2035,"unicode":"🧖🏼"},{"annotation":"person in steamy room: medium skin tone","group":1,"hexcode":"1F9D6-1F3FD","order":2036,"unicode":"🧖🏽"},{"annotation":"person in steamy room: medium-dark skin tone","group":1,"hexcode":"1F9D6-1F3FE","order":2037,"unicode":"🧖🏾"},{"annotation":"person in steamy room: dark skin tone","group":1,"hexcode":"1F9D6-1F3FF","order":2038,"unicode":"🧖🏿"}]},{"annotation":"man in steamy room","group":1,"hexcode":"1F9D6-200D-2642-FE0F","order":2039,"tags":["sauna","steam room"],"unicode":"🧖‍♂️","skins":[{"annotation":"man in steamy room: light skin tone","group":1,"hexcode":"1F9D6-1F3FB-200D-2642-FE0F","order":2041,"unicode":"🧖🏻‍♂️"},{"annotation":"man in steamy room: medium-light skin tone","group":1,"hexcode":"1F9D6-1F3FC-200D-2642-FE0F","order":2043,"unicode":"🧖🏼‍♂️"},{"annotation":"man in steamy room: medium skin tone","group":1,"hexcode":"1F9D6-1F3FD-200D-2642-FE0F","order":2045,"unicode":"🧖🏽‍♂️"},{"annotation":"man in steamy room: medium-dark skin tone","group":1,"hexcode":"1F9D6-1F3FE-200D-2642-FE0F","order":2047,"unicode":"🧖🏾‍♂️"},{"annotation":"man in steamy room: dark skin tone","group":1,"hexcode":"1F9D6-1F3FF-200D-2642-FE0F","order":2049,"unicode":"🧖🏿‍♂️"}]},{"annotation":"woman in steamy room","group":1,"hexcode":"1F9D6-200D-2640-FE0F","order":2051,"tags":["sauna","steam room"],"unicode":"🧖‍♀️","skins":[{"annotation":"woman in steamy room: light skin tone","group":1,"hexcode":"1F9D6-1F3FB-200D-2640-FE0F","order":2053,"unicode":"🧖🏻‍♀️"},{"annotation":"woman in steamy room: medium-light skin tone","group":1,"hexcode":"1F9D6-1F3FC-200D-2640-FE0F","order":2055,"unicode":"🧖🏼‍♀️"},{"annotation":"woman in steamy room: medium skin tone","group":1,"hexcode":"1F9D6-1F3FD-200D-2640-FE0F","order":2057,"unicode":"🧖🏽‍♀️"},{"annotation":"woman in steamy room: medium-dark skin tone","group":1,"hexcode":"1F9D6-1F3FE-200D-2640-FE0F","order":2059,"unicode":"🧖🏾‍♀️"},{"annotation":"woman in steamy room: dark skin tone","group":1,"hexcode":"1F9D6-1F3FF-200D-2640-FE0F","order":2061,"unicode":"🧖🏿‍♀️"}]},{"annotation":"person climbing","group":1,"hexcode":"1F9D7","order":2063,"tags":["climber"],"unicode":"🧗","skins":[{"annotation":"person climbing: light skin tone","group":1,"hexcode":"1F9D7-1F3FB","order":2064,"unicode":"🧗🏻"},{"annotation":"person climbing: medium-light skin tone","group":1,"hexcode":"1F9D7-1F3FC","order":2065,"unicode":"🧗🏼"},{"annotation":"person climbing: medium skin tone","group":1,"hexcode":"1F9D7-1F3FD","order":2066,"unicode":"🧗🏽"},{"annotation":"person climbing: medium-dark skin tone","group":1,"hexcode":"1F9D7-1F3FE","order":2067,"unicode":"🧗🏾"},{"annotation":"person climbing: dark skin tone","group":1,"hexcode":"1F9D7-1F3FF","order":2068,"unicode":"🧗🏿"}]},{"annotation":"man climbing","group":1,"hexcode":"1F9D7-200D-2642-FE0F","order":2069,"tags":["climber"],"unicode":"🧗‍♂️","skins":[{"annotation":"man climbing: light skin tone","group":1,"hexcode":"1F9D7-1F3FB-200D-2642-FE0F","order":2071,"unicode":"🧗🏻‍♂️"},{"annotation":"man climbing: medium-light skin tone","group":1,"hexcode":"1F9D7-1F3FC-200D-2642-FE0F","order":2073,"unicode":"🧗🏼‍♂️"},{"annotation":"man climbing: medium skin tone","group":1,"hexcode":"1F9D7-1F3FD-200D-2642-FE0F","order":2075,"unicode":"🧗🏽‍♂️"},{"annotation":"man climbing: medium-dark skin tone","group":1,"hexcode":"1F9D7-1F3FE-200D-2642-FE0F","order":2077,"unicode":"🧗🏾‍♂️"},{"annotation":"man climbing: dark skin tone","group":1,"hexcode":"1F9D7-1F3FF-200D-2642-FE0F","order":2079,"unicode":"🧗🏿‍♂️"}]},{"annotation":"woman climbing","group":1,"hexcode":"1F9D7-200D-2640-FE0F","order":2081,"tags":["climber"],"unicode":"🧗‍♀️","skins":[{"annotation":"woman climbing: light skin tone","group":1,"hexcode":"1F9D7-1F3FB-200D-2640-FE0F","order":2083,"unicode":"🧗🏻‍♀️"},{"annotation":"woman climbing: medium-light skin tone","group":1,"hexcode":"1F9D7-1F3FC-200D-2640-FE0F","order":2085,"unicode":"🧗🏼‍♀️"},{"annotation":"woman climbing: medium skin tone","group":1,"hexcode":"1F9D7-1F3FD-200D-2640-FE0F","order":2087,"unicode":"🧗🏽‍♀️"},{"annotation":"woman climbing: medium-dark skin tone","group":1,"hexcode":"1F9D7-1F3FE-200D-2640-FE0F","order":2089,"unicode":"🧗🏾‍♀️"},{"annotation":"woman climbing: dark skin tone","group":1,"hexcode":"1F9D7-1F3FF-200D-2640-FE0F","order":2091,"unicode":"🧗🏿‍♀️"}]},{"annotation":"person fencing","group":1,"hexcode":"1F93A","order":2093,"tags":["fencer","fencing","sword"],"unicode":"🤺"},{"annotation":"horse racing","group":1,"hexcode":"1F3C7","order":2094,"tags":["horse","jockey","racehorse","racing"],"unicode":"🏇","skins":[{"annotation":"horse racing: light skin tone","group":1,"hexcode":"1F3C7-1F3FB","order":2095,"unicode":"🏇🏻"},{"annotation":"horse racing: medium-light skin tone","group":1,"hexcode":"1F3C7-1F3FC","order":2096,"unicode":"🏇🏼"},{"annotation":"horse racing: medium skin tone","group":1,"hexcode":"1F3C7-1F3FD","order":2097,"unicode":"🏇🏽"},{"annotation":"horse racing: medium-dark skin tone","group":1,"hexcode":"1F3C7-1F3FE","order":2098,"unicode":"🏇🏾"},{"annotation":"horse racing: dark skin tone","group":1,"hexcode":"1F3C7-1F3FF","order":2099,"unicode":"🏇🏿"}]},{"annotation":"skier","group":1,"hexcode":"26F7","order":2101,"tags":["ski","snow"],"unicode":"⛷️"},{"annotation":"snowboarder","group":1,"hexcode":"1F3C2","order":2102,"tags":["ski","snow","snowboard"],"unicode":"🏂️","skins":[{"annotation":"snowboarder: light skin tone","group":1,"hexcode":"1F3C2-1F3FB","order":2103,"unicode":"🏂🏻"},{"annotation":"snowboarder: medium-light skin tone","group":1,"hexcode":"1F3C2-1F3FC","order":2104,"unicode":"🏂🏼"},{"annotation":"snowboarder: medium skin tone","group":1,"hexcode":"1F3C2-1F3FD","order":2105,"unicode":"🏂🏽"},{"annotation":"snowboarder: medium-dark skin tone","group":1,"hexcode":"1F3C2-1F3FE","order":2106,"unicode":"🏂🏾"},{"annotation":"snowboarder: dark skin tone","group":1,"hexcode":"1F3C2-1F3FF","order":2107,"unicode":"🏂🏿"}]},{"annotation":"person golfing","group":1,"hexcode":"1F3CC","order":2109,"tags":["ball","golf"],"unicode":"🏌️","skins":[{"annotation":"person golfing: light skin tone","group":1,"hexcode":"1F3CC-1F3FB","order":2110,"unicode":"🏌🏻"},{"annotation":"person golfing: medium-light skin tone","group":1,"hexcode":"1F3CC-1F3FC","order":2111,"unicode":"🏌🏼"},{"annotation":"person golfing: medium skin tone","group":1,"hexcode":"1F3CC-1F3FD","order":2112,"unicode":"🏌🏽"},{"annotation":"person golfing: medium-dark skin tone","group":1,"hexcode":"1F3CC-1F3FE","order":2113,"unicode":"🏌🏾"},{"annotation":"person golfing: dark skin tone","group":1,"hexcode":"1F3CC-1F3FF","order":2114,"unicode":"🏌🏿"}]},{"annotation":"man golfing","group":1,"hexcode":"1F3CC-FE0F-200D-2642-FE0F","order":2115,"tags":["golf","man"],"unicode":"🏌️‍♂️","skins":[{"annotation":"man golfing: light skin tone","group":1,"hexcode":"1F3CC-1F3FB-200D-2642-FE0F","order":2119,"unicode":"🏌🏻‍♂️"},{"annotation":"man golfing: medium-light skin tone","group":1,"hexcode":"1F3CC-1F3FC-200D-2642-FE0F","order":2121,"unicode":"🏌🏼‍♂️"},{"annotation":"man golfing: medium skin tone","group":1,"hexcode":"1F3CC-1F3FD-200D-2642-FE0F","order":2123,"unicode":"🏌🏽‍♂️"},{"annotation":"man golfing: medium-dark skin tone","group":1,"hexcode":"1F3CC-1F3FE-200D-2642-FE0F","order":2125,"unicode":"🏌🏾‍♂️"},{"annotation":"man golfing: dark skin tone","group":1,"hexcode":"1F3CC-1F3FF-200D-2642-FE0F","order":2127,"unicode":"🏌🏿‍♂️"}]},{"annotation":"woman golfing","group":1,"hexcode":"1F3CC-FE0F-200D-2640-FE0F","order":2129,"tags":["golf","woman"],"unicode":"🏌️‍♀️","skins":[{"annotation":"woman golfing: light skin tone","group":1,"hexcode":"1F3CC-1F3FB-200D-2640-FE0F","order":2133,"unicode":"🏌🏻‍♀️"},{"annotation":"woman golfing: medium-light skin tone","group":1,"hexcode":"1F3CC-1F3FC-200D-2640-FE0F","order":2135,"unicode":"🏌🏼‍♀️"},{"annotation":"woman golfing: medium skin tone","group":1,"hexcode":"1F3CC-1F3FD-200D-2640-FE0F","order":2137,"unicode":"🏌🏽‍♀️"},{"annotation":"woman golfing: medium-dark skin tone","group":1,"hexcode":"1F3CC-1F3FE-200D-2640-FE0F","order":2139,"unicode":"🏌🏾‍♀️"},{"annotation":"woman golfing: dark skin tone","group":1,"hexcode":"1F3CC-1F3FF-200D-2640-FE0F","order":2141,"unicode":"🏌🏿‍♀️"}]},{"annotation":"person surfing","group":1,"hexcode":"1F3C4","order":2143,"tags":["surfing"],"unicode":"🏄️","skins":[{"annotation":"person surfing: light skin tone","group":1,"hexcode":"1F3C4-1F3FB","order":2144,"unicode":"🏄🏻"},{"annotation":"person surfing: medium-light skin tone","group":1,"hexcode":"1F3C4-1F3FC","order":2145,"unicode":"🏄🏼"},{"annotation":"person surfing: medium skin tone","group":1,"hexcode":"1F3C4-1F3FD","order":2146,"unicode":"🏄🏽"},{"annotation":"person surfing: medium-dark skin tone","group":1,"hexcode":"1F3C4-1F3FE","order":2147,"unicode":"🏄🏾"},{"annotation":"person surfing: dark skin tone","group":1,"hexcode":"1F3C4-1F3FF","order":2148,"unicode":"🏄🏿"}]},{"annotation":"man surfing","group":1,"hexcode":"1F3C4-200D-2642-FE0F","order":2149,"tags":["man","surfing"],"unicode":"🏄‍♂️","skins":[{"annotation":"man surfing: light skin tone","group":1,"hexcode":"1F3C4-1F3FB-200D-2642-FE0F","order":2151,"unicode":"🏄🏻‍♂️"},{"annotation":"man surfing: medium-light skin tone","group":1,"hexcode":"1F3C4-1F3FC-200D-2642-FE0F","order":2153,"unicode":"🏄🏼‍♂️"},{"annotation":"man surfing: medium skin tone","group":1,"hexcode":"1F3C4-1F3FD-200D-2642-FE0F","order":2155,"unicode":"🏄🏽‍♂️"},{"annotation":"man surfing: medium-dark skin tone","group":1,"hexcode":"1F3C4-1F3FE-200D-2642-FE0F","order":2157,"unicode":"🏄🏾‍♂️"},{"annotation":"man surfing: dark skin tone","group":1,"hexcode":"1F3C4-1F3FF-200D-2642-FE0F","order":2159,"unicode":"🏄🏿‍♂️"}]},{"annotation":"woman surfing","group":1,"hexcode":"1F3C4-200D-2640-FE0F","order":2161,"tags":["surfing","woman"],"unicode":"🏄‍♀️","skins":[{"annotation":"woman surfing: light skin tone","group":1,"hexcode":"1F3C4-1F3FB-200D-2640-FE0F","order":2163,"unicode":"🏄🏻‍♀️"},{"annotation":"woman surfing: medium-light skin tone","group":1,"hexcode":"1F3C4-1F3FC-200D-2640-FE0F","order":2165,"unicode":"🏄🏼‍♀️"},{"annotation":"woman surfing: medium skin tone","group":1,"hexcode":"1F3C4-1F3FD-200D-2640-FE0F","order":2167,"unicode":"🏄🏽‍♀️"},{"annotation":"woman surfing: medium-dark skin tone","group":1,"hexcode":"1F3C4-1F3FE-200D-2640-FE0F","order":2169,"unicode":"🏄🏾‍♀️"},{"annotation":"woman surfing: dark skin tone","group":1,"hexcode":"1F3C4-1F3FF-200D-2640-FE0F","order":2171,"unicode":"🏄🏿‍♀️"}]},{"annotation":"person rowing boat","group":1,"hexcode":"1F6A3","order":2173,"tags":["boat","rowboat"],"unicode":"🚣","skins":[{"annotation":"person rowing boat: light skin tone","group":1,"hexcode":"1F6A3-1F3FB","order":2174,"unicode":"🚣🏻"},{"annotation":"person rowing boat: medium-light skin tone","group":1,"hexcode":"1F6A3-1F3FC","order":2175,"unicode":"🚣🏼"},{"annotation":"person rowing boat: medium skin tone","group":1,"hexcode":"1F6A3-1F3FD","order":2176,"unicode":"🚣🏽"},{"annotation":"person rowing boat: medium-dark skin tone","group":1,"hexcode":"1F6A3-1F3FE","order":2177,"unicode":"🚣🏾"},{"annotation":"person rowing boat: dark skin tone","group":1,"hexcode":"1F6A3-1F3FF","order":2178,"unicode":"🚣🏿"}]},{"annotation":"man rowing boat","group":1,"hexcode":"1F6A3-200D-2642-FE0F","order":2179,"tags":["boat","man","rowboat"],"unicode":"🚣‍♂️","skins":[{"annotation":"man rowing boat: light skin tone","group":1,"hexcode":"1F6A3-1F3FB-200D-2642-FE0F","order":2181,"unicode":"🚣🏻‍♂️"},{"annotation":"man rowing boat: medium-light skin tone","group":1,"hexcode":"1F6A3-1F3FC-200D-2642-FE0F","order":2183,"unicode":"🚣🏼‍♂️"},{"annotation":"man rowing boat: medium skin tone","group":1,"hexcode":"1F6A3-1F3FD-200D-2642-FE0F","order":2185,"unicode":"🚣🏽‍♂️"},{"annotation":"man rowing boat: medium-dark skin tone","group":1,"hexcode":"1F6A3-1F3FE-200D-2642-FE0F","order":2187,"unicode":"🚣🏾‍♂️"},{"annotation":"man rowing boat: dark skin tone","group":1,"hexcode":"1F6A3-1F3FF-200D-2642-FE0F","order":2189,"unicode":"🚣🏿‍♂️"}]},{"annotation":"woman rowing boat","group":1,"hexcode":"1F6A3-200D-2640-FE0F","order":2191,"tags":["boat","rowboat","woman"],"unicode":"🚣‍♀️","skins":[{"annotation":"woman rowing boat: light skin tone","group":1,"hexcode":"1F6A3-1F3FB-200D-2640-FE0F","order":2193,"unicode":"🚣🏻‍♀️"},{"annotation":"woman rowing boat: medium-light skin tone","group":1,"hexcode":"1F6A3-1F3FC-200D-2640-FE0F","order":2195,"unicode":"🚣🏼‍♀️"},{"annotation":"woman rowing boat: medium skin tone","group":1,"hexcode":"1F6A3-1F3FD-200D-2640-FE0F","order":2197,"unicode":"🚣🏽‍♀️"},{"annotation":"woman rowing boat: medium-dark skin tone","group":1,"hexcode":"1F6A3-1F3FE-200D-2640-FE0F","order":2199,"unicode":"🚣🏾‍♀️"},{"annotation":"woman rowing boat: dark skin tone","group":1,"hexcode":"1F6A3-1F3FF-200D-2640-FE0F","order":2201,"unicode":"🚣🏿‍♀️"}]},{"annotation":"person swimming","group":1,"hexcode":"1F3CA","order":2203,"tags":["swim"],"unicode":"🏊️","skins":[{"annotation":"person swimming: light skin tone","group":1,"hexcode":"1F3CA-1F3FB","order":2204,"unicode":"🏊🏻"},{"annotation":"person swimming: medium-light skin tone","group":1,"hexcode":"1F3CA-1F3FC","order":2205,"unicode":"🏊🏼"},{"annotation":"person swimming: medium skin tone","group":1,"hexcode":"1F3CA-1F3FD","order":2206,"unicode":"🏊🏽"},{"annotation":"person swimming: medium-dark skin tone","group":1,"hexcode":"1F3CA-1F3FE","order":2207,"unicode":"🏊🏾"},{"annotation":"person swimming: dark skin tone","group":1,"hexcode":"1F3CA-1F3FF","order":2208,"unicode":"🏊🏿"}]},{"annotation":"man swimming","group":1,"hexcode":"1F3CA-200D-2642-FE0F","order":2209,"tags":["man","swim"],"unicode":"🏊‍♂️","skins":[{"annotation":"man swimming: light skin tone","group":1,"hexcode":"1F3CA-1F3FB-200D-2642-FE0F","order":2211,"unicode":"🏊🏻‍♂️"},{"annotation":"man swimming: medium-light skin tone","group":1,"hexcode":"1F3CA-1F3FC-200D-2642-FE0F","order":2213,"unicode":"🏊🏼‍♂️"},{"annotation":"man swimming: medium skin tone","group":1,"hexcode":"1F3CA-1F3FD-200D-2642-FE0F","order":2215,"unicode":"🏊🏽‍♂️"},{"annotation":"man swimming: medium-dark skin tone","group":1,"hexcode":"1F3CA-1F3FE-200D-2642-FE0F","order":2217,"unicode":"🏊🏾‍♂️"},{"annotation":"man swimming: dark skin tone","group":1,"hexcode":"1F3CA-1F3FF-200D-2642-FE0F","order":2219,"unicode":"🏊🏿‍♂️"}]},{"annotation":"woman swimming","group":1,"hexcode":"1F3CA-200D-2640-FE0F","order":2221,"tags":["swim","woman"],"unicode":"🏊‍♀️","skins":[{"annotation":"woman swimming: light skin tone","group":1,"hexcode":"1F3CA-1F3FB-200D-2640-FE0F","order":2223,"unicode":"🏊🏻‍♀️"},{"annotation":"woman swimming: medium-light skin tone","group":1,"hexcode":"1F3CA-1F3FC-200D-2640-FE0F","order":2225,"unicode":"🏊🏼‍♀️"},{"annotation":"woman swimming: medium skin tone","group":1,"hexcode":"1F3CA-1F3FD-200D-2640-FE0F","order":2227,"unicode":"🏊🏽‍♀️"},{"annotation":"woman swimming: medium-dark skin tone","group":1,"hexcode":"1F3CA-1F3FE-200D-2640-FE0F","order":2229,"unicode":"🏊🏾‍♀️"},{"annotation":"woman swimming: dark skin tone","group":1,"hexcode":"1F3CA-1F3FF-200D-2640-FE0F","order":2231,"unicode":"🏊🏿‍♀️"}]},{"annotation":"person bouncing ball","group":1,"hexcode":"26F9","order":2234,"tags":["ball"],"unicode":"⛹️","skins":[{"annotation":"person bouncing ball: light skin tone","group":1,"hexcode":"26F9-1F3FB","order":2235,"unicode":"⛹🏻"},{"annotation":"person bouncing ball: medium-light skin tone","group":1,"hexcode":"26F9-1F3FC","order":2236,"unicode":"⛹🏼"},{"annotation":"person bouncing ball: medium skin tone","group":1,"hexcode":"26F9-1F3FD","order":2237,"unicode":"⛹🏽"},{"annotation":"person bouncing ball: medium-dark skin tone","group":1,"hexcode":"26F9-1F3FE","order":2238,"unicode":"⛹🏾"},{"annotation":"person bouncing ball: dark skin tone","group":1,"hexcode":"26F9-1F3FF","order":2239,"unicode":"⛹🏿"}]},{"annotation":"man bouncing ball","group":1,"hexcode":"26F9-FE0F-200D-2642-FE0F","order":2240,"tags":["ball","man"],"unicode":"⛹️‍♂️","skins":[{"annotation":"man bouncing ball: light skin tone","group":1,"hexcode":"26F9-1F3FB-200D-2642-FE0F","order":2244,"unicode":"⛹🏻‍♂️"},{"annotation":"man bouncing ball: medium-light skin tone","group":1,"hexcode":"26F9-1F3FC-200D-2642-FE0F","order":2246,"unicode":"⛹🏼‍♂️"},{"annotation":"man bouncing ball: medium skin tone","group":1,"hexcode":"26F9-1F3FD-200D-2642-FE0F","order":2248,"unicode":"⛹🏽‍♂️"},{"annotation":"man bouncing ball: medium-dark skin tone","group":1,"hexcode":"26F9-1F3FE-200D-2642-FE0F","order":2250,"unicode":"⛹🏾‍♂️"},{"annotation":"man bouncing ball: dark skin tone","group":1,"hexcode":"26F9-1F3FF-200D-2642-FE0F","order":2252,"unicode":"⛹🏿‍♂️"}]},{"annotation":"woman bouncing ball","group":1,"hexcode":"26F9-FE0F-200D-2640-FE0F","order":2254,"tags":["ball","woman"],"unicode":"⛹️‍♀️","skins":[{"annotation":"woman bouncing ball: light skin tone","group":1,"hexcode":"26F9-1F3FB-200D-2640-FE0F","order":2258,"unicode":"⛹🏻‍♀️"},{"annotation":"woman bouncing ball: medium-light skin tone","group":1,"hexcode":"26F9-1F3FC-200D-2640-FE0F","order":2260,"unicode":"⛹🏼‍♀️"},{"annotation":"woman bouncing ball: medium skin tone","group":1,"hexcode":"26F9-1F3FD-200D-2640-FE0F","order":2262,"unicode":"⛹🏽‍♀️"},{"annotation":"woman bouncing ball: medium-dark skin tone","group":1,"hexcode":"26F9-1F3FE-200D-2640-FE0F","order":2264,"unicode":"⛹🏾‍♀️"},{"annotation":"woman bouncing ball: dark skin tone","group":1,"hexcode":"26F9-1F3FF-200D-2640-FE0F","order":2266,"unicode":"⛹🏿‍♀️"}]},{"annotation":"person lifting weights","group":1,"hexcode":"1F3CB","order":2269,"tags":["lifter","weight"],"unicode":"🏋️","skins":[{"annotation":"person lifting weights: light skin tone","group":1,"hexcode":"1F3CB-1F3FB","order":2270,"unicode":"🏋🏻"},{"annotation":"person lifting weights: medium-light skin tone","group":1,"hexcode":"1F3CB-1F3FC","order":2271,"unicode":"🏋🏼"},{"annotation":"person lifting weights: medium skin tone","group":1,"hexcode":"1F3CB-1F3FD","order":2272,"unicode":"🏋🏽"},{"annotation":"person lifting weights: medium-dark skin tone","group":1,"hexcode":"1F3CB-1F3FE","order":2273,"unicode":"🏋🏾"},{"annotation":"person lifting weights: dark skin tone","group":1,"hexcode":"1F3CB-1F3FF","order":2274,"unicode":"🏋🏿"}]},{"annotation":"man lifting weights","group":1,"hexcode":"1F3CB-FE0F-200D-2642-FE0F","order":2275,"tags":["man","weight lifter"],"unicode":"🏋️‍♂️","skins":[{"annotation":"man lifting weights: light skin tone","group":1,"hexcode":"1F3CB-1F3FB-200D-2642-FE0F","order":2279,"unicode":"🏋🏻‍♂️"},{"annotation":"man lifting weights: medium-light skin tone","group":1,"hexcode":"1F3CB-1F3FC-200D-2642-FE0F","order":2281,"unicode":"🏋🏼‍♂️"},{"annotation":"man lifting weights: medium skin tone","group":1,"hexcode":"1F3CB-1F3FD-200D-2642-FE0F","order":2283,"unicode":"🏋🏽‍♂️"},{"annotation":"man lifting weights: medium-dark skin tone","group":1,"hexcode":"1F3CB-1F3FE-200D-2642-FE0F","order":2285,"unicode":"🏋🏾‍♂️"},{"annotation":"man lifting weights: dark skin tone","group":1,"hexcode":"1F3CB-1F3FF-200D-2642-FE0F","order":2287,"unicode":"🏋🏿‍♂️"}]},{"annotation":"woman lifting weights","group":1,"hexcode":"1F3CB-FE0F-200D-2640-FE0F","order":2289,"tags":["weight lifter","woman"],"unicode":"🏋️‍♀️","skins":[{"annotation":"woman lifting weights: light skin tone","group":1,"hexcode":"1F3CB-1F3FB-200D-2640-FE0F","order":2293,"unicode":"🏋🏻‍♀️"},{"annotation":"woman lifting weights: medium-light skin tone","group":1,"hexcode":"1F3CB-1F3FC-200D-2640-FE0F","order":2295,"unicode":"🏋🏼‍♀️"},{"annotation":"woman lifting weights: medium skin tone","group":1,"hexcode":"1F3CB-1F3FD-200D-2640-FE0F","order":2297,"unicode":"🏋🏽‍♀️"},{"annotation":"woman lifting weights: medium-dark skin tone","group":1,"hexcode":"1F3CB-1F3FE-200D-2640-FE0F","order":2299,"unicode":"🏋🏾‍♀️"},{"annotation":"woman lifting weights: dark skin tone","group":1,"hexcode":"1F3CB-1F3FF-200D-2640-FE0F","order":2301,"unicode":"🏋🏿‍♀️"}]},{"annotation":"person biking","group":1,"hexcode":"1F6B4","order":2303,"tags":["bicycle","biking","cyclist"],"unicode":"🚴","skins":[{"annotation":"person biking: light skin tone","group":1,"hexcode":"1F6B4-1F3FB","order":2304,"unicode":"🚴🏻"},{"annotation":"person biking: medium-light skin tone","group":1,"hexcode":"1F6B4-1F3FC","order":2305,"unicode":"🚴🏼"},{"annotation":"person biking: medium skin tone","group":1,"hexcode":"1F6B4-1F3FD","order":2306,"unicode":"🚴🏽"},{"annotation":"person biking: medium-dark skin tone","group":1,"hexcode":"1F6B4-1F3FE","order":2307,"unicode":"🚴🏾"},{"annotation":"person biking: dark skin tone","group":1,"hexcode":"1F6B4-1F3FF","order":2308,"unicode":"🚴🏿"}]},{"annotation":"man biking","group":1,"hexcode":"1F6B4-200D-2642-FE0F","order":2309,"tags":["bicycle","biking","cyclist","man"],"unicode":"🚴‍♂️","skins":[{"annotation":"man biking: light skin tone","group":1,"hexcode":"1F6B4-1F3FB-200D-2642-FE0F","order":2311,"unicode":"🚴🏻‍♂️"},{"annotation":"man biking: medium-light skin tone","group":1,"hexcode":"1F6B4-1F3FC-200D-2642-FE0F","order":2313,"unicode":"🚴🏼‍♂️"},{"annotation":"man biking: medium skin tone","group":1,"hexcode":"1F6B4-1F3FD-200D-2642-FE0F","order":2315,"unicode":"🚴🏽‍♂️"},{"annotation":"man biking: medium-dark skin tone","group":1,"hexcode":"1F6B4-1F3FE-200D-2642-FE0F","order":2317,"unicode":"🚴🏾‍♂️"},{"annotation":"man biking: dark skin tone","group":1,"hexcode":"1F6B4-1F3FF-200D-2642-FE0F","order":2319,"unicode":"🚴🏿‍♂️"}]},{"annotation":"woman biking","group":1,"hexcode":"1F6B4-200D-2640-FE0F","order":2321,"tags":["bicycle","biking","cyclist","woman"],"unicode":"🚴‍♀️","skins":[{"annotation":"woman biking: light skin tone","group":1,"hexcode":"1F6B4-1F3FB-200D-2640-FE0F","order":2323,"unicode":"🚴🏻‍♀️"},{"annotation":"woman biking: medium-light skin tone","group":1,"hexcode":"1F6B4-1F3FC-200D-2640-FE0F","order":2325,"unicode":"🚴🏼‍♀️"},{"annotation":"woman biking: medium skin tone","group":1,"hexcode":"1F6B4-1F3FD-200D-2640-FE0F","order":2327,"unicode":"🚴🏽‍♀️"},{"annotation":"woman biking: medium-dark skin tone","group":1,"hexcode":"1F6B4-1F3FE-200D-2640-FE0F","order":2329,"unicode":"🚴🏾‍♀️"},{"annotation":"woman biking: dark skin tone","group":1,"hexcode":"1F6B4-1F3FF-200D-2640-FE0F","order":2331,"unicode":"🚴🏿‍♀️"}]},{"annotation":"person mountain biking","group":1,"hexcode":"1F6B5","order":2333,"tags":["bicycle","bicyclist","bike","cyclist","mountain"],"unicode":"🚵","skins":[{"annotation":"person mountain biking: light skin tone","group":1,"hexcode":"1F6B5-1F3FB","order":2334,"unicode":"🚵🏻"},{"annotation":"person mountain biking: medium-light skin tone","group":1,"hexcode":"1F6B5-1F3FC","order":2335,"unicode":"🚵🏼"},{"annotation":"person mountain biking: medium skin tone","group":1,"hexcode":"1F6B5-1F3FD","order":2336,"unicode":"🚵🏽"},{"annotation":"person mountain biking: medium-dark skin tone","group":1,"hexcode":"1F6B5-1F3FE","order":2337,"unicode":"🚵🏾"},{"annotation":"person mountain biking: dark skin tone","group":1,"hexcode":"1F6B5-1F3FF","order":2338,"unicode":"🚵🏿"}]},{"annotation":"man mountain biking","group":1,"hexcode":"1F6B5-200D-2642-FE0F","order":2339,"tags":["bicycle","bike","cyclist","man","mountain"],"unicode":"🚵‍♂️","skins":[{"annotation":"man mountain biking: light skin tone","group":1,"hexcode":"1F6B5-1F3FB-200D-2642-FE0F","order":2341,"unicode":"🚵🏻‍♂️"},{"annotation":"man mountain biking: medium-light skin tone","group":1,"hexcode":"1F6B5-1F3FC-200D-2642-FE0F","order":2343,"unicode":"🚵🏼‍♂️"},{"annotation":"man mountain biking: medium skin tone","group":1,"hexcode":"1F6B5-1F3FD-200D-2642-FE0F","order":2345,"unicode":"🚵🏽‍♂️"},{"annotation":"man mountain biking: medium-dark skin tone","group":1,"hexcode":"1F6B5-1F3FE-200D-2642-FE0F","order":2347,"unicode":"🚵🏾‍♂️"},{"annotation":"man mountain biking: dark skin tone","group":1,"hexcode":"1F6B5-1F3FF-200D-2642-FE0F","order":2349,"unicode":"🚵🏿‍♂️"}]},{"annotation":"woman mountain biking","group":1,"hexcode":"1F6B5-200D-2640-FE0F","order":2351,"tags":["bicycle","bike","biking","cyclist","mountain","woman"],"unicode":"🚵‍♀️","skins":[{"annotation":"woman mountain biking: light skin tone","group":1,"hexcode":"1F6B5-1F3FB-200D-2640-FE0F","order":2353,"unicode":"🚵🏻‍♀️"},{"annotation":"woman mountain biking: medium-light skin tone","group":1,"hexcode":"1F6B5-1F3FC-200D-2640-FE0F","order":2355,"unicode":"🚵🏼‍♀️"},{"annotation":"woman mountain biking: medium skin tone","group":1,"hexcode":"1F6B5-1F3FD-200D-2640-FE0F","order":2357,"unicode":"🚵🏽‍♀️"},{"annotation":"woman mountain biking: medium-dark skin tone","group":1,"hexcode":"1F6B5-1F3FE-200D-2640-FE0F","order":2359,"unicode":"🚵🏾‍♀️"},{"annotation":"woman mountain biking: dark skin tone","group":1,"hexcode":"1F6B5-1F3FF-200D-2640-FE0F","order":2361,"unicode":"🚵🏿‍♀️"}]},{"annotation":"person cartwheeling","group":1,"hexcode":"1F938","order":2363,"tags":["cartwheel","gymnastics"],"unicode":"🤸","skins":[{"annotation":"person cartwheeling: light skin tone","group":1,"hexcode":"1F938-1F3FB","order":2364,"unicode":"🤸🏻"},{"annotation":"person cartwheeling: medium-light skin tone","group":1,"hexcode":"1F938-1F3FC","order":2365,"unicode":"🤸🏼"},{"annotation":"person cartwheeling: medium skin tone","group":1,"hexcode":"1F938-1F3FD","order":2366,"unicode":"🤸🏽"},{"annotation":"person cartwheeling: medium-dark skin tone","group":1,"hexcode":"1F938-1F3FE","order":2367,"unicode":"🤸🏾"},{"annotation":"person cartwheeling: dark skin tone","group":1,"hexcode":"1F938-1F3FF","order":2368,"unicode":"🤸🏿"}]},{"annotation":"man cartwheeling","group":1,"hexcode":"1F938-200D-2642-FE0F","order":2369,"tags":["cartwheel","gymnastics","man"],"unicode":"🤸‍♂️","skins":[{"annotation":"man cartwheeling: light skin tone","group":1,"hexcode":"1F938-1F3FB-200D-2642-FE0F","order":2371,"unicode":"🤸🏻‍♂️"},{"annotation":"man cartwheeling: medium-light skin tone","group":1,"hexcode":"1F938-1F3FC-200D-2642-FE0F","order":2373,"unicode":"🤸🏼‍♂️"},{"annotation":"man cartwheeling: medium skin tone","group":1,"hexcode":"1F938-1F3FD-200D-2642-FE0F","order":2375,"unicode":"🤸🏽‍♂️"},{"annotation":"man cartwheeling: medium-dark skin tone","group":1,"hexcode":"1F938-1F3FE-200D-2642-FE0F","order":2377,"unicode":"🤸🏾‍♂️"},{"annotation":"man cartwheeling: dark skin tone","group":1,"hexcode":"1F938-1F3FF-200D-2642-FE0F","order":2379,"unicode":"🤸🏿‍♂️"}]},{"annotation":"woman cartwheeling","group":1,"hexcode":"1F938-200D-2640-FE0F","order":2381,"tags":["cartwheel","gymnastics","woman"],"unicode":"🤸‍♀️","skins":[{"annotation":"woman cartwheeling: light skin tone","group":1,"hexcode":"1F938-1F3FB-200D-2640-FE0F","order":2383,"unicode":"🤸🏻‍♀️"},{"annotation":"woman cartwheeling: medium-light skin tone","group":1,"hexcode":"1F938-1F3FC-200D-2640-FE0F","order":2385,"unicode":"🤸🏼‍♀️"},{"annotation":"woman cartwheeling: medium skin tone","group":1,"hexcode":"1F938-1F3FD-200D-2640-FE0F","order":2387,"unicode":"🤸🏽‍♀️"},{"annotation":"woman cartwheeling: medium-dark skin tone","group":1,"hexcode":"1F938-1F3FE-200D-2640-FE0F","order":2389,"unicode":"🤸🏾‍♀️"},{"annotation":"woman cartwheeling: dark skin tone","group":1,"hexcode":"1F938-1F3FF-200D-2640-FE0F","order":2391,"unicode":"🤸🏿‍♀️"}]},{"annotation":"people wrestling","group":1,"hexcode":"1F93C","order":2393,"tags":["wrestle","wrestler"],"unicode":"🤼"},{"annotation":"men wrestling","group":1,"hexcode":"1F93C-200D-2642-FE0F","order":2394,"tags":["men","wrestle"],"unicode":"🤼‍♂️"},{"annotation":"women wrestling","group":1,"hexcode":"1F93C-200D-2640-FE0F","order":2396,"tags":["women","wrestle"],"unicode":"🤼‍♀️"},{"annotation":"person playing water polo","group":1,"hexcode":"1F93D","order":2398,"tags":["polo","water"],"unicode":"🤽","skins":[{"annotation":"person playing water polo: light skin tone","group":1,"hexcode":"1F93D-1F3FB","order":2399,"unicode":"🤽🏻"},{"annotation":"person playing water polo: medium-light skin tone","group":1,"hexcode":"1F93D-1F3FC","order":2400,"unicode":"🤽🏼"},{"annotation":"person playing water polo: medium skin tone","group":1,"hexcode":"1F93D-1F3FD","order":2401,"unicode":"🤽🏽"},{"annotation":"person playing water polo: medium-dark skin tone","group":1,"hexcode":"1F93D-1F3FE","order":2402,"unicode":"🤽🏾"},{"annotation":"person playing water polo: dark skin tone","group":1,"hexcode":"1F93D-1F3FF","order":2403,"unicode":"🤽🏿"}]},{"annotation":"man playing water polo","group":1,"hexcode":"1F93D-200D-2642-FE0F","order":2404,"tags":["man","water polo"],"unicode":"🤽‍♂️","skins":[{"annotation":"man playing water polo: light skin tone","group":1,"hexcode":"1F93D-1F3FB-200D-2642-FE0F","order":2406,"unicode":"🤽🏻‍♂️"},{"annotation":"man playing water polo: medium-light skin tone","group":1,"hexcode":"1F93D-1F3FC-200D-2642-FE0F","order":2408,"unicode":"🤽🏼‍♂️"},{"annotation":"man playing water polo: medium skin tone","group":1,"hexcode":"1F93D-1F3FD-200D-2642-FE0F","order":2410,"unicode":"🤽🏽‍♂️"},{"annotation":"man playing water polo: medium-dark skin tone","group":1,"hexcode":"1F93D-1F3FE-200D-2642-FE0F","order":2412,"unicode":"🤽🏾‍♂️"},{"annotation":"man playing water polo: dark skin tone","group":1,"hexcode":"1F93D-1F3FF-200D-2642-FE0F","order":2414,"unicode":"🤽🏿‍♂️"}]},{"annotation":"woman playing water polo","group":1,"hexcode":"1F93D-200D-2640-FE0F","order":2416,"tags":["water polo","woman"],"unicode":"🤽‍♀️","skins":[{"annotation":"woman playing water polo: light skin tone","group":1,"hexcode":"1F93D-1F3FB-200D-2640-FE0F","order":2418,"unicode":"🤽🏻‍♀️"},{"annotation":"woman playing water polo: medium-light skin tone","group":1,"hexcode":"1F93D-1F3FC-200D-2640-FE0F","order":2420,"unicode":"🤽🏼‍♀️"},{"annotation":"woman playing water polo: medium skin tone","group":1,"hexcode":"1F93D-1F3FD-200D-2640-FE0F","order":2422,"unicode":"🤽🏽‍♀️"},{"annotation":"woman playing water polo: medium-dark skin tone","group":1,"hexcode":"1F93D-1F3FE-200D-2640-FE0F","order":2424,"unicode":"🤽🏾‍♀️"},{"annotation":"woman playing water polo: dark skin tone","group":1,"hexcode":"1F93D-1F3FF-200D-2640-FE0F","order":2426,"unicode":"🤽🏿‍♀️"}]},{"annotation":"person playing handball","group":1,"hexcode":"1F93E","order":2428,"tags":["ball","handball"],"unicode":"🤾","skins":[{"annotation":"person playing handball: light skin tone","group":1,"hexcode":"1F93E-1F3FB","order":2429,"unicode":"🤾🏻"},{"annotation":"person playing handball: medium-light skin tone","group":1,"hexcode":"1F93E-1F3FC","order":2430,"unicode":"🤾🏼"},{"annotation":"person playing handball: medium skin tone","group":1,"hexcode":"1F93E-1F3FD","order":2431,"unicode":"🤾🏽"},{"annotation":"person playing handball: medium-dark skin tone","group":1,"hexcode":"1F93E-1F3FE","order":2432,"unicode":"🤾🏾"},{"annotation":"person playing handball: dark skin tone","group":1,"hexcode":"1F93E-1F3FF","order":2433,"unicode":"🤾🏿"}]},{"annotation":"man playing handball","group":1,"hexcode":"1F93E-200D-2642-FE0F","order":2434,"tags":["handball","man"],"unicode":"🤾‍♂️","skins":[{"annotation":"man playing handball: light skin tone","group":1,"hexcode":"1F93E-1F3FB-200D-2642-FE0F","order":2436,"unicode":"🤾🏻‍♂️"},{"annotation":"man playing handball: medium-light skin tone","group":1,"hexcode":"1F93E-1F3FC-200D-2642-FE0F","order":2438,"unicode":"🤾🏼‍♂️"},{"annotation":"man playing handball: medium skin tone","group":1,"hexcode":"1F93E-1F3FD-200D-2642-FE0F","order":2440,"unicode":"🤾🏽‍♂️"},{"annotation":"man playing handball: medium-dark skin tone","group":1,"hexcode":"1F93E-1F3FE-200D-2642-FE0F","order":2442,"unicode":"🤾🏾‍♂️"},{"annotation":"man playing handball: dark skin tone","group":1,"hexcode":"1F93E-1F3FF-200D-2642-FE0F","order":2444,"unicode":"🤾🏿‍♂️"}]},{"annotation":"woman playing handball","group":1,"hexcode":"1F93E-200D-2640-FE0F","order":2446,"tags":["handball","woman"],"unicode":"🤾‍♀️","skins":[{"annotation":"woman playing handball: light skin tone","group":1,"hexcode":"1F93E-1F3FB-200D-2640-FE0F","order":2448,"unicode":"🤾🏻‍♀️"},{"annotation":"woman playing handball: medium-light skin tone","group":1,"hexcode":"1F93E-1F3FC-200D-2640-FE0F","order":2450,"unicode":"🤾🏼‍♀️"},{"annotation":"woman playing handball: medium skin tone","group":1,"hexcode":"1F93E-1F3FD-200D-2640-FE0F","order":2452,"unicode":"🤾🏽‍♀️"},{"annotation":"woman playing handball: medium-dark skin tone","group":1,"hexcode":"1F93E-1F3FE-200D-2640-FE0F","order":2454,"unicode":"🤾🏾‍♀️"},{"annotation":"woman playing handball: dark skin tone","group":1,"hexcode":"1F93E-1F3FF-200D-2640-FE0F","order":2456,"unicode":"🤾🏿‍♀️"}]},{"annotation":"person juggling","group":1,"hexcode":"1F939","order":2458,"tags":["balance","juggle","multitask","skill"],"unicode":"🤹","skins":[{"annotation":"person juggling: light skin tone","group":1,"hexcode":"1F939-1F3FB","order":2459,"unicode":"🤹🏻"},{"annotation":"person juggling: medium-light skin tone","group":1,"hexcode":"1F939-1F3FC","order":2460,"unicode":"🤹🏼"},{"annotation":"person juggling: medium skin tone","group":1,"hexcode":"1F939-1F3FD","order":2461,"unicode":"🤹🏽"},{"annotation":"person juggling: medium-dark skin tone","group":1,"hexcode":"1F939-1F3FE","order":2462,"unicode":"🤹🏾"},{"annotation":"person juggling: dark skin tone","group":1,"hexcode":"1F939-1F3FF","order":2463,"unicode":"🤹🏿"}]},{"annotation":"man juggling","group":1,"hexcode":"1F939-200D-2642-FE0F","order":2464,"tags":["juggling","man","multitask"],"unicode":"🤹‍♂️","skins":[{"annotation":"man juggling: light skin tone","group":1,"hexcode":"1F939-1F3FB-200D-2642-FE0F","order":2466,"unicode":"🤹🏻‍♂️"},{"annotation":"man juggling: medium-light skin tone","group":1,"hexcode":"1F939-1F3FC-200D-2642-FE0F","order":2468,"unicode":"🤹🏼‍♂️"},{"annotation":"man juggling: medium skin tone","group":1,"hexcode":"1F939-1F3FD-200D-2642-FE0F","order":2470,"unicode":"🤹🏽‍♂️"},{"annotation":"man juggling: medium-dark skin tone","group":1,"hexcode":"1F939-1F3FE-200D-2642-FE0F","order":2472,"unicode":"🤹🏾‍♂️"},{"annotation":"man juggling: dark skin tone","group":1,"hexcode":"1F939-1F3FF-200D-2642-FE0F","order":2474,"unicode":"🤹🏿‍♂️"}]},{"annotation":"woman juggling","group":1,"hexcode":"1F939-200D-2640-FE0F","order":2476,"tags":["juggling","multitask","woman"],"unicode":"🤹‍♀️","skins":[{"annotation":"woman juggling: light skin tone","group":1,"hexcode":"1F939-1F3FB-200D-2640-FE0F","order":2478,"unicode":"🤹🏻‍♀️"},{"annotation":"woman juggling: medium-light skin tone","group":1,"hexcode":"1F939-1F3FC-200D-2640-FE0F","order":2480,"unicode":"🤹🏼‍♀️"},{"annotation":"woman juggling: medium skin tone","group":1,"hexcode":"1F939-1F3FD-200D-2640-FE0F","order":2482,"unicode":"🤹🏽‍♀️"},{"annotation":"woman juggling: medium-dark skin tone","group":1,"hexcode":"1F939-1F3FE-200D-2640-FE0F","order":2484,"unicode":"🤹🏾‍♀️"},{"annotation":"woman juggling: dark skin tone","group":1,"hexcode":"1F939-1F3FF-200D-2640-FE0F","order":2486,"unicode":"🤹🏿‍♀️"}]},{"annotation":"person in lotus position","group":1,"hexcode":"1F9D8","order":2488,"tags":["meditation","yoga"],"unicode":"🧘","skins":[{"annotation":"person in lotus position: light skin tone","group":1,"hexcode":"1F9D8-1F3FB","order":2489,"unicode":"🧘🏻"},{"annotation":"person in lotus position: medium-light skin tone","group":1,"hexcode":"1F9D8-1F3FC","order":2490,"unicode":"🧘🏼"},{"annotation":"person in lotus position: medium skin tone","group":1,"hexcode":"1F9D8-1F3FD","order":2491,"unicode":"🧘🏽"},{"annotation":"person in lotus position: medium-dark skin tone","group":1,"hexcode":"1F9D8-1F3FE","order":2492,"unicode":"🧘🏾"},{"annotation":"person in lotus position: dark skin tone","group":1,"hexcode":"1F9D8-1F3FF","order":2493,"unicode":"🧘🏿"}]},{"annotation":"man in lotus position","group":1,"hexcode":"1F9D8-200D-2642-FE0F","order":2494,"tags":["meditation","yoga"],"unicode":"🧘‍♂️","skins":[{"annotation":"man in lotus position: light skin tone","group":1,"hexcode":"1F9D8-1F3FB-200D-2642-FE0F","order":2496,"unicode":"🧘🏻‍♂️"},{"annotation":"man in lotus position: medium-light skin tone","group":1,"hexcode":"1F9D8-1F3FC-200D-2642-FE0F","order":2498,"unicode":"🧘🏼‍♂️"},{"annotation":"man in lotus position: medium skin tone","group":1,"hexcode":"1F9D8-1F3FD-200D-2642-FE0F","order":2500,"unicode":"🧘🏽‍♂️"},{"annotation":"man in lotus position: medium-dark skin tone","group":1,"hexcode":"1F9D8-1F3FE-200D-2642-FE0F","order":2502,"unicode":"🧘🏾‍♂️"},{"annotation":"man in lotus position: dark skin tone","group":1,"hexcode":"1F9D8-1F3FF-200D-2642-FE0F","order":2504,"unicode":"🧘🏿‍♂️"}]},{"annotation":"woman in lotus position","group":1,"hexcode":"1F9D8-200D-2640-FE0F","order":2506,"tags":["meditation","yoga"],"unicode":"🧘‍♀️","skins":[{"annotation":"woman in lotus position: light skin tone","group":1,"hexcode":"1F9D8-1F3FB-200D-2640-FE0F","order":2508,"unicode":"🧘🏻‍♀️"},{"annotation":"woman in lotus position: medium-light skin tone","group":1,"hexcode":"1F9D8-1F3FC-200D-2640-FE0F","order":2510,"unicode":"🧘🏼‍♀️"},{"annotation":"woman in lotus position: medium skin tone","group":1,"hexcode":"1F9D8-1F3FD-200D-2640-FE0F","order":2512,"unicode":"🧘🏽‍♀️"},{"annotation":"woman in lotus position: medium-dark skin tone","group":1,"hexcode":"1F9D8-1F3FE-200D-2640-FE0F","order":2514,"unicode":"🧘🏾‍♀️"},{"annotation":"woman in lotus position: dark skin tone","group":1,"hexcode":"1F9D8-1F3FF-200D-2640-FE0F","order":2516,"unicode":"🧘🏿‍♀️"}]},{"annotation":"person taking bath","group":1,"hexcode":"1F6C0","order":2518,"tags":["bath","bathtub"],"unicode":"🛀","skins":[{"annotation":"person taking bath: light skin tone","group":1,"hexcode":"1F6C0-1F3FB","order":2519,"unicode":"🛀🏻"},{"annotation":"person taking bath: medium-light skin tone","group":1,"hexcode":"1F6C0-1F3FC","order":2520,"unicode":"🛀🏼"},{"annotation":"person taking bath: medium skin tone","group":1,"hexcode":"1F6C0-1F3FD","order":2521,"unicode":"🛀🏽"},{"annotation":"person taking bath: medium-dark skin tone","group":1,"hexcode":"1F6C0-1F3FE","order":2522,"unicode":"🛀🏾"},{"annotation":"person taking bath: dark skin tone","group":1,"hexcode":"1F6C0-1F3FF","order":2523,"unicode":"🛀🏿"}]},{"annotation":"person in bed","group":1,"hexcode":"1F6CC","order":2524,"tags":["hotel","sleep"],"unicode":"🛌","skins":[{"annotation":"person in bed: light skin tone","group":1,"hexcode":"1F6CC-1F3FB","order":2525,"unicode":"🛌🏻"},{"annotation":"person in bed: medium-light skin tone","group":1,"hexcode":"1F6CC-1F3FC","order":2526,"unicode":"🛌🏼"},{"annotation":"person in bed: medium skin tone","group":1,"hexcode":"1F6CC-1F3FD","order":2527,"unicode":"🛌🏽"},{"annotation":"person in bed: medium-dark skin tone","group":1,"hexcode":"1F6CC-1F3FE","order":2528,"unicode":"🛌🏾"},{"annotation":"person in bed: dark skin tone","group":1,"hexcode":"1F6CC-1F3FF","order":2529,"unicode":"🛌🏿"}]},{"annotation":"people holding hands","group":1,"hexcode":"1F9D1-200D-1F91D-200D-1F9D1","order":2530,"tags":["couple","hand","hold","holding hands","person"],"unicode":"🧑‍🤝‍🧑","skins":[{"annotation":"people holding hands: light skin tone","group":1,"hexcode":"1F9D1-1F3FB-200D-1F91D-200D-1F9D1-1F3FB","order":2531,"unicode":"🧑🏻‍🤝‍🧑🏻"},{"annotation":"people holding hands: light skin tone, medium-light skin tone","group":1,"hexcode":"1F9D1-1F3FB-200D-1F91D-200D-1F9D1-1F3FC","order":2532,"unicode":"🧑🏻‍🤝‍🧑🏼"},{"annotation":"people holding hands: light skin tone, medium skin tone","group":1,"hexcode":"1F9D1-1F3FB-200D-1F91D-200D-1F9D1-1F3FD","order":2533,"unicode":"🧑🏻‍🤝‍🧑🏽"},{"annotation":"people holding hands: light skin tone, medium-dark skin tone","group":1,"hexcode":"1F9D1-1F3FB-200D-1F91D-200D-1F9D1-1F3FE","order":2534,"unicode":"🧑🏻‍🤝‍🧑🏾"},{"annotation":"people holding hands: light skin tone, dark skin tone","group":1,"hexcode":"1F9D1-1F3FB-200D-1F91D-200D-1F9D1-1F3FF","order":2535,"unicode":"🧑🏻‍🤝‍🧑🏿"},{"annotation":"people holding hands: medium-light skin tone, light skin tone","group":1,"hexcode":"1F9D1-1F3FC-200D-1F91D-200D-1F9D1-1F3FB","order":2536,"unicode":"🧑🏼‍🤝‍🧑🏻"},{"annotation":"people holding hands: medium-light skin tone","group":1,"hexcode":"1F9D1-1F3FC-200D-1F91D-200D-1F9D1-1F3FC","order":2537,"unicode":"🧑🏼‍🤝‍🧑🏼"},{"annotation":"people holding hands: medium-light skin tone, medium skin tone","group":1,"hexcode":"1F9D1-1F3FC-200D-1F91D-200D-1F9D1-1F3FD","order":2538,"unicode":"🧑🏼‍🤝‍🧑🏽"},{"annotation":"people holding hands: medium-light skin tone, medium-dark skin tone","group":1,"hexcode":"1F9D1-1F3FC-200D-1F91D-200D-1F9D1-1F3FE","order":2539,"unicode":"🧑🏼‍🤝‍🧑🏾"},{"annotation":"people holding hands: medium-light skin tone, dark skin tone","group":1,"hexcode":"1F9D1-1F3FC-200D-1F91D-200D-1F9D1-1F3FF","order":2540,"unicode":"🧑🏼‍🤝‍🧑🏿"},{"annotation":"people holding hands: medium skin tone, light skin tone","group":1,"hexcode":"1F9D1-1F3FD-200D-1F91D-200D-1F9D1-1F3FB","order":2541,"unicode":"🧑🏽‍🤝‍🧑🏻"},{"annotation":"people holding hands: medium skin tone, medium-light skin tone","group":1,"hexcode":"1F9D1-1F3FD-200D-1F91D-200D-1F9D1-1F3FC","order":2542,"unicode":"🧑🏽‍🤝‍🧑🏼"},{"annotation":"people holding hands: medium skin tone","group":1,"hexcode":"1F9D1-1F3FD-200D-1F91D-200D-1F9D1-1F3FD","order":2543,"unicode":"🧑🏽‍🤝‍🧑🏽"},{"annotation":"people holding hands: medium skin tone, medium-dark skin tone","group":1,"hexcode":"1F9D1-1F3FD-200D-1F91D-200D-1F9D1-1F3FE","order":2544,"unicode":"🧑🏽‍🤝‍🧑🏾"},{"annotation":"people holding hands: medium skin tone, dark skin tone","group":1,"hexcode":"1F9D1-1F3FD-200D-1F91D-200D-1F9D1-1F3FF","order":2545,"unicode":"🧑🏽‍🤝‍🧑🏿"},{"annotation":"people holding hands: medium-dark skin tone, light skin tone","group":1,"hexcode":"1F9D1-1F3FE-200D-1F91D-200D-1F9D1-1F3FB","order":2546,"unicode":"🧑🏾‍🤝‍🧑🏻"},{"annotation":"people holding hands: medium-dark skin tone, medium-light skin tone","group":1,"hexcode":"1F9D1-1F3FE-200D-1F91D-200D-1F9D1-1F3FC","order":2547,"unicode":"🧑🏾‍🤝‍🧑🏼"},{"annotation":"people holding hands: medium-dark skin tone, medium skin tone","group":1,"hexcode":"1F9D1-1F3FE-200D-1F91D-200D-1F9D1-1F3FD","order":2548,"unicode":"🧑🏾‍🤝‍🧑🏽"},{"annotation":"people holding hands: medium-dark skin tone","group":1,"hexcode":"1F9D1-1F3FE-200D-1F91D-200D-1F9D1-1F3FE","order":2549,"unicode":"🧑🏾‍🤝‍🧑🏾"},{"annotation":"people holding hands: medium-dark skin tone, dark skin tone","group":1,"hexcode":"1F9D1-1F3FE-200D-1F91D-200D-1F9D1-1F3FF","order":2550,"unicode":"🧑🏾‍🤝‍🧑🏿"},{"annotation":"people holding hands: dark skin tone, light skin tone","group":1,"hexcode":"1F9D1-1F3FF-200D-1F91D-200D-1F9D1-1F3FB","order":2551,"unicode":"🧑🏿‍🤝‍🧑🏻"},{"annotation":"people holding hands: dark skin tone, medium-light skin tone","group":1,"hexcode":"1F9D1-1F3FF-200D-1F91D-200D-1F9D1-1F3FC","order":2552,"unicode":"🧑🏿‍🤝‍🧑🏼"},{"annotation":"people holding hands: dark skin tone, medium skin tone","group":1,"hexcode":"1F9D1-1F3FF-200D-1F91D-200D-1F9D1-1F3FD","order":2553,"unicode":"🧑🏿‍🤝‍🧑🏽"},{"annotation":"people holding hands: dark skin tone, medium-dark skin tone","group":1,"hexcode":"1F9D1-1F3FF-200D-1F91D-200D-1F9D1-1F3FE","order":2554,"unicode":"🧑🏿‍🤝‍🧑🏾"},{"annotation":"people holding hands: dark skin tone","group":1,"hexcode":"1F9D1-1F3FF-200D-1F91D-200D-1F9D1-1F3FF","order":2555,"unicode":"🧑🏿‍🤝‍🧑🏿"}]},{"annotation":"women holding hands","group":1,"hexcode":"1F46D","order":2556,"tags":["couple","hand","holding hands","women"],"unicode":"👭","skins":[{"annotation":"women holding hands: light skin tone","group":1,"hexcode":"1F46D-1F3FB","order":2557,"unicode":"👭🏻"},{"annotation":"women holding hands: medium-light skin tone","group":1,"hexcode":"1F46D-1F3FC","order":2563,"unicode":"👭🏼"},{"annotation":"women holding hands: medium skin tone","group":1,"hexcode":"1F46D-1F3FD","order":2569,"unicode":"👭🏽"},{"annotation":"women holding hands: medium-dark skin tone","group":1,"hexcode":"1F46D-1F3FE","order":2575,"unicode":"👭🏾"},{"annotation":"women holding hands: dark skin tone","group":1,"hexcode":"1F46D-1F3FF","order":2581,"unicode":"👭🏿"},{"annotation":"women holding hands: light skin tone, medium-light skin tone","group":1,"hexcode":"1F469-1F3FB-200D-1F91D-200D-1F469-1F3FC","order":2558,"unicode":"👩🏻‍🤝‍👩🏼"},{"annotation":"women holding hands: light skin tone, medium skin tone","group":1,"hexcode":"1F469-1F3FB-200D-1F91D-200D-1F469-1F3FD","order":2559,"unicode":"👩🏻‍🤝‍👩🏽"},{"annotation":"women holding hands: light skin tone, medium-dark skin tone","group":1,"hexcode":"1F469-1F3FB-200D-1F91D-200D-1F469-1F3FE","order":2560,"unicode":"👩🏻‍🤝‍👩🏾"},{"annotation":"women holding hands: light skin tone, dark skin tone","group":1,"hexcode":"1F469-1F3FB-200D-1F91D-200D-1F469-1F3FF","order":2561,"unicode":"👩🏻‍🤝‍👩🏿"},{"annotation":"women holding hands: medium-light skin tone, light skin tone","group":1,"hexcode":"1F469-1F3FC-200D-1F91D-200D-1F469-1F3FB","order":2562,"unicode":"👩🏼‍🤝‍👩🏻"},{"annotation":"women holding hands: medium-light skin tone, medium skin tone","group":1,"hexcode":"1F469-1F3FC-200D-1F91D-200D-1F469-1F3FD","order":2564,"unicode":"👩🏼‍🤝‍👩🏽"},{"annotation":"women holding hands: medium-light skin tone, medium-dark skin tone","group":1,"hexcode":"1F469-1F3FC-200D-1F91D-200D-1F469-1F3FE","order":2565,"unicode":"👩🏼‍🤝‍👩🏾"},{"annotation":"women holding hands: medium-light skin tone, dark skin tone","group":1,"hexcode":"1F469-1F3FC-200D-1F91D-200D-1F469-1F3FF","order":2566,"unicode":"👩🏼‍🤝‍👩🏿"},{"annotation":"women holding hands: medium skin tone, light skin tone","group":1,"hexcode":"1F469-1F3FD-200D-1F91D-200D-1F469-1F3FB","order":2567,"unicode":"👩🏽‍🤝‍👩🏻"},{"annotation":"women holding hands: medium skin tone, medium-light skin tone","group":1,"hexcode":"1F469-1F3FD-200D-1F91D-200D-1F469-1F3FC","order":2568,"unicode":"👩🏽‍🤝‍👩🏼"},{"annotation":"women holding hands: medium skin tone, medium-dark skin tone","group":1,"hexcode":"1F469-1F3FD-200D-1F91D-200D-1F469-1F3FE","order":2570,"unicode":"👩🏽‍🤝‍👩🏾"},{"annotation":"women holding hands: medium skin tone, dark skin tone","group":1,"hexcode":"1F469-1F3FD-200D-1F91D-200D-1F469-1F3FF","order":2571,"unicode":"👩🏽‍🤝‍👩🏿"},{"annotation":"women holding hands: medium-dark skin tone, light skin tone","group":1,"hexcode":"1F469-1F3FE-200D-1F91D-200D-1F469-1F3FB","order":2572,"unicode":"👩🏾‍🤝‍👩🏻"},{"annotation":"women holding hands: medium-dark skin tone, medium-light skin tone","group":1,"hexcode":"1F469-1F3FE-200D-1F91D-200D-1F469-1F3FC","order":2573,"unicode":"👩🏾‍🤝‍👩🏼"},{"annotation":"women holding hands: medium-dark skin tone, medium skin tone","group":1,"hexcode":"1F469-1F3FE-200D-1F91D-200D-1F469-1F3FD","order":2574,"unicode":"👩🏾‍🤝‍👩🏽"},{"annotation":"women holding hands: medium-dark skin tone, dark skin tone","group":1,"hexcode":"1F469-1F3FE-200D-1F91D-200D-1F469-1F3FF","order":2576,"unicode":"👩🏾‍🤝‍👩🏿"},{"annotation":"women holding hands: dark skin tone, light skin tone","group":1,"hexcode":"1F469-1F3FF-200D-1F91D-200D-1F469-1F3FB","order":2577,"unicode":"👩🏿‍🤝‍👩🏻"},{"annotation":"women holding hands: dark skin tone, medium-light skin tone","group":1,"hexcode":"1F469-1F3FF-200D-1F91D-200D-1F469-1F3FC","order":2578,"unicode":"👩🏿‍🤝‍👩🏼"},{"annotation":"women holding hands: dark skin tone, medium skin tone","group":1,"hexcode":"1F469-1F3FF-200D-1F91D-200D-1F469-1F3FD","order":2579,"unicode":"👩🏿‍🤝‍👩🏽"},{"annotation":"women holding hands: dark skin tone, medium-dark skin tone","group":1,"hexcode":"1F469-1F3FF-200D-1F91D-200D-1F469-1F3FE","order":2580,"unicode":"👩🏿‍🤝‍👩🏾"}]},{"annotation":"woman and man holding hands","group":1,"hexcode":"1F46B","order":2582,"tags":["couple","hand","hold","holding hands","man","woman"],"unicode":"👫","skins":[{"annotation":"woman and man holding hands: light skin tone","group":1,"hexcode":"1F46B-1F3FB","order":2583,"unicode":"👫🏻"},{"annotation":"woman and man holding hands: medium-light skin tone","group":1,"hexcode":"1F46B-1F3FC","order":2589,"unicode":"👫🏼"},{"annotation":"woman and man holding hands: medium skin tone","group":1,"hexcode":"1F46B-1F3FD","order":2595,"unicode":"👫🏽"},{"annotation":"woman and man holding hands: medium-dark skin tone","group":1,"hexcode":"1F46B-1F3FE","order":2601,"unicode":"👫🏾"},{"annotation":"woman and man holding hands: dark skin tone","group":1,"hexcode":"1F46B-1F3FF","order":2607,"unicode":"👫🏿"},{"annotation":"woman and man holding hands: light skin tone, medium-light skin tone","group":1,"hexcode":"1F469-1F3FB-200D-1F91D-200D-1F468-1F3FC","order":2584,"unicode":"👩🏻‍🤝‍👨🏼"},{"annotation":"woman and man holding hands: light skin tone, medium skin tone","group":1,"hexcode":"1F469-1F3FB-200D-1F91D-200D-1F468-1F3FD","order":2585,"unicode":"👩🏻‍🤝‍👨🏽"},{"annotation":"woman and man holding hands: light skin tone, medium-dark skin tone","group":1,"hexcode":"1F469-1F3FB-200D-1F91D-200D-1F468-1F3FE","order":2586,"unicode":"👩🏻‍🤝‍👨🏾"},{"annotation":"woman and man holding hands: light skin tone, dark skin tone","group":1,"hexcode":"1F469-1F3FB-200D-1F91D-200D-1F468-1F3FF","order":2587,"unicode":"👩🏻‍🤝‍👨🏿"},{"annotation":"woman and man holding hands: medium-light skin tone, light skin tone","group":1,"hexcode":"1F469-1F3FC-200D-1F91D-200D-1F468-1F3FB","order":2588,"unicode":"👩🏼‍🤝‍👨🏻"},{"annotation":"woman and man holding hands: medium-light skin tone, medium skin tone","group":1,"hexcode":"1F469-1F3FC-200D-1F91D-200D-1F468-1F3FD","order":2590,"unicode":"👩🏼‍🤝‍👨🏽"},{"annotation":"woman and man holding hands: medium-light skin tone, medium-dark skin tone","group":1,"hexcode":"1F469-1F3FC-200D-1F91D-200D-1F468-1F3FE","order":2591,"unicode":"👩🏼‍🤝‍👨🏾"},{"annotation":"woman and man holding hands: medium-light skin tone, dark skin tone","group":1,"hexcode":"1F469-1F3FC-200D-1F91D-200D-1F468-1F3FF","order":2592,"unicode":"👩🏼‍🤝‍👨🏿"},{"annotation":"woman and man holding hands: medium skin tone, light skin tone","group":1,"hexcode":"1F469-1F3FD-200D-1F91D-200D-1F468-1F3FB","order":2593,"unicode":"👩🏽‍🤝‍👨🏻"},{"annotation":"woman and man holding hands: medium skin tone, medium-light skin tone","group":1,"hexcode":"1F469-1F3FD-200D-1F91D-200D-1F468-1F3FC","order":2594,"unicode":"👩🏽‍🤝‍👨🏼"},{"annotation":"woman and man holding hands: medium skin tone, medium-dark skin tone","group":1,"hexcode":"1F469-1F3FD-200D-1F91D-200D-1F468-1F3FE","order":2596,"unicode":"👩🏽‍🤝‍👨🏾"},{"annotation":"woman and man holding hands: medium skin tone, dark skin tone","group":1,"hexcode":"1F469-1F3FD-200D-1F91D-200D-1F468-1F3FF","order":2597,"unicode":"👩🏽‍🤝‍👨🏿"},{"annotation":"woman and man holding hands: medium-dark skin tone, light skin tone","group":1,"hexcode":"1F469-1F3FE-200D-1F91D-200D-1F468-1F3FB","order":2598,"unicode":"👩🏾‍🤝‍👨🏻"},{"annotation":"woman and man holding hands: medium-dark skin tone, medium-light skin tone","group":1,"hexcode":"1F469-1F3FE-200D-1F91D-200D-1F468-1F3FC","order":2599,"unicode":"👩🏾‍🤝‍👨🏼"},{"annotation":"woman and man holding hands: medium-dark skin tone, medium skin tone","group":1,"hexcode":"1F469-1F3FE-200D-1F91D-200D-1F468-1F3FD","order":2600,"unicode":"👩🏾‍🤝‍👨🏽"},{"annotation":"woman and man holding hands: medium-dark skin tone, dark skin tone","group":1,"hexcode":"1F469-1F3FE-200D-1F91D-200D-1F468-1F3FF","order":2602,"unicode":"👩🏾‍🤝‍👨🏿"},{"annotation":"woman and man holding hands: dark skin tone, light skin tone","group":1,"hexcode":"1F469-1F3FF-200D-1F91D-200D-1F468-1F3FB","order":2603,"unicode":"👩🏿‍🤝‍👨🏻"},{"annotation":"woman and man holding hands: dark skin tone, medium-light skin tone","group":1,"hexcode":"1F469-1F3FF-200D-1F91D-200D-1F468-1F3FC","order":2604,"unicode":"👩🏿‍🤝‍👨🏼"},{"annotation":"woman and man holding hands: dark skin tone, medium skin tone","group":1,"hexcode":"1F469-1F3FF-200D-1F91D-200D-1F468-1F3FD","order":2605,"unicode":"👩🏿‍🤝‍👨🏽"},{"annotation":"woman and man holding hands: dark skin tone, medium-dark skin tone","group":1,"hexcode":"1F469-1F3FF-200D-1F91D-200D-1F468-1F3FE","order":2606,"unicode":"👩🏿‍🤝‍👨🏾"}]},{"annotation":"men holding hands","group":1,"hexcode":"1F46C","order":2608,"tags":["couple","gemini","holding hands","man","men","twins","zodiac"],"unicode":"👬","skins":[{"annotation":"men holding hands: light skin tone","group":1,"hexcode":"1F46C-1F3FB","order":2609,"unicode":"👬🏻"},{"annotation":"men holding hands: medium-light skin tone","group":1,"hexcode":"1F46C-1F3FC","order":2615,"unicode":"👬🏼"},{"annotation":"men holding hands: medium skin tone","group":1,"hexcode":"1F46C-1F3FD","order":2621,"unicode":"👬🏽"},{"annotation":"men holding hands: medium-dark skin tone","group":1,"hexcode":"1F46C-1F3FE","order":2627,"unicode":"👬🏾"},{"annotation":"men holding hands: dark skin tone","group":1,"hexcode":"1F46C-1F3FF","order":2633,"unicode":"👬🏿"},{"annotation":"men holding hands: light skin tone, medium-light skin tone","group":1,"hexcode":"1F468-1F3FB-200D-1F91D-200D-1F468-1F3FC","order":2610,"unicode":"👨🏻‍🤝‍👨🏼"},{"annotation":"men holding hands: light skin tone, medium skin tone","group":1,"hexcode":"1F468-1F3FB-200D-1F91D-200D-1F468-1F3FD","order":2611,"unicode":"👨🏻‍🤝‍👨🏽"},{"annotation":"men holding hands: light skin tone, medium-dark skin tone","group":1,"hexcode":"1F468-1F3FB-200D-1F91D-200D-1F468-1F3FE","order":2612,"unicode":"👨🏻‍🤝‍👨🏾"},{"annotation":"men holding hands: light skin tone, dark skin tone","group":1,"hexcode":"1F468-1F3FB-200D-1F91D-200D-1F468-1F3FF","order":2613,"unicode":"👨🏻‍🤝‍👨🏿"},{"annotation":"men holding hands: medium-light skin tone, light skin tone","group":1,"hexcode":"1F468-1F3FC-200D-1F91D-200D-1F468-1F3FB","order":2614,"unicode":"👨🏼‍🤝‍👨🏻"},{"annotation":"men holding hands: medium-light skin tone, medium skin tone","group":1,"hexcode":"1F468-1F3FC-200D-1F91D-200D-1F468-1F3FD","order":2616,"unicode":"👨🏼‍🤝‍👨🏽"},{"annotation":"men holding hands: medium-light skin tone, medium-dark skin tone","group":1,"hexcode":"1F468-1F3FC-200D-1F91D-200D-1F468-1F3FE","order":2617,"unicode":"👨🏼‍🤝‍👨🏾"},{"annotation":"men holding hands: medium-light skin tone, dark skin tone","group":1,"hexcode":"1F468-1F3FC-200D-1F91D-200D-1F468-1F3FF","order":2618,"unicode":"👨🏼‍🤝‍👨🏿"},{"annotation":"men holding hands: medium skin tone, light skin tone","group":1,"hexcode":"1F468-1F3FD-200D-1F91D-200D-1F468-1F3FB","order":2619,"unicode":"👨🏽‍🤝‍👨🏻"},{"annotation":"men holding hands: medium skin tone, medium-light skin tone","group":1,"hexcode":"1F468-1F3FD-200D-1F91D-200D-1F468-1F3FC","order":2620,"unicode":"👨🏽‍🤝‍👨🏼"},{"annotation":"men holding hands: medium skin tone, medium-dark skin tone","group":1,"hexcode":"1F468-1F3FD-200D-1F91D-200D-1F468-1F3FE","order":2622,"unicode":"👨🏽‍🤝‍👨🏾"},{"annotation":"men holding hands: medium skin tone, dark skin tone","group":1,"hexcode":"1F468-1F3FD-200D-1F91D-200D-1F468-1F3FF","order":2623,"unicode":"👨🏽‍🤝‍👨🏿"},{"annotation":"men holding hands: medium-dark skin tone, light skin tone","group":1,"hexcode":"1F468-1F3FE-200D-1F91D-200D-1F468-1F3FB","order":2624,"unicode":"👨🏾‍🤝‍👨🏻"},{"annotation":"men holding hands: medium-dark skin tone, medium-light skin tone","group":1,"hexcode":"1F468-1F3FE-200D-1F91D-200D-1F468-1F3FC","order":2625,"unicode":"👨🏾‍🤝‍👨🏼"},{"annotation":"men holding hands: medium-dark skin tone, medium skin tone","group":1,"hexcode":"1F468-1F3FE-200D-1F91D-200D-1F468-1F3FD","order":2626,"unicode":"👨🏾‍🤝‍👨🏽"},{"annotation":"men holding hands: medium-dark skin tone, dark skin tone","group":1,"hexcode":"1F468-1F3FE-200D-1F91D-200D-1F468-1F3FF","order":2628,"unicode":"👨🏾‍🤝‍👨🏿"},{"annotation":"men holding hands: dark skin tone, light skin tone","group":1,"hexcode":"1F468-1F3FF-200D-1F91D-200D-1F468-1F3FB","order":2629,"unicode":"👨🏿‍🤝‍👨🏻"},{"annotation":"men holding hands: dark skin tone, medium-light skin tone","group":1,"hexcode":"1F468-1F3FF-200D-1F91D-200D-1F468-1F3FC","order":2630,"unicode":"👨🏿‍🤝‍👨🏼"},{"annotation":"men holding hands: dark skin tone, medium skin tone","group":1,"hexcode":"1F468-1F3FF-200D-1F91D-200D-1F468-1F3FD","order":2631,"unicode":"👨🏿‍🤝‍👨🏽"},{"annotation":"men holding hands: dark skin tone, medium-dark skin tone","group":1,"hexcode":"1F468-1F3FF-200D-1F91D-200D-1F468-1F3FE","order":2632,"unicode":"👨🏿‍🤝‍👨🏾"}]},{"annotation":"kiss","group":1,"hexcode":"1F48F","order":2634,"tags":["couple"],"unicode":"💏","skins":[{"annotation":"kiss: light skin tone","group":1,"hexcode":"1F48F-1F3FB","order":2635,"unicode":"💏🏻"},{"annotation":"kiss: medium-light skin tone","group":1,"hexcode":"1F48F-1F3FC","order":2636,"unicode":"💏🏼"},{"annotation":"kiss: medium skin tone","group":1,"hexcode":"1F48F-1F3FD","order":2637,"unicode":"💏🏽"},{"annotation":"kiss: medium-dark skin tone","group":1,"hexcode":"1F48F-1F3FE","order":2638,"unicode":"💏🏾"},{"annotation":"kiss: dark skin tone","group":1,"hexcode":"1F48F-1F3FF","order":2639,"unicode":"💏🏿"},{"annotation":"kiss: person, person, light skin tone, medium-light skin tone","group":1,"hexcode":"1F9D1-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FC","order":2640,"unicode":"🧑🏻‍❤️‍💋‍🧑🏼"},{"annotation":"kiss: person, person, light skin tone, medium skin tone","group":1,"hexcode":"1F9D1-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FD","order":2642,"unicode":"🧑🏻‍❤️‍💋‍🧑🏽"},{"annotation":"kiss: person, person, light skin tone, medium-dark skin tone","group":1,"hexcode":"1F9D1-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FE","order":2644,"unicode":"🧑🏻‍❤️‍💋‍🧑🏾"},{"annotation":"kiss: person, person, light skin tone, dark skin tone","group":1,"hexcode":"1F9D1-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FF","order":2646,"unicode":"🧑🏻‍❤️‍💋‍🧑🏿"},{"annotation":"kiss: person, person, medium-light skin tone, light skin tone","group":1,"hexcode":"1F9D1-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FB","order":2648,"unicode":"🧑🏼‍❤️‍💋‍🧑🏻"},{"annotation":"kiss: person, person, medium-light skin tone, medium skin tone","group":1,"hexcode":"1F9D1-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FD","order":2650,"unicode":"🧑🏼‍❤️‍💋‍🧑🏽"},{"annotation":"kiss: person, person, medium-light skin tone, medium-dark skin tone","group":1,"hexcode":"1F9D1-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FE","order":2652,"unicode":"🧑🏼‍❤️‍💋‍🧑🏾"},{"annotation":"kiss: person, person, medium-light skin tone, dark skin tone","group":1,"hexcode":"1F9D1-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FF","order":2654,"unicode":"🧑🏼‍❤️‍💋‍🧑🏿"},{"annotation":"kiss: person, person, medium skin tone, light skin tone","group":1,"hexcode":"1F9D1-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FB","order":2656,"unicode":"🧑🏽‍❤️‍💋‍🧑🏻"},{"annotation":"kiss: person, person, medium skin tone, medium-light skin tone","group":1,"hexcode":"1F9D1-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FC","order":2658,"unicode":"🧑🏽‍❤️‍💋‍🧑🏼"},{"annotation":"kiss: person, person, medium skin tone, medium-dark skin tone","group":1,"hexcode":"1F9D1-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FE","order":2660,"unicode":"🧑🏽‍❤️‍💋‍🧑🏾"},{"annotation":"kiss: person, person, medium skin tone, dark skin tone","group":1,"hexcode":"1F9D1-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FF","order":2662,"unicode":"🧑🏽‍❤️‍💋‍🧑🏿"},{"annotation":"kiss: person, person, medium-dark skin tone, light skin tone","group":1,"hexcode":"1F9D1-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FB","order":2664,"unicode":"🧑🏾‍❤️‍💋‍🧑🏻"},{"annotation":"kiss: person, person, medium-dark skin tone, medium-light skin tone","group":1,"hexcode":"1F9D1-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FC","order":2666,"unicode":"🧑🏾‍❤️‍💋‍🧑🏼"},{"annotation":"kiss: person, person, medium-dark skin tone, medium skin tone","group":1,"hexcode":"1F9D1-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FD","order":2668,"unicode":"🧑🏾‍❤️‍💋‍🧑🏽"},{"annotation":"kiss: person, person, medium-dark skin tone, dark skin tone","group":1,"hexcode":"1F9D1-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FF","order":2670,"unicode":"🧑🏾‍❤️‍💋‍🧑🏿"},{"annotation":"kiss: person, person, dark skin tone, light skin tone","group":1,"hexcode":"1F9D1-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FB","order":2672,"unicode":"🧑🏿‍❤️‍💋‍🧑🏻"},{"annotation":"kiss: person, person, dark skin tone, medium-light skin tone","group":1,"hexcode":"1F9D1-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FC","order":2674,"unicode":"🧑🏿‍❤️‍💋‍🧑🏼"},{"annotation":"kiss: person, person, dark skin tone, medium skin tone","group":1,"hexcode":"1F9D1-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FD","order":2676,"unicode":"🧑🏿‍❤️‍💋‍🧑🏽"},{"annotation":"kiss: person, person, dark skin tone, medium-dark skin tone","group":1,"hexcode":"1F9D1-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FE","order":2678,"unicode":"🧑🏿‍❤️‍💋‍🧑🏾"}]},{"annotation":"kiss: woman, man","group":1,"hexcode":"1F469-200D-2764-FE0F-200D-1F48B-200D-1F468","order":2680,"tags":["couple","kiss","man","woman"],"unicode":"👩‍❤️‍💋‍👨","skins":[{"annotation":"kiss: woman, man, light skin tone","group":1,"hexcode":"1F469-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FB","order":2682,"unicode":"👩🏻‍❤️‍💋‍👨🏻"},{"annotation":"kiss: woman, man, light skin tone, medium-light skin tone","group":1,"hexcode":"1F469-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FC","order":2684,"unicode":"👩🏻‍❤️‍💋‍👨🏼"},{"annotation":"kiss: woman, man, light skin tone, medium skin tone","group":1,"hexcode":"1F469-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FD","order":2686,"unicode":"👩🏻‍❤️‍💋‍👨🏽"},{"annotation":"kiss: woman, man, light skin tone, medium-dark skin tone","group":1,"hexcode":"1F469-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FE","order":2688,"unicode":"👩🏻‍❤️‍💋‍👨🏾"},{"annotation":"kiss: woman, man, light skin tone, dark skin tone","group":1,"hexcode":"1F469-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FF","order":2690,"unicode":"👩🏻‍❤️‍💋‍👨🏿"},{"annotation":"kiss: woman, man, medium-light skin tone, light skin tone","group":1,"hexcode":"1F469-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FB","order":2692,"unicode":"👩🏼‍❤️‍💋‍👨🏻"},{"annotation":"kiss: woman, man, medium-light skin tone","group":1,"hexcode":"1F469-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FC","order":2694,"unicode":"👩🏼‍❤️‍💋‍👨🏼"},{"annotation":"kiss: woman, man, medium-light skin tone, medium skin tone","group":1,"hexcode":"1F469-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FD","order":2696,"unicode":"👩🏼‍❤️‍💋‍👨🏽"},{"annotation":"kiss: woman, man, medium-light skin tone, medium-dark skin tone","group":1,"hexcode":"1F469-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FE","order":2698,"unicode":"👩🏼‍❤️‍💋‍👨🏾"},{"annotation":"kiss: woman, man, medium-light skin tone, dark skin tone","group":1,"hexcode":"1F469-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FF","order":2700,"unicode":"👩🏼‍❤️‍💋‍👨🏿"},{"annotation":"kiss: woman, man, medium skin tone, light skin tone","group":1,"hexcode":"1F469-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FB","order":2702,"unicode":"👩🏽‍❤️‍💋‍👨🏻"},{"annotation":"kiss: woman, man, medium skin tone, medium-light skin tone","group":1,"hexcode":"1F469-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FC","order":2704,"unicode":"👩🏽‍❤️‍💋‍👨🏼"},{"annotation":"kiss: woman, man, medium skin tone","group":1,"hexcode":"1F469-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FD","order":2706,"unicode":"👩🏽‍❤️‍💋‍👨🏽"},{"annotation":"kiss: woman, man, medium skin tone, medium-dark skin tone","group":1,"hexcode":"1F469-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FE","order":2708,"unicode":"👩🏽‍❤️‍💋‍👨🏾"},{"annotation":"kiss: woman, man, medium skin tone, dark skin tone","group":1,"hexcode":"1F469-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FF","order":2710,"unicode":"👩🏽‍❤️‍💋‍👨🏿"},{"annotation":"kiss: woman, man, medium-dark skin tone, light skin tone","group":1,"hexcode":"1F469-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FB","order":2712,"unicode":"👩🏾‍❤️‍💋‍👨🏻"},{"annotation":"kiss: woman, man, medium-dark skin tone, medium-light skin tone","group":1,"hexcode":"1F469-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FC","order":2714,"unicode":"👩🏾‍❤️‍💋‍👨🏼"},{"annotation":"kiss: woman, man, medium-dark skin tone, medium skin tone","group":1,"hexcode":"1F469-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FD","order":2716,"unicode":"👩🏾‍❤️‍💋‍👨🏽"},{"annotation":"kiss: woman, man, medium-dark skin tone","group":1,"hexcode":"1F469-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FE","order":2718,"unicode":"👩🏾‍❤️‍💋‍👨🏾"},{"annotation":"kiss: woman, man, medium-dark skin tone, dark skin tone","group":1,"hexcode":"1F469-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FF","order":2720,"unicode":"👩🏾‍❤️‍💋‍👨🏿"},{"annotation":"kiss: woman, man, dark skin tone, light skin tone","group":1,"hexcode":"1F469-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FB","order":2722,"unicode":"👩🏿‍❤️‍💋‍👨🏻"},{"annotation":"kiss: woman, man, dark skin tone, medium-light skin tone","group":1,"hexcode":"1F469-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FC","order":2724,"unicode":"👩🏿‍❤️‍💋‍👨🏼"},{"annotation":"kiss: woman, man, dark skin tone, medium skin tone","group":1,"hexcode":"1F469-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FD","order":2726,"unicode":"👩🏿‍❤️‍💋‍👨🏽"},{"annotation":"kiss: woman, man, dark skin tone, medium-dark skin tone","group":1,"hexcode":"1F469-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FE","order":2728,"unicode":"👩🏿‍❤️‍💋‍👨🏾"},{"annotation":"kiss: woman, man, dark skin tone","group":1,"hexcode":"1F469-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FF","order":2730,"unicode":"👩🏿‍❤️‍💋‍👨🏿"}]},{"annotation":"kiss: man, man","group":1,"hexcode":"1F468-200D-2764-FE0F-200D-1F48B-200D-1F468","order":2732,"tags":["couple","kiss","man"],"unicode":"👨‍❤️‍💋‍👨","skins":[{"annotation":"kiss: man, man, light skin tone","group":1,"hexcode":"1F468-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FB","order":2734,"unicode":"👨🏻‍❤️‍💋‍👨🏻"},{"annotation":"kiss: man, man, light skin tone, medium-light skin tone","group":1,"hexcode":"1F468-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FC","order":2736,"unicode":"👨🏻‍❤️‍💋‍👨🏼"},{"annotation":"kiss: man, man, light skin tone, medium skin tone","group":1,"hexcode":"1F468-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FD","order":2738,"unicode":"👨🏻‍❤️‍💋‍👨🏽"},{"annotation":"kiss: man, man, light skin tone, medium-dark skin tone","group":1,"hexcode":"1F468-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FE","order":2740,"unicode":"👨🏻‍❤️‍💋‍👨🏾"},{"annotation":"kiss: man, man, light skin tone, dark skin tone","group":1,"hexcode":"1F468-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FF","order":2742,"unicode":"👨🏻‍❤️‍💋‍👨🏿"},{"annotation":"kiss: man, man, medium-light skin tone, light skin tone","group":1,"hexcode":"1F468-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FB","order":2744,"unicode":"👨🏼‍❤️‍💋‍👨🏻"},{"annotation":"kiss: man, man, medium-light skin tone","group":1,"hexcode":"1F468-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FC","order":2746,"unicode":"👨🏼‍❤️‍💋‍👨🏼"},{"annotation":"kiss: man, man, medium-light skin tone, medium skin tone","group":1,"hexcode":"1F468-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FD","order":2748,"unicode":"👨🏼‍❤️‍💋‍👨🏽"},{"annotation":"kiss: man, man, medium-light skin tone, medium-dark skin tone","group":1,"hexcode":"1F468-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FE","order":2750,"unicode":"👨🏼‍❤️‍💋‍👨🏾"},{"annotation":"kiss: man, man, medium-light skin tone, dark skin tone","group":1,"hexcode":"1F468-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FF","order":2752,"unicode":"👨🏼‍❤️‍💋‍👨🏿"},{"annotation":"kiss: man, man, medium skin tone, light skin tone","group":1,"hexcode":"1F468-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FB","order":2754,"unicode":"👨🏽‍❤️‍💋‍👨🏻"},{"annotation":"kiss: man, man, medium skin tone, medium-light skin tone","group":1,"hexcode":"1F468-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FC","order":2756,"unicode":"👨🏽‍❤️‍💋‍👨🏼"},{"annotation":"kiss: man, man, medium skin tone","group":1,"hexcode":"1F468-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FD","order":2758,"unicode":"👨🏽‍❤️‍💋‍👨🏽"},{"annotation":"kiss: man, man, medium skin tone, medium-dark skin tone","group":1,"hexcode":"1F468-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FE","order":2760,"unicode":"👨🏽‍❤️‍💋‍👨🏾"},{"annotation":"kiss: man, man, medium skin tone, dark skin tone","group":1,"hexcode":"1F468-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FF","order":2762,"unicode":"👨🏽‍❤️‍💋‍👨🏿"},{"annotation":"kiss: man, man, medium-dark skin tone, light skin tone","group":1,"hexcode":"1F468-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FB","order":2764,"unicode":"👨🏾‍❤️‍💋‍👨🏻"},{"annotation":"kiss: man, man, medium-dark skin tone, medium-light skin tone","group":1,"hexcode":"1F468-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FC","order":2766,"unicode":"👨🏾‍❤️‍💋‍👨🏼"},{"annotation":"kiss: man, man, medium-dark skin tone, medium skin tone","group":1,"hexcode":"1F468-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FD","order":2768,"unicode":"👨🏾‍❤️‍💋‍👨🏽"},{"annotation":"kiss: man, man, medium-dark skin tone","group":1,"hexcode":"1F468-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FE","order":2770,"unicode":"👨🏾‍❤️‍💋‍👨🏾"},{"annotation":"kiss: man, man, medium-dark skin tone, dark skin tone","group":1,"hexcode":"1F468-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FF","order":2772,"unicode":"👨🏾‍❤️‍💋‍👨🏿"},{"annotation":"kiss: man, man, dark skin tone, light skin tone","group":1,"hexcode":"1F468-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FB","order":2774,"unicode":"👨🏿‍❤️‍💋‍👨🏻"},{"annotation":"kiss: man, man, dark skin tone, medium-light skin tone","group":1,"hexcode":"1F468-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FC","order":2776,"unicode":"👨🏿‍❤️‍💋‍👨🏼"},{"annotation":"kiss: man, man, dark skin tone, medium skin tone","group":1,"hexcode":"1F468-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FD","order":2778,"unicode":"👨🏿‍❤️‍💋‍👨🏽"},{"annotation":"kiss: man, man, dark skin tone, medium-dark skin tone","group":1,"hexcode":"1F468-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FE","order":2780,"unicode":"👨🏿‍❤️‍💋‍👨🏾"},{"annotation":"kiss: man, man, dark skin tone","group":1,"hexcode":"1F468-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FF","order":2782,"unicode":"👨🏿‍❤️‍💋‍👨🏿"}]},{"annotation":"kiss: woman, woman","group":1,"hexcode":"1F469-200D-2764-FE0F-200D-1F48B-200D-1F469","order":2784,"tags":["couple","kiss","woman"],"unicode":"👩‍❤️‍💋‍👩","skins":[{"annotation":"kiss: woman, woman, light skin tone","group":1,"hexcode":"1F469-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FB","order":2786,"unicode":"👩🏻‍❤️‍💋‍👩🏻"},{"annotation":"kiss: woman, woman, light skin tone, medium-light skin tone","group":1,"hexcode":"1F469-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FC","order":2788,"unicode":"👩🏻‍❤️‍💋‍👩🏼"},{"annotation":"kiss: woman, woman, light skin tone, medium skin tone","group":1,"hexcode":"1F469-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FD","order":2790,"unicode":"👩🏻‍❤️‍💋‍👩🏽"},{"annotation":"kiss: woman, woman, light skin tone, medium-dark skin tone","group":1,"hexcode":"1F469-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FE","order":2792,"unicode":"👩🏻‍❤️‍💋‍👩🏾"},{"annotation":"kiss: woman, woman, light skin tone, dark skin tone","group":1,"hexcode":"1F469-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FF","order":2794,"unicode":"👩🏻‍❤️‍💋‍👩🏿"},{"annotation":"kiss: woman, woman, medium-light skin tone, light skin tone","group":1,"hexcode":"1F469-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FB","order":2796,"unicode":"👩🏼‍❤️‍💋‍👩🏻"},{"annotation":"kiss: woman, woman, medium-light skin tone","group":1,"hexcode":"1F469-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FC","order":2798,"unicode":"👩🏼‍❤️‍💋‍👩🏼"},{"annotation":"kiss: woman, woman, medium-light skin tone, medium skin tone","group":1,"hexcode":"1F469-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FD","order":2800,"unicode":"👩🏼‍❤️‍💋‍👩🏽"},{"annotation":"kiss: woman, woman, medium-light skin tone, medium-dark skin tone","group":1,"hexcode":"1F469-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FE","order":2802,"unicode":"👩🏼‍❤️‍💋‍👩🏾"},{"annotation":"kiss: woman, woman, medium-light skin tone, dark skin tone","group":1,"hexcode":"1F469-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FF","order":2804,"unicode":"👩🏼‍❤️‍💋‍👩🏿"},{"annotation":"kiss: woman, woman, medium skin tone, light skin tone","group":1,"hexcode":"1F469-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FB","order":2806,"unicode":"👩🏽‍❤️‍💋‍👩🏻"},{"annotation":"kiss: woman, woman, medium skin tone, medium-light skin tone","group":1,"hexcode":"1F469-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FC","order":2808,"unicode":"👩🏽‍❤️‍💋‍👩🏼"},{"annotation":"kiss: woman, woman, medium skin tone","group":1,"hexcode":"1F469-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FD","order":2810,"unicode":"👩🏽‍❤️‍💋‍👩🏽"},{"annotation":"kiss: woman, woman, medium skin tone, medium-dark skin tone","group":1,"hexcode":"1F469-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FE","order":2812,"unicode":"👩🏽‍❤️‍💋‍👩🏾"},{"annotation":"kiss: woman, woman, medium skin tone, dark skin tone","group":1,"hexcode":"1F469-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FF","order":2814,"unicode":"👩🏽‍❤️‍💋‍👩🏿"},{"annotation":"kiss: woman, woman, medium-dark skin tone, light skin tone","group":1,"hexcode":"1F469-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FB","order":2816,"unicode":"👩🏾‍❤️‍💋‍👩🏻"},{"annotation":"kiss: woman, woman, medium-dark skin tone, medium-light skin tone","group":1,"hexcode":"1F469-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FC","order":2818,"unicode":"👩🏾‍❤️‍💋‍👩🏼"},{"annotation":"kiss: woman, woman, medium-dark skin tone, medium skin tone","group":1,"hexcode":"1F469-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FD","order":2820,"unicode":"👩🏾‍❤️‍💋‍👩🏽"},{"annotation":"kiss: woman, woman, medium-dark skin tone","group":1,"hexcode":"1F469-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FE","order":2822,"unicode":"👩🏾‍❤️‍💋‍👩🏾"},{"annotation":"kiss: woman, woman, medium-dark skin tone, dark skin tone","group":1,"hexcode":"1F469-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FF","order":2824,"unicode":"👩🏾‍❤️‍💋‍👩🏿"},{"annotation":"kiss: woman, woman, dark skin tone, light skin tone","group":1,"hexcode":"1F469-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FB","order":2826,"unicode":"👩🏿‍❤️‍💋‍👩🏻"},{"annotation":"kiss: woman, woman, dark skin tone, medium-light skin tone","group":1,"hexcode":"1F469-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FC","order":2828,"unicode":"👩🏿‍❤️‍💋‍👩🏼"},{"annotation":"kiss: woman, woman, dark skin tone, medium skin tone","group":1,"hexcode":"1F469-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FD","order":2830,"unicode":"👩🏿‍❤️‍💋‍👩🏽"},{"annotation":"kiss: woman, woman, dark skin tone, medium-dark skin tone","group":1,"hexcode":"1F469-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FE","order":2832,"unicode":"👩🏿‍❤️‍💋‍👩🏾"},{"annotation":"kiss: woman, woman, dark skin tone","group":1,"hexcode":"1F469-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FF","order":2834,"unicode":"👩🏿‍❤️‍💋‍👩🏿"}]},{"annotation":"couple with heart","group":1,"hexcode":"1F491","order":2836,"tags":["couple","love"],"unicode":"💑","skins":[{"annotation":"couple with heart: light skin tone","group":1,"hexcode":"1F491-1F3FB","order":2837,"unicode":"💑🏻"},{"annotation":"couple with heart: medium-light skin tone","group":1,"hexcode":"1F491-1F3FC","order":2838,"unicode":"💑🏼"},{"annotation":"couple with heart: medium skin tone","group":1,"hexcode":"1F491-1F3FD","order":2839,"unicode":"💑🏽"},{"annotation":"couple with heart: medium-dark skin tone","group":1,"hexcode":"1F491-1F3FE","order":2840,"unicode":"💑🏾"},{"annotation":"couple with heart: dark skin tone","group":1,"hexcode":"1F491-1F3FF","order":2841,"unicode":"💑🏿"},{"annotation":"couple with heart: person, person, light skin tone, medium-light skin tone","group":1,"hexcode":"1F9D1-1F3FB-200D-2764-FE0F-200D-1F9D1-1F3FC","order":2842,"unicode":"🧑🏻‍❤️‍🧑🏼"},{"annotation":"couple with heart: person, person, light skin tone, medium skin tone","group":1,"hexcode":"1F9D1-1F3FB-200D-2764-FE0F-200D-1F9D1-1F3FD","order":2844,"unicode":"🧑🏻‍❤️‍🧑🏽"},{"annotation":"couple with heart: person, person, light skin tone, medium-dark skin tone","group":1,"hexcode":"1F9D1-1F3FB-200D-2764-FE0F-200D-1F9D1-1F3FE","order":2846,"unicode":"🧑🏻‍❤️‍🧑🏾"},{"annotation":"couple with heart: person, person, light skin tone, dark skin tone","group":1,"hexcode":"1F9D1-1F3FB-200D-2764-FE0F-200D-1F9D1-1F3FF","order":2848,"unicode":"🧑🏻‍❤️‍🧑🏿"},{"annotation":"couple with heart: person, person, medium-light skin tone, light skin tone","group":1,"hexcode":"1F9D1-1F3FC-200D-2764-FE0F-200D-1F9D1-1F3FB","order":2850,"unicode":"🧑🏼‍❤️‍🧑🏻"},{"annotation":"couple with heart: person, person, medium-light skin tone, medium skin tone","group":1,"hexcode":"1F9D1-1F3FC-200D-2764-FE0F-200D-1F9D1-1F3FD","order":2852,"unicode":"🧑🏼‍❤️‍🧑🏽"},{"annotation":"couple with heart: person, person, medium-light skin tone, medium-dark skin tone","group":1,"hexcode":"1F9D1-1F3FC-200D-2764-FE0F-200D-1F9D1-1F3FE","order":2854,"unicode":"🧑🏼‍❤️‍🧑🏾"},{"annotation":"couple with heart: person, person, medium-light skin tone, dark skin tone","group":1,"hexcode":"1F9D1-1F3FC-200D-2764-FE0F-200D-1F9D1-1F3FF","order":2856,"unicode":"🧑🏼‍❤️‍🧑🏿"},{"annotation":"couple with heart: person, person, medium skin tone, light skin tone","group":1,"hexcode":"1F9D1-1F3FD-200D-2764-FE0F-200D-1F9D1-1F3FB","order":2858,"unicode":"🧑🏽‍❤️‍🧑🏻"},{"annotation":"couple with heart: person, person, medium skin tone, medium-light skin tone","group":1,"hexcode":"1F9D1-1F3FD-200D-2764-FE0F-200D-1F9D1-1F3FC","order":2860,"unicode":"🧑🏽‍❤️‍🧑🏼"},{"annotation":"couple with heart: person, person, medium skin tone, medium-dark skin tone","group":1,"hexcode":"1F9D1-1F3FD-200D-2764-FE0F-200D-1F9D1-1F3FE","order":2862,"unicode":"🧑🏽‍❤️‍🧑🏾"},{"annotation":"couple with heart: person, person, medium skin tone, dark skin tone","group":1,"hexcode":"1F9D1-1F3FD-200D-2764-FE0F-200D-1F9D1-1F3FF","order":2864,"unicode":"🧑🏽‍❤️‍🧑🏿"},{"annotation":"couple with heart: person, person, medium-dark skin tone, light skin tone","group":1,"hexcode":"1F9D1-1F3FE-200D-2764-FE0F-200D-1F9D1-1F3FB","order":2866,"unicode":"🧑🏾‍❤️‍🧑🏻"},{"annotation":"couple with heart: person, person, medium-dark skin tone, medium-light skin tone","group":1,"hexcode":"1F9D1-1F3FE-200D-2764-FE0F-200D-1F9D1-1F3FC","order":2868,"unicode":"🧑🏾‍❤️‍🧑🏼"},{"annotation":"couple with heart: person, person, medium-dark skin tone, medium skin tone","group":1,"hexcode":"1F9D1-1F3FE-200D-2764-FE0F-200D-1F9D1-1F3FD","order":2870,"unicode":"🧑🏾‍❤️‍🧑🏽"},{"annotation":"couple with heart: person, person, medium-dark skin tone, dark skin tone","group":1,"hexcode":"1F9D1-1F3FE-200D-2764-FE0F-200D-1F9D1-1F3FF","order":2872,"unicode":"🧑🏾‍❤️‍🧑🏿"},{"annotation":"couple with heart: person, person, dark skin tone, light skin tone","group":1,"hexcode":"1F9D1-1F3FF-200D-2764-FE0F-200D-1F9D1-1F3FB","order":2874,"unicode":"🧑🏿‍❤️‍🧑🏻"},{"annotation":"couple with heart: person, person, dark skin tone, medium-light skin tone","group":1,"hexcode":"1F9D1-1F3FF-200D-2764-FE0F-200D-1F9D1-1F3FC","order":2876,"unicode":"🧑🏿‍❤️‍🧑🏼"},{"annotation":"couple with heart: person, person, dark skin tone, medium skin tone","group":1,"hexcode":"1F9D1-1F3FF-200D-2764-FE0F-200D-1F9D1-1F3FD","order":2878,"unicode":"🧑🏿‍❤️‍🧑🏽"},{"annotation":"couple with heart: person, person, dark skin tone, medium-dark skin tone","group":1,"hexcode":"1F9D1-1F3FF-200D-2764-FE0F-200D-1F9D1-1F3FE","order":2880,"unicode":"🧑🏿‍❤️‍🧑🏾"}]},{"annotation":"couple with heart: woman, man","group":1,"hexcode":"1F469-200D-2764-FE0F-200D-1F468","order":2882,"tags":["couple","couple with heart","love","man","woman"],"unicode":"👩‍❤️‍👨","skins":[{"annotation":"couple with heart: woman, man, light skin tone","group":1,"hexcode":"1F469-1F3FB-200D-2764-FE0F-200D-1F468-1F3FB","order":2884,"unicode":"👩🏻‍❤️‍👨🏻"},{"annotation":"couple with heart: woman, man, light skin tone, medium-light skin tone","group":1,"hexcode":"1F469-1F3FB-200D-2764-FE0F-200D-1F468-1F3FC","order":2886,"unicode":"👩🏻‍❤️‍👨🏼"},{"annotation":"couple with heart: woman, man, light skin tone, medium skin tone","group":1,"hexcode":"1F469-1F3FB-200D-2764-FE0F-200D-1F468-1F3FD","order":2888,"unicode":"👩🏻‍❤️‍👨🏽"},{"annotation":"couple with heart: woman, man, light skin tone, medium-dark skin tone","group":1,"hexcode":"1F469-1F3FB-200D-2764-FE0F-200D-1F468-1F3FE","order":2890,"unicode":"👩🏻‍❤️‍👨🏾"},{"annotation":"couple with heart: woman, man, light skin tone, dark skin tone","group":1,"hexcode":"1F469-1F3FB-200D-2764-FE0F-200D-1F468-1F3FF","order":2892,"unicode":"👩🏻‍❤️‍👨🏿"},{"annotation":"couple with heart: woman, man, medium-light skin tone, light skin tone","group":1,"hexcode":"1F469-1F3FC-200D-2764-FE0F-200D-1F468-1F3FB","order":2894,"unicode":"👩🏼‍❤️‍👨🏻"},{"annotation":"couple with heart: woman, man, medium-light skin tone","group":1,"hexcode":"1F469-1F3FC-200D-2764-FE0F-200D-1F468-1F3FC","order":2896,"unicode":"👩🏼‍❤️‍👨🏼"},{"annotation":"couple with heart: woman, man, medium-light skin tone, medium skin tone","group":1,"hexcode":"1F469-1F3FC-200D-2764-FE0F-200D-1F468-1F3FD","order":2898,"unicode":"👩🏼‍❤️‍👨🏽"},{"annotation":"couple with heart: woman, man, medium-light skin tone, medium-dark skin tone","group":1,"hexcode":"1F469-1F3FC-200D-2764-FE0F-200D-1F468-1F3FE","order":2900,"unicode":"👩🏼‍❤️‍👨🏾"},{"annotation":"couple with heart: woman, man, medium-light skin tone, dark skin tone","group":1,"hexcode":"1F469-1F3FC-200D-2764-FE0F-200D-1F468-1F3FF","order":2902,"unicode":"👩🏼‍❤️‍👨🏿"},{"annotation":"couple with heart: woman, man, medium skin tone, light skin tone","group":1,"hexcode":"1F469-1F3FD-200D-2764-FE0F-200D-1F468-1F3FB","order":2904,"unicode":"👩🏽‍❤️‍👨🏻"},{"annotation":"couple with heart: woman, man, medium skin tone, medium-light skin tone","group":1,"hexcode":"1F469-1F3FD-200D-2764-FE0F-200D-1F468-1F3FC","order":2906,"unicode":"👩🏽‍❤️‍👨🏼"},{"annotation":"couple with heart: woman, man, medium skin tone","group":1,"hexcode":"1F469-1F3FD-200D-2764-FE0F-200D-1F468-1F3FD","order":2908,"unicode":"👩🏽‍❤️‍👨🏽"},{"annotation":"couple with heart: woman, man, medium skin tone, medium-dark skin tone","group":1,"hexcode":"1F469-1F3FD-200D-2764-FE0F-200D-1F468-1F3FE","order":2910,"unicode":"👩🏽‍❤️‍👨🏾"},{"annotation":"couple with heart: woman, man, medium skin tone, dark skin tone","group":1,"hexcode":"1F469-1F3FD-200D-2764-FE0F-200D-1F468-1F3FF","order":2912,"unicode":"👩🏽‍❤️‍👨🏿"},{"annotation":"couple with heart: woman, man, medium-dark skin tone, light skin tone","group":1,"hexcode":"1F469-1F3FE-200D-2764-FE0F-200D-1F468-1F3FB","order":2914,"unicode":"👩🏾‍❤️‍👨🏻"},{"annotation":"couple with heart: woman, man, medium-dark skin tone, medium-light skin tone","group":1,"hexcode":"1F469-1F3FE-200D-2764-FE0F-200D-1F468-1F3FC","order":2916,"unicode":"👩🏾‍❤️‍👨🏼"},{"annotation":"couple with heart: woman, man, medium-dark skin tone, medium skin tone","group":1,"hexcode":"1F469-1F3FE-200D-2764-FE0F-200D-1F468-1F3FD","order":2918,"unicode":"👩🏾‍❤️‍👨🏽"},{"annotation":"couple with heart: woman, man, medium-dark skin tone","group":1,"hexcode":"1F469-1F3FE-200D-2764-FE0F-200D-1F468-1F3FE","order":2920,"unicode":"👩🏾‍❤️‍👨🏾"},{"annotation":"couple with heart: woman, man, medium-dark skin tone, dark skin tone","group":1,"hexcode":"1F469-1F3FE-200D-2764-FE0F-200D-1F468-1F3FF","order":2922,"unicode":"👩🏾‍❤️‍👨🏿"},{"annotation":"couple with heart: woman, man, dark skin tone, light skin tone","group":1,"hexcode":"1F469-1F3FF-200D-2764-FE0F-200D-1F468-1F3FB","order":2924,"unicode":"👩🏿‍❤️‍👨🏻"},{"annotation":"couple with heart: woman, man, dark skin tone, medium-light skin tone","group":1,"hexcode":"1F469-1F3FF-200D-2764-FE0F-200D-1F468-1F3FC","order":2926,"unicode":"👩🏿‍❤️‍👨🏼"},{"annotation":"couple with heart: woman, man, dark skin tone, medium skin tone","group":1,"hexcode":"1F469-1F3FF-200D-2764-FE0F-200D-1F468-1F3FD","order":2928,"unicode":"👩🏿‍❤️‍👨🏽"},{"annotation":"couple with heart: woman, man, dark skin tone, medium-dark skin tone","group":1,"hexcode":"1F469-1F3FF-200D-2764-FE0F-200D-1F468-1F3FE","order":2930,"unicode":"👩🏿‍❤️‍👨🏾"},{"annotation":"couple with heart: woman, man, dark skin tone","group":1,"hexcode":"1F469-1F3FF-200D-2764-FE0F-200D-1F468-1F3FF","order":2932,"unicode":"👩🏿‍❤️‍👨🏿"}]},{"annotation":"couple with heart: man, man","group":1,"hexcode":"1F468-200D-2764-FE0F-200D-1F468","order":2934,"tags":["couple","couple with heart","love","man"],"unicode":"👨‍❤️‍👨","skins":[{"annotation":"couple with heart: man, man, light skin tone","group":1,"hexcode":"1F468-1F3FB-200D-2764-FE0F-200D-1F468-1F3FB","order":2936,"unicode":"👨🏻‍❤️‍👨🏻"},{"annotation":"couple with heart: man, man, light skin tone, medium-light skin tone","group":1,"hexcode":"1F468-1F3FB-200D-2764-FE0F-200D-1F468-1F3FC","order":2938,"unicode":"👨🏻‍❤️‍👨🏼"},{"annotation":"couple with heart: man, man, light skin tone, medium skin tone","group":1,"hexcode":"1F468-1F3FB-200D-2764-FE0F-200D-1F468-1F3FD","order":2940,"unicode":"👨🏻‍❤️‍👨🏽"},{"annotation":"couple with heart: man, man, light skin tone, medium-dark skin tone","group":1,"hexcode":"1F468-1F3FB-200D-2764-FE0F-200D-1F468-1F3FE","order":2942,"unicode":"👨🏻‍❤️‍👨🏾"},{"annotation":"couple with heart: man, man, light skin tone, dark skin tone","group":1,"hexcode":"1F468-1F3FB-200D-2764-FE0F-200D-1F468-1F3FF","order":2944,"unicode":"👨🏻‍❤️‍👨🏿"},{"annotation":"couple with heart: man, man, medium-light skin tone, light skin tone","group":1,"hexcode":"1F468-1F3FC-200D-2764-FE0F-200D-1F468-1F3FB","order":2946,"unicode":"👨🏼‍❤️‍👨🏻"},{"annotation":"couple with heart: man, man, medium-light skin tone","group":1,"hexcode":"1F468-1F3FC-200D-2764-FE0F-200D-1F468-1F3FC","order":2948,"unicode":"👨🏼‍❤️‍👨🏼"},{"annotation":"couple with heart: man, man, medium-light skin tone, medium skin tone","group":1,"hexcode":"1F468-1F3FC-200D-2764-FE0F-200D-1F468-1F3FD","order":2950,"unicode":"👨🏼‍❤️‍👨🏽"},{"annotation":"couple with heart: man, man, medium-light skin tone, medium-dark skin tone","group":1,"hexcode":"1F468-1F3FC-200D-2764-FE0F-200D-1F468-1F3FE","order":2952,"unicode":"👨🏼‍❤️‍👨🏾"},{"annotation":"couple with heart: man, man, medium-light skin tone, dark skin tone","group":1,"hexcode":"1F468-1F3FC-200D-2764-FE0F-200D-1F468-1F3FF","order":2954,"unicode":"👨🏼‍❤️‍👨🏿"},{"annotation":"couple with heart: man, man, medium skin tone, light skin tone","group":1,"hexcode":"1F468-1F3FD-200D-2764-FE0F-200D-1F468-1F3FB","order":2956,"unicode":"👨🏽‍❤️‍👨🏻"},{"annotation":"couple with heart: man, man, medium skin tone, medium-light skin tone","group":1,"hexcode":"1F468-1F3FD-200D-2764-FE0F-200D-1F468-1F3FC","order":2958,"unicode":"👨🏽‍❤️‍👨🏼"},{"annotation":"couple with heart: man, man, medium skin tone","group":1,"hexcode":"1F468-1F3FD-200D-2764-FE0F-200D-1F468-1F3FD","order":2960,"unicode":"👨🏽‍❤️‍👨🏽"},{"annotation":"couple with heart: man, man, medium skin tone, medium-dark skin tone","group":1,"hexcode":"1F468-1F3FD-200D-2764-FE0F-200D-1F468-1F3FE","order":2962,"unicode":"👨🏽‍❤️‍👨🏾"},{"annotation":"couple with heart: man, man, medium skin tone, dark skin tone","group":1,"hexcode":"1F468-1F3FD-200D-2764-FE0F-200D-1F468-1F3FF","order":2964,"unicode":"👨🏽‍❤️‍👨🏿"},{"annotation":"couple with heart: man, man, medium-dark skin tone, light skin tone","group":1,"hexcode":"1F468-1F3FE-200D-2764-FE0F-200D-1F468-1F3FB","order":2966,"unicode":"👨🏾‍❤️‍👨🏻"},{"annotation":"couple with heart: man, man, medium-dark skin tone, medium-light skin tone","group":1,"hexcode":"1F468-1F3FE-200D-2764-FE0F-200D-1F468-1F3FC","order":2968,"unicode":"👨🏾‍❤️‍👨🏼"},{"annotation":"couple with heart: man, man, medium-dark skin tone, medium skin tone","group":1,"hexcode":"1F468-1F3FE-200D-2764-FE0F-200D-1F468-1F3FD","order":2970,"unicode":"👨🏾‍❤️‍👨🏽"},{"annotation":"couple with heart: man, man, medium-dark skin tone","group":1,"hexcode":"1F468-1F3FE-200D-2764-FE0F-200D-1F468-1F3FE","order":2972,"unicode":"👨🏾‍❤️‍👨🏾"},{"annotation":"couple with heart: man, man, medium-dark skin tone, dark skin tone","group":1,"hexcode":"1F468-1F3FE-200D-2764-FE0F-200D-1F468-1F3FF","order":2974,"unicode":"👨🏾‍❤️‍👨🏿"},{"annotation":"couple with heart: man, man, dark skin tone, light skin tone","group":1,"hexcode":"1F468-1F3FF-200D-2764-FE0F-200D-1F468-1F3FB","order":2976,"unicode":"👨🏿‍❤️‍👨🏻"},{"annotation":"couple with heart: man, man, dark skin tone, medium-light skin tone","group":1,"hexcode":"1F468-1F3FF-200D-2764-FE0F-200D-1F468-1F3FC","order":2978,"unicode":"👨🏿‍❤️‍👨🏼"},{"annotation":"couple with heart: man, man, dark skin tone, medium skin tone","group":1,"hexcode":"1F468-1F3FF-200D-2764-FE0F-200D-1F468-1F3FD","order":2980,"unicode":"👨🏿‍❤️‍👨🏽"},{"annotation":"couple with heart: man, man, dark skin tone, medium-dark skin tone","group":1,"hexcode":"1F468-1F3FF-200D-2764-FE0F-200D-1F468-1F3FE","order":2982,"unicode":"👨🏿‍❤️‍👨🏾"},{"annotation":"couple with heart: man, man, dark skin tone","group":1,"hexcode":"1F468-1F3FF-200D-2764-FE0F-200D-1F468-1F3FF","order":2984,"unicode":"👨🏿‍❤️‍👨🏿"}]},{"annotation":"couple with heart: woman, woman","group":1,"hexcode":"1F469-200D-2764-FE0F-200D-1F469","order":2986,"tags":["couple","couple with heart","love","woman"],"unicode":"👩‍❤️‍👩","skins":[{"annotation":"couple with heart: woman, woman, light skin tone","group":1,"hexcode":"1F469-1F3FB-200D-2764-FE0F-200D-1F469-1F3FB","order":2988,"unicode":"👩🏻‍❤️‍👩🏻"},{"annotation":"couple with heart: woman, woman, light skin tone, medium-light skin tone","group":1,"hexcode":"1F469-1F3FB-200D-2764-FE0F-200D-1F469-1F3FC","order":2990,"unicode":"👩🏻‍❤️‍👩🏼"},{"annotation":"couple with heart: woman, woman, light skin tone, medium skin tone","group":1,"hexcode":"1F469-1F3FB-200D-2764-FE0F-200D-1F469-1F3FD","order":2992,"unicode":"👩🏻‍❤️‍👩🏽"},{"annotation":"couple with heart: woman, woman, light skin tone, medium-dark skin tone","group":1,"hexcode":"1F469-1F3FB-200D-2764-FE0F-200D-1F469-1F3FE","order":2994,"unicode":"👩🏻‍❤️‍👩🏾"},{"annotation":"couple with heart: woman, woman, light skin tone, dark skin tone","group":1,"hexcode":"1F469-1F3FB-200D-2764-FE0F-200D-1F469-1F3FF","order":2996,"unicode":"👩🏻‍❤️‍👩🏿"},{"annotation":"couple with heart: woman, woman, medium-light skin tone, light skin tone","group":1,"hexcode":"1F469-1F3FC-200D-2764-FE0F-200D-1F469-1F3FB","order":2998,"unicode":"👩🏼‍❤️‍👩🏻"},{"annotation":"couple with heart: woman, woman, medium-light skin tone","group":1,"hexcode":"1F469-1F3FC-200D-2764-FE0F-200D-1F469-1F3FC","order":3000,"unicode":"👩🏼‍❤️‍👩🏼"},{"annotation":"couple with heart: woman, woman, medium-light skin tone, medium skin tone","group":1,"hexcode":"1F469-1F3FC-200D-2764-FE0F-200D-1F469-1F3FD","order":3002,"unicode":"👩🏼‍❤️‍👩🏽"},{"annotation":"couple with heart: woman, woman, medium-light skin tone, medium-dark skin tone","group":1,"hexcode":"1F469-1F3FC-200D-2764-FE0F-200D-1F469-1F3FE","order":3004,"unicode":"👩🏼‍❤️‍👩🏾"},{"annotation":"couple with heart: woman, woman, medium-light skin tone, dark skin tone","group":1,"hexcode":"1F469-1F3FC-200D-2764-FE0F-200D-1F469-1F3FF","order":3006,"unicode":"👩🏼‍❤️‍👩🏿"},{"annotation":"couple with heart: woman, woman, medium skin tone, light skin tone","group":1,"hexcode":"1F469-1F3FD-200D-2764-FE0F-200D-1F469-1F3FB","order":3008,"unicode":"👩🏽‍❤️‍👩🏻"},{"annotation":"couple with heart: woman, woman, medium skin tone, medium-light skin tone","group":1,"hexcode":"1F469-1F3FD-200D-2764-FE0F-200D-1F469-1F3FC","order":3010,"unicode":"👩🏽‍❤️‍👩🏼"},{"annotation":"couple with heart: woman, woman, medium skin tone","group":1,"hexcode":"1F469-1F3FD-200D-2764-FE0F-200D-1F469-1F3FD","order":3012,"unicode":"👩🏽‍❤️‍👩🏽"},{"annotation":"couple with heart: woman, woman, medium skin tone, medium-dark skin tone","group":1,"hexcode":"1F469-1F3FD-200D-2764-FE0F-200D-1F469-1F3FE","order":3014,"unicode":"👩🏽‍❤️‍👩🏾"},{"annotation":"couple with heart: woman, woman, medium skin tone, dark skin tone","group":1,"hexcode":"1F469-1F3FD-200D-2764-FE0F-200D-1F469-1F3FF","order":3016,"unicode":"👩🏽‍❤️‍👩🏿"},{"annotation":"couple with heart: woman, woman, medium-dark skin tone, light skin tone","group":1,"hexcode":"1F469-1F3FE-200D-2764-FE0F-200D-1F469-1F3FB","order":3018,"unicode":"👩🏾‍❤️‍👩🏻"},{"annotation":"couple with heart: woman, woman, medium-dark skin tone, medium-light skin tone","group":1,"hexcode":"1F469-1F3FE-200D-2764-FE0F-200D-1F469-1F3FC","order":3020,"unicode":"👩🏾‍❤️‍👩🏼"},{"annotation":"couple with heart: woman, woman, medium-dark skin tone, medium skin tone","group":1,"hexcode":"1F469-1F3FE-200D-2764-FE0F-200D-1F469-1F3FD","order":3022,"unicode":"👩🏾‍❤️‍👩🏽"},{"annotation":"couple with heart: woman, woman, medium-dark skin tone","group":1,"hexcode":"1F469-1F3FE-200D-2764-FE0F-200D-1F469-1F3FE","order":3024,"unicode":"👩🏾‍❤️‍👩🏾"},{"annotation":"couple with heart: woman, woman, medium-dark skin tone, dark skin tone","group":1,"hexcode":"1F469-1F3FE-200D-2764-FE0F-200D-1F469-1F3FF","order":3026,"unicode":"👩🏾‍❤️‍👩🏿"},{"annotation":"couple with heart: woman, woman, dark skin tone, light skin tone","group":1,"hexcode":"1F469-1F3FF-200D-2764-FE0F-200D-1F469-1F3FB","order":3028,"unicode":"👩🏿‍❤️‍👩🏻"},{"annotation":"couple with heart: woman, woman, dark skin tone, medium-light skin tone","group":1,"hexcode":"1F469-1F3FF-200D-2764-FE0F-200D-1F469-1F3FC","order":3030,"unicode":"👩🏿‍❤️‍👩🏼"},{"annotation":"couple with heart: woman, woman, dark skin tone, medium skin tone","group":1,"hexcode":"1F469-1F3FF-200D-2764-FE0F-200D-1F469-1F3FD","order":3032,"unicode":"👩🏿‍❤️‍👩🏽"},{"annotation":"couple with heart: woman, woman, dark skin tone, medium-dark skin tone","group":1,"hexcode":"1F469-1F3FF-200D-2764-FE0F-200D-1F469-1F3FE","order":3034,"unicode":"👩🏿‍❤️‍👩🏾"},{"annotation":"couple with heart: woman, woman, dark skin tone","group":1,"hexcode":"1F469-1F3FF-200D-2764-FE0F-200D-1F469-1F3FF","order":3036,"unicode":"👩🏿‍❤️‍👩🏿"}]},{"annotation":"family","group":1,"hexcode":"1F46A","order":3038,"tags":["family"],"unicode":"👪️"},{"annotation":"family: man, woman, boy","group":1,"hexcode":"1F468-200D-1F469-200D-1F466","order":3039,"tags":["boy","family","man","woman"],"unicode":"👨‍👩‍👦"},{"annotation":"family: man, woman, girl","group":1,"hexcode":"1F468-200D-1F469-200D-1F467","order":3040,"tags":["family","girl","man","woman"],"unicode":"👨‍👩‍👧"},{"annotation":"family: man, woman, girl, boy","group":1,"hexcode":"1F468-200D-1F469-200D-1F467-200D-1F466","order":3041,"tags":["boy","family","girl","man","woman"],"unicode":"👨‍👩‍👧‍👦"},{"annotation":"family: man, woman, boy, boy","group":1,"hexcode":"1F468-200D-1F469-200D-1F466-200D-1F466","order":3042,"tags":["boy","family","man","woman"],"unicode":"👨‍👩‍👦‍👦"},{"annotation":"family: man, woman, girl, girl","group":1,"hexcode":"1F468-200D-1F469-200D-1F467-200D-1F467","order":3043,"tags":["family","girl","man","woman"],"unicode":"👨‍👩‍👧‍👧"},{"annotation":"family: man, man, boy","group":1,"hexcode":"1F468-200D-1F468-200D-1F466","order":3044,"tags":["boy","family","man"],"unicode":"👨‍👨‍👦"},{"annotation":"family: man, man, girl","group":1,"hexcode":"1F468-200D-1F468-200D-1F467","order":3045,"tags":["family","girl","man"],"unicode":"👨‍👨‍👧"},{"annotation":"family: man, man, girl, boy","group":1,"hexcode":"1F468-200D-1F468-200D-1F467-200D-1F466","order":3046,"tags":["boy","family","girl","man"],"unicode":"👨‍👨‍👧‍👦"},{"annotation":"family: man, man, boy, boy","group":1,"hexcode":"1F468-200D-1F468-200D-1F466-200D-1F466","order":3047,"tags":["boy","family","man"],"unicode":"👨‍👨‍👦‍👦"},{"annotation":"family: man, man, girl, girl","group":1,"hexcode":"1F468-200D-1F468-200D-1F467-200D-1F467","order":3048,"tags":["family","girl","man"],"unicode":"👨‍👨‍👧‍👧"},{"annotation":"family: woman, woman, boy","group":1,"hexcode":"1F469-200D-1F469-200D-1F466","order":3049,"tags":["boy","family","woman"],"unicode":"👩‍👩‍👦"},{"annotation":"family: woman, woman, girl","group":1,"hexcode":"1F469-200D-1F469-200D-1F467","order":3050,"tags":["family","girl","woman"],"unicode":"👩‍👩‍👧"},{"annotation":"family: woman, woman, girl, boy","group":1,"hexcode":"1F469-200D-1F469-200D-1F467-200D-1F466","order":3051,"tags":["boy","family","girl","woman"],"unicode":"👩‍👩‍👧‍👦"},{"annotation":"family: woman, woman, boy, boy","group":1,"hexcode":"1F469-200D-1F469-200D-1F466-200D-1F466","order":3052,"tags":["boy","family","woman"],"unicode":"👩‍👩‍👦‍👦"},{"annotation":"family: woman, woman, girl, girl","group":1,"hexcode":"1F469-200D-1F469-200D-1F467-200D-1F467","order":3053,"tags":["family","girl","woman"],"unicode":"👩‍👩‍👧‍👧"},{"annotation":"family: man, boy","group":1,"hexcode":"1F468-200D-1F466","order":3054,"tags":["boy","family","man"],"unicode":"👨‍👦"},{"annotation":"family: man, boy, boy","group":1,"hexcode":"1F468-200D-1F466-200D-1F466","order":3055,"tags":["boy","family","man"],"unicode":"👨‍👦‍👦"},{"annotation":"family: man, girl","group":1,"hexcode":"1F468-200D-1F467","order":3056,"tags":["family","girl","man"],"unicode":"👨‍👧"},{"annotation":"family: man, girl, boy","group":1,"hexcode":"1F468-200D-1F467-200D-1F466","order":3057,"tags":["boy","family","girl","man"],"unicode":"👨‍👧‍👦"},{"annotation":"family: man, girl, girl","group":1,"hexcode":"1F468-200D-1F467-200D-1F467","order":3058,"tags":["family","girl","man"],"unicode":"👨‍👧‍👧"},{"annotation":"family: woman, boy","group":1,"hexcode":"1F469-200D-1F466","order":3059,"tags":["boy","family","woman"],"unicode":"👩‍👦"},{"annotation":"family: woman, boy, boy","group":1,"hexcode":"1F469-200D-1F466-200D-1F466","order":3060,"tags":["boy","family","woman"],"unicode":"👩‍👦‍👦"},{"annotation":"family: woman, girl","group":1,"hexcode":"1F469-200D-1F467","order":3061,"tags":["family","girl","woman"],"unicode":"👩‍👧"},{"annotation":"family: woman, girl, boy","group":1,"hexcode":"1F469-200D-1F467-200D-1F466","order":3062,"tags":["boy","family","girl","woman"],"unicode":"👩‍👧‍👦"},{"annotation":"family: woman, girl, girl","group":1,"hexcode":"1F469-200D-1F467-200D-1F467","order":3063,"tags":["family","girl","woman"],"unicode":"👩‍👧‍👧"},{"annotation":"speaking head","group":1,"hexcode":"1F5E3","order":3065,"tags":["face","head","silhouette","speak","speaking"],"unicode":"🗣️"},{"annotation":"bust in silhouette","group":1,"hexcode":"1F464","order":3066,"tags":["bust","silhouette"],"unicode":"👤"},{"annotation":"busts in silhouette","group":1,"hexcode":"1F465","order":3067,"tags":["bust","silhouette"],"unicode":"👥"},{"annotation":"people hugging","group":1,"hexcode":"1FAC2","order":3068,"tags":["goodbye","hello","hug","thanks"],"unicode":"🫂"},{"annotation":"footprints","group":1,"hexcode":"1F463","order":3069,"tags":["clothing","footprint","print"],"unicode":"👣"},{"annotation":"light skin tone","group":2,"hexcode":"1F3FB","order":3070,"tags":["skin tone","type 1–2"],"unicode":"🏻"},{"annotation":"medium-light skin tone","group":2,"hexcode":"1F3FC","order":3071,"tags":["skin tone","type 3"],"unicode":"🏼"},{"annotation":"medium skin tone","group":2,"hexcode":"1F3FD","order":3072,"tags":["skin tone","type 4"],"unicode":"🏽"},{"annotation":"medium-dark skin tone","group":2,"hexcode":"1F3FE","order":3073,"tags":["skin tone","type 5"],"unicode":"🏾"},{"annotation":"dark skin tone","group":2,"hexcode":"1F3FF","order":3074,"tags":["skin tone","type 6"],"unicode":"🏿"},{"annotation":"red hair","group":2,"hexcode":"1F9B0","order":3075,"tags":["ginger","redhead"],"unicode":"🦰"},{"annotation":"curly hair","group":2,"hexcode":"1F9B1","order":3076,"tags":["afro","curly","ringlets"],"unicode":"🦱"},{"annotation":"white hair","group":2,"hexcode":"1F9B3","order":3077,"tags":["gray","hair","old","white"],"unicode":"🦳"},{"annotation":"bald","group":2,"hexcode":"1F9B2","order":3078,"tags":["chemotherapy","hairless","no hair","shaven"],"unicode":"🦲"},{"annotation":"monkey face","group":3,"hexcode":"1F435","order":3079,"tags":["face","monkey"],"unicode":"🐵"},{"annotation":"monkey","group":3,"hexcode":"1F412","order":3080,"tags":["monkey"],"unicode":"🐒"},{"annotation":"gorilla","group":3,"hexcode":"1F98D","order":3081,"tags":["gorilla"],"unicode":"🦍"},{"annotation":"orangutan","group":3,"hexcode":"1F9A7","order":3082,"tags":["ape"],"unicode":"🦧"},{"annotation":"dog face","group":3,"hexcode":"1F436","order":3083,"tags":["dog","face","pet"],"unicode":"🐶"},{"annotation":"dog","group":3,"hexcode":"1F415","order":3084,"tags":["pet"],"unicode":"🐕️"},{"annotation":"guide dog","group":3,"hexcode":"1F9AE","order":3085,"tags":["accessibility","blind","guide"],"unicode":"🦮"},{"annotation":"service dog","group":3,"hexcode":"1F415-200D-1F9BA","order":3086,"tags":["accessibility","assistance","dog","service"],"unicode":"🐕‍🦺"},{"annotation":"poodle","group":3,"hexcode":"1F429","order":3087,"tags":["dog"],"unicode":"🐩"},{"annotation":"wolf","group":3,"hexcode":"1F43A","order":3088,"tags":["face"],"unicode":"🐺"},{"annotation":"fox","group":3,"hexcode":"1F98A","order":3089,"tags":["face"],"unicode":"🦊"},{"annotation":"raccoon","group":3,"hexcode":"1F99D","order":3090,"tags":["curious","sly"],"unicode":"🦝"},{"annotation":"cat face","group":3,"hexcode":"1F431","order":3091,"tags":["cat","face","pet"],"unicode":"🐱"},{"annotation":"cat","group":3,"hexcode":"1F408","order":3092,"tags":["pet"],"unicode":"🐈️"},{"annotation":"black cat","group":3,"hexcode":"1F408-200D-2B1B","order":3093,"tags":["black","cat","unlucky"],"unicode":"🐈‍⬛"},{"annotation":"lion","group":3,"hexcode":"1F981","order":3094,"tags":["face","leo","zodiac"],"unicode":"🦁"},{"annotation":"tiger face","group":3,"hexcode":"1F42F","order":3095,"tags":["face","tiger"],"unicode":"🐯"},{"annotation":"tiger","group":3,"hexcode":"1F405","order":3096,"tags":["tiger"],"unicode":"🐅"},{"annotation":"leopard","group":3,"hexcode":"1F406","order":3097,"tags":["leopard"],"unicode":"🐆"},{"annotation":"horse face","group":3,"hexcode":"1F434","order":3098,"tags":["face","horse"],"unicode":"🐴"},{"annotation":"horse","group":3,"hexcode":"1F40E","order":3099,"tags":["equestrian","racehorse","racing"],"unicode":"🐎"},{"annotation":"unicorn","group":3,"hexcode":"1F984","order":3100,"tags":["face"],"unicode":"🦄"},{"annotation":"zebra","group":3,"hexcode":"1F993","order":3101,"tags":["stripe"],"unicode":"🦓"},{"annotation":"deer","group":3,"hexcode":"1F98C","order":3102,"tags":["deer"],"unicode":"🦌"},{"annotation":"bison","group":3,"hexcode":"1F9AC","order":3103,"tags":["buffalo","herd","wisent"],"unicode":"🦬"},{"annotation":"cow face","group":3,"hexcode":"1F42E","order":3104,"tags":["cow","face"],"unicode":"🐮"},{"annotation":"ox","group":3,"hexcode":"1F402","order":3105,"tags":["bull","taurus","zodiac"],"unicode":"🐂"},{"annotation":"water buffalo","group":3,"hexcode":"1F403","order":3106,"tags":["buffalo","water"],"unicode":"🐃"},{"annotation":"cow","group":3,"hexcode":"1F404","order":3107,"tags":["cow"],"unicode":"🐄"},{"annotation":"pig face","group":3,"hexcode":"1F437","order":3108,"tags":["face","pig"],"unicode":"🐷"},{"annotation":"pig","group":3,"hexcode":"1F416","order":3109,"tags":["sow"],"unicode":"🐖"},{"annotation":"boar","group":3,"hexcode":"1F417","order":3110,"tags":["pig"],"unicode":"🐗"},{"annotation":"pig nose","group":3,"hexcode":"1F43D","order":3111,"tags":["face","nose","pig"],"unicode":"🐽"},{"annotation":"ram","group":3,"hexcode":"1F40F","order":3112,"tags":["aries","male","sheep","zodiac"],"unicode":"🐏"},{"annotation":"ewe","group":3,"hexcode":"1F411","order":3113,"tags":["female","sheep"],"unicode":"🐑"},{"annotation":"goat","group":3,"hexcode":"1F410","order":3114,"tags":["capricorn","zodiac"],"unicode":"🐐"},{"annotation":"camel","group":3,"hexcode":"1F42A","order":3115,"tags":["dromedary","hump"],"unicode":"🐪"},{"annotation":"two-hump camel","group":3,"hexcode":"1F42B","order":3116,"tags":["bactrian","camel","hump"],"unicode":"🐫"},{"annotation":"llama","group":3,"hexcode":"1F999","order":3117,"tags":["alpaca","guanaco","vicuña","wool"],"unicode":"🦙"},{"annotation":"giraffe","group":3,"hexcode":"1F992","order":3118,"tags":["spots"],"unicode":"🦒"},{"annotation":"elephant","group":3,"hexcode":"1F418","order":3119,"tags":["elephant"],"unicode":"🐘"},{"annotation":"mammoth","group":3,"hexcode":"1F9A3","order":3120,"tags":["extinction","large","tusk","woolly"],"unicode":"🦣"},{"annotation":"rhinoceros","group":3,"hexcode":"1F98F","order":3121,"tags":["rhinoceros"],"unicode":"🦏"},{"annotation":"hippopotamus","group":3,"hexcode":"1F99B","order":3122,"tags":["hippo"],"unicode":"🦛"},{"annotation":"mouse face","group":3,"hexcode":"1F42D","order":3123,"tags":["face","mouse"],"unicode":"🐭"},{"annotation":"mouse","group":3,"hexcode":"1F401","order":3124,"tags":["mouse"],"unicode":"🐁"},{"annotation":"rat","group":3,"hexcode":"1F400","order":3125,"tags":["rat"],"unicode":"🐀"},{"annotation":"hamster","group":3,"hexcode":"1F439","order":3126,"tags":["face","pet"],"unicode":"🐹"},{"annotation":"rabbit face","group":3,"hexcode":"1F430","order":3127,"tags":["bunny","face","pet","rabbit"],"unicode":"🐰"},{"annotation":"rabbit","group":3,"hexcode":"1F407","order":3128,"tags":["bunny","pet"],"unicode":"🐇"},{"annotation":"chipmunk","group":3,"hexcode":"1F43F","order":3130,"tags":["squirrel"],"unicode":"🐿️"},{"annotation":"beaver","group":3,"hexcode":"1F9AB","order":3131,"tags":["dam"],"unicode":"🦫"},{"annotation":"hedgehog","group":3,"hexcode":"1F994","order":3132,"tags":["spiny"],"unicode":"🦔"},{"annotation":"bat","group":3,"hexcode":"1F987","order":3133,"tags":["vampire"],"unicode":"🦇"},{"annotation":"bear","group":3,"hexcode":"1F43B","order":3134,"tags":["face"],"unicode":"🐻"},{"annotation":"polar bear","group":3,"hexcode":"1F43B-200D-2744-FE0F","order":3135,"tags":["arctic","bear","white"],"unicode":"🐻‍❄️"},{"annotation":"koala","group":3,"hexcode":"1F428","order":3137,"tags":["bear"],"unicode":"🐨"},{"annotation":"panda","group":3,"hexcode":"1F43C","order":3138,"tags":["face"],"unicode":"🐼"},{"annotation":"sloth","group":3,"hexcode":"1F9A5","order":3139,"tags":["lazy","slow"],"unicode":"🦥"},{"annotation":"otter","group":3,"hexcode":"1F9A6","order":3140,"tags":["fishing","playful"],"unicode":"🦦"},{"annotation":"skunk","group":3,"hexcode":"1F9A8","order":3141,"tags":["stink"],"unicode":"🦨"},{"annotation":"kangaroo","group":3,"hexcode":"1F998","order":3142,"tags":["australia","joey","jump","marsupial"],"unicode":"🦘"},{"annotation":"badger","group":3,"hexcode":"1F9A1","order":3143,"tags":["honey badger","pester"],"unicode":"🦡"},{"annotation":"paw prints","group":3,"hexcode":"1F43E","order":3144,"tags":["feet","paw","print"],"unicode":"🐾"},{"annotation":"turkey","group":3,"hexcode":"1F983","order":3145,"tags":["bird"],"unicode":"🦃"},{"annotation":"chicken","group":3,"hexcode":"1F414","order":3146,"tags":["bird"],"unicode":"🐔"},{"annotation":"rooster","group":3,"hexcode":"1F413","order":3147,"tags":["bird"],"unicode":"🐓"},{"annotation":"hatching chick","group":3,"hexcode":"1F423","order":3148,"tags":["baby","bird","chick","hatching"],"unicode":"🐣"},{"annotation":"baby chick","group":3,"hexcode":"1F424","order":3149,"tags":["baby","bird","chick"],"unicode":"🐤"},{"annotation":"front-facing baby chick","group":3,"hexcode":"1F425","order":3150,"tags":["baby","bird","chick"],"unicode":"🐥"},{"annotation":"bird","group":3,"hexcode":"1F426","order":3151,"tags":["bird"],"unicode":"🐦️"},{"annotation":"penguin","group":3,"hexcode":"1F427","order":3152,"tags":["bird"],"unicode":"🐧"},{"annotation":"dove","group":3,"hexcode":"1F54A","order":3154,"tags":["bird","fly","peace"],"unicode":"🕊️"},{"annotation":"eagle","group":3,"hexcode":"1F985","order":3155,"tags":["bird"],"unicode":"🦅"},{"annotation":"duck","group":3,"hexcode":"1F986","order":3156,"tags":["bird"],"unicode":"🦆"},{"annotation":"swan","group":3,"hexcode":"1F9A2","order":3157,"tags":["bird","cygnet","ugly duckling"],"unicode":"🦢"},{"annotation":"owl","group":3,"hexcode":"1F989","order":3158,"tags":["bird","wise"],"unicode":"🦉"},{"annotation":"dodo","group":3,"hexcode":"1F9A4","order":3159,"tags":["extinction","large","mauritius"],"unicode":"🦤"},{"annotation":"feather","group":3,"hexcode":"1FAB6","order":3160,"tags":["bird","flight","light","plumage"],"unicode":"🪶"},{"annotation":"flamingo","group":3,"hexcode":"1F9A9","order":3161,"tags":["flamboyant","tropical"],"unicode":"🦩"},{"annotation":"peacock","group":3,"hexcode":"1F99A","order":3162,"tags":["bird","ostentatious","peahen","proud"],"unicode":"🦚"},{"annotation":"parrot","group":3,"hexcode":"1F99C","order":3163,"tags":["bird","pirate","talk"],"unicode":"🦜"},{"annotation":"frog","group":3,"hexcode":"1F438","order":3164,"tags":["face"],"unicode":"🐸"},{"annotation":"crocodile","group":3,"hexcode":"1F40A","order":3165,"tags":["crocodile"],"unicode":"🐊"},{"annotation":"turtle","group":3,"hexcode":"1F422","order":3166,"tags":["terrapin","tortoise"],"unicode":"🐢"},{"annotation":"lizard","group":3,"hexcode":"1F98E","order":3167,"tags":["reptile"],"unicode":"🦎"},{"annotation":"snake","group":3,"hexcode":"1F40D","order":3168,"tags":["bearer","ophiuchus","serpent","zodiac"],"unicode":"🐍"},{"annotation":"dragon face","group":3,"hexcode":"1F432","order":3169,"tags":["dragon","face","fairy tale"],"unicode":"🐲"},{"annotation":"dragon","group":3,"hexcode":"1F409","order":3170,"tags":["fairy tale"],"unicode":"🐉"},{"annotation":"sauropod","group":3,"hexcode":"1F995","order":3171,"tags":["brachiosaurus","brontosaurus","diplodocus"],"unicode":"🦕"},{"annotation":"T-Rex","group":3,"hexcode":"1F996","order":3172,"tags":["t-rex","tyrannosaurus rex"],"unicode":"🦖"},{"annotation":"spouting whale","group":3,"hexcode":"1F433","order":3173,"tags":["face","spouting","whale"],"unicode":"🐳"},{"annotation":"whale","group":3,"hexcode":"1F40B","order":3174,"tags":["whale"],"unicode":"🐋"},{"annotation":"dolphin","group":3,"hexcode":"1F42C","order":3175,"tags":["flipper"],"unicode":"🐬"},{"annotation":"seal","group":3,"hexcode":"1F9AD","order":3176,"tags":["sea lion"],"unicode":"🦭"},{"annotation":"fish","group":3,"hexcode":"1F41F","order":3177,"tags":["pisces","zodiac"],"unicode":"🐟️"},{"annotation":"tropical fish","group":3,"hexcode":"1F420","order":3178,"tags":["fish","tropical"],"unicode":"🐠"},{"annotation":"blowfish","group":3,"hexcode":"1F421","order":3179,"tags":["fish"],"unicode":"🐡"},{"annotation":"shark","group":3,"hexcode":"1F988","order":3180,"tags":["fish"],"unicode":"🦈"},{"annotation":"octopus","group":3,"hexcode":"1F419","order":3181,"tags":["octopus"],"unicode":"🐙"},{"annotation":"spiral shell","group":3,"hexcode":"1F41A","order":3182,"tags":["shell","spiral"],"unicode":"🐚"},{"annotation":"snail","group":3,"hexcode":"1F40C","order":3183,"tags":["snail"],"unicode":"🐌"},{"annotation":"butterfly","group":3,"hexcode":"1F98B","order":3184,"tags":["insect","pretty"],"unicode":"🦋"},{"annotation":"bug","group":3,"hexcode":"1F41B","order":3185,"tags":["insect"],"unicode":"🐛"},{"annotation":"ant","group":3,"hexcode":"1F41C","order":3186,"tags":["insect"],"unicode":"🐜"},{"annotation":"honeybee","group":3,"hexcode":"1F41D","order":3187,"tags":["bee","insect"],"unicode":"🐝"},{"annotation":"beetle","group":3,"hexcode":"1FAB2","order":3188,"tags":["bug","insect"],"unicode":"🪲"},{"annotation":"lady beetle","group":3,"hexcode":"1F41E","order":3189,"tags":["beetle","insect","ladybird","ladybug"],"unicode":"🐞"},{"annotation":"cricket","group":3,"hexcode":"1F997","order":3190,"tags":["grasshopper"],"unicode":"🦗"},{"annotation":"cockroach","group":3,"hexcode":"1FAB3","order":3191,"tags":["insect","pest","roach"],"unicode":"🪳"},{"annotation":"spider","group":3,"hexcode":"1F577","order":3193,"tags":["insect"],"unicode":"🕷️"},{"annotation":"spider web","group":3,"hexcode":"1F578","order":3195,"tags":["spider","web"],"unicode":"🕸️"},{"annotation":"scorpion","group":3,"hexcode":"1F982","order":3196,"tags":["scorpio","zodiac"],"unicode":"🦂"},{"annotation":"mosquito","group":3,"hexcode":"1F99F","order":3197,"tags":["disease","fever","malaria","pest","virus"],"unicode":"🦟"},{"annotation":"fly","group":3,"hexcode":"1FAB0","order":3198,"tags":["disease","maggot","pest","rotting"],"unicode":"🪰"},{"annotation":"worm","group":3,"hexcode":"1FAB1","order":3199,"tags":["annelid","earthworm","parasite"],"unicode":"🪱"},{"annotation":"microbe","group":3,"hexcode":"1F9A0","order":3200,"tags":["amoeba","bacteria","virus"],"unicode":"🦠"},{"annotation":"bouquet","group":3,"hexcode":"1F490","order":3201,"tags":["flower"],"unicode":"💐"},{"annotation":"cherry blossom","group":3,"hexcode":"1F338","order":3202,"tags":["blossom","cherry","flower"],"unicode":"🌸"},{"annotation":"white flower","group":3,"hexcode":"1F4AE","order":3203,"tags":["flower"],"unicode":"💮"},{"annotation":"rosette","group":3,"hexcode":"1F3F5","order":3205,"tags":["plant"],"unicode":"🏵️"},{"annotation":"rose","group":3,"hexcode":"1F339","order":3206,"tags":["flower"],"unicode":"🌹"},{"annotation":"wilted flower","group":3,"hexcode":"1F940","order":3207,"tags":["flower","wilted"],"unicode":"🥀"},{"annotation":"hibiscus","group":3,"hexcode":"1F33A","order":3208,"tags":["flower"],"unicode":"🌺"},{"annotation":"sunflower","group":3,"hexcode":"1F33B","order":3209,"tags":["flower","sun"],"unicode":"🌻"},{"annotation":"blossom","group":3,"hexcode":"1F33C","order":3210,"tags":["flower"],"unicode":"🌼"},{"annotation":"tulip","group":3,"hexcode":"1F337","order":3211,"tags":["flower"],"unicode":"🌷"},{"annotation":"seedling","group":3,"hexcode":"1F331","order":3212,"tags":["young"],"unicode":"🌱"},{"annotation":"potted plant","group":3,"hexcode":"1FAB4","order":3213,"tags":["boring","grow","house","nurturing","plant","useless"],"unicode":"🪴"},{"annotation":"evergreen tree","group":3,"hexcode":"1F332","order":3214,"tags":["tree"],"unicode":"🌲"},{"annotation":"deciduous tree","group":3,"hexcode":"1F333","order":3215,"tags":["deciduous","shedding","tree"],"unicode":"🌳"},{"annotation":"palm tree","group":3,"hexcode":"1F334","order":3216,"tags":["palm","tree"],"unicode":"🌴"},{"annotation":"cactus","group":3,"hexcode":"1F335","order":3217,"tags":["plant"],"unicode":"🌵"},{"annotation":"sheaf of rice","group":3,"hexcode":"1F33E","order":3218,"tags":["ear","grain","rice"],"unicode":"🌾"},{"annotation":"herb","group":3,"hexcode":"1F33F","order":3219,"tags":["leaf"],"unicode":"🌿"},{"annotation":"shamrock","group":3,"hexcode":"2618","order":3221,"tags":["plant"],"unicode":"☘️"},{"annotation":"four leaf clover","group":3,"hexcode":"1F340","order":3222,"tags":["4","clover","four","four-leaf clover","leaf"],"unicode":"🍀"},{"annotation":"maple leaf","group":3,"hexcode":"1F341","order":3223,"tags":["falling","leaf","maple"],"unicode":"🍁"},{"annotation":"fallen leaf","group":3,"hexcode":"1F342","order":3224,"tags":["falling","leaf"],"unicode":"🍂"},{"annotation":"leaf fluttering in wind","group":3,"hexcode":"1F343","order":3225,"tags":["blow","flutter","leaf","wind"],"unicode":"🍃"},{"annotation":"grapes","group":4,"hexcode":"1F347","order":3226,"tags":["fruit","grape"],"unicode":"🍇"},{"annotation":"melon","group":4,"hexcode":"1F348","order":3227,"tags":["fruit"],"unicode":"🍈"},{"annotation":"watermelon","group":4,"hexcode":"1F349","order":3228,"tags":["fruit"],"unicode":"🍉"},{"annotation":"tangerine","group":4,"hexcode":"1F34A","order":3229,"tags":["fruit","orange"],"unicode":"🍊"},{"annotation":"lemon","group":4,"hexcode":"1F34B","order":3230,"tags":["citrus","fruit"],"unicode":"🍋"},{"annotation":"banana","group":4,"hexcode":"1F34C","order":3231,"tags":["fruit"],"unicode":"🍌"},{"annotation":"pineapple","group":4,"hexcode":"1F34D","order":3232,"tags":["fruit"],"unicode":"🍍"},{"annotation":"mango","group":4,"hexcode":"1F96D","order":3233,"tags":["fruit","tropical"],"unicode":"🥭"},{"annotation":"red apple","group":4,"hexcode":"1F34E","order":3234,"tags":["apple","fruit","red"],"unicode":"🍎"},{"annotation":"green apple","group":4,"hexcode":"1F34F","order":3235,"tags":["apple","fruit","green"],"unicode":"🍏"},{"annotation":"pear","group":4,"hexcode":"1F350","order":3236,"tags":["fruit"],"unicode":"🍐"},{"annotation":"peach","group":4,"hexcode":"1F351","order":3237,"tags":["fruit"],"unicode":"🍑"},{"annotation":"cherries","group":4,"hexcode":"1F352","order":3238,"tags":["berries","cherry","fruit","red"],"unicode":"🍒"},{"annotation":"strawberry","group":4,"hexcode":"1F353","order":3239,"tags":["berry","fruit"],"unicode":"🍓"},{"annotation":"blueberries","group":4,"hexcode":"1FAD0","order":3240,"tags":["berry","bilberry","blue","blueberry"],"unicode":"🫐"},{"annotation":"kiwi fruit","group":4,"hexcode":"1F95D","order":3241,"tags":["food","fruit","kiwi"],"unicode":"🥝"},{"annotation":"tomato","group":4,"hexcode":"1F345","order":3242,"tags":["fruit","vegetable"],"unicode":"🍅"},{"annotation":"olive","group":4,"hexcode":"1FAD2","order":3243,"tags":["food"],"unicode":"🫒"},{"annotation":"coconut","group":4,"hexcode":"1F965","order":3244,"tags":["palm","piña colada"],"unicode":"🥥"},{"annotation":"avocado","group":4,"hexcode":"1F951","order":3245,"tags":["food","fruit"],"unicode":"🥑"},{"annotation":"eggplant","group":4,"hexcode":"1F346","order":3246,"tags":["aubergine","vegetable"],"unicode":"🍆"},{"annotation":"potato","group":4,"hexcode":"1F954","order":3247,"tags":["food","vegetable"],"unicode":"🥔"},{"annotation":"carrot","group":4,"hexcode":"1F955","order":3248,"tags":["food","vegetable"],"unicode":"🥕"},{"annotation":"ear of corn","group":4,"hexcode":"1F33D","order":3249,"tags":["corn","ear","maize","maze"],"unicode":"🌽"},{"annotation":"hot pepper","group":4,"hexcode":"1F336","order":3251,"tags":["hot","pepper"],"unicode":"🌶️"},{"annotation":"bell pepper","group":4,"hexcode":"1FAD1","order":3252,"tags":["capsicum","pepper","vegetable"],"unicode":"🫑"},{"annotation":"cucumber","group":4,"hexcode":"1F952","order":3253,"tags":["food","pickle","vegetable"],"unicode":"🥒"},{"annotation":"leafy green","group":4,"hexcode":"1F96C","order":3254,"tags":["bok choy","cabbage","kale","lettuce"],"unicode":"🥬"},{"annotation":"broccoli","group":4,"hexcode":"1F966","order":3255,"tags":["wild cabbage"],"unicode":"🥦"},{"annotation":"garlic","group":4,"hexcode":"1F9C4","order":3256,"tags":["flavoring"],"unicode":"🧄"},{"annotation":"onion","group":4,"hexcode":"1F9C5","order":3257,"tags":["flavoring"],"unicode":"🧅"},{"annotation":"mushroom","group":4,"hexcode":"1F344","order":3258,"tags":["toadstool"],"unicode":"🍄"},{"annotation":"peanuts","group":4,"hexcode":"1F95C","order":3259,"tags":["food","nut","peanut","vegetable"],"unicode":"🥜"},{"annotation":"chestnut","group":4,"hexcode":"1F330","order":3260,"tags":["plant"],"unicode":"🌰"},{"annotation":"bread","group":4,"hexcode":"1F35E","order":3261,"tags":["loaf"],"unicode":"🍞"},{"annotation":"croissant","group":4,"hexcode":"1F950","order":3262,"tags":["bread","breakfast","food","french","roll"],"unicode":"🥐"},{"annotation":"baguette bread","group":4,"hexcode":"1F956","order":3263,"tags":["baguette","bread","food","french"],"unicode":"🥖"},{"annotation":"flatbread","group":4,"hexcode":"1FAD3","order":3264,"tags":["arepa","lavash","naan","pita"],"unicode":"🫓"},{"annotation":"pretzel","group":4,"hexcode":"1F968","order":3265,"tags":["twisted"],"unicode":"🥨"},{"annotation":"bagel","group":4,"hexcode":"1F96F","order":3266,"tags":["bakery","breakfast","schmear"],"unicode":"🥯"},{"annotation":"pancakes","group":4,"hexcode":"1F95E","order":3267,"tags":["breakfast","crêpe","food","hotcake","pancake"],"unicode":"🥞"},{"annotation":"waffle","group":4,"hexcode":"1F9C7","order":3268,"tags":["breakfast","indecisive","iron"],"unicode":"🧇"},{"annotation":"cheese wedge","group":4,"hexcode":"1F9C0","order":3269,"tags":["cheese"],"unicode":"🧀"},{"annotation":"meat on bone","group":4,"hexcode":"1F356","order":3270,"tags":["bone","meat"],"unicode":"🍖"},{"annotation":"poultry leg","group":4,"hexcode":"1F357","order":3271,"tags":["bone","chicken","drumstick","leg","poultry"],"unicode":"🍗"},{"annotation":"cut of meat","group":4,"hexcode":"1F969","order":3272,"tags":["chop","lambchop","porkchop","steak"],"unicode":"🥩"},{"annotation":"bacon","group":4,"hexcode":"1F953","order":3273,"tags":["breakfast","food","meat"],"unicode":"🥓"},{"annotation":"hamburger","group":4,"hexcode":"1F354","order":3274,"tags":["burger"],"unicode":"🍔"},{"annotation":"french fries","group":4,"hexcode":"1F35F","order":3275,"tags":["french","fries"],"unicode":"🍟"},{"annotation":"pizza","group":4,"hexcode":"1F355","order":3276,"tags":["cheese","slice"],"unicode":"🍕"},{"annotation":"hot dog","group":4,"hexcode":"1F32D","order":3277,"tags":["frankfurter","hotdog","sausage"],"unicode":"🌭"},{"annotation":"sandwich","group":4,"hexcode":"1F96A","order":3278,"tags":["bread"],"unicode":"🥪"},{"annotation":"taco","group":4,"hexcode":"1F32E","order":3279,"tags":["mexican"],"unicode":"🌮"},{"annotation":"burrito","group":4,"hexcode":"1F32F","order":3280,"tags":["mexican","wrap"],"unicode":"🌯"},{"annotation":"tamale","group":4,"hexcode":"1FAD4","order":3281,"tags":["mexican","wrapped"],"unicode":"🫔"},{"annotation":"stuffed flatbread","group":4,"hexcode":"1F959","order":3282,"tags":["falafel","flatbread","food","gyro","kebab","stuffed"],"unicode":"🥙"},{"annotation":"falafel","group":4,"hexcode":"1F9C6","order":3283,"tags":["chickpea","meatball"],"unicode":"🧆"},{"annotation":"egg","group":4,"hexcode":"1F95A","order":3284,"tags":["breakfast","food"],"unicode":"🥚"},{"annotation":"cooking","group":4,"hexcode":"1F373","order":3285,"tags":["breakfast","egg","frying","pan"],"unicode":"🍳"},{"annotation":"shallow pan of food","group":4,"hexcode":"1F958","order":3286,"tags":["casserole","food","paella","pan","shallow"],"unicode":"🥘"},{"annotation":"pot of food","group":4,"hexcode":"1F372","order":3287,"tags":["pot","stew"],"unicode":"🍲"},{"annotation":"fondue","group":4,"hexcode":"1FAD5","order":3288,"tags":["cheese","chocolate","melted","pot","swiss"],"unicode":"🫕"},{"annotation":"bowl with spoon","group":4,"hexcode":"1F963","order":3289,"tags":["breakfast","cereal","congee"],"unicode":"🥣"},{"annotation":"green salad","group":4,"hexcode":"1F957","order":3290,"tags":["food","green","salad"],"unicode":"🥗"},{"annotation":"popcorn","group":4,"hexcode":"1F37F","order":3291,"tags":["popcorn"],"unicode":"🍿"},{"annotation":"butter","group":4,"hexcode":"1F9C8","order":3292,"tags":["dairy"],"unicode":"🧈"},{"annotation":"salt","group":4,"hexcode":"1F9C2","order":3293,"tags":["condiment","shaker"],"unicode":"🧂"},{"annotation":"canned food","group":4,"hexcode":"1F96B","order":3294,"tags":["can"],"unicode":"🥫"},{"annotation":"bento box","group":4,"hexcode":"1F371","order":3295,"tags":["bento","box"],"unicode":"🍱"},{"annotation":"rice cracker","group":4,"hexcode":"1F358","order":3296,"tags":["cracker","rice"],"unicode":"🍘"},{"annotation":"rice ball","group":4,"hexcode":"1F359","order":3297,"tags":["ball","japanese","rice"],"unicode":"🍙"},{"annotation":"cooked rice","group":4,"hexcode":"1F35A","order":3298,"tags":["cooked","rice"],"unicode":"🍚"},{"annotation":"curry rice","group":4,"hexcode":"1F35B","order":3299,"tags":["curry","rice"],"unicode":"🍛"},{"annotation":"steaming bowl","group":4,"hexcode":"1F35C","order":3300,"tags":["bowl","noodle","ramen","steaming"],"unicode":"🍜"},{"annotation":"spaghetti","group":4,"hexcode":"1F35D","order":3301,"tags":["pasta"],"unicode":"🍝"},{"annotation":"roasted sweet potato","group":4,"hexcode":"1F360","order":3302,"tags":["potato","roasted","sweet"],"unicode":"🍠"},{"annotation":"oden","group":4,"hexcode":"1F362","order":3303,"tags":["kebab","seafood","skewer","stick"],"unicode":"🍢"},{"annotation":"sushi","group":4,"hexcode":"1F363","order":3304,"tags":["sushi"],"unicode":"🍣"},{"annotation":"fried shrimp","group":4,"hexcode":"1F364","order":3305,"tags":["fried","prawn","shrimp","tempura"],"unicode":"🍤"},{"annotation":"fish cake with swirl","group":4,"hexcode":"1F365","order":3306,"tags":["cake","fish","pastry","swirl"],"unicode":"🍥"},{"annotation":"moon cake","group":4,"hexcode":"1F96E","order":3307,"tags":["autumn","festival","yuèbǐng"],"unicode":"🥮"},{"annotation":"dango","group":4,"hexcode":"1F361","order":3308,"tags":["dessert","japanese","skewer","stick","sweet"],"unicode":"🍡"},{"annotation":"dumpling","group":4,"hexcode":"1F95F","order":3309,"tags":["empanada","gyōza","jiaozi","pierogi","potsticker"],"unicode":"🥟"},{"annotation":"fortune cookie","group":4,"hexcode":"1F960","order":3310,"tags":["prophecy"],"unicode":"🥠"},{"annotation":"takeout box","group":4,"hexcode":"1F961","order":3311,"tags":["oyster pail"],"unicode":"🥡"},{"annotation":"crab","group":4,"hexcode":"1F980","order":3312,"tags":["cancer","zodiac"],"unicode":"🦀"},{"annotation":"lobster","group":4,"hexcode":"1F99E","order":3313,"tags":["bisque","claws","seafood"],"unicode":"🦞"},{"annotation":"shrimp","group":4,"hexcode":"1F990","order":3314,"tags":["food","shellfish","small"],"unicode":"🦐"},{"annotation":"squid","group":4,"hexcode":"1F991","order":3315,"tags":["food","molusc"],"unicode":"🦑"},{"annotation":"oyster","group":4,"hexcode":"1F9AA","order":3316,"tags":["diving","pearl"],"unicode":"🦪"},{"annotation":"soft ice cream","group":4,"hexcode":"1F366","order":3317,"tags":["cream","dessert","ice","icecream","soft","sweet"],"unicode":"🍦"},{"annotation":"shaved ice","group":4,"hexcode":"1F367","order":3318,"tags":["dessert","ice","shaved","sweet"],"unicode":"🍧"},{"annotation":"ice cream","group":4,"hexcode":"1F368","order":3319,"tags":["cream","dessert","ice","sweet"],"unicode":"🍨"},{"annotation":"doughnut","group":4,"hexcode":"1F369","order":3320,"tags":["breakfast","dessert","donut","sweet"],"unicode":"🍩"},{"annotation":"cookie","group":4,"hexcode":"1F36A","order":3321,"tags":["dessert","sweet"],"unicode":"🍪"},{"annotation":"birthday cake","group":4,"hexcode":"1F382","order":3322,"tags":["birthday","cake","celebration","dessert","pastry","sweet"],"unicode":"🎂"},{"annotation":"shortcake","group":4,"hexcode":"1F370","order":3323,"tags":["cake","dessert","pastry","slice","sweet"],"unicode":"🍰"},{"annotation":"cupcake","group":4,"hexcode":"1F9C1","order":3324,"tags":["bakery","sweet"],"unicode":"🧁"},{"annotation":"pie","group":4,"hexcode":"1F967","order":3325,"tags":["filling","pastry"],"unicode":"🥧"},{"annotation":"chocolate bar","group":4,"hexcode":"1F36B","order":3326,"tags":["bar","chocolate","dessert","sweet"],"unicode":"🍫"},{"annotation":"candy","group":4,"hexcode":"1F36C","order":3327,"tags":["dessert","sweet"],"unicode":"🍬"},{"annotation":"lollipop","group":4,"hexcode":"1F36D","order":3328,"tags":["candy","dessert","sweet"],"unicode":"🍭"},{"annotation":"custard","group":4,"hexcode":"1F36E","order":3329,"tags":["dessert","pudding","sweet"],"unicode":"🍮"},{"annotation":"honey pot","group":4,"hexcode":"1F36F","order":3330,"tags":["honey","honeypot","pot","sweet"],"unicode":"🍯"},{"annotation":"baby bottle","group":4,"hexcode":"1F37C","order":3331,"tags":["baby","bottle","drink","milk"],"unicode":"🍼"},{"annotation":"glass of milk","group":4,"hexcode":"1F95B","order":3332,"tags":["drink","glass","milk"],"unicode":"🥛"},{"annotation":"hot beverage","group":4,"hexcode":"2615","order":3333,"tags":["beverage","coffee","drink","hot","steaming","tea"],"unicode":"☕️"},{"annotation":"teapot","group":4,"hexcode":"1FAD6","order":3334,"tags":["drink","pot","tea"],"unicode":"🫖"},{"annotation":"teacup without handle","group":4,"hexcode":"1F375","order":3335,"tags":["beverage","cup","drink","tea","teacup"],"unicode":"🍵"},{"annotation":"sake","group":4,"hexcode":"1F376","order":3336,"tags":["bar","beverage","bottle","cup","drink"],"unicode":"🍶"},{"annotation":"bottle with popping cork","group":4,"hexcode":"1F37E","order":3337,"tags":["bar","bottle","cork","drink","popping"],"unicode":"🍾"},{"annotation":"wine glass","group":4,"hexcode":"1F377","order":3338,"tags":["bar","beverage","drink","glass","wine"],"unicode":"🍷"},{"annotation":"cocktail glass","group":4,"hexcode":"1F378","order":3339,"tags":["bar","cocktail","drink","glass"],"unicode":"🍸️"},{"annotation":"tropical drink","group":4,"hexcode":"1F379","order":3340,"tags":["bar","drink","tropical"],"unicode":"🍹"},{"annotation":"beer mug","group":4,"hexcode":"1F37A","order":3341,"tags":["bar","beer","drink","mug"],"unicode":"🍺"},{"annotation":"clinking beer mugs","group":4,"hexcode":"1F37B","order":3342,"tags":["bar","beer","clink","drink","mug"],"unicode":"🍻"},{"annotation":"clinking glasses","group":4,"hexcode":"1F942","order":3343,"tags":["celebrate","clink","drink","glass"],"unicode":"🥂"},{"annotation":"tumbler glass","group":4,"hexcode":"1F943","order":3344,"tags":["glass","liquor","shot","tumbler","whisky"],"unicode":"🥃"},{"annotation":"cup with straw","group":4,"hexcode":"1F964","order":3345,"tags":["juice","soda"],"unicode":"🥤"},{"annotation":"bubble tea","group":4,"hexcode":"1F9CB","order":3346,"tags":["bubble","milk","pearl","tea"],"unicode":"🧋"},{"annotation":"beverage box","group":4,"hexcode":"1F9C3","order":3347,"tags":["beverage","box","juice","straw","sweet"],"unicode":"🧃"},{"annotation":"mate","group":4,"hexcode":"1F9C9","order":3348,"tags":["drink"],"unicode":"🧉"},{"annotation":"ice","group":4,"hexcode":"1F9CA","order":3349,"tags":["cold","ice cube","iceberg"],"unicode":"🧊"},{"annotation":"chopsticks","group":4,"hexcode":"1F962","order":3350,"tags":["hashi"],"unicode":"🥢"},{"annotation":"fork and knife with plate","group":4,"hexcode":"1F37D","order":3352,"tags":["cooking","fork","knife","plate"],"unicode":"🍽️"},{"annotation":"fork and knife","group":4,"hexcode":"1F374","order":3353,"tags":["cooking","cutlery","fork","knife"],"unicode":"🍴"},{"annotation":"spoon","group":4,"hexcode":"1F944","order":3354,"tags":["tableware"],"unicode":"🥄"},{"annotation":"kitchen knife","group":4,"hexcode":"1F52A","order":3355,"tags":["cooking","hocho","knife","tool","weapon"],"unicode":"🔪"},{"annotation":"amphora","group":4,"hexcode":"1F3FA","order":3356,"tags":["aquarius","cooking","drink","jug","zodiac"],"unicode":"🏺"},{"annotation":"globe showing Europe-Africa","group":5,"hexcode":"1F30D","order":3357,"tags":["africa","earth","europe","globe","globe showing europe-africa","world"],"unicode":"🌍️"},{"annotation":"globe showing Americas","group":5,"hexcode":"1F30E","order":3358,"tags":["americas","earth","globe","globe showing americas","world"],"unicode":"🌎️"},{"annotation":"globe showing Asia-Australia","group":5,"hexcode":"1F30F","order":3359,"tags":["asia","australia","earth","globe","globe showing asia-australia","world"],"unicode":"🌏️"},{"annotation":"globe with meridians","group":5,"hexcode":"1F310","order":3360,"tags":["earth","globe","meridians","world"],"unicode":"🌐"},{"annotation":"world map","group":5,"hexcode":"1F5FA","order":3362,"tags":["map","world"],"unicode":"🗺️"},{"annotation":"map of Japan","group":5,"hexcode":"1F5FE","order":3363,"tags":["japan","map","map of japan"],"unicode":"🗾"},{"annotation":"compass","group":5,"hexcode":"1F9ED","order":3364,"tags":["magnetic","navigation","orienteering"],"unicode":"🧭"},{"annotation":"snow-capped mountain","group":5,"hexcode":"1F3D4","order":3366,"tags":["cold","mountain","snow"],"unicode":"🏔️"},{"annotation":"mountain","group":5,"hexcode":"26F0","order":3368,"tags":["mountain"],"unicode":"⛰️"},{"annotation":"volcano","group":5,"hexcode":"1F30B","order":3369,"tags":["eruption","mountain"],"unicode":"🌋"},{"annotation":"mount fuji","group":5,"hexcode":"1F5FB","order":3370,"tags":["fuji","mountain"],"unicode":"🗻"},{"annotation":"camping","group":5,"hexcode":"1F3D5","order":3372,"tags":["camping"],"unicode":"🏕️"},{"annotation":"beach with umbrella","group":5,"hexcode":"1F3D6","order":3374,"tags":["beach","umbrella"],"unicode":"🏖️"},{"annotation":"desert","group":5,"hexcode":"1F3DC","order":3376,"tags":["desert"],"unicode":"🏜️"},{"annotation":"desert island","group":5,"hexcode":"1F3DD","order":3378,"tags":["desert","island"],"unicode":"🏝️"},{"annotation":"national park","group":5,"hexcode":"1F3DE","order":3380,"tags":["park"],"unicode":"🏞️"},{"annotation":"stadium","group":5,"hexcode":"1F3DF","order":3382,"tags":["stadium"],"unicode":"🏟️"},{"annotation":"classical building","group":5,"hexcode":"1F3DB","order":3384,"tags":["classical"],"unicode":"🏛️"},{"annotation":"building construction","group":5,"hexcode":"1F3D7","order":3386,"tags":["construction"],"unicode":"🏗️"},{"annotation":"brick","group":5,"hexcode":"1F9F1","order":3387,"tags":["bricks","clay","mortar","wall"],"unicode":"🧱"},{"annotation":"rock","group":5,"hexcode":"1FAA8","order":3388,"tags":["boulder","heavy","solid","stone"],"unicode":"🪨"},{"annotation":"wood","group":5,"hexcode":"1FAB5","order":3389,"tags":["log","lumber","timber"],"unicode":"🪵"},{"annotation":"hut","group":5,"hexcode":"1F6D6","order":3390,"tags":["house","roundhouse","yurt"],"unicode":"🛖"},{"annotation":"houses","group":5,"hexcode":"1F3D8","order":3392,"tags":["houses"],"unicode":"🏘️"},{"annotation":"derelict house","group":5,"hexcode":"1F3DA","order":3394,"tags":["derelict","house"],"unicode":"🏚️"},{"annotation":"house","group":5,"hexcode":"1F3E0","order":3395,"tags":["home"],"unicode":"🏠️"},{"annotation":"house with garden","group":5,"hexcode":"1F3E1","order":3396,"tags":["garden","home","house"],"unicode":"🏡"},{"annotation":"office building","group":5,"hexcode":"1F3E2","order":3397,"tags":["building"],"unicode":"🏢"},{"annotation":"Japanese post office","group":5,"hexcode":"1F3E3","order":3398,"tags":["japanese","japanese post office","post"],"unicode":"🏣"},{"annotation":"post office","group":5,"hexcode":"1F3E4","order":3399,"tags":["european","post"],"unicode":"🏤"},{"annotation":"hospital","group":5,"hexcode":"1F3E5","order":3400,"tags":["doctor","medicine"],"unicode":"🏥"},{"annotation":"bank","group":5,"hexcode":"1F3E6","order":3401,"tags":["building"],"unicode":"🏦"},{"annotation":"hotel","group":5,"hexcode":"1F3E8","order":3402,"tags":["building"],"unicode":"🏨"},{"annotation":"love hotel","group":5,"hexcode":"1F3E9","order":3403,"tags":["hotel","love"],"unicode":"🏩"},{"annotation":"convenience store","group":5,"hexcode":"1F3EA","order":3404,"tags":["convenience","store"],"unicode":"🏪"},{"annotation":"school","group":5,"hexcode":"1F3EB","order":3405,"tags":["building"],"unicode":"🏫"},{"annotation":"department store","group":5,"hexcode":"1F3EC","order":3406,"tags":["department","store"],"unicode":"🏬"},{"annotation":"factory","group":5,"hexcode":"1F3ED","order":3407,"tags":["building"],"unicode":"🏭️"},{"annotation":"Japanese castle","group":5,"hexcode":"1F3EF","order":3408,"tags":["castle","japanese"],"unicode":"🏯"},{"annotation":"castle","group":5,"hexcode":"1F3F0","order":3409,"tags":["european"],"unicode":"🏰"},{"annotation":"wedding","group":5,"hexcode":"1F492","order":3410,"tags":["chapel","romance"],"unicode":"💒"},{"annotation":"Tokyo tower","group":5,"hexcode":"1F5FC","order":3411,"tags":["tokyo","tower"],"unicode":"🗼"},{"annotation":"Statue of Liberty","group":5,"hexcode":"1F5FD","order":3412,"tags":["liberty","statue","statue of liberty"],"unicode":"🗽"},{"annotation":"church","group":5,"hexcode":"26EA","order":3413,"tags":["christian","cross","religion"],"unicode":"⛪️"},{"annotation":"mosque","group":5,"hexcode":"1F54C","order":3414,"tags":["islam","muslim","religion"],"unicode":"🕌"},{"annotation":"hindu temple","group":5,"hexcode":"1F6D5","order":3415,"tags":["hindu","temple"],"unicode":"🛕"},{"annotation":"synagogue","group":5,"hexcode":"1F54D","order":3416,"tags":["jew","jewish","religion","temple"],"unicode":"🕍"},{"annotation":"shinto shrine","group":5,"hexcode":"26E9","order":3418,"tags":["religion","shinto","shrine"],"unicode":"⛩️"},{"annotation":"kaaba","group":5,"hexcode":"1F54B","order":3419,"tags":["islam","muslim","religion"],"unicode":"🕋"},{"annotation":"fountain","group":5,"hexcode":"26F2","order":3420,"tags":["fountain"],"unicode":"⛲️"},{"annotation":"tent","group":5,"hexcode":"26FA","order":3421,"tags":["camping"],"unicode":"⛺️"},{"annotation":"foggy","group":5,"hexcode":"1F301","order":3422,"tags":["fog"],"unicode":"🌁"},{"annotation":"night with stars","group":5,"hexcode":"1F303","order":3423,"tags":["night","star"],"unicode":"🌃"},{"annotation":"cityscape","group":5,"hexcode":"1F3D9","order":3425,"tags":["city"],"unicode":"🏙️"},{"annotation":"sunrise over mountains","group":5,"hexcode":"1F304","order":3426,"tags":["morning","mountain","sun","sunrise"],"unicode":"🌄"},{"annotation":"sunrise","group":5,"hexcode":"1F305","order":3427,"tags":["morning","sun"],"unicode":"🌅"},{"annotation":"cityscape at dusk","group":5,"hexcode":"1F306","order":3428,"tags":["city","dusk","evening","landscape","sunset"],"unicode":"🌆"},{"annotation":"sunset","group":5,"hexcode":"1F307","order":3429,"tags":["dusk","sun"],"unicode":"🌇"},{"annotation":"bridge at night","group":5,"hexcode":"1F309","order":3430,"tags":["bridge","night"],"unicode":"🌉"},{"annotation":"hot springs","group":5,"hexcode":"2668","order":3432,"tags":["hot","hotsprings","springs","steaming"],"unicode":"♨️"},{"annotation":"carousel horse","group":5,"hexcode":"1F3A0","order":3433,"tags":["carousel","horse"],"unicode":"🎠"},{"annotation":"ferris wheel","group":5,"hexcode":"1F3A1","order":3434,"tags":["amusement park","ferris","wheel"],"unicode":"🎡"},{"annotation":"roller coaster","group":5,"hexcode":"1F3A2","order":3435,"tags":["amusement park","coaster","roller"],"unicode":"🎢"},{"annotation":"barber pole","group":5,"hexcode":"1F488","order":3436,"tags":["barber","haircut","pole"],"unicode":"💈"},{"annotation":"circus tent","group":5,"hexcode":"1F3AA","order":3437,"tags":["circus","tent"],"unicode":"🎪"},{"annotation":"locomotive","group":5,"hexcode":"1F682","order":3438,"tags":["engine","railway","steam","train"],"unicode":"🚂"},{"annotation":"railway car","group":5,"hexcode":"1F683","order":3439,"tags":["car","electric","railway","train","tram","trolleybus"],"unicode":"🚃"},{"annotation":"high-speed train","group":5,"hexcode":"1F684","order":3440,"tags":["railway","shinkansen","speed","train"],"unicode":"🚄"},{"annotation":"bullet train","group":5,"hexcode":"1F685","order":3441,"tags":["bullet","railway","shinkansen","speed","train"],"unicode":"🚅"},{"annotation":"train","group":5,"hexcode":"1F686","order":3442,"tags":["railway"],"unicode":"🚆"},{"annotation":"metro","group":5,"hexcode":"1F687","order":3443,"tags":["subway"],"unicode":"🚇️"},{"annotation":"light rail","group":5,"hexcode":"1F688","order":3444,"tags":["railway"],"unicode":"🚈"},{"annotation":"station","group":5,"hexcode":"1F689","order":3445,"tags":["railway","train"],"unicode":"🚉"},{"annotation":"tram","group":5,"hexcode":"1F68A","order":3446,"tags":["trolleybus"],"unicode":"🚊"},{"annotation":"monorail","group":5,"hexcode":"1F69D","order":3447,"tags":["vehicle"],"unicode":"🚝"},{"annotation":"mountain railway","group":5,"hexcode":"1F69E","order":3448,"tags":["car","mountain","railway"],"unicode":"🚞"},{"annotation":"tram car","group":5,"hexcode":"1F68B","order":3449,"tags":["car","tram","trolleybus"],"unicode":"🚋"},{"annotation":"bus","group":5,"hexcode":"1F68C","order":3450,"tags":["vehicle"],"unicode":"🚌"},{"annotation":"oncoming bus","group":5,"hexcode":"1F68D","order":3451,"tags":["bus","oncoming"],"unicode":"🚍️"},{"annotation":"trolleybus","group":5,"hexcode":"1F68E","order":3452,"tags":["bus","tram","trolley"],"unicode":"🚎"},{"annotation":"minibus","group":5,"hexcode":"1F690","order":3453,"tags":["bus"],"unicode":"🚐"},{"annotation":"ambulance","group":5,"hexcode":"1F691","order":3454,"tags":["vehicle"],"unicode":"🚑️"},{"annotation":"fire engine","group":5,"hexcode":"1F692","order":3455,"tags":["engine","fire","truck"],"unicode":"🚒"},{"annotation":"police car","group":5,"hexcode":"1F693","order":3456,"tags":["car","patrol","police"],"unicode":"🚓"},{"annotation":"oncoming police car","group":5,"hexcode":"1F694","order":3457,"tags":["car","oncoming","police"],"unicode":"🚔️"},{"annotation":"taxi","group":5,"hexcode":"1F695","order":3458,"tags":["vehicle"],"unicode":"🚕"},{"annotation":"oncoming taxi","group":5,"hexcode":"1F696","order":3459,"tags":["oncoming","taxi"],"unicode":"🚖"},{"annotation":"automobile","group":5,"hexcode":"1F697","order":3460,"tags":["car"],"unicode":"🚗"},{"annotation":"oncoming automobile","group":5,"hexcode":"1F698","order":3461,"tags":["automobile","car","oncoming"],"unicode":"🚘️"},{"annotation":"sport utility vehicle","group":5,"hexcode":"1F699","order":3462,"tags":["recreational","sport utility"],"unicode":"🚙"},{"annotation":"pickup truck","group":5,"hexcode":"1F6FB","order":3463,"tags":["pick-up","pickup","truck"],"unicode":"🛻"},{"annotation":"delivery truck","group":5,"hexcode":"1F69A","order":3464,"tags":["delivery","truck"],"unicode":"🚚"},{"annotation":"articulated lorry","group":5,"hexcode":"1F69B","order":3465,"tags":["lorry","semi","truck"],"unicode":"🚛"},{"annotation":"tractor","group":5,"hexcode":"1F69C","order":3466,"tags":["vehicle"],"unicode":"🚜"},{"annotation":"racing car","group":5,"hexcode":"1F3CE","order":3468,"tags":["car","racing"],"unicode":"🏎️"},{"annotation":"motorcycle","group":5,"hexcode":"1F3CD","order":3470,"tags":["racing"],"unicode":"🏍️"},{"annotation":"motor scooter","group":5,"hexcode":"1F6F5","order":3471,"tags":["motor","scooter"],"unicode":"🛵"},{"annotation":"manual wheelchair","group":5,"hexcode":"1F9BD","order":3472,"tags":["accessibility"],"unicode":"🦽"},{"annotation":"motorized wheelchair","group":5,"hexcode":"1F9BC","order":3473,"tags":["accessibility"],"unicode":"🦼"},{"annotation":"auto rickshaw","group":5,"hexcode":"1F6FA","order":3474,"tags":["tuk tuk"],"unicode":"🛺"},{"annotation":"bicycle","group":5,"hexcode":"1F6B2","order":3475,"tags":["bike"],"unicode":"🚲️"},{"annotation":"kick scooter","group":5,"hexcode":"1F6F4","order":3476,"tags":["kick","scooter"],"unicode":"🛴"},{"annotation":"skateboard","group":5,"hexcode":"1F6F9","order":3477,"tags":["board"],"unicode":"🛹"},{"annotation":"roller skate","group":5,"hexcode":"1F6FC","order":3478,"tags":["roller","skate"],"unicode":"🛼"},{"annotation":"bus stop","group":5,"hexcode":"1F68F","order":3479,"tags":["bus","busstop","stop"],"unicode":"🚏"},{"annotation":"motorway","group":5,"hexcode":"1F6E3","order":3481,"tags":["highway","road"],"unicode":"🛣️"},{"annotation":"railway track","group":5,"hexcode":"1F6E4","order":3483,"tags":["railway","train"],"unicode":"🛤️"},{"annotation":"oil drum","group":5,"hexcode":"1F6E2","order":3485,"tags":["drum","oil"],"unicode":"🛢️"},{"annotation":"fuel pump","group":5,"hexcode":"26FD","order":3486,"tags":["diesel","fuel","fuelpump","gas","pump","station"],"unicode":"⛽️"},{"annotation":"police car light","group":5,"hexcode":"1F6A8","order":3487,"tags":["beacon","car","light","police","revolving"],"unicode":"🚨"},{"annotation":"horizontal traffic light","group":5,"hexcode":"1F6A5","order":3488,"tags":["light","signal","traffic"],"unicode":"🚥"},{"annotation":"vertical traffic light","group":5,"hexcode":"1F6A6","order":3489,"tags":["light","signal","traffic"],"unicode":"🚦"},{"annotation":"stop sign","group":5,"hexcode":"1F6D1","order":3490,"tags":["octagonal","sign","stop"],"unicode":"🛑"},{"annotation":"construction","group":5,"hexcode":"1F6A7","order":3491,"tags":["barrier"],"unicode":"🚧"},{"annotation":"anchor","group":5,"hexcode":"2693","order":3492,"tags":["ship","tool"],"unicode":"⚓️"},{"annotation":"sailboat","group":5,"hexcode":"26F5","order":3493,"tags":["boat","resort","sea","yacht"],"unicode":"⛵️"},{"annotation":"canoe","group":5,"hexcode":"1F6F6","order":3494,"tags":["boat"],"unicode":"🛶"},{"annotation":"speedboat","group":5,"hexcode":"1F6A4","order":3495,"tags":["boat"],"unicode":"🚤"},{"annotation":"passenger ship","group":5,"hexcode":"1F6F3","order":3497,"tags":["passenger","ship"],"unicode":"🛳️"},{"annotation":"ferry","group":5,"hexcode":"26F4","order":3499,"tags":["boat","passenger"],"unicode":"⛴️"},{"annotation":"motor boat","group":5,"hexcode":"1F6E5","order":3501,"tags":["boat","motorboat"],"unicode":"🛥️"},{"annotation":"ship","group":5,"hexcode":"1F6A2","order":3502,"tags":["boat","passenger"],"unicode":"🚢"},{"annotation":"airplane","group":5,"hexcode":"2708","order":3504,"tags":["aeroplane"],"unicode":"✈️"},{"annotation":"small airplane","group":5,"hexcode":"1F6E9","order":3506,"tags":["aeroplane","airplane"],"unicode":"🛩️"},{"annotation":"airplane departure","group":5,"hexcode":"1F6EB","order":3507,"tags":["aeroplane","airplane","check-in","departure","departures"],"unicode":"🛫"},{"annotation":"airplane arrival","group":5,"hexcode":"1F6EC","order":3508,"tags":["aeroplane","airplane","arrivals","arriving","landing"],"unicode":"🛬"},{"annotation":"parachute","group":5,"hexcode":"1FA82","order":3509,"tags":["hang-glide","parasail","skydive"],"unicode":"🪂"},{"annotation":"seat","group":5,"hexcode":"1F4BA","order":3510,"tags":["chair"],"unicode":"💺"},{"annotation":"helicopter","group":5,"hexcode":"1F681","order":3511,"tags":["vehicle"],"unicode":"🚁"},{"annotation":"suspension railway","group":5,"hexcode":"1F69F","order":3512,"tags":["railway","suspension"],"unicode":"🚟"},{"annotation":"mountain cableway","group":5,"hexcode":"1F6A0","order":3513,"tags":["cable","gondola","mountain"],"unicode":"🚠"},{"annotation":"aerial tramway","group":5,"hexcode":"1F6A1","order":3514,"tags":["aerial","cable","car","gondola","tramway"],"unicode":"🚡"},{"annotation":"satellite","group":5,"hexcode":"1F6F0","order":3516,"tags":["space"],"unicode":"🛰️"},{"annotation":"rocket","group":5,"hexcode":"1F680","order":3517,"tags":["space"],"unicode":"🚀"},{"annotation":"flying saucer","group":5,"hexcode":"1F6F8","order":3518,"tags":["ufo"],"unicode":"🛸"},{"annotation":"bellhop bell","group":5,"hexcode":"1F6CE","order":3520,"tags":["bell","bellhop","hotel"],"unicode":"🛎️"},{"annotation":"luggage","group":5,"hexcode":"1F9F3","order":3521,"tags":["packing","travel"],"unicode":"🧳"},{"annotation":"hourglass done","group":5,"hexcode":"231B","order":3522,"tags":["sand","timer"],"unicode":"⌛️"},{"annotation":"hourglass not done","group":5,"hexcode":"23F3","order":3523,"tags":["hourglass","sand","timer"],"unicode":"⏳️"},{"annotation":"watch","group":5,"hexcode":"231A","order":3524,"tags":["clock"],"unicode":"⌚️"},{"annotation":"alarm clock","group":5,"hexcode":"23F0","order":3525,"tags":["alarm","clock"],"unicode":"⏰"},{"annotation":"stopwatch","group":5,"hexcode":"23F1","order":3527,"tags":["clock"],"unicode":"⏱️"},{"annotation":"timer clock","group":5,"hexcode":"23F2","order":3529,"tags":["clock","timer"],"unicode":"⏲️"},{"annotation":"mantelpiece clock","group":5,"hexcode":"1F570","order":3531,"tags":["clock"],"unicode":"🕰️"},{"annotation":"twelve o’clock","group":5,"hexcode":"1F55B","order":3532,"tags":["00","12","12:00","clock","o’clock","twelve"],"unicode":"🕛️"},{"annotation":"twelve-thirty","group":5,"hexcode":"1F567","order":3533,"tags":["12","12:30","clock","thirty","twelve"],"unicode":"🕧️"},{"annotation":"one o’clock","group":5,"hexcode":"1F550","order":3534,"tags":["00","1","1:00","clock","one","o’clock"],"unicode":"🕐️"},{"annotation":"one-thirty","group":5,"hexcode":"1F55C","order":3535,"tags":["1","1:30","clock","one","thirty"],"unicode":"🕜️"},{"annotation":"two o’clock","group":5,"hexcode":"1F551","order":3536,"tags":["00","2","2:00","clock","o’clock","two"],"unicode":"🕑️"},{"annotation":"two-thirty","group":5,"hexcode":"1F55D","order":3537,"tags":["2","2:30","clock","thirty","two"],"unicode":"🕝️"},{"annotation":"three o’clock","group":5,"hexcode":"1F552","order":3538,"tags":["00","3","3:00","clock","o’clock","three"],"unicode":"🕒️"},{"annotation":"three-thirty","group":5,"hexcode":"1F55E","order":3539,"tags":["3","3:30","clock","thirty","three"],"unicode":"🕞️"},{"annotation":"four o’clock","group":5,"hexcode":"1F553","order":3540,"tags":["00","4","4:00","clock","four","o’clock"],"unicode":"🕓️"},{"annotation":"four-thirty","group":5,"hexcode":"1F55F","order":3541,"tags":["4","4:30","clock","four","thirty"],"unicode":"🕟️"},{"annotation":"five o’clock","group":5,"hexcode":"1F554","order":3542,"tags":["00","5","5:00","clock","five","o’clock"],"unicode":"🕔️"},{"annotation":"five-thirty","group":5,"hexcode":"1F560","order":3543,"tags":["5","5:30","clock","five","thirty"],"unicode":"🕠️"},{"annotation":"six o’clock","group":5,"hexcode":"1F555","order":3544,"tags":["00","6","6:00","clock","o’clock","six"],"unicode":"🕕️"},{"annotation":"six-thirty","group":5,"hexcode":"1F561","order":3545,"tags":["6","6:30","clock","six","thirty"],"unicode":"🕡️"},{"annotation":"seven o’clock","group":5,"hexcode":"1F556","order":3546,"tags":["00","7","7:00","clock","o’clock","seven"],"unicode":"🕖️"},{"annotation":"seven-thirty","group":5,"hexcode":"1F562","order":3547,"tags":["7","7:30","clock","seven","thirty"],"unicode":"🕢️"},{"annotation":"eight o’clock","group":5,"hexcode":"1F557","order":3548,"tags":["00","8","8:00","clock","eight","o’clock"],"unicode":"🕗️"},{"annotation":"eight-thirty","group":5,"hexcode":"1F563","order":3549,"tags":["8","8:30","clock","eight","thirty"],"unicode":"🕣️"},{"annotation":"nine o’clock","group":5,"hexcode":"1F558","order":3550,"tags":["00","9","9:00","clock","nine","o’clock"],"unicode":"🕘️"},{"annotation":"nine-thirty","group":5,"hexcode":"1F564","order":3551,"tags":["9","9:30","clock","nine","thirty"],"unicode":"🕤️"},{"annotation":"ten o’clock","group":5,"hexcode":"1F559","order":3552,"tags":["00","10","10:00","clock","o’clock","ten"],"unicode":"🕙️"},{"annotation":"ten-thirty","group":5,"hexcode":"1F565","order":3553,"tags":["10","10:30","clock","ten","thirty"],"unicode":"🕥️"},{"annotation":"eleven o’clock","group":5,"hexcode":"1F55A","order":3554,"tags":["00","11","11:00","clock","eleven","o’clock"],"unicode":"🕚️"},{"annotation":"eleven-thirty","group":5,"hexcode":"1F566","order":3555,"tags":["11","11:30","clock","eleven","thirty"],"unicode":"🕦️"},{"annotation":"new moon","group":5,"hexcode":"1F311","order":3556,"tags":["dark","moon"],"unicode":"🌑"},{"annotation":"waxing crescent moon","group":5,"hexcode":"1F312","order":3557,"tags":["crescent","moon","waxing"],"unicode":"🌒"},{"annotation":"first quarter moon","group":5,"hexcode":"1F313","order":3558,"tags":["moon","quarter"],"unicode":"🌓"},{"annotation":"waxing gibbous moon","group":5,"hexcode":"1F314","order":3559,"tags":["gibbous","moon","waxing"],"unicode":"🌔"},{"annotation":"full moon","group":5,"hexcode":"1F315","order":3560,"tags":["full","moon"],"unicode":"🌕️"},{"annotation":"waning gibbous moon","group":5,"hexcode":"1F316","order":3561,"tags":["gibbous","moon","waning"],"unicode":"🌖"},{"annotation":"last quarter moon","group":5,"hexcode":"1F317","order":3562,"tags":["moon","quarter"],"unicode":"🌗"},{"annotation":"waning crescent moon","group":5,"hexcode":"1F318","order":3563,"tags":["crescent","moon","waning"],"unicode":"🌘"},{"annotation":"crescent moon","group":5,"hexcode":"1F319","order":3564,"tags":["crescent","moon"],"unicode":"🌙"},{"annotation":"new moon face","group":5,"hexcode":"1F31A","order":3565,"tags":["face","moon"],"unicode":"🌚"},{"annotation":"first quarter moon face","group":5,"hexcode":"1F31B","order":3566,"tags":["face","moon","quarter"],"unicode":"🌛"},{"annotation":"last quarter moon face","group":5,"hexcode":"1F31C","order":3567,"tags":["face","moon","quarter"],"unicode":"🌜️"},{"annotation":"thermometer","group":5,"hexcode":"1F321","order":3569,"tags":["weather"],"unicode":"🌡️"},{"annotation":"sun","group":5,"hexcode":"2600","order":3571,"tags":["bright","rays","sunny"],"unicode":"☀️"},{"annotation":"full moon face","group":5,"hexcode":"1F31D","order":3572,"tags":["bright","face","full","moon"],"unicode":"🌝"},{"annotation":"sun with face","group":5,"hexcode":"1F31E","order":3573,"tags":["bright","face","sun"],"unicode":"🌞"},{"annotation":"ringed planet","group":5,"hexcode":"1FA90","order":3574,"tags":["saturn","saturnine"],"unicode":"🪐"},{"annotation":"star","group":5,"hexcode":"2B50","order":3575,"tags":["star"],"unicode":"⭐️"},{"annotation":"glowing star","group":5,"hexcode":"1F31F","order":3576,"tags":["glittery","glow","shining","sparkle","star"],"unicode":"🌟"},{"annotation":"shooting star","group":5,"hexcode":"1F320","order":3577,"tags":["falling","shooting","star"],"unicode":"🌠"},{"annotation":"milky way","group":5,"hexcode":"1F30C","order":3578,"tags":["space"],"unicode":"🌌"},{"annotation":"cloud","group":5,"hexcode":"2601","order":3580,"tags":["weather"],"unicode":"☁️"},{"annotation":"sun behind cloud","group":5,"hexcode":"26C5","order":3581,"tags":["cloud","sun"],"unicode":"⛅️"},{"annotation":"cloud with lightning and rain","group":5,"hexcode":"26C8","order":3583,"tags":["cloud","rain","thunder"],"unicode":"⛈️"},{"annotation":"sun behind small cloud","group":5,"hexcode":"1F324","order":3585,"tags":["cloud","sun"],"unicode":"🌤️"},{"annotation":"sun behind large cloud","group":5,"hexcode":"1F325","order":3587,"tags":["cloud","sun"],"unicode":"🌥️"},{"annotation":"sun behind rain cloud","group":5,"hexcode":"1F326","order":3589,"tags":["cloud","rain","sun"],"unicode":"🌦️"},{"annotation":"cloud with rain","group":5,"hexcode":"1F327","order":3591,"tags":["cloud","rain"],"unicode":"🌧️"},{"annotation":"cloud with snow","group":5,"hexcode":"1F328","order":3593,"tags":["cloud","cold","snow"],"unicode":"🌨️"},{"annotation":"cloud with lightning","group":5,"hexcode":"1F329","order":3595,"tags":["cloud","lightning"],"unicode":"🌩️"},{"annotation":"tornado","group":5,"hexcode":"1F32A","order":3597,"tags":["cloud","whirlwind"],"unicode":"🌪️"},{"annotation":"fog","group":5,"hexcode":"1F32B","order":3599,"tags":["cloud"],"unicode":"🌫️"},{"annotation":"wind face","group":5,"hexcode":"1F32C","order":3601,"tags":["blow","cloud","face","wind"],"unicode":"🌬️"},{"annotation":"cyclone","group":5,"hexcode":"1F300","order":3602,"tags":["dizzy","hurricane","twister","typhoon"],"unicode":"🌀"},{"annotation":"rainbow","group":5,"hexcode":"1F308","order":3603,"tags":["rain"],"unicode":"🌈"},{"annotation":"closed umbrella","group":5,"hexcode":"1F302","order":3604,"tags":["clothing","rain","umbrella"],"unicode":"🌂"},{"annotation":"umbrella","group":5,"hexcode":"2602","order":3606,"tags":["clothing","rain"],"unicode":"☂️"},{"annotation":"umbrella with rain drops","group":5,"hexcode":"2614","order":3607,"tags":["clothing","drop","rain","umbrella"],"unicode":"☔️"},{"annotation":"umbrella on ground","group":5,"hexcode":"26F1","order":3609,"tags":["rain","sun","umbrella"],"unicode":"⛱️"},{"annotation":"high voltage","group":5,"hexcode":"26A1","order":3610,"tags":["danger","electric","lightning","voltage","zap"],"unicode":"⚡️"},{"annotation":"snowflake","group":5,"hexcode":"2744","order":3612,"tags":["cold","snow"],"unicode":"❄️"},{"annotation":"snowman","group":5,"hexcode":"2603","order":3614,"tags":["cold","snow"],"unicode":"☃️"},{"annotation":"snowman without snow","group":5,"hexcode":"26C4","order":3615,"tags":["cold","snow","snowman"],"unicode":"⛄️"},{"annotation":"comet","group":5,"hexcode":"2604","order":3617,"tags":["space"],"unicode":"☄️"},{"annotation":"fire","group":5,"hexcode":"1F525","order":3618,"tags":["flame","tool"],"unicode":"🔥"},{"annotation":"droplet","group":5,"hexcode":"1F4A7","order":3619,"tags":["cold","comic","drop","sweat"],"unicode":"💧"},{"annotation":"water wave","group":5,"hexcode":"1F30A","order":3620,"tags":["ocean","water","wave"],"unicode":"🌊"},{"annotation":"jack-o-lantern","group":6,"hexcode":"1F383","order":3621,"tags":["celebration","halloween","jack","lantern"],"unicode":"🎃"},{"annotation":"Christmas tree","group":6,"hexcode":"1F384","order":3622,"tags":["celebration","christmas","tree"],"unicode":"🎄"},{"annotation":"fireworks","group":6,"hexcode":"1F386","order":3623,"tags":["celebration"],"unicode":"🎆"},{"annotation":"sparkler","group":6,"hexcode":"1F387","order":3624,"tags":["celebration","fireworks","sparkle"],"unicode":"🎇"},{"annotation":"firecracker","group":6,"hexcode":"1F9E8","order":3625,"tags":["dynamite","explosive","fireworks"],"unicode":"🧨"},{"annotation":"sparkles","group":6,"hexcode":"2728","order":3626,"tags":["*","sparkle","star"],"unicode":"✨"},{"annotation":"balloon","group":6,"hexcode":"1F388","order":3627,"tags":["celebration"],"unicode":"🎈"},{"annotation":"party popper","group":6,"hexcode":"1F389","order":3628,"tags":["celebration","party","popper","tada"],"unicode":"🎉"},{"annotation":"confetti ball","group":6,"hexcode":"1F38A","order":3629,"tags":["ball","celebration","confetti"],"unicode":"🎊"},{"annotation":"tanabata tree","group":6,"hexcode":"1F38B","order":3630,"tags":["banner","celebration","japanese","tree"],"unicode":"🎋"},{"annotation":"pine decoration","group":6,"hexcode":"1F38D","order":3631,"tags":["bamboo","celebration","japanese","pine"],"unicode":"🎍"},{"annotation":"Japanese dolls","group":6,"hexcode":"1F38E","order":3632,"tags":["celebration","doll","festival","japanese","japanese dolls"],"unicode":"🎎"},{"annotation":"carp streamer","group":6,"hexcode":"1F38F","order":3633,"tags":["carp","celebration","streamer"],"unicode":"🎏"},{"annotation":"wind chime","group":6,"hexcode":"1F390","order":3634,"tags":["bell","celebration","chime","wind"],"unicode":"🎐"},{"annotation":"moon viewing ceremony","group":6,"hexcode":"1F391","order":3635,"tags":["celebration","ceremony","moon"],"unicode":"🎑"},{"annotation":"red envelope","group":6,"hexcode":"1F9E7","order":3636,"tags":["gift","good luck","hóngbāo","lai see","money"],"unicode":"🧧"},{"annotation":"ribbon","group":6,"hexcode":"1F380","order":3637,"tags":["celebration"],"unicode":"🎀"},{"annotation":"wrapped gift","group":6,"hexcode":"1F381","order":3638,"tags":["box","celebration","gift","present","wrapped"],"unicode":"🎁"},{"annotation":"reminder ribbon","group":6,"hexcode":"1F397","order":3640,"tags":["celebration","reminder","ribbon"],"unicode":"🎗️"},{"annotation":"admission tickets","group":6,"hexcode":"1F39F","order":3642,"tags":["admission","ticket"],"unicode":"🎟️"},{"annotation":"ticket","group":6,"hexcode":"1F3AB","order":3643,"tags":["admission"],"unicode":"🎫"},{"annotation":"military medal","group":6,"hexcode":"1F396","order":3645,"tags":["celebration","medal","military"],"unicode":"🎖️"},{"annotation":"trophy","group":6,"hexcode":"1F3C6","order":3646,"tags":["prize"],"unicode":"🏆️"},{"annotation":"sports medal","group":6,"hexcode":"1F3C5","order":3647,"tags":["medal"],"unicode":"🏅"},{"annotation":"1st place medal","group":6,"hexcode":"1F947","order":3648,"tags":["first","gold","medal"],"unicode":"🥇"},{"annotation":"2nd place medal","group":6,"hexcode":"1F948","order":3649,"tags":["medal","second","silver"],"unicode":"🥈"},{"annotation":"3rd place medal","group":6,"hexcode":"1F949","order":3650,"tags":["bronze","medal","third"],"unicode":"🥉"},{"annotation":"soccer ball","group":6,"hexcode":"26BD","order":3651,"tags":["ball","football","soccer"],"unicode":"⚽️"},{"annotation":"baseball","group":6,"hexcode":"26BE","order":3652,"tags":["ball"],"unicode":"⚾️"},{"annotation":"softball","group":6,"hexcode":"1F94E","order":3653,"tags":["ball","glove","underarm"],"unicode":"🥎"},{"annotation":"basketball","group":6,"hexcode":"1F3C0","order":3654,"tags":["ball","hoop"],"unicode":"🏀"},{"annotation":"volleyball","group":6,"hexcode":"1F3D0","order":3655,"tags":["ball","game"],"unicode":"🏐"},{"annotation":"american football","group":6,"hexcode":"1F3C8","order":3656,"tags":["american","ball","football"],"unicode":"🏈"},{"annotation":"rugby football","group":6,"hexcode":"1F3C9","order":3657,"tags":["ball","football","rugby"],"unicode":"🏉"},{"annotation":"tennis","group":6,"hexcode":"1F3BE","order":3658,"tags":["ball","racquet"],"unicode":"🎾"},{"annotation":"flying disc","group":6,"hexcode":"1F94F","order":3659,"tags":["ultimate"],"unicode":"🥏"},{"annotation":"bowling","group":6,"hexcode":"1F3B3","order":3660,"tags":["ball","game"],"unicode":"🎳"},{"annotation":"cricket game","group":6,"hexcode":"1F3CF","order":3661,"tags":["ball","bat","game"],"unicode":"🏏"},{"annotation":"field hockey","group":6,"hexcode":"1F3D1","order":3662,"tags":["ball","field","game","hockey","stick"],"unicode":"🏑"},{"annotation":"ice hockey","group":6,"hexcode":"1F3D2","order":3663,"tags":["game","hockey","ice","puck","stick"],"unicode":"🏒"},{"annotation":"lacrosse","group":6,"hexcode":"1F94D","order":3664,"tags":["ball","goal","stick"],"unicode":"🥍"},{"annotation":"ping pong","group":6,"hexcode":"1F3D3","order":3665,"tags":["ball","bat","game","paddle","table tennis"],"unicode":"🏓"},{"annotation":"badminton","group":6,"hexcode":"1F3F8","order":3666,"tags":["birdie","game","racquet","shuttlecock"],"unicode":"🏸"},{"annotation":"boxing glove","group":6,"hexcode":"1F94A","order":3667,"tags":["boxing","glove"],"unicode":"🥊"},{"annotation":"martial arts uniform","group":6,"hexcode":"1F94B","order":3668,"tags":["judo","karate","martial arts","taekwondo","uniform"],"unicode":"🥋"},{"annotation":"goal net","group":6,"hexcode":"1F945","order":3669,"tags":["goal","net"],"unicode":"🥅"},{"annotation":"flag in hole","group":6,"hexcode":"26F3","order":3670,"tags":["golf","hole"],"unicode":"⛳️"},{"annotation":"ice skate","group":6,"hexcode":"26F8","order":3672,"tags":["ice","skate"],"unicode":"⛸️"},{"annotation":"fishing pole","group":6,"hexcode":"1F3A3","order":3673,"tags":["fish","pole"],"unicode":"🎣"},{"annotation":"diving mask","group":6,"hexcode":"1F93F","order":3674,"tags":["diving","scuba","snorkeling"],"unicode":"🤿"},{"annotation":"running shirt","group":6,"hexcode":"1F3BD","order":3675,"tags":["athletics","running","sash","shirt"],"unicode":"🎽"},{"annotation":"skis","group":6,"hexcode":"1F3BF","order":3676,"tags":["ski","snow"],"unicode":"🎿"},{"annotation":"sled","group":6,"hexcode":"1F6F7","order":3677,"tags":["sledge","sleigh"],"unicode":"🛷"},{"annotation":"curling stone","group":6,"hexcode":"1F94C","order":3678,"tags":["game","rock"],"unicode":"🥌"},{"annotation":"bullseye","group":6,"hexcode":"1F3AF","order":3679,"tags":["dart","direct hit","game","hit","target"],"unicode":"🎯"},{"annotation":"yo-yo","group":6,"hexcode":"1FA80","order":3680,"tags":["fluctuate","toy"],"unicode":"🪀"},{"annotation":"kite","group":6,"hexcode":"1FA81","order":3681,"tags":["fly","soar"],"unicode":"🪁"},{"annotation":"pool 8 ball","group":6,"hexcode":"1F3B1","order":3682,"tags":["8","ball","billiard","eight","game"],"unicode":"🎱"},{"annotation":"crystal ball","group":6,"hexcode":"1F52E","order":3683,"tags":["ball","crystal","fairy tale","fantasy","fortune","tool"],"unicode":"🔮"},{"annotation":"magic wand","group":6,"hexcode":"1FA84","order":3684,"tags":["magic","witch","wizard"],"unicode":"🪄"},{"annotation":"nazar amulet","group":6,"hexcode":"1F9FF","order":3685,"tags":["bead","charm","evil-eye","nazar","talisman"],"unicode":"🧿"},{"annotation":"video game","group":6,"hexcode":"1F3AE","order":3686,"tags":["controller","game"],"unicode":"🎮️"},{"annotation":"joystick","group":6,"hexcode":"1F579","order":3688,"tags":["game","video game"],"unicode":"🕹️"},{"annotation":"slot machine","group":6,"hexcode":"1F3B0","order":3689,"tags":["game","slot"],"unicode":"🎰"},{"annotation":"game die","group":6,"hexcode":"1F3B2","order":3690,"tags":["dice","die","game"],"unicode":"🎲"},{"annotation":"puzzle piece","group":6,"hexcode":"1F9E9","order":3691,"tags":["clue","interlocking","jigsaw","piece","puzzle"],"unicode":"🧩"},{"annotation":"teddy bear","group":6,"hexcode":"1F9F8","order":3692,"tags":["plaything","plush","stuffed","toy"],"unicode":"🧸"},{"annotation":"piñata","group":6,"hexcode":"1FA85","order":3693,"tags":["celebration","party"],"unicode":"🪅"},{"annotation":"nesting dolls","group":6,"hexcode":"1FA86","order":3694,"tags":["doll","nesting","russia"],"unicode":"🪆"},{"annotation":"spade suit","group":6,"hexcode":"2660","order":3696,"tags":["card","game"],"unicode":"♠️"},{"annotation":"heart suit","group":6,"hexcode":"2665","order":3698,"tags":["card","game"],"unicode":"♥️"},{"annotation":"diamond suit","group":6,"hexcode":"2666","order":3700,"tags":["card","game"],"unicode":"♦️"},{"annotation":"club suit","group":6,"hexcode":"2663","order":3702,"tags":["card","game"],"unicode":"♣️"},{"annotation":"chess pawn","group":6,"hexcode":"265F","order":3704,"tags":["chess","dupe","expendable"],"unicode":"♟️"},{"annotation":"joker","group":6,"hexcode":"1F0CF","order":3705,"tags":["card","game","wildcard"],"unicode":"🃏"},{"annotation":"mahjong red dragon","group":6,"hexcode":"1F004","order":3706,"tags":["game","mahjong","red"],"unicode":"🀄️"},{"annotation":"flower playing cards","group":6,"hexcode":"1F3B4","order":3707,"tags":["card","flower","game","japanese","playing"],"unicode":"🎴"},{"annotation":"performing arts","group":6,"hexcode":"1F3AD","order":3708,"tags":["art","mask","performing","theater","theatre"],"unicode":"🎭️"},{"annotation":"framed picture","group":6,"hexcode":"1F5BC","order":3710,"tags":["art","frame","museum","painting","picture"],"unicode":"🖼️"},{"annotation":"artist palette","group":6,"hexcode":"1F3A8","order":3711,"tags":["art","museum","painting","palette"],"unicode":"🎨"},{"annotation":"thread","group":6,"hexcode":"1F9F5","order":3712,"tags":["needle","sewing","spool","string"],"unicode":"🧵"},{"annotation":"sewing needle","group":6,"hexcode":"1FAA1","order":3713,"tags":["embroidery","needle","sewing","stitches","sutures","tailoring"],"unicode":"🪡"},{"annotation":"yarn","group":6,"hexcode":"1F9F6","order":3714,"tags":["ball","crochet","knit"],"unicode":"🧶"},{"annotation":"knot","group":6,"hexcode":"1FAA2","order":3715,"tags":["rope","tangled","tie","twine","twist"],"unicode":"🪢"},{"annotation":"glasses","group":7,"hexcode":"1F453","order":3716,"tags":["clothing","eye","eyeglasses","eyewear"],"unicode":"👓️"},{"annotation":"sunglasses","group":7,"hexcode":"1F576","order":3718,"tags":["dark","eye","eyewear","glasses"],"unicode":"🕶️"},{"annotation":"goggles","group":7,"hexcode":"1F97D","order":3719,"tags":["eye protection","swimming","welding"],"unicode":"🥽"},{"annotation":"lab coat","group":7,"hexcode":"1F97C","order":3720,"tags":["doctor","experiment","scientist"],"unicode":"🥼"},{"annotation":"safety vest","group":7,"hexcode":"1F9BA","order":3721,"tags":["emergency","safety","vest"],"unicode":"🦺"},{"annotation":"necktie","group":7,"hexcode":"1F454","order":3722,"tags":["clothing","tie"],"unicode":"👔"},{"annotation":"t-shirt","group":7,"hexcode":"1F455","order":3723,"tags":["clothing","shirt","tshirt"],"unicode":"👕"},{"annotation":"jeans","group":7,"hexcode":"1F456","order":3724,"tags":["clothing","pants","trousers"],"unicode":"👖"},{"annotation":"scarf","group":7,"hexcode":"1F9E3","order":3725,"tags":["neck"],"unicode":"🧣"},{"annotation":"gloves","group":7,"hexcode":"1F9E4","order":3726,"tags":["hand"],"unicode":"🧤"},{"annotation":"coat","group":7,"hexcode":"1F9E5","order":3727,"tags":["jacket"],"unicode":"🧥"},{"annotation":"socks","group":7,"hexcode":"1F9E6","order":3728,"tags":["stocking"],"unicode":"🧦"},{"annotation":"dress","group":7,"hexcode":"1F457","order":3729,"tags":["clothing"],"unicode":"👗"},{"annotation":"kimono","group":7,"hexcode":"1F458","order":3730,"tags":["clothing"],"unicode":"👘"},{"annotation":"sari","group":7,"hexcode":"1F97B","order":3731,"tags":["clothing","dress"],"unicode":"🥻"},{"annotation":"one-piece swimsuit","group":7,"hexcode":"1FA71","order":3732,"tags":["bathing suit"],"unicode":"🩱"},{"annotation":"briefs","group":7,"hexcode":"1FA72","order":3733,"tags":["bathing suit","one-piece","swimsuit","underwear"],"unicode":"🩲"},{"annotation":"shorts","group":7,"hexcode":"1FA73","order":3734,"tags":["bathing suit","pants","underwear"],"unicode":"🩳"},{"annotation":"bikini","group":7,"hexcode":"1F459","order":3735,"tags":["clothing","swim"],"unicode":"👙"},{"annotation":"woman’s clothes","group":7,"hexcode":"1F45A","order":3736,"tags":["clothing","woman"],"unicode":"👚"},{"annotation":"purse","group":7,"hexcode":"1F45B","order":3737,"tags":["clothing","coin"],"unicode":"👛"},{"annotation":"handbag","group":7,"hexcode":"1F45C","order":3738,"tags":["bag","clothing","purse"],"unicode":"👜"},{"annotation":"clutch bag","group":7,"hexcode":"1F45D","order":3739,"tags":["bag","clothing","pouch"],"unicode":"👝"},{"annotation":"shopping bags","group":7,"hexcode":"1F6CD","order":3741,"tags":["bag","hotel","shopping"],"unicode":"🛍️"},{"annotation":"backpack","group":7,"hexcode":"1F392","order":3742,"tags":["bag","rucksack","satchel","school"],"unicode":"🎒"},{"annotation":"thong sandal","group":7,"hexcode":"1FA74","order":3743,"tags":["beach sandals","sandals","thong sandals","thongs","zōri"],"unicode":"🩴"},{"annotation":"man’s shoe","group":7,"hexcode":"1F45E","order":3744,"tags":["clothing","man","shoe"],"unicode":"👞"},{"annotation":"running shoe","group":7,"hexcode":"1F45F","order":3745,"tags":["athletic","clothing","shoe","sneaker"],"unicode":"👟"},{"annotation":"hiking boot","group":7,"hexcode":"1F97E","order":3746,"tags":["backpacking","boot","camping","hiking"],"unicode":"🥾"},{"annotation":"flat shoe","group":7,"hexcode":"1F97F","order":3747,"tags":["ballet flat","slip-on","slipper"],"unicode":"🥿"},{"annotation":"high-heeled shoe","group":7,"hexcode":"1F460","order":3748,"tags":["clothing","heel","shoe","woman"],"unicode":"👠"},{"annotation":"woman’s sandal","group":7,"hexcode":"1F461","order":3749,"tags":["clothing","sandal","shoe","woman"],"unicode":"👡"},{"annotation":"ballet shoes","group":7,"hexcode":"1FA70","order":3750,"tags":["ballet","dance"],"unicode":"🩰"},{"annotation":"woman’s boot","group":7,"hexcode":"1F462","order":3751,"tags":["boot","clothing","shoe","woman"],"unicode":"👢"},{"annotation":"crown","group":7,"hexcode":"1F451","order":3752,"tags":["clothing","king","queen"],"unicode":"👑"},{"annotation":"woman’s hat","group":7,"hexcode":"1F452","order":3753,"tags":["clothing","hat","woman"],"unicode":"👒"},{"annotation":"top hat","group":7,"hexcode":"1F3A9","order":3754,"tags":["clothing","hat","top","tophat"],"unicode":"🎩"},{"annotation":"graduation cap","group":7,"hexcode":"1F393","order":3755,"tags":["cap","celebration","clothing","graduation","hat"],"unicode":"🎓️"},{"annotation":"billed cap","group":7,"hexcode":"1F9E2","order":3756,"tags":["baseball cap"],"unicode":"🧢"},{"annotation":"military helmet","group":7,"hexcode":"1FA96","order":3757,"tags":["army","helmet","military","soldier","warrior"],"unicode":"🪖"},{"annotation":"rescue worker’s helmet","group":7,"hexcode":"26D1","order":3759,"tags":["aid","cross","face","hat","helmet"],"unicode":"⛑️"},{"annotation":"prayer beads","group":7,"hexcode":"1F4FF","order":3760,"tags":["beads","clothing","necklace","prayer","religion"],"unicode":"📿"},{"annotation":"lipstick","group":7,"hexcode":"1F484","order":3761,"tags":["cosmetics","makeup"],"unicode":"💄"},{"annotation":"ring","group":7,"hexcode":"1F48D","order":3762,"tags":["diamond"],"unicode":"💍"},{"annotation":"gem stone","group":7,"hexcode":"1F48E","order":3763,"tags":["diamond","gem","jewel"],"unicode":"💎"},{"annotation":"muted speaker","group":7,"hexcode":"1F507","order":3764,"tags":["mute","quiet","silent","speaker"],"unicode":"🔇"},{"annotation":"speaker low volume","group":7,"hexcode":"1F508","order":3765,"tags":["soft"],"unicode":"🔈️"},{"annotation":"speaker medium volume","group":7,"hexcode":"1F509","order":3766,"tags":["medium"],"unicode":"🔉"},{"annotation":"speaker high volume","group":7,"hexcode":"1F50A","order":3767,"tags":["loud"],"unicode":"🔊"},{"annotation":"loudspeaker","group":7,"hexcode":"1F4E2","order":3768,"tags":["loud","public address"],"unicode":"📢"},{"annotation":"megaphone","group":7,"hexcode":"1F4E3","order":3769,"tags":["cheering"],"unicode":"📣"},{"annotation":"postal horn","group":7,"hexcode":"1F4EF","order":3770,"tags":["horn","post","postal"],"unicode":"📯"},{"annotation":"bell","group":7,"hexcode":"1F514","order":3771,"tags":["bell"],"unicode":"🔔"},{"annotation":"bell with slash","group":7,"hexcode":"1F515","order":3772,"tags":["bell","forbidden","mute","quiet","silent"],"unicode":"🔕"},{"annotation":"musical score","group":7,"hexcode":"1F3BC","order":3773,"tags":["music","score"],"unicode":"🎼"},{"annotation":"musical note","group":7,"hexcode":"1F3B5","order":3774,"tags":["music","note"],"unicode":"🎵"},{"annotation":"musical notes","group":7,"hexcode":"1F3B6","order":3775,"tags":["music","note","notes"],"unicode":"🎶"},{"annotation":"studio microphone","group":7,"hexcode":"1F399","order":3777,"tags":["mic","microphone","music","studio"],"unicode":"🎙️"},{"annotation":"level slider","group":7,"hexcode":"1F39A","order":3779,"tags":["level","music","slider"],"unicode":"🎚️"},{"annotation":"control knobs","group":7,"hexcode":"1F39B","order":3781,"tags":["control","knobs","music"],"unicode":"🎛️"},{"annotation":"microphone","group":7,"hexcode":"1F3A4","order":3782,"tags":["karaoke","mic"],"unicode":"🎤"},{"annotation":"headphone","group":7,"hexcode":"1F3A7","order":3783,"tags":["earbud"],"unicode":"🎧️"},{"annotation":"radio","group":7,"hexcode":"1F4FB","order":3784,"tags":["video"],"unicode":"📻️"},{"annotation":"saxophone","group":7,"hexcode":"1F3B7","order":3785,"tags":["instrument","music","sax"],"unicode":"🎷"},{"annotation":"accordion","group":7,"hexcode":"1FA97","order":3786,"tags":["concertina","squeeze box"],"unicode":"🪗"},{"annotation":"guitar","group":7,"hexcode":"1F3B8","order":3787,"tags":["instrument","music"],"unicode":"🎸"},{"annotation":"musical keyboard","group":7,"hexcode":"1F3B9","order":3788,"tags":["instrument","keyboard","music","piano"],"unicode":"🎹"},{"annotation":"trumpet","group":7,"hexcode":"1F3BA","order":3789,"tags":["instrument","music"],"unicode":"🎺"},{"annotation":"violin","group":7,"hexcode":"1F3BB","order":3790,"tags":["instrument","music"],"unicode":"🎻"},{"annotation":"banjo","group":7,"hexcode":"1FA95","order":3791,"tags":["music","stringed"],"unicode":"🪕"},{"annotation":"drum","group":7,"hexcode":"1F941","order":3792,"tags":["drumsticks","music"],"unicode":"🥁"},{"annotation":"long drum","group":7,"hexcode":"1FA98","order":3793,"tags":["beat","conga","drum","rhythm"],"unicode":"🪘"},{"annotation":"mobile phone","group":7,"hexcode":"1F4F1","order":3794,"tags":["cell","mobile","phone","telephone"],"unicode":"📱"},{"annotation":"mobile phone with arrow","group":7,"hexcode":"1F4F2","order":3795,"tags":["arrow","cell","mobile","phone","receive"],"unicode":"📲"},{"annotation":"telephone","group":7,"hexcode":"260E","order":3797,"tags":["phone"],"unicode":"☎️"},{"annotation":"telephone receiver","group":7,"hexcode":"1F4DE","order":3798,"tags":["phone","receiver","telephone"],"unicode":"📞"},{"annotation":"pager","group":7,"hexcode":"1F4DF","order":3799,"tags":["pager"],"unicode":"📟️"},{"annotation":"fax machine","group":7,"hexcode":"1F4E0","order":3800,"tags":["fax"],"unicode":"📠"},{"annotation":"battery","group":7,"hexcode":"1F50B","order":3801,"tags":["battery"],"unicode":"🔋"},{"annotation":"electric plug","group":7,"hexcode":"1F50C","order":3802,"tags":["electric","electricity","plug"],"unicode":"🔌"},{"annotation":"laptop","group":7,"hexcode":"1F4BB","order":3803,"tags":["computer","pc","personal"],"unicode":"💻️"},{"annotation":"desktop computer","group":7,"hexcode":"1F5A5","order":3805,"tags":["computer","desktop"],"unicode":"🖥️"},{"annotation":"printer","group":7,"hexcode":"1F5A8","order":3807,"tags":["computer"],"unicode":"🖨️"},{"annotation":"keyboard","group":7,"hexcode":"2328","order":3809,"tags":["computer"],"unicode":"⌨️"},{"annotation":"computer mouse","group":7,"hexcode":"1F5B1","order":3811,"tags":["computer"],"unicode":"🖱️"},{"annotation":"trackball","group":7,"hexcode":"1F5B2","order":3813,"tags":["computer"],"unicode":"🖲️"},{"annotation":"computer disk","group":7,"hexcode":"1F4BD","order":3814,"tags":["computer","disk","minidisk","optical"],"unicode":"💽"},{"annotation":"floppy disk","group":7,"hexcode":"1F4BE","order":3815,"tags":["computer","disk","floppy"],"unicode":"💾"},{"annotation":"optical disk","group":7,"hexcode":"1F4BF","order":3816,"tags":["cd","computer","disk","optical"],"unicode":"💿️"},{"annotation":"dvd","group":7,"hexcode":"1F4C0","order":3817,"tags":["blu-ray","computer","disk","optical"],"unicode":"📀"},{"annotation":"abacus","group":7,"hexcode":"1F9EE","order":3818,"tags":["calculation"],"unicode":"🧮"},{"annotation":"movie camera","group":7,"hexcode":"1F3A5","order":3819,"tags":["camera","cinema","movie"],"unicode":"🎥"},{"annotation":"film frames","group":7,"hexcode":"1F39E","order":3821,"tags":["cinema","film","frames","movie"],"unicode":"🎞️"},{"annotation":"film projector","group":7,"hexcode":"1F4FD","order":3823,"tags":["cinema","film","movie","projector","video"],"unicode":"📽️"},{"annotation":"clapper board","group":7,"hexcode":"1F3AC","order":3824,"tags":["clapper","movie"],"unicode":"🎬️"},{"annotation":"television","group":7,"hexcode":"1F4FA","order":3825,"tags":["tv","video"],"unicode":"📺️"},{"annotation":"camera","group":7,"hexcode":"1F4F7","order":3826,"tags":["video"],"unicode":"📷️"},{"annotation":"camera with flash","group":7,"hexcode":"1F4F8","order":3827,"tags":["camera","flash","video"],"unicode":"📸"},{"annotation":"video camera","group":7,"hexcode":"1F4F9","order":3828,"tags":["camera","video"],"unicode":"📹️"},{"annotation":"videocassette","group":7,"hexcode":"1F4FC","order":3829,"tags":["tape","vhs","video"],"unicode":"📼"},{"annotation":"magnifying glass tilted left","group":7,"hexcode":"1F50D","order":3830,"tags":["glass","magnifying","search","tool"],"unicode":"🔍️"},{"annotation":"magnifying glass tilted right","group":7,"hexcode":"1F50E","order":3831,"tags":["glass","magnifying","search","tool"],"unicode":"🔎"},{"annotation":"candle","group":7,"hexcode":"1F56F","order":3833,"tags":["light"],"unicode":"🕯️"},{"annotation":"light bulb","group":7,"hexcode":"1F4A1","order":3834,"tags":["bulb","comic","electric","idea","light"],"unicode":"💡"},{"annotation":"flashlight","group":7,"hexcode":"1F526","order":3835,"tags":["electric","light","tool","torch"],"unicode":"🔦"},{"annotation":"red paper lantern","group":7,"hexcode":"1F3EE","order":3836,"tags":["bar","lantern","light","red"],"unicode":"🏮"},{"annotation":"diya lamp","group":7,"hexcode":"1FA94","order":3837,"tags":["diya","lamp","oil"],"unicode":"🪔"},{"annotation":"notebook with decorative cover","group":7,"hexcode":"1F4D4","order":3838,"tags":["book","cover","decorated","notebook"],"unicode":"📔"},{"annotation":"closed book","group":7,"hexcode":"1F4D5","order":3839,"tags":["book","closed"],"unicode":"📕"},{"annotation":"open book","group":7,"hexcode":"1F4D6","order":3840,"tags":["book","open"],"unicode":"📖"},{"annotation":"green book","group":7,"hexcode":"1F4D7","order":3841,"tags":["book","green"],"unicode":"📗"},{"annotation":"blue book","group":7,"hexcode":"1F4D8","order":3842,"tags":["blue","book"],"unicode":"📘"},{"annotation":"orange book","group":7,"hexcode":"1F4D9","order":3843,"tags":["book","orange"],"unicode":"📙"},{"annotation":"books","group":7,"hexcode":"1F4DA","order":3844,"tags":["book"],"unicode":"📚️"},{"annotation":"notebook","group":7,"hexcode":"1F4D3","order":3845,"tags":["notebook"],"unicode":"📓"},{"annotation":"ledger","group":7,"hexcode":"1F4D2","order":3846,"tags":["notebook"],"unicode":"📒"},{"annotation":"page with curl","group":7,"hexcode":"1F4C3","order":3847,"tags":["curl","document","page"],"unicode":"📃"},{"annotation":"scroll","group":7,"hexcode":"1F4DC","order":3848,"tags":["paper"],"unicode":"📜"},{"annotation":"page facing up","group":7,"hexcode":"1F4C4","order":3849,"tags":["document","page"],"unicode":"📄"},{"annotation":"newspaper","group":7,"hexcode":"1F4F0","order":3850,"tags":["news","paper"],"unicode":"📰"},{"annotation":"rolled-up newspaper","group":7,"hexcode":"1F5DE","order":3852,"tags":["news","newspaper","paper","rolled"],"unicode":"🗞️"},{"annotation":"bookmark tabs","group":7,"hexcode":"1F4D1","order":3853,"tags":["bookmark","mark","marker","tabs"],"unicode":"📑"},{"annotation":"bookmark","group":7,"hexcode":"1F516","order":3854,"tags":["mark"],"unicode":"🔖"},{"annotation":"label","group":7,"hexcode":"1F3F7","order":3856,"tags":["label"],"unicode":"🏷️"},{"annotation":"money bag","group":7,"hexcode":"1F4B0","order":3857,"tags":["bag","dollar","money","moneybag"],"unicode":"💰️"},{"annotation":"coin","group":7,"hexcode":"1FA99","order":3858,"tags":["gold","metal","money","silver","treasure"],"unicode":"🪙"},{"annotation":"yen banknote","group":7,"hexcode":"1F4B4","order":3859,"tags":["banknote","bill","currency","money","note","yen"],"unicode":"💴"},{"annotation":"dollar banknote","group":7,"hexcode":"1F4B5","order":3860,"tags":["banknote","bill","currency","dollar","money","note"],"unicode":"💵"},{"annotation":"euro banknote","group":7,"hexcode":"1F4B6","order":3861,"tags":["banknote","bill","currency","euro","money","note"],"unicode":"💶"},{"annotation":"pound banknote","group":7,"hexcode":"1F4B7","order":3862,"tags":["banknote","bill","currency","money","note","pound"],"unicode":"💷"},{"annotation":"money with wings","group":7,"hexcode":"1F4B8","order":3863,"tags":["banknote","bill","fly","money","wings"],"unicode":"💸"},{"annotation":"credit card","group":7,"hexcode":"1F4B3","order":3864,"tags":["card","credit","money"],"unicode":"💳️"},{"annotation":"receipt","group":7,"hexcode":"1F9FE","order":3865,"tags":["accounting","bookkeeping","evidence","proof"],"unicode":"🧾"},{"annotation":"chart increasing with yen","group":7,"hexcode":"1F4B9","order":3866,"tags":["chart","graph","growth","money","yen"],"unicode":"💹"},{"annotation":"envelope","group":7,"hexcode":"2709","order":3868,"tags":["email","letter"],"unicode":"✉️"},{"annotation":"e-mail","group":7,"hexcode":"1F4E7","order":3869,"tags":["email","letter","mail"],"unicode":"📧"},{"annotation":"incoming envelope","group":7,"hexcode":"1F4E8","order":3870,"tags":["e-mail","email","envelope","incoming","letter","receive"],"unicode":"📨"},{"annotation":"envelope with arrow","group":7,"hexcode":"1F4E9","order":3871,"tags":["arrow","e-mail","email","envelope","outgoing"],"unicode":"📩"},{"annotation":"outbox tray","group":7,"hexcode":"1F4E4","order":3872,"tags":["box","letter","mail","outbox","sent","tray"],"unicode":"📤️"},{"annotation":"inbox tray","group":7,"hexcode":"1F4E5","order":3873,"tags":["box","inbox","letter","mail","receive","tray"],"unicode":"📥️"},{"annotation":"package","group":7,"hexcode":"1F4E6","order":3874,"tags":["box","parcel"],"unicode":"📦️"},{"annotation":"closed mailbox with raised flag","group":7,"hexcode":"1F4EB","order":3875,"tags":["closed","mail","mailbox","postbox"],"unicode":"📫️"},{"annotation":"closed mailbox with lowered flag","group":7,"hexcode":"1F4EA","order":3876,"tags":["closed","lowered","mail","mailbox","postbox"],"unicode":"📪️"},{"annotation":"open mailbox with raised flag","group":7,"hexcode":"1F4EC","order":3877,"tags":["mail","mailbox","open","postbox"],"unicode":"📬️"},{"annotation":"open mailbox with lowered flag","group":7,"hexcode":"1F4ED","order":3878,"tags":["lowered","mail","mailbox","open","postbox"],"unicode":"📭️"},{"annotation":"postbox","group":7,"hexcode":"1F4EE","order":3879,"tags":["mail","mailbox"],"unicode":"📮"},{"annotation":"ballot box with ballot","group":7,"hexcode":"1F5F3","order":3881,"tags":["ballot","box"],"unicode":"🗳️"},{"annotation":"pencil","group":7,"hexcode":"270F","order":3883,"tags":["pencil"],"unicode":"✏️"},{"annotation":"black nib","group":7,"hexcode":"2712","order":3885,"tags":["nib","pen"],"unicode":"✒️"},{"annotation":"fountain pen","group":7,"hexcode":"1F58B","order":3887,"tags":["fountain","pen"],"unicode":"🖋️"},{"annotation":"pen","group":7,"hexcode":"1F58A","order":3889,"tags":["ballpoint"],"unicode":"🖊️"},{"annotation":"paintbrush","group":7,"hexcode":"1F58C","order":3891,"tags":["painting"],"unicode":"🖌️"},{"annotation":"crayon","group":7,"hexcode":"1F58D","order":3893,"tags":["crayon"],"unicode":"🖍️"},{"annotation":"memo","group":7,"hexcode":"1F4DD","order":3894,"tags":["pencil"],"unicode":"📝"},{"annotation":"briefcase","group":7,"hexcode":"1F4BC","order":3895,"tags":["briefcase"],"unicode":"💼"},{"annotation":"file folder","group":7,"hexcode":"1F4C1","order":3896,"tags":["file","folder"],"unicode":"📁"},{"annotation":"open file folder","group":7,"hexcode":"1F4C2","order":3897,"tags":["file","folder","open"],"unicode":"📂"},{"annotation":"card index dividers","group":7,"hexcode":"1F5C2","order":3899,"tags":["card","dividers","index"],"unicode":"🗂️"},{"annotation":"calendar","group":7,"hexcode":"1F4C5","order":3900,"tags":["date"],"unicode":"📅"},{"annotation":"tear-off calendar","group":7,"hexcode":"1F4C6","order":3901,"tags":["calendar"],"unicode":"📆"},{"annotation":"spiral notepad","group":7,"hexcode":"1F5D2","order":3903,"tags":["note","pad","spiral"],"unicode":"🗒️"},{"annotation":"spiral calendar","group":7,"hexcode":"1F5D3","order":3905,"tags":["calendar","pad","spiral"],"unicode":"🗓️"},{"annotation":"card index","group":7,"hexcode":"1F4C7","order":3906,"tags":["card","index","rolodex"],"unicode":"📇"},{"annotation":"chart increasing","group":7,"hexcode":"1F4C8","order":3907,"tags":["chart","graph","growth","trend","upward"],"unicode":"📈"},{"annotation":"chart decreasing","group":7,"hexcode":"1F4C9","order":3908,"tags":["chart","down","graph","trend"],"unicode":"📉"},{"annotation":"bar chart","group":7,"hexcode":"1F4CA","order":3909,"tags":["bar","chart","graph"],"unicode":"📊"},{"annotation":"clipboard","group":7,"hexcode":"1F4CB","order":3910,"tags":["clipboard"],"unicode":"📋️"},{"annotation":"pushpin","group":7,"hexcode":"1F4CC","order":3911,"tags":["pin"],"unicode":"📌"},{"annotation":"round pushpin","group":7,"hexcode":"1F4CD","order":3912,"tags":["pin","pushpin"],"unicode":"📍"},{"annotation":"paperclip","group":7,"hexcode":"1F4CE","order":3913,"tags":["paperclip"],"unicode":"📎"},{"annotation":"linked paperclips","group":7,"hexcode":"1F587","order":3915,"tags":["link","paperclip"],"unicode":"🖇️"},{"annotation":"straight ruler","group":7,"hexcode":"1F4CF","order":3916,"tags":["ruler","straight edge"],"unicode":"📏"},{"annotation":"triangular ruler","group":7,"hexcode":"1F4D0","order":3917,"tags":["ruler","set","triangle"],"unicode":"📐"},{"annotation":"scissors","group":7,"hexcode":"2702","order":3919,"tags":["cutting","tool"],"unicode":"✂️"},{"annotation":"card file box","group":7,"hexcode":"1F5C3","order":3921,"tags":["box","card","file"],"unicode":"🗃️"},{"annotation":"file cabinet","group":7,"hexcode":"1F5C4","order":3923,"tags":["cabinet","file","filing"],"unicode":"🗄️"},{"annotation":"wastebasket","group":7,"hexcode":"1F5D1","order":3925,"tags":["wastebasket"],"unicode":"🗑️"},{"annotation":"locked","group":7,"hexcode":"1F512","order":3926,"tags":["closed"],"unicode":"🔒️"},{"annotation":"unlocked","group":7,"hexcode":"1F513","order":3927,"tags":["lock","open","unlock"],"unicode":"🔓️"},{"annotation":"locked with pen","group":7,"hexcode":"1F50F","order":3928,"tags":["ink","lock","nib","pen","privacy"],"unicode":"🔏"},{"annotation":"locked with key","group":7,"hexcode":"1F510","order":3929,"tags":["closed","key","lock","secure"],"unicode":"🔐"},{"annotation":"key","group":7,"hexcode":"1F511","order":3930,"tags":["lock","password"],"unicode":"🔑"},{"annotation":"old key","group":7,"hexcode":"1F5DD","order":3932,"tags":["clue","key","lock","old"],"unicode":"🗝️"},{"annotation":"hammer","group":7,"hexcode":"1F528","order":3933,"tags":["tool"],"unicode":"🔨"},{"annotation":"axe","group":7,"hexcode":"1FA93","order":3934,"tags":["chop","hatchet","split","wood"],"unicode":"🪓"},{"annotation":"pick","group":7,"hexcode":"26CF","order":3936,"tags":["mining","tool"],"unicode":"⛏️"},{"annotation":"hammer and pick","group":7,"hexcode":"2692","order":3938,"tags":["hammer","pick","tool"],"unicode":"⚒️"},{"annotation":"hammer and wrench","group":7,"hexcode":"1F6E0","order":3940,"tags":["hammer","spanner","tool","wrench"],"unicode":"🛠️"},{"annotation":"dagger","group":7,"hexcode":"1F5E1","order":3942,"tags":["knife","weapon"],"unicode":"🗡️"},{"annotation":"crossed swords","group":7,"hexcode":"2694","order":3944,"tags":["crossed","swords","weapon"],"unicode":"⚔️"},{"annotation":"water pistol","group":7,"hexcode":"1F52B","order":3945,"tags":["gun","handgun","pistol","revolver","tool","water","weapon"],"unicode":"🔫"},{"annotation":"boomerang","group":7,"hexcode":"1FA83","order":3946,"tags":["australia","rebound","repercussion"],"unicode":"🪃"},{"annotation":"bow and arrow","group":7,"hexcode":"1F3F9","order":3947,"tags":["archer","arrow","bow","sagittarius","zodiac"],"unicode":"🏹"},{"annotation":"shield","group":7,"hexcode":"1F6E1","order":3949,"tags":["weapon"],"unicode":"🛡️"},{"annotation":"carpentry saw","group":7,"hexcode":"1FA9A","order":3950,"tags":["carpenter","lumber","saw","tool"],"unicode":"🪚"},{"annotation":"wrench","group":7,"hexcode":"1F527","order":3951,"tags":["spanner","tool"],"unicode":"🔧"},{"annotation":"screwdriver","group":7,"hexcode":"1FA9B","order":3952,"tags":["screw","tool"],"unicode":"🪛"},{"annotation":"nut and bolt","group":7,"hexcode":"1F529","order":3953,"tags":["bolt","nut","tool"],"unicode":"🔩"},{"annotation":"gear","group":7,"hexcode":"2699","order":3955,"tags":["cog","cogwheel","tool"],"unicode":"⚙️"},{"annotation":"clamp","group":7,"hexcode":"1F5DC","order":3957,"tags":["compress","tool","vice"],"unicode":"🗜️"},{"annotation":"balance scale","group":7,"hexcode":"2696","order":3959,"tags":["balance","justice","libra","scale","zodiac"],"unicode":"⚖️"},{"annotation":"white cane","group":7,"hexcode":"1F9AF","order":3960,"tags":["accessibility","blind"],"unicode":"🦯"},{"annotation":"link","group":7,"hexcode":"1F517","order":3961,"tags":["link"],"unicode":"🔗"},{"annotation":"chains","group":7,"hexcode":"26D3","order":3963,"tags":["chain"],"unicode":"⛓️"},{"annotation":"hook","group":7,"hexcode":"1FA9D","order":3964,"tags":["catch","crook","curve","ensnare","selling point"],"unicode":"🪝"},{"annotation":"toolbox","group":7,"hexcode":"1F9F0","order":3965,"tags":["chest","mechanic","tool"],"unicode":"🧰"},{"annotation":"magnet","group":7,"hexcode":"1F9F2","order":3966,"tags":["attraction","horseshoe","magnetic"],"unicode":"🧲"},{"annotation":"ladder","group":7,"hexcode":"1FA9C","order":3967,"tags":["climb","rung","step"],"unicode":"🪜"},{"annotation":"alembic","group":7,"hexcode":"2697","order":3969,"tags":["chemistry","tool"],"unicode":"⚗️"},{"annotation":"test tube","group":7,"hexcode":"1F9EA","order":3970,"tags":["chemist","chemistry","experiment","lab","science"],"unicode":"🧪"},{"annotation":"petri dish","group":7,"hexcode":"1F9EB","order":3971,"tags":["bacteria","biologist","biology","culture","lab"],"unicode":"🧫"},{"annotation":"dna","group":7,"hexcode":"1F9EC","order":3972,"tags":["biologist","evolution","gene","genetics","life"],"unicode":"🧬"},{"annotation":"microscope","group":7,"hexcode":"1F52C","order":3973,"tags":["science","tool"],"unicode":"🔬"},{"annotation":"telescope","group":7,"hexcode":"1F52D","order":3974,"tags":["science","tool"],"unicode":"🔭"},{"annotation":"satellite antenna","group":7,"hexcode":"1F4E1","order":3975,"tags":["antenna","dish","satellite"],"unicode":"📡"},{"annotation":"syringe","group":7,"hexcode":"1F489","order":3976,"tags":["medicine","needle","shot","sick"],"unicode":"💉"},{"annotation":"drop of blood","group":7,"hexcode":"1FA78","order":3977,"tags":["bleed","blood donation","injury","medicine","menstruation"],"unicode":"🩸"},{"annotation":"pill","group":7,"hexcode":"1F48A","order":3978,"tags":["doctor","medicine","sick"],"unicode":"💊"},{"annotation":"adhesive bandage","group":7,"hexcode":"1FA79","order":3979,"tags":["bandage"],"unicode":"🩹"},{"annotation":"stethoscope","group":7,"hexcode":"1FA7A","order":3980,"tags":["doctor","heart","medicine"],"unicode":"🩺"},{"annotation":"door","group":7,"hexcode":"1F6AA","order":3981,"tags":["door"],"unicode":"🚪"},{"annotation":"elevator","group":7,"hexcode":"1F6D7","order":3982,"tags":["accessibility","hoist","lift"],"unicode":"🛗"},{"annotation":"mirror","group":7,"hexcode":"1FA9E","order":3983,"tags":["reflection","reflector","speculum"],"unicode":"🪞"},{"annotation":"window","group":7,"hexcode":"1FA9F","order":3984,"tags":["frame","fresh air","opening","transparent","view"],"unicode":"🪟"},{"annotation":"bed","group":7,"hexcode":"1F6CF","order":3986,"tags":["hotel","sleep"],"unicode":"🛏️"},{"annotation":"couch and lamp","group":7,"hexcode":"1F6CB","order":3988,"tags":["couch","hotel","lamp"],"unicode":"🛋️"},{"annotation":"chair","group":7,"hexcode":"1FA91","order":3989,"tags":["seat","sit"],"unicode":"🪑"},{"annotation":"toilet","group":7,"hexcode":"1F6BD","order":3990,"tags":["toilet"],"unicode":"🚽"},{"annotation":"plunger","group":7,"hexcode":"1FAA0","order":3991,"tags":["force cup","plumber","suction","toilet"],"unicode":"🪠"},{"annotation":"shower","group":7,"hexcode":"1F6BF","order":3992,"tags":["water"],"unicode":"🚿"},{"annotation":"bathtub","group":7,"hexcode":"1F6C1","order":3993,"tags":["bath"],"unicode":"🛁"},{"annotation":"mouse trap","group":7,"hexcode":"1FAA4","order":3994,"tags":["bait","mousetrap","snare","trap"],"unicode":"🪤"},{"annotation":"razor","group":7,"hexcode":"1FA92","order":3995,"tags":["sharp","shave"],"unicode":"🪒"},{"annotation":"lotion bottle","group":7,"hexcode":"1F9F4","order":3996,"tags":["lotion","moisturizer","shampoo","sunscreen"],"unicode":"🧴"},{"annotation":"safety pin","group":7,"hexcode":"1F9F7","order":3997,"tags":["diaper","punk rock"],"unicode":"🧷"},{"annotation":"broom","group":7,"hexcode":"1F9F9","order":3998,"tags":["cleaning","sweeping","witch"],"unicode":"🧹"},{"annotation":"basket","group":7,"hexcode":"1F9FA","order":3999,"tags":["farming","laundry","picnic"],"unicode":"🧺"},{"annotation":"roll of paper","group":7,"hexcode":"1F9FB","order":4000,"tags":["paper towels","toilet paper"],"unicode":"🧻"},{"annotation":"bucket","group":7,"hexcode":"1FAA3","order":4001,"tags":["cask","pail","vat"],"unicode":"🪣"},{"annotation":"soap","group":7,"hexcode":"1F9FC","order":4002,"tags":["bar","bathing","cleaning","lather","soapdish"],"unicode":"🧼"},{"annotation":"toothbrush","group":7,"hexcode":"1FAA5","order":4003,"tags":["bathroom","brush","clean","dental","hygiene","teeth"],"unicode":"🪥"},{"annotation":"sponge","group":7,"hexcode":"1F9FD","order":4004,"tags":["absorbing","cleaning","porous"],"unicode":"🧽"},{"annotation":"fire extinguisher","group":7,"hexcode":"1F9EF","order":4005,"tags":["extinguish","fire","quench"],"unicode":"🧯"},{"annotation":"shopping cart","group":7,"hexcode":"1F6D2","order":4006,"tags":["cart","shopping","trolley"],"unicode":"🛒"},{"annotation":"cigarette","group":7,"hexcode":"1F6AC","order":4007,"tags":["smoking"],"unicode":"🚬"},{"annotation":"coffin","group":7,"hexcode":"26B0","order":4009,"tags":["death"],"unicode":"⚰️"},{"annotation":"headstone","group":7,"hexcode":"1FAA6","order":4010,"tags":["cemetery","grave","graveyard","tombstone"],"unicode":"🪦"},{"annotation":"funeral urn","group":7,"hexcode":"26B1","order":4012,"tags":["ashes","death","funeral","urn"],"unicode":"⚱️"},{"annotation":"moai","group":7,"hexcode":"1F5FF","order":4013,"tags":["face","moyai","statue"],"unicode":"🗿"},{"annotation":"placard","group":7,"hexcode":"1FAA7","order":4014,"tags":["demonstration","picket","protest","sign"],"unicode":"🪧"},{"annotation":"ATM sign","group":8,"hexcode":"1F3E7","order":4015,"tags":["atm","atm sign","automated","bank","teller"],"unicode":"🏧"},{"annotation":"litter in bin sign","group":8,"hexcode":"1F6AE","order":4016,"tags":["litter","litter bin"],"unicode":"🚮"},{"annotation":"potable water","group":8,"hexcode":"1F6B0","order":4017,"tags":["drinking","potable","water"],"unicode":"🚰"},{"annotation":"wheelchair symbol","group":8,"hexcode":"267F","order":4018,"tags":["access"],"unicode":"♿️"},{"annotation":"men’s room","group":8,"hexcode":"1F6B9","order":4019,"tags":["lavatory","man","restroom","wc"],"unicode":"🚹️"},{"annotation":"women’s room","group":8,"hexcode":"1F6BA","order":4020,"tags":["lavatory","restroom","wc","woman"],"unicode":"🚺️"},{"annotation":"restroom","group":8,"hexcode":"1F6BB","order":4021,"tags":["lavatory","wc"],"unicode":"🚻"},{"annotation":"baby symbol","group":8,"hexcode":"1F6BC","order":4022,"tags":["baby","changing"],"unicode":"🚼️"},{"annotation":"water closet","group":8,"hexcode":"1F6BE","order":4023,"tags":["closet","lavatory","restroom","water","wc"],"unicode":"🚾"},{"annotation":"passport control","group":8,"hexcode":"1F6C2","order":4024,"tags":["control","passport"],"unicode":"🛂"},{"annotation":"customs","group":8,"hexcode":"1F6C3","order":4025,"tags":["customs"],"unicode":"🛃"},{"annotation":"baggage claim","group":8,"hexcode":"1F6C4","order":4026,"tags":["baggage","claim"],"unicode":"🛄"},{"annotation":"left luggage","group":8,"hexcode":"1F6C5","order":4027,"tags":["baggage","locker","luggage"],"unicode":"🛅"},{"annotation":"warning","group":8,"hexcode":"26A0","order":4029,"tags":["warning"],"unicode":"⚠️"},{"annotation":"children crossing","group":8,"hexcode":"1F6B8","order":4030,"tags":["child","crossing","pedestrian","traffic"],"unicode":"🚸"},{"annotation":"no entry","group":8,"hexcode":"26D4","order":4031,"tags":["entry","forbidden","no","not","prohibited","traffic"],"unicode":"⛔️"},{"annotation":"prohibited","group":8,"hexcode":"1F6AB","order":4032,"tags":["entry","forbidden","no","not"],"unicode":"🚫"},{"annotation":"no bicycles","group":8,"hexcode":"1F6B3","order":4033,"tags":["bicycle","bike","forbidden","no","prohibited"],"unicode":"🚳"},{"annotation":"no smoking","group":8,"hexcode":"1F6AD","order":4034,"tags":["forbidden","no","not","prohibited","smoking"],"unicode":"🚭️"},{"annotation":"no littering","group":8,"hexcode":"1F6AF","order":4035,"tags":["forbidden","litter","no","not","prohibited"],"unicode":"🚯"},{"annotation":"non-potable water","group":8,"hexcode":"1F6B1","order":4036,"tags":["non-drinking","non-potable","water"],"unicode":"🚱"},{"annotation":"no pedestrians","group":8,"hexcode":"1F6B7","order":4037,"tags":["forbidden","no","not","pedestrian","prohibited"],"unicode":"🚷"},{"annotation":"no mobile phones","group":8,"hexcode":"1F4F5","order":4038,"tags":["cell","forbidden","mobile","no","phone"],"unicode":"📵"},{"annotation":"no one under eighteen","group":8,"hexcode":"1F51E","order":4039,"tags":["18","age restriction","eighteen","prohibited","underage"],"unicode":"🔞"},{"annotation":"radioactive","group":8,"hexcode":"2622","order":4041,"tags":["sign"],"unicode":"☢️"},{"annotation":"biohazard","group":8,"hexcode":"2623","order":4043,"tags":["sign"],"unicode":"☣️"},{"annotation":"up arrow","group":8,"hexcode":"2B06","order":4045,"tags":["arrow","cardinal","direction","north"],"unicode":"⬆️"},{"annotation":"up-right arrow","group":8,"hexcode":"2197","order":4047,"tags":["arrow","direction","intercardinal","northeast"],"unicode":"↗️"},{"annotation":"right arrow","group":8,"hexcode":"27A1","order":4049,"tags":["arrow","cardinal","direction","east"],"unicode":"➡️"},{"annotation":"down-right arrow","group":8,"hexcode":"2198","order":4051,"tags":["arrow","direction","intercardinal","southeast"],"unicode":"↘️"},{"annotation":"down arrow","group":8,"hexcode":"2B07","order":4053,"tags":["arrow","cardinal","direction","down","south"],"unicode":"⬇️"},{"annotation":"down-left arrow","group":8,"hexcode":"2199","order":4055,"tags":["arrow","direction","intercardinal","southwest"],"unicode":"↙️"},{"annotation":"left arrow","group":8,"hexcode":"2B05","order":4057,"tags":["arrow","cardinal","direction","west"],"unicode":"⬅️"},{"annotation":"up-left arrow","group":8,"hexcode":"2196","order":4059,"tags":["arrow","direction","intercardinal","northwest"],"unicode":"↖️"},{"annotation":"up-down arrow","group":8,"hexcode":"2195","order":4061,"tags":["arrow"],"unicode":"↕️"},{"annotation":"left-right arrow","group":8,"hexcode":"2194","order":4063,"tags":["arrow"],"unicode":"↔️"},{"annotation":"right arrow curving left","group":8,"hexcode":"21A9","order":4065,"tags":["arrow"],"unicode":"↩️"},{"annotation":"left arrow curving right","group":8,"hexcode":"21AA","order":4067,"tags":["arrow"],"unicode":"↪️"},{"annotation":"right arrow curving up","group":8,"hexcode":"2934","order":4069,"tags":["arrow"],"unicode":"⤴️"},{"annotation":"right arrow curving down","group":8,"hexcode":"2935","order":4071,"tags":["arrow","down"],"unicode":"⤵️"},{"annotation":"clockwise vertical arrows","group":8,"hexcode":"1F503","order":4072,"tags":["arrow","clockwise","reload"],"unicode":"🔃"},{"annotation":"counterclockwise arrows button","group":8,"hexcode":"1F504","order":4073,"tags":["anticlockwise","arrow","counterclockwise","withershins"],"unicode":"🔄"},{"annotation":"BACK arrow","group":8,"hexcode":"1F519","order":4074,"tags":["arrow","back","back arrow"],"unicode":"🔙"},{"annotation":"END arrow","group":8,"hexcode":"1F51A","order":4075,"tags":["arrow","end","end arrow"],"unicode":"🔚"},{"annotation":"ON! arrow","group":8,"hexcode":"1F51B","order":4076,"tags":["arrow","mark","on","on! arrow"],"unicode":"🔛"},{"annotation":"SOON arrow","group":8,"hexcode":"1F51C","order":4077,"tags":["arrow","soon","soon arrow"],"unicode":"🔜"},{"annotation":"TOP arrow","group":8,"hexcode":"1F51D","order":4078,"tags":["arrow","top","top arrow","up"],"unicode":"🔝"},{"annotation":"place of worship","group":8,"hexcode":"1F6D0","order":4079,"tags":["religion","worship"],"unicode":"🛐"},{"annotation":"atom symbol","group":8,"hexcode":"269B","order":4081,"tags":["atheist","atom"],"unicode":"⚛️"},{"annotation":"om","group":8,"hexcode":"1F549","order":4083,"tags":["hindu","religion"],"unicode":"🕉️"},{"annotation":"star of David","group":8,"hexcode":"2721","order":4085,"tags":["david","jew","jewish","religion","star","star of david"],"unicode":"✡️"},{"annotation":"wheel of dharma","group":8,"hexcode":"2638","order":4087,"tags":["buddhist","dharma","religion","wheel"],"unicode":"☸️"},{"annotation":"yin yang","group":8,"hexcode":"262F","order":4089,"tags":["religion","tao","taoist","yang","yin"],"unicode":"☯️"},{"annotation":"latin cross","group":8,"hexcode":"271D","order":4091,"tags":["christian","cross","religion"],"unicode":"✝️"},{"annotation":"orthodox cross","group":8,"hexcode":"2626","order":4093,"tags":["christian","cross","religion"],"unicode":"☦️"},{"annotation":"star and crescent","group":8,"hexcode":"262A","order":4095,"tags":["islam","muslim","religion"],"unicode":"☪️"},{"annotation":"peace symbol","group":8,"hexcode":"262E","order":4097,"tags":["peace"],"unicode":"☮️"},{"annotation":"menorah","group":8,"hexcode":"1F54E","order":4098,"tags":["candelabrum","candlestick","religion"],"unicode":"🕎"},{"annotation":"dotted six-pointed star","group":8,"hexcode":"1F52F","order":4099,"tags":["fortune","star"],"unicode":"🔯"},{"annotation":"Aries","group":8,"hexcode":"2648","order":4100,"tags":["aries","ram","zodiac"],"unicode":"♈️"},{"annotation":"Taurus","group":8,"hexcode":"2649","order":4101,"tags":["bull","ox","taurus","zodiac"],"unicode":"♉️"},{"annotation":"Gemini","group":8,"hexcode":"264A","order":4102,"tags":["gemini","twins","zodiac"],"unicode":"♊️"},{"annotation":"Cancer","group":8,"hexcode":"264B","order":4103,"tags":["cancer","crab","zodiac"],"unicode":"♋️"},{"annotation":"Leo","group":8,"hexcode":"264C","order":4104,"tags":["leo","lion","zodiac"],"unicode":"♌️"},{"annotation":"Virgo","group":8,"hexcode":"264D","order":4105,"tags":["virgo","zodiac"],"unicode":"♍️"},{"annotation":"Libra","group":8,"hexcode":"264E","order":4106,"tags":["balance","justice","libra","scales","zodiac"],"unicode":"♎️"},{"annotation":"Scorpio","group":8,"hexcode":"264F","order":4107,"tags":["scorpio","scorpion","scorpius","zodiac"],"unicode":"♏️"},{"annotation":"Sagittarius","group":8,"hexcode":"2650","order":4108,"tags":["archer","sagittarius","zodiac"],"unicode":"♐️"},{"annotation":"Capricorn","group":8,"hexcode":"2651","order":4109,"tags":["capricorn","goat","zodiac"],"unicode":"♑️"},{"annotation":"Aquarius","group":8,"hexcode":"2652","order":4110,"tags":["aquarius","bearer","water","zodiac"],"unicode":"♒️"},{"annotation":"Pisces","group":8,"hexcode":"2653","order":4111,"tags":["fish","pisces","zodiac"],"unicode":"♓️"},{"annotation":"Ophiuchus","group":8,"hexcode":"26CE","order":4112,"tags":["bearer","ophiuchus","serpent","snake","zodiac"],"unicode":"⛎"},{"annotation":"shuffle tracks button","group":8,"hexcode":"1F500","order":4113,"tags":["arrow","crossed"],"unicode":"🔀"},{"annotation":"repeat button","group":8,"hexcode":"1F501","order":4114,"tags":["arrow","clockwise","repeat"],"unicode":"🔁"},{"annotation":"repeat single button","group":8,"hexcode":"1F502","order":4115,"tags":["arrow","clockwise","once"],"unicode":"🔂"},{"annotation":"play button","group":8,"hexcode":"25B6","order":4117,"tags":["arrow","play","right","triangle"],"unicode":"▶️"},{"annotation":"fast-forward button","group":8,"hexcode":"23E9","order":4118,"tags":["arrow","double","fast","forward"],"unicode":"⏩️"},{"annotation":"next track button","group":8,"hexcode":"23ED","order":4120,"tags":["arrow","next scene","next track","triangle"],"unicode":"⏭️"},{"annotation":"play or pause button","group":8,"hexcode":"23EF","order":4122,"tags":["arrow","pause","play","right","triangle"],"unicode":"⏯️"},{"annotation":"reverse button","group":8,"hexcode":"25C0","order":4124,"tags":["arrow","left","reverse","triangle"],"unicode":"◀️"},{"annotation":"fast reverse button","group":8,"hexcode":"23EA","order":4125,"tags":["arrow","double","rewind"],"unicode":"⏪️"},{"annotation":"last track button","group":8,"hexcode":"23EE","order":4127,"tags":["arrow","previous scene","previous track","triangle"],"unicode":"⏮️"},{"annotation":"upwards button","group":8,"hexcode":"1F53C","order":4128,"tags":["arrow","button","red"],"unicode":"🔼"},{"annotation":"fast up button","group":8,"hexcode":"23EB","order":4129,"tags":["arrow","double"],"unicode":"⏫"},{"annotation":"downwards button","group":8,"hexcode":"1F53D","order":4130,"tags":["arrow","button","down","red"],"unicode":"🔽"},{"annotation":"fast down button","group":8,"hexcode":"23EC","order":4131,"tags":["arrow","double","down"],"unicode":"⏬"},{"annotation":"pause button","group":8,"hexcode":"23F8","order":4133,"tags":["bar","double","pause","vertical"],"unicode":"⏸️"},{"annotation":"stop button","group":8,"hexcode":"23F9","order":4135,"tags":["square","stop"],"unicode":"⏹️"},{"annotation":"record button","group":8,"hexcode":"23FA","order":4137,"tags":["circle","record"],"unicode":"⏺️"},{"annotation":"eject button","group":8,"hexcode":"23CF","order":4139,"tags":["eject"],"unicode":"⏏️"},{"annotation":"cinema","group":8,"hexcode":"1F3A6","order":4140,"tags":["camera","film","movie"],"unicode":"🎦"},{"annotation":"dim button","group":8,"hexcode":"1F505","order":4141,"tags":["brightness","dim","low"],"unicode":"🔅"},{"annotation":"bright button","group":8,"hexcode":"1F506","order":4142,"tags":["bright","brightness"],"unicode":"🔆"},{"annotation":"antenna bars","group":8,"hexcode":"1F4F6","order":4143,"tags":["antenna","bar","cell","mobile","phone"],"unicode":"📶"},{"annotation":"vibration mode","group":8,"hexcode":"1F4F3","order":4144,"tags":["cell","mobile","mode","phone","telephone","vibration"],"unicode":"📳"},{"annotation":"mobile phone off","group":8,"hexcode":"1F4F4","order":4145,"tags":["cell","mobile","off","phone","telephone"],"unicode":"📴"},{"annotation":"female sign","group":8,"hexcode":"2640","order":4147,"tags":["woman"],"unicode":"♀️"},{"annotation":"male sign","group":8,"hexcode":"2642","order":4149,"tags":["man"],"unicode":"♂️"},{"annotation":"transgender symbol","group":8,"hexcode":"26A7","order":4151,"tags":["transgender"],"unicode":"⚧️"},{"annotation":"multiply","group":8,"hexcode":"2716","order":4153,"tags":["cancel","multiplication","sign","x","×"],"unicode":"✖️"},{"annotation":"plus","group":8,"hexcode":"2795","order":4154,"tags":["+","math","sign"],"unicode":"➕"},{"annotation":"minus","group":8,"hexcode":"2796","order":4155,"tags":["-","math","sign","−"],"unicode":"➖"},{"annotation":"divide","group":8,"hexcode":"2797","order":4156,"tags":["division","math","sign","÷"],"unicode":"➗"},{"annotation":"infinity","group":8,"hexcode":"267E","order":4158,"tags":["forever","unbounded","universal"],"unicode":"♾️"},{"annotation":"double exclamation mark","group":8,"hexcode":"203C","order":4160,"tags":["!","!!","bangbang","exclamation","mark"],"unicode":"‼️"},{"annotation":"exclamation question mark","group":8,"hexcode":"2049","order":4162,"tags":["!","!?","?","exclamation","interrobang","mark","punctuation","question"],"unicode":"⁉️"},{"annotation":"red question mark","group":8,"hexcode":"2753","order":4163,"tags":["?","mark","punctuation","question"],"unicode":"❓️"},{"annotation":"white question mark","group":8,"hexcode":"2754","order":4164,"tags":["?","mark","outlined","punctuation","question"],"unicode":"❔"},{"annotation":"white exclamation mark","group":8,"hexcode":"2755","order":4165,"tags":["!","exclamation","mark","outlined","punctuation"],"unicode":"❕"},{"annotation":"red exclamation mark","group":8,"hexcode":"2757","order":4166,"tags":["!","exclamation","mark","punctuation"],"unicode":"❗️"},{"annotation":"wavy dash","group":8,"hexcode":"3030","order":4168,"tags":["dash","punctuation","wavy"],"unicode":"〰️"},{"annotation":"currency exchange","group":8,"hexcode":"1F4B1","order":4169,"tags":["bank","currency","exchange","money"],"unicode":"💱"},{"annotation":"heavy dollar sign","group":8,"hexcode":"1F4B2","order":4170,"tags":["currency","dollar","money"],"unicode":"💲"},{"annotation":"medical symbol","group":8,"hexcode":"2695","order":4172,"tags":["aesculapius","medicine","staff"],"unicode":"⚕️"},{"annotation":"recycling symbol","group":8,"hexcode":"267B","order":4174,"tags":["recycle"],"unicode":"♻️"},{"annotation":"fleur-de-lis","group":8,"hexcode":"269C","order":4176,"tags":["fleur-de-lis"],"unicode":"⚜️"},{"annotation":"trident emblem","group":8,"hexcode":"1F531","order":4177,"tags":["anchor","emblem","ship","tool","trident"],"unicode":"🔱"},{"annotation":"name badge","group":8,"hexcode":"1F4DB","order":4178,"tags":["badge","name"],"unicode":"📛"},{"annotation":"Japanese symbol for beginner","group":8,"hexcode":"1F530","order":4179,"tags":["beginner","chevron","japanese","japanese symbol for beginner","leaf"],"unicode":"🔰"},{"annotation":"hollow red circle","group":8,"hexcode":"2B55","order":4180,"tags":["circle","large","o","red"],"unicode":"⭕️"},{"annotation":"check mark button","group":8,"hexcode":"2705","order":4181,"tags":["button","check","mark","✓"],"unicode":"✅"},{"annotation":"check box with check","group":8,"hexcode":"2611","order":4183,"tags":["box","check","✓"],"unicode":"☑️"},{"annotation":"check mark","group":8,"hexcode":"2714","order":4185,"tags":["check","mark","✓"],"unicode":"✔️"},{"annotation":"cross mark","group":8,"hexcode":"274C","order":4186,"tags":["cancel","cross","mark","multiplication","multiply","x","×"],"unicode":"❌"},{"annotation":"cross mark button","group":8,"hexcode":"274E","order":4187,"tags":["mark","square","x","×"],"unicode":"❎"},{"annotation":"curly loop","group":8,"hexcode":"27B0","order":4188,"tags":["curl","loop"],"unicode":"➰"},{"annotation":"double curly loop","group":8,"hexcode":"27BF","order":4189,"tags":["curl","double","loop"],"unicode":"➿"},{"annotation":"part alternation mark","group":8,"hexcode":"303D","order":4191,"tags":["mark","part"],"unicode":"〽️"},{"annotation":"eight-spoked asterisk","group":8,"hexcode":"2733","order":4193,"tags":["*","asterisk"],"unicode":"✳️"},{"annotation":"eight-pointed star","group":8,"hexcode":"2734","order":4195,"tags":["*","star"],"unicode":"✴️"},{"annotation":"sparkle","group":8,"hexcode":"2747","order":4197,"tags":["*"],"unicode":"❇️"},{"annotation":"copyright","group":8,"hexcode":"00A9","order":4199,"tags":["c"],"unicode":"©️"},{"annotation":"registered","group":8,"hexcode":"00AE","order":4201,"tags":["r"],"unicode":"®️"},{"annotation":"trade mark","group":8,"hexcode":"2122","order":4203,"tags":["mark","tm","trademark"],"unicode":"™️"},{"annotation":"keycap: #","group":8,"hexcode":"0023-FE0F-20E3","order":4204,"tags":["keycap"],"unicode":"#️⃣"},{"annotation":"keycap: *","group":8,"hexcode":"002A-FE0F-20E3","order":4206,"tags":["keycap"],"unicode":"*️⃣"},{"annotation":"keycap: 0","group":8,"hexcode":"0030-FE0F-20E3","order":4208,"tags":["keycap"],"unicode":"0️⃣"},{"annotation":"keycap: 1","group":8,"hexcode":"0031-FE0F-20E3","order":4210,"tags":["keycap"],"unicode":"1️⃣"},{"annotation":"keycap: 2","group":8,"hexcode":"0032-FE0F-20E3","order":4212,"tags":["keycap"],"unicode":"2️⃣"},{"annotation":"keycap: 3","group":8,"hexcode":"0033-FE0F-20E3","order":4214,"tags":["keycap"],"unicode":"3️⃣"},{"annotation":"keycap: 4","group":8,"hexcode":"0034-FE0F-20E3","order":4216,"tags":["keycap"],"unicode":"4️⃣"},{"annotation":"keycap: 5","group":8,"hexcode":"0035-FE0F-20E3","order":4218,"tags":["keycap"],"unicode":"5️⃣"},{"annotation":"keycap: 6","group":8,"hexcode":"0036-FE0F-20E3","order":4220,"tags":["keycap"],"unicode":"6️⃣"},{"annotation":"keycap: 7","group":8,"hexcode":"0037-FE0F-20E3","order":4222,"tags":["keycap"],"unicode":"7️⃣"},{"annotation":"keycap: 8","group":8,"hexcode":"0038-FE0F-20E3","order":4224,"tags":["keycap"],"unicode":"8️⃣"},{"annotation":"keycap: 9","group":8,"hexcode":"0039-FE0F-20E3","order":4226,"tags":["keycap"],"unicode":"9️⃣"},{"annotation":"keycap: 10","group":8,"hexcode":"1F51F","order":4228,"tags":["keycap"],"unicode":"🔟"},{"annotation":"input latin uppercase","group":8,"hexcode":"1F520","order":4229,"tags":["abcd","input","latin","letters","uppercase"],"unicode":"🔠"},{"annotation":"input latin lowercase","group":8,"hexcode":"1F521","order":4230,"tags":["abcd","input","latin","letters","lowercase"],"unicode":"🔡"},{"annotation":"input numbers","group":8,"hexcode":"1F522","order":4231,"tags":["1234","input","numbers"],"unicode":"🔢"},{"annotation":"input symbols","group":8,"hexcode":"1F523","order":4232,"tags":["input","〒♪&%"],"unicode":"🔣"},{"annotation":"input latin letters","group":8,"hexcode":"1F524","order":4233,"tags":["abc","alphabet","input","latin","letters"],"unicode":"🔤"},{"annotation":"A button (blood type)","group":8,"hexcode":"1F170","order":4235,"tags":["a","a button (blood type)","blood type"],"unicode":"🅰️"},{"annotation":"AB button (blood type)","group":8,"hexcode":"1F18E","order":4236,"tags":["ab","ab button (blood type)","blood type"],"unicode":"🆎"},{"annotation":"B button (blood type)","group":8,"hexcode":"1F171","order":4238,"tags":["b","b button (blood type)","blood type"],"unicode":"🅱️"},{"annotation":"CL button","group":8,"hexcode":"1F191","order":4239,"tags":["cl","cl button"],"unicode":"🆑"},{"annotation":"COOL button","group":8,"hexcode":"1F192","order":4240,"tags":["cool","cool button"],"unicode":"🆒"},{"annotation":"FREE button","group":8,"hexcode":"1F193","order":4241,"tags":["free","free button"],"unicode":"🆓"},{"annotation":"information","group":8,"hexcode":"2139","order":4243,"tags":["i"],"unicode":"ℹ️"},{"annotation":"ID button","group":8,"hexcode":"1F194","order":4244,"tags":["id","id button","identity"],"unicode":"🆔"},{"annotation":"circled M","group":8,"hexcode":"24C2","order":4246,"tags":["circle","circled m","m"],"unicode":"Ⓜ️"},{"annotation":"NEW button","group":8,"hexcode":"1F195","order":4247,"tags":["new","new button"],"unicode":"🆕"},{"annotation":"NG button","group":8,"hexcode":"1F196","order":4248,"tags":["ng","ng button"],"unicode":"🆖"},{"annotation":"O button (blood type)","group":8,"hexcode":"1F17E","order":4250,"tags":["blood type","o","o button (blood type)"],"unicode":"🅾️"},{"annotation":"OK button","group":8,"hexcode":"1F197","order":4251,"tags":["ok","ok button"],"unicode":"🆗"},{"annotation":"P button","group":8,"hexcode":"1F17F","order":4253,"tags":["p button","parking"],"unicode":"🅿️"},{"annotation":"SOS button","group":8,"hexcode":"1F198","order":4254,"tags":["help","sos","sos button"],"unicode":"🆘"},{"annotation":"UP! button","group":8,"hexcode":"1F199","order":4255,"tags":["mark","up","up! button"],"unicode":"🆙"},{"annotation":"VS button","group":8,"hexcode":"1F19A","order":4256,"tags":["versus","vs","vs button"],"unicode":"🆚"},{"annotation":"Japanese “here” button","group":8,"hexcode":"1F201","order":4257,"tags":["japanese","japanese “here” button","katakana","“here”","ココ"],"unicode":"🈁"},{"annotation":"Japanese “service charge” button","group":8,"hexcode":"1F202","order":4259,"tags":["japanese","japanese “service charge” button","katakana","“service charge”","サ"],"unicode":"🈂️"},{"annotation":"Japanese “monthly amount” button","group":8,"hexcode":"1F237","order":4261,"tags":["ideograph","japanese","japanese “monthly amount” button","“monthly amount”","月"],"unicode":"🈷️"},{"annotation":"Japanese “not free of charge” button","group":8,"hexcode":"1F236","order":4262,"tags":["ideograph","japanese","japanese “not free of charge” button","“not free of charge”","有"],"unicode":"🈶"},{"annotation":"Japanese “reserved” button","group":8,"hexcode":"1F22F","order":4263,"tags":["ideograph","japanese","japanese “reserved” button","“reserved”","指"],"unicode":"🈯️"},{"annotation":"Japanese “bargain” button","group":8,"hexcode":"1F250","order":4264,"tags":["ideograph","japanese","japanese “bargain” button","“bargain”","得"],"unicode":"🉐"},{"annotation":"Japanese “discount” button","group":8,"hexcode":"1F239","order":4265,"tags":["ideograph","japanese","japanese “discount” button","“discount”","割"],"unicode":"🈹"},{"annotation":"Japanese “free of charge” button","group":8,"hexcode":"1F21A","order":4266,"tags":["ideograph","japanese","japanese “free of charge” button","“free of charge”","無"],"unicode":"🈚️"},{"annotation":"Japanese “prohibited” button","group":8,"hexcode":"1F232","order":4267,"tags":["ideograph","japanese","japanese “prohibited” button","“prohibited”","禁"],"unicode":"🈲"},{"annotation":"Japanese “acceptable” button","group":8,"hexcode":"1F251","order":4268,"tags":["ideograph","japanese","japanese “acceptable” button","“acceptable”","可"],"unicode":"🉑"},{"annotation":"Japanese “application” button","group":8,"hexcode":"1F238","order":4269,"tags":["ideograph","japanese","japanese “application” button","“application”","申"],"unicode":"🈸"},{"annotation":"Japanese “passing grade” button","group":8,"hexcode":"1F234","order":4270,"tags":["ideograph","japanese","japanese “passing grade” button","“passing grade”","合"],"unicode":"🈴"},{"annotation":"Japanese “vacancy” button","group":8,"hexcode":"1F233","order":4271,"tags":["ideograph","japanese","japanese “vacancy” button","“vacancy”","空"],"unicode":"🈳"},{"annotation":"Japanese “congratulations” button","group":8,"hexcode":"3297","order":4273,"tags":["ideograph","japanese","japanese “congratulations” button","“congratulations”","祝"],"unicode":"㊗️"},{"annotation":"Japanese “secret” button","group":8,"hexcode":"3299","order":4275,"tags":["ideograph","japanese","japanese “secret” button","“secret”","秘"],"unicode":"㊙️"},{"annotation":"Japanese “open for business” button","group":8,"hexcode":"1F23A","order":4276,"tags":["ideograph","japanese","japanese “open for business” button","“open for business”","営"],"unicode":"🈺"},{"annotation":"Japanese “no vacancy” button","group":8,"hexcode":"1F235","order":4277,"tags":["ideograph","japanese","japanese “no vacancy” button","“no vacancy”","満"],"unicode":"🈵"},{"annotation":"red circle","group":8,"hexcode":"1F534","order":4278,"tags":["circle","geometric","red"],"unicode":"🔴"},{"annotation":"orange circle","group":8,"hexcode":"1F7E0","order":4279,"tags":["circle","orange"],"unicode":"🟠"},{"annotation":"yellow circle","group":8,"hexcode":"1F7E1","order":4280,"tags":["circle","yellow"],"unicode":"🟡"},{"annotation":"green circle","group":8,"hexcode":"1F7E2","order":4281,"tags":["circle","green"],"unicode":"🟢"},{"annotation":"blue circle","group":8,"hexcode":"1F535","order":4282,"tags":["blue","circle","geometric"],"unicode":"🔵"},{"annotation":"purple circle","group":8,"hexcode":"1F7E3","order":4283,"tags":["circle","purple"],"unicode":"🟣"},{"annotation":"brown circle","group":8,"hexcode":"1F7E4","order":4284,"tags":["brown","circle"],"unicode":"🟤"},{"annotation":"black circle","group":8,"hexcode":"26AB","order":4285,"tags":["circle","geometric"],"unicode":"⚫️"},{"annotation":"white circle","group":8,"hexcode":"26AA","order":4286,"tags":["circle","geometric"],"unicode":"⚪️"},{"annotation":"red square","group":8,"hexcode":"1F7E5","order":4287,"tags":["red","square"],"unicode":"🟥"},{"annotation":"orange square","group":8,"hexcode":"1F7E7","order":4288,"tags":["orange","square"],"unicode":"🟧"},{"annotation":"yellow square","group":8,"hexcode":"1F7E8","order":4289,"tags":["square","yellow"],"unicode":"🟨"},{"annotation":"green square","group":8,"hexcode":"1F7E9","order":4290,"tags":["green","square"],"unicode":"🟩"},{"annotation":"blue square","group":8,"hexcode":"1F7E6","order":4291,"tags":["blue","square"],"unicode":"🟦"},{"annotation":"purple square","group":8,"hexcode":"1F7EA","order":4292,"tags":["purple","square"],"unicode":"🟪"},{"annotation":"brown square","group":8,"hexcode":"1F7EB","order":4293,"tags":["brown","square"],"unicode":"🟫"},{"annotation":"black large square","group":8,"hexcode":"2B1B","order":4294,"tags":["geometric","square"],"unicode":"⬛️"},{"annotation":"white large square","group":8,"hexcode":"2B1C","order":4295,"tags":["geometric","square"],"unicode":"⬜️"},{"annotation":"black medium square","group":8,"hexcode":"25FC","order":4297,"tags":["geometric","square"],"unicode":"◼️"},{"annotation":"white medium square","group":8,"hexcode":"25FB","order":4299,"tags":["geometric","square"],"unicode":"◻️"},{"annotation":"black medium-small square","group":8,"hexcode":"25FE","order":4300,"tags":["geometric","square"],"unicode":"◾️"},{"annotation":"white medium-small square","group":8,"hexcode":"25FD","order":4301,"tags":["geometric","square"],"unicode":"◽️"},{"annotation":"black small square","group":8,"hexcode":"25AA","order":4303,"tags":["geometric","square"],"unicode":"▪️"},{"annotation":"white small square","group":8,"hexcode":"25AB","order":4305,"tags":["geometric","square"],"unicode":"▫️"},{"annotation":"large orange diamond","group":8,"hexcode":"1F536","order":4306,"tags":["diamond","geometric","orange"],"unicode":"🔶"},{"annotation":"large blue diamond","group":8,"hexcode":"1F537","order":4307,"tags":["blue","diamond","geometric"],"unicode":"🔷"},{"annotation":"small orange diamond","group":8,"hexcode":"1F538","order":4308,"tags":["diamond","geometric","orange"],"unicode":"🔸"},{"annotation":"small blue diamond","group":8,"hexcode":"1F539","order":4309,"tags":["blue","diamond","geometric"],"unicode":"🔹"},{"annotation":"red triangle pointed up","group":8,"hexcode":"1F53A","order":4310,"tags":["geometric","red"],"unicode":"🔺"},{"annotation":"red triangle pointed down","group":8,"hexcode":"1F53B","order":4311,"tags":["down","geometric","red"],"unicode":"🔻"},{"annotation":"diamond with a dot","group":8,"hexcode":"1F4A0","order":4312,"tags":["comic","diamond","geometric","inside"],"unicode":"💠"},{"annotation":"radio button","group":8,"hexcode":"1F518","order":4313,"tags":["button","geometric","radio"],"unicode":"🔘"},{"annotation":"white square button","group":8,"hexcode":"1F533","order":4314,"tags":["button","geometric","outlined","square"],"unicode":"🔳"},{"annotation":"black square button","group":8,"hexcode":"1F532","order":4315,"tags":["button","geometric","square"],"unicode":"🔲"},{"annotation":"chequered flag","group":9,"hexcode":"1F3C1","order":4316,"tags":["checkered","chequered","racing"],"unicode":"🏁"},{"annotation":"triangular flag","group":9,"hexcode":"1F6A9","order":4317,"tags":["post"],"unicode":"🚩"},{"annotation":"crossed flags","group":9,"hexcode":"1F38C","order":4318,"tags":["celebration","cross","crossed","japanese"],"unicode":"🎌"},{"annotation":"black flag","group":9,"hexcode":"1F3F4","order":4319,"tags":["waving"],"unicode":"🏴"},{"annotation":"white flag","group":9,"hexcode":"1F3F3","order":4321,"tags":["waving"],"unicode":"🏳️"},{"annotation":"rainbow flag","group":9,"hexcode":"1F3F3-FE0F-200D-1F308","order":4322,"tags":["pride","rainbow"],"unicode":"🏳️‍🌈"},{"annotation":"transgender flag","group":9,"hexcode":"1F3F3-FE0F-200D-26A7-FE0F","order":4324,"tags":["flag","light blue","pink","transgender","white"],"unicode":"🏳️‍⚧️"},{"annotation":"pirate flag","group":9,"hexcode":"1F3F4-200D-2620-FE0F","order":4328,"tags":["jolly roger","pirate","plunder","treasure"],"unicode":"🏴‍☠️"},{"annotation":"flag: Ascension Island","group":9,"hexcode":"1F1E6-1F1E8","order":4330,"tags":["AC","flag"],"unicode":"🇦🇨"},{"annotation":"flag: Andorra","group":9,"hexcode":"1F1E6-1F1E9","order":4331,"tags":["AD","flag"],"unicode":"🇦🇩"},{"annotation":"flag: United Arab Emirates","group":9,"hexcode":"1F1E6-1F1EA","order":4332,"tags":["AE","flag"],"unicode":"🇦🇪"},{"annotation":"flag: Afghanistan","group":9,"hexcode":"1F1E6-1F1EB","order":4333,"tags":["AF","flag"],"unicode":"🇦🇫"},{"annotation":"flag: Antigua & Barbuda","group":9,"hexcode":"1F1E6-1F1EC","order":4334,"tags":["AG","flag"],"unicode":"🇦🇬"},{"annotation":"flag: Anguilla","group":9,"hexcode":"1F1E6-1F1EE","order":4335,"tags":["AI","flag"],"unicode":"🇦🇮"},{"annotation":"flag: Albania","group":9,"hexcode":"1F1E6-1F1F1","order":4336,"tags":["AL","flag"],"unicode":"🇦🇱"},{"annotation":"flag: Armenia","group":9,"hexcode":"1F1E6-1F1F2","order":4337,"tags":["AM","flag"],"unicode":"🇦🇲"},{"annotation":"flag: Angola","group":9,"hexcode":"1F1E6-1F1F4","order":4338,"tags":["AO","flag"],"unicode":"🇦🇴"},{"annotation":"flag: Antarctica","group":9,"hexcode":"1F1E6-1F1F6","order":4339,"tags":["AQ","flag"],"unicode":"🇦🇶"},{"annotation":"flag: Argentina","group":9,"hexcode":"1F1E6-1F1F7","order":4340,"tags":["AR","flag"],"unicode":"🇦🇷"},{"annotation":"flag: American Samoa","group":9,"hexcode":"1F1E6-1F1F8","order":4341,"tags":["AS","flag"],"unicode":"🇦🇸"},{"annotation":"flag: Austria","group":9,"hexcode":"1F1E6-1F1F9","order":4342,"tags":["AT","flag"],"unicode":"🇦🇹"},{"annotation":"flag: Australia","group":9,"hexcode":"1F1E6-1F1FA","order":4343,"tags":["AU","flag"],"unicode":"🇦🇺"},{"annotation":"flag: Aruba","group":9,"hexcode":"1F1E6-1F1FC","order":4344,"tags":["AW","flag"],"unicode":"🇦🇼"},{"annotation":"flag: Åland Islands","group":9,"hexcode":"1F1E6-1F1FD","order":4345,"tags":["AX","flag"],"unicode":"🇦🇽"},{"annotation":"flag: Azerbaijan","group":9,"hexcode":"1F1E6-1F1FF","order":4346,"tags":["AZ","flag"],"unicode":"🇦🇿"},{"annotation":"flag: Bosnia & Herzegovina","group":9,"hexcode":"1F1E7-1F1E6","order":4347,"tags":["BA","flag"],"unicode":"🇧🇦"},{"annotation":"flag: Barbados","group":9,"hexcode":"1F1E7-1F1E7","order":4348,"tags":["BB","flag"],"unicode":"🇧🇧"},{"annotation":"flag: Bangladesh","group":9,"hexcode":"1F1E7-1F1E9","order":4349,"tags":["BD","flag"],"unicode":"🇧🇩"},{"annotation":"flag: Belgium","group":9,"hexcode":"1F1E7-1F1EA","order":4350,"tags":["BE","flag"],"unicode":"🇧🇪"},{"annotation":"flag: Burkina Faso","group":9,"hexcode":"1F1E7-1F1EB","order":4351,"tags":["BF","flag"],"unicode":"🇧🇫"},{"annotation":"flag: Bulgaria","group":9,"hexcode":"1F1E7-1F1EC","order":4352,"tags":["BG","flag"],"unicode":"🇧🇬"},{"annotation":"flag: Bahrain","group":9,"hexcode":"1F1E7-1F1ED","order":4353,"tags":["BH","flag"],"unicode":"🇧🇭"},{"annotation":"flag: Burundi","group":9,"hexcode":"1F1E7-1F1EE","order":4354,"tags":["BI","flag"],"unicode":"🇧🇮"},{"annotation":"flag: Benin","group":9,"hexcode":"1F1E7-1F1EF","order":4355,"tags":["BJ","flag"],"unicode":"🇧🇯"},{"annotation":"flag: St. Barthélemy","group":9,"hexcode":"1F1E7-1F1F1","order":4356,"tags":["BL","flag"],"unicode":"🇧🇱"},{"annotation":"flag: Bermuda","group":9,"hexcode":"1F1E7-1F1F2","order":4357,"tags":["BM","flag"],"unicode":"🇧🇲"},{"annotation":"flag: Brunei","group":9,"hexcode":"1F1E7-1F1F3","order":4358,"tags":["BN","flag"],"unicode":"🇧🇳"},{"annotation":"flag: Bolivia","group":9,"hexcode":"1F1E7-1F1F4","order":4359,"tags":["BO","flag"],"unicode":"🇧🇴"},{"annotation":"flag: Caribbean Netherlands","group":9,"hexcode":"1F1E7-1F1F6","order":4360,"tags":["BQ","flag"],"unicode":"🇧🇶"},{"annotation":"flag: Brazil","group":9,"hexcode":"1F1E7-1F1F7","order":4361,"tags":["BR","flag"],"unicode":"🇧🇷"},{"annotation":"flag: Bahamas","group":9,"hexcode":"1F1E7-1F1F8","order":4362,"tags":["BS","flag"],"unicode":"🇧🇸"},{"annotation":"flag: Bhutan","group":9,"hexcode":"1F1E7-1F1F9","order":4363,"tags":["BT","flag"],"unicode":"🇧🇹"},{"annotation":"flag: Bouvet Island","group":9,"hexcode":"1F1E7-1F1FB","order":4364,"tags":["BV","flag"],"unicode":"🇧🇻"},{"annotation":"flag: Botswana","group":9,"hexcode":"1F1E7-1F1FC","order":4365,"tags":["BW","flag"],"unicode":"🇧🇼"},{"annotation":"flag: Belarus","group":9,"hexcode":"1F1E7-1F1FE","order":4366,"tags":["BY","flag"],"unicode":"🇧🇾"},{"annotation":"flag: Belize","group":9,"hexcode":"1F1E7-1F1FF","order":4367,"tags":["BZ","flag"],"unicode":"🇧🇿"},{"annotation":"flag: Canada","group":9,"hexcode":"1F1E8-1F1E6","order":4368,"tags":["CA","flag"],"unicode":"🇨🇦"},{"annotation":"flag: Cocos (Keeling) Islands","group":9,"hexcode":"1F1E8-1F1E8","order":4369,"tags":["CC","flag"],"unicode":"🇨🇨"},{"annotation":"flag: Congo - Kinshasa","group":9,"hexcode":"1F1E8-1F1E9","order":4370,"tags":["CD","flag"],"unicode":"🇨🇩"},{"annotation":"flag: Central African Republic","group":9,"hexcode":"1F1E8-1F1EB","order":4371,"tags":["CF","flag"],"unicode":"🇨🇫"},{"annotation":"flag: Congo - Brazzaville","group":9,"hexcode":"1F1E8-1F1EC","order":4372,"tags":["CG","flag"],"unicode":"🇨🇬"},{"annotation":"flag: Switzerland","group":9,"hexcode":"1F1E8-1F1ED","order":4373,"tags":["CH","flag"],"unicode":"🇨🇭"},{"annotation":"flag: Côte d’Ivoire","group":9,"hexcode":"1F1E8-1F1EE","order":4374,"tags":["CI","flag"],"unicode":"🇨🇮"},{"annotation":"flag: Cook Islands","group":9,"hexcode":"1F1E8-1F1F0","order":4375,"tags":["CK","flag"],"unicode":"🇨🇰"},{"annotation":"flag: Chile","group":9,"hexcode":"1F1E8-1F1F1","order":4376,"tags":["CL","flag"],"unicode":"🇨🇱"},{"annotation":"flag: Cameroon","group":9,"hexcode":"1F1E8-1F1F2","order":4377,"tags":["CM","flag"],"unicode":"🇨🇲"},{"annotation":"flag: China","group":9,"hexcode":"1F1E8-1F1F3","order":4378,"tags":["CN","flag"],"unicode":"🇨🇳"},{"annotation":"flag: Colombia","group":9,"hexcode":"1F1E8-1F1F4","order":4379,"tags":["CO","flag"],"unicode":"🇨🇴"},{"annotation":"flag: Clipperton Island","group":9,"hexcode":"1F1E8-1F1F5","order":4380,"tags":["CP","flag"],"unicode":"🇨🇵"},{"annotation":"flag: Costa Rica","group":9,"hexcode":"1F1E8-1F1F7","order":4381,"tags":["CR","flag"],"unicode":"🇨🇷"},{"annotation":"flag: Cuba","group":9,"hexcode":"1F1E8-1F1FA","order":4382,"tags":["CU","flag"],"unicode":"🇨🇺"},{"annotation":"flag: Cape Verde","group":9,"hexcode":"1F1E8-1F1FB","order":4383,"tags":["CV","flag"],"unicode":"🇨🇻"},{"annotation":"flag: Curaçao","group":9,"hexcode":"1F1E8-1F1FC","order":4384,"tags":["CW","flag"],"unicode":"🇨🇼"},{"annotation":"flag: Christmas Island","group":9,"hexcode":"1F1E8-1F1FD","order":4385,"tags":["CX","flag"],"unicode":"🇨🇽"},{"annotation":"flag: Cyprus","group":9,"hexcode":"1F1E8-1F1FE","order":4386,"tags":["CY","flag"],"unicode":"🇨🇾"},{"annotation":"flag: Czechia","group":9,"hexcode":"1F1E8-1F1FF","order":4387,"tags":["CZ","flag"],"unicode":"🇨🇿"},{"annotation":"flag: Germany","group":9,"hexcode":"1F1E9-1F1EA","order":4388,"tags":["DE","flag"],"unicode":"🇩🇪"},{"annotation":"flag: Diego Garcia","group":9,"hexcode":"1F1E9-1F1EC","order":4389,"tags":["DG","flag"],"unicode":"🇩🇬"},{"annotation":"flag: Djibouti","group":9,"hexcode":"1F1E9-1F1EF","order":4390,"tags":["DJ","flag"],"unicode":"🇩🇯"},{"annotation":"flag: Denmark","group":9,"hexcode":"1F1E9-1F1F0","order":4391,"tags":["DK","flag"],"unicode":"🇩🇰"},{"annotation":"flag: Dominica","group":9,"hexcode":"1F1E9-1F1F2","order":4392,"tags":["DM","flag"],"unicode":"🇩🇲"},{"annotation":"flag: Dominican Republic","group":9,"hexcode":"1F1E9-1F1F4","order":4393,"tags":["DO","flag"],"unicode":"🇩🇴"},{"annotation":"flag: Algeria","group":9,"hexcode":"1F1E9-1F1FF","order":4394,"tags":["DZ","flag"],"unicode":"🇩🇿"},{"annotation":"flag: Ceuta & Melilla","group":9,"hexcode":"1F1EA-1F1E6","order":4395,"tags":["EA","flag"],"unicode":"🇪🇦"},{"annotation":"flag: Ecuador","group":9,"hexcode":"1F1EA-1F1E8","order":4396,"tags":["EC","flag"],"unicode":"🇪🇨"},{"annotation":"flag: Estonia","group":9,"hexcode":"1F1EA-1F1EA","order":4397,"tags":["EE","flag"],"unicode":"🇪🇪"},{"annotation":"flag: Egypt","group":9,"hexcode":"1F1EA-1F1EC","order":4398,"tags":["EG","flag"],"unicode":"🇪🇬"},{"annotation":"flag: Western Sahara","group":9,"hexcode":"1F1EA-1F1ED","order":4399,"tags":["EH","flag"],"unicode":"🇪🇭"},{"annotation":"flag: Eritrea","group":9,"hexcode":"1F1EA-1F1F7","order":4400,"tags":["ER","flag"],"unicode":"🇪🇷"},{"annotation":"flag: Spain","group":9,"hexcode":"1F1EA-1F1F8","order":4401,"tags":["ES","flag"],"unicode":"🇪🇸"},{"annotation":"flag: Ethiopia","group":9,"hexcode":"1F1EA-1F1F9","order":4402,"tags":["ET","flag"],"unicode":"🇪🇹"},{"annotation":"flag: European Union","group":9,"hexcode":"1F1EA-1F1FA","order":4403,"tags":["EU","flag"],"unicode":"🇪🇺"},{"annotation":"flag: Finland","group":9,"hexcode":"1F1EB-1F1EE","order":4404,"tags":["FI","flag"],"unicode":"🇫🇮"},{"annotation":"flag: Fiji","group":9,"hexcode":"1F1EB-1F1EF","order":4405,"tags":["FJ","flag"],"unicode":"🇫🇯"},{"annotation":"flag: Falkland Islands","group":9,"hexcode":"1F1EB-1F1F0","order":4406,"tags":["FK","flag"],"unicode":"🇫🇰"},{"annotation":"flag: Micronesia","group":9,"hexcode":"1F1EB-1F1F2","order":4407,"tags":["FM","flag"],"unicode":"🇫🇲"},{"annotation":"flag: Faroe Islands","group":9,"hexcode":"1F1EB-1F1F4","order":4408,"tags":["FO","flag"],"unicode":"🇫🇴"},{"annotation":"flag: France","group":9,"hexcode":"1F1EB-1F1F7","order":4409,"tags":["FR","flag"],"unicode":"🇫🇷"},{"annotation":"flag: Gabon","group":9,"hexcode":"1F1EC-1F1E6","order":4410,"tags":["GA","flag"],"unicode":"🇬🇦"},{"annotation":"flag: United Kingdom","group":9,"hexcode":"1F1EC-1F1E7","order":4411,"tags":["GB","flag"],"unicode":"🇬🇧"},{"annotation":"flag: Grenada","group":9,"hexcode":"1F1EC-1F1E9","order":4412,"tags":["GD","flag"],"unicode":"🇬🇩"},{"annotation":"flag: Georgia","group":9,"hexcode":"1F1EC-1F1EA","order":4413,"tags":["GE","flag"],"unicode":"🇬🇪"},{"annotation":"flag: French Guiana","group":9,"hexcode":"1F1EC-1F1EB","order":4414,"tags":["GF","flag"],"unicode":"🇬🇫"},{"annotation":"flag: Guernsey","group":9,"hexcode":"1F1EC-1F1EC","order":4415,"tags":["GG","flag"],"unicode":"🇬🇬"},{"annotation":"flag: Ghana","group":9,"hexcode":"1F1EC-1F1ED","order":4416,"tags":["GH","flag"],"unicode":"🇬🇭"},{"annotation":"flag: Gibraltar","group":9,"hexcode":"1F1EC-1F1EE","order":4417,"tags":["GI","flag"],"unicode":"🇬🇮"},{"annotation":"flag: Greenland","group":9,"hexcode":"1F1EC-1F1F1","order":4418,"tags":["GL","flag"],"unicode":"🇬🇱"},{"annotation":"flag: Gambia","group":9,"hexcode":"1F1EC-1F1F2","order":4419,"tags":["GM","flag"],"unicode":"🇬🇲"},{"annotation":"flag: Guinea","group":9,"hexcode":"1F1EC-1F1F3","order":4420,"tags":["GN","flag"],"unicode":"🇬🇳"},{"annotation":"flag: Guadeloupe","group":9,"hexcode":"1F1EC-1F1F5","order":4421,"tags":["GP","flag"],"unicode":"🇬🇵"},{"annotation":"flag: Equatorial Guinea","group":9,"hexcode":"1F1EC-1F1F6","order":4422,"tags":["GQ","flag"],"unicode":"🇬🇶"},{"annotation":"flag: Greece","group":9,"hexcode":"1F1EC-1F1F7","order":4423,"tags":["GR","flag"],"unicode":"🇬🇷"},{"annotation":"flag: South Georgia & South Sandwich Islands","group":9,"hexcode":"1F1EC-1F1F8","order":4424,"tags":["GS","flag"],"unicode":"🇬🇸"},{"annotation":"flag: Guatemala","group":9,"hexcode":"1F1EC-1F1F9","order":4425,"tags":["GT","flag"],"unicode":"🇬🇹"},{"annotation":"flag: Guam","group":9,"hexcode":"1F1EC-1F1FA","order":4426,"tags":["GU","flag"],"unicode":"🇬🇺"},{"annotation":"flag: Guinea-Bissau","group":9,"hexcode":"1F1EC-1F1FC","order":4427,"tags":["GW","flag"],"unicode":"🇬🇼"},{"annotation":"flag: Guyana","group":9,"hexcode":"1F1EC-1F1FE","order":4428,"tags":["GY","flag"],"unicode":"🇬🇾"},{"annotation":"flag: Hong Kong SAR China","group":9,"hexcode":"1F1ED-1F1F0","order":4429,"tags":["HK","flag"],"unicode":"🇭🇰"},{"annotation":"flag: Heard & McDonald Islands","group":9,"hexcode":"1F1ED-1F1F2","order":4430,"tags":["HM","flag"],"unicode":"🇭🇲"},{"annotation":"flag: Honduras","group":9,"hexcode":"1F1ED-1F1F3","order":4431,"tags":["HN","flag"],"unicode":"🇭🇳"},{"annotation":"flag: Croatia","group":9,"hexcode":"1F1ED-1F1F7","order":4432,"tags":["HR","flag"],"unicode":"🇭🇷"},{"annotation":"flag: Haiti","group":9,"hexcode":"1F1ED-1F1F9","order":4433,"tags":["HT","flag"],"unicode":"🇭🇹"},{"annotation":"flag: Hungary","group":9,"hexcode":"1F1ED-1F1FA","order":4434,"tags":["HU","flag"],"unicode":"🇭🇺"},{"annotation":"flag: Canary Islands","group":9,"hexcode":"1F1EE-1F1E8","order":4435,"tags":["IC","flag"],"unicode":"🇮🇨"},{"annotation":"flag: Indonesia","group":9,"hexcode":"1F1EE-1F1E9","order":4436,"tags":["ID","flag"],"unicode":"🇮🇩"},{"annotation":"flag: Ireland","group":9,"hexcode":"1F1EE-1F1EA","order":4437,"tags":["IE","flag"],"unicode":"🇮🇪"},{"annotation":"flag: Israel","group":9,"hexcode":"1F1EE-1F1F1","order":4438,"tags":["IL","flag"],"unicode":"🇮🇱"},{"annotation":"flag: Isle of Man","group":9,"hexcode":"1F1EE-1F1F2","order":4439,"tags":["IM","flag"],"unicode":"🇮🇲"},{"annotation":"flag: India","group":9,"hexcode":"1F1EE-1F1F3","order":4440,"tags":["IN","flag"],"unicode":"🇮🇳"},{"annotation":"flag: British Indian Ocean Territory","group":9,"hexcode":"1F1EE-1F1F4","order":4441,"tags":["IO","flag"],"unicode":"🇮🇴"},{"annotation":"flag: Iraq","group":9,"hexcode":"1F1EE-1F1F6","order":4442,"tags":["IQ","flag"],"unicode":"🇮🇶"},{"annotation":"flag: Iran","group":9,"hexcode":"1F1EE-1F1F7","order":4443,"tags":["IR","flag"],"unicode":"🇮🇷"},{"annotation":"flag: Iceland","group":9,"hexcode":"1F1EE-1F1F8","order":4444,"tags":["IS","flag"],"unicode":"🇮🇸"},{"annotation":"flag: Italy","group":9,"hexcode":"1F1EE-1F1F9","order":4445,"tags":["IT","flag"],"unicode":"🇮🇹"},{"annotation":"flag: Jersey","group":9,"hexcode":"1F1EF-1F1EA","order":4446,"tags":["JE","flag"],"unicode":"🇯🇪"},{"annotation":"flag: Jamaica","group":9,"hexcode":"1F1EF-1F1F2","order":4447,"tags":["JM","flag"],"unicode":"🇯🇲"},{"annotation":"flag: Jordan","group":9,"hexcode":"1F1EF-1F1F4","order":4448,"tags":["JO","flag"],"unicode":"🇯🇴"},{"annotation":"flag: Japan","group":9,"hexcode":"1F1EF-1F1F5","order":4449,"tags":["JP","flag"],"unicode":"🇯🇵"},{"annotation":"flag: Kenya","group":9,"hexcode":"1F1F0-1F1EA","order":4450,"tags":["KE","flag"],"unicode":"🇰🇪"},{"annotation":"flag: Kyrgyzstan","group":9,"hexcode":"1F1F0-1F1EC","order":4451,"tags":["KG","flag"],"unicode":"🇰🇬"},{"annotation":"flag: Cambodia","group":9,"hexcode":"1F1F0-1F1ED","order":4452,"tags":["KH","flag"],"unicode":"🇰🇭"},{"annotation":"flag: Kiribati","group":9,"hexcode":"1F1F0-1F1EE","order":4453,"tags":["KI","flag"],"unicode":"🇰🇮"},{"annotation":"flag: Comoros","group":9,"hexcode":"1F1F0-1F1F2","order":4454,"tags":["KM","flag"],"unicode":"🇰🇲"},{"annotation":"flag: St. Kitts & Nevis","group":9,"hexcode":"1F1F0-1F1F3","order":4455,"tags":["KN","flag"],"unicode":"🇰🇳"},{"annotation":"flag: North Korea","group":9,"hexcode":"1F1F0-1F1F5","order":4456,"tags":["KP","flag"],"unicode":"🇰🇵"},{"annotation":"flag: South Korea","group":9,"hexcode":"1F1F0-1F1F7","order":4457,"tags":["KR","flag"],"unicode":"🇰🇷"},{"annotation":"flag: Kuwait","group":9,"hexcode":"1F1F0-1F1FC","order":4458,"tags":["KW","flag"],"unicode":"🇰🇼"},{"annotation":"flag: Cayman Islands","group":9,"hexcode":"1F1F0-1F1FE","order":4459,"tags":["KY","flag"],"unicode":"🇰🇾"},{"annotation":"flag: Kazakhstan","group":9,"hexcode":"1F1F0-1F1FF","order":4460,"tags":["KZ","flag"],"unicode":"🇰🇿"},{"annotation":"flag: Laos","group":9,"hexcode":"1F1F1-1F1E6","order":4461,"tags":["LA","flag"],"unicode":"🇱🇦"},{"annotation":"flag: Lebanon","group":9,"hexcode":"1F1F1-1F1E7","order":4462,"tags":["LB","flag"],"unicode":"🇱🇧"},{"annotation":"flag: St. Lucia","group":9,"hexcode":"1F1F1-1F1E8","order":4463,"tags":["LC","flag"],"unicode":"🇱🇨"},{"annotation":"flag: Liechtenstein","group":9,"hexcode":"1F1F1-1F1EE","order":4464,"tags":["LI","flag"],"unicode":"🇱🇮"},{"annotation":"flag: Sri Lanka","group":9,"hexcode":"1F1F1-1F1F0","order":4465,"tags":["LK","flag"],"unicode":"🇱🇰"},{"annotation":"flag: Liberia","group":9,"hexcode":"1F1F1-1F1F7","order":4466,"tags":["LR","flag"],"unicode":"🇱🇷"},{"annotation":"flag: Lesotho","group":9,"hexcode":"1F1F1-1F1F8","order":4467,"tags":["LS","flag"],"unicode":"🇱🇸"},{"annotation":"flag: Lithuania","group":9,"hexcode":"1F1F1-1F1F9","order":4468,"tags":["LT","flag"],"unicode":"🇱🇹"},{"annotation":"flag: Luxembourg","group":9,"hexcode":"1F1F1-1F1FA","order":4469,"tags":["LU","flag"],"unicode":"🇱🇺"},{"annotation":"flag: Latvia","group":9,"hexcode":"1F1F1-1F1FB","order":4470,"tags":["LV","flag"],"unicode":"🇱🇻"},{"annotation":"flag: Libya","group":9,"hexcode":"1F1F1-1F1FE","order":4471,"tags":["LY","flag"],"unicode":"🇱🇾"},{"annotation":"flag: Morocco","group":9,"hexcode":"1F1F2-1F1E6","order":4472,"tags":["MA","flag"],"unicode":"🇲🇦"},{"annotation":"flag: Monaco","group":9,"hexcode":"1F1F2-1F1E8","order":4473,"tags":["MC","flag"],"unicode":"🇲🇨"},{"annotation":"flag: Moldova","group":9,"hexcode":"1F1F2-1F1E9","order":4474,"tags":["MD","flag"],"unicode":"🇲🇩"},{"annotation":"flag: Montenegro","group":9,"hexcode":"1F1F2-1F1EA","order":4475,"tags":["ME","flag"],"unicode":"🇲🇪"},{"annotation":"flag: St. Martin","group":9,"hexcode":"1F1F2-1F1EB","order":4476,"tags":["MF","flag"],"unicode":"🇲🇫"},{"annotation":"flag: Madagascar","group":9,"hexcode":"1F1F2-1F1EC","order":4477,"tags":["MG","flag"],"unicode":"🇲🇬"},{"annotation":"flag: Marshall Islands","group":9,"hexcode":"1F1F2-1F1ED","order":4478,"tags":["MH","flag"],"unicode":"🇲🇭"},{"annotation":"flag: North Macedonia","group":9,"hexcode":"1F1F2-1F1F0","order":4479,"tags":["MK","flag"],"unicode":"🇲🇰"},{"annotation":"flag: Mali","group":9,"hexcode":"1F1F2-1F1F1","order":4480,"tags":["ML","flag"],"unicode":"🇲🇱"},{"annotation":"flag: Myanmar (Burma)","group":9,"hexcode":"1F1F2-1F1F2","order":4481,"tags":["MM","flag"],"unicode":"🇲🇲"},{"annotation":"flag: Mongolia","group":9,"hexcode":"1F1F2-1F1F3","order":4482,"tags":["MN","flag"],"unicode":"🇲🇳"},{"annotation":"flag: Macao SAR China","group":9,"hexcode":"1F1F2-1F1F4","order":4483,"tags":["MO","flag"],"unicode":"🇲🇴"},{"annotation":"flag: Northern Mariana Islands","group":9,"hexcode":"1F1F2-1F1F5","order":4484,"tags":["MP","flag"],"unicode":"🇲🇵"},{"annotation":"flag: Martinique","group":9,"hexcode":"1F1F2-1F1F6","order":4485,"tags":["MQ","flag"],"unicode":"🇲🇶"},{"annotation":"flag: Mauritania","group":9,"hexcode":"1F1F2-1F1F7","order":4486,"tags":["MR","flag"],"unicode":"🇲🇷"},{"annotation":"flag: Montserrat","group":9,"hexcode":"1F1F2-1F1F8","order":4487,"tags":["MS","flag"],"unicode":"🇲🇸"},{"annotation":"flag: Malta","group":9,"hexcode":"1F1F2-1F1F9","order":4488,"tags":["MT","flag"],"unicode":"🇲🇹"},{"annotation":"flag: Mauritius","group":9,"hexcode":"1F1F2-1F1FA","order":4489,"tags":["MU","flag"],"unicode":"🇲🇺"},{"annotation":"flag: Maldives","group":9,"hexcode":"1F1F2-1F1FB","order":4490,"tags":["MV","flag"],"unicode":"🇲🇻"},{"annotation":"flag: Malawi","group":9,"hexcode":"1F1F2-1F1FC","order":4491,"tags":["MW","flag"],"unicode":"🇲🇼"},{"annotation":"flag: Mexico","group":9,"hexcode":"1F1F2-1F1FD","order":4492,"tags":["MX","flag"],"unicode":"🇲🇽"},{"annotation":"flag: Malaysia","group":9,"hexcode":"1F1F2-1F1FE","order":4493,"tags":["MY","flag"],"unicode":"🇲🇾"},{"annotation":"flag: Mozambique","group":9,"hexcode":"1F1F2-1F1FF","order":4494,"tags":["MZ","flag"],"unicode":"🇲🇿"},{"annotation":"flag: Namibia","group":9,"hexcode":"1F1F3-1F1E6","order":4495,"tags":["NA","flag"],"unicode":"🇳🇦"},{"annotation":"flag: New Caledonia","group":9,"hexcode":"1F1F3-1F1E8","order":4496,"tags":["NC","flag"],"unicode":"🇳🇨"},{"annotation":"flag: Niger","group":9,"hexcode":"1F1F3-1F1EA","order":4497,"tags":["NE","flag"],"unicode":"🇳🇪"},{"annotation":"flag: Norfolk Island","group":9,"hexcode":"1F1F3-1F1EB","order":4498,"tags":["NF","flag"],"unicode":"🇳🇫"},{"annotation":"flag: Nigeria","group":9,"hexcode":"1F1F3-1F1EC","order":4499,"tags":["NG","flag"],"unicode":"🇳🇬"},{"annotation":"flag: Nicaragua","group":9,"hexcode":"1F1F3-1F1EE","order":4500,"tags":["NI","flag"],"unicode":"🇳🇮"},{"annotation":"flag: Netherlands","group":9,"hexcode":"1F1F3-1F1F1","order":4501,"tags":["NL","flag"],"unicode":"🇳🇱"},{"annotation":"flag: Norway","group":9,"hexcode":"1F1F3-1F1F4","order":4502,"tags":["NO","flag"],"unicode":"🇳🇴"},{"annotation":"flag: Nepal","group":9,"hexcode":"1F1F3-1F1F5","order":4503,"tags":["NP","flag"],"unicode":"🇳🇵"},{"annotation":"flag: Nauru","group":9,"hexcode":"1F1F3-1F1F7","order":4504,"tags":["NR","flag"],"unicode":"🇳🇷"},{"annotation":"flag: Niue","group":9,"hexcode":"1F1F3-1F1FA","order":4505,"tags":["NU","flag"],"unicode":"🇳🇺"},{"annotation":"flag: New Zealand","group":9,"hexcode":"1F1F3-1F1FF","order":4506,"tags":["NZ","flag"],"unicode":"🇳🇿"},{"annotation":"flag: Oman","group":9,"hexcode":"1F1F4-1F1F2","order":4507,"tags":["OM","flag"],"unicode":"🇴🇲"},{"annotation":"flag: Panama","group":9,"hexcode":"1F1F5-1F1E6","order":4508,"tags":["PA","flag"],"unicode":"🇵🇦"},{"annotation":"flag: Peru","group":9,"hexcode":"1F1F5-1F1EA","order":4509,"tags":["PE","flag"],"unicode":"🇵🇪"},{"annotation":"flag: French Polynesia","group":9,"hexcode":"1F1F5-1F1EB","order":4510,"tags":["PF","flag"],"unicode":"🇵🇫"},{"annotation":"flag: Papua New Guinea","group":9,"hexcode":"1F1F5-1F1EC","order":4511,"tags":["PG","flag"],"unicode":"🇵🇬"},{"annotation":"flag: Philippines","group":9,"hexcode":"1F1F5-1F1ED","order":4512,"tags":["PH","flag"],"unicode":"🇵🇭"},{"annotation":"flag: Pakistan","group":9,"hexcode":"1F1F5-1F1F0","order":4513,"tags":["PK","flag"],"unicode":"🇵🇰"},{"annotation":"flag: Poland","group":9,"hexcode":"1F1F5-1F1F1","order":4514,"tags":["PL","flag"],"unicode":"🇵🇱"},{"annotation":"flag: St. Pierre & Miquelon","group":9,"hexcode":"1F1F5-1F1F2","order":4515,"tags":["PM","flag"],"unicode":"🇵🇲"},{"annotation":"flag: Pitcairn Islands","group":9,"hexcode":"1F1F5-1F1F3","order":4516,"tags":["PN","flag"],"unicode":"🇵🇳"},{"annotation":"flag: Puerto Rico","group":9,"hexcode":"1F1F5-1F1F7","order":4517,"tags":["PR","flag"],"unicode":"🇵🇷"},{"annotation":"flag: Palestinian Territories","group":9,"hexcode":"1F1F5-1F1F8","order":4518,"tags":["PS","flag"],"unicode":"🇵🇸"},{"annotation":"flag: Portugal","group":9,"hexcode":"1F1F5-1F1F9","order":4519,"tags":["PT","flag"],"unicode":"🇵🇹"},{"annotation":"flag: Palau","group":9,"hexcode":"1F1F5-1F1FC","order":4520,"tags":["PW","flag"],"unicode":"🇵🇼"},{"annotation":"flag: Paraguay","group":9,"hexcode":"1F1F5-1F1FE","order":4521,"tags":["PY","flag"],"unicode":"🇵🇾"},{"annotation":"flag: Qatar","group":9,"hexcode":"1F1F6-1F1E6","order":4522,"tags":["QA","flag"],"unicode":"🇶🇦"},{"annotation":"flag: Réunion","group":9,"hexcode":"1F1F7-1F1EA","order":4523,"tags":["RE","flag"],"unicode":"🇷🇪"},{"annotation":"flag: Romania","group":9,"hexcode":"1F1F7-1F1F4","order":4524,"tags":["RO","flag"],"unicode":"🇷🇴"},{"annotation":"flag: Serbia","group":9,"hexcode":"1F1F7-1F1F8","order":4525,"tags":["RS","flag"],"unicode":"🇷🇸"},{"annotation":"flag: Russia","group":9,"hexcode":"1F1F7-1F1FA","order":4526,"tags":["RU","flag"],"unicode":"🇷🇺"},{"annotation":"flag: Rwanda","group":9,"hexcode":"1F1F7-1F1FC","order":4527,"tags":["RW","flag"],"unicode":"🇷🇼"},{"annotation":"flag: Saudi Arabia","group":9,"hexcode":"1F1F8-1F1E6","order":4528,"tags":["SA","flag"],"unicode":"🇸🇦"},{"annotation":"flag: Solomon Islands","group":9,"hexcode":"1F1F8-1F1E7","order":4529,"tags":["SB","flag"],"unicode":"🇸🇧"},{"annotation":"flag: Seychelles","group":9,"hexcode":"1F1F8-1F1E8","order":4530,"tags":["SC","flag"],"unicode":"🇸🇨"},{"annotation":"flag: Sudan","group":9,"hexcode":"1F1F8-1F1E9","order":4531,"tags":["SD","flag"],"unicode":"🇸🇩"},{"annotation":"flag: Sweden","group":9,"hexcode":"1F1F8-1F1EA","order":4532,"tags":["SE","flag"],"unicode":"🇸🇪"},{"annotation":"flag: Singapore","group":9,"hexcode":"1F1F8-1F1EC","order":4533,"tags":["SG","flag"],"unicode":"🇸🇬"},{"annotation":"flag: St. Helena","group":9,"hexcode":"1F1F8-1F1ED","order":4534,"tags":["SH","flag"],"unicode":"🇸🇭"},{"annotation":"flag: Slovenia","group":9,"hexcode":"1F1F8-1F1EE","order":4535,"tags":["SI","flag"],"unicode":"🇸🇮"},{"annotation":"flag: Svalbard & Jan Mayen","group":9,"hexcode":"1F1F8-1F1EF","order":4536,"tags":["SJ","flag"],"unicode":"🇸🇯"},{"annotation":"flag: Slovakia","group":9,"hexcode":"1F1F8-1F1F0","order":4537,"tags":["SK","flag"],"unicode":"🇸🇰"},{"annotation":"flag: Sierra Leone","group":9,"hexcode":"1F1F8-1F1F1","order":4538,"tags":["SL","flag"],"unicode":"🇸🇱"},{"annotation":"flag: San Marino","group":9,"hexcode":"1F1F8-1F1F2","order":4539,"tags":["SM","flag"],"unicode":"🇸🇲"},{"annotation":"flag: Senegal","group":9,"hexcode":"1F1F8-1F1F3","order":4540,"tags":["SN","flag"],"unicode":"🇸🇳"},{"annotation":"flag: Somalia","group":9,"hexcode":"1F1F8-1F1F4","order":4541,"tags":["SO","flag"],"unicode":"🇸🇴"},{"annotation":"flag: Suriname","group":9,"hexcode":"1F1F8-1F1F7","order":4542,"tags":["SR","flag"],"unicode":"🇸🇷"},{"annotation":"flag: South Sudan","group":9,"hexcode":"1F1F8-1F1F8","order":4543,"tags":["SS","flag"],"unicode":"🇸🇸"},{"annotation":"flag: São Tomé & Príncipe","group":9,"hexcode":"1F1F8-1F1F9","order":4544,"tags":["ST","flag"],"unicode":"🇸🇹"},{"annotation":"flag: El Salvador","group":9,"hexcode":"1F1F8-1F1FB","order":4545,"tags":["SV","flag"],"unicode":"🇸🇻"},{"annotation":"flag: Sint Maarten","group":9,"hexcode":"1F1F8-1F1FD","order":4546,"tags":["SX","flag"],"unicode":"🇸🇽"},{"annotation":"flag: Syria","group":9,"hexcode":"1F1F8-1F1FE","order":4547,"tags":["SY","flag"],"unicode":"🇸🇾"},{"annotation":"flag: Eswatini","group":9,"hexcode":"1F1F8-1F1FF","order":4548,"tags":["SZ","flag"],"unicode":"🇸🇿"},{"annotation":"flag: Tristan da Cunha","group":9,"hexcode":"1F1F9-1F1E6","order":4549,"tags":["TA","flag"],"unicode":"🇹🇦"},{"annotation":"flag: Turks & Caicos Islands","group":9,"hexcode":"1F1F9-1F1E8","order":4550,"tags":["TC","flag"],"unicode":"🇹🇨"},{"annotation":"flag: Chad","group":9,"hexcode":"1F1F9-1F1E9","order":4551,"tags":["TD","flag"],"unicode":"🇹🇩"},{"annotation":"flag: French Southern Territories","group":9,"hexcode":"1F1F9-1F1EB","order":4552,"tags":["TF","flag"],"unicode":"🇹🇫"},{"annotation":"flag: Togo","group":9,"hexcode":"1F1F9-1F1EC","order":4553,"tags":["TG","flag"],"unicode":"🇹🇬"},{"annotation":"flag: Thailand","group":9,"hexcode":"1F1F9-1F1ED","order":4554,"tags":["TH","flag"],"unicode":"🇹🇭"},{"annotation":"flag: Tajikistan","group":9,"hexcode":"1F1F9-1F1EF","order":4555,"tags":["TJ","flag"],"unicode":"🇹🇯"},{"annotation":"flag: Tokelau","group":9,"hexcode":"1F1F9-1F1F0","order":4556,"tags":["TK","flag"],"unicode":"🇹🇰"},{"annotation":"flag: Timor-Leste","group":9,"hexcode":"1F1F9-1F1F1","order":4557,"tags":["TL","flag"],"unicode":"🇹🇱"},{"annotation":"flag: Turkmenistan","group":9,"hexcode":"1F1F9-1F1F2","order":4558,"tags":["TM","flag"],"unicode":"🇹🇲"},{"annotation":"flag: Tunisia","group":9,"hexcode":"1F1F9-1F1F3","order":4559,"tags":["TN","flag"],"unicode":"🇹🇳"},{"annotation":"flag: Tonga","group":9,"hexcode":"1F1F9-1F1F4","order":4560,"tags":["TO","flag"],"unicode":"🇹🇴"},{"annotation":"flag: Turkey","group":9,"hexcode":"1F1F9-1F1F7","order":4561,"tags":["TR","flag"],"unicode":"🇹🇷"},{"annotation":"flag: Trinidad & Tobago","group":9,"hexcode":"1F1F9-1F1F9","order":4562,"tags":["TT","flag"],"unicode":"🇹🇹"},{"annotation":"flag: Tuvalu","group":9,"hexcode":"1F1F9-1F1FB","order":4563,"tags":["TV","flag"],"unicode":"🇹🇻"},{"annotation":"flag: Taiwan","group":9,"hexcode":"1F1F9-1F1FC","order":4564,"tags":["TW","flag"],"unicode":"🇹🇼"},{"annotation":"flag: Tanzania","group":9,"hexcode":"1F1F9-1F1FF","order":4565,"tags":["TZ","flag"],"unicode":"🇹🇿"},{"annotation":"flag: Ukraine","group":9,"hexcode":"1F1FA-1F1E6","order":4566,"tags":["UA","flag"],"unicode":"🇺🇦"},{"annotation":"flag: Uganda","group":9,"hexcode":"1F1FA-1F1EC","order":4567,"tags":["UG","flag"],"unicode":"🇺🇬"},{"annotation":"flag: U.S. Outlying Islands","group":9,"hexcode":"1F1FA-1F1F2","order":4568,"tags":["UM","flag"],"unicode":"🇺🇲"},{"annotation":"flag: United Nations","group":9,"hexcode":"1F1FA-1F1F3","order":4569,"tags":["UN","flag"],"unicode":"🇺🇳"},{"annotation":"flag: United States","group":9,"hexcode":"1F1FA-1F1F8","order":4570,"tags":["US","flag"],"unicode":"🇺🇸"},{"annotation":"flag: Uruguay","group":9,"hexcode":"1F1FA-1F1FE","order":4571,"tags":["UY","flag"],"unicode":"🇺🇾"},{"annotation":"flag: Uzbekistan","group":9,"hexcode":"1F1FA-1F1FF","order":4572,"tags":["UZ","flag"],"unicode":"🇺🇿"},{"annotation":"flag: Vatican City","group":9,"hexcode":"1F1FB-1F1E6","order":4573,"tags":["VA","flag"],"unicode":"🇻🇦"},{"annotation":"flag: St. Vincent & Grenadines","group":9,"hexcode":"1F1FB-1F1E8","order":4574,"tags":["VC","flag"],"unicode":"🇻🇨"},{"annotation":"flag: Venezuela","group":9,"hexcode":"1F1FB-1F1EA","order":4575,"tags":["VE","flag"],"unicode":"🇻🇪"},{"annotation":"flag: British Virgin Islands","group":9,"hexcode":"1F1FB-1F1EC","order":4576,"tags":["VG","flag"],"unicode":"🇻🇬"},{"annotation":"flag: U.S. Virgin Islands","group":9,"hexcode":"1F1FB-1F1EE","order":4577,"tags":["VI","flag"],"unicode":"🇻🇮"},{"annotation":"flag: Vietnam","group":9,"hexcode":"1F1FB-1F1F3","order":4578,"tags":["VN","flag"],"unicode":"🇻🇳"},{"annotation":"flag: Vanuatu","group":9,"hexcode":"1F1FB-1F1FA","order":4579,"tags":["VU","flag"],"unicode":"🇻🇺"},{"annotation":"flag: Wallis & Futuna","group":9,"hexcode":"1F1FC-1F1EB","order":4580,"tags":["WF","flag"],"unicode":"🇼🇫"},{"annotation":"flag: Samoa","group":9,"hexcode":"1F1FC-1F1F8","order":4581,"tags":["WS","flag"],"unicode":"🇼🇸"},{"annotation":"flag: Kosovo","group":9,"hexcode":"1F1FD-1F1F0","order":4582,"tags":["XK","flag"],"unicode":"🇽🇰"},{"annotation":"flag: Yemen","group":9,"hexcode":"1F1FE-1F1EA","order":4583,"tags":["YE","flag"],"unicode":"🇾🇪"},{"annotation":"flag: Mayotte","group":9,"hexcode":"1F1FE-1F1F9","order":4584,"tags":["YT","flag"],"unicode":"🇾🇹"},{"annotation":"flag: South Africa","group":9,"hexcode":"1F1FF-1F1E6","order":4585,"tags":["ZA","flag"],"unicode":"🇿🇦"},{"annotation":"flag: Zambia","group":9,"hexcode":"1F1FF-1F1F2","order":4586,"tags":["ZM","flag"],"unicode":"🇿🇲"},{"annotation":"flag: Zimbabwe","group":9,"hexcode":"1F1FF-1F1FC","order":4587,"tags":["ZW","flag"],"unicode":"🇿🇼"},{"annotation":"flag: England","group":9,"hexcode":"1F3F4-E0067-E0062-E0065-E006E-E0067-E007F","order":4588,"tags":["flag","gbeng"],"unicode":"🏴󠁧󠁢󠁥󠁮󠁧󠁿"},{"annotation":"flag: Scotland","group":9,"hexcode":"1F3F4-E0067-E0062-E0073-E0063-E0074-E007F","order":4589,"tags":["flag","gbsct"],"unicode":"🏴󠁧󠁢󠁳󠁣󠁴󠁿"},{"annotation":"flag: Wales","group":9,"hexcode":"1F3F4-E0067-E0062-E0077-E006C-E0073-E007F","order":4590,"tags":["flag","gbwls"],"unicode":"🏴󠁧󠁢󠁷󠁬󠁳󠁿"}]'),ns=JSON.parse('{"2049":"interrobang","2122":"tm","2139":"information_source","2194":"left_right_arrow","2195":"arrow_up_down","2196":"arrow_upper_left","2197":"arrow_upper_right","2198":"arrow_lower_right","2199":"arrow_lower_left","2328":"keyboard","2600":"sunny","2601":"cloud","2602":"umbrella2","2603":"snowman2","2604":"comet","2611":"ballot_box_with_check","2614":"umbrella","2615":"coffee","2618":"shamrock","2620":["skull_crossbones","skull_and_crossbones"],"2622":["radioactive","radioactive_sign"],"2623":["biohazard","biohazard_sign"],"2626":"orthodox_cross","2638":"wheel_of_dharma","2639":["frowning2","white_frowning_face"],"2640":"female_sign","2642":"male_sign","2648":"aries","2649":"taurus","2650":"sagittarius","2651":"capricorn","2652":"aquarius","2653":"pisces","2660":"spades","2663":"clubs","2665":"hearts","2666":"diamonds","2668":"hotsprings","2692":["hammer_pick","hammer_and_pick"],"2693":"anchor","2694":"crossed_swords","2695":"medical_symbol","2696":"scales","2697":"alembic","2699":"gear","2702":"scissors","2705":"white_check_mark","2708":"airplane","2709":"envelope","2712":"black_nib","2714":"heavy_check_mark","2716":"heavy_multiplication_x","2721":"star_of_david","2728":"sparkles","2733":"eight_spoked_asterisk","2734":"eight_pointed_black_star","2744":"snowflake","2747":"sparkle","2753":"question","2754":"grey_question","2755":"grey_exclamation","2757":"exclamation","2763":["heart_exclamation","heavy_heart_exclamation_mark_ornament"],"2764":"heart","2795":"heavy_plus_sign","2796":"heavy_minus_sign","2797":"heavy_division_sign","2934":"arrow_heading_up","2935":"arrow_heading_down","3030":"wavy_dash","3297":"congratulations","3299":"secret","1F600":"grinning","1F603":"smiley","1F604":"smile","1F601":"grin","1F606":["laughing","satisfied"],"1F605":"sweat_smile","1F602":"joy","1F923":["rofl","rolling_on_the_floor_laughing"],"263A":"relaxed","1F60A":"blush","1F607":"innocent","1F642":["slight_smile","slightly_smiling_face"],"1F643":["upside_down","upside_down_face"],"1F609":"wink","1F60C":"relieved","1F972":"smiling_face_with_tear","1F60D":"heart_eyes","1F970":"smiling_face_with_3_hearts","1F618":"kissing_heart","1F617":"kissing","1F619":"kissing_smiling_eyes","1F61A":"kissing_closed_eyes","1F60B":"yum","1F61B":"stuck_out_tongue","1F61D":"stuck_out_tongue_closed_eyes","1F61C":"stuck_out_tongue_winking_eye","1F92A":"zany_face","1F928":"face_with_raised_eyebrow","1F9D0":"face_with_monocle","1F913":["nerd","nerd_face"],"1F60E":"sunglasses","1F929":"star_struck","1F973":"partying_face","1F60F":"smirk","1F612":"unamused","1F61E":"disappointed","1F614":"pensive","1F61F":"worried","1F615":"confused","1F641":["slight_frown","slightly_frowning_face"],"1F623":"persevere","1F616":"confounded","1F62B":"tired_face","1F629":"weary","1F97A":"pleading_face","1F622":"cry","1F62D":"sob","1F624":"triumph","1F62E-200D-1F4A8":"face_exhaling","1F620":"angry","1F621":"rage","1F92C":"face_with_symbols_over_mouth","1F92F":"exploding_head","1F633":"flushed","1F636-200D-1F32B-FE0F":"face_in_clouds","1F975":"hot_face","1F976":"cold_face","1F631":"scream","1F628":"fearful","1F630":"cold_sweat","1F625":"disappointed_relieved","1F613":"sweat","1F917":["hugging","hugging_face"],"1F914":["thinking","thinking_face"],"1F92D":"face_with_hand_over_mouth","1F971":"yawning_face","1F92B":"shushing_face","1F925":["lying_face","liar"],"1F636":"no_mouth","1F610":"neutral_face","1F611":"expressionless","1F62C":"grimacing","1F644":["rolling_eyes","face_with_rolling_eyes"],"1F62F":"hushed","1F626":"frowning","1F627":"anguished","1F62E":"open_mouth","1F632":"astonished","1F634":"sleeping","1F924":["drooling_face","drool"],"1F62A":"sleepy","1F635":"dizzy_face","1F635-200D-1F4AB":"face_with_spiral_eyes","1F910":["zipper_mouth","zipper_mouth_face"],"1F974":"woozy_face","1F922":["nauseated_face","sick"],"1F92E":"face_vomiting","1F927":["sneezing_face","sneeze"],"1F637":"mask","1F912":["thermometer_face","face_with_thermometer"],"1F915":["head_bandage","face_with_head_bandage"],"1F911":["money_mouth","money_mouth_face"],"1F920":["cowboy","face_with_cowboy_hat"],"1F978":"disguised_face","1F608":"smiling_imp","1F47F":"imp","1F479":"japanese_ogre","1F47A":"japanese_goblin","1F921":["clown","clown_face"],"1F4A9":["poop","shit","hankey","poo"],"1F47B":"ghost","1F480":["skull","skeleton"],"1F47D":"alien","1F47E":"space_invader","1F916":["robot","robot_face"],"1F383":"jack_o_lantern","1F63A":"smiley_cat","1F638":"smile_cat","1F639":"joy_cat","1F63B":"heart_eyes_cat","1F63C":"smirk_cat","1F63D":"kissing_cat","1F640":"scream_cat","1F63F":"crying_cat_face","1F63E":"pouting_cat","1F932":"palms_up_together","1F932-1F3FB":["palms_up_together_tone1","palms_up_together_light_skin_tone"],"1F932-1F3FC":["palms_up_together_tone2","palms_up_together_medium_light_skin_tone"],"1F932-1F3FD":["palms_up_together_tone3","palms_up_together_medium_skin_tone"],"1F932-1F3FE":["palms_up_together_tone4","palms_up_together_medium_dark_skin_tone"],"1F932-1F3FF":["palms_up_together_tone5","palms_up_together_dark_skin_tone"],"1F450":"open_hands","1F450-1F3FB":"open_hands_tone1","1F450-1F3FC":"open_hands_tone2","1F450-1F3FD":"open_hands_tone3","1F450-1F3FE":"open_hands_tone4","1F450-1F3FF":"open_hands_tone5","1F64C":"raised_hands","1F64C-1F3FB":"raised_hands_tone1","1F64C-1F3FC":"raised_hands_tone2","1F64C-1F3FD":"raised_hands_tone3","1F64C-1F3FE":"raised_hands_tone4","1F64C-1F3FF":"raised_hands_tone5","1F44F":"clap","1F44F-1F3FB":"clap_tone1","1F44F-1F3FC":"clap_tone2","1F44F-1F3FD":"clap_tone3","1F44F-1F3FE":"clap_tone4","1F44F-1F3FF":"clap_tone5","1F91D":["handshake","shaking_hands"],"1F44D":["thumbsup","+1","thumbup"],"1F44D-1F3FB":["thumbsup_tone1","+1_tone1","thumbup_tone1"],"1F44D-1F3FC":["thumbsup_tone2","+1_tone2","thumbup_tone2"],"1F44D-1F3FD":["thumbsup_tone3","+1_tone3","thumbup_tone3"],"1F44D-1F3FE":["thumbsup_tone4","+1_tone4","thumbup_tone4"],"1F44D-1F3FF":["thumbsup_tone5","+1_tone5","thumbup_tone5"],"1F44E":["thumbsdown","-1","thumbdown"],"1F44E-1F3FB":["thumbsdown_tone1","-1_tone1","thumbdown_tone1"],"1F44E-1F3FC":["thumbsdown_tone2","-1_tone2","thumbdown_tone2"],"1F44E-1F3FD":["thumbsdown_tone3","-1_tone3","thumbdown_tone3"],"1F44E-1F3FE":["thumbsdown_tone4","-1_tone4","thumbdown_tone4"],"1F44E-1F3FF":["thumbsdown_tone5","-1_tone5","thumbdown_tone5"],"1F44A":"punch","1F44A-1F3FB":"punch_tone1","1F44A-1F3FC":"punch_tone2","1F44A-1F3FD":"punch_tone3","1F44A-1F3FE":"punch_tone4","1F44A-1F3FF":"punch_tone5","270A":"fist","270A-1F3FB":"fist_tone1","270A-1F3FC":"fist_tone2","270A-1F3FD":"fist_tone3","270A-1F3FE":"fist_tone4","270A-1F3FF":"fist_tone5","1F91B":["left_facing_fist","left_fist"],"1F91B-1F3FB":["left_facing_fist_tone1","left_fist_tone1"],"1F91B-1F3FC":["left_facing_fist_tone2","left_fist_tone2"],"1F91B-1F3FD":["left_facing_fist_tone3","left_fist_tone3"],"1F91B-1F3FE":["left_facing_fist_tone4","left_fist_tone4"],"1F91B-1F3FF":["left_facing_fist_tone5","left_fist_tone5"],"1F91C":["right_facing_fist","right_fist"],"1F91C-1F3FB":["right_facing_fist_tone1","right_fist_tone1"],"1F91C-1F3FC":["right_facing_fist_tone2","right_fist_tone2"],"1F91C-1F3FD":["right_facing_fist_tone3","right_fist_tone3"],"1F91C-1F3FE":["right_facing_fist_tone4","right_fist_tone4"],"1F91C-1F3FF":["right_facing_fist_tone5","right_fist_tone5"],"1F91E":["fingers_crossed","hand_with_index_and_middle_finger_crossed"],"1F91E-1F3FB":["fingers_crossed_tone1","hand_with_index_and_middle_fingers_crossed_tone1"],"1F91E-1F3FC":["fingers_crossed_tone2","hand_with_index_and_middle_fingers_crossed_tone2"],"1F91E-1F3FD":["fingers_crossed_tone3","hand_with_index_and_middle_fingers_crossed_tone3"],"1F91E-1F3FE":["fingers_crossed_tone4","hand_with_index_and_middle_fingers_crossed_tone4"],"1F91E-1F3FF":["fingers_crossed_tone5","hand_with_index_and_middle_fingers_crossed_tone5"],"270C":"v","270C-1F3FB":"v_tone1","270C-1F3FC":"v_tone2","270C-1F3FD":"v_tone3","270C-1F3FE":"v_tone4","270C-1F3FF":"v_tone5","1F91F":"love_you_gesture","1F91F-1F3FB":["love_you_gesture_tone1","love_you_gesture_light_skin_tone"],"1F91F-1F3FC":["love_you_gesture_tone2","love_you_gesture_medium_light_skin_tone"],"1F91F-1F3FD":["love_you_gesture_tone3","love_you_gesture_medium_skin_tone"],"1F91F-1F3FE":["love_you_gesture_tone4","love_you_gesture_medium_dark_skin_tone"],"1F91F-1F3FF":["love_you_gesture_tone5","love_you_gesture_dark_skin_tone"],"1F918":["metal","sign_of_the_horns"],"1F918-1F3FB":["metal_tone1","sign_of_the_horns_tone1"],"1F918-1F3FC":["metal_tone2","sign_of_the_horns_tone2"],"1F918-1F3FD":["metal_tone3","sign_of_the_horns_tone3"],"1F918-1F3FE":["metal_tone4","sign_of_the_horns_tone4"],"1F918-1F3FF":["metal_tone5","sign_of_the_horns_tone5"],"1F44C":"ok_hand","1F44C-1F3FB":"ok_hand_tone1","1F44C-1F3FC":"ok_hand_tone2","1F44C-1F3FD":"ok_hand_tone3","1F44C-1F3FE":"ok_hand_tone4","1F44C-1F3FF":"ok_hand_tone5","1F90F":"pinching_hand","1F90F-1F3FB":["pinching_hand_tone1","pinching_hand_light_skin_tone"],"1F90F-1F3FC":["pinching_hand_tone2","pinching_hand_medium_light_skin_tone"],"1F90F-1F3FD":["pinching_hand_tone3","pinching_hand_medium_skin_tone"],"1F90F-1F3FE":["pinching_hand_tone4","pinching_hand_medium_dark_skin_tone"],"1F90F-1F3FF":["pinching_hand_tone5","pinching_hand_dark_skin_tone"],"1F90C":"pinched_fingers","1F90C-1F3FC":["pinched_fingers_tone2","pinched_fingers_medium_light_skin_tone"],"1F90C-1F3FB":["pinched_fingers_tone1","pinched_fingers_light_skin_tone"],"1F90C-1F3FD":["pinched_fingers_tone3","pinched_fingers_medium_skin_tone"],"1F90C-1F3FE":["pinched_fingers_tone4","pinched_fingers_medium_dark_skin_tone"],"1F90C-1F3FF":["pinched_fingers_tone5","pinched_fingers_dark_skin_tone"],"1F448":"point_left","1F448-1F3FB":"point_left_tone1","1F448-1F3FC":"point_left_tone2","1F448-1F3FD":"point_left_tone3","1F448-1F3FE":"point_left_tone4","1F448-1F3FF":"point_left_tone5","1F449":"point_right","1F449-1F3FB":"point_right_tone1","1F449-1F3FC":"point_right_tone2","1F449-1F3FD":"point_right_tone3","1F449-1F3FE":"point_right_tone4","1F449-1F3FF":"point_right_tone5","1F446":"point_up_2","1F446-1F3FB":"point_up_2_tone1","1F446-1F3FC":"point_up_2_tone2","1F446-1F3FD":"point_up_2_tone3","1F446-1F3FE":"point_up_2_tone4","1F446-1F3FF":"point_up_2_tone5","1F447":"point_down","1F447-1F3FB":"point_down_tone1","1F447-1F3FC":"point_down_tone2","1F447-1F3FD":"point_down_tone3","1F447-1F3FE":"point_down_tone4","1F447-1F3FF":"point_down_tone5","261D":"point_up","261D-1F3FB":"point_up_tone1","261D-1F3FC":"point_up_tone2","261D-1F3FD":"point_up_tone3","261D-1F3FE":"point_up_tone4","261D-1F3FF":"point_up_tone5","270B":"raised_hand","270B-1F3FB":"raised_hand_tone1","270B-1F3FC":"raised_hand_tone2","270B-1F3FD":"raised_hand_tone3","270B-1F3FE":"raised_hand_tone4","270B-1F3FF":"raised_hand_tone5","1F91A":["raised_back_of_hand","back_of_hand"],"1F91A-1F3FB":["raised_back_of_hand_tone1","back_of_hand_tone1"],"1F91A-1F3FC":["raised_back_of_hand_tone2","back_of_hand_tone2"],"1F91A-1F3FD":["raised_back_of_hand_tone3","back_of_hand_tone3"],"1F91A-1F3FE":["raised_back_of_hand_tone4","back_of_hand_tone4"],"1F91A-1F3FF":["raised_back_of_hand_tone5","back_of_hand_tone5"],"1F590":["hand_splayed","raised_hand_with_fingers_splayed"],"1F590-1F3FB":["hand_splayed_tone1","raised_hand_with_fingers_splayed_tone1"],"1F590-1F3FC":["hand_splayed_tone2","raised_hand_with_fingers_splayed_tone2"],"1F590-1F3FD":["hand_splayed_tone3","raised_hand_with_fingers_splayed_tone3"],"1F590-1F3FE":["hand_splayed_tone4","raised_hand_with_fingers_splayed_tone4"],"1F590-1F3FF":["hand_splayed_tone5","raised_hand_with_fingers_splayed_tone5"],"1F596":["vulcan","raised_hand_with_part_between_middle_and_ring_fingers"],"1F596-1F3FB":["vulcan_tone1","raised_hand_with_part_between_middle_and_ring_fingers_tone1"],"1F596-1F3FC":["vulcan_tone2","raised_hand_with_part_between_middle_and_ring_fingers_tone2"],"1F596-1F3FD":["vulcan_tone3","raised_hand_with_part_between_middle_and_ring_fingers_tone3"],"1F596-1F3FE":["vulcan_tone4","raised_hand_with_part_between_middle_and_ring_fingers_tone4"],"1F596-1F3FF":["vulcan_tone5","raised_hand_with_part_between_middle_and_ring_fingers_tone5"],"1F44B":"wave","1F44B-1F3FB":"wave_tone1","1F44B-1F3FC":"wave_tone2","1F44B-1F3FD":"wave_tone3","1F44B-1F3FE":"wave_tone4","1F44B-1F3FF":"wave_tone5","1F919":["call_me","call_me_hand"],"1F919-1F3FB":["call_me_tone1","call_me_hand_tone1"],"1F919-1F3FC":["call_me_tone2","call_me_hand_tone2"],"1F919-1F3FD":["call_me_tone3","call_me_hand_tone3"],"1F919-1F3FE":["call_me_tone4","call_me_hand_tone4"],"1F919-1F3FF":["call_me_tone5","call_me_hand_tone5"],"1F4AA":"muscle","1F4AA-1F3FB":"muscle_tone1","1F4AA-1F3FC":"muscle_tone2","1F4AA-1F3FD":"muscle_tone3","1F4AA-1F3FE":"muscle_tone4","1F4AA-1F3FF":"muscle_tone5","1F9BE":"mechanical_arm","1F595":["middle_finger","reversed_hand_with_middle_finger_extended"],"1F595-1F3FB":["middle_finger_tone1","reversed_hand_with_middle_finger_extended_tone1"],"1F595-1F3FC":["middle_finger_tone2","reversed_hand_with_middle_finger_extended_tone2"],"1F595-1F3FD":["middle_finger_tone3","reversed_hand_with_middle_finger_extended_tone3"],"1F595-1F3FE":["middle_finger_tone4","reversed_hand_with_middle_finger_extended_tone4"],"1F595-1F3FF":["middle_finger_tone5","reversed_hand_with_middle_finger_extended_tone5"],"270D":"writing_hand","270D-1F3FB":"writing_hand_tone1","270D-1F3FC":"writing_hand_tone2","270D-1F3FD":"writing_hand_tone3","270D-1F3FE":"writing_hand_tone4","270D-1F3FF":"writing_hand_tone5","1F64F":"pray","1F64F-1F3FB":"pray_tone1","1F64F-1F3FC":"pray_tone2","1F64F-1F3FD":"pray_tone3","1F64F-1F3FE":"pray_tone4","1F64F-1F3FF":"pray_tone5","1F9B6":"foot","1F9B6-1F3FB":["foot_tone1","foot_light_skin_tone"],"1F9B6-1F3FC":["foot_tone2","foot_medium_light_skin_tone"],"1F9B6-1F3FD":["foot_tone3","foot_medium_skin_tone"],"1F9B6-1F3FE":["foot_tone4","foot_medium_dark_skin_tone"],"1F9B6-1F3FF":["foot_tone5","foot_dark_skin_tone"],"1F9B5":"leg","1F9B5-1F3FB":["leg_tone1","leg_light_skin_tone"],"1F9B5-1F3FC":["leg_tone2","leg_medium_light_skin_tone"],"1F9B5-1F3FD":["leg_tone3","leg_medium_skin_tone"],"1F9B5-1F3FE":["leg_tone4","leg_medium_dark_skin_tone"],"1F9B5-1F3FF":["leg_tone5","leg_dark_skin_tone"],"1F9BF":"mechanical_leg","1F484":"lipstick","1F48B":"kiss","1F444":"lips","1F9B7":"tooth","1F445":"tongue","1F442":"ear","1F442-1F3FB":"ear_tone1","1F442-1F3FC":"ear_tone2","1F9D1-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FE":["kiss_person_person_tone5_tone4","kiss_person_person_dark_skin_tone_medium_dark_skin_tone"],"1F442-1F3FD":"ear_tone3","1F442-1F3FE":"ear_tone4","1F442-1F3FF":"ear_tone5","1F9BB":"ear_with_hearing_aid","1F9BB-1F3FB":["ear_with_hearing_aid_tone1","ear_with_hearing_aid_light_skin_tone"],"1F9BB-1F3FC":["ear_with_hearing_aid_tone2","ear_with_hearing_aid_medium_light_skin_tone"],"1F9BB-1F3FD":["ear_with_hearing_aid_tone3","ear_with_hearing_aid_medium_skin_tone"],"1F9BB-1F3FE":["ear_with_hearing_aid_tone4","ear_with_hearing_aid_medium_dark_skin_tone"],"1F9BB-1F3FF":["ear_with_hearing_aid_tone5","ear_with_hearing_aid_dark_skin_tone"],"1F443":"nose","1F443-1F3FB":"nose_tone1","1F443-1F3FC":"nose_tone2","1F443-1F3FD":"nose_tone3","1F443-1F3FE":"nose_tone4","1F443-1F3FF":"nose_tone5","1F463":"footprints","1F441":"eye","1F440":"eyes","1F9E0":"brain","1FAC0":"anatomical_heart","1FAC1":"lungs","1F9B4":"bone","1F5E3":["speaking_head","speaking_head_in_silhouette"],"1F464":"bust_in_silhouette","1F465":"busts_in_silhouette","1FAC2":"people_hugging","1F476":"baby","1F476-1F3FB":"baby_tone1","1F476-1F3FC":"baby_tone2","1F476-1F3FD":"baby_tone3","1F476-1F3FE":"baby_tone4","1F476-1F3FF":"baby_tone5","1F467":"girl","1F467-1F3FB":"girl_tone1","1F467-1F3FC":"girl_tone2","1F467-1F3FD":"girl_tone3","1F467-1F3FE":"girl_tone4","1F467-1F3FF":"girl_tone5","1F9D2":"child","1F9D2-1F3FB":["child_tone1","child_light_skin_tone"],"1F9D2-1F3FC":["child_tone2","child_medium_light_skin_tone"],"1F9D2-1F3FD":["child_tone3","child_medium_skin_tone"],"1F9D2-1F3FE":["child_tone4","child_medium_dark_skin_tone"],"1F9D2-1F3FF":["child_tone5","child_dark_skin_tone"],"1F466":"boy","1F466-1F3FB":"boy_tone1","1F466-1F3FC":"boy_tone2","1F466-1F3FD":"boy_tone3","1F466-1F3FE":"boy_tone4","1F466-1F3FF":"boy_tone5","1F469":"woman","1F469-1F3FB":"woman_tone1","1F469-1F3FC":"woman_tone2","1F469-1F3FD":"woman_tone3","1F469-1F3FE":"woman_tone4","1F469-1F3FF":"woman_tone5","1F9D1":"adult","1F9D1-1F3FB":["adult_tone1","adult_light_skin_tone"],"1F9D1-1F3FC":["adult_tone2","adult_medium_light_skin_tone"],"1F9D1-1F3FD":["adult_tone3","adult_medium_skin_tone"],"1F9D1-1F3FE":["adult_tone4","adult_medium_dark_skin_tone"],"1F9D1-1F3FF":["adult_tone5","adult_dark_skin_tone"],"1F468":"man","1F468-1F3FB":"man_tone1","1F468-1F3FC":"man_tone2","1F468-1F3FD":"man_tone3","1F468-1F3FE":"man_tone4","1F468-1F3FF":"man_tone5","1F9D1-200D-1F9B1":"person_curly_hair","1F9D1-1F3FB-200D-1F9B1":["person_tone1_curly_hair","person_light_skin_tone_curly_hair"],"1F9D1-1F3FC-200D-1F9B1":["person_tone2_curly_hair","person_medium_light_skin_tone_curly_hair"],"1F9D1-1F3FD-200D-1F9B1":["person_tone3_curly_hair","person_medium_skin_tone_curly_hair"],"1F9D1-1F3FE-200D-1F9B1":["person_tone4_curly_hair","person_medium_dark_skin_tone_curly_hair"],"1F9D1-1F3FF-200D-1F9B1":["person_tone5_curly_hair","person_dark_skin_tone_curly_hair"],"1F469-200D-1F9B1":"woman_curly_haired","1F469-1F3FB-200D-1F9B1":["woman_curly_haired_tone1","woman_curly_haired_light_skin_tone"],"1F469-1F3FC-200D-1F9B1":["woman_curly_haired_tone2","woman_curly_haired_medium_light_skin_tone"],"1F469-1F3FD-200D-1F9B1":["woman_curly_haired_tone3","woman_curly_haired_medium_skin_tone"],"1F469-1F3FE-200D-1F9B1":["woman_curly_haired_tone4","woman_curly_haired_medium_dark_skin_tone"],"1F469-1F3FF-200D-1F9B1":["woman_curly_haired_tone5","woman_curly_haired_dark_skin_tone"],"1F468-200D-1F9B1":"man_curly_haired","1F468-1F3FB-200D-1F9B1":["man_curly_haired_tone1","man_curly_haired_light_skin_tone"],"1F468-1F3FC-200D-1F9B1":["man_curly_haired_tone2","man_curly_haired_medium_light_skin_tone"],"1F468-1F3FD-200D-1F9B1":["man_curly_haired_tone3","man_curly_haired_medium_skin_tone"],"1F468-1F3FE-200D-1F9B1":["man_curly_haired_tone4","man_curly_haired_medium_dark_skin_tone"],"1F468-1F3FF-200D-1F9B1":["man_curly_haired_tone5","man_curly_haired_dark_skin_tone"],"1F9D1-200D-1F9B0":"person_red_hair","1F9D1-1F3FB-200D-1F9B0":["person_tone1_red_hair","person_light_skin_tone_red_hair"],"1F9D1-1F3FC-200D-1F9B0":["person_tone2_red_hair","person_medium_light_skin_tone_red_hair"],"1F9D1-1F3FD-200D-1F9B0":["person_tone3_red_hair","person_medium_skin_tone_red_hair"],"1F9D1-1F3FE-200D-1F9B0":["person_tone4_red_hair","person_medium_dark_skin_tone_red_hair"],"1F9D1-1F3FF-200D-1F9B0":["person_tone5_red_hair","person_dark_skin_tone_red_hair"],"1F469-200D-1F9B0":"woman_red_haired","1F469-1F3FB-200D-1F9B0":["woman_red_haired_tone1","woman_red_haired_light_skin_tone"],"1F469-1F3FC-200D-1F9B0":["woman_red_haired_tone2","woman_red_haired_medium_light_skin_tone"],"1F469-1F3FD-200D-1F9B0":["woman_red_haired_tone3","woman_red_haired_medium_skin_tone"],"1F469-1F3FE-200D-1F9B0":["woman_red_haired_tone4","woman_red_haired_medium_dark_skin_tone"],"1F469-1F3FF-200D-1F9B0":["woman_red_haired_tone5","woman_red_haired_dark_skin_tone"],"1F468-200D-1F9B0":"man_red_haired","1F468-1F3FB-200D-1F9B0":["man_red_haired_tone1","man_red_haired_light_skin_tone"],"1F468-1F3FC-200D-1F9B0":["man_red_haired_tone2","man_red_haired_medium_light_skin_tone"],"1F468-1F3FD-200D-1F9B0":["man_red_haired_tone3","man_red_haired_medium_skin_tone"],"1F468-1F3FE-200D-1F9B0":["man_red_haired_tone4","man_red_haired_medium_dark_skin_tone"],"1F468-1F3FF-200D-1F9B0":["man_red_haired_tone5","man_red_haired_dark_skin_tone"],"1F471-200D-2640-FE0F":"blond-haired_woman","1F471-1F3FB-200D-2640-FE0F":["blond-haired_woman_tone1","blond-haired_woman_light_skin_tone"],"1F471-1F3FC-200D-2640-FE0F":["blond-haired_woman_tone2","blond-haired_woman_medium_light_skin_tone"],"1F471-1F3FD-200D-2640-FE0F":["blond-haired_woman_tone3","blond-haired_woman_medium_skin_tone"],"1F471-1F3FE-200D-2640-FE0F":["blond-haired_woman_tone4","blond-haired_woman_medium_dark_skin_tone"],"1F471-1F3FF-200D-2640-FE0F":["blond-haired_woman_tone5","blond-haired_woman_dark_skin_tone"],"1F471":["blond_haired_person","person_with_blond_hair"],"1F471-1F3FB":["blond_haired_person_tone1","person_with_blond_hair_tone1"],"1F471-1F3FC":["blond_haired_person_tone2","person_with_blond_hair_tone2"],"1F471-1F3FD":["blond_haired_person_tone3","person_with_blond_hair_tone3"],"1F471-1F3FE":["blond_haired_person_tone4","person_with_blond_hair_tone4"],"1F471-1F3FF":["blond_haired_person_tone5","person_with_blond_hair_tone5"],"1F471-200D-2642-FE0F":"blond-haired_man","1F471-1F3FB-200D-2642-FE0F":["blond-haired_man_tone1","blond-haired_man_light_skin_tone"],"1F471-1F3FC-200D-2642-FE0F":["blond-haired_man_tone2","blond-haired_man_medium_light_skin_tone"],"1F471-1F3FD-200D-2642-FE0F":["blond-haired_man_tone3","blond-haired_man_medium_skin_tone"],"1F471-1F3FE-200D-2642-FE0F":["blond-haired_man_tone4","blond-haired_man_medium_dark_skin_tone"],"1F471-1F3FF-200D-2642-FE0F":["blond-haired_man_tone5","blond-haired_man_dark_skin_tone"],"1F9D1-200D-1F9B3":"person_white_hair","1F9D1-1F3FB-200D-1F9B3":["person_tone1_white_hair","person_light_skin_tone_white_hair"],"1F9D1-1F3FC-200D-1F9B3":["person_tone2_white_hair","person_medium_light_skin_tone_white_hair"],"1F9D1-1F3FD-200D-1F9B3":["person_tone3_white_hair","person_medium_skin_tone_white_hair"],"1F9D1-1F3FE-200D-1F9B3":["person_tone4_white_hair","person_medium_dark_skin_tone_white_hair"],"1F9D1-1F3FF-200D-1F9B3":["person_tone5_white_hair","person_dark_skin_tone_white_hair"],"1F469-200D-1F9B3":"woman_white_haired","1F469-1F3FB-200D-1F9B3":["woman_white_haired_tone1","woman_white_haired_light_skin_tone"],"1F469-1F3FC-200D-1F9B3":["woman_white_haired_tone2","woman_white_haired_medium_light_skin_tone"],"1F469-1F3FD-200D-1F9B3":["woman_white_haired_tone3","woman_white_haired_medium_skin_tone"],"1F469-1F3FE-200D-1F9B3":["woman_white_haired_tone4","woman_white_haired_medium_dark_skin_tone"],"1F469-1F3FF-200D-1F9B3":["woman_white_haired_tone5","woman_white_haired_dark_skin_tone"],"1F468-200D-1F9B3":"man_white_haired","1F468-1F3FB-200D-1F9B3":["man_white_haired_tone1","man_white_haired_light_skin_tone"],"1F468-1F3FC-200D-1F9B3":["man_white_haired_tone2","man_white_haired_medium_light_skin_tone"],"1F468-1F3FD-200D-1F9B3":["man_white_haired_tone3","man_white_haired_medium_skin_tone"],"1F468-1F3FE-200D-1F9B3":["man_white_haired_tone4","man_white_haired_medium_dark_skin_tone"],"1F468-1F3FF-200D-1F9B3":["man_white_haired_tone5","man_white_haired_dark_skin_tone"],"1F9D1-200D-1F9B2":"person_bald","1F9D1-1F3FB-200D-1F9B2":["person_tone1_bald","person_light_skin_tone_bald"],"1F9D1-1F3FC-200D-1F9B2":["person_tone2_bald","person_medium_light_skin_tone_bald"],"1F9D1-1F3FD-200D-1F9B2":["person_tone3_bald","person_medium_skin_tone_bald"],"1F9D1-1F3FE-200D-1F9B2":["person_tone4_bald","person_medium_dark_skin_tone_bald"],"1F9D1-1F3FF-200D-1F9B2":["person_tone5_bald","person_dark_skin_tone_bald"],"1F469-200D-1F9B2":"woman_bald","1F469-1F3FB-200D-1F9B2":["woman_bald_tone1","woman_bald_light_skin_tone"],"1F469-1F3FC-200D-1F9B2":["woman_bald_tone2","woman_bald_medium_light_skin_tone"],"1F469-1F3FD-200D-1F9B2":["woman_bald_tone3","woman_bald_medium_skin_tone"],"1F469-1F3FE-200D-1F9B2":["woman_bald_tone4","woman_bald_medium_dark_skin_tone"],"1F469-1F3FF-200D-1F9B2":["woman_bald_tone5","woman_bald_dark_skin_tone"],"1F468-200D-1F9B2":"man_bald","1F468-1F3FB-200D-1F9B2":["man_bald_tone1","man_bald_light_skin_tone"],"1F468-1F3FC-200D-1F9B2":["man_bald_tone2","man_bald_medium_light_skin_tone"],"1F468-1F3FD-200D-1F9B2":["man_bald_tone3","man_bald_medium_skin_tone"],"1F468-1F3FE-200D-1F9B2":["man_bald_tone4","man_bald_medium_dark_skin_tone"],"1F468-1F3FF-200D-1F9B2":["man_bald_tone5","man_bald_dark_skin_tone"],"1F9D4":"bearded_person","1F9D4-1F3FB":["bearded_person_tone1","bearded_person_light_skin_tone"],"1F9D4-1F3FC":["bearded_person_tone2","bearded_person_medium_light_skin_tone"],"1F9D4-1F3FD":["bearded_person_tone3","bearded_person_medium_skin_tone"],"1F9D4-1F3FE":["bearded_person_tone4","bearded_person_medium_dark_skin_tone"],"1F9D4-1F3FF":["bearded_person_tone5","bearded_person_dark_skin_tone"],"1F9D4-200D-2642-FE0F":"man_beard","1F9D4-1F3FB-200D-2642-FE0F":["man_tone1_beard","man_light_skin_tone_beard"],"1F9D4-1F3FC-200D-2642-FE0F":["man_tone2_beard","man_medium_light_skin_tone_beard"],"1F9D4-1F3FD-200D-2642-FE0F":["man_tone3_beard","man_medium_skin_tone_beard"],"1F9D4-1F3FE-200D-2642-FE0F":["man_tone4_beard","man_medium_dark_skin_tone_beard"],"1F9D4-1F3FF-200D-2642-FE0F":["man_tone5_beard","man_dark_skin_tone_beard"],"1F9D4-200D-2640-FE0F":"woman_beard","1F9D4-1F3FB-200D-2640-FE0F":["woman_tone1_beard","woman_light_skin_tone_beard"],"1F9D4-1F3FC-200D-2640-FE0F":["woman_tone2_beard","woman_medium_light_skin_tone_beard"],"1F9D4-1F3FD-200D-2640-FE0F":["woman_tone3_beard","woman_medium_skin_tone_beard"],"1F9D4-1F3FE-200D-2640-FE0F":["woman_tone4_beard","woman_medium_dark_skin_tone_beard"],"1F9D4-1F3FF-200D-2640-FE0F":["woman_tone5_beard","woman_dark_skin_tone_beard"],"1F475":["older_woman","grandma"],"1F475-1F3FB":["older_woman_tone1","grandma_tone1"],"1F475-1F3FC":["older_woman_tone2","grandma_tone2"],"1F475-1F3FD":["older_woman_tone3","grandma_tone3"],"1F475-1F3FE":["older_woman_tone4","grandma_tone4"],"1F475-1F3FF":["older_woman_tone5","grandma_tone5"],"1F9D3":"older_adult","1F9D3-1F3FB":["older_adult_tone1","older_adult_light_skin_tone"],"1F9D3-1F3FC":["older_adult_tone2","older_adult_medium_light_skin_tone"],"1F9D3-1F3FD":["older_adult_tone3","older_adult_medium_skin_tone"],"1F9D3-1F3FE":["older_adult_tone4","older_adult_medium_dark_skin_tone"],"1F9D3-1F3FF":["older_adult_tone5","older_adult_dark_skin_tone"],"1F474":"older_man","1F474-1F3FB":"older_man_tone1","1F474-1F3FC":"older_man_tone2","1F474-1F3FD":"older_man_tone3","1F474-1F3FE":"older_man_tone4","1F474-1F3FF":"older_man_tone5","1F472":["man_with_chinese_cap","man_with_gua_pi_mao"],"1F472-1F3FB":["man_with_chinese_cap_tone1","man_with_gua_pi_mao_tone1"],"1F472-1F3FC":["man_with_chinese_cap_tone2","man_with_gua_pi_mao_tone2"],"1F472-1F3FD":["man_with_chinese_cap_tone3","man_with_gua_pi_mao_tone3"],"1F472-1F3FE":["man_with_chinese_cap_tone4","man_with_gua_pi_mao_tone4"],"1F472-1F3FF":["man_with_chinese_cap_tone5","man_with_gua_pi_mao_tone5"],"1F473":["person_wearing_turban","man_with_turban"],"1F473-1F3FB":["person_wearing_turban_tone1","man_with_turban_tone1"],"1F473-1F3FC":["person_wearing_turban_tone2","man_with_turban_tone2"],"1F473-1F3FD":["person_wearing_turban_tone3","man_with_turban_tone3"],"1F473-1F3FE":["person_wearing_turban_tone4","man_with_turban_tone4"],"1F473-1F3FF":["person_wearing_turban_tone5","man_with_turban_tone5"],"1F473-200D-2640-FE0F":"woman_wearing_turban","1F473-1F3FB-200D-2640-FE0F":["woman_wearing_turban_tone1","woman_wearing_turban_light_skin_tone"],"1F473-1F3FC-200D-2640-FE0F":["woman_wearing_turban_tone2","woman_wearing_turban_medium_light_skin_tone"],"1F473-1F3FD-200D-2640-FE0F":["woman_wearing_turban_tone3","woman_wearing_turban_medium_skin_tone"],"1F473-1F3FE-200D-2640-FE0F":["woman_wearing_turban_tone4","woman_wearing_turban_medium_dark_skin_tone"],"1F473-1F3FF-200D-2640-FE0F":["woman_wearing_turban_tone5","woman_wearing_turban_dark_skin_tone"],"1F473-200D-2642-FE0F":"man_wearing_turban","1F473-1F3FB-200D-2642-FE0F":["man_wearing_turban_tone1","man_wearing_turban_light_skin_tone"],"1F473-1F3FC-200D-2642-FE0F":["man_wearing_turban_tone2","man_wearing_turban_medium_light_skin_tone"],"1F473-1F3FD-200D-2642-FE0F":["man_wearing_turban_tone3","man_wearing_turban_medium_skin_tone"],"1F473-1F3FE-200D-2642-FE0F":["man_wearing_turban_tone4","man_wearing_turban_medium_dark_skin_tone"],"1F473-1F3FF-200D-2642-FE0F":["man_wearing_turban_tone5","man_wearing_turban_dark_skin_tone"],"1F9D5":"woman_with_headscarf","1F9D5-1F3FB":["woman_with_headscarf_tone1","woman_with_headscarf_light_skin_tone"],"1F9D5-1F3FC":["woman_with_headscarf_tone2","woman_with_headscarf_medium_light_skin_tone"],"1F9D5-1F3FD":["woman_with_headscarf_tone3","woman_with_headscarf_medium_skin_tone"],"1F9D5-1F3FE":["woman_with_headscarf_tone4","woman_with_headscarf_medium_dark_skin_tone"],"1F9D5-1F3FF":["woman_with_headscarf_tone5","woman_with_headscarf_dark_skin_tone"],"1F46E":["police_officer","cop"],"1F46E-1F3FB":["police_officer_tone1","cop_tone1"],"1F46E-1F3FC":["police_officer_tone2","cop_tone2"],"1F46E-1F3FD":["police_officer_tone3","cop_tone3"],"1F46E-1F3FE":["police_officer_tone4","cop_tone4"],"1F46E-1F3FF":["police_officer_tone5","cop_tone5"],"1F46E-200D-2640-FE0F":"woman_police_officer","1F46E-1F3FB-200D-2640-FE0F":["woman_police_officer_tone1","woman_police_officer_light_skin_tone"],"1F46E-1F3FC-200D-2640-FE0F":["woman_police_officer_tone2","woman_police_officer_medium_light_skin_tone"],"1F46E-1F3FD-200D-2640-FE0F":["woman_police_officer_tone3","woman_police_officer_medium_skin_tone"],"1F46E-1F3FE-200D-2640-FE0F":["woman_police_officer_tone4","woman_police_officer_medium_dark_skin_tone"],"1F46E-1F3FF-200D-2640-FE0F":["woman_police_officer_tone5","woman_police_officer_dark_skin_tone"],"1F46E-200D-2642-FE0F":"man_police_officer","1F46E-1F3FB-200D-2642-FE0F":["man_police_officer_tone1","man_police_officer_light_skin_tone"],"1F46E-1F3FC-200D-2642-FE0F":["man_police_officer_tone2","man_police_officer_medium_light_skin_tone"],"1F46E-1F3FD-200D-2642-FE0F":["man_police_officer_tone3","man_police_officer_medium_skin_tone"],"1F46E-1F3FE-200D-2642-FE0F":["man_police_officer_tone4","man_police_officer_medium_dark_skin_tone"],"1F46E-1F3FF-200D-2642-FE0F":["man_police_officer_tone5","man_police_officer_dark_skin_tone"],"1F477":"construction_worker","1F477-1F3FB":"construction_worker_tone1","1F477-1F3FC":"construction_worker_tone2","1F477-1F3FD":"construction_worker_tone3","1F477-1F3FE":"construction_worker_tone4","1F477-1F3FF":"construction_worker_tone5","1F477-200D-2640-FE0F":"woman_construction_worker","1F477-1F3FB-200D-2640-FE0F":["woman_construction_worker_tone1","woman_construction_worker_light_skin_tone"],"1F477-1F3FC-200D-2640-FE0F":["woman_construction_worker_tone2","woman_construction_worker_medium_light_skin_tone"],"1F477-1F3FD-200D-2640-FE0F":["woman_construction_worker_tone3","woman_construction_worker_medium_skin_tone"],"1F477-1F3FE-200D-2640-FE0F":["woman_construction_worker_tone4","woman_construction_worker_medium_dark_skin_tone"],"1F477-1F3FF-200D-2640-FE0F":["woman_construction_worker_tone5","woman_construction_worker_dark_skin_tone"],"1F477-200D-2642-FE0F":"man_construction_worker","1F477-1F3FB-200D-2642-FE0F":["man_construction_worker_tone1","man_construction_worker_light_skin_tone"],"1F477-1F3FC-200D-2642-FE0F":["man_construction_worker_tone2","man_construction_worker_medium_light_skin_tone"],"1F477-1F3FD-200D-2642-FE0F":["man_construction_worker_tone3","man_construction_worker_medium_skin_tone"],"1F477-1F3FE-200D-2642-FE0F":["man_construction_worker_tone4","man_construction_worker_medium_dark_skin_tone"],"1F477-1F3FF-200D-2642-FE0F":["man_construction_worker_tone5","man_construction_worker_dark_skin_tone"],"1F482":["guard","guardsman"],"1F482-1F3FB":["guard_tone1","guardsman_tone1"],"1F482-1F3FC":["guard_tone2","guardsman_tone2"],"1F482-1F3FD":["guard_tone3","guardsman_tone3"],"1F482-1F3FE":["guard_tone4","guardsman_tone4"],"1F482-1F3FF":["guard_tone5","guardsman_tone5"],"1F482-200D-2640-FE0F":"woman_guard","1F482-1F3FB-200D-2640-FE0F":["woman_guard_tone1","woman_guard_light_skin_tone"],"1F482-1F3FC-200D-2640-FE0F":["woman_guard_tone2","woman_guard_medium_light_skin_tone"],"1F482-1F3FD-200D-2640-FE0F":["woman_guard_tone3","woman_guard_medium_skin_tone"],"1F482-1F3FE-200D-2640-FE0F":["woman_guard_tone4","woman_guard_medium_dark_skin_tone"],"1F482-1F3FF-200D-2640-FE0F":["woman_guard_tone5","woman_guard_dark_skin_tone"],"1F482-200D-2642-FE0F":"man_guard","1F482-1F3FB-200D-2642-FE0F":["man_guard_tone1","man_guard_light_skin_tone"],"1F482-1F3FC-200D-2642-FE0F":["man_guard_tone2","man_guard_medium_light_skin_tone"],"1F482-1F3FD-200D-2642-FE0F":["man_guard_tone3","man_guard_medium_skin_tone"],"1F482-1F3FE-200D-2642-FE0F":["man_guard_tone4","man_guard_medium_dark_skin_tone"],"1F482-1F3FF-200D-2642-FE0F":["man_guard_tone5","man_guard_dark_skin_tone"],"1F575":["detective","spy","sleuth_or_spy"],"1F575-1F3FB":["detective_tone1","spy_tone1","sleuth_or_spy_tone1"],"1F575-1F3FC":["detective_tone2","spy_tone2","sleuth_or_spy_tone2"],"1F575-1F3FD":["detective_tone3","spy_tone3","sleuth_or_spy_tone3"],"1F575-1F3FE":["detective_tone4","spy_tone4","sleuth_or_spy_tone4"],"1F575-1F3FF":["detective_tone5","spy_tone5","sleuth_or_spy_tone5"],"1F575-FE0F-200D-2640-FE0F":"woman_detective","1F575-1F3FB-200D-2640-FE0F":["woman_detective_tone1","woman_detective_light_skin_tone"],"1F575-1F3FC-200D-2640-FE0F":["woman_detective_tone2","woman_detective_medium_light_skin_tone"],"1F575-1F3FD-200D-2640-FE0F":["woman_detective_tone3","woman_detective_medium_skin_tone"],"1F575-1F3FE-200D-2640-FE0F":["woman_detective_tone4","woman_detective_medium_dark_skin_tone"],"1F575-1F3FF-200D-2640-FE0F":["woman_detective_tone5","woman_detective_dark_skin_tone"],"1F575-FE0F-200D-2642-FE0F":"man_detective","1F575-1F3FB-200D-2642-FE0F":["man_detective_tone1","man_detective_light_skin_tone"],"1F575-1F3FC-200D-2642-FE0F":["man_detective_tone2","man_detective_medium_light_skin_tone"],"1F575-1F3FD-200D-2642-FE0F":["man_detective_tone3","man_detective_medium_skin_tone"],"1F575-1F3FE-200D-2642-FE0F":["man_detective_tone4","man_detective_medium_dark_skin_tone"],"1F575-1F3FF-200D-2642-FE0F":["man_detective_tone5","man_detective_dark_skin_tone"],"1F9D1-200D-2695-FE0F":"health_worker","1F9D1-1F3FB-200D-2695-FE0F":["health_worker_tone1","health_worker_light_skin_tone"],"1F9D1-1F3FC-200D-2695-FE0F":["health_worker_tone2","health_worker_medium_light_skin_tone"],"1F9D1-1F3FD-200D-2695-FE0F":["health_worker_tone3","health_worker_medium_skin_tone"],"1F9D1-1F3FE-200D-2695-FE0F":["health_worker_tone4","health_worker_medium_dark_skin_tone"],"1F9D1-1F3FF-200D-2695-FE0F":["health_worker_tone5","health_worker_dark_skin_tone"],"1F469-200D-2695-FE0F":"woman_health_worker","1F469-1F3FB-200D-2695-FE0F":["woman_health_worker_tone1","woman_health_worker_light_skin_tone"],"1F469-1F3FC-200D-2695-FE0F":["woman_health_worker_tone2","woman_health_worker_medium_light_skin_tone"],"1F469-1F3FD-200D-2695-FE0F":["woman_health_worker_tone3","woman_health_worker_medium_skin_tone"],"1F469-1F3FE-200D-2695-FE0F":["woman_health_worker_tone4","woman_health_worker_medium_dark_skin_tone"],"1F469-1F3FF-200D-2695-FE0F":["woman_health_worker_tone5","woman_health_worker_dark_skin_tone"],"1F468-200D-2695-FE0F":"man_health_worker","1F468-1F3FB-200D-2695-FE0F":["man_health_worker_tone1","man_health_worker_light_skin_tone"],"1F468-1F3FC-200D-2695-FE0F":["man_health_worker_tone2","man_health_worker_medium_light_skin_tone"],"1F468-1F3FD-200D-2695-FE0F":["man_health_worker_tone3","man_health_worker_medium_skin_tone"],"1F468-1F3FE-200D-2695-FE0F":["man_health_worker_tone4","man_health_worker_medium_dark_skin_tone"],"1F468-1F3FF-200D-2695-FE0F":["man_health_worker_tone5","man_health_worker_dark_skin_tone"],"1F9D1-200D-1F33E":"farmer","1F9D1-1F3FB-200D-1F33E":["farmer_tone1","farmer_light_skin_tone"],"1F9D1-1F3FC-200D-1F33E":["farmer_tone2","farmer_medium_light_skin_tone"],"1F9D1-1F3FD-200D-1F33E":["farmer_tone3","farmer_medium_skin_tone"],"1F9D1-1F3FE-200D-1F33E":["farmer_tone4","farmer_medium_dark_skin_tone"],"1F9D1-1F3FF-200D-1F33E":["farmer_tone5","farmer_dark_skin_tone"],"1F469-200D-1F33E":"woman_farmer","1F469-1F3FB-200D-1F33E":["woman_farmer_tone1","woman_farmer_light_skin_tone"],"1F469-1F3FC-200D-1F33E":["woman_farmer_tone2","woman_farmer_medium_light_skin_tone"],"1F469-1F3FD-200D-1F33E":["woman_farmer_tone3","woman_farmer_medium_skin_tone"],"1F469-1F3FE-200D-1F33E":["woman_farmer_tone4","woman_farmer_medium_dark_skin_tone"],"1F469-1F3FF-200D-1F33E":["woman_farmer_tone5","woman_farmer_dark_skin_tone"],"1F468-200D-1F33E":"man_farmer","1F468-1F3FB-200D-1F33E":["man_farmer_tone1","man_farmer_light_skin_tone"],"1F468-1F3FC-200D-1F33E":["man_farmer_tone2","man_farmer_medium_light_skin_tone"],"1F468-1F3FD-200D-1F33E":["man_farmer_tone3","man_farmer_medium_skin_tone"],"1F468-1F3FE-200D-1F33E":["man_farmer_tone4","man_farmer_medium_dark_skin_tone"],"1F468-1F3FF-200D-1F33E":["man_farmer_tone5","man_farmer_dark_skin_tone"],"1F9D1-200D-1F373":"cook","1F9D1-1F3FB-200D-1F373":["cook_tone1","cook_light_skin_tone"],"1F9D1-1F3FC-200D-1F373":["cook_tone2","cook_medium_light_skin_tone"],"1F9D1-1F3FD-200D-1F373":["cook_tone3","cook_medium_skin_tone"],"1F9D1-1F3FE-200D-1F373":["cook_tone4","cook_medium_dark_skin_tone"],"1F9D1-1F3FF-200D-1F373":["cook_tone5","cook_dark_skin_tone"],"1F469-200D-1F373":"woman_cook","1F469-1F3FB-200D-1F373":["woman_cook_tone1","woman_cook_light_skin_tone"],"1F469-1F3FC-200D-1F373":["woman_cook_tone2","woman_cook_medium_light_skin_tone"],"1F469-1F3FD-200D-1F373":["woman_cook_tone3","woman_cook_medium_skin_tone"],"1F469-1F3FE-200D-1F373":["woman_cook_tone4","woman_cook_medium_dark_skin_tone"],"1F469-1F3FF-200D-1F373":["woman_cook_tone5","woman_cook_dark_skin_tone"],"1F468-200D-1F373":"man_cook","1F468-1F3FB-200D-1F373":["man_cook_tone1","man_cook_light_skin_tone"],"1F468-1F3FC-200D-1F373":["man_cook_tone2","man_cook_medium_light_skin_tone"],"1F468-1F3FD-200D-1F373":["man_cook_tone3","man_cook_medium_skin_tone"],"1F468-1F3FE-200D-1F373":["man_cook_tone4","man_cook_medium_dark_skin_tone"],"1F468-1F3FF-200D-1F373":["man_cook_tone5","man_cook_dark_skin_tone"],"1F9D1-200D-1F393":"student","1F9D1-1F3FB-200D-1F393":["student_tone1","student_light_skin_tone"],"1F9D1-1F3FC-200D-1F393":["student_tone2","student_medium_light_skin_tone"],"1F9D1-1F3FD-200D-1F393":["student_tone3","student_medium_skin_tone"],"1F9D1-1F3FE-200D-1F393":["student_tone4","student_medium_dark_skin_tone"],"1F9D1-1F3FF-200D-1F393":["student_tone5","student_dark_skin_tone"],"1F469-200D-1F393":"woman_student","1F469-1F3FB-200D-1F393":["woman_student_tone1","woman_student_light_skin_tone"],"1F469-1F3FC-200D-1F393":["woman_student_tone2","woman_student_medium_light_skin_tone"],"1F469-1F3FD-200D-1F393":["woman_student_tone3","woman_student_medium_skin_tone"],"1F469-1F3FE-200D-1F393":["woman_student_tone4","woman_student_medium_dark_skin_tone"],"1F469-1F3FF-200D-1F393":["woman_student_tone5","woman_student_dark_skin_tone"],"1F468-200D-1F393":"man_student","1F468-1F3FB-200D-1F393":["man_student_tone1","man_student_light_skin_tone"],"1F468-1F3FC-200D-1F393":["man_student_tone2","man_student_medium_light_skin_tone"],"1F468-1F3FD-200D-1F393":["man_student_tone3","man_student_medium_skin_tone"],"1F468-1F3FE-200D-1F393":["man_student_tone4","man_student_medium_dark_skin_tone"],"1F468-1F3FF-200D-1F393":["man_student_tone5","man_student_dark_skin_tone"],"1F9D1-200D-1F3A4":"singer","1F9D1-1F3FB-200D-1F3A4":["singer_tone1","singer_light_skin_tone"],"1F9D1-1F3FC-200D-1F3A4":["singer_tone2","singer_medium_light_skin_tone"],"1F9D1-1F3FD-200D-1F3A4":["singer_tone3","singer_medium_skin_tone"],"1F9D1-1F3FE-200D-1F3A4":["singer_tone4","singer_medium_dark_skin_tone"],"1F9D1-1F3FF-200D-1F3A4":["singer_tone5","singer_dark_skin_tone"],"1F469-200D-1F3A4":"woman_singer","1F469-1F3FB-200D-1F3A4":["woman_singer_tone1","woman_singer_light_skin_tone"],"1F469-1F3FC-200D-1F3A4":["woman_singer_tone2","woman_singer_medium_light_skin_tone"],"1F469-1F3FD-200D-1F3A4":["woman_singer_tone3","woman_singer_medium_skin_tone"],"1F469-1F3FE-200D-1F3A4":["woman_singer_tone4","woman_singer_medium_dark_skin_tone"],"1F469-1F3FF-200D-1F3A4":["woman_singer_tone5","woman_singer_dark_skin_tone"],"1F468-200D-1F3A4":"man_singer","1F468-1F3FB-200D-1F3A4":["man_singer_tone1","man_singer_light_skin_tone"],"1F468-1F3FC-200D-1F3A4":["man_singer_tone2","man_singer_medium_light_skin_tone"],"1F468-1F3FD-200D-1F3A4":["man_singer_tone3","man_singer_medium_skin_tone"],"1F468-1F3FE-200D-1F3A4":["man_singer_tone4","man_singer_medium_dark_skin_tone"],"1F468-1F3FF-200D-1F3A4":["man_singer_tone5","man_singer_dark_skin_tone"],"1F9D1-200D-1F3EB":"teacher","1F9D1-1F3FB-200D-1F3EB":["teacher_tone1","teacher_light_skin_tone"],"1F9D1-1F3FC-200D-1F3EB":["teacher_tone2","teacher_medium_light_skin_tone"],"1F9D1-1F3FD-200D-1F3EB":["teacher_tone3","teacher_medium_skin_tone"],"1F9D1-1F3FE-200D-1F3EB":["teacher_tone4","teacher_medium_dark_skin_tone"],"1F9D1-1F3FF-200D-1F3EB":["teacher_tone5","teacher_dark_skin_tone"],"1F469-200D-1F3EB":"woman_teacher","1F469-1F3FB-200D-1F3EB":["woman_teacher_tone1","woman_teacher_light_skin_tone"],"1F469-1F3FC-200D-1F3EB":["woman_teacher_tone2","woman_teacher_medium_light_skin_tone"],"1F469-1F3FD-200D-1F3EB":["woman_teacher_tone3","woman_teacher_medium_skin_tone"],"1F469-1F3FE-200D-1F3EB":["woman_teacher_tone4","woman_teacher_medium_dark_skin_tone"],"1F469-1F3FF-200D-1F3EB":["woman_teacher_tone5","woman_teacher_dark_skin_tone"],"1F468-200D-1F3EB":"man_teacher","1F468-1F3FB-200D-1F3EB":["man_teacher_tone1","man_teacher_light_skin_tone"],"1F468-1F3FC-200D-1F3EB":["man_teacher_tone2","man_teacher_medium_light_skin_tone"],"1F468-1F3FD-200D-1F3EB":["man_teacher_tone3","man_teacher_medium_skin_tone"],"1F468-1F3FE-200D-1F3EB":["man_teacher_tone4","man_teacher_medium_dark_skin_tone"],"1F468-1F3FF-200D-1F3EB":["man_teacher_tone5","man_teacher_dark_skin_tone"],"1F9D1-200D-1F3ED":"factory_worker","1F9D1-1F3FB-200D-1F3ED":["factory_worker_tone1","factory_worker_light_skin_tone"],"1F9D1-1F3FC-200D-1F3ED":["factory_worker_tone2","factory_worker_medium_light_skin_tone"],"1F9D1-1F3FD-200D-1F3ED":["factory_worker_tone3","factory_worker_medium_skin_tone"],"1F9D1-1F3FE-200D-1F3ED":["factory_worker_tone4","factory_worker_medium_dark_skin_tone"],"1F9D1-1F3FF-200D-1F3ED":["factory_worker_tone5","factory_worker_dark_skin_tone"],"1F469-200D-1F3ED":"woman_factory_worker","1F469-1F3FB-200D-1F3ED":["woman_factory_worker_tone1","woman_factory_worker_light_skin_tone"],"1F469-1F3FC-200D-1F3ED":["woman_factory_worker_tone2","woman_factory_worker_medium_light_skin_tone"],"1F469-1F3FD-200D-1F3ED":["woman_factory_worker_tone3","woman_factory_worker_medium_skin_tone"],"1F469-1F3FE-200D-1F3ED":["woman_factory_worker_tone4","woman_factory_worker_medium_dark_skin_tone"],"1F469-1F3FF-200D-1F3ED":["woman_factory_worker_tone5","woman_factory_worker_dark_skin_tone"],"1F468-200D-1F3ED":"man_factory_worker","1F468-1F3FB-200D-1F3ED":["man_factory_worker_tone1","man_factory_worker_light_skin_tone"],"1F468-1F3FC-200D-1F3ED":["man_factory_worker_tone2","man_factory_worker_medium_light_skin_tone"],"1F468-1F3FD-200D-1F3ED":["man_factory_worker_tone3","man_factory_worker_medium_skin_tone"],"1F468-1F3FE-200D-1F3ED":["man_factory_worker_tone4","man_factory_worker_medium_dark_skin_tone"],"1F468-1F3FF-200D-1F3ED":["man_factory_worker_tone5","man_factory_worker_dark_skin_tone"],"1F9D1-200D-1F4BB":"technologist","1F9D1-1F3FB-200D-1F4BB":["technologist_tone1","technologist_light_skin_tone"],"1F9D1-1F3FC-200D-1F4BB":["technologist_tone2","technologist_medium_light_skin_tone"],"1F9D1-1F3FD-200D-1F4BB":["technologist_tone3","technologist_medium_skin_tone"],"1F9D1-1F3FE-200D-1F4BB":["technologist_tone4","technologist_medium_dark_skin_tone"],"1F9D1-1F3FF-200D-1F4BB":["technologist_tone5","technologist_dark_skin_tone"],"1F469-200D-1F4BB":"woman_technologist","1F469-1F3FB-200D-1F4BB":["woman_technologist_tone1","woman_technologist_light_skin_tone"],"1F469-1F3FC-200D-1F4BB":["woman_technologist_tone2","woman_technologist_medium_light_skin_tone"],"1F469-1F3FD-200D-1F4BB":["woman_technologist_tone3","woman_technologist_medium_skin_tone"],"1F469-1F3FE-200D-1F4BB":["woman_technologist_tone4","woman_technologist_medium_dark_skin_tone"],"1F469-1F3FF-200D-1F4BB":["woman_technologist_tone5","woman_technologist_dark_skin_tone"],"1F468-200D-1F4BB":"man_technologist","1F468-1F3FB-200D-1F4BB":["man_technologist_tone1","man_technologist_light_skin_tone"],"1F468-1F3FC-200D-1F4BB":["man_technologist_tone2","man_technologist_medium_light_skin_tone"],"1F468-1F3FD-200D-1F4BB":["man_technologist_tone3","man_technologist_medium_skin_tone"],"1F468-1F3FE-200D-1F4BB":["man_technologist_tone4","man_technologist_medium_dark_skin_tone"],"1F468-1F3FF-200D-1F4BB":["man_technologist_tone5","man_technologist_dark_skin_tone"],"1F9D1-200D-1F4BC":"office_worker","1F9D1-1F3FB-200D-1F4BC":["office_worker_tone1","office_worker_light_skin_tone"],"1F9D1-1F3FC-200D-1F4BC":["office_worker_tone2","office_worker_medium_light_skin_tone"],"1F9D1-1F3FD-200D-1F4BC":["office_worker_tone3","office_worker_medium_skin_tone"],"1F9D1-1F3FE-200D-1F4BC":["office_worker_tone4","office_worker_medium_dark_skin_tone"],"1F9D1-1F3FF-200D-1F4BC":["office_worker_tone5","office_worker_dark_skin_tone"],"1F469-200D-1F4BC":"woman_office_worker","1F469-1F3FB-200D-1F4BC":["woman_office_worker_tone1","woman_office_worker_light_skin_tone"],"1F469-1F3FC-200D-1F4BC":["woman_office_worker_tone2","woman_office_worker_medium_light_skin_tone"],"1F469-1F3FD-200D-1F4BC":["woman_office_worker_tone3","woman_office_worker_medium_skin_tone"],"1F469-1F3FE-200D-1F4BC":["woman_office_worker_tone4","woman_office_worker_medium_dark_skin_tone"],"1F469-1F3FF-200D-1F4BC":["woman_office_worker_tone5","woman_office_worker_dark_skin_tone"],"1F468-200D-1F4BC":"man_office_worker","1F468-1F3FB-200D-1F4BC":["man_office_worker_tone1","man_office_worker_light_skin_tone"],"1F468-1F3FC-200D-1F4BC":["man_office_worker_tone2","man_office_worker_medium_light_skin_tone"],"1F468-1F3FD-200D-1F4BC":["man_office_worker_tone3","man_office_worker_medium_skin_tone"],"1F468-1F3FE-200D-1F4BC":["man_office_worker_tone4","man_office_worker_medium_dark_skin_tone"],"1F468-1F3FF-200D-1F4BC":["man_office_worker_tone5","man_office_worker_dark_skin_tone"],"1F9D1-200D-1F527":"mechanic","1F9D1-1F3FB-200D-1F527":["mechanic_tone1","mechanic_light_skin_tone"],"1F9D1-1F3FC-200D-1F527":["mechanic_tone2","mechanic_medium_light_skin_tone"],"1F9D1-1F3FD-200D-1F527":["mechanic_tone3","mechanic_medium_skin_tone"],"1F9D1-1F3FE-200D-1F527":["mechanic_tone4","mechanic_medium_dark_skin_tone"],"1F9D1-1F3FF-200D-1F527":["mechanic_tone5","mechanic_dark_skin_tone"],"1F469-200D-1F527":"woman_mechanic","1F469-1F3FB-200D-1F527":["woman_mechanic_tone1","woman_mechanic_light_skin_tone"],"1F469-1F3FC-200D-1F527":["woman_mechanic_tone2","woman_mechanic_medium_light_skin_tone"],"1F469-1F3FD-200D-1F527":["woman_mechanic_tone3","woman_mechanic_medium_skin_tone"],"1F469-1F3FE-200D-1F527":["woman_mechanic_tone4","woman_mechanic_medium_dark_skin_tone"],"1F469-1F3FF-200D-1F527":["woman_mechanic_tone5","woman_mechanic_dark_skin_tone"],"1F468-200D-1F527":"man_mechanic","1F468-1F3FB-200D-1F527":["man_mechanic_tone1","man_mechanic_light_skin_tone"],"1F468-1F3FC-200D-1F527":["man_mechanic_tone2","man_mechanic_medium_light_skin_tone"],"1F468-1F3FD-200D-1F527":["man_mechanic_tone3","man_mechanic_medium_skin_tone"],"1F468-1F3FE-200D-1F527":["man_mechanic_tone4","man_mechanic_medium_dark_skin_tone"],"1F468-1F3FF-200D-1F527":["man_mechanic_tone5","man_mechanic_dark_skin_tone"],"1F9D1-200D-1F52C":"scientist","1F9D1-1F3FB-200D-1F52C":["scientist_tone1","scientist_light_skin_tone"],"1F9D1-1F3FC-200D-1F52C":["scientist_tone2","scientist_medium_light_skin_tone"],"1F9D1-1F3FD-200D-1F52C":["scientist_tone3","scientist_medium_skin_tone"],"1F9D1-1F3FE-200D-1F52C":["scientist_tone4","scientist_medium_dark_skin_tone"],"1F9D1-1F3FF-200D-1F52C":["scientist_tone5","scientist_dark_skin_tone"],"1F469-200D-1F52C":"woman_scientist","1F469-1F3FB-200D-1F52C":["woman_scientist_tone1","woman_scientist_light_skin_tone"],"1F469-1F3FC-200D-1F52C":["woman_scientist_tone2","woman_scientist_medium_light_skin_tone"],"1F469-1F3FD-200D-1F52C":["woman_scientist_tone3","woman_scientist_medium_skin_tone"],"1F469-1F3FE-200D-1F52C":["woman_scientist_tone4","woman_scientist_medium_dark_skin_tone"],"1F469-1F3FF-200D-1F52C":["woman_scientist_tone5","woman_scientist_dark_skin_tone"],"1F468-200D-1F52C":"man_scientist","1F468-1F3FB-200D-1F52C":["man_scientist_tone1","man_scientist_light_skin_tone"],"1F468-1F3FC-200D-1F52C":["man_scientist_tone2","man_scientist_medium_light_skin_tone"],"1F468-1F3FD-200D-1F52C":["man_scientist_tone3","man_scientist_medium_skin_tone"],"1F468-1F3FE-200D-1F52C":["man_scientist_tone4","man_scientist_medium_dark_skin_tone"],"1F468-1F3FF-200D-1F52C":["man_scientist_tone5","man_scientist_dark_skin_tone"],"1F9D1-200D-1F3A8":"artist","1F9D1-1F3FB-200D-1F3A8":["artist_tone1","artist_light_skin_tone"],"1F9D1-1F3FC-200D-1F3A8":["artist_tone2","artist_medium_light_skin_tone"],"1F9D1-1F3FD-200D-1F3A8":["artist_tone3","artist_medium_skin_tone"],"1F9D1-1F3FE-200D-1F3A8":["artist_tone4","artist_medium_dark_skin_tone"],"1F9D1-1F3FF-200D-1F3A8":["artist_tone5","artist_dark_skin_tone"],"1F469-200D-1F3A8":"woman_artist","1F469-1F3FB-200D-1F3A8":["woman_artist_tone1","woman_artist_light_skin_tone"],"1F469-1F3FC-200D-1F3A8":["woman_artist_tone2","woman_artist_medium_light_skin_tone"],"1F469-1F3FD-200D-1F3A8":["woman_artist_tone3","woman_artist_medium_skin_tone"],"1F469-1F3FE-200D-1F3A8":["woman_artist_tone4","woman_artist_medium_dark_skin_tone"],"1F469-1F3FF-200D-1F3A8":["woman_artist_tone5","woman_artist_dark_skin_tone"],"1F468-200D-1F3A8":"man_artist","1F468-1F3FB-200D-1F3A8":["man_artist_tone1","man_artist_light_skin_tone"],"1F468-1F3FC-200D-1F3A8":["man_artist_tone2","man_artist_medium_light_skin_tone"],"1F468-1F3FD-200D-1F3A8":["man_artist_tone3","man_artist_medium_skin_tone"],"1F468-1F3FE-200D-1F3A8":["man_artist_tone4","man_artist_medium_dark_skin_tone"],"1F468-1F3FF-200D-1F3A8":["man_artist_tone5","man_artist_dark_skin_tone"],"1F9D1-200D-1F692":"firefighter","1F9D1-1F3FB-200D-1F692":["firefighter_tone1","firefighter_light_skin_tone"],"1F9D1-1F3FC-200D-1F692":["firefighter_tone2","firefighter_medium_light_skin_tone"],"1F9D1-1F3FD-200D-1F692":["firefighter_tone3","firefighter_medium_skin_tone"],"1F9D1-1F3FE-200D-1F692":["firefighter_tone4","firefighter_medium_dark_skin_tone"],"1F9D1-1F3FF-200D-1F692":["firefighter_tone5","firefighter_dark_skin_tone"],"1F469-200D-1F692":"woman_firefighter","1F469-1F3FB-200D-1F692":["woman_firefighter_tone1","woman_firefighter_light_skin_tone"],"1F469-1F3FC-200D-1F692":["woman_firefighter_tone2","woman_firefighter_medium_light_skin_tone"],"1F469-1F3FD-200D-1F692":["woman_firefighter_tone3","woman_firefighter_medium_skin_tone"],"1F469-1F3FE-200D-1F692":["woman_firefighter_tone4","woman_firefighter_medium_dark_skin_tone"],"1F469-1F3FF-200D-1F692":["woman_firefighter_tone5","woman_firefighter_dark_skin_tone"],"1F468-200D-1F692":"man_firefighter","1F468-1F3FB-200D-1F692":["man_firefighter_tone1","man_firefighter_light_skin_tone"],"1F468-1F3FC-200D-1F692":["man_firefighter_tone2","man_firefighter_medium_light_skin_tone"],"1F468-1F3FD-200D-1F692":["man_firefighter_tone3","man_firefighter_medium_skin_tone"],"1F468-1F3FE-200D-1F692":["man_firefighter_tone4","man_firefighter_medium_dark_skin_tone"],"1F468-1F3FF-200D-1F692":["man_firefighter_tone5","man_firefighter_dark_skin_tone"],"1F9D1-200D-2708-FE0F":"pilot","1F9D1-1F3FB-200D-2708-FE0F":["pilot_tone1","pilot_light_skin_tone"],"1F9D1-1F3FC-200D-2708-FE0F":["pilot_tone2","pilot_medium_light_skin_tone"],"1F9D1-1F3FD-200D-2708-FE0F":["pilot_tone3","pilot_medium_skin_tone"],"1F9D1-1F3FE-200D-2708-FE0F":["pilot_tone4","pilot_medium_dark_skin_tone"],"1F9D1-1F3FF-200D-2708-FE0F":["pilot_tone5","pilot_dark_skin_tone"],"1F469-200D-2708-FE0F":"woman_pilot","1F469-1F3FB-200D-2708-FE0F":["woman_pilot_tone1","woman_pilot_light_skin_tone"],"1F469-1F3FC-200D-2708-FE0F":["woman_pilot_tone2","woman_pilot_medium_light_skin_tone"],"1F469-1F3FD-200D-2708-FE0F":["woman_pilot_tone3","woman_pilot_medium_skin_tone"],"1F469-1F3FE-200D-2708-FE0F":["woman_pilot_tone4","woman_pilot_medium_dark_skin_tone"],"1F469-1F3FF-200D-2708-FE0F":["woman_pilot_tone5","woman_pilot_dark_skin_tone"],"1F468-200D-2708-FE0F":"man_pilot","1F468-1F3FB-200D-2708-FE0F":["man_pilot_tone1","man_pilot_light_skin_tone"],"1F468-1F3FC-200D-2708-FE0F":["man_pilot_tone2","man_pilot_medium_light_skin_tone"],"1F468-1F3FD-200D-2708-FE0F":["man_pilot_tone3","man_pilot_medium_skin_tone"],"1F468-1F3FE-200D-2708-FE0F":["man_pilot_tone4","man_pilot_medium_dark_skin_tone"],"1F468-1F3FF-200D-2708-FE0F":["man_pilot_tone5","man_pilot_dark_skin_tone"],"1F9D1-200D-1F680":"astronaut","1F9D1-1F3FB-200D-1F680":["astronaut_tone1","astronaut_light_skin_tone"],"1F9D1-1F3FC-200D-1F680":["astronaut_tone2","astronaut_medium_light_skin_tone"],"1F9D1-1F3FD-200D-1F680":["astronaut_tone3","astronaut_medium_skin_tone"],"1F9D1-1F3FE-200D-1F680":["astronaut_tone4","astronaut_medium_dark_skin_tone"],"1F9D1-1F3FF-200D-1F680":["astronaut_tone5","astronaut_dark_skin_tone"],"1F469-200D-1F680":"woman_astronaut","1F469-1F3FB-200D-1F680":["woman_astronaut_tone1","woman_astronaut_light_skin_tone"],"1F469-1F3FC-200D-1F680":["woman_astronaut_tone2","woman_astronaut_medium_light_skin_tone"],"1F469-1F3FD-200D-1F680":["woman_astronaut_tone3","woman_astronaut_medium_skin_tone"],"1F469-1F3FE-200D-1F680":["woman_astronaut_tone4","woman_astronaut_medium_dark_skin_tone"],"1F469-1F3FF-200D-1F680":["woman_astronaut_tone5","woman_astronaut_dark_skin_tone"],"1F468-200D-1F680":"man_astronaut","1F468-1F3FB-200D-1F680":["man_astronaut_tone1","man_astronaut_light_skin_tone"],"1F468-1F3FC-200D-1F680":["man_astronaut_tone2","man_astronaut_medium_light_skin_tone"],"1F468-1F3FD-200D-1F680":["man_astronaut_tone3","man_astronaut_medium_skin_tone"],"1F468-1F3FE-200D-1F680":["man_astronaut_tone4","man_astronaut_medium_dark_skin_tone"],"1F468-1F3FF-200D-1F680":["man_astronaut_tone5","man_astronaut_dark_skin_tone"],"1F9D1-200D-2696-FE0F":"judge","1F9D1-1F3FB-200D-2696-FE0F":["judge_tone1","judge_light_skin_tone"],"1F9D1-1F3FC-200D-2696-FE0F":["judge_tone2","judge_medium_light_skin_tone"],"1F9D1-1F3FD-200D-2696-FE0F":["judge_tone3","judge_medium_skin_tone"],"1F9D1-1F3FE-200D-2696-FE0F":["judge_tone4","judge_medium_dark_skin_tone"],"1F9D1-1F3FF-200D-2696-FE0F":["judge_tone5","judge_dark_skin_tone"],"1F469-200D-2696-FE0F":"woman_judge","1F469-1F3FB-200D-2696-FE0F":["woman_judge_tone1","woman_judge_light_skin_tone"],"1F469-1F3FC-200D-2696-FE0F":["woman_judge_tone2","woman_judge_medium_light_skin_tone"],"1F469-1F3FD-200D-2696-FE0F":["woman_judge_tone3","woman_judge_medium_skin_tone"],"1F469-1F3FE-200D-2696-FE0F":["woman_judge_tone4","woman_judge_medium_dark_skin_tone"],"1F469-1F3FF-200D-2696-FE0F":["woman_judge_tone5","woman_judge_dark_skin_tone"],"1F468-200D-2696-FE0F":"man_judge","1F468-1F3FB-200D-2696-FE0F":["man_judge_tone1","man_judge_light_skin_tone"],"1F468-1F3FC-200D-2696-FE0F":["man_judge_tone2","man_judge_medium_light_skin_tone"],"1F468-1F3FD-200D-2696-FE0F":["man_judge_tone3","man_judge_medium_skin_tone"],"1F468-1F3FE-200D-2696-FE0F":["man_judge_tone4","man_judge_medium_dark_skin_tone"],"1F468-1F3FF-200D-2696-FE0F":["man_judge_tone5","man_judge_dark_skin_tone"],"1F470":"person_with_veil","1F470-1F3FB":"person_with_veil_tone1","1F470-1F3FC":"person_with_veil_tone2","1F470-1F3FD":"person_with_veil_tone3","1F470-1F3FE":"person_with_veil_tone4","1F470-1F3FF":"person_with_veil_tone5","1F470-200D-2640-FE0F":"woman_with_veil","1F470-1F3FB-200D-2640-FE0F":["woman_with_veil_tone1","woman_with_veil_light_skin_tone"],"1F470-1F3FC-200D-2640-FE0F":["woman_with_veil_tone2","woman_with_veil_medium_light_skin_tone"],"1F470-1F3FD-200D-2640-FE0F":["woman_with_veil_tone3","woman_with_veil_medium_skin_tone"],"1F470-1F3FE-200D-2640-FE0F":["woman_with_veil_tone4","woman_with_veil_medium_dark_skin_tone"],"1F470-1F3FF-200D-2640-FE0F":["woman_with_veil_tone5","woman_with_veil_dark_skin_tone"],"1F470-200D-2642-FE0F":"man_with_veil","1F470-1F3FB-200D-2642-FE0F":["man_with_veil_tone1","man_with_veil_light_skin_tone"],"1F470-1F3FC-200D-2642-FE0F":["man_with_veil_tone2","man_with_veil_medium_light_skin_tone"],"1F470-1F3FD-200D-2642-FE0F":["man_with_veil_tone3","man_with_veil_medium_skin_tone"],"1F470-1F3FE-200D-2642-FE0F":["man_with_veil_tone4","man_with_veil_medium_dark_skin_tone"],"1F470-1F3FF-200D-2642-FE0F":["man_with_veil_tone5","man_with_veil_dark_skin_tone"],"1F935":"person_in_tuxedo","1F935-1F3FB":["person_in_tuxedo_tone1","tuxedo_tone1"],"1F935-1F3FC":["person_in_tuxedo_tone2","tuxedo_tone2"],"1F935-1F3FD":["person_in_tuxedo_tone3","tuxedo_tone3"],"1F935-1F3FE":["person_in_tuxedo_tone4","tuxedo_tone4"],"1F935-1F3FF":["person_in_tuxedo_tone5","tuxedo_tone5"],"1F935-200D-2640-FE0F":"woman_in_tuxedo","1F935-1F3FB-200D-2640-FE0F":["woman_in_tuxedo_tone1","woman_in_tuxedo_light_skin_tone"],"1F935-1F3FC-200D-2640-FE0F":["woman_in_tuxedo_tone2","woman_in_tuxedo_medium_light_skin_tone"],"1F935-1F3FD-200D-2640-FE0F":["woman_in_tuxedo_tone3","woman_in_tuxedo_medium_skin_tone"],"1F935-1F3FE-200D-2640-FE0F":["woman_in_tuxedo_tone4","woman_in_tuxedo_medium_dark_skin_tone"],"1F935-1F3FF-200D-2640-FE0F":["woman_in_tuxedo_tone5","woman_in_tuxedo_dark_skin_tone"],"1F935-200D-2642-FE0F":"man_in_tuxedo","1F935-1F3FB-200D-2642-FE0F":["man_in_tuxedo_tone1","man_in_tuxedo_light_skin_tone"],"1F935-1F3FC-200D-2642-FE0F":["man_in_tuxedo_tone2","man_in_tuxedo_medium_light_skin_tone"],"1F935-1F3FD-200D-2642-FE0F":["man_in_tuxedo_tone3","man_in_tuxedo_medium_skin_tone"],"1F935-1F3FE-200D-2642-FE0F":["man_in_tuxedo_tone4","man_in_tuxedo_medium_dark_skin_tone"],"1F935-1F3FF-200D-2642-FE0F":["man_in_tuxedo_tone5","man_in_tuxedo_dark_skin_tone"],"1F478":"princess","1F478-1F3FB":"princess_tone1","1F478-1F3FC":"princess_tone2","1F478-1F3FD":"princess_tone3","1F478-1F3FE":"princess_tone4","1F478-1F3FF":"princess_tone5","1F934":"prince","1F934-1F3FB":"prince_tone1","1F934-1F3FC":"prince_tone2","1F934-1F3FD":"prince_tone3","1F934-1F3FE":"prince_tone4","1F934-1F3FF":"prince_tone5","1F9B8":"superhero","1F9B8-1F3FB":["superhero_tone1","superhero_light_skin_tone"],"1F9B8-1F3FC":["superhero_tone2","superhero_medium_light_skin_tone"],"1F9B8-1F3FD":["superhero_tone3","superhero_medium_skin_tone"],"1F9B8-1F3FE":["superhero_tone4","superhero_medium_dark_skin_tone"],"1F9B8-1F3FF":["superhero_tone5","superhero_dark_skin_tone"],"1F9B8-200D-2640-FE0F":"woman_superhero","1F9B8-1F3FB-200D-2640-FE0F":["woman_superhero_tone1","woman_superhero_light_skin_tone"],"1F9B8-1F3FC-200D-2640-FE0F":["woman_superhero_tone2","woman_superhero_medium_light_skin_tone"],"1F9B8-1F3FD-200D-2640-FE0F":["woman_superhero_tone3","woman_superhero_medium_skin_tone"],"1F9B8-1F3FE-200D-2640-FE0F":["woman_superhero_tone4","woman_superhero_medium_dark_skin_tone"],"1F9B8-1F3FF-200D-2640-FE0F":["woman_superhero_tone5","woman_superhero_dark_skin_tone"],"1F9B8-200D-2642-FE0F":"man_superhero","1F9B8-1F3FB-200D-2642-FE0F":["man_superhero_tone1","man_superhero_light_skin_tone"],"1F9B8-1F3FC-200D-2642-FE0F":["man_superhero_tone2","man_superhero_medium_light_skin_tone"],"1F9B8-1F3FD-200D-2642-FE0F":["man_superhero_tone3","man_superhero_medium_skin_tone"],"1F9B8-1F3FE-200D-2642-FE0F":["man_superhero_tone4","man_superhero_medium_dark_skin_tone"],"1F9B8-1F3FF-200D-2642-FE0F":["man_superhero_tone5","man_superhero_dark_skin_tone"],"1F9B9":"supervillain","1F9B9-1F3FB":["supervillain_tone1","supervillain_light_skin_tone"],"1F9B9-1F3FC":["supervillain_tone2","supervillain_medium_light_skin_tone"],"1F9B9-1F3FD":["supervillain_tone3","supervillain_medium_skin_tone"],"1F9B9-1F3FE":["supervillain_tone4","supervillain_medium_dark_skin_tone"],"1F9B9-1F3FF":["supervillain_tone5","supervillain_dark_skin_tone"],"1F9B9-200D-2640-FE0F":"woman_supervillain","1F9B9-1F3FB-200D-2640-FE0F":["woman_supervillain_tone1","woman_supervillain_light_skin_tone"],"1F9B9-1F3FC-200D-2640-FE0F":["woman_supervillain_tone2","woman_supervillain_medium_light_skin_tone"],"1F9B9-1F3FD-200D-2640-FE0F":["woman_supervillain_tone3","woman_supervillain_medium_skin_tone"],"1F9B9-1F3FE-200D-2640-FE0F":["woman_supervillain_tone4","woman_supervillain_medium_dark_skin_tone"],"1F9B9-1F3FF-200D-2640-FE0F":["woman_supervillain_tone5","woman_supervillain_dark_skin_tone"],"1F9B9-200D-2642-FE0F":"man_supervillain","1F9B9-1F3FB-200D-2642-FE0F":["man_supervillain_tone1","man_supervillain_light_skin_tone"],"1F9B9-1F3FC-200D-2642-FE0F":["man_supervillain_tone2","man_supervillain_medium_light_skin_tone"],"1F9B9-1F3FD-200D-2642-FE0F":["man_supervillain_tone3","man_supervillain_medium_skin_tone"],"1F9B9-1F3FE-200D-2642-FE0F":["man_supervillain_tone4","man_supervillain_medium_dark_skin_tone"],"1F9B9-1F3FF-200D-2642-FE0F":["man_supervillain_tone5","man_supervillain_dark_skin_tone"],"1F977":"ninja","1F977-1F3FB":["ninja_tone1","ninja_light_skin_tone"],"1F977-1F3FC":["ninja_tone2","ninja_medium_light_skin_tone"],"1F977-1F3FD":["ninja_tone3","ninja_medium_skin_tone"],"1F977-1F3FE":["ninja_tone4","ninja_medium_dark_skin_tone"],"1F977-1F3FF":["ninja_tone5","ninja_dark_skin_tone"],"1F9D1-200D-1F384":"mx_claus","1F9D1-1F3FB-200D-1F384":["mx_claus_tone1","mx_claus_light_skin_tone"],"1F9D1-1F3FC-200D-1F384":["mx_claus_tone2","mx_claus_medium_light_skin_tone"],"1F9D1-1F3FD-200D-1F384":["mx_claus_tone3","mx_claus_medium_skin_tone"],"1F9D1-1F3FE-200D-1F384":["mx_claus_tone4","mx_claus_medium_dark_skin_tone"],"1F9D1-1F3FF-200D-1F384":["mx_claus_tone5","mx_claus_dark_skin_tone"],"1F936":["mrs_claus","mother_christmas"],"1F936-1F3FB":["mrs_claus_tone1","mother_christmas_tone1"],"1F936-1F3FC":["mrs_claus_tone2","mother_christmas_tone2"],"1F936-1F3FD":["mrs_claus_tone3","mother_christmas_tone3"],"1F936-1F3FE":["mrs_claus_tone4","mother_christmas_tone4"],"1F936-1F3FF":["mrs_claus_tone5","mother_christmas_tone5"],"1F385":"santa","1F385-1F3FB":"santa_tone1","1F385-1F3FC":"santa_tone2","1F385-1F3FD":"santa_tone3","1F385-1F3FE":"santa_tone4","1F385-1F3FF":"santa_tone5","1F9D9":"mage","1F9D9-1F3FB":["mage_tone1","mage_light_skin_tone"],"1F9D9-1F3FC":["mage_tone2","mage_medium_light_skin_tone"],"1F9D9-1F3FD":["mage_tone3","mage_medium_skin_tone"],"1F9D9-1F3FE":["mage_tone4","mage_medium_dark_skin_tone"],"1F9D9-1F3FF":["mage_tone5","mage_dark_skin_tone"],"1F9D9-200D-2640-FE0F":"woman_mage","1F9D9-1F3FB-200D-2640-FE0F":["woman_mage_tone1","woman_mage_light_skin_tone"],"1F9D9-1F3FC-200D-2640-FE0F":["woman_mage_tone2","woman_mage_medium_light_skin_tone"],"1F9D9-1F3FD-200D-2640-FE0F":["woman_mage_tone3","woman_mage_medium_skin_tone"],"1F9D9-1F3FE-200D-2640-FE0F":["woman_mage_tone4","woman_mage_medium_dark_skin_tone"],"1F9D9-1F3FF-200D-2640-FE0F":["woman_mage_tone5","woman_mage_dark_skin_tone"],"1F9D9-200D-2642-FE0F":"man_mage","1F9D9-1F3FB-200D-2642-FE0F":["man_mage_tone1","man_mage_light_skin_tone"],"1F9D9-1F3FC-200D-2642-FE0F":["man_mage_tone2","man_mage_medium_light_skin_tone"],"1F9D9-1F3FD-200D-2642-FE0F":["man_mage_tone3","man_mage_medium_skin_tone"],"1F9D9-1F3FE-200D-2642-FE0F":["man_mage_tone4","man_mage_medium_dark_skin_tone"],"1F9D9-1F3FF-200D-2642-FE0F":["man_mage_tone5","man_mage_dark_skin_tone"],"1F9DD":"elf","1F9DD-1F3FB":["elf_tone1","elf_light_skin_tone"],"1F9DD-1F3FC":["elf_tone2","elf_medium_light_skin_tone"],"1F9DD-1F3FD":["elf_tone3","elf_medium_skin_tone"],"1F9DD-1F3FE":["elf_tone4","elf_medium_dark_skin_tone"],"1F9DD-1F3FF":["elf_tone5","elf_dark_skin_tone"],"1F9DD-200D-2640-FE0F":"woman_elf","1F9DD-1F3FB-200D-2640-FE0F":["woman_elf_tone1","woman_elf_light_skin_tone"],"1F9DD-1F3FC-200D-2640-FE0F":["woman_elf_tone2","woman_elf_medium_light_skin_tone"],"1F9DD-1F3FD-200D-2640-FE0F":["woman_elf_tone3","woman_elf_medium_skin_tone"],"1F9DD-1F3FE-200D-2640-FE0F":["woman_elf_tone4","woman_elf_medium_dark_skin_tone"],"1F9DD-1F3FF-200D-2640-FE0F":["woman_elf_tone5","woman_elf_dark_skin_tone"],"1F9DD-200D-2642-FE0F":"man_elf","1F9DD-1F3FB-200D-2642-FE0F":["man_elf_tone1","man_elf_light_skin_tone"],"1F9DD-1F3FC-200D-2642-FE0F":["man_elf_tone2","man_elf_medium_light_skin_tone"],"1F9DD-1F3FD-200D-2642-FE0F":["man_elf_tone3","man_elf_medium_skin_tone"],"1F9DD-1F3FE-200D-2642-FE0F":["man_elf_tone4","man_elf_medium_dark_skin_tone"],"1F9DD-1F3FF-200D-2642-FE0F":["man_elf_tone5","man_elf_dark_skin_tone"],"1F9DB":"vampire","1F9DB-1F3FB":["vampire_tone1","vampire_light_skin_tone"],"1F9DB-1F3FC":["vampire_tone2","vampire_medium_light_skin_tone"],"1F9DB-1F3FD":["vampire_tone3","vampire_medium_skin_tone"],"1F9DB-1F3FE":["vampire_tone4","vampire_medium_dark_skin_tone"],"1F9DB-1F3FF":["vampire_tone5","vampire_dark_skin_tone"],"1F9DB-200D-2640-FE0F":"woman_vampire","1F9DB-1F3FB-200D-2640-FE0F":["woman_vampire_tone1","woman_vampire_light_skin_tone"],"1F9DB-1F3FC-200D-2640-FE0F":["woman_vampire_tone2","woman_vampire_medium_light_skin_tone"],"1F9DB-1F3FD-200D-2640-FE0F":["woman_vampire_tone3","woman_vampire_medium_skin_tone"],"1F9DB-1F3FE-200D-2640-FE0F":["woman_vampire_tone4","woman_vampire_medium_dark_skin_tone"],"1F9DB-1F3FF-200D-2640-FE0F":["woman_vampire_tone5","woman_vampire_dark_skin_tone"],"1F9DB-200D-2642-FE0F":"man_vampire","1F9DB-1F3FB-200D-2642-FE0F":["man_vampire_tone1","man_vampire_light_skin_tone"],"1F9DB-1F3FC-200D-2642-FE0F":["man_vampire_tone2","man_vampire_medium_light_skin_tone"],"1F9DB-1F3FD-200D-2642-FE0F":["man_vampire_tone3","man_vampire_medium_skin_tone"],"1F9DB-1F3FE-200D-2642-FE0F":["man_vampire_tone4","man_vampire_medium_dark_skin_tone"],"1F9DB-1F3FF-200D-2642-FE0F":["man_vampire_tone5","man_vampire_dark_skin_tone"],"1F9DF":"zombie","1F9DF-200D-2640-FE0F":"woman_zombie","1F9DF-200D-2642-FE0F":"man_zombie","1F9DE":"genie","1F9DE-200D-2640-FE0F":"woman_genie","1F9DE-200D-2642-FE0F":"man_genie","1F9DC":"merperson","1F9DC-1F3FB":["merperson_tone1","merperson_light_skin_tone"],"1F9DC-1F3FC":["merperson_tone2","merperson_medium_light_skin_tone"],"1F9DC-1F3FD":["merperson_tone3","merperson_medium_skin_tone"],"1F9DC-1F3FE":["merperson_tone4","merperson_medium_dark_skin_tone"],"1F9DC-1F3FF":["merperson_tone5","merperson_dark_skin_tone"],"1F9DC-200D-2640-FE0F":"mermaid","1F9DC-1F3FB-200D-2640-FE0F":["mermaid_tone1","mermaid_light_skin_tone"],"1F9DC-1F3FC-200D-2640-FE0F":["mermaid_tone2","mermaid_medium_light_skin_tone"],"1F9DC-1F3FD-200D-2640-FE0F":["mermaid_tone3","mermaid_medium_skin_tone"],"1F9DC-1F3FE-200D-2640-FE0F":["mermaid_tone4","mermaid_medium_dark_skin_tone"],"1F9DC-1F3FF-200D-2640-FE0F":["mermaid_tone5","mermaid_dark_skin_tone"],"1F9DC-200D-2642-FE0F":"merman","1F9DC-1F3FB-200D-2642-FE0F":["merman_tone1","merman_light_skin_tone"],"1F9DC-1F3FC-200D-2642-FE0F":["merman_tone2","merman_medium_light_skin_tone"],"1F9DC-1F3FD-200D-2642-FE0F":["merman_tone3","merman_medium_skin_tone"],"1F9DC-1F3FE-200D-2642-FE0F":["merman_tone4","merman_medium_dark_skin_tone"],"1F9DC-1F3FF-200D-2642-FE0F":["merman_tone5","merman_dark_skin_tone"],"1F9DA":"fairy","1F9DA-1F3FB":["fairy_tone1","fairy_light_skin_tone"],"1F9DA-1F3FC":["fairy_tone2","fairy_medium_light_skin_tone"],"1F9DA-1F3FD":["fairy_tone3","fairy_medium_skin_tone"],"1F9DA-1F3FE":["fairy_tone4","fairy_medium_dark_skin_tone"],"1F9DA-1F3FF":["fairy_tone5","fairy_dark_skin_tone"],"1F9DA-200D-2640-FE0F":"woman_fairy","1F9DA-1F3FB-200D-2640-FE0F":["woman_fairy_tone1","woman_fairy_light_skin_tone"],"1F9DA-1F3FC-200D-2640-FE0F":["woman_fairy_tone2","woman_fairy_medium_light_skin_tone"],"1F9DA-1F3FD-200D-2640-FE0F":["woman_fairy_tone3","woman_fairy_medium_skin_tone"],"1F9DA-1F3FE-200D-2640-FE0F":["woman_fairy_tone4","woman_fairy_medium_dark_skin_tone"],"1F9DA-1F3FF-200D-2640-FE0F":["woman_fairy_tone5","woman_fairy_dark_skin_tone"],"1F9DA-200D-2642-FE0F":"man_fairy","1F9DA-1F3FB-200D-2642-FE0F":["man_fairy_tone1","man_fairy_light_skin_tone"],"1F9DA-1F3FC-200D-2642-FE0F":["man_fairy_tone2","man_fairy_medium_light_skin_tone"],"1F9DA-1F3FD-200D-2642-FE0F":["man_fairy_tone3","man_fairy_medium_skin_tone"],"1F9DA-1F3FE-200D-2642-FE0F":["man_fairy_tone4","man_fairy_medium_dark_skin_tone"],"1F9DA-1F3FF-200D-2642-FE0F":["man_fairy_tone5","man_fairy_dark_skin_tone"],"1F47C":"angel","1F47C-1F3FB":"angel_tone1","1F47C-1F3FC":"angel_tone2","1F47C-1F3FD":"angel_tone3","1F47C-1F3FE":"angel_tone4","1F47C-1F3FF":"angel_tone5","1F930":["pregnant_woman","expecting_woman"],"1F930-1F3FB":["pregnant_woman_tone1","expecting_woman_tone1"],"1F930-1F3FC":["pregnant_woman_tone2","expecting_woman_tone2"],"1F930-1F3FD":["pregnant_woman_tone3","expecting_woman_tone3"],"1F930-1F3FE":["pregnant_woman_tone4","expecting_woman_tone4"],"1F930-1F3FF":["pregnant_woman_tone5","expecting_woman_tone5"],"1F931":"breast_feeding","1F931-1F3FB":["breast_feeding_tone1","breast_feeding_light_skin_tone"],"1F931-1F3FC":["breast_feeding_tone2","breast_feeding_medium_light_skin_tone"],"1F931-1F3FD":["breast_feeding_tone3","breast_feeding_medium_skin_tone"],"1F931-1F3FE":["breast_feeding_tone4","breast_feeding_medium_dark_skin_tone"],"1F931-1F3FF":["breast_feeding_tone5","breast_feeding_dark_skin_tone"],"1F9D1-200D-1F37C":"person_feeding_baby","1F9D1-1F3FB-200D-1F37C":["person_feeding_baby_tone1","person_feeding_baby_light_skin_tone"],"1F9D1-1F3FC-200D-1F37C":["person_feeding_baby_tone2","person_feeding_baby_medium_light_skin_tone"],"1F9D1-1F3FD-200D-1F37C":["person_feeding_baby_tone3","person_feeding_baby_medium_skin_tone"],"1F9D1-1F3FE-200D-1F37C":["person_feeding_baby_tone4","person_feeding_baby_medium_dark_skin_tone"],"1F9D1-1F3FF-200D-1F37C":["person_feeding_baby_tone5","person_feeding_baby_dark_skin_tone"],"1F469-200D-1F37C":"woman_feeding_baby","1F469-1F3FB-200D-1F37C":["woman_feeding_baby_tone1","woman_feeding_baby_light_skin_tone"],"1F469-1F3FC-200D-1F37C":["woman_feeding_baby_tone2","woman_feeding_baby_medium_light_skin_tone"],"1F469-1F3FD-200D-1F37C":["woman_feeding_baby_tone3","woman_feeding_baby_medium_skin_tone"],"1F469-1F3FE-200D-1F37C":["woman_feeding_baby_tone4","woman_feeding_baby_medium_dark_skin_tone"],"1F469-1F3FF-200D-1F37C":["woman_feeding_baby_tone5","woman_feeding_baby_dark_skin_tone"],"1F468-200D-1F37C":"man_feeding_baby","1F468-1F3FB-200D-1F37C":["man_feeding_baby_tone1","man_feeding_baby_light_skin_tone"],"1F468-1F3FC-200D-1F37C":["man_feeding_baby_tone2","man_feeding_baby_medium_light_skin_tone"],"1F468-1F3FD-200D-1F37C":["man_feeding_baby_tone3","man_feeding_baby_medium_skin_tone"],"1F468-1F3FE-200D-1F37C":["man_feeding_baby_tone4","man_feeding_baby_medium_dark_skin_tone"],"1F468-1F3FF-200D-1F37C":["man_feeding_baby_tone5","man_feeding_baby_dark_skin_tone"],"1F647":["person_bowing","bow"],"1F647-1F3FB":["person_bowing_tone1","bow_tone1"],"1F647-1F3FC":["person_bowing_tone2","bow_tone2"],"1F647-1F3FD":["person_bowing_tone3","bow_tone3"],"1F647-1F3FE":["person_bowing_tone4","bow_tone4"],"1F647-1F3FF":["person_bowing_tone5","bow_tone5"],"1F647-200D-2640-FE0F":"woman_bowing","1F647-1F3FB-200D-2640-FE0F":["woman_bowing_tone1","woman_bowing_light_skin_tone"],"1F647-1F3FC-200D-2640-FE0F":["woman_bowing_tone2","woman_bowing_medium_light_skin_tone"],"1F647-1F3FD-200D-2640-FE0F":["woman_bowing_tone3","woman_bowing_medium_skin_tone"],"1F647-1F3FE-200D-2640-FE0F":["woman_bowing_tone4","woman_bowing_medium_dark_skin_tone"],"1F647-1F3FF-200D-2640-FE0F":["woman_bowing_tone5","woman_bowing_dark_skin_tone"],"1F647-200D-2642-FE0F":"man_bowing","1F647-1F3FB-200D-2642-FE0F":["man_bowing_tone1","man_bowing_light_skin_tone"],"1F647-1F3FC-200D-2642-FE0F":["man_bowing_tone2","man_bowing_medium_light_skin_tone"],"1F647-1F3FD-200D-2642-FE0F":["man_bowing_tone3","man_bowing_medium_skin_tone"],"1F647-1F3FE-200D-2642-FE0F":["man_bowing_tone4","man_bowing_medium_dark_skin_tone"],"1F647-1F3FF-200D-2642-FE0F":["man_bowing_tone5","man_bowing_dark_skin_tone"],"1F481":["person_tipping_hand","information_desk_person"],"1F481-1F3FB":["person_tipping_hand_tone1","information_desk_person_tone1"],"1F481-1F3FC":["person_tipping_hand_tone2","information_desk_person_tone2"],"1F481-1F3FD":["person_tipping_hand_tone3","information_desk_person_tone3"],"1F481-1F3FE":["person_tipping_hand_tone4","information_desk_person_tone4"],"1F481-1F3FF":["person_tipping_hand_tone5","information_desk_person_tone5"],"1F481-200D-2640-FE0F":"woman_tipping_hand","1F481-1F3FB-200D-2640-FE0F":["woman_tipping_hand_tone1","woman_tipping_hand_light_skin_tone"],"1F481-1F3FC-200D-2640-FE0F":["woman_tipping_hand_tone2","woman_tipping_hand_medium_light_skin_tone"],"1F481-1F3FD-200D-2640-FE0F":["woman_tipping_hand_tone3","woman_tipping_hand_medium_skin_tone"],"1F481-1F3FE-200D-2640-FE0F":["woman_tipping_hand_tone4","woman_tipping_hand_medium_dark_skin_tone"],"1F481-1F3FF-200D-2640-FE0F":["woman_tipping_hand_tone5","woman_tipping_hand_dark_skin_tone"],"1F481-200D-2642-FE0F":"man_tipping_hand","1F481-1F3FB-200D-2642-FE0F":["man_tipping_hand_tone1","man_tipping_hand_light_skin_tone"],"1F481-1F3FC-200D-2642-FE0F":["man_tipping_hand_tone2","man_tipping_hand_medium_light_skin_tone"],"1F481-1F3FD-200D-2642-FE0F":["man_tipping_hand_tone3","man_tipping_hand_medium_skin_tone"],"1F481-1F3FE-200D-2642-FE0F":["man_tipping_hand_tone4","man_tipping_hand_medium_dark_skin_tone"],"1F481-1F3FF-200D-2642-FE0F":["man_tipping_hand_tone5","man_tipping_hand_dark_skin_tone"],"1F645":["person_gesturing_no","no_good"],"1F645-1F3FB":["person_gesturing_no_tone1","no_good_tone1"],"1F645-1F3FC":["person_gesturing_no_tone2","no_good_tone2"],"1F645-1F3FD":["person_gesturing_no_tone3","no_good_tone3"],"1F645-1F3FE":["person_gesturing_no_tone4","no_good_tone4"],"1F645-1F3FF":["person_gesturing_no_tone5","no_good_tone5"],"1F645-200D-2640-FE0F":"woman_gesturing_no","1F645-1F3FB-200D-2640-FE0F":["woman_gesturing_no_tone1","woman_gesturing_no_light_skin_tone"],"1F645-1F3FC-200D-2640-FE0F":["woman_gesturing_no_tone2","woman_gesturing_no_medium_light_skin_tone"],"1F645-1F3FD-200D-2640-FE0F":["woman_gesturing_no_tone3","woman_gesturing_no_medium_skin_tone"],"1F645-1F3FE-200D-2640-FE0F":["woman_gesturing_no_tone4","woman_gesturing_no_medium_dark_skin_tone"],"1F645-1F3FF-200D-2640-FE0F":["woman_gesturing_no_tone5","woman_gesturing_no_dark_skin_tone"],"1F645-200D-2642-FE0F":"man_gesturing_no","1F645-1F3FB-200D-2642-FE0F":["man_gesturing_no_tone1","man_gesturing_no_light_skin_tone"],"1F645-1F3FC-200D-2642-FE0F":["man_gesturing_no_tone2","man_gesturing_no_medium_light_skin_tone"],"1F645-1F3FD-200D-2642-FE0F":["man_gesturing_no_tone3","man_gesturing_no_medium_skin_tone"],"1F645-1F3FE-200D-2642-FE0F":["man_gesturing_no_tone4","man_gesturing_no_medium_dark_skin_tone"],"1F645-1F3FF-200D-2642-FE0F":["man_gesturing_no_tone5","man_gesturing_no_dark_skin_tone"],"1F646":["person_gesturing_ok","ok_woman"],"1F646-1F3FB":["person_gesturing_ok_tone1","ok_woman_tone1"],"1F646-1F3FC":["person_gesturing_ok_tone2","ok_woman_tone2"],"1F646-1F3FD":["person_gesturing_ok_tone3","ok_woman_tone3"],"1F646-1F3FE":["person_gesturing_ok_tone4","ok_woman_tone4"],"1F646-1F3FF":["person_gesturing_ok_tone5","ok_woman_tone5"],"1F646-200D-2640-FE0F":"woman_gesturing_ok","1F646-1F3FB-200D-2640-FE0F":["woman_gesturing_ok_tone1","woman_gesturing_ok_light_skin_tone"],"1F646-1F3FC-200D-2640-FE0F":["woman_gesturing_ok_tone2","woman_gesturing_ok_medium_light_skin_tone"],"1F646-1F3FD-200D-2640-FE0F":["woman_gesturing_ok_tone3","woman_gesturing_ok_medium_skin_tone"],"1F646-1F3FE-200D-2640-FE0F":["woman_gesturing_ok_tone4","woman_gesturing_ok_medium_dark_skin_tone"],"1F646-1F3FF-200D-2640-FE0F":["woman_gesturing_ok_tone5","woman_gesturing_ok_dark_skin_tone"],"1F646-200D-2642-FE0F":"man_gesturing_ok","1F646-1F3FB-200D-2642-FE0F":["man_gesturing_ok_tone1","man_gesturing_ok_light_skin_tone"],"1F646-1F3FC-200D-2642-FE0F":["man_gesturing_ok_tone2","man_gesturing_ok_medium_light_skin_tone"],"1F646-1F3FD-200D-2642-FE0F":["man_gesturing_ok_tone3","man_gesturing_ok_medium_skin_tone"],"1F646-1F3FE-200D-2642-FE0F":["man_gesturing_ok_tone4","man_gesturing_ok_medium_dark_skin_tone"],"1F646-1F3FF-200D-2642-FE0F":["man_gesturing_ok_tone5","man_gesturing_ok_dark_skin_tone"],"1F64B":["person_raising_hand","raising_hand"],"1F64B-1F3FB":["person_raising_hand_tone1","raising_hand_tone1"],"1F64B-1F3FC":["person_raising_hand_tone2","raising_hand_tone2"],"1F64B-1F3FD":["person_raising_hand_tone3","raising_hand_tone3"],"1F64B-1F3FE":["person_raising_hand_tone4","raising_hand_tone4"],"1F64B-1F3FF":["person_raising_hand_tone5","raising_hand_tone5"],"1F64B-200D-2640-FE0F":"woman_raising_hand","1F64B-1F3FB-200D-2640-FE0F":["woman_raising_hand_tone1","woman_raising_hand_light_skin_tone"],"1F64B-1F3FC-200D-2640-FE0F":["woman_raising_hand_tone2","woman_raising_hand_medium_light_skin_tone"],"1F64B-1F3FD-200D-2640-FE0F":["woman_raising_hand_tone3","woman_raising_hand_medium_skin_tone"],"1F64B-1F3FE-200D-2640-FE0F":["woman_raising_hand_tone4","woman_raising_hand_medium_dark_skin_tone"],"1F64B-1F3FF-200D-2640-FE0F":["woman_raising_hand_tone5","woman_raising_hand_dark_skin_tone"],"1F64B-200D-2642-FE0F":"man_raising_hand","1F64B-1F3FB-200D-2642-FE0F":["man_raising_hand_tone1","man_raising_hand_light_skin_tone"],"1F64B-1F3FC-200D-2642-FE0F":["man_raising_hand_tone2","man_raising_hand_medium_light_skin_tone"],"1F64B-1F3FD-200D-2642-FE0F":["man_raising_hand_tone3","man_raising_hand_medium_skin_tone"],"1F64B-1F3FE-200D-2642-FE0F":["man_raising_hand_tone4","man_raising_hand_medium_dark_skin_tone"],"1F64B-1F3FF-200D-2642-FE0F":["man_raising_hand_tone5","man_raising_hand_dark_skin_tone"],"1F9CF":"deaf_person","1F9CF-1F3FB":["deaf_person_tone1","deaf_person_light_skin_tone"],"1F9CF-1F3FC":["deaf_person_tone2","deaf_person_medium_light_skin_tone"],"1F9CF-1F3FD":["deaf_person_tone3","deaf_person_medium_skin_tone"],"1F9CF-1F3FE":["deaf_person_tone4","deaf_person_medium_dark_skin_tone"],"1F9CF-1F3FF":["deaf_person_tone5","deaf_person_dark_skin_tone"],"1F9CF-200D-2640-FE0F":"deaf_woman","1F9CF-1F3FB-200D-2640-FE0F":["deaf_woman_tone1","deaf_woman_light_skin_tone"],"1F9CF-1F3FC-200D-2640-FE0F":["deaf_woman_tone2","deaf_woman_medium_light_skin_tone"],"1F9CF-1F3FD-200D-2640-FE0F":["deaf_woman_tone3","deaf_woman_medium_skin_tone"],"1F9CF-1F3FE-200D-2640-FE0F":["deaf_woman_tone4","deaf_woman_medium_dark_skin_tone"],"1F9CF-1F3FF-200D-2640-FE0F":["deaf_woman_tone5","deaf_woman_dark_skin_tone"],"1F9CF-200D-2642-FE0F":"deaf_man","1F9CF-1F3FB-200D-2642-FE0F":["deaf_man_tone1","deaf_man_light_skin_tone"],"1F9CF-1F3FC-200D-2642-FE0F":["deaf_man_tone2","deaf_man_medium_light_skin_tone"],"1F9CF-1F3FD-200D-2642-FE0F":["deaf_man_tone3","deaf_man_medium_skin_tone"],"1F9CF-1F3FE-200D-2642-FE0F":["deaf_man_tone4","deaf_man_medium_dark_skin_tone"],"1F9CF-1F3FF-200D-2642-FE0F":["deaf_man_tone5","deaf_man_dark_skin_tone"],"1F926":["person_facepalming","face_palm","facepalm"],"1F926-1F3FB":["person_facepalming_tone1","face_palm_tone1","facepalm_tone1"],"1F926-1F3FC":["person_facepalming_tone2","face_palm_tone2","facepalm_tone2"],"1F926-1F3FD":["person_facepalming_tone3","face_palm_tone3","facepalm_tone3"],"1F926-1F3FE":["person_facepalming_tone4","face_palm_tone4","facepalm_tone4"],"1F926-1F3FF":["person_facepalming_tone5","face_palm_tone5","facepalm_tone5"],"1F926-200D-2640-FE0F":"woman_facepalming","1F926-1F3FB-200D-2640-FE0F":["woman_facepalming_tone1","woman_facepalming_light_skin_tone"],"1F926-1F3FC-200D-2640-FE0F":["woman_facepalming_tone2","woman_facepalming_medium_light_skin_tone"],"1F926-1F3FD-200D-2640-FE0F":["woman_facepalming_tone3","woman_facepalming_medium_skin_tone"],"1F926-1F3FE-200D-2640-FE0F":["woman_facepalming_tone4","woman_facepalming_medium_dark_skin_tone"],"1F926-1F3FF-200D-2640-FE0F":["woman_facepalming_tone5","woman_facepalming_dark_skin_tone"],"1F926-200D-2642-FE0F":"man_facepalming","1F926-1F3FB-200D-2642-FE0F":["man_facepalming_tone1","man_facepalming_light_skin_tone"],"1F926-1F3FC-200D-2642-FE0F":["man_facepalming_tone2","man_facepalming_medium_light_skin_tone"],"1F926-1F3FD-200D-2642-FE0F":["man_facepalming_tone3","man_facepalming_medium_skin_tone"],"1F926-1F3FE-200D-2642-FE0F":["man_facepalming_tone4","man_facepalming_medium_dark_skin_tone"],"1F926-1F3FF-200D-2642-FE0F":["man_facepalming_tone5","man_facepalming_dark_skin_tone"],"1F937":["person_shrugging","shrug"],"1F937-1F3FB":["person_shrugging_tone1","shrug_tone1"],"1F937-1F3FC":["person_shrugging_tone2","shrug_tone2"],"1F937-1F3FD":["person_shrugging_tone3","shrug_tone3"],"1F937-1F3FE":["person_shrugging_tone4","shrug_tone4"],"1F937-1F3FF":["person_shrugging_tone5","shrug_tone5"],"1F937-200D-2640-FE0F":"woman_shrugging","1F937-1F3FB-200D-2640-FE0F":["woman_shrugging_tone1","woman_shrugging_light_skin_tone"],"1F937-1F3FC-200D-2640-FE0F":["woman_shrugging_tone2","woman_shrugging_medium_light_skin_tone"],"1F937-1F3FD-200D-2640-FE0F":["woman_shrugging_tone3","woman_shrugging_medium_skin_tone"],"1F937-1F3FE-200D-2640-FE0F":["woman_shrugging_tone4","woman_shrugging_medium_dark_skin_tone"],"1F937-1F3FF-200D-2640-FE0F":["woman_shrugging_tone5","woman_shrugging_dark_skin_tone"],"1F937-200D-2642-FE0F":"man_shrugging","1F937-1F3FB-200D-2642-FE0F":["man_shrugging_tone1","man_shrugging_light_skin_tone"],"1F937-1F3FC-200D-2642-FE0F":["man_shrugging_tone2","man_shrugging_medium_light_skin_tone"],"1F937-1F3FD-200D-2642-FE0F":["man_shrugging_tone3","man_shrugging_medium_skin_tone"],"1F937-1F3FE-200D-2642-FE0F":["man_shrugging_tone4","man_shrugging_medium_dark_skin_tone"],"1F937-1F3FF-200D-2642-FE0F":["man_shrugging_tone5","man_shrugging_dark_skin_tone"],"1F64E":["person_pouting","person_with_pouting_face"],"1F64E-1F3FB":["person_pouting_tone1","person_with_pouting_face_tone1"],"1F64E-1F3FC":["person_pouting_tone2","person_with_pouting_face_tone2"],"1F64E-1F3FD":["person_pouting_tone3","person_with_pouting_face_tone3"],"1F64E-1F3FE":["person_pouting_tone4","person_with_pouting_face_tone4"],"1F64E-1F3FF":["person_pouting_tone5","person_with_pouting_face_tone5"],"1F64E-200D-2640-FE0F":"woman_pouting","1F64E-1F3FB-200D-2640-FE0F":["woman_pouting_tone1","woman_pouting_light_skin_tone"],"1F64E-1F3FC-200D-2640-FE0F":["woman_pouting_tone2","woman_pouting_medium_light_skin_tone"],"1F64E-1F3FD-200D-2640-FE0F":["woman_pouting_tone3","woman_pouting_medium_skin_tone"],"1F64E-1F3FE-200D-2640-FE0F":["woman_pouting_tone4","woman_pouting_medium_dark_skin_tone"],"1F64E-1F3FF-200D-2640-FE0F":["woman_pouting_tone5","woman_pouting_dark_skin_tone"],"1F64E-200D-2642-FE0F":"man_pouting","1F64E-1F3FB-200D-2642-FE0F":["man_pouting_tone1","man_pouting_light_skin_tone"],"1F64E-1F3FC-200D-2642-FE0F":["man_pouting_tone2","man_pouting_medium_light_skin_tone"],"1F64E-1F3FD-200D-2642-FE0F":["man_pouting_tone3","man_pouting_medium_skin_tone"],"1F64E-1F3FE-200D-2642-FE0F":["man_pouting_tone4","man_pouting_medium_dark_skin_tone"],"1F64E-1F3FF-200D-2642-FE0F":["man_pouting_tone5","man_pouting_dark_skin_tone"],"1F64D":"person_frowning","1F64D-1F3FB":"person_frowning_tone1","1F64D-1F3FC":"person_frowning_tone2","1F64D-1F3FD":"person_frowning_tone3","1F64D-1F3FE":"person_frowning_tone4","1F64D-1F3FF":"person_frowning_tone5","1F64D-200D-2640-FE0F":"woman_frowning","1F64D-1F3FB-200D-2640-FE0F":["woman_frowning_tone1","woman_frowning_light_skin_tone"],"1F64D-1F3FC-200D-2640-FE0F":["woman_frowning_tone2","woman_frowning_medium_light_skin_tone"],"1F64D-1F3FD-200D-2640-FE0F":["woman_frowning_tone3","woman_frowning_medium_skin_tone"],"1F64D-1F3FE-200D-2640-FE0F":["woman_frowning_tone4","woman_frowning_medium_dark_skin_tone"],"1F64D-1F3FF-200D-2640-FE0F":["woman_frowning_tone5","woman_frowning_dark_skin_tone"],"1F64D-200D-2642-FE0F":"man_frowning","1F64D-1F3FB-200D-2642-FE0F":["man_frowning_tone1","man_frowning_light_skin_tone"],"1F64D-1F3FC-200D-2642-FE0F":["man_frowning_tone2","man_frowning_medium_light_skin_tone"],"1F64D-1F3FD-200D-2642-FE0F":["man_frowning_tone3","man_frowning_medium_skin_tone"],"1F64D-1F3FE-200D-2642-FE0F":["man_frowning_tone4","man_frowning_medium_dark_skin_tone"],"1F64D-1F3FF-200D-2642-FE0F":["man_frowning_tone5","man_frowning_dark_skin_tone"],"1F487":["person_getting_haircut","haircut"],"1F487-1F3FB":["person_getting_haircut_tone1","haircut_tone1"],"1F487-1F3FC":["person_getting_haircut_tone2","haircut_tone2"],"1F487-1F3FD":["person_getting_haircut_tone3","haircut_tone3"],"1F487-1F3FE":["person_getting_haircut_tone4","haircut_tone4"],"1F487-1F3FF":["person_getting_haircut_tone5","haircut_tone5"],"1F487-200D-2640-FE0F":"woman_getting_haircut","1F487-1F3FB-200D-2640-FE0F":["woman_getting_haircut_tone1","woman_getting_haircut_light_skin_tone"],"1F487-1F3FC-200D-2640-FE0F":["woman_getting_haircut_tone2","woman_getting_haircut_medium_light_skin_tone"],"1F487-1F3FD-200D-2640-FE0F":["woman_getting_haircut_tone3","woman_getting_haircut_medium_skin_tone"],"1F487-1F3FE-200D-2640-FE0F":["woman_getting_haircut_tone4","woman_getting_haircut_medium_dark_skin_tone"],"1F487-1F3FF-200D-2640-FE0F":["woman_getting_haircut_tone5","woman_getting_haircut_dark_skin_tone"],"1F487-200D-2642-FE0F":"man_getting_haircut","1F487-1F3FB-200D-2642-FE0F":["man_getting_haircut_tone1","man_getting_haircut_light_skin_tone"],"1F487-1F3FC-200D-2642-FE0F":["man_getting_haircut_tone2","man_getting_haircut_medium_light_skin_tone"],"1F487-1F3FD-200D-2642-FE0F":["man_getting_haircut_tone3","man_getting_haircut_medium_skin_tone"],"1F487-1F3FE-200D-2642-FE0F":["man_getting_haircut_tone4","man_getting_haircut_medium_dark_skin_tone"],"1F487-1F3FF-200D-2642-FE0F":["man_getting_haircut_tone5","man_getting_haircut_dark_skin_tone"],"1F486":["person_getting_massage","massage"],"1F486-1F3FB":["person_getting_massage_tone1","massage_tone1"],"1F486-1F3FC":["person_getting_massage_tone2","massage_tone2"],"1F486-1F3FD":["person_getting_massage_tone3","massage_tone3"],"1F486-1F3FE":["person_getting_massage_tone4","massage_tone4"],"1F486-1F3FF":["person_getting_massage_tone5","massage_tone5"],"1F486-200D-2640-FE0F":"woman_getting_face_massage","1F486-1F3FB-200D-2640-FE0F":["woman_getting_face_massage_tone1","woman_getting_face_massage_light_skin_tone"],"1F486-1F3FC-200D-2640-FE0F":["woman_getting_face_massage_tone2","woman_getting_face_massage_medium_light_skin_tone"],"1F486-1F3FD-200D-2640-FE0F":["woman_getting_face_massage_tone3","woman_getting_face_massage_medium_skin_tone"],"1F486-1F3FE-200D-2640-FE0F":["woman_getting_face_massage_tone4","woman_getting_face_massage_medium_dark_skin_tone"],"1F486-1F3FF-200D-2640-FE0F":["woman_getting_face_massage_tone5","woman_getting_face_massage_dark_skin_tone"],"1F486-200D-2642-FE0F":"man_getting_face_massage","1F486-1F3FB-200D-2642-FE0F":["man_getting_face_massage_tone1","man_getting_face_massage_light_skin_tone"],"1F486-1F3FC-200D-2642-FE0F":["man_getting_face_massage_tone2","man_getting_face_massage_medium_light_skin_tone"],"1F486-1F3FD-200D-2642-FE0F":["man_getting_face_massage_tone3","man_getting_face_massage_medium_skin_tone"],"1F486-1F3FE-200D-2642-FE0F":["man_getting_face_massage_tone4","man_getting_face_massage_medium_dark_skin_tone"],"1F486-1F3FF-200D-2642-FE0F":["man_getting_face_massage_tone5","man_getting_face_massage_dark_skin_tone"],"1F9D6":"person_in_steamy_room","1F9D6-1F3FB":["person_in_steamy_room_tone1","person_in_steamy_room_light_skin_tone"],"1F9D6-1F3FC":["person_in_steamy_room_tone2","person_in_steamy_room_medium_light_skin_tone"],"1F9D6-1F3FD":["person_in_steamy_room_tone3","person_in_steamy_room_medium_skin_tone"],"1F9D6-1F3FE":["person_in_steamy_room_tone4","person_in_steamy_room_medium_dark_skin_tone"],"1F9D6-1F3FF":["person_in_steamy_room_tone5","person_in_steamy_room_dark_skin_tone"],"1F9D6-200D-2640-FE0F":"woman_in_steamy_room","1F9D6-1F3FB-200D-2640-FE0F":["woman_in_steamy_room_tone1","woman_in_steamy_room_light_skin_tone"],"1F9D6-1F3FC-200D-2640-FE0F":["woman_in_steamy_room_tone2","woman_in_steamy_room_medium_light_skin_tone"],"1F9D6-1F3FD-200D-2640-FE0F":["woman_in_steamy_room_tone3","woman_in_steamy_room_medium_skin_tone"],"1F9D6-1F3FE-200D-2640-FE0F":["woman_in_steamy_room_tone4","woman_in_steamy_room_medium_dark_skin_tone"],"1F9D6-1F3FF-200D-2640-FE0F":["woman_in_steamy_room_tone5","woman_in_steamy_room_dark_skin_tone"],"1F9D6-200D-2642-FE0F":"man_in_steamy_room","1F9D6-1F3FB-200D-2642-FE0F":["man_in_steamy_room_tone1","man_in_steamy_room_light_skin_tone"],"1F9D6-1F3FC-200D-2642-FE0F":["man_in_steamy_room_tone2","man_in_steamy_room_medium_light_skin_tone"],"1F9D6-1F3FD-200D-2642-FE0F":["man_in_steamy_room_tone3","man_in_steamy_room_medium_skin_tone"],"1F9D6-1F3FE-200D-2642-FE0F":["man_in_steamy_room_tone4","man_in_steamy_room_medium_dark_skin_tone"],"1F9D6-1F3FF-200D-2642-FE0F":["man_in_steamy_room_tone5","man_in_steamy_room_dark_skin_tone"],"1F485":"nail_care","1F485-1F3FB":"nail_care_tone1","1F485-1F3FC":"nail_care_tone2","1F485-1F3FD":"nail_care_tone3","1F485-1F3FE":"nail_care_tone4","1F485-1F3FF":"nail_care_tone5","1F933":"selfie","1F933-1F3FB":"selfie_tone1","1F933-1F3FC":"selfie_tone2","1F933-1F3FD":"selfie_tone3","1F933-1F3FE":"selfie_tone4","1F933-1F3FF":"selfie_tone5","1F483":"dancer","1F483-1F3FB":"dancer_tone1","1F483-1F3FC":"dancer_tone2","1F483-1F3FD":"dancer_tone3","1F483-1F3FE":"dancer_tone4","1F483-1F3FF":"dancer_tone5","1F57A":["man_dancing","male_dancer"],"1F57A-1F3FB":["man_dancing_tone1","male_dancer_tone1"],"1F57A-1F3FC":["man_dancing_tone2","male_dancer_tone2"],"1F57A-1F3FD":["man_dancing_tone3","male_dancer_tone3"],"1F57A-1F3FF":["man_dancing_tone5","male_dancer_tone5"],"1F57A-1F3FE":["man_dancing_tone4","male_dancer_tone4"],"1F46F":["people_with_bunny_ears_partying","dancers"],"1F46F-200D-2640-FE0F":"women_with_bunny_ears_partying","1F46F-200D-2642-FE0F":"men_with_bunny_ears_partying","1F574":["levitate","man_in_business_suit_levitating"],"1F574-1F3FB":["levitate_tone1","man_in_business_suit_levitating_tone1","man_in_business_suit_levitating_light_skin_tone"],"1F574-1F3FC":["levitate_tone2","man_in_business_suit_levitating_tone2","man_in_business_suit_levitating_medium_light_skin_tone"],"1F574-1F3FD":["levitate_tone3","man_in_business_suit_levitating_tone3","man_in_business_suit_levitating_medium_skin_tone"],"1F574-1F3FE":["levitate_tone4","man_in_business_suit_levitating_tone4","man_in_business_suit_levitating_medium_dark_skin_tone"],"1F574-1F3FF":["levitate_tone5","man_in_business_suit_levitating_tone5","man_in_business_suit_levitating_dark_skin_tone"],"1F9D1-200D-1F9BD":"person_in_manual_wheelchair","1F9D1-1F3FB-200D-1F9BD":["person_in_manual_wheelchair_tone1","person_in_manual_wheelchair_light_skin_tone"],"1F9D1-1F3FC-200D-1F9BD":["person_in_manual_wheelchair_tone2","person_in_manual_wheelchair_medium_light_skin_tone"],"1F9D1-1F3FD-200D-1F9BD":["person_in_manual_wheelchair_tone3","person_in_manual_wheelchair_medium_skin_tone"],"1F9D1-1F3FE-200D-1F9BD":["person_in_manual_wheelchair_tone4","person_in_manual_wheelchair_medium_dark_skin_tone"],"1F9D1-1F3FF-200D-1F9BD":["person_in_manual_wheelchair_tone5","person_in_manual_wheelchair_dark_skin_tone"],"1F469-200D-1F9BD":"woman_in_manual_wheelchair","1F469-1F3FB-200D-1F9BD":["woman_in_manual_wheelchair_tone1","woman_in_manual_wheelchair_light_skin_tone"],"1F469-1F3FC-200D-1F9BD":["woman_in_manual_wheelchair_tone2","woman_in_manual_wheelchair_medium_light_skin_tone"],"1F469-1F3FD-200D-1F9BD":["woman_in_manual_wheelchair_tone3","woman_in_manual_wheelchair_medium_skin_tone"],"1F469-1F3FE-200D-1F9BD":["woman_in_manual_wheelchair_tone4","woman_in_manual_wheelchair_medium_dark_skin_tone"],"1F469-1F3FF-200D-1F9BD":["woman_in_manual_wheelchair_tone5","woman_in_manual_wheelchair_dark_skin_tone"],"1F468-200D-1F9BD":"man_in_manual_wheelchair","1F468-1F3FB-200D-1F9BD":["man_in_manual_wheelchair_tone1","man_in_manual_wheelchair_light_skin_tone"],"1F468-1F3FC-200D-1F9BD":["man_in_manual_wheelchair_tone2","man_in_manual_wheelchair_medium_light_skin_tone"],"1F468-1F3FD-200D-1F9BD":["man_in_manual_wheelchair_tone3","man_in_manual_wheelchair_medium_skin_tone"],"1F468-1F3FE-200D-1F9BD":["man_in_manual_wheelchair_tone4","man_in_manual_wheelchair_medium_dark_skin_tone"],"1F468-1F3FF-200D-1F9BD":["man_in_manual_wheelchair_tone5","man_in_manual_wheelchair_dark_skin_tone"],"1F9D1-200D-1F9BC":"person_in_motorized_wheelchair","1F9D1-1F3FB-200D-1F9BC":["person_in_motorized_wheelchair_tone1","person_in_motorized_wheelchair_light_skin_tone"],"1F9D1-1F3FC-200D-1F9BC":["person_in_motorized_wheelchair_tone2","person_in_motorized_wheelchair_medium_light_skin_tone"],"1F9D1-1F3FD-200D-1F9BC":["person_in_motorized_wheelchair_tone3","person_in_motorized_wheelchair_medium_skin_tone"],"1F9D1-1F3FE-200D-1F9BC":["person_in_motorized_wheelchair_tone4","person_in_motorized_wheelchair_medium_dark_skin_tone"],"1F9D1-1F3FF-200D-1F9BC":["person_in_motorized_wheelchair_tone5","person_in_motorized_wheelchair_dark_skin_tone"],"1F469-200D-1F9BC":"woman_in_motorized_wheelchair","1F469-1F3FB-200D-1F9BC":["woman_in_motorized_wheelchair_tone1","woman_in_motorized_wheelchair_light_skin_tone"],"1F469-1F3FC-200D-1F9BC":["woman_in_motorized_wheelchair_tone2","woman_in_motorized_wheelchair_medium_light_skin_tone"],"1F469-1F3FD-200D-1F9BC":["woman_in_motorized_wheelchair_tone3","woman_in_motorized_wheelchair_medium_skin_tone"],"1F469-1F3FE-200D-1F9BC":["woman_in_motorized_wheelchair_tone4","woman_in_motorized_wheelchair_medium_dark_skin_tone"],"1F469-1F3FF-200D-1F9BC":["woman_in_motorized_wheelchair_tone5","woman_in_motorized_wheelchair_dark_skin_tone"],"1F468-200D-1F9BC":"man_in_motorized_wheelchair","1F468-1F3FB-200D-1F9BC":["man_in_motorized_wheelchair_tone1","man_in_motorized_wheelchair_light_skin_tone"],"1F468-1F3FC-200D-1F9BC":["man_in_motorized_wheelchair_tone2","man_in_motorized_wheelchair_medium_light_skin_tone"],"1F468-1F3FD-200D-1F9BC":["man_in_motorized_wheelchair_tone3","man_in_motorized_wheelchair_medium_skin_tone"],"1F468-1F3FE-200D-1F9BC":["man_in_motorized_wheelchair_tone4","man_in_motorized_wheelchair_medium_dark_skin_tone"],"1F468-1F3FF-200D-1F9BC":["man_in_motorized_wheelchair_tone5","man_in_motorized_wheelchair_dark_skin_tone"],"1F6B6":["person_walking","walking"],"1F6B6-1F3FB":["person_walking_tone1","walking_tone1"],"1F6B6-1F3FC":["person_walking_tone2","walking_tone2"],"1F6B6-1F3FD":["person_walking_tone3","walking_tone3"],"1F6B6-1F3FE":["person_walking_tone4","walking_tone4"],"1F6B6-1F3FF":["person_walking_tone5","walking_tone5"],"1F6B6-200D-2640-FE0F":"woman_walking","1F6B6-1F3FB-200D-2640-FE0F":["woman_walking_tone1","woman_walking_light_skin_tone"],"1F6B6-1F3FC-200D-2640-FE0F":["woman_walking_tone2","woman_walking_medium_light_skin_tone"],"1F6B6-1F3FD-200D-2640-FE0F":["woman_walking_tone3","woman_walking_medium_skin_tone"],"1F6B6-1F3FE-200D-2640-FE0F":["woman_walking_tone4","woman_walking_medium_dark_skin_tone"],"1F6B6-1F3FF-200D-2640-FE0F":["woman_walking_tone5","woman_walking_dark_skin_tone"],"1F6B6-200D-2642-FE0F":"man_walking","1F6B6-1F3FB-200D-2642-FE0F":["man_walking_tone1","man_walking_light_skin_tone"],"1F6B6-1F3FC-200D-2642-FE0F":["man_walking_tone2","man_walking_medium_light_skin_tone"],"1F6B6-1F3FD-200D-2642-FE0F":["man_walking_tone3","man_walking_medium_skin_tone"],"1F6B6-1F3FE-200D-2642-FE0F":["man_walking_tone4","man_walking_medium_dark_skin_tone"],"1F6B6-1F3FF-200D-2642-FE0F":["man_walking_tone5","man_walking_dark_skin_tone"],"1F9D1-200D-1F9AF":"person_with_probing_cane","1F9D1-1F3FB-200D-1F9AF":["person_with_probing_cane_tone1","person_with_probing_cane_light_skin_tone"],"1F9D1-1F3FC-200D-1F9AF":["person_with_probing_cane_tone2","person_with_probing_cane_medium_light_skin_tone"],"1F9D1-1F3FD-200D-1F9AF":["person_with_probing_cane_tone3","person_with_probing_cane_medium_skin_tone"],"1F9D1-1F3FE-200D-1F9AF":["person_with_probing_cane_tone4","person_with_probing_cane_medium_dark_skin_tone"],"1F9D1-1F3FF-200D-1F9AF":["person_with_probing_cane_tone5","person_with_probing_cane_dark_skin_tone"],"1F469-200D-1F9AF":"woman_with_probing_cane","1F469-1F3FB-200D-1F9AF":["woman_with_probing_cane_tone1","woman_with_probing_cane_light_skin_tone"],"1F469-1F3FC-200D-1F9AF":["woman_with_probing_cane_tone2","woman_with_probing_cane_medium_light_skin_tone"],"1F469-1F3FD-200D-1F9AF":["woman_with_probing_cane_tone3","woman_with_probing_cane_medium_skin_tone"],"1F469-1F3FE-200D-1F9AF":["woman_with_probing_cane_tone4","woman_with_probing_cane_medium_dark_skin_tone"],"1F469-1F3FF-200D-1F9AF":["woman_with_probing_cane_tone5","woman_with_probing_cane_dark_skin_tone"],"1F468-200D-1F9AF":"man_with_probing_cane","1F468-1F3FB-200D-1F9AF":["man_with_probing_cane_tone1","man_with_probing_cane_light_skin_tone"],"1F468-1F3FD-200D-1F9AF":["man_with_probing_cane_tone3","man_with_probing_cane_medium_skin_tone"],"1F468-1F3FC-200D-1F9AF":["man_with_probing_cane_tone2","man_with_probing_cane_medium_light_skin_tone"],"1F468-1F3FE-200D-1F9AF":["man_with_probing_cane_tone4","man_with_probing_cane_medium_dark_skin_tone"],"1F468-1F3FF-200D-1F9AF":["man_with_probing_cane_tone5","man_with_probing_cane_dark_skin_tone"],"1F9CE":"person_kneeling","1F9CE-1F3FB":["person_kneeling_tone1","person_kneeling_light_skin_tone"],"1F9CE-1F3FC":["person_kneeling_tone2","person_kneeling_medium_light_skin_tone"],"1F9CE-1F3FD":["person_kneeling_tone3","person_kneeling_medium_skin_tone"],"1F9CE-1F3FE":["person_kneeling_tone4","person_kneeling_medium_dark_skin_tone"],"1F9CE-1F3FF":["person_kneeling_tone5","person_kneeling_dark_skin_tone"],"1F9CE-200D-2640-FE0F":"woman_kneeling","1F9CE-1F3FB-200D-2640-FE0F":["woman_kneeling_tone1","woman_kneeling_light_skin_tone"],"1F9CE-1F3FC-200D-2640-FE0F":["woman_kneeling_tone2","woman_kneeling_medium_light_skin_tone"],"1F9CE-1F3FD-200D-2640-FE0F":["woman_kneeling_tone3","woman_kneeling_medium_skin_tone"],"1F9CE-1F3FE-200D-2640-FE0F":["woman_kneeling_tone4","woman_kneeling_medium_dark_skin_tone"],"1F9CE-1F3FF-200D-2640-FE0F":["woman_kneeling_tone5","woman_kneeling_dark_skin_tone"],"1F9CE-200D-2642-FE0F":"man_kneeling","1F9CE-1F3FB-200D-2642-FE0F":["man_kneeling_tone1","man_kneeling_light_skin_tone"],"1F9CE-1F3FC-200D-2642-FE0F":["man_kneeling_tone2","man_kneeling_medium_light_skin_tone"],"1F9CE-1F3FD-200D-2642-FE0F":["man_kneeling_tone3","man_kneeling_medium_skin_tone"],"1F9CE-1F3FE-200D-2642-FE0F":["man_kneeling_tone4","man_kneeling_medium_dark_skin_tone"],"1F9CE-1F3FF-200D-2642-FE0F":["man_kneeling_tone5","man_kneeling_dark_skin_tone"],"1F3C3":["person_running","runner"],"1F3C3-1F3FB":["person_running_tone1","runner_tone1"],"1F3C3-1F3FC":["person_running_tone2","runner_tone2"],"1F3C3-1F3FD":["person_running_tone3","runner_tone3"],"1F3C3-1F3FE":["person_running_tone4","runner_tone4"],"1F3C3-1F3FF":["person_running_tone5","runner_tone5"],"1F3C3-200D-2640-FE0F":"woman_running","1F3C3-1F3FB-200D-2640-FE0F":["woman_running_tone1","woman_running_light_skin_tone"],"1F3C3-1F3FC-200D-2640-FE0F":["woman_running_tone2","woman_running_medium_light_skin_tone"],"1F3C3-1F3FD-200D-2640-FE0F":["woman_running_tone3","woman_running_medium_skin_tone"],"1F3C3-1F3FE-200D-2640-FE0F":["woman_running_tone4","woman_running_medium_dark_skin_tone"],"1F3C3-1F3FF-200D-2640-FE0F":["woman_running_tone5","woman_running_dark_skin_tone"],"1F3C3-200D-2642-FE0F":"man_running","1F3C3-1F3FB-200D-2642-FE0F":["man_running_tone1","man_running_light_skin_tone"],"1F3C3-1F3FC-200D-2642-FE0F":["man_running_tone2","man_running_medium_light_skin_tone"],"1F3C3-1F3FD-200D-2642-FE0F":["man_running_tone3","man_running_medium_skin_tone"],"1F3C3-1F3FE-200D-2642-FE0F":["man_running_tone4","man_running_medium_dark_skin_tone"],"1F3C3-1F3FF-200D-2642-FE0F":["man_running_tone5","man_running_dark_skin_tone"],"1F9CD":"person_standing","1F9CD-1F3FB":["person_standing_tone1","person_standing_light_skin_tone"],"1F9CD-1F3FC":["person_standing_tone2","person_standing_medium_light_skin_tone"],"1F9CD-1F3FD":["person_standing_tone3","person_standing_medium_skin_tone"],"1F9CD-1F3FE":["person_standing_tone4","person_standing_medium_dark_skin_tone"],"1F9CD-1F3FF":["person_standing_tone5","person_standing_dark_skin_tone"],"1F9CD-200D-2640-FE0F":"woman_standing","1F9CD-1F3FB-200D-2640-FE0F":["woman_standing_tone1","woman_standing_light_skin_tone"],"1F9CD-1F3FC-200D-2640-FE0F":["woman_standing_tone2","woman_standing_medium_light_skin_tone"],"1F9CD-1F3FD-200D-2640-FE0F":["woman_standing_tone3","woman_standing_medium_skin_tone"],"1F9CD-1F3FE-200D-2640-FE0F":["woman_standing_tone4","woman_standing_medium_dark_skin_tone"],"1F9CD-1F3FF-200D-2640-FE0F":["woman_standing_tone5","woman_standing_dark_skin_tone"],"1F9CD-200D-2642-FE0F":"man_standing","1F9CD-1F3FB-200D-2642-FE0F":["man_standing_tone1","man_standing_light_skin_tone"],"1F9CD-1F3FC-200D-2642-FE0F":["man_standing_tone2","man_standing_medium_light_skin_tone"],"1F9CD-1F3FD-200D-2642-FE0F":["man_standing_tone3","man_standing_medium_skin_tone"],"1F9CD-1F3FE-200D-2642-FE0F":["man_standing_tone4","man_standing_medium_dark_skin_tone"],"1F9CD-1F3FF-200D-2642-FE0F":["man_standing_tone5","man_standing_dark_skin_tone"],"1F9D1-200D-1F91D-200D-1F9D1":"people_holding_hands","1F9D1-1F3FB-200D-1F91D-200D-1F9D1-1F3FB":["people_holding_hands_tone1","people_holding_hands_light_skin_tone"],"1F9D1-1F3FB-200D-1F91D-200D-1F9D1-1F3FC":["people_holding_hands_tone1_tone2","people_holding_hands_light_skin_tone_medium_light_skin_tone"],"1F9D1-1F3FB-200D-1F91D-200D-1F9D1-1F3FD":["people_holding_hands_tone1_tone3","people_holding_hands_light_skin_tone_medium_skin_tone"],"1F9D1-1F3FB-200D-1F91D-200D-1F9D1-1F3FE":["people_holding_hands_tone1_tone4","people_holding_hands_light_skin_tone_medium_dark_skin_tone"],"1F9D1-1F3FB-200D-1F91D-200D-1F9D1-1F3FF":["people_holding_hands_tone1_tone5","people_holding_hands_light_skin_tone_dark_skin_tone"],"1F9D1-1F3FC-200D-1F91D-200D-1F9D1-1F3FB":["people_holding_hands_tone2_tone1","people_holding_hands_medium_light_skin_tone_light_skin_tone"],"1F9D1-1F3FC-200D-1F91D-200D-1F9D1-1F3FC":["people_holding_hands_tone2","people_holding_hands_medium_light_skin_tone"],"1F9D1-1F3FC-200D-1F91D-200D-1F9D1-1F3FD":["people_holding_hands_tone2_tone3","people_holding_hands_medium_light_skin_tone_medium_skin_tone"],"1F9D1-1F3FC-200D-1F91D-200D-1F9D1-1F3FE":["people_holding_hands_tone2_tone4","people_holding_hands_medium_light_skin_tone_medium_dark_skin_tone"],"1F9D1-1F3FC-200D-1F91D-200D-1F9D1-1F3FF":["people_holding_hands_tone2_tone5","people_holding_hands_medium_light_skin_tone_dark_skin_tone"],"1F9D1-1F3FD-200D-1F91D-200D-1F9D1-1F3FB":["people_holding_hands_tone3_tone1","people_holding_hands_medium_skin_tone_light_skin_tone"],"1F9D1-1F3FD-200D-1F91D-200D-1F9D1-1F3FC":["people_holding_hands_tone3_tone2","people_holding_hands_medium_skin_tone_medium_light_skin_tone"],"1F9D1-1F3FD-200D-1F91D-200D-1F9D1-1F3FD":["people_holding_hands_tone3","people_holding_hands_medium_skin_tone"],"1F9D1-1F3FD-200D-1F91D-200D-1F9D1-1F3FE":["people_holding_hands_tone3_tone4","people_holding_hands_medium_skin_tone_medium_dark_skin_tone"],"1F9D1-1F3FD-200D-1F91D-200D-1F9D1-1F3FF":["people_holding_hands_tone3_tone5","people_holding_hands_medium_skin_tone_dark_skin_tone"],"1F9D1-1F3FE-200D-1F91D-200D-1F9D1-1F3FB":["people_holding_hands_tone4_tone1","people_holding_hands_medium_dark_skin_tone_light_skin_tone"],"1F9D1-1F3FE-200D-1F91D-200D-1F9D1-1F3FC":["people_holding_hands_tone4_tone2","people_holding_hands_medium_dark_skin_tone_medium_light_skin_tone"],"1F9D1-1F3FE-200D-1F91D-200D-1F9D1-1F3FD":["people_holding_hands_tone4_tone3","people_holding_hands_medium_dark_skin_tone_medium_skin_tone"],"1F9D1-1F3FE-200D-1F91D-200D-1F9D1-1F3FE":["people_holding_hands_tone4","people_holding_hands_medium_dark_skin_tone"],"1F9D1-1F3FE-200D-1F91D-200D-1F9D1-1F3FF":["people_holding_hands_tone4_tone5","people_holding_hands_medium_dark_skin_tone_dark_skin_tone"],"1F9D1-1F3FF-200D-1F91D-200D-1F9D1-1F3FB":["people_holding_hands_tone5_tone1","people_holding_hands_dark_skin_tone_light_skin_tone"],"1F9D1-1F3FF-200D-1F91D-200D-1F9D1-1F3FC":["people_holding_hands_tone5_tone2","people_holding_hands_dark_skin_tone_medium_light_skin_tone"],"1F9D1-1F3FF-200D-1F91D-200D-1F9D1-1F3FD":["people_holding_hands_tone5_tone3","people_holding_hands_dark_skin_tone_medium_skin_tone"],"1F9D1-1F3FF-200D-1F91D-200D-1F9D1-1F3FE":["people_holding_hands_tone5_tone4","people_holding_hands_dark_skin_tone_medium_dark_skin_tone"],"1F9D1-1F3FF-200D-1F91D-200D-1F9D1-1F3FF":["people_holding_hands_tone5","people_holding_hands_dark_skin_tone"],"1F46B":"couple","1F46B-1F3FB":["woman_and_man_holding_hands_tone1","woman_and_man_holding_hands_light_skin_tone"],"1F469-1F3FB-200D-1F91D-200D-1F468-1F3FC":["woman_and_man_holding_hands_tone1_tone2","woman_and_man_holding_hands_light_skin_tone_medium_light_skin_tone"],"1F469-1F3FB-200D-1F91D-200D-1F468-1F3FD":["woman_and_man_holding_hands_tone1_tone3","woman_and_man_holding_hands_light_skin_tone_medium_skin_tone"],"1F469-1F3FB-200D-1F91D-200D-1F468-1F3FE":["woman_and_man_holding_hands_tone1_tone4","woman_and_man_holding_hands_light_skin_tone_medium_dark_skin_tone"],"1F469-1F3FB-200D-1F91D-200D-1F468-1F3FF":["woman_and_man_holding_hands_tone1_tone5","woman_and_man_holding_hands_light_skin_tone_dark_skin_tone"],"1F469-1F3FC-200D-1F91D-200D-1F468-1F3FB":["woman_and_man_holding_hands_tone2_tone1","woman_and_man_holding_hands_medium_light_skin_tone_light_skin_tone"],"1F46B-1F3FC":["woman_and_man_holding_hands_tone2","woman_and_man_holding_hands_medium_light_skin_tone"],"1F469-1F3FC-200D-1F91D-200D-1F468-1F3FD":["woman_and_man_holding_hands_tone2_tone3","woman_and_man_holding_hands_medium_light_skin_tone_medium_skin_tone"],"1F469-1F3FC-200D-1F91D-200D-1F468-1F3FE":["woman_and_man_holding_hands_tone2_tone4","woman_and_man_holding_hands_medium_light_skin_tone_medium_dark_skin_tone"],"1F469-1F3FC-200D-1F91D-200D-1F468-1F3FF":["woman_and_man_holding_hands_tone2_tone5","woman_and_man_holding_hands_medium_light_skin_tone_dark_skin_tone"],"1F469-1F3FD-200D-1F91D-200D-1F468-1F3FB":["woman_and_man_holding_hands_tone3_tone1","woman_and_man_holding_hands_medium_skin_tone_light_skin_tone"],"1F469-1F3FD-200D-1F91D-200D-1F468-1F3FC":["woman_and_man_holding_hands_tone3_tone2","woman_and_man_holding_hands_medium_skin_tone_medium_light_skin_tone"],"1F46B-1F3FD":["woman_and_man_holding_hands_tone3","woman_and_man_holding_hands_medium_skin_tone"],"1F469-1F3FD-200D-1F91D-200D-1F468-1F3FE":["woman_and_man_holding_hands_tone3_tone4","woman_and_man_holding_hands_medium_skin_tone_medium_dark_skin_tone"],"1F469-1F3FD-200D-1F91D-200D-1F468-1F3FF":["woman_and_man_holding_hands_tone3_tone5","woman_and_man_holding_hands_medium_skin_tone_dark_skin_tone"],"1F469-1F3FE-200D-1F91D-200D-1F468-1F3FB":["woman_and_man_holding_hands_tone4_tone1","woman_and_man_holding_hands_medium_dark_skin_tone_light_skin_tone"],"1F469-1F3FE-200D-1F91D-200D-1F468-1F3FC":["woman_and_man_holding_hands_tone4_tone2","woman_and_man_holding_hands_medium_dark_skin_tone_medium_light_skin_tone"],"1F469-1F3FE-200D-1F91D-200D-1F468-1F3FD":["woman_and_man_holding_hands_tone4_tone3","woman_and_man_holding_hands_medium_dark_skin_tone_medium_skin_tone"],"1F46B-1F3FE":["woman_and_man_holding_hands_tone4","woman_and_man_holding_hands_medium_dark_skin_tone"],"1F469-1F3FE-200D-1F91D-200D-1F468-1F3FF":["woman_and_man_holding_hands_tone4_tone5","woman_and_man_holding_hands_medium_dark_skin_tone_dark_skin_tone"],"1F469-1F3FF-200D-1F91D-200D-1F468-1F3FB":["woman_and_man_holding_hands_tone5_tone1","woman_and_man_holding_hands_dark_skin_tone_light_skin_tone"],"1F469-1F3FF-200D-1F91D-200D-1F468-1F3FC":["woman_and_man_holding_hands_tone5_tone2","woman_and_man_holding_hands_dark_skin_tone_medium_light_skin_tone"],"1F469-1F3FF-200D-1F91D-200D-1F468-1F3FD":["woman_and_man_holding_hands_tone5_tone3","woman_and_man_holding_hands_dark_skin_tone_medium_skin_tone"],"1F469-1F3FF-200D-1F91D-200D-1F468-1F3FE":["woman_and_man_holding_hands_tone5_tone4","woman_and_man_holding_hands_dark_skin_tone_medium_dark_skin_tone"],"1F46B-1F3FF":["woman_and_man_holding_hands_tone5","woman_and_man_holding_hands_dark_skin_tone"],"1F46D":"two_women_holding_hands","1F46D-1F3FB":["women_holding_hands_tone1","women_holding_hands_light_skin_tone"],"1F469-1F3FB-200D-1F91D-200D-1F469-1F3FC":["women_holding_hands_tone1_tone2","women_holding_hands_light_skin_tone_medium_light_skin_tone"],"1F469-1F3FB-200D-1F91D-200D-1F469-1F3FD":["women_holding_hands_tone1_tone3","women_holding_hands_light_skin_tone_medium_skin_tone"],"1F469-1F3FB-200D-1F91D-200D-1F469-1F3FE":["women_holding_hands_tone1_tone4","women_holding_hands_light_skin_tone_medium_dark_skin_tone"],"1F469-1F3FB-200D-1F91D-200D-1F469-1F3FF":["women_holding_hands_tone1_tone5","women_holding_hands_light_skin_tone_dark_skin_tone"],"1F469-1F3FC-200D-1F91D-200D-1F469-1F3FB":["women_holding_hands_tone2_tone1","women_holding_hands_medium_light_skin_tone_light_skin_tone"],"1F46D-1F3FC":["women_holding_hands_tone2","women_holding_hands_medium_light_skin_tone"],"1F469-1F3FC-200D-1F91D-200D-1F469-1F3FD":["women_holding_hands_tone2_tone3","women_holding_hands_medium_light_skin_tone_medium_skin_tone"],"1F469-1F3FC-200D-1F91D-200D-1F469-1F3FE":["women_holding_hands_tone2_tone4","women_holding_hands_medium_light_skin_tone_medium_dark_skin_tone"],"1F469-1F3FC-200D-1F91D-200D-1F469-1F3FF":["women_holding_hands_tone2_tone5","women_holding_hands_medium_light_skin_tone_dark_skin_tone"],"1F469-1F3FD-200D-1F91D-200D-1F469-1F3FB":["women_holding_hands_tone3_tone1","women_holding_hands_medium_skin_tone_light_skin_tone"],"1F469-1F3FD-200D-1F91D-200D-1F469-1F3FC":["women_holding_hands_tone3_tone2","women_holding_hands_medium_skin_tone_medium_light_skin_tone"],"1F46D-1F3FD":["women_holding_hands_tone3","women_holding_hands_medium_skin_tone"],"1F469-1F3FD-200D-1F91D-200D-1F469-1F3FE":["women_holding_hands_tone3_tone4","women_holding_hands_medium_skin_tone_medium_dark_skin_tone"],"1F469-1F3FD-200D-1F91D-200D-1F469-1F3FF":["women_holding_hands_tone3_tone5","women_holding_hands_medium_skin_tone_dark_skin_tone"],"1F469-1F3FE-200D-1F91D-200D-1F469-1F3FB":["women_holding_hands_tone4_tone1","women_holding_hands_medium_dark_skin_tone_light_skin_tone"],"1F469-1F3FE-200D-1F91D-200D-1F469-1F3FC":["women_holding_hands_tone4_tone2","women_holding_hands_medium_dark_skin_tone_medium_light_skin_tone"],"1F469-1F3FE-200D-1F91D-200D-1F469-1F3FD":["women_holding_hands_tone4_tone3","women_holding_hands_medium_dark_skin_tone_medium_skin_tone"],"1F46D-1F3FE":["women_holding_hands_tone4","women_holding_hands_medium_dark_skin_tone"],"1F469-1F3FE-200D-1F91D-200D-1F469-1F3FF":["women_holding_hands_tone4_tone5","women_holding_hands_medium_dark_skin_tone_dark_skin_tone"],"1F469-1F3FF-200D-1F91D-200D-1F469-1F3FB":["women_holding_hands_tone5_tone1","women_holding_hands_dark_skin_tone_light_skin_tone"],"1F469-1F3FF-200D-1F91D-200D-1F469-1F3FC":["women_holding_hands_tone5_tone2","women_holding_hands_dark_skin_tone_medium_light_skin_tone"],"1F469-1F3FF-200D-1F91D-200D-1F469-1F3FD":["women_holding_hands_tone5_tone3","women_holding_hands_dark_skin_tone_medium_skin_tone"],"1F469-1F3FF-200D-1F91D-200D-1F469-1F3FE":["women_holding_hands_tone5_tone4","women_holding_hands_dark_skin_tone_medium_dark_skin_tone"],"1F46D-1F3FF":["women_holding_hands_tone5","women_holding_hands_dark_skin_tone"],"1F46C":"two_men_holding_hands","1F46C-1F3FB":["men_holding_hands_tone1","men_holding_hands_light_skin_tone"],"1F468-1F3FB-200D-1F91D-200D-1F468-1F3FC":["men_holding_hands_tone1_tone2","men_holding_hands_light_skin_tone_medium_light_skin_tone"],"1F468-1F3FB-200D-1F91D-200D-1F468-1F3FD":["men_holding_hands_tone1_tone3","men_holding_hands_light_skin_tone_medium_skin_tone"],"1F468-1F3FB-200D-1F91D-200D-1F468-1F3FE":["men_holding_hands_tone1_tone4","men_holding_hands_light_skin_tone_medium_dark_skin_tone"],"1F468-1F3FB-200D-1F91D-200D-1F468-1F3FF":["men_holding_hands_tone1_tone5","men_holding_hands_light_skin_tone_dark_skin_tone"],"1F468-1F3FC-200D-1F91D-200D-1F468-1F3FB":["men_holding_hands_tone2_tone1","men_holding_hands_medium_light_skin_tone_light_skin_tone"],"1F46C-1F3FC":["men_holding_hands_tone2","men_holding_hands_medium_light_skin_tone"],"1F468-1F3FC-200D-1F91D-200D-1F468-1F3FD":["men_holding_hands_tone2_tone3","men_holding_hands_medium_light_skin_tone_medium_skin_tone"],"1F468-1F3FC-200D-1F91D-200D-1F468-1F3FE":["men_holding_hands_tone2_tone4","men_holding_hands_medium_light_skin_tone_medium_dark_skin_tone"],"1F468-1F3FC-200D-1F91D-200D-1F468-1F3FF":["men_holding_hands_tone2_tone5","men_holding_hands_medium_light_skin_tone_dark_skin_tone"],"1F468-1F3FD-200D-1F91D-200D-1F468-1F3FB":["men_holding_hands_tone3_tone1","men_holding_hands_medium_skin_tone_light_skin_tone"],"1F468-1F3FD-200D-1F91D-200D-1F468-1F3FC":["men_holding_hands_tone3_tone2","men_holding_hands_medium_skin_tone_medium_light_skin_tone"],"1F46C-1F3FD":["men_holding_hands_tone3","men_holding_hands_medium_skin_tone"],"1F468-1F3FD-200D-1F91D-200D-1F468-1F3FE":["men_holding_hands_tone3_tone4","men_holding_hands_medium_skin_tone_medium_dark_skin_tone"],"1F468-1F3FD-200D-1F91D-200D-1F468-1F3FF":["men_holding_hands_tone3_tone5","men_holding_hands_medium_skin_tone_dark_skin_tone"],"1F468-1F3FE-200D-1F91D-200D-1F468-1F3FB":["men_holding_hands_tone4_tone1","men_holding_hands_medium_dark_skin_tone_light_skin_tone"],"1F468-1F3FE-200D-1F91D-200D-1F468-1F3FC":["men_holding_hands_tone4_tone2","men_holding_hands_medium_dark_skin_tone_medium_light_skin_tone"],"1F468-1F3FE-200D-1F91D-200D-1F468-1F3FD":["men_holding_hands_tone4_tone3","men_holding_hands_medium_dark_skin_tone_medium_skin_tone"],"1F46C-1F3FE":["men_holding_hands_tone4","men_holding_hands_medium_dark_skin_tone"],"1F468-1F3FE-200D-1F91D-200D-1F468-1F3FF":["men_holding_hands_tone4_tone5","men_holding_hands_medium_dark_skin_tone_dark_skin_tone"],"1F468-1F3FF-200D-1F91D-200D-1F468-1F3FB":["men_holding_hands_tone5_tone1","men_holding_hands_dark_skin_tone_light_skin_tone"],"1F468-1F3FF-200D-1F91D-200D-1F468-1F3FC":["men_holding_hands_tone5_tone2","men_holding_hands_dark_skin_tone_medium_light_skin_tone"],"1F468-1F3FF-200D-1F91D-200D-1F468-1F3FD":["men_holding_hands_tone5_tone3","men_holding_hands_dark_skin_tone_medium_skin_tone"],"1F468-1F3FF-200D-1F91D-200D-1F468-1F3FE":["men_holding_hands_tone5_tone4","men_holding_hands_dark_skin_tone_medium_dark_skin_tone"],"1F46C-1F3FF":["men_holding_hands_tone5","men_holding_hands_dark_skin_tone"],"1F491":"couple_with_heart","1F491-1F3FB":["couple_with_heart_tone1","couple_with_heart_light_skin_tone"],"1F9D1-1F3FB-200D-2764-FE0F-200D-1F9D1-1F3FC":["couple_with_heart_person_person_tone1_tone2","couple_with_heart_person_person_light_skin_tone_medium_light_skin_tone"],"1F9D1-1F3FB-200D-2764-FE0F-200D-1F9D1-1F3FD":["couple_with_heart_person_person_tone1_tone3","couple_with_heart_person_person_light_skin_tone_medium_skin_tone"],"1F9D1-1F3FB-200D-2764-FE0F-200D-1F9D1-1F3FE":["couple_with_heart_person_person_tone1_tone4","couple_with_heart_person_person_light_skin_tone_medium_dark_skin_tone"],"1F9D1-1F3FB-200D-2764-FE0F-200D-1F9D1-1F3FF":["couple_with_heart_person_person_tone1_tone5","couple_with_heart_person_person_light_skin_tone_dark_skin_tone"],"1F9D1-1F3FC-200D-2764-FE0F-200D-1F9D1-1F3FB":["couple_with_heart_person_person_tone2_tone1","couple_with_heart_person_person_medium_light_skin_tone_light_skin_tone"],"1F491-1F3FC":["couple_with_heart_tone2","couple_with_heart_medium_light_skin_tone"],"1F9D1-1F3FC-200D-2764-FE0F-200D-1F9D1-1F3FD":["couple_with_heart_person_person_tone2_tone3","couple_with_heart_person_person_medium_light_skin_tone_medium_skin_tone"],"1F9D1-1F3FC-200D-2764-FE0F-200D-1F9D1-1F3FE":["couple_with_heart_person_person_tone2_tone4","couple_with_heart_person_person_medium_light_skin_tone_medium_dark_skin_tone"],"1F9D1-1F3FC-200D-2764-FE0F-200D-1F9D1-1F3FF":["couple_with_heart_person_person_tone2_tone5","couple_with_heart_person_person_medium_light_skin_tone_dark_skin_tone"],"1F9D1-1F3FD-200D-2764-FE0F-200D-1F9D1-1F3FB":["couple_with_heart_person_person_tone3_tone1","couple_with_heart_person_person_medium_skin_tone_light_skin_tone"],"1F9D1-1F3FD-200D-2764-FE0F-200D-1F9D1-1F3FC":["couple_with_heart_person_person_tone3_tone2","couple_with_heart_person_person_medium_skin_tone_medium_light_skin_tone"],"1F491-1F3FD":["couple_with_heart_tone3","couple_with_heart_medium_skin_tone"],"1F9D1-1F3FD-200D-2764-FE0F-200D-1F9D1-1F3FE":["couple_with_heart_person_person_tone3_tone4","couple_with_heart_person_person_medium_skin_tone_medium_dark_skin_tone"],"1F9D1-1F3FD-200D-2764-FE0F-200D-1F9D1-1F3FF":["couple_with_heart_person_person_tone3_tone5","couple_with_heart_person_person_medium_skin_tone_dark_skin_tone"],"1F9D1-1F3FE-200D-2764-FE0F-200D-1F9D1-1F3FB":["couple_with_heart_person_person_tone4_tone1","couple_with_heart_person_person_medium_dark_skin_tone_light_skin_tone"],"1F9D1-1F3FE-200D-2764-FE0F-200D-1F9D1-1F3FC":["couple_with_heart_person_person_tone4_tone2","couple_with_heart_person_person_medium_dark_skin_tone_medium_light_skin_tone"],"1F9D1-1F3FE-200D-2764-FE0F-200D-1F9D1-1F3FD":["couple_with_heart_person_person_tone4_tone3","couple_with_heart_person_person_medium_dark_skin_tone_medium_skin_tone"],"1F491-1F3FE":["couple_with_heart_tone4","couple_with_heart_medium_dark_skin_tone"],"1F9D1-1F3FE-200D-2764-FE0F-200D-1F9D1-1F3FF":["couple_with_heart_person_person_tone4_tone5","couple_with_heart_person_person_medium_dark_skin_tone_dark_skin_tone"],"1F9D1-1F3FF-200D-2764-FE0F-200D-1F9D1-1F3FB":["couple_with_heart_person_person_tone5_tone1","couple_with_heart_person_person_dark_skin_tone_light_skin_tone"],"1F9D1-1F3FF-200D-2764-FE0F-200D-1F9D1-1F3FC":["couple_with_heart_person_person_tone5_tone2","couple_with_heart_person_person_dark_skin_tone_medium_light_skin_tone"],"1F9D1-1F3FF-200D-2764-FE0F-200D-1F9D1-1F3FD":["couple_with_heart_person_person_tone5_tone3","couple_with_heart_person_person_dark_skin_tone_medium_skin_tone"],"1F9D1-1F3FF-200D-2764-FE0F-200D-1F9D1-1F3FE":["couple_with_heart_person_person_tone5_tone4","couple_with_heart_person_person_dark_skin_tone_medium_dark_skin_tone"],"1F491-1F3FF":["couple_with_heart_tone5","couple_with_heart_dark_skin_tone"],"1F469-200D-2764-FE0F-200D-1F468":"couple_with_heart_woman_man","1F469-1F3FB-200D-2764-FE0F-200D-1F468-1F3FB":["couple_with_heart_woman_man_tone1","couple_with_heart_woman_man_light_skin_tone"],"1F469-1F3FB-200D-2764-FE0F-200D-1F468-1F3FC":["couple_with_heart_woman_man_tone1_tone2","couple_with_heart_woman_man_light_skin_tone_medium_light_skin_tone"],"1F469-1F3FB-200D-2764-FE0F-200D-1F468-1F3FD":["couple_with_heart_woman_man_tone1_tone3","couple_with_heart_woman_man_light_skin_tone_medium_skin_tone"],"1F469-1F3FB-200D-2764-FE0F-200D-1F468-1F3FE":["couple_with_heart_woman_man_tone1_tone4","couple_with_heart_woman_man_light_skin_tone_medium_dark_skin_tone"],"1F469-1F3FB-200D-2764-FE0F-200D-1F468-1F3FF":["couple_with_heart_woman_man_tone1_tone5","couple_with_heart_woman_man_light_skin_tone_dark_skin_tone"],"1F469-1F3FC-200D-2764-FE0F-200D-1F468-1F3FB":["couple_with_heart_woman_man_tone2_tone1","couple_with_heart_woman_man_medium_light_skin_tone_light_skin_tone"],"1F469-1F3FC-200D-2764-FE0F-200D-1F468-1F3FC":["couple_with_heart_woman_man_tone2","couple_with_heart_woman_man_medium_light_skin_tone"],"1F469-1F3FC-200D-2764-FE0F-200D-1F468-1F3FD":["couple_with_heart_woman_man_tone2_tone3","couple_with_heart_woman_man_medium_light_skin_tone_medium_skin_tone"],"1F469-1F3FC-200D-2764-FE0F-200D-1F468-1F3FE":["couple_with_heart_woman_man_tone2_tone4","couple_with_heart_woman_man_medium_light_skin_tone_medium_dark_skin_tone"],"1F469-1F3FC-200D-2764-FE0F-200D-1F468-1F3FF":["couple_with_heart_woman_man_tone2_tone5","couple_with_heart_woman_man_medium_light_skin_tone_dark_skin_tone"],"1F469-1F3FD-200D-2764-FE0F-200D-1F468-1F3FB":["couple_with_heart_woman_man_tone3_tone1","couple_with_heart_woman_man_medium_skin_tone_light_skin_tone"],"1F469-1F3FD-200D-2764-FE0F-200D-1F468-1F3FC":["couple_with_heart_woman_man_tone3_tone2","couple_with_heart_woman_man_medium_skin_tone_medium_light_skin_tone"],"1F469-1F3FD-200D-2764-FE0F-200D-1F468-1F3FD":["couple_with_heart_woman_man_tone3","couple_with_heart_woman_man_medium_skin_tone"],"1F469-1F3FD-200D-2764-FE0F-200D-1F468-1F3FE":["couple_with_heart_woman_man_tone3_tone4","couple_with_heart_woman_man_medium_skin_tone_medium_dark_skin_tone"],"1F469-1F3FD-200D-2764-FE0F-200D-1F468-1F3FF":["couple_with_heart_woman_man_tone3_tone5","couple_with_heart_woman_man_medium_skin_tone_dark_skin_tone"],"1F469-1F3FE-200D-2764-FE0F-200D-1F468-1F3FB":["couple_with_heart_woman_man_tone4_tone1","couple_with_heart_woman_man_medium_dark_skin_tone_light_skin_tone"],"1F469-1F3FE-200D-2764-FE0F-200D-1F468-1F3FC":["couple_with_heart_woman_man_tone4_tone2","couple_with_heart_woman_man_medium_dark_skin_tone_medium_light_skin_tone"],"1F469-1F3FE-200D-2764-FE0F-200D-1F468-1F3FD":["couple_with_heart_woman_man_tone4_tone3","couple_with_heart_woman_man_medium_dark_skin_tone_medium_skin_tone"],"1F469-1F3FE-200D-2764-FE0F-200D-1F468-1F3FE":["couple_with_heart_woman_man_tone4","couple_with_heart_woman_man_medium_dark_skin_tone"],"1F469-1F3FE-200D-2764-FE0F-200D-1F468-1F3FF":["couple_with_heart_woman_man_tone4_tone5","couple_with_heart_woman_man_medium_dark_skin_tone_dark_skin_tone"],"1F469-1F3FF-200D-2764-FE0F-200D-1F468-1F3FB":["couple_with_heart_woman_man_tone5_tone1","couple_with_heart_woman_man_dark_skin_tone_light_skin_tone"],"1F469-1F3FF-200D-2764-FE0F-200D-1F468-1F3FC":["couple_with_heart_woman_man_tone5_tone2","couple_with_heart_woman_man_dark_skin_tone_medium_light_skin_tone"],"1F469-1F3FF-200D-2764-FE0F-200D-1F468-1F3FD":["couple_with_heart_woman_man_tone5_tone3","couple_with_heart_woman_man_dark_skin_tone_medium_skin_tone"],"1F469-1F3FF-200D-2764-FE0F-200D-1F468-1F3FE":["couple_with_heart_woman_man_tone5_tone4","couple_with_heart_woman_man_dark_skin_tone_medium_dark_skin_tone"],"1F469-1F3FF-200D-2764-FE0F-200D-1F468-1F3FF":["couple_with_heart_woman_man_tone5","couple_with_heart_woman_man_dark_skin_tone"],"1F469-200D-2764-FE0F-200D-1F469":["couple_ww","couple_with_heart_ww"],"1F469-1F3FB-200D-2764-FE0F-200D-1F469-1F3FB":["couple_with_heart_woman_woman_tone1","couple_with_heart_woman_woman_light_skin_tone"],"1F469-1F3FB-200D-2764-FE0F-200D-1F469-1F3FC":["couple_with_heart_woman_woman_tone1_tone2","couple_with_heart_woman_woman_light_skin_tone_medium_light_skin_tone"],"1F469-1F3FB-200D-2764-FE0F-200D-1F469-1F3FD":["couple_with_heart_woman_woman_tone1_tone3","couple_with_heart_woman_woman_light_skin_tone_medium_skin_tone"],"1F469-1F3FB-200D-2764-FE0F-200D-1F469-1F3FE":["couple_with_heart_woman_woman_tone1_tone4","couple_with_heart_woman_woman_light_skin_tone_medium_dark_skin_tone"],"1F469-1F3FB-200D-2764-FE0F-200D-1F469-1F3FF":["couple_with_heart_woman_woman_tone1_tone5","couple_with_heart_woman_woman_light_skin_tone_dark_skin_tone"],"1F469-1F3FC-200D-2764-FE0F-200D-1F469-1F3FB":["couple_with_heart_woman_woman_tone2_tone1","couple_with_heart_woman_woman_medium_light_skin_tone_light_skin_tone"],"1F469-1F3FC-200D-2764-FE0F-200D-1F469-1F3FC":["couple_with_heart_woman_woman_tone2","couple_with_heart_woman_woman_medium_light_skin_tone"],"1F469-1F3FC-200D-2764-FE0F-200D-1F469-1F3FD":["couple_with_heart_woman_woman_tone2_tone3","couple_with_heart_woman_woman_medium_light_skin_tone_medium_skin_tone"],"1F469-1F3FC-200D-2764-FE0F-200D-1F469-1F3FE":["couple_with_heart_woman_woman_tone2_tone4","couple_with_heart_woman_woman_medium_light_skin_tone_medium_dark_skin_tone"],"1F469-1F3FC-200D-2764-FE0F-200D-1F469-1F3FF":["couple_with_heart_woman_woman_tone2_tone5","couple_with_heart_woman_woman_medium_light_skin_tone_dark_skin_tone"],"1F469-1F3FD-200D-2764-FE0F-200D-1F469-1F3FB":["couple_with_heart_woman_woman_tone3_tone1","couple_with_heart_woman_woman_medium_skin_tone_light_skin_tone"],"1F469-1F3FD-200D-2764-FE0F-200D-1F469-1F3FC":["couple_with_heart_woman_woman_tone3_tone2","couple_with_heart_woman_woman_medium_skin_tone_medium_light_skin_tone"],"1F469-1F3FD-200D-2764-FE0F-200D-1F469-1F3FD":["couple_with_heart_woman_woman_tone3","couple_with_heart_woman_woman_medium_skin_tone"],"1F469-1F3FD-200D-2764-FE0F-200D-1F469-1F3FE":["couple_with_heart_woman_woman_tone3_tone4","couple_with_heart_woman_woman_medium_skin_tone_medium_dark_skin_tone"],"1F469-1F3FD-200D-2764-FE0F-200D-1F469-1F3FF":["couple_with_heart_woman_woman_tone3_tone5","couple_with_heart_woman_woman_medium_skin_tone_dark_skin_tone"],"1F469-1F3FE-200D-2764-FE0F-200D-1F469-1F3FB":["couple_with_heart_woman_woman_tone4_tone1","couple_with_heart_woman_woman_medium_dark_skin_tone_light_skin_tone"],"1F469-1F3FE-200D-2764-FE0F-200D-1F469-1F3FC":["couple_with_heart_woman_woman_tone4_tone2","couple_with_heart_woman_woman_medium_dark_skin_tone_medium_light_skin_tone"],"1F469-1F3FE-200D-2764-FE0F-200D-1F469-1F3FD":["couple_with_heart_woman_woman_tone4_tone3","couple_with_heart_woman_woman_medium_dark_skin_tone_medium_skin_tone"],"1F469-1F3FE-200D-2764-FE0F-200D-1F469-1F3FE":["couple_with_heart_woman_woman_tone4","couple_with_heart_woman_woman_medium_dark_skin_tone"],"1F469-1F3FE-200D-2764-FE0F-200D-1F469-1F3FF":["couple_with_heart_woman_woman_tone4_tone5","couple_with_heart_woman_woman_medium_dark_skin_tone_dark_skin_tone"],"1F469-1F3FF-200D-2764-FE0F-200D-1F469-1F3FB":["couple_with_heart_woman_woman_tone5_tone1","couple_with_heart_woman_woman_dark_skin_tone_light_skin_tone"],"1F469-1F3FF-200D-2764-FE0F-200D-1F469-1F3FC":["couple_with_heart_woman_woman_tone5_tone2","couple_with_heart_woman_woman_dark_skin_tone_medium_light_skin_tone"],"1F469-1F3FF-200D-2764-FE0F-200D-1F469-1F3FD":["couple_with_heart_woman_woman_tone5_tone3","couple_with_heart_woman_woman_dark_skin_tone_medium_skin_tone"],"1F469-1F3FF-200D-2764-FE0F-200D-1F469-1F3FE":["couple_with_heart_woman_woman_tone5_tone4","couple_with_heart_woman_woman_dark_skin_tone_medium_dark_skin_tone"],"1F469-1F3FF-200D-2764-FE0F-200D-1F469-1F3FF":["couple_with_heart_woman_woman_tone5","couple_with_heart_woman_woman_dark_skin_tone"],"1F468-200D-2764-FE0F-200D-1F468":["couple_mm","couple_with_heart_mm"],"1F468-1F3FB-200D-2764-FE0F-200D-1F468-1F3FB":["couple_with_heart_man_man_tone1","couple_with_heart_man_man_light_skin_tone"],"1F468-1F3FB-200D-2764-FE0F-200D-1F468-1F3FC":["couple_with_heart_man_man_tone1_tone2","couple_with_heart_man_man_light_skin_tone_medium_light_skin_tone"],"1F468-1F3FB-200D-2764-FE0F-200D-1F468-1F3FD":["couple_with_heart_man_man_tone1_tone3","couple_with_heart_man_man_light_skin_tone_medium_skin_tone"],"1F468-1F3FB-200D-2764-FE0F-200D-1F468-1F3FE":["couple_with_heart_man_man_tone1_tone4","couple_with_heart_man_man_light_skin_tone_medium_dark_skin_tone"],"1F468-1F3FB-200D-2764-FE0F-200D-1F468-1F3FF":["couple_with_heart_man_man_tone1_tone5","couple_with_heart_man_man_light_skin_tone_dark_skin_tone"],"1F468-1F3FC-200D-2764-FE0F-200D-1F468-1F3FB":["couple_with_heart_man_man_tone2_tone1","couple_with_heart_man_man_medium_light_skin_tone_light_skin_tone"],"1F468-1F3FC-200D-2764-FE0F-200D-1F468-1F3FC":["couple_with_heart_man_man_tone2","couple_with_heart_man_man_medium_light_skin_tone"],"1F468-1F3FC-200D-2764-FE0F-200D-1F468-1F3FD":["couple_with_heart_man_man_tone2_tone3","couple_with_heart_man_man_medium_light_skin_tone_medium_skin_tone"],"1F468-1F3FC-200D-2764-FE0F-200D-1F468-1F3FE":["couple_with_heart_man_man_tone2_tone4","couple_with_heart_man_man_medium_light_skin_tone_medium_dark_skin_tone"],"1F468-1F3FC-200D-2764-FE0F-200D-1F468-1F3FF":["couple_with_heart_man_man_tone2_tone5","couple_with_heart_man_man_medium_light_skin_tone_dark_skin_tone"],"1F468-1F3FD-200D-2764-FE0F-200D-1F468-1F3FB":["couple_with_heart_man_man_tone3_tone1","couple_with_heart_man_man_medium_skin_tone_light_skin_tone"],"1F468-1F3FD-200D-2764-FE0F-200D-1F468-1F3FC":["couple_with_heart_man_man_tone3_tone2","couple_with_heart_man_man_medium_skin_tone_medium_light_skin_tone"],"1F468-1F3FD-200D-2764-FE0F-200D-1F468-1F3FD":["couple_with_heart_man_man_tone3","couple_with_heart_man_man_medium_skin_tone"],"1F468-1F3FD-200D-2764-FE0F-200D-1F468-1F3FE":["couple_with_heart_man_man_tone3_tone4","couple_with_heart_man_man_medium_skin_tone_medium_dark_skin_tone"],"1F468-1F3FD-200D-2764-FE0F-200D-1F468-1F3FF":["couple_with_heart_man_man_tone3_tone5","couple_with_heart_man_man_medium_skin_tone_dark_skin_tone"],"1F468-1F3FE-200D-2764-FE0F-200D-1F468-1F3FB":["couple_with_heart_man_man_tone4_tone1","couple_with_heart_man_man_medium_dark_skin_tone_light_skin_tone"],"1F468-1F3FE-200D-2764-FE0F-200D-1F468-1F3FC":["couple_with_heart_man_man_tone4_tone2","couple_with_heart_man_man_medium_dark_skin_tone_medium_light_skin_tone"],"1F468-1F3FE-200D-2764-FE0F-200D-1F468-1F3FD":["couple_with_heart_man_man_tone4_tone3","couple_with_heart_man_man_medium_dark_skin_tone_medium_skin_tone"],"1F468-1F3FE-200D-2764-FE0F-200D-1F468-1F3FE":["couple_with_heart_man_man_tone4","couple_with_heart_man_man_medium_dark_skin_tone"],"1F468-1F3FE-200D-2764-FE0F-200D-1F468-1F3FF":["couple_with_heart_man_man_tone4_tone5","couple_with_heart_man_man_medium_dark_skin_tone_dark_skin_tone"],"1F468-1F3FF-200D-2764-FE0F-200D-1F468-1F3FB":["couple_with_heart_man_man_tone5_tone1","couple_with_heart_man_man_dark_skin_tone_light_skin_tone"],"1F468-1F3FF-200D-2764-FE0F-200D-1F468-1F3FC":["couple_with_heart_man_man_tone5_tone2","couple_with_heart_man_man_dark_skin_tone_medium_light_skin_tone"],"1F468-1F3FF-200D-2764-FE0F-200D-1F468-1F3FD":["couple_with_heart_man_man_tone5_tone3","couple_with_heart_man_man_dark_skin_tone_medium_skin_tone"],"1F468-1F3FF-200D-2764-FE0F-200D-1F468-1F3FE":["couple_with_heart_man_man_tone5_tone4","couple_with_heart_man_man_dark_skin_tone_medium_dark_skin_tone"],"1F468-1F3FF-200D-2764-FE0F-200D-1F468-1F3FF":["couple_with_heart_man_man_tone5","couple_with_heart_man_man_dark_skin_tone"],"1F48F":"couplekiss","1F48F-1F3FB":["kiss_tone1","kiss_light_skin_tone"],"1F9D1-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FC":["kiss_person_person_tone1_tone2","kiss_person_person_light_skin_tone_medium_light_skin_tone"],"1F9D1-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FD":["kiss_person_person_tone1_tone3","kiss_person_person_light_skin_tone_medium_skin_tone"],"1F9D1-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FE":["kiss_person_person_tone1_tone4","kiss_person_person_light_skin_tone_medium_dark_skin_tone"],"1F9D1-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FF":["kiss_person_person_tone1_tone5","kiss_person_person_light_skin_tone_dark_skin_tone"],"1F9D1-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FB":["kiss_person_person_tone2_tone1","kiss_person_person_medium_light_skin_tone_light_skin_tone"],"1F48F-1F3FC":["kiss_tone2","kiss_medium_light_skin_tone"],"1F9D1-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FD":["kiss_person_person_tone2_tone3","kiss_person_person_medium_light_skin_tone_medium_skin_tone"],"1F9D1-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FE":["kiss_person_person_tone2_tone4","kiss_person_person_medium_light_skin_tone_medium_dark_skin_tone"],"1F9D1-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FF":["kiss_person_person_tone2_tone5","kiss_person_person_medium_light_skin_tone_dark_skin_tone"],"1F9D1-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FB":["kiss_person_person_tone3_tone1","kiss_person_person_medium_skin_tone_light_skin_tone"],"1F9D1-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FC":["kiss_person_person_tone3_tone2","kiss_person_person_medium_skin_tone_medium_light_skin_tone"],"1F48F-1F3FD":["kiss_tone3","kiss_medium_skin_tone"],"1F9D1-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FE":["kiss_person_person_tone3_tone4","kiss_person_person_medium_skin_tone_medium_dark_skin_tone"],"1F9D1-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FF":["kiss_person_person_tone3_tone5","kiss_person_person_medium_skin_tone_dark_skin_tone"],"1F9D1-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FB":["kiss_person_person_tone4_tone1","kiss_person_person_medium_dark_skin_tone_light_skin_tone"],"1F9D1-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FC":["kiss_person_person_tone4_tone2","kiss_person_person_medium_dark_skin_tone_medium_light_skin_tone"],"1F9D1-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FD":["kiss_person_person_tone4_tone3","kiss_person_person_medium_dark_skin_tone_medium_skin_tone"],"1F48F-1F3FE":["kiss_tone4","kiss_medium_dark_skin_tone"],"1F9D1-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FF":["kiss_person_person_tone4_tone5","kiss_person_person_medium_dark_skin_tone_dark_skin_tone"],"1F9D1-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FB":["kiss_person_person_tone5_tone1","kiss_person_person_dark_skin_tone_light_skin_tone"],"1F9D1-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FC":["kiss_person_person_tone5_tone2","kiss_person_person_dark_skin_tone_medium_light_skin_tone"],"1F9D1-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FD":["kiss_person_person_tone5_tone3","kiss_person_person_dark_skin_tone_medium_skin_tone"],"1F48F-1F3FF":["kiss_tone5","kiss_dark_skin_tone"],"1F469-200D-2764-FE0F-200D-1F48B-200D-1F468":"kiss_woman_man","1F469-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FB":["kiss_woman_man_tone1","kiss_woman_man_light_skin_tone"],"1F469-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FC":["kiss_woman_man_tone1_tone2","kiss_woman_man_light_skin_tone_medium_light_skin_tone"],"1F469-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FD":["kiss_woman_man_tone1_tone3","kiss_woman_man_light_skin_tone_medium_skin_tone"],"1F469-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FE":["kiss_woman_man_tone1_tone4","kiss_woman_man_light_skin_tone_medium_dark_skin_tone"],"1F469-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FF":["kiss_woman_man_tone1_tone5","kiss_woman_man_light_skin_tone_dark_skin_tone"],"1F469-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FB":["kiss_woman_man_tone2_tone1","kiss_woman_man_medium_light_skin_tone_light_skin_tone"],"1F469-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FC":["kiss_woman_man_tone2","kiss_woman_man_medium_light_skin_tone"],"1F469-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FD":["kiss_woman_man_tone2_tone3","kiss_woman_man_medium_light_skin_tone_medium_skin_tone"],"1F469-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FE":["kiss_woman_man_tone2_tone4","kiss_woman_man_medium_light_skin_tone_medium_dark_skin_tone"],"1F469-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FF":["kiss_woman_man_tone2_tone5","kiss_woman_man_medium_light_skin_tone_dark_skin_tone"],"1F469-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FB":["kiss_woman_man_tone3_tone1","kiss_woman_man_medium_skin_tone_light_skin_tone"],"1F469-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FC":["kiss_woman_man_tone3_tone2","kiss_woman_man_medium_skin_tone_medium_light_skin_tone"],"1F469-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FD":["kiss_woman_man_tone3","kiss_woman_man_medium_skin_tone"],"1F469-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FE":["kiss_woman_man_tone3_tone4","kiss_woman_man_medium_skin_tone_medium_dark_skin_tone"],"1F469-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FF":["kiss_woman_man_tone3_tone5","kiss_woman_man_medium_skin_tone_dark_skin_tone"],"1F469-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FB":["kiss_woman_man_tone4_tone1","kiss_woman_man_medium_dark_skin_tone_light_skin_tone"],"1F469-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FC":["kiss_woman_man_tone4_tone2","kiss_woman_man_medium_dark_skin_tone_medium_light_skin_tone"],"1F469-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FD":["kiss_woman_man_tone4_tone3","kiss_woman_man_medium_dark_skin_tone_medium_skin_tone"],"1F469-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FE":["kiss_woman_man_tone4","kiss_woman_man_medium_dark_skin_tone"],"1F469-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FF":["kiss_woman_man_tone4_tone5","kiss_woman_man_medium_dark_skin_tone_dark_skin_tone"],"1F469-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FB":["kiss_woman_man_tone5_tone1","kiss_woman_man_dark_skin_tone_light_skin_tone"],"1F469-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FC":["kiss_woman_man_tone5_tone2","kiss_woman_man_dark_skin_tone_medium_light_skin_tone"],"1F469-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FD":["kiss_woman_man_tone5_tone3","kiss_woman_man_dark_skin_tone_medium_skin_tone"],"1F469-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FE":["kiss_woman_man_tone5_tone4","kiss_woman_man_dark_skin_tone_medium_dark_skin_tone"],"1F469-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FF":["kiss_woman_man_tone5","kiss_woman_man_dark_skin_tone"],"1F469-200D-2764-FE0F-200D-1F48B-200D-1F469":["kiss_ww","couplekiss_ww"],"1F469-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FB":["kiss_woman_woman_tone1","kiss_woman_woman_light_skin_tone"],"1F469-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FC":["kiss_woman_woman_tone1_tone2","kiss_woman_woman_light_skin_tone_medium_light_skin_tone"],"1F469-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FD":["kiss_woman_woman_tone1_tone3","kiss_woman_woman_light_skin_tone_medium_skin_tone"],"1F469-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FE":["kiss_woman_woman_tone1_tone4","kiss_woman_woman_light_skin_tone_medium_dark_skin_tone"],"1F469-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FF":["kiss_woman_woman_tone1_tone5","kiss_woman_woman_light_skin_tone_dark_skin_tone"],"1F469-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FB":["kiss_woman_woman_tone2_tone1","kiss_woman_woman_medium_light_skin_tone_light_skin_tone"],"1F469-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FC":["kiss_woman_woman_tone2","kiss_woman_woman_medium_light_skin_tone"],"1F469-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FD":["kiss_woman_woman_tone2_tone3","kiss_woman_woman_medium_light_skin_tone_medium_skin_tone"],"1F469-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FE":["kiss_woman_woman_tone2_tone4","kiss_woman_woman_medium_light_skin_tone_medium_dark_skin_tone"],"1F469-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FF":["kiss_woman_woman_tone2_tone5","kiss_woman_woman_medium_light_skin_tone_dark_skin_tone"],"1F469-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FB":["kiss_woman_woman_tone3_tone1","kiss_woman_woman_medium_skin_tone_light_skin_tone"],"1F469-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FC":["kiss_woman_woman_tone3_tone2","kiss_woman_woman_medium_skin_tone_medium_light_skin_tone"],"1F469-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FD":["kiss_woman_woman_tone3","kiss_woman_woman_medium_skin_tone"],"1F469-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FE":["kiss_woman_woman_tone3_tone4","kiss_woman_woman_medium_skin_tone_medium_dark_skin_tone"],"1F469-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FF":["kiss_woman_woman_tone3_tone5","kiss_woman_woman_medium_skin_tone_dark_skin_tone"],"1F469-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FB":["kiss_woman_woman_tone4_tone1","kiss_woman_woman_medium_dark_skin_tone_light_skin_tone"],"1F469-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FC":["kiss_woman_woman_tone4_tone2","kiss_woman_woman_medium_dark_skin_tone_medium_light_skin_tone"],"1F469-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FD":["kiss_woman_woman_tone4_tone3","kiss_woman_woman_medium_dark_skin_tone_medium_skin_tone"],"1F469-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FE":["kiss_woman_woman_tone4","kiss_woman_woman_medium_dark_skin_tone"],"1F469-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FF":["kiss_woman_woman_tone4_tone5","kiss_woman_woman_medium_dark_skin_tone_dark_skin_tone"],"1F469-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FB":["kiss_woman_woman_tone5_tone1","kiss_woman_woman_dark_skin_tone_light_skin_tone"],"1F469-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FC":["kiss_woman_woman_tone5_tone2","kiss_woman_woman_dark_skin_tone_medium_light_skin_tone"],"1F469-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FD":["kiss_woman_woman_tone5_tone3","kiss_woman_woman_dark_skin_tone_medium_skin_tone"],"1F469-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FE":["kiss_woman_woman_tone5_tone4","kiss_woman_woman_dark_skin_tone_medium_dark_skin_tone"],"1F469-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FF":["kiss_woman_woman_tone5","kiss_woman_woman_dark_skin_tone"],"1F468-200D-2764-FE0F-200D-1F48B-200D-1F468":["kiss_mm","couplekiss_mm"],"1F468-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FB":["kiss_man_man_tone1","kiss_man_man_light_skin_tone"],"1F468-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FC":["kiss_man_man_tone1_tone2","kiss_man_man_light_skin_tone_medium_light_skin_tone"],"1F468-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FD":["kiss_man_man_tone1_tone3","kiss_man_man_light_skin_tone_medium_skin_tone"],"1F468-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FE":["kiss_man_man_tone1_tone4","kiss_man_man_light_skin_tone_medium_dark_skin_tone"],"1F468-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FF":["kiss_man_man_tone1_tone5","kiss_man_man_light_skin_tone_dark_skin_tone"],"1F468-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FB":["kiss_man_man_tone2_tone1","kiss_man_man_medium_light_skin_tone_light_skin_tone"],"1F468-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FC":["kiss_man_man_tone2","kiss_man_man_medium_light_skin_tone"],"1F468-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FD":["kiss_man_man_tone2_tone3","kiss_man_man_medium_light_skin_tone_medium_skin_tone"],"1F468-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FE":["kiss_man_man_tone2_tone4","kiss_man_man_medium_light_skin_tone_medium_dark_skin_tone"],"1F468-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FF":["kiss_man_man_tone2_tone5","kiss_man_man_medium_light_skin_tone_dark_skin_tone"],"1F468-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FB":["kiss_man_man_tone3_tone1","kiss_man_man_medium_skin_tone_light_skin_tone"],"1F468-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FC":["kiss_man_man_tone3_tone2","kiss_man_man_medium_skin_tone_medium_light_skin_tone"],"1F468-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FD":["kiss_man_man_tone3","kiss_man_man_medium_skin_tone"],"1F468-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FE":["kiss_man_man_tone3_tone4","kiss_man_man_medium_skin_tone_medium_dark_skin_tone"],"1F468-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FF":["kiss_man_man_tone3_tone5","kiss_man_man_medium_skin_tone_dark_skin_tone"],"1F468-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FB":["kiss_man_man_tone4_tone1","kiss_man_man_medium_dark_skin_tone_light_skin_tone"],"1F468-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FC":["kiss_man_man_tone4_tone2","kiss_man_man_medium_dark_skin_tone_medium_light_skin_tone"],"1F468-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FD":["kiss_man_man_tone4_tone3","kiss_man_man_medium_dark_skin_tone_medium_skin_tone"],"1F468-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FE":["kiss_man_man_tone4","kiss_man_man_medium_dark_skin_tone"],"1F468-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FF":["kiss_man_man_tone4_tone5","kiss_man_man_medium_dark_skin_tone_dark_skin_tone"],"1F468-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FB":["kiss_man_man_tone5_tone1","kiss_man_man_dark_skin_tone_light_skin_tone"],"1F468-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FC":["kiss_man_man_tone5_tone2","kiss_man_man_dark_skin_tone_medium_light_skin_tone"],"1F468-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FD":["kiss_man_man_tone5_tone3","kiss_man_man_dark_skin_tone_medium_skin_tone"],"1F468-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FE":["kiss_man_man_tone5_tone4","kiss_man_man_dark_skin_tone_medium_dark_skin_tone"],"1F468-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FF":["kiss_man_man_tone5","kiss_man_man_dark_skin_tone"],"1F46A":"family","1F468-200D-1F469-200D-1F466":"family_man_woman_boy","1F468-200D-1F469-200D-1F467":"family_mwg","1F468-200D-1F469-200D-1F467-200D-1F466":"family_mwgb","1F468-200D-1F469-200D-1F466-200D-1F466":"family_mwbb","1F468-200D-1F469-200D-1F467-200D-1F467":"family_mwgg","1F469-200D-1F469-200D-1F466":"family_wwb","1F469-200D-1F469-200D-1F467":"family_wwg","1F469-200D-1F469-200D-1F467-200D-1F466":"family_wwgb","1F469-200D-1F469-200D-1F466-200D-1F466":"family_wwbb","1F469-200D-1F469-200D-1F467-200D-1F467":"family_wwgg","1F468-200D-1F468-200D-1F466":"family_mmb","1F468-200D-1F468-200D-1F467":"family_mmg","1F468-200D-1F468-200D-1F467-200D-1F466":"family_mmgb","1F468-200D-1F468-200D-1F466-200D-1F466":"family_mmbb","1F468-200D-1F468-200D-1F467-200D-1F467":"family_mmgg","1F469-200D-1F466":"family_woman_boy","1F469-200D-1F467":"family_woman_girl","1F469-200D-1F467-200D-1F466":"family_woman_girl_boy","1F469-200D-1F466-200D-1F466":"family_woman_boy_boy","1F469-200D-1F467-200D-1F467":"family_woman_girl_girl","1F468-200D-1F466":"family_man_boy","1F468-200D-1F467":"family_man_girl","1F468-200D-1F467-200D-1F466":"family_man_girl_boy","1F468-200D-1F466-200D-1F466":"family_man_boy_boy","1F468-200D-1F467-200D-1F467":"family_man_girl_girl","1F9F6":"yarn","1F9F5":"thread","1F9E5":"coat","1F97C":"lab_coat","1F9BA":"safety_vest","1F45A":"womans_clothes","1F455":"shirt","1F456":"jeans","1FA72":"briefs","1FA73":"shorts","1F454":"necktie","1F457":"dress","1F459":"bikini","1FA71":"one_piece_swimsuit","1F458":"kimono","1F97B":"sari","1F97F":"womans_flat_shoe","1F460":"high_heel","1F461":"sandal","1F462":"boot","1F45E":"mans_shoe","1F45F":"athletic_shoe","1F97E":"hiking_boot","1FA74":"thong_sandal","1F9E6":"socks","1F9E4":"gloves","1F9E3":"scarf","1F3A9":"tophat","1F9E2":"billed_cap","1F452":"womans_hat","1F393":"mortar_board","26D1":["helmet_with_cross","helmet_with_white_cross"],"1FA96":"military_helmet","1F451":"crown","1F48D":"ring","1F45D":"pouch","1F45B":"purse","1F45C":"handbag","1F4BC":"briefcase","1F392":"school_satchel","1F9F3":"luggage","1F453":"eyeglasses","1F576":"dark_sunglasses","1F97D":"goggles","1F302":"closed_umbrella","1F9B1":"curly_haired","1F9B0":"red_haired","1F9B3":"white_haired","1F9B2":"bald","1F436":"dog","1F431":"cat","1F42D":"mouse","1F439":"hamster","1F430":"rabbit","1F98A":["fox","fox_face"],"1F43B":"bear","1F43C":"panda_face","1F43B-200D-2744-FE0F":"polar_bear","1F428":"koala","1F42F":"tiger","1F981":["lion_face","lion"],"1F42E":"cow","1F437":"pig","1F43D":"pig_nose","1F438":"frog","1F435":"monkey_face","1F648":"see_no_evil","1F649":"hear_no_evil","1F64A":"speak_no_evil","1F412":"monkey","1F414":"chicken","1F427":"penguin","1F426":"bird","1F424":"baby_chick","1F423":"hatching_chick","1F425":"hatched_chick","1F986":"duck","1F9A4":"dodo","1F985":"eagle","1F989":"owl","1F987":"bat","1F43A":"wolf","1F417":"boar","1F434":"horse","1F984":["unicorn","unicorn_face"],"1F41D":"bee","1F41B":"bug","1F98B":"butterfly","1F40C":"snail","1FAB1":"worm","1F41E":"lady_beetle","1F41C":"ant","1FAB0":"fly","1F99F":"mosquito","1FAB3":"cockroach","1FAB2":"beetle","1F997":"cricket","1F577":"spider","1F578":"spider_web","1F982":"scorpion","1F422":"turtle","1F40D":"snake","1F98E":"lizard","1F996":"t_rex","1F995":"sauropod","1F419":"octopus","1F991":"squid","1F990":"shrimp","1F99E":"lobster","1F980":"crab","1F421":"blowfish","1F420":"tropical_fish","1F41F":"fish","1F9AD":"seal","1F42C":"dolphin","1F433":"whale","1F40B":"whale2","1F988":"shark","1F40A":"crocodile","1F405":"tiger2","1F406":"leopard","1F993":"zebra","1F98D":"gorilla","1F9A7":"orangutan","1F418":"elephant","1F9A3":"mammoth","1F9AC":"bison","1F99B":"hippopotamus","1F98F":["rhino","rhinoceros"],"1F42A":"dromedary_camel","1F42B":"camel","1F992":"giraffe","1F998":"kangaroo","1F403":"water_buffalo","1F402":"ox","1F404":"cow2","1F40E":"racehorse","1F416":"pig2","1F40F":"ram","1F411":"sheep","1F999":"llama","1F410":"goat","1F98C":"deer","1F415":"dog2","1F429":"poodle","1F9AE":"guide_dog","1F415-200D-1F9BA":"service_dog","1F408":"cat2","1F408-200D-2B1B":"black_cat","1F413":"rooster","1F983":"turkey","1F99A":"peacock","1F99C":"parrot","1F9A2":"swan","1F9A9":"flamingo","1F54A":["dove","dove_of_peace"],"1F407":"rabbit2","1F99D":"raccoon","1F9A8":"skunk","1F9A1":"badger","1F9AB":"beaver","1F9A6":"otter","1F9A5":"sloth","1F401":"mouse2","1F400":"rat","1F43F":"chipmunk","1F994":"hedgehog","1F43E":["feet","paw_prints"],"1F409":"dragon","1F432":"dragon_face","1F335":"cactus","1F384":"christmas_tree","1F332":"evergreen_tree","1F333":"deciduous_tree","1F334":"palm_tree","1F331":"seedling","1F33F":"herb","1F340":"four_leaf_clover","1F38D":"bamboo","1F38B":"tanabata_tree","1F343":"leaves","1F342":"fallen_leaf","1F341":"maple_leaf","1FAB6":"feather","1F344":"mushroom","1F41A":"shell","1FAA8":"rock","1FAB5":"wood","1F33E":"ear_of_rice","1FAB4":"potted_plant","1F490":"bouquet","1F337":"tulip","1F339":"rose","1F940":["wilted_rose","wilted_flower"],"1F33A":"hibiscus","1F338":"cherry_blossom","1F33C":"blossom","1F33B":"sunflower","1F31E":"sun_with_face","1F31D":"full_moon_with_face","1F31B":"first_quarter_moon_with_face","1F31C":"last_quarter_moon_with_face","1F31A":"new_moon_with_face","1F315":"full_moon","1F316":"waning_gibbous_moon","1F317":"last_quarter_moon","1F318":"waning_crescent_moon","1F311":"new_moon","1F312":"waxing_crescent_moon","1F313":"first_quarter_moon","1F314":"waxing_gibbous_moon","1F319":"crescent_moon","1F30E":"earth_americas","1F30D":"earth_africa","1F30F":"earth_asia","1FA90":"ringed_planet","1F4AB":"dizzy","2B50":"star","1F31F":"star2","26A1":"zap","1F4A5":"boom","1F525":["fire","flame"],"1F32A":["cloud_tornado","cloud_with_tornado"],"1F308":"rainbow","1F324":["white_sun_small_cloud","white_sun_with_small_cloud"],"26C5":"partly_sunny","1F325":["white_sun_cloud","white_sun_behind_cloud"],"1F326":["white_sun_rain_cloud","white_sun_behind_cloud_with_rain"],"1F327":["cloud_rain","cloud_with_rain"],"26C8":["thunder_cloud_rain","thunder_cloud_and_rain"],"1F329":["cloud_lightning","cloud_with_lightning"],"1F328":["cloud_snow","cloud_with_snow"],"26C4":"snowman","1F32C":"wind_blowing_face","1F4A8":"dash","1F4A7":"droplet","1F4A6":"sweat_drops","1F30A":"ocean","1F32B":"fog","1F34F":"green_apple","1F34E":"apple","1F350":"pear","1F34A":"tangerine","1F34B":"lemon","1F34C":"banana","1F349":"watermelon","1F347":"grapes","1FAD0":"blueberries","1F353":"strawberry","1F348":"melon","1F352":"cherries","1F351":"peach","1F96D":"mango","1F34D":"pineapple","1F965":"coconut","1F95D":["kiwi","kiwifruit"],"1F345":"tomato","1F346":"eggplant","1F951":"avocado","1FAD2":"olive","1F966":"broccoli","1F96C":"leafy_green","1FAD1":"bell_pepper","1F952":"cucumber","1F336":"hot_pepper","1F33D":"corn","1F955":"carrot","1F9C4":"garlic","1F9C5":"onion","1F954":"potato","1F360":"sweet_potato","1F950":"croissant","1F96F":"bagel","1F35E":"bread","1F956":["french_bread","baguette_bread"],"1FAD3":"flatbread","1F968":"pretzel","1F9C0":["cheese","cheese_wedge"],"1F95A":"egg","1F373":"cooking","1F9C8":"butter","1F95E":"pancakes","1F9C7":"waffle","1F953":"bacon","1F969":"cut_of_meat","1F357":"poultry_leg","1F356":"meat_on_bone","1F32D":["hotdog","hot_dog"],"1F354":"hamburger","1F35F":"fries","1F355":"pizza","1F96A":"sandwich","1F959":["stuffed_flatbread","stuffed_pita"],"1F9C6":"falafel","1F32E":"taco","1F32F":"burrito","1FAD4":"tamale","1F957":["salad","green_salad"],"1F958":["shallow_pan_of_food","paella"],"1FAD5":"fondue","1F96B":"canned_food","1F35D":"spaghetti","1F35C":"ramen","1F372":"stew","1F35B":"curry","1F363":"sushi","1F371":"bento","1F95F":"dumpling","1F9AA":"oyster","1F364":"fried_shrimp","1F359":"rice_ball","1F35A":"rice","1F358":"rice_cracker","1F365":"fish_cake","1F960":"fortune_cookie","1F96E":"moon_cake","1F362":"oden","1F361":"dango","1F367":"shaved_ice","1F368":"ice_cream","1F366":"icecream","1F967":"pie","1F9C1":"cupcake","1F370":"cake","1F382":"birthday","1F36E":["custard","pudding","flan"],"1F36D":"lollipop","1F36C":"candy","1F36B":"chocolate_bar","1F37F":"popcorn","1F369":"doughnut","1F36A":"cookie","1F330":"chestnut","1F95C":["peanuts","shelled_peanut"],"1F36F":"honey_pot","1F95B":["milk","glass_of_milk"],"1F37C":"baby_bottle","1F375":"tea","1FAD6":"teapot","1F9C9":"mate","1F9CB":"bubble_tea","1F9C3":"beverage_box","1F964":"cup_with_straw","1F376":"sake","1F37A":"beer","1F37B":"beers","1F942":["champagne_glass","clinking_glass"],"1F377":"wine_glass","1F943":["tumbler_glass","whisky"],"1F378":"cocktail","1F379":"tropical_drink","1F37E":["champagne","bottle_with_popping_cork"],"1F9CA":"ice_cube","1F944":"spoon","1F374":"fork_and_knife","1F37D":["fork_knife_plate","fork_and_knife_with_plate"],"1F963":"bowl_with_spoon","1F961":"takeout_box","1F962":"chopsticks","1F9C2":"salt","26BD":"soccer","1F3C0":"basketball","1F3C8":"football","26BE":"baseball","1F94E":"softball","1F3BE":"tennis","1F3D0":"volleyball","1F3C9":"rugby_football","1F94F":"flying_disc","1FA83":"boomerang","1F3B1":"8ball","1FA80":"yo_yo","1F3D3":["ping_pong","table_tennis"],"1F3F8":"badminton","1F3D2":"hockey","1F3D1":"field_hockey","1F94D":"lacrosse","1F3CF":["cricket_game","cricket_bat_ball"],"1F945":["goal","goal_net"],"26F3":"golf","1FA81":"kite","1F3F9":["bow_and_arrow","archery"],"1F3A3":"fishing_pole_and_fish","1F93F":"diving_mask","1F94A":["boxing_glove","boxing_gloves"],"1F94B":["martial_arts_uniform","karate_uniform"],"1F3BD":"running_shirt_with_sash","1F6F9":"skateboard","1F6FC":"roller_skate","1F6F7":"sled","26F8":"ice_skate","1F94C":"curling_stone","1F3BF":"ski","26F7":"skier","1F3C2":"snowboarder","1F3C2-1F3FB":["snowboarder_tone1","snowboarder_light_skin_tone"],"1F3C2-1F3FC":["snowboarder_tone2","snowboarder_medium_light_skin_tone"],"1F3C2-1F3FD":["snowboarder_tone3","snowboarder_medium_skin_tone"],"1F3C2-1F3FE":["snowboarder_tone4","snowboarder_medium_dark_skin_tone"],"1F3C2-1F3FF":["snowboarder_tone5","snowboarder_dark_skin_tone"],"1FA82":"parachute","1F3CB":["person_lifting_weights","lifter","weight_lifter"],"1F3CB-1F3FB":["person_lifting_weights_tone1","lifter_tone1","weight_lifter_tone1"],"1F3CB-1F3FC":["person_lifting_weights_tone2","lifter_tone2","weight_lifter_tone2"],"1F3CB-1F3FD":["person_lifting_weights_tone3","lifter_tone3","weight_lifter_tone3"],"1F3CB-1F3FE":["person_lifting_weights_tone4","lifter_tone4","weight_lifter_tone4"],"1F3CB-1F3FF":["person_lifting_weights_tone5","lifter_tone5","weight_lifter_tone5"],"1F3CB-FE0F-200D-2640-FE0F":"woman_lifting_weights","1F3CB-1F3FB-200D-2640-FE0F":["woman_lifting_weights_tone1","woman_lifting_weights_light_skin_tone"],"1F3CB-1F3FC-200D-2640-FE0F":["woman_lifting_weights_tone2","woman_lifting_weights_medium_light_skin_tone"],"1F3CB-1F3FD-200D-2640-FE0F":["woman_lifting_weights_tone3","woman_lifting_weights_medium_skin_tone"],"1F3CB-1F3FE-200D-2640-FE0F":["woman_lifting_weights_tone4","woman_lifting_weights_medium_dark_skin_tone"],"1F3CB-1F3FF-200D-2640-FE0F":["woman_lifting_weights_tone5","woman_lifting_weights_dark_skin_tone"],"1F3CB-FE0F-200D-2642-FE0F":"man_lifting_weights","1F3CB-1F3FB-200D-2642-FE0F":["man_lifting_weights_tone1","man_lifting_weights_light_skin_tone"],"1F3CB-1F3FC-200D-2642-FE0F":["man_lifting_weights_tone2","man_lifting_weights_medium_light_skin_tone"],"1F3CB-1F3FD-200D-2642-FE0F":["man_lifting_weights_tone3","man_lifting_weights_medium_skin_tone"],"1F3CB-1F3FE-200D-2642-FE0F":["man_lifting_weights_tone4","man_lifting_weights_medium_dark_skin_tone"],"1F3CB-1F3FF-200D-2642-FE0F":["man_lifting_weights_tone5","man_lifting_weights_dark_skin_tone"],"1F93C":["people_wrestling","wrestlers","wrestling"],"1F93C-200D-2640-FE0F":"women_wrestling","1F93C-200D-2642-FE0F":"men_wrestling","1F938":["person_doing_cartwheel","cartwheel"],"1F938-1F3FB":["person_doing_cartwheel_tone1","cartwheel_tone1"],"1F938-1F3FC":["person_doing_cartwheel_tone2","cartwheel_tone2"],"1F938-1F3FD":["person_doing_cartwheel_tone3","cartwheel_tone3"],"1F938-1F3FE":["person_doing_cartwheel_tone4","cartwheel_tone4"],"1F938-1F3FF":["person_doing_cartwheel_tone5","cartwheel_tone5"],"1F938-200D-2640-FE0F":"woman_cartwheeling","1F938-1F3FB-200D-2640-FE0F":["woman_cartwheeling_tone1","woman_cartwheeling_light_skin_tone"],"1F938-1F3FC-200D-2640-FE0F":["woman_cartwheeling_tone2","woman_cartwheeling_medium_light_skin_tone"],"1F938-1F3FD-200D-2640-FE0F":["woman_cartwheeling_tone3","woman_cartwheeling_medium_skin_tone"],"1F938-1F3FE-200D-2640-FE0F":["woman_cartwheeling_tone4","woman_cartwheeling_medium_dark_skin_tone"],"1F938-1F3FF-200D-2640-FE0F":["woman_cartwheeling_tone5","woman_cartwheeling_dark_skin_tone"],"1F938-200D-2642-FE0F":"man_cartwheeling","1F938-1F3FB-200D-2642-FE0F":["man_cartwheeling_tone1","man_cartwheeling_light_skin_tone"],"1F938-1F3FC-200D-2642-FE0F":["man_cartwheeling_tone2","man_cartwheeling_medium_light_skin_tone"],"1F938-1F3FD-200D-2642-FE0F":["man_cartwheeling_tone3","man_cartwheeling_medium_skin_tone"],"1F938-1F3FE-200D-2642-FE0F":["man_cartwheeling_tone4","man_cartwheeling_medium_dark_skin_tone"],"1F938-1F3FF-200D-2642-FE0F":["man_cartwheeling_tone5","man_cartwheeling_dark_skin_tone"],"26F9":["person_bouncing_ball","basketball_player","person_with_ball"],"26F9-1F3FB":["person_bouncing_ball_tone1","basketball_player_tone1","person_with_ball_tone1"],"26F9-1F3FC":["person_bouncing_ball_tone2","basketball_player_tone2","person_with_ball_tone2"],"26F9-1F3FD":["person_bouncing_ball_tone3","basketball_player_tone3","person_with_ball_tone3"],"26F9-1F3FE":["person_bouncing_ball_tone4","basketball_player_tone4","person_with_ball_tone4"],"26F9-1F3FF":["person_bouncing_ball_tone5","basketball_player_tone5","person_with_ball_tone5"],"26F9-FE0F-200D-2640-FE0F":"woman_bouncing_ball","26F9-1F3FB-200D-2640-FE0F":["woman_bouncing_ball_tone1","woman_bouncing_ball_light_skin_tone"],"26F9-1F3FC-200D-2640-FE0F":["woman_bouncing_ball_tone2","woman_bouncing_ball_medium_light_skin_tone"],"26F9-1F3FD-200D-2640-FE0F":["woman_bouncing_ball_tone3","woman_bouncing_ball_medium_skin_tone"],"26F9-1F3FE-200D-2640-FE0F":["woman_bouncing_ball_tone4","woman_bouncing_ball_medium_dark_skin_tone"],"26F9-1F3FF-200D-2640-FE0F":["woman_bouncing_ball_tone5","woman_bouncing_ball_dark_skin_tone"],"26F9-FE0F-200D-2642-FE0F":"man_bouncing_ball","26F9-1F3FB-200D-2642-FE0F":["man_bouncing_ball_tone1","man_bouncing_ball_light_skin_tone"],"26F9-1F3FC-200D-2642-FE0F":["man_bouncing_ball_tone2","man_bouncing_ball_medium_light_skin_tone"],"26F9-1F3FD-200D-2642-FE0F":["man_bouncing_ball_tone3","man_bouncing_ball_medium_skin_tone"],"26F9-1F3FE-200D-2642-FE0F":["man_bouncing_ball_tone4","man_bouncing_ball_medium_dark_skin_tone"],"26F9-1F3FF-200D-2642-FE0F":["man_bouncing_ball_tone5","man_bouncing_ball_dark_skin_tone"],"1F93A":["person_fencing","fencer","fencing"],"1F93E":["person_playing_handball","handball"],"1F93E-1F3FB":["person_playing_handball_tone1","handball_tone1"],"1F93E-1F3FC":["person_playing_handball_tone2","handball_tone2"],"1F93E-1F3FD":["person_playing_handball_tone3","handball_tone3"],"1F93E-1F3FE":["person_playing_handball_tone4","handball_tone4"],"1F93E-1F3FF":["person_playing_handball_tone5","handball_tone5"],"1F93E-200D-2640-FE0F":"woman_playing_handball","1F93E-1F3FB-200D-2640-FE0F":["woman_playing_handball_tone1","woman_playing_handball_light_skin_tone"],"1F93E-1F3FC-200D-2640-FE0F":["woman_playing_handball_tone2","woman_playing_handball_medium_light_skin_tone"],"1F93E-1F3FD-200D-2640-FE0F":["woman_playing_handball_tone3","woman_playing_handball_medium_skin_tone"],"1F93E-1F3FE-200D-2640-FE0F":["woman_playing_handball_tone4","woman_playing_handball_medium_dark_skin_tone"],"1F93E-1F3FF-200D-2640-FE0F":["woman_playing_handball_tone5","woman_playing_handball_dark_skin_tone"],"1F93E-200D-2642-FE0F":"man_playing_handball","1F93E-1F3FB-200D-2642-FE0F":["man_playing_handball_tone1","man_playing_handball_light_skin_tone"],"1F93E-1F3FC-200D-2642-FE0F":["man_playing_handball_tone2","man_playing_handball_medium_light_skin_tone"],"1F93E-1F3FD-200D-2642-FE0F":["man_playing_handball_tone3","man_playing_handball_medium_skin_tone"],"1F93E-1F3FE-200D-2642-FE0F":["man_playing_handball_tone4","man_playing_handball_medium_dark_skin_tone"],"1F93E-1F3FF-200D-2642-FE0F":["man_playing_handball_tone5","man_playing_handball_dark_skin_tone"],"1F3CC":["person_golfing","golfer"],"1F3CC-1F3FB":["person_golfing_tone1","person_golfing_light_skin_tone"],"1F3CC-1F3FC":["person_golfing_tone2","person_golfing_medium_light_skin_tone"],"1F3CC-1F3FD":["person_golfing_tone3","person_golfing_medium_skin_tone"],"1F3CC-1F3FE":["person_golfing_tone4","person_golfing_medium_dark_skin_tone"],"1F3CC-1F3FF":["person_golfing_tone5","person_golfing_dark_skin_tone"],"1F3CC-FE0F-200D-2640-FE0F":"woman_golfing","1F3CC-1F3FB-200D-2640-FE0F":["woman_golfing_tone1","woman_golfing_light_skin_tone"],"1F3CC-1F3FC-200D-2640-FE0F":["woman_golfing_tone2","woman_golfing_medium_light_skin_tone"],"1F3CC-1F3FD-200D-2640-FE0F":["woman_golfing_tone3","woman_golfing_medium_skin_tone"],"1F3CC-1F3FE-200D-2640-FE0F":["woman_golfing_tone4","woman_golfing_medium_dark_skin_tone"],"1F3CC-1F3FF-200D-2640-FE0F":["woman_golfing_tone5","woman_golfing_dark_skin_tone"],"1F3CC-FE0F-200D-2642-FE0F":"man_golfing","1F3CC-1F3FB-200D-2642-FE0F":["man_golfing_tone1","man_golfing_light_skin_tone"],"1F3CC-1F3FC-200D-2642-FE0F":["man_golfing_tone2","man_golfing_medium_light_skin_tone"],"1F3CC-1F3FD-200D-2642-FE0F":["man_golfing_tone3","man_golfing_medium_skin_tone"],"1F3CC-1F3FE-200D-2642-FE0F":["man_golfing_tone4","man_golfing_medium_dark_skin_tone"],"1F3CC-1F3FF-200D-2642-FE0F":["man_golfing_tone5","man_golfing_dark_skin_tone"],"1F3C7":"horse_racing","1F3C7-1F3FB":"horse_racing_tone1","1F3C7-1F3FC":"horse_racing_tone2","1F3C7-1F3FD":"horse_racing_tone3","1F3C7-1F3FE":"horse_racing_tone4","1F3C7-1F3FF":"horse_racing_tone5","1F9D8":"person_in_lotus_position","1F9D8-1F3FB":["person_in_lotus_position_tone1","person_in_lotus_position_light_skin_tone"],"1F9D8-1F3FC":["person_in_lotus_position_tone2","person_in_lotus_position_medium_light_skin_tone"],"1F9D8-1F3FD":["person_in_lotus_position_tone3","person_in_lotus_position_medium_skin_tone"],"1F9D8-1F3FE":["person_in_lotus_position_tone4","person_in_lotus_position_medium_dark_skin_tone"],"1F9D8-1F3FF":["person_in_lotus_position_tone5","person_in_lotus_position_dark_skin_tone"],"1F9D8-200D-2640-FE0F":"woman_in_lotus_position","1F9D8-1F3FB-200D-2640-FE0F":["woman_in_lotus_position_tone1","woman_in_lotus_position_light_skin_tone"],"1F9D8-1F3FC-200D-2640-FE0F":["woman_in_lotus_position_tone2","woman_in_lotus_position_medium_light_skin_tone"],"1F9D8-1F3FD-200D-2640-FE0F":["woman_in_lotus_position_tone3","woman_in_lotus_position_medium_skin_tone"],"1F9D8-1F3FE-200D-2640-FE0F":["woman_in_lotus_position_tone4","woman_in_lotus_position_medium_dark_skin_tone"],"1F9D8-1F3FF-200D-2640-FE0F":["woman_in_lotus_position_tone5","woman_in_lotus_position_dark_skin_tone"],"1F9D8-200D-2642-FE0F":"man_in_lotus_position","1F9D8-1F3FB-200D-2642-FE0F":["man_in_lotus_position_tone1","man_in_lotus_position_light_skin_tone"],"1F9D8-1F3FC-200D-2642-FE0F":["man_in_lotus_position_tone2","man_in_lotus_position_medium_light_skin_tone"],"1F9D8-1F3FD-200D-2642-FE0F":["man_in_lotus_position_tone3","man_in_lotus_position_medium_skin_tone"],"1F9D8-1F3FE-200D-2642-FE0F":["man_in_lotus_position_tone4","man_in_lotus_position_medium_dark_skin_tone"],"1F9D8-1F3FF-200D-2642-FE0F":["man_in_lotus_position_tone5","man_in_lotus_position_dark_skin_tone"],"1F3C4":["person_surfing","surfer"],"1F3C4-1F3FB":["person_surfing_tone1","surfer_tone1"],"1F3C4-1F3FC":["person_surfing_tone2","surfer_tone2"],"1F3C4-1F3FD":["person_surfing_tone3","surfer_tone3"],"1F3C4-1F3FE":["person_surfing_tone4","surfer_tone4"],"1F3C4-1F3FF":["person_surfing_tone5","surfer_tone5"],"1F3C4-200D-2640-FE0F":"woman_surfing","1F3C4-1F3FB-200D-2640-FE0F":["woman_surfing_tone1","woman_surfing_light_skin_tone"],"1F3C4-1F3FC-200D-2640-FE0F":["woman_surfing_tone2","woman_surfing_medium_light_skin_tone"],"1F3C4-1F3FD-200D-2640-FE0F":["woman_surfing_tone3","woman_surfing_medium_skin_tone"],"1F3C4-1F3FE-200D-2640-FE0F":["woman_surfing_tone4","woman_surfing_medium_dark_skin_tone"],"1F3C4-1F3FF-200D-2640-FE0F":["woman_surfing_tone5","woman_surfing_dark_skin_tone"],"1F3C4-200D-2642-FE0F":"man_surfing","1F3C4-1F3FB-200D-2642-FE0F":["man_surfing_tone1","man_surfing_light_skin_tone"],"1F3C4-1F3FC-200D-2642-FE0F":["man_surfing_tone2","man_surfing_medium_light_skin_tone"],"1F3C4-1F3FD-200D-2642-FE0F":["man_surfing_tone3","man_surfing_medium_skin_tone"],"1F3C4-1F3FE-200D-2642-FE0F":["man_surfing_tone4","man_surfing_medium_dark_skin_tone"],"1F3C4-1F3FF-200D-2642-FE0F":["man_surfing_tone5","man_surfing_dark_skin_tone"],"1F3CA":["person_swimming","swimmer"],"1F3CA-1F3FB":["person_swimming_tone1","swimmer_tone1"],"1F3CA-1F3FC":["person_swimming_tone2","swimmer_tone2"],"1F3CA-1F3FD":["person_swimming_tone3","swimmer_tone3"],"1F3CA-1F3FE":["person_swimming_tone4","swimmer_tone4"],"1F3CA-1F3FF":["person_swimming_tone5","swimmer_tone5"],"1F3CA-200D-2640-FE0F":"woman_swimming","1F3CA-1F3FB-200D-2640-FE0F":["woman_swimming_tone1","woman_swimming_light_skin_tone"],"1F3CA-1F3FC-200D-2640-FE0F":["woman_swimming_tone2","woman_swimming_medium_light_skin_tone"],"1F3CA-1F3FD-200D-2640-FE0F":["woman_swimming_tone3","woman_swimming_medium_skin_tone"],"1F3CA-1F3FE-200D-2640-FE0F":["woman_swimming_tone4","woman_swimming_medium_dark_skin_tone"],"1F3CA-1F3FF-200D-2640-FE0F":["woman_swimming_tone5","woman_swimming_dark_skin_tone"],"1F3CA-200D-2642-FE0F":"man_swimming","1F3CA-1F3FB-200D-2642-FE0F":["man_swimming_tone1","man_swimming_light_skin_tone"],"1F3CA-1F3FC-200D-2642-FE0F":["man_swimming_tone2","man_swimming_medium_light_skin_tone"],"1F3CA-1F3FD-200D-2642-FE0F":["man_swimming_tone3","man_swimming_medium_skin_tone"],"1F3CA-1F3FE-200D-2642-FE0F":["man_swimming_tone4","man_swimming_medium_dark_skin_tone"],"1F3CA-1F3FF-200D-2642-FE0F":["man_swimming_tone5","man_swimming_dark_skin_tone"],"1F93D":["person_playing_water_polo","water_polo"],"1F93D-1F3FB":["person_playing_water_polo_tone1","water_polo_tone1"],"1F93D-1F3FC":["person_playing_water_polo_tone2","water_polo_tone2"],"1F93D-1F3FD":["person_playing_water_polo_tone3","water_polo_tone3"],"1F93D-1F3FE":["person_playing_water_polo_tone4","water_polo_tone4"],"1F93D-1F3FF":["person_playing_water_polo_tone5","water_polo_tone5"],"1F93D-200D-2640-FE0F":"woman_playing_water_polo","1F93D-1F3FB-200D-2640-FE0F":["woman_playing_water_polo_tone1","woman_playing_water_polo_light_skin_tone"],"1F93D-1F3FC-200D-2640-FE0F":["woman_playing_water_polo_tone2","woman_playing_water_polo_medium_light_skin_tone"],"1F93D-1F3FD-200D-2640-FE0F":["woman_playing_water_polo_tone3","woman_playing_water_polo_medium_skin_tone"],"1F93D-1F3FE-200D-2640-FE0F":["woman_playing_water_polo_tone4","woman_playing_water_polo_medium_dark_skin_tone"],"1F93D-1F3FF-200D-2640-FE0F":["woman_playing_water_polo_tone5","woman_playing_water_polo_dark_skin_tone"],"1F93D-200D-2642-FE0F":"man_playing_water_polo","1F93D-1F3FB-200D-2642-FE0F":["man_playing_water_polo_tone1","man_playing_water_polo_light_skin_tone"],"1F93D-1F3FC-200D-2642-FE0F":["man_playing_water_polo_tone2","man_playing_water_polo_medium_light_skin_tone"],"1F93D-1F3FD-200D-2642-FE0F":["man_playing_water_polo_tone3","man_playing_water_polo_medium_skin_tone"],"1F93D-1F3FE-200D-2642-FE0F":["man_playing_water_polo_tone4","man_playing_water_polo_medium_dark_skin_tone"],"1F93D-1F3FF-200D-2642-FE0F":["man_playing_water_polo_tone5","man_playing_water_polo_dark_skin_tone"],"1F6A3":["person_rowing_boat","rowboat"],"1F6A3-1F3FB":["person_rowing_boat_tone1","rowboat_tone1"],"1F6A3-1F3FC":["person_rowing_boat_tone2","rowboat_tone2"],"1F6A3-1F3FD":["person_rowing_boat_tone3","rowboat_tone3"],"1F6A3-1F3FE":["person_rowing_boat_tone4","rowboat_tone4"],"1F6A3-1F3FF":["person_rowing_boat_tone5","rowboat_tone5"],"1F6A3-200D-2640-FE0F":"woman_rowing_boat","1F6A3-1F3FB-200D-2640-FE0F":["woman_rowing_boat_tone1","woman_rowing_boat_light_skin_tone"],"1F6A3-1F3FC-200D-2640-FE0F":["woman_rowing_boat_tone2","woman_rowing_boat_medium_light_skin_tone"],"1F6A3-1F3FD-200D-2640-FE0F":["woman_rowing_boat_tone3","woman_rowing_boat_medium_skin_tone"],"1F6A3-1F3FE-200D-2640-FE0F":["woman_rowing_boat_tone4","woman_rowing_boat_medium_dark_skin_tone"],"1F6A3-1F3FF-200D-2640-FE0F":["woman_rowing_boat_tone5","woman_rowing_boat_dark_skin_tone"],"1F6A3-200D-2642-FE0F":"man_rowing_boat","1F6A3-1F3FB-200D-2642-FE0F":["man_rowing_boat_tone1","man_rowing_boat_light_skin_tone"],"1F6A3-1F3FC-200D-2642-FE0F":["man_rowing_boat_tone2","man_rowing_boat_medium_light_skin_tone"],"1F6A3-1F3FD-200D-2642-FE0F":["man_rowing_boat_tone3","man_rowing_boat_medium_skin_tone"],"1F6A3-1F3FE-200D-2642-FE0F":["man_rowing_boat_tone4","man_rowing_boat_medium_dark_skin_tone"],"1F6A3-1F3FF-200D-2642-FE0F":["man_rowing_boat_tone5","man_rowing_boat_dark_skin_tone"],"1F9D7":"person_climbing","1F9D7-1F3FB":["person_climbing_tone1","person_climbing_light_skin_tone"],"1F9D7-1F3FC":["person_climbing_tone2","person_climbing_medium_light_skin_tone"],"1F9D7-1F3FD":["person_climbing_tone3","person_climbing_medium_skin_tone"],"1F9D7-1F3FE":["person_climbing_tone4","person_climbing_medium_dark_skin_tone"],"1F9D7-1F3FF":["person_climbing_tone5","person_climbing_dark_skin_tone"],"1F9D7-200D-2640-FE0F":"woman_climbing","1F9D7-1F3FB-200D-2640-FE0F":["woman_climbing_tone1","woman_climbing_light_skin_tone"],"1F9D7-1F3FC-200D-2640-FE0F":["woman_climbing_tone2","woman_climbing_medium_light_skin_tone"],"1F9D7-1F3FD-200D-2640-FE0F":["woman_climbing_tone3","woman_climbing_medium_skin_tone"],"1F9D7-1F3FE-200D-2640-FE0F":["woman_climbing_tone4","woman_climbing_medium_dark_skin_tone"],"1F9D7-1F3FF-200D-2640-FE0F":["woman_climbing_tone5","woman_climbing_dark_skin_tone"],"1F9D7-200D-2642-FE0F":"man_climbing","1F9D7-1F3FB-200D-2642-FE0F":["man_climbing_tone1","man_climbing_light_skin_tone"],"1F9D7-1F3FC-200D-2642-FE0F":["man_climbing_tone2","man_climbing_medium_light_skin_tone"],"1F9D7-1F3FD-200D-2642-FE0F":["man_climbing_tone3","man_climbing_medium_skin_tone"],"1F9D7-1F3FE-200D-2642-FE0F":["man_climbing_tone4","man_climbing_medium_dark_skin_tone"],"1F9D7-1F3FF-200D-2642-FE0F":["man_climbing_tone5","man_climbing_dark_skin_tone"],"1F6B5":["person_mountain_biking","mountain_bicyclist"],"1F6B5-1F3FB":["person_mountain_biking_tone1","mountain_bicyclist_tone1"],"1F6B5-1F3FC":["person_mountain_biking_tone2","mountain_bicyclist_tone2"],"1F6B5-1F3FD":["person_mountain_biking_tone3","mountain_bicyclist_tone3"],"1F6B5-1F3FE":["person_mountain_biking_tone4","mountain_bicyclist_tone4"],"1F6B5-1F3FF":["person_mountain_biking_tone5","mountain_bicyclist_tone5"],"1F6B5-200D-2640-FE0F":"woman_mountain_biking","1F6B5-1F3FB-200D-2640-FE0F":["woman_mountain_biking_tone1","woman_mountain_biking_light_skin_tone"],"1F6B5-1F3FC-200D-2640-FE0F":["woman_mountain_biking_tone2","woman_mountain_biking_medium_light_skin_tone"],"1F6B5-1F3FD-200D-2640-FE0F":["woman_mountain_biking_tone3","woman_mountain_biking_medium_skin_tone"],"1F6B5-1F3FE-200D-2640-FE0F":["woman_mountain_biking_tone4","woman_mountain_biking_medium_dark_skin_tone"],"1F6B5-1F3FF-200D-2640-FE0F":["woman_mountain_biking_tone5","woman_mountain_biking_dark_skin_tone"],"1F6B5-200D-2642-FE0F":"man_mountain_biking","1F6B5-1F3FB-200D-2642-FE0F":["man_mountain_biking_tone1","man_mountain_biking_light_skin_tone"],"1F6B5-1F3FC-200D-2642-FE0F":["man_mountain_biking_tone2","man_mountain_biking_medium_light_skin_tone"],"1F6B5-1F3FD-200D-2642-FE0F":["man_mountain_biking_tone3","man_mountain_biking_medium_skin_tone"],"1F6B5-1F3FE-200D-2642-FE0F":["man_mountain_biking_tone4","man_mountain_biking_medium_dark_skin_tone"],"1F6B5-1F3FF-200D-2642-FE0F":["man_mountain_biking_tone5","man_mountain_biking_dark_skin_tone"],"1F6B4":["person_biking","bicyclist"],"1F6B4-1F3FB":["person_biking_tone1","bicyclist_tone1"],"1F6B4-1F3FC":["person_biking_tone2","bicyclist_tone2"],"1F6B4-1F3FD":["person_biking_tone3","bicyclist_tone3"],"1F6B4-1F3FE":["person_biking_tone4","bicyclist_tone4"],"1F6B4-1F3FF":["person_biking_tone5","bicyclist_tone5"],"1F6B4-200D-2640-FE0F":"woman_biking","1F6B4-1F3FB-200D-2640-FE0F":["woman_biking_tone1","woman_biking_light_skin_tone"],"1F6B4-1F3FC-200D-2640-FE0F":["woman_biking_tone2","woman_biking_medium_light_skin_tone"],"1F6B4-1F3FD-200D-2640-FE0F":["woman_biking_tone3","woman_biking_medium_skin_tone"],"1F6B4-1F3FE-200D-2640-FE0F":["woman_biking_tone4","woman_biking_medium_dark_skin_tone"],"1F6B4-1F3FF-200D-2640-FE0F":["woman_biking_tone5","woman_biking_dark_skin_tone"],"1F6B4-200D-2642-FE0F":"man_biking","1F6B4-1F3FB-200D-2642-FE0F":["man_biking_tone1","man_biking_light_skin_tone"],"1F6B4-1F3FC-200D-2642-FE0F":["man_biking_tone2","man_biking_medium_light_skin_tone"],"1F6B4-1F3FD-200D-2642-FE0F":["man_biking_tone3","man_biking_medium_skin_tone"],"1F6B4-1F3FE-200D-2642-FE0F":["man_biking_tone4","man_biking_medium_dark_skin_tone"],"1F6B4-1F3FF-200D-2642-FE0F":["man_biking_tone5","man_biking_dark_skin_tone"],"1F3C6":"trophy","1F947":["first_place","first_place_medal"],"1F948":["second_place","second_place_medal"],"1F949":["third_place","third_place_medal"],"1F3C5":["medal","sports_medal"],"1F396":"military_medal","1F3F5":"rosette","1F397":"reminder_ribbon","1F3AB":"ticket","1F39F":["tickets","admission_tickets"],"1F3AA":"circus_tent","1F939":["person_juggling","juggling","juggler"],"1F939-1F3FB":["person_juggling_tone1","juggling_tone1","juggler_tone1"],"1F939-1F3FC":["person_juggling_tone2","juggling_tone2","juggler_tone2"],"1F939-1F3FD":["person_juggling_tone3","juggling_tone3","juggler_tone3"],"1F939-1F3FE":["person_juggling_tone4","juggling_tone4","juggler_tone4"],"1F939-1F3FF":["person_juggling_tone5","juggling_tone5","juggler_tone5"],"1F939-200D-2640-FE0F":"woman_juggling","1F939-1F3FB-200D-2640-FE0F":["woman_juggling_tone1","woman_juggling_light_skin_tone"],"1F939-1F3FC-200D-2640-FE0F":["woman_juggling_tone2","woman_juggling_medium_light_skin_tone"],"1F939-1F3FD-200D-2640-FE0F":["woman_juggling_tone3","woman_juggling_medium_skin_tone"],"1F939-1F3FE-200D-2640-FE0F":["woman_juggling_tone4","woman_juggling_medium_dark_skin_tone"],"1F939-1F3FF-200D-2640-FE0F":["woman_juggling_tone5","woman_juggling_dark_skin_tone"],"1F939-200D-2642-FE0F":"man_juggling","1F939-1F3FB-200D-2642-FE0F":["man_juggling_tone1","man_juggling_light_skin_tone"],"1F939-1F3FC-200D-2642-FE0F":["man_juggling_tone2","man_juggling_medium_light_skin_tone"],"1F939-1F3FD-200D-2642-FE0F":["man_juggling_tone3","man_juggling_medium_skin_tone"],"1F939-1F3FE-200D-2642-FE0F":["man_juggling_tone4","man_juggling_medium_dark_skin_tone"],"1F939-1F3FF-200D-2642-FE0F":["man_juggling_tone5","man_juggling_dark_skin_tone"],"1F3AD":"performing_arts","1FA70":"ballet_shoes","1F3A8":"art","1F3AC":"clapper","1F3A4":"microphone","1F3A7":"headphones","1F3BC":"musical_score","1F3B9":"musical_keyboard","1F941":["drum","drum_with_drumsticks"],"1FA98":"long_drum","1F3B7":"saxophone","1F3BA":"trumpet","1F3B8":"guitar","1FA95":"banjo","1F3BB":"violin","1FA97":"accordion","1F3B2":"game_die","265F":"chess_pawn","1F3AF":"dart","1F3B3":"bowling","1F3AE":"video_game","1F3B0":"slot_machine","1F9E9":"jigsaw","1F697":"red_car","1F695":"taxi","1F699":"blue_car","1F6FB":"pickup_truck","1F68C":"bus","1F68E":"trolleybus","1F3CE":["race_car","racing_car"],"1F693":"police_car","1F691":"ambulance","1F692":"fire_engine","1F690":"minibus","1F69A":"truck","1F69B":"articulated_lorry","1F69C":"tractor","1F9AF":"probing_cane","1F9BD":"manual_wheelchair","1F9BC":"motorized_wheelchair","1F6F4":"scooter","1F6B2":"bike","1F6F5":["motor_scooter","motorbike"],"1F3CD":["motorcycle","racing_motorcycle"],"1F6FA":"auto_rickshaw","1F6A8":"rotating_light","1F694":"oncoming_police_car","1F68D":"oncoming_bus","1F698":"oncoming_automobile","1F696":"oncoming_taxi","1F6A1":"aerial_tramway","1F6A0":"mountain_cableway","1F69F":"suspension_railway","1F683":"railway_car","1F68B":"train","1F69E":"mountain_railway","1F69D":"monorail","1F684":"bullettrain_side","1F685":"bullettrain_front","1F688":"light_rail","1F682":"steam_locomotive","1F686":"train2","1F687":"metro","1F68A":"tram","1F689":"station","1F6EB":"airplane_departure","1F6EC":"airplane_arriving","1F6E9":["airplane_small","small_airplane"],"1F4BA":"seat","1F6F0":"satellite_orbital","1F680":"rocket","1F6F8":"flying_saucer","1F681":"helicopter","1F6F6":["canoe","kayak"],"26F5":"sailboat","1F6A4":"speedboat","1F6E5":"motorboat","1F6F3":["cruise_ship","passenger_ship"],"26F4":"ferry","1F6A2":"ship","26FD":"fuelpump","1F6A7":"construction","1F6A6":"vertical_traffic_light","1F6A5":"traffic_light","1F68F":"busstop","1F5FA":["map","world_map"],"1F5FF":"moyai","1F5FD":"statue_of_liberty","1F5FC":"tokyo_tower","1F3F0":"european_castle","1F3EF":"japanese_castle","1F3DF":"stadium","1F3A1":"ferris_wheel","1F3A2":"roller_coaster","1F3A0":"carousel_horse","26F2":"fountain","26F1":["beach_umbrella","umbrella_on_ground"],"1F3D6":["beach","beach_with_umbrella"],"1F3DD":["island","desert_island"],"1F3DC":"desert","1F30B":"volcano","26F0":"mountain","1F3D4":["mountain_snow","snow_capped_mountain"],"1F5FB":"mount_fuji","1F3D5":"camping","26FA":"tent","1F3E0":"house","1F3E1":"house_with_garden","1F3D8":["homes","house_buildings"],"1F3DA":["house_abandoned","derelict_house_building"],"1F6D6":"hut","1F3D7":["construction_site","building_construction"],"1F3ED":"factory","1F3E2":"office","1F3EC":"department_store","1F3E3":"post_office","1F3E4":"european_post_office","1F3E5":"hospital","1F3E6":"bank","1F3E8":"hotel","1F3EA":"convenience_store","1F3EB":"school","1F3E9":"love_hotel","1F492":"wedding","1F3DB":"classical_building","26EA":"church","1F54C":"mosque","1F54D":"synagogue","1F6D5":"hindu_temple","1F54B":"kaaba","26E9":"shinto_shrine","1F6E4":["railway_track","railroad_track"],"1F6E3":"motorway","1F5FE":"japan","1F391":"rice_scene","1F3DE":["park","national_park"],"1F305":"sunrise","1F304":"sunrise_over_mountains","1F320":"stars","1F387":"sparkler","1F386":"fireworks","1F307":["city_sunset","city_sunrise"],"1F306":"city_dusk","1F3D9":"cityscape","1F303":"night_with_stars","1F30C":"milky_way","1F309":"bridge_at_night","1F301":"foggy","231A":"watch","1F4F1":"mobile_phone","1F4F2":"calling","1F4BB":"computer","1F5A5":["desktop","desktop_computer"],"1F5A8":"printer","1F5B1":["mouse_three_button","three_button_mouse"],"1F5B2":"trackball","1F579":"joystick","1F5DC":"compression","1F4BD":"minidisc","1F4BE":"floppy_disk","1F4BF":"cd","1F4C0":"dvd","1F4FC":"vhs","1F4F7":"camera","1F4F8":"camera_with_flash","1F4F9":"video_camera","1F3A5":"movie_camera","1F4FD":["projector","film_projector"],"1F39E":"film_frames","1F4DE":"telephone_receiver","260E":"telephone","1F4DF":"pager","1F4E0":"fax","1F4FA":"tv","1F4FB":"radio","1F399":["microphone2","studio_microphone"],"1F39A":"level_slider","1F39B":"control_knobs","1F9ED":"compass","23F1":"stopwatch","23F2":["timer","timer_clock"],"23F0":"alarm_clock","1F570":["clock","mantlepiece_clock"],"231B":"hourglass","23F3":"hourglass_flowing_sand","1F4E1":"satellite","1F50B":"battery","1F50C":"electric_plug","1F4A1":"bulb","1F526":"flashlight","1F56F":"candle","1FA94":"diya_lamp","1F9EF":"fire_extinguisher","1F6E2":["oil","oil_drum"],"1F4B8":"money_with_wings","1F4B5":"dollar","1F4B4":"yen","1F4B6":"euro","1F4B7":"pound","1FA99":"coin","1F4B0":"moneybag","1F4B3":"credit_card","1F48E":"gem","1FA9C":"ladder","1F9F0":"toolbox","1FA9B":"screwdriver","1F527":"wrench","1F528":"hammer","1F6E0":["tools","hammer_and_wrench"],"26CF":"pick","1F529":"nut_and_bolt","1F9F1":"bricks","26D3":"chains","1FA9D":"hook","1FAA2":"knot","1F9F2":"magnet","1F52B":"gun","1F4A3":"bomb","1F9E8":"firecracker","1FA93":"axe","1FA9A":"carpentry_saw","1F52A":"knife","1F5E1":["dagger","dagger_knife"],"1F6E1":"shield","1F6AC":"smoking","26B0":"coffin","1FAA6":"headstone","26B1":["urn","funeral_urn"],"1F3FA":"amphora","1FA84":"magic_wand","1F52E":"crystal_ball","1F4FF":"prayer_beads","1F9FF":"nazar_amulet","1F488":"barber","1F52D":"telescope","1F52C":"microscope","1F573":"hole","1FA9F":"window","1FA79":"adhesive_bandage","1FA7A":"stethoscope","1F48A":"pill","1F489":"syringe","1FA78":"drop_of_blood","1F9EC":"dna","1F9A0":"microbe","1F9EB":"petri_dish","1F9EA":"test_tube","1F321":"thermometer","1FAA4":"mouse_trap","1F9F9":"broom","1F9FA":"basket","1FAA1":"sewing_needle","1F9FB":"roll_of_paper","1F6BD":"toilet","1FAA0":"plunger","1FAA3":"bucket","1F6B0":"potable_water","1F6BF":"shower","1F6C1":"bathtub","1F6C0":"bath","1F6C0-1F3FB":"bath_tone1","1F6C0-1F3FC":"bath_tone2","1F6C0-1F3FD":"bath_tone3","1F6C0-1F3FE":"bath_tone4","1F6C0-1F3FF":"bath_tone5","1FAA5":"toothbrush","1F9FC":"soap","1FA92":"razor","1F9FD":"sponge","1F9F4":"squeeze_bottle","1F6CE":["bellhop","bellhop_bell"],"1F511":"key","1F5DD":["key2","old_key"],"1F6AA":"door","1FA91":"chair","1FA9E":"mirror","1F6CB":["couch","couch_and_lamp"],"1F6CF":"bed","1F6CC":"sleeping_accommodation","1F6CC-1F3FB":["person_in_bed_tone1","person_in_bed_light_skin_tone"],"1F6CC-1F3FC":["person_in_bed_tone2","person_in_bed_medium_light_skin_tone"],"1F6CC-1F3FD":["person_in_bed_tone3","person_in_bed_medium_skin_tone"],"1F6CC-1F3FE":["person_in_bed_tone4","person_in_bed_medium_dark_skin_tone"],"1F6CC-1F3FF":["person_in_bed_tone5","person_in_bed_dark_skin_tone"],"1F9F8":"teddy_bear","1F5BC":["frame_photo","frame_with_picture"],"1F6CD":"shopping_bags","1F6D2":["shopping_cart","shopping_trolley"],"1F381":"gift","1F388":"balloon","1F38F":"flags","1F380":"ribbon","1F38A":"confetti_ball","1F389":"tada","1FA85":"pinata","1FA86":"nesting_dolls","1F38E":"dolls","1F3EE":"izakaya_lantern","1F390":"wind_chime","1F9E7":"red_envelope","1F4E9":"envelope_with_arrow","1F4E8":"incoming_envelope","1F4E7":["e-mail","email"],"1F48C":"love_letter","1F4E5":"inbox_tray","1F4E4":"outbox_tray","1F4E6":"package","1F3F7":"label","1F4EA":"mailbox_closed","1F4EB":"mailbox","1F4EC":"mailbox_with_mail","1F4ED":"mailbox_with_no_mail","1F4EE":"postbox","1F4EF":"postal_horn","1FAA7":"placard","1F4DC":"scroll","1F4C3":"page_with_curl","1F4C4":"page_facing_up","1F4D1":"bookmark_tabs","1F9FE":"receipt","1F4CA":"bar_chart","1F4C8":"chart_with_upwards_trend","1F4C9":"chart_with_downwards_trend","1F5D2":["notepad_spiral","spiral_note_pad"],"1F5D3":["calendar_spiral","spiral_calendar_pad"],"1F4C6":"calendar","1F4C5":"date","1F5D1":"wastebasket","1F4C7":"card_index","1F5C3":["card_box","card_file_box"],"1F5F3":["ballot_box","ballot_box_with_ballot"],"1F5C4":"file_cabinet","1F4CB":"clipboard","1F4C1":"file_folder","1F4C2":"open_file_folder","1F5C2":["dividers","card_index_dividers"],"1F5DE":["newspaper2","rolled_up_newspaper"],"1F4F0":"newspaper","1F4D3":"notebook","1F4D4":"notebook_with_decorative_cover","1F4D2":"ledger","1F4D5":"closed_book","1F4D7":"green_book","1F4D8":"blue_book","1F4D9":"orange_book","1F4DA":"books","1F4D6":"book","1F516":"bookmark","1F9F7":"safety_pin","1F517":"link","1F4CE":"paperclip","1F587":["paperclips","linked_paperclips"],"1F4D0":"triangular_ruler","1F4CF":"straight_ruler","1F9EE":"abacus","1F4CC":"pushpin","1F4CD":"round_pushpin","1F58A":["pen_ballpoint","lower_left_ballpoint_pen"],"1F58B":["pen_fountain","lower_left_fountain_pen"],"1F58C":["paintbrush","lower_left_paintbrush"],"1F58D":["crayon","lower_left_crayon"],"1F4DD":["pencil","memo"],"270F":"pencil2","1F50D":"mag","1F50E":"mag_right","1F50F":"lock_with_ink_pen","1F510":"closed_lock_with_key","1F512":"lock","1F513":"unlock","1F9E1":"orange_heart","1F49B":"yellow_heart","1F49A":"green_heart","1F499":"blue_heart","1F49C":"purple_heart","1F5A4":"black_heart","1F90E":"brown_heart","1F90D":"white_heart","1F494":"broken_heart","1F495":"two_hearts","1F49E":"revolving_hearts","1F493":"heartbeat","1F497":"heartpulse","1F496":"sparkling_heart","1F498":"cupid","1F49D":"gift_heart","2764-FE0F-200D-1FA79":"mending_heart","2764-FE0F-200D-1F525":"heart_on_fire","1F49F":"heart_decoration","262E":["peace","peace_symbol"],"271D":["cross","latin_cross"],"262A":"star_and_crescent","1F549":"om_symbol","1F52F":"six_pointed_star","1F54E":"menorah","262F":"yin_yang","1F6D0":["place_of_worship","worship_symbol"],"26CE":"ophiuchus","264A":"gemini","264B":"cancer","264C":"leo","264D":"virgo","264E":"libra","264F":"scorpius","1F194":"id","269B":["atom","atom_symbol"],"1F251":"accept","1F4F4":"mobile_phone_off","1F4F3":"vibration_mode","1F236":"u6709","1F21A":"u7121","1F238":"u7533","1F23A":"u55b6","1F237":"u6708","1F19A":"vs","1F4AE":"white_flower","1F250":"ideograph_advantage","1F234":"u5408","1F235":"u6e80","1F239":"u5272","1F232":"u7981","1F170":"a","1F171":"b","1F18E":"ab","1F191":"cl","1F17E":"o2","1F198":"sos","274C":"x","2B55":"o","1F6D1":["octagonal_sign","stop_sign"],"26D4":"no_entry","1F4DB":"name_badge","1F6AB":"no_entry_sign","1F4AF":"100","1F4A2":"anger","1F6B7":"no_pedestrians","1F6AF":"do_not_litter","1F6B3":"no_bicycles","1F6B1":"non-potable_water","1F51E":"underage","1F4F5":"no_mobile_phones","1F6AD":"no_smoking","203C":"bangbang","1F505":"low_brightness","1F506":"high_brightness","303D":"part_alternation_mark","26A0":"warning","1F6B8":"children_crossing","1F531":"trident","269C":"fleur-de-lis","1F530":"beginner","267B":"recycle","1F22F":"u6307","1F4B9":"chart","274E":"negative_squared_cross_mark","1F310":"globe_with_meridians","1F4A0":"diamond_shape_with_a_dot_inside","24C2":"m","1F300":"cyclone","1F4A4":"zzz","1F3E7":"atm","1F6BE":"wc","267F":"wheelchair","1F17F":"parking","1F233":"u7a7a","1F202":"sa","1F6C2":"passport_control","1F6C3":"customs","1F6C4":"baggage_claim","1F6C5":"left_luggage","1F6D7":"elevator","1F6B9":"mens","1F6BA":"womens","1F6BC":"baby_symbol","1F6BB":"restroom","1F6AE":"put_litter_in_its_place","1F3A6":"cinema","1F4F6":"signal_strength","1F201":"koko","1F523":"symbols","1F524":"abc","1F521":"abcd","1F520":"capital_abcd","1F196":"ng","1F197":"ok","1F199":"up","1F192":"cool","1F195":"new","1F193":"free","0030-FE0F-20E3":"zero","0031-FE0F-20E3":"one","0032-FE0F-20E3":"two","0033-FE0F-20E3":"three","0034-FE0F-20E3":"four","0035-FE0F-20E3":"five","0036-FE0F-20E3":"six","0037-FE0F-20E3":"seven","0038-FE0F-20E3":"eight","0039-FE0F-20E3":"nine","1F51F":"keycap_ten","1F522":"1234","0023-FE0F-20E3":"hash","002A-FE0F-20E3":["asterisk","keycap_asterisk"],"23CF":["eject","eject_symbol"],"25B6":"arrow_forward","23F8":["pause_button","double_vertical_bar"],"23EF":"play_pause","23F9":"stop_button","23FA":"record_button","23ED":["track_next","next_track"],"23EE":["track_previous","previous_track"],"23E9":"fast_forward","23EA":"rewind","23EB":"arrow_double_up","23EC":"arrow_double_down","25C0":"arrow_backward","1F53C":"arrow_up_small","1F53D":"arrow_down_small","27A1":"arrow_right","2B05":"arrow_left","2B06":"arrow_up","2B07":"arrow_down","21AA":"arrow_right_hook","21A9":"leftwards_arrow_with_hook","1F500":"twisted_rightwards_arrows","1F501":"repeat","1F502":"repeat_one","1F504":"arrows_counterclockwise","1F503":"arrows_clockwise","1F3B5":"musical_note","1F3B6":"notes","267E":"infinity","1F4B2":"heavy_dollar_sign","1F4B1":"currency_exchange","00A9":"copyright","00AE":"registered","27B0":"curly_loop","27BF":"loop","1F51A":"end","1F519":"back","1F51B":"on","1F51D":"top","1F51C":"soon","1F518":"radio_button","26AA":"white_circle","26AB":"black_circle","1F534":"red_circle","1F535":"blue_circle","1F7E4":"brown_circle","1F7E3":"purple_circle","1F7E2":"green_circle","1F7E1":"yellow_circle","1F7E0":"orange_circle","1F53A":"small_red_triangle","1F53B":"small_red_triangle_down","1F538":"small_orange_diamond","1F539":"small_blue_diamond","1F536":"large_orange_diamond","1F537":"large_blue_diamond","1F533":"white_square_button","1F532":"black_square_button","25AA":"black_small_square","25AB":"white_small_square","25FE":"black_medium_small_square","25FD":"white_medium_small_square","25FC":"black_medium_square","25FB":"white_medium_square","2B1B":"black_large_square","2B1C":"white_large_square","1F7E7":"orange_square","1F7E6":"blue_square","1F7E5":"red_square","1F7EB":"brown_square","1F7EA":"purple_square","1F7E9":"green_square","1F7E8":"yellow_square","1F508":"speaker","1F507":"mute","1F509":"sound","1F50A":"loud_sound","1F514":"bell","1F515":"no_bell","1F4E3":"mega","1F4E2":"loudspeaker","1F5E8":["speech_left","left_speech_bubble"],"1F441-FE0F-200D-1F5E8-FE0F":"eye_in_speech_bubble","1F4AC":"speech_balloon","1F4AD":"thought_balloon","1F5EF":["anger_right","right_anger_bubble"],"1F0CF":"black_joker","1F3B4":"flower_playing_cards","1F004":"mahjong","1F550":"clock1","1F551":"clock2","1F552":"clock3","1F553":"clock4","1F554":"clock5","1F555":"clock6","1F556":"clock7","1F557":"clock8","1F558":"clock9","1F559":"clock10","1F55A":"clock11","1F55B":"clock12","1F55C":"clock130","1F55D":"clock230","1F55E":"clock330","1F55F":"clock430","1F560":"clock530","1F561":"clock630","1F562":"clock730","1F563":"clock830","1F564":"clock930","1F565":"clock1030","1F566":"clock1130","1F567":"clock1230","26A7":"transgender_symbol","1F3F3":["flag_white","waving_white_flag"],"1F3F4":["flag_black","waving_black_flag"],"1F3C1":"checkered_flag","1F6A9":"triangular_flag_on_post","1F3F3-FE0F-200D-1F308":["rainbow_flag","gay_pride_flag"],"1F3F3-FE0F-200D-26A7-FE0F":"transgender_flag","1F3F4-200D-2620-FE0F":"pirate_flag","1F1E6-1F1EB":["flag_af","af"],"1F1E6-1F1FD":["flag_ax","ax"],"1F1E6-1F1F1":["flag_al","al"],"1F1E9-1F1FF":["flag_dz","dz"],"1F1E6-1F1F8":["flag_as","as"],"1F1E6-1F1E9":["flag_ad","ad"],"1F1E6-1F1F4":["flag_ao","ao"],"1F1E6-1F1EE":["flag_ai","ai"],"1F1E6-1F1F6":["flag_aq","aq"],"1F1E6-1F1EC":["flag_ag","ag"],"1F1E6-1F1F7":["flag_ar","ar"],"1F1E6-1F1F2":["flag_am","am"],"1F1E6-1F1FC":["flag_aw","aw"],"1F1E6-1F1FA":["flag_au","au"],"1F1E6-1F1F9":["flag_at","at"],"1F1E6-1F1FF":["flag_az","az"],"1F1E7-1F1F8":["flag_bs","bs"],"1F1E7-1F1ED":["flag_bh","bh"],"1F1E7-1F1E9":["flag_bd","bd"],"1F1E7-1F1E7":["flag_bb","bb"],"1F1E7-1F1FE":["flag_by","by"],"1F1E7-1F1EA":["flag_be","be"],"1F1E7-1F1FF":["flag_bz","bz"],"1F1E7-1F1EF":["flag_bj","bj"],"1F1E7-1F1F2":["flag_bm","bm"],"1F1E7-1F1F9":["flag_bt","bt"],"1F1E7-1F1F4":["flag_bo","bo"],"1F1E7-1F1E6":["flag_ba","ba"],"1F1E7-1F1FC":["flag_bw","bw"],"1F1E7-1F1F7":["flag_br","br"],"1F1EE-1F1F4":["flag_io","io"],"1F1FB-1F1EC":["flag_vg","vg"],"1F1E7-1F1F3":["flag_bn","bn"],"1F1E7-1F1EC":["flag_bg","bg"],"1F1E7-1F1EB":["flag_bf","bf"],"1F1E7-1F1EE":["flag_bi","bi"],"1F1F0-1F1ED":["flag_kh","kh"],"1F1E8-1F1F2":["flag_cm","cm"],"1F1E8-1F1E6":["flag_ca","ca"],"1F1EE-1F1E8":["flag_ic","ic"],"1F1E8-1F1FB":["flag_cv","cv"],"1F1E7-1F1F6":["flag_bq","bq"],"1F1F0-1F1FE":["flag_ky","ky"],"1F1E8-1F1EB":["flag_cf","cf"],"1F1F9-1F1E9":["flag_td","td"],"1F1E8-1F1F1":["flag_cl","chile"],"1F1E8-1F1F3":["flag_cn","cn"],"1F1E8-1F1FD":["flag_cx","cx"],"1F1E8-1F1E8":["flag_cc","cc"],"1F1E8-1F1F4":["flag_co","co"],"1F1F0-1F1F2":["flag_km","km"],"1F1E8-1F1EC":["flag_cg","cg"],"1F1E8-1F1E9":["flag_cd","congo"],"1F1E8-1F1F0":["flag_ck","ck"],"1F1E8-1F1F7":["flag_cr","cr"],"1F1E8-1F1EE":["flag_ci","ci"],"1F1ED-1F1F7":["flag_hr","hr"],"1F1E8-1F1FA":["flag_cu","cu"],"1F1E8-1F1FC":["flag_cw","cw"],"1F1E8-1F1FE":["flag_cy","cy"],"1F1E8-1F1FF":["flag_cz","cz"],"1F1E9-1F1F0":["flag_dk","dk"],"1F1E9-1F1EF":["flag_dj","dj"],"1F1E9-1F1F2":["flag_dm","dm"],"1F1E9-1F1F4":["flag_do","do"],"1F1EA-1F1E8":["flag_ec","ec"],"1F1EA-1F1EC":["flag_eg","eg"],"1F1F8-1F1FB":["flag_sv","sv"],"1F1EC-1F1F6":["flag_gq","gq"],"1F1EA-1F1F7":["flag_er","er"],"1F1EA-1F1EA":["flag_ee","ee"],"1F1EA-1F1F9":["flag_et","et"],"1F1EA-1F1FA":["flag_eu","eu"],"1F1EB-1F1F0":["flag_fk","fk"],"1F1EB-1F1F4":["flag_fo","fo"],"1F1EB-1F1EF":["flag_fj","fj"],"1F1EB-1F1EE":["flag_fi","fi"],"1F1EB-1F1F7":["flag_fr","fr"],"1F1EC-1F1EB":["flag_gf","gf"],"1F1F5-1F1EB":["flag_pf","pf"],"1F1F9-1F1EB":["flag_tf","tf"],"1F1EC-1F1E6":["flag_ga","ga"],"1F1EC-1F1F2":["flag_gm","gm"],"1F1EC-1F1EA":["flag_ge","ge"],"1F1E9-1F1EA":["flag_de","de"],"1F1EC-1F1ED":["flag_gh","gh"],"1F1EC-1F1EE":["flag_gi","gi"],"1F1EC-1F1F7":["flag_gr","gr"],"1F1EC-1F1F1":["flag_gl","gl"],"1F1EC-1F1E9":["flag_gd","gd"],"1F1EC-1F1F5":["flag_gp","gp"],"1F1EC-1F1FA":["flag_gu","gu"],"1F1EC-1F1F9":["flag_gt","gt"],"1F1EC-1F1EC":["flag_gg","gg"],"1F1EC-1F1F3":["flag_gn","gn"],"1F1EC-1F1FC":["flag_gw","gw"],"1F1EC-1F1FE":["flag_gy","gy"],"1F1ED-1F1F9":["flag_ht","ht"],"1F1ED-1F1F3":["flag_hn","hn"],"1F1ED-1F1F0":["flag_hk","hk"],"1F1ED-1F1FA":["flag_hu","hu"],"1F1EE-1F1F8":["flag_is","is"],"1F1EE-1F1F3":["flag_in","in"],"1F1EE-1F1E9":["flag_id","indonesia"],"1F1EE-1F1F7":["flag_ir","ir"],"1F1EE-1F1F6":["flag_iq","iq"],"1F1EE-1F1EA":["flag_ie","ie"],"1F1EE-1F1F2":["flag_im","im"],"1F1EE-1F1F1":["flag_il","il"],"1F1EE-1F1F9":["flag_it","it"],"1F1EF-1F1F2":["flag_jm","jm"],"1F1EF-1F1F5":["flag_jp","jp"],"1F38C":"crossed_flags","1F1EF-1F1EA":["flag_je","je"],"1F1EF-1F1F4":["flag_jo","jo"],"1F1F0-1F1FF":["flag_kz","kz"],"1F1F0-1F1EA":["flag_ke","ke"],"1F1F0-1F1EE":["flag_ki","ki"],"1F1FD-1F1F0":["flag_xk","xk"],"1F1F0-1F1FC":["flag_kw","kw"],"1F1F0-1F1EC":["flag_kg","kg"],"1F1F1-1F1E6":["flag_la","la"],"1F1F1-1F1FB":["flag_lv","lv"],"1F1F1-1F1E7":["flag_lb","lb"],"1F1F1-1F1F8":["flag_ls","ls"],"1F1F1-1F1F7":["flag_lr","lr"],"1F1F1-1F1FE":["flag_ly","ly"],"1F1F1-1F1EE":["flag_li","li"],"1F1F1-1F1F9":["flag_lt","lt"],"1F1F1-1F1FA":["flag_lu","lu"],"1F1F2-1F1F4":["flag_mo","mo"],"1F1F2-1F1F0":["flag_mk","mk"],"1F1F2-1F1EC":["flag_mg","mg"],"1F1F2-1F1FC":["flag_mw","mw"],"1F1F2-1F1FE":["flag_my","my"],"1F1F2-1F1FB":["flag_mv","mv"],"1F1F2-1F1F1":["flag_ml","ml"],"1F1F2-1F1F9":["flag_mt","mt"],"1F1F2-1F1ED":["flag_mh","mh"],"1F1F2-1F1F6":["flag_mq","mq"],"1F1F2-1F1F7":["flag_mr","mr"],"1F1F2-1F1FA":["flag_mu","mu"],"1F1FE-1F1F9":["flag_yt","yt"],"1F1F2-1F1FD":["flag_mx","mx"],"1F1EB-1F1F2":["flag_fm","fm"],"1F1F2-1F1E9":["flag_md","md"],"1F1F2-1F1E8":["flag_mc","mc"],"1F1F2-1F1F3":["flag_mn","mn"],"1F1F2-1F1EA":["flag_me","me"],"1F1F2-1F1F8":["flag_ms","ms"],"1F1F2-1F1E6":["flag_ma","ma"],"1F1F2-1F1FF":["flag_mz","mz"],"1F1F2-1F1F2":["flag_mm","mm"],"1F1F3-1F1E6":["flag_na","na"],"1F1F3-1F1F7":["flag_nr","nr"],"1F1F3-1F1F5":["flag_np","np"],"1F1F3-1F1F1":["flag_nl","nl"],"1F1F3-1F1E8":["flag_nc","nc"],"1F1F3-1F1FF":["flag_nz","nz"],"1F1F3-1F1EE":["flag_ni","ni"],"1F1F3-1F1EA":["flag_ne","ne"],"1F1F3-1F1EC":["flag_ng","nigeria"],"1F1F3-1F1FA":["flag_nu","nu"],"1F1F3-1F1EB":["flag_nf","nf"],"1F1F0-1F1F5":["flag_kp","kp"],"1F1F2-1F1F5":["flag_mp","mp"],"1F1F3-1F1F4":["flag_no","no"],"1F1F4-1F1F2":["flag_om","om"],"1F1F5-1F1F0":["flag_pk","pk"],"1F1F5-1F1FC":["flag_pw","pw"],"1F1F5-1F1F8":["flag_ps","ps"],"1F1F5-1F1E6":["flag_pa","pa"],"1F1F5-1F1EC":["flag_pg","pg"],"1F1F5-1F1FE":["flag_py","py"],"1F1F5-1F1EA":["flag_pe","pe"],"1F1F5-1F1ED":["flag_ph","ph"],"1F1F5-1F1F3":["flag_pn","pn"],"1F1F5-1F1F1":["flag_pl","pl"],"1F1F5-1F1F9":["flag_pt","pt"],"1F1F5-1F1F7":["flag_pr","pr"],"1F1F6-1F1E6":["flag_qa","qa"],"1F1F7-1F1EA":["flag_re","re"],"1F1F7-1F1F4":["flag_ro","ro"],"1F1F7-1F1FA":["flag_ru","ru"],"1F1F7-1F1FC":["flag_rw","rw"],"1F1FC-1F1F8":["flag_ws","ws"],"1F1F8-1F1F2":["flag_sm","sm"],"1F1F8-1F1F9":["flag_st","st"],"1F1F8-1F1E6":["flag_sa","saudiarabia","saudi"],"1F1F8-1F1F3":["flag_sn","sn"],"1F1F7-1F1F8":["flag_rs","rs"],"1F1F8-1F1E8":["flag_sc","sc"],"1F1F8-1F1F1":["flag_sl","sl"],"1F1F8-1F1EC":["flag_sg","sg"],"1F1F8-1F1FD":["flag_sx","sx"],"1F1F8-1F1F0":["flag_sk","sk"],"1F1F8-1F1EE":["flag_si","si"],"1F1EC-1F1F8":["flag_gs","gs"],"1F1F8-1F1E7":["flag_sb","sb"],"1F1F8-1F1F4":["flag_so","so"],"1F1FF-1F1E6":["flag_za","za"],"1F1F0-1F1F7":["flag_kr","kr"],"1F1F8-1F1F8":["flag_ss","ss"],"1F1EA-1F1F8":["flag_es","es"],"1F1F1-1F1F0":["flag_lk","lk"],"1F1E7-1F1F1":["flag_bl","bl"],"1F1F8-1F1ED":["flag_sh","sh"],"1F1F0-1F1F3":["flag_kn","kn"],"1F1F1-1F1E8":["flag_lc","lc"],"1F1F5-1F1F2":["flag_pm","pm"],"1F1FB-1F1E8":["flag_vc","vc"],"1F1F8-1F1E9":["flag_sd","sd"],"1F1F8-1F1F7":["flag_sr","sr"],"1F1F8-1F1FF":["flag_sz","sz"],"1F1F8-1F1EA":["flag_se","se"],"1F1E8-1F1ED":["flag_ch","ch"],"1F1F8-1F1FE":["flag_sy","sy"],"1F1F9-1F1FC":["flag_tw","tw"],"1F1F9-1F1EF":["flag_tj","tj"],"1F1F9-1F1FF":["flag_tz","tz"],"1F1F9-1F1ED":["flag_th","th"],"1F1F9-1F1F1":["flag_tl","tl"],"1F1F9-1F1EC":["flag_tg","tg"],"1F1F9-1F1F0":["flag_tk","tk"],"1F1F9-1F1F4":["flag_to","to"],"1F1F9-1F1F9":["flag_tt","tt"],"1F1F9-1F1F3":["flag_tn","tn"],"1F1F9-1F1F7":["flag_tr","tr"],"1F1F9-1F1F2":["flag_tm","turkmenistan"],"1F1F9-1F1E8":["flag_tc","tc"],"1F1FB-1F1EE":["flag_vi","vi"],"1F1F9-1F1FB":["flag_tv","tuvalu"],"1F1FA-1F1EC":["flag_ug","ug"],"1F1FA-1F1E6":["flag_ua","ua"],"1F1E6-1F1EA":["flag_ae","ae"],"1F1EC-1F1E7":["flag_gb","gb"],"1F3F4-E0067-E0062-E0065-E006E-E0067-E007F":"england","1F3F4-E0067-E0062-E0073-E0063-E0074-E007F":"scotland","1F3F4-E0067-E0062-E0077-E006C-E0073-E007F":"wales","1F1FA-1F1F8":["flag_us","us"],"1F1FA-1F1FE":["flag_uy","uy"],"1F1FA-1F1FF":["flag_uz","uz"],"1F1FB-1F1FA":["flag_vu","vu"],"1F1FB-1F1E6":["flag_va","va"],"1F1FB-1F1EA":["flag_ve","ve"],"1F1FB-1F1F3":["flag_vn","vn"],"1F1FC-1F1EB":["flag_wf","wf"],"1F1EA-1F1ED":["flag_eh","eh"],"1F1FE-1F1EA":["flag_ye","ye"],"1F1FF-1F1F2":["flag_zm","zm"],"1F1FF-1F1FC":["flag_zw","zw"],"1F1E6-1F1E8":["flag_ac","ac"],"1F1E7-1F1FB":["flag_bv","bv"],"1F1E8-1F1F5":["flag_cp","cp"],"1F1EA-1F1E6":["flag_ea","ea"],"1F1E9-1F1EC":["flag_dg","dg"],"1F1ED-1F1F2":["flag_hm","hm"],"1F1F2-1F1EB":["flag_mf","mf"],"1F1F8-1F1EF":["flag_sj","sj"],"1F1F9-1F1E6":["flag_ta","ta"],"1F1FA-1F1F2":["flag_um","um"],"1F1FA-1F1F3":"united_nations","1F3FB":"tone1","1F3FC":"tone2","1F3FD":"tone3","1F3FE":"tone4","1F3FF":"tone5","1F1FF":"regional_indicator_z","1F1FE":"regional_indicator_y","1F1FD":"regional_indicator_x","1F1FC":"regional_indicator_w","1F1FB":"regional_indicator_v","1F1FA":"regional_indicator_u","1F1F9":"regional_indicator_t","1F1F8":"regional_indicator_s","1F1F7":"regional_indicator_r","1F1F6":"regional_indicator_q","1F1F5":"regional_indicator_p","1F1F4":"regional_indicator_o","1F1F3":"regional_indicator_n","1F1F2":"regional_indicator_m","1F1F1":"regional_indicator_l","1F1F0":"regional_indicator_k","1F1EF":"regional_indicator_j","1F1EE":"regional_indicator_i","1F1ED":"regional_indicator_h","1F1EC":"regional_indicator_g","1F1EB":"regional_indicator_f","1F1EA":"regional_indicator_e","1F1E9":"regional_indicator_d","1F1E8":"regional_indicator_c","1F1E7":"regional_indicator_b","1F1E6":"regional_indicator_a"}');function os(e){return Array.isArray?Array.isArray(e):"[object Array]"===cs(e)}function rs(e){return"string"==typeof e}function is(e){return"number"==typeof e}function as(e){return"object"==typeof e}function ss(e){return null!=e}function us(e){return!e.trim().length}function cs(e){return null==e?void 0===e?"[object Undefined]":"[object Null]":Object.prototype.toString.call(e)}const ls=Object.prototype.hasOwnProperty;class ds{constructor(e){this._keys=[],this._keyMap={};let t=0;e.forEach((e=>{let n=hs(e);t+=n.weight,this._keys.push(n),this._keyMap[n.id]=n,t+=n.weight})),this._keys.forEach((e=>{e.weight/=t}))}get(e){return this._keyMap[e]}keys(){return this._keys}toJSON(){return JSON.stringify(this._keys)}}function hs(e){let t=null,n=null,o=null,r=1;if(rs(e)||os(e))o=e,t=ps(e),n=fs(e);else{if(!ls.call(e,"name"))throw new Error("Missing name property in key");const i=e.name;if(o=i,ls.call(e,"weight")&&(r=e.weight,r<=0))throw new Error((e=>`Property 'weight' in key '${e}' must be a positive integer`)(i));t=ps(i),n=fs(i)}return{path:t,id:n,weight:r,src:o}}function ps(e){return os(e)?e:e.split(".")}function fs(e){return os(e)?e.join("."):e}var gs={isCaseSensitive:!1,includeScore:!1,keys:[],shouldSort:!0,sortFn:(e,t)=>e.score===t.score?e.idx{if(ss(e))if(t[i]){const a=e[t[i]];if(!ss(a))return;if(i===t.length-1&&(rs(a)||is(a)||function(e){return!0===e||!1===e||function(e){return as(e)&&null!==e}(e)&&"[object Boolean]"==cs(e)}(a)))n.push(function(e){return null==e?"":function(e){if("string"==typeof e)return e;let t=e+"";return"0"==t&&1/e==-1/0?"-0":t}(e)}(a));else if(os(a)){o=!0;for(let e=0,n=a.length;e{this._keysMap[e.id]=t}))}create(){!this.isCreated&&this.docs.length&&(this.isCreated=!0,rs(this.docs[0])?this.docs.forEach(((e,t)=>{this._addString(e,t)})):this.docs.forEach(((e,t)=>{this._addObject(e,t)})),this.norm.clear())}add(e){const t=this.size();rs(e)?this._addString(e,t):this._addObject(e,t)}removeAt(e){this.records.splice(e,1);for(let t=e,n=this.size();t{let r=this.getFn(e,t.path);if(ss(r))if(os(r)){let e=[];const t=[{nestedArrIndex:-1,value:r}];for(;t.length;){const{nestedArrIndex:n,value:o}=t.pop();if(ss(o))if(rs(o)&&!us(o)){let t={v:o,i:n,n:this.norm.get(o)};e.push(t)}else os(o)&&o.forEach(((e,n)=>{t.push({nestedArrIndex:n,value:e})}))}n.$[o]=e}else if(!us(r)){let e={v:r,n:this.norm.get(r)};n.$[o]=e}})),this.records.push(n)}toJSON(){return{keys:this.keys,records:this.records}}}function Fs(e,t,{getFn:n=gs.getFn}={}){const o=new _s({getFn:n});return o.setKeys(e.map(hs)),o.setSources(t),o.create(),o}function ys(e,{errors:t=0,currentLocation:n=0,expectedLocation:o=0,distance:r=gs.distance,ignoreLocation:i=gs.ignoreLocation}={}){const a=t/e.length;if(i)return a;const s=Math.abs(o-n);return r?a+s/r:s?1:a}const bs=32;function vs(e){let t={};for(let n=0,o=e.length;n{this.chunks.push({pattern:e,alphabet:vs(e),startIndex:t})},l=this.pattern.length;if(l>bs){let e=0;const t=l%bs,n=l-t;for(;e{const{isMatch:f,score:g,indices:m}=function(e,t,n,{location:o=gs.location,distance:r=gs.distance,threshold:i=gs.threshold,findAllMatches:a=gs.findAllMatches,minMatchCharLength:s=gs.minMatchCharLength,includeMatches:u=gs.includeMatches,ignoreLocation:c=gs.ignoreLocation}={}){if(t.length>bs)throw new Error("Pattern length exceeds max of 32.");const l=t.length,d=e.length,h=Math.max(0,Math.min(o,d));let p=i,f=h;const g=s>1||u,m=g?Array(d):[];let _;for(;(_=e.indexOf(t,f))>-1;){let e=ys(t,{currentLocation:_,expectedLocation:h,distance:r,ignoreLocation:c});if(p=Math.min(e,p),f=_+l,g){let e=0;for(;e=u;i-=1){let a=i-1,s=n[e.charAt(a)];if(g&&(m[a]=+!!s),w[i]=(w[i+1]<<1|1)&s,o&&(w[i]|=(F[i+1]|F[i])<<1|1|F[i+1]),w[i]&v&&(y=ys(t,{errors:o,currentLocation:a,expectedLocation:h,distance:r,ignoreLocation:c}),y<=p)){if(p=y,f=a,f<=h)break;u=Math.max(1,2*h-f)}}if(ys(t,{errors:o+1,currentLocation:h,expectedLocation:h,distance:r,ignoreLocation:c})>p)break;F=w}const w={isMatch:f>=0,score:Math.max(.001,y)};if(g){const e=function(e=[],t=gs.minMatchCharLength){let n=[],o=-1,r=-1,i=0;for(let a=e.length;i=t&&n.push([o,r]),o=-1)}return e[i-1]&&i-o>=t&&n.push([o,i-1]),n}(m,s);e.length?u&&(w.indices=e):w.isMatch=!1}return w}(e,t,h,{location:o+p,distance:r,threshold:i,findAllMatches:a,minMatchCharLength:s,includeMatches:n,ignoreLocation:u});f&&(d=!0),l+=g,f&&m&&(c=[...c,...m])}));let h={isMatch:d,score:d?l/this.chunks.length:1};return d&&n&&(h.indices=c),h}}class Es{constructor(e){this.pattern=e}static isMultiMatch(e){return ks(e,this.multiRegex)}static isSingleMatch(e){return ks(e,this.singleRegex)}search(){}}function ks(e,t){const n=e.match(t);return n?n[1]:null}class Ds extends Es{constructor(e,{location:t=gs.location,threshold:n=gs.threshold,distance:o=gs.distance,includeMatches:r=gs.includeMatches,findAllMatches:i=gs.findAllMatches,minMatchCharLength:a=gs.minMatchCharLength,isCaseSensitive:s=gs.isCaseSensitive,ignoreLocation:u=gs.ignoreLocation}={}){super(e),this._bitapSearch=new ws(e,{location:t,threshold:n,distance:o,includeMatches:r,findAllMatches:i,minMatchCharLength:a,isCaseSensitive:s,ignoreLocation:u})}static get type(){return"fuzzy"}static get multiRegex(){return/^"(.*)"$/}static get singleRegex(){return/^(.*)$/}search(e){return this._bitapSearch.searchIn(e)}}class Ss extends Es{constructor(e){super(e)}static get type(){return"include"}static get multiRegex(){return/^'"(.*)"$/}static get singleRegex(){return/^'(.*)$/}search(e){let t,n=0;const o=[],r=this.pattern.length;for(;(t=e.indexOf(this.pattern,n))>-1;)n=t+r,o.push([t,n-1]);const i=!!o.length;return{isMatch:i,score:i?0:1,indices:o}}}const xs=[class extends Es{constructor(e){super(e)}static get type(){return"exact"}static get multiRegex(){return/^="(.*)"$/}static get singleRegex(){return/^=(.*)$/}search(e){const t=e===this.pattern;return{isMatch:t,score:t?0:1,indices:[0,this.pattern.length-1]}}},Ss,class extends Es{constructor(e){super(e)}static get type(){return"prefix-exact"}static get multiRegex(){return/^\^"(.*)"$/}static get singleRegex(){return/^\^(.*)$/}search(e){const t=e.startsWith(this.pattern);return{isMatch:t,score:t?0:1,indices:[0,this.pattern.length-1]}}},class extends Es{constructor(e){super(e)}static get type(){return"inverse-prefix-exact"}static get multiRegex(){return/^!\^"(.*)"$/}static get singleRegex(){return/^!\^(.*)$/}search(e){const t=!e.startsWith(this.pattern);return{isMatch:t,score:t?0:1,indices:[0,e.length-1]}}},class extends Es{constructor(e){super(e)}static get type(){return"inverse-suffix-exact"}static get multiRegex(){return/^!"(.*)"\$$/}static get singleRegex(){return/^!(.*)\$$/}search(e){const t=!e.endsWith(this.pattern);return{isMatch:t,score:t?0:1,indices:[0,e.length-1]}}},class extends Es{constructor(e){super(e)}static get type(){return"suffix-exact"}static get multiRegex(){return/^"(.*)"\$$/}static get singleRegex(){return/^(.*)\$$/}search(e){const t=e.endsWith(this.pattern);return{isMatch:t,score:t?0:1,indices:[e.length-this.pattern.length,e.length-1]}}},class extends Es{constructor(e){super(e)}static get type(){return"inverse-exact"}static get multiRegex(){return/^!"(.*)"$/}static get singleRegex(){return/^!(.*)$/}search(e){const t=-1===e.indexOf(this.pattern);return{isMatch:t,score:t?0:1,indices:[0,e.length-1]}}},Ds],Cs=xs.length,As=/ +(?=([^\"]*\"[^\"]*\")*[^\"]*$)/,Ts=new Set([Ds.type,Ss.type]);const Rs=[];function Is(e,t){for(let n=0,o=Rs.length;n!(!e.$and&&!e.$or),Bs=e=>({[Ms]:Object.keys(e).map((t=>({[t]:e[t]})))});function Ns(e,t,{auto:n=!0}={}){const o=e=>{let r=Object.keys(e);const i=(e=>!!e.$path)(e);if(!i&&r.length>1&&!Os(e))return o(Bs(e));if((e=>!os(e)&&as(e)&&!Os(e))(e)){const o=i?e.$path:r[0],a=i?e.$val:e[o];if(!rs(a))throw new Error((e=>`Invalid value for key ${e}`)(o));const s={keyId:fs(o),pattern:a};return n&&(s.searcher=Is(a,t)),s}let a={children:[],operator:r[0]};return r.forEach((t=>{const n=e[t];os(n)&&n.forEach((e=>{a.children.push(o(e))}))})),a};return Os(e)||(e=Bs(e)),o(e)}function Ls(e,t){const n=e.matches;t.matches=[],ss(n)&&n.forEach((e=>{if(!ss(e.indices)||!e.indices.length)return;const{indices:n,value:o}=e;let r={indices:n,value:o};e.key&&(r.key=e.key.src),e.idx>-1&&(r.refIndex=e.idx),t.matches.push(r)}))}function Ps(e,t){t.score=e.score}class Us{constructor(e,t={},n){this.options={...gs,...t},this.options.useExtendedSearch,this._keyStore=new ds(this.options.keys),this.setCollection(e,n)}setCollection(e,t){if(this._docs=e,t&&!(t instanceof _s))throw new Error("Incorrect 'index' type");this._myIndex=t||Fs(this.options.keys,this._docs,{getFn:this.options.getFn})}add(e){ss(e)&&(this._docs.push(e),this._myIndex.add(e))}remove(e=(()=>!1)){const t=[];for(let n=0,o=this._docs.length;n{let n=1;e.matches.forEach((({key:e,norm:o,score:r})=>{const i=e?e.weight:null;n*=Math.pow(0===r&&i?Number.EPSILON:r,(i||1)*(t?1:o))})),e.score=n}))}(s,{ignoreFieldNorm:a}),r&&s.sort(i),is(t)&&t>-1&&(s=s.slice(0,t)),function(e,t,{includeMatches:n=gs.includeMatches,includeScore:o=gs.includeScore}={}){const r=[];return n&&r.push(Ls),o&&r.push(Ps),e.map((e=>{const{idx:n}=e,o={item:t[n],refIndex:n};return r.length&&r.forEach((t=>{t(e,o)})),o}))}(s,this._docs,{includeMatches:n,includeScore:o})}_searchStringList(e){const t=Is(e,this.options),{records:n}=this._myIndex,o=[];return n.forEach((({v:e,i:n,n:r})=>{if(!ss(e))return;const{isMatch:i,score:a,indices:s}=t.searchIn(e);i&&o.push({item:e,idx:n,matches:[{score:a,value:e,norm:r,indices:s}]})})),o}_searchLogical(e){const t=Ns(e,this.options),n=(e,t,o)=>{if(!e.children){const{keyId:n,searcher:r}=e,i=this._findMatches({key:this._keyStore.get(n),value:this._myIndex.getValueForItemAtKeyId(t,n),searcher:r});return i&&i.length?[{idx:o,item:t,matches:i}]:[]}switch(e.operator){case Ms:{const r=[];for(let i=0,a=e.children.length;i{if(ss(e)){let a=n(t,e,o);a.length&&(r[o]||(r[o]={idx:o,item:e,matches:[]},i.push(r[o])),a.forEach((({matches:e})=>{r[o].matches.push(...e)})))}})),i}_searchObjectList(e){const t=Is(e,this.options),{keys:n,records:o}=this._myIndex,r=[];return o.forEach((({$:e,i:o})=>{if(!ss(e))return;let i=[];n.forEach(((n,o)=>{i.push(...this._findMatches({key:n,value:e[o],searcher:t}))})),i.length&&r.push({idx:o,item:e,matches:i})})),r}_findMatches({key:e,value:t,searcher:n}){if(!ss(t))return[];let o=[];if(os(t))t.forEach((({v:t,i:r,n:i})=>{if(!ss(t))return;const{isMatch:a,score:s,indices:u}=n.searchIn(t);a&&o.push({score:s,key:e,value:t,idx:r,norm:i,indices:u})}));else{const{v:r,n:i}=t,{isMatch:a,score:s,indices:u}=n.searchIn(r);a&&o.push({score:s,key:e,value:r,norm:i,indices:u})}return o}}Us.version="6.4.6",Us.createIndex=Fs,Us.parseIndex=function(e,{getFn:t=gs.getFn}={}){const{keys:n,records:o}=e,r=new _s({getFn:t});return r.setKeys(n),r.setIndexRecords(o),r},Us.config=gs,Us.parseQuery=Ns,function(...e){Rs.push(...e)}(class{constructor(e,{isCaseSensitive:t=gs.isCaseSensitive,includeMatches:n=gs.includeMatches,minMatchCharLength:o=gs.minMatchCharLength,ignoreLocation:r=gs.ignoreLocation,findAllMatches:i=gs.findAllMatches,location:a=gs.location,threshold:s=gs.threshold,distance:u=gs.distance}={}){this.query=null,this.options={isCaseSensitive:t,includeMatches:n,minMatchCharLength:o,findAllMatches:i,ignoreLocation:r,location:a,threshold:s,distance:u},this.pattern=t?e:e.toLowerCase(),this.query=function(e,t={}){return e.split("|").map((e=>{let n=e.trim().split(As).filter((e=>e&&!!e.trim())),o=[];for(let e=0,r=n.length;ee.length)&&(t=e.length);for(var n=0,o=new Array(t);n=t)return"break";var s=n[a];i.push(o.createElement("span",{key:a},Qa(es.parse(s.unicode,{attributes:function(){var e;return{unicode:s.unicode,shortcodes:null===(e=s.shortcodes)||void 0===e?void 0:e.toString()}}}))))},s=r;s20&&(t=t.slice(0,20)),t.map((function(e){return e.item}))}(e)):i([])}return(0,o.useEffect)((function(){return ou.on("search-emoji",a),function(){ou.removeListener("search-emoji",a)}}),[]),0!==r.length&&o.createElement(ru,{key:"-1",name:"Search results",emojis:r})}function au(e){var t=e.onSelect,n=(0,o.useRef)(null),r=(0,o.useRef)(null);function i(e){return!1===e.classList.contains("emoji")}function a(e){var t=e.getAttribute("unicode"),n=e.getAttribute("shortcodes");return{unicode:t,shortcodes:n=void 0===n?void 0:n.split(",")}}function s(e){var t=e,n=r.current.firstElementChild,o=n.childElementCount;o>Gs.length&&(t+=o-Gs.length),n.children[t].scrollIntoView()}return o.createElement("div",{id:"emoji-board",className:"emoji-board"},o.createElement("div",{className:"emoji-board__content"},o.createElement("div",{className:"emoji-board__emojis"},o.createElement(Fn,{ref:r,autoHide:!0},o.createElement("div",{onMouseMove:function(e){if(!i(e.target)){var t=a(e.target).shortcodes;void 0!==t?n.current.placeholder!==t[0]&&n.current.setAttribute("placeholder",":".concat(t[0],":")):n.current.placeholder="Search"}},onClick:function(e){if(!i(e.target)){var n=e.target;t(a(n))}}},o.createElement(iu,null),Gs.map((function(e){return o.createElement(ru,{key:e.name,name:e.name,emojis:e.emojis})}))))),o.createElement("div",{className:"emoji-board__search"},o.createElement(Et,{size:"small",src:Vs}),o.createElement(Tt,{onChange:function(e){var t=e.target.value;setTimeout((function(){e.target.value===t&&(ou.emit("search-emoji",t),r.current.scrollTop=0)}),500)},forwardRef:n,placeholder:"Search"}))),o.createElement("div",{className:"emoji-board__nav"},o.createElement(Yr,{onClick:function(){return s(0)},src:Ws,tooltip:"Smileys",tooltipPlacement:"right"}),o.createElement(Yr,{onClick:function(){return s(1)},src:Ys,tooltip:"Animals",tooltipPlacement:"right"}),o.createElement(Yr,{onClick:function(){return s(2)},src:Zs,tooltip:"Food",tooltipPlacement:"right"}),o.createElement(Yr,{onClick:function(){return s(3)},src:Xs,tooltip:"Activity",tooltipPlacement:"right"}),o.createElement(Yr,{onClick:function(){return s(4)},src:Js,tooltip:"Travel",tooltipPlacement:"right"}),o.createElement(Yr,{onClick:function(){return s(5)},src:Qs,tooltip:"Objects",tooltipPlacement:"right"}),o.createElement(Yr,{onClick:function(){return s(6)},src:eu,tooltip:"Symbols",tooltipPlacement:"right"}),o.createElement(Yr,{onClick:function(){return s(7)},src:tu,tooltip:"Flags",tooltipPlacement:"right"})))}ru.propTypes={name:l().string.isRequired,emojis:l().arrayOf(l().shape({length:l().number,unicode:l().string,shortcodes:l().oneOfType([l().string,l().arrayOf(l().string)])})).isRequired},au.propTypes={onSelect:l().func.isRequired};const su=au,uu=n.p+"assets/vertical-menu.180cbca47512a24456ba0a74e64a5405.svg",cu=n.p+"assets/circle-plus.d6fd1e875f585a026f8196da8e1a7b64.svg",lu=n.p+"assets/send.507da28d5579add6eccc11cba4870a69.svg",du=n.p+"assets/add-user.d87fd7bdbcd69110487cade29b6cdab6.svg",hu=n.p+"assets/chevron-bottom.8fba8942b34b3f8d54820d2dfde94cc2.svg",pu=n.p+"assets/shield.498420bdf2ec5957adc2646fa892026d.svg",fu=n.p+"assets/vlc.12ce0b57b1b136a0150c3c5f147ef08f.svg",gu=n.p+"assets/volume-full.a74609ebaadf79cabc7fee7590f52793.svg",mu=n.p+"assets/file.71d04d960aa446d4672fc1f60cd462dc.svg";function _u(e,t,n,o,r,i,a){try{var s=e[i](a),u=s.value}catch(e){return void n(e)}s.done?t(u):Promise.resolve(u).then(o,r)}function Fu(e){return function(){var t=this,n=arguments;return new Promise((function(o,r){var i=e.apply(t,n);function a(e){_u(i,o,r,a,s,"next",e)}function s(e){_u(i,o,r,a,s,"throw",e)}a(void 0)}))}}function yu(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(e)){var n=[],o=!0,r=!1,i=void 0;try{for(var a,s=e[Symbol.iterator]();!(o=(a=s.next()).done)&&(n.push(a.value),!t||n.length!==t);o=!0);}catch(e){r=!0,i=e}finally{try{o||null==s.return||s.return()}finally{if(r)throw i}}return n}}(e,t)||bu(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function bu(e,t){if(e){if("string"==typeof e)return vu(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?vu(e,t):void 0}}function vu(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,o=new Array(t);n"))return null;var t=e.slice(e.indexOf("@")),n=t.slice(0,t.indexOf(">")),o=(t=t.slice(t.indexOf(">")+2)).slice(0,t.indexOf("\n\n"));return t=t.slice(t.indexOf("\n\n")+2),""===n?null:{userId:n,replyContent:o,content:t}}function Du(e){var t=e.current.scrollHeight-e.current.offsetHeight;e.current.scrollTop=t}function Su(e){var t=e.current;return t.scrollHeight-(t.scrollTop+t.offsetHeight)<=e.current.lastElementChild.lastElementChild.lastElementChild.offsetHeight+48}function xu(e){var t,n=e.roomId,r=Qe.matrixClient,i=r.getRoom(n).getAvatarUrl(r.baseUrl,36,36,"crop"),a=r.getRoom(n).name,s=Qe.roomList.directs.has(n),u=null===(t=r.getRoom(n).currentState.getStateEvents("m.room.topic")[0])||void 0===t?void 0:t.getContent().topic;return o.createElement(Hr,null,o.createElement(Sr,{imageSrc:i,text:a.slice(0,1),bgColor:gn(a),size:"small"}),o.createElement(Vr,null,o.createElement(vt,{variant:"h2"},a),void 0!==u&&o.createElement("p",{title:u,className:"text text-b3"},u)),o.createElement(Yr,{onClick:dn,tooltip:"People",src:Lr}),o.createElement(Ir,{placement:"bottom",content:function(e){return o.createElement(o.Fragment,null,o.createElement(Mr,null,"Options"),o.createElement(Or,{iconSrc:du,onClick:function(){pn(n),e()}},"Invite"),o.createElement(Or,{iconSrc:Ga,variant:"danger",onClick:function(){return Ni(n,s)}},"Leave"))},render:function(e){return o.createElement(Yr,{onClick:e,tooltip:"Options",src:uu})}}))}xu.propTypes={roomId:l().string.isRequired};var Cu=!0;function Au(e){var t,n=e.roomId,r=e.roomTimeline,i=e.timelineScroll,a=yu((0,o.useState)(!1),2),s=a[0],u=a[1],c=yu((0,o.useState)(null),2),l=c[0],d=c[1],h=yu((0,o.useState)(null),2),p=h[0],f=h[1],g=Qe.matrixClient;function m(){!0!==i.isScrollable()&&r.paginateBack()}function _(){var e=r.room,t=r.timeline;ut(e)&&0!==t.length&&g.sendReadReceipt(t[t.length-1])}function F(){r.isOngoingPagination||s||r.paginateBack()}function y(e){Cu=e,e&&_()}var b=function(e){e?(f({}),m()):u(!0)},v=function(){Cu&&_(),d({})};(0,o.useEffect)((function(){u(!1),Cu=!0}),[n]),(0,o.useEffect)((function(){return _()}),[r]),(0,o.useEffect)((function(){return r.on(se.events.roomTimeline.EVENT,v),r.on(se.events.roomTimeline.PAGINATED,b),wu.on("reached-top",F),wu.on("toggle-reached-bottom",y),function(){r.removeListener(se.events.roomTimeline.EVENT,v),r.removeListener(se.events.roomTimeline.PAGINATED,b),wu.removeListener("reached-top",F),wu.removeListener("toggle-reached-bottom",y)}}),[r,s,p]),(0,o.useLayoutEffect)((function(){i.reachBottom(),m()}),[r]),(0,o.useLayoutEffect)((function(){null!==p&&i.tryRestoringScroll()}),[p]),(0,o.useEffect)((function(){null!==l&&Cu&&i.reachBottom()}),[l]);var w=null,E=null===(t=r.room.currentState.getStateEvents("m.room.topic")[0])||void 0===t?void 0:t.getContent().topic;return o.createElement("div",{className:"channel-view__content"},o.createElement("div",{className:"timeline__wrapper"},"m.room.create"!==r.timeline[0].getType()&&!s&&o.createElement(o.Fragment,null,o.createElement(wa,{key:Math.random().toString(20).substr(2,6)}),o.createElement(wa,{key:Math.random().toString(20).substr(2,6)}),o.createElement(wa,{key:Math.random().toString(20).substr(2,6)})),"m.room.create"!==r.timeline[0].getType()&&s&&o.createElement(Xa,{key:Math.random().toString(20).substr(2,6),avatarSrc:r.room.getAvatarUrl(Qe.matrixClient.baseUrl,80,80,"crop"),name:r.room.name,heading:"Welcome to ".concat(r.room.name),desc:"This is the beginning of ".concat(r.room.name," channel.").concat(void 0!==E?" Topic: ".concat(E):"")}),r.timeline.map((function(e){var t;if("m.room.create"===e.getType()){var n,i=null===(n=r.room.currentState.getStateEvents("m.room.topic")[0])||void 0===n?void 0:n.getContent().topic;return o.createElement(Xa,{key:e.getId(),avatarSrc:r.room.getAvatarUrl(Qe.matrixClient.baseUrl,80,80,"crop"),name:r.room.name,heading:"Welcome to ".concat(r.room.name),desc:"This is the beginning of ".concat(r.room.name," channel.").concat(void 0!==i?" Topic: ".concat(i):""),time:"Created at ".concat(vi()(e.getDate(),"dd mmmm yyyy, hh:MM TT"))})}if("m.room.message"!==e.getType()&&"m.room.encrypted"!==e.getType()&&"m.room.member"!==e.getType())return!1;if("m.replace"===(null===(t=e.getRelation())||void 0===t?void 0:t.rel_type))return!1;if(e.isRedacted())return!1;var a,s,u,c,l,d,h,p=null;if(null!==w&&(a=e.getDate(),s=w.getDate(),a.getDay()!==s.getDay()||a.getMonth()!==s.getMonth()||a.getYear()!==s.getYear())&&(p=o.createElement(Ki,{key:"divider-".concat(e.getId()),text:"".concat(vi()(e.getDate(),"mmmm dd, yyyy"))})),"m.room.member"!==e.getType()){var f,m=null!==w&&"m.room.member"!==w.getType()&&function(e,t){var n=(e.getTime()-t.getTime())/1e3;return n/=60,Math.abs(Math.round(n))}(e.getDate(),w.getDate())<=5&&w.getSender()===e.getSender(),_=e.getContent().body;if(void 0===_)return null;var F=null,y=null,b="org.matrix.custom.html"===e.getContent().format,v=void 0!==(null===(f=e.getWireContent()["m.relates_to"])||void 0===f?void 0:f["m.in_reply_to"]),E=r.editedTimeline.has(e.getId()),k=r.reactionTimeline.has(e.getId());if(v){var D=ku(_);if(null!==D){var S=it(D.userId);F={color:gn(D.userId),to:S,content:D.replyContent},_=D.content}}if(E){var x=r.editedTimeline.get(e.getId()),C=x[x.length-1];if(void 0===C.getContent()["m.new_content"])return null;var A=C.getContent()["m.new_content"].body,T=ku(A);b="org.matrix.custom.html"===C.getContent()["m.new_content"].format,_=null===T?A:T.content}k&&(y=[],r.reactionTimeline.get(e.getId()).forEach((function(e){if(null!==e.getRelation())if(function(e){for(var t=0;te}};return o.createElement("div",{className:"channel-view"},o.createElement(xu,{roomId:t}),o.createElement("div",{className:"channel-view__content-wrapper"},o.createElement("div",{className:"channel-view__scrollable"},o.createElement(Fn,{onScroll:function(e){var t=e.target,n=t.scrollTop,o=t.scrollHeight;if(t.offsetHeight,Bu=n,Nu=o,!Lu&&Su(a)&&(Lu=!0,wu.emit("toggle-reached-bottom",!0)),Lu&&!Su(a)&&(Lu=!1,wu.emit("toggle-reached-bottom",!1)),n<288&&!1===Pu)return Pu=!0,void wu.emit("reached-top");Pu=!1},ref:a,autoHide:!0},null!==r&&o.createElement(Au,{roomId:t,roomTimeline:r,timelineScroll:s})),null!==r&&o.createElement(Tu,{roomId:t,roomTimeline:r,timelineScroll:s})),null!==r&&o.createElement(Ru,null,o.createElement(Mu,{roomId:t,roomTimeline:r,timelineScroll:s}),o.createElement(Ou,{roomId:t,roomTimeline:r}))))}Uu.propTypes={roomId:l().string.isRequired};const ju=Uu;function qu(e){var t=e.avatarSrc,n=e.name,r=e.color,i=e.peopleRole,a=e.onClick;return o.createElement("div",{className:"people-selector__container"},o.createElement("button",{className:"people-selector",onMouseUp:function(e){return Dt(e,".people-selector")},onClick:a,type:"button"},o.createElement(Sr,{imageSrc:t,text:n.slice(0,1),bgColor:r,size:"extra-small"}),o.createElement(vt,{className:"people-selector__name",variant:"b1"},n),null!==i&&o.createElement(vt,{className:"people-selector__role",variant:"b3"},i)))}qu.defaultProps={avatarSrc:null,peopleRole:null},qu.propTypes={avatarSrc:l().string,name:l().string.isRequired,color:l().string.isRequired,peopleRole:l().string,onClick:l().func.isRequired};const zu=qu;function Ku(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,o=new Array(t);no.toLowerCase()?1:0}function Hu(e,t){var n=String(e.powerLevel),o=String(t.powerLevel);return"100"===n&&(n="90.9"),"100"===o&&(o="90.9"),n.toLowerCase()>o.toLowerCase()?-1:n.toLowerCase()e.length)&&(t=e.length);for(var n=0,o=new Array(t);ne.length)&&(t=e.length);for(var n=0,o=new Array(t);ne.length)&&(t=e.length);for(var n=0,o=new Array(t);ne.length)&&(t=e.length);for(var n=0,o=new Array(t);ne.length)&&(t=e.length);for(var n=0,o=new Array(t);n1,c(!0),h({username:t}),!n){e.next=19;break}return e.prev=7,e.next=10,I.getProfileInfo(t);case 10:o=e.sent,g([{user_id:t,display_name:o.displayname,avatar_url:o.avatar_url}]),e.next=17;break;case 14:e.prev=14,e.t0=e.catch(7),h({error:"".concat(t," not found!")});case 17:e.next=33;break;case 19:return e.prev=19,e.next=22,I.searchUserDirectory({term:t,limit:20});case 22:if(0!==(r=e.sent).results.length){e.next=27;break}return h({error:'No matches found for "'.concat(t,'"!')}),c(!1),e.abrupt("return");case 27:g(r.results),e.next=33;break;case 30:e.prev=30,e.t1=e.catch(19),h({error:"Something went wrong!"});case 33:c(!1);case 34:case"end":return e.stop()}}),e,null,[[7,14],[19,30]])})))).apply(this,arguments)}function P(){return(P=Cc(regeneratorRuntime.mark((function e(t){var n;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(I.getUserId()!==t){e.next=2;break}return e.abrupt("return");case 2:return e.prev=2,O(t),b.delete(t),v(M(b)),e.next=8,Li({isPublic:!1,isEncrypted:!0,isDirect:!0,invite:[t]});case 8:n=e.sent,S.set(n.room_id,t),x(M(S)),e.next=18;break;case 13:e.prev=13,e.t0=e.catch(2),B(t),"string"==typeof e.t0.message?b.set(t,e.t0.message):b.set(t,"Something went wrong!"),v(M(b));case 18:case"end":return e.stop()}}),e,null,[[2,13]])})))).apply(this,arguments)}function U(){return(U=Cc(regeneratorRuntime.mark((function e(t){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(void 0!==i){e.next=2;break}return e.abrupt("return");case 2:return e.prev=2,O(t),b.delete(t),v(M(b)),e.next=8,Ui(i,t);case 8:A.add(t),T(new Set(Array.from(A))),B(t),e.next=18;break;case 13:e.prev=13,e.t0=e.catch(2),B(t),"string"==typeof e.t0.message?b.set(t,e.t0.message):b.set(t,"Something went wrong!"),v(M(b));case 18:case"end":return e.stop()}}),e,null,[[2,13]])})))).apply(this,arguments)}return(0,o.useEffect)((function(){return function(){c(!1),h({}),g([]),F(new Set),v(new Map),k(new Map),x(new Map),T(new Set)}}),[r]),(0,o.useEffect)((function(){return Qe.roomList.on(se.events.roomList.ROOM_CREATED,N),function(){Qe.roomList.removeListener(se.events.roomList.ROOM_CREATED,N)}}),[r,_,E,S]),o.createElement(rc,{isOpen:r,title:"string"==typeof i?"Invite to ".concat(I.getRoom(i).name):"Direct message",contentOptions:o.createElement(Yr,{src:sc,onClick:a,tooltip:"Close"}),onRequestClose:a},o.createElement("div",{className:"invite-user"},o.createElement("form",{className:"invite-user__form",onSubmit:function(e){e.preventDefault(),function(){L.apply(this,arguments)}()}},o.createElement(Tt,{forwardRef:R,label:"Username or userId"}),o.createElement(xt,{disabled:u,iconSrc:Lr,variant:"primary",type:"submit"},"Search")),o.createElement("div",{className:"invite-user__search-status"},void 0!==d.username&&u&&o.createElement("div",{className:"flex--center"},o.createElement(It,{size:"small"}),o.createElement(vt,{variant:"b2"},'Searching for user "'.concat(d.username,'"...'))),void 0!==d.username&&!u&&o.createElement(vt,{variant:"b2"},'Search result for user "'.concat(d.username,'"')),d.error&&o.createElement(vt,{className:"invite-user__search-error",variant:"b2"},d.error)),0!==f.length&&o.createElement("div",{className:"invite-user__content"},(t=function(e){var t=function(e,t){return o.createElement(vt,{variant:"b2"},o.createElement("span",{style:{color:t?"var(--bg-positive)":"var(--bg-negative)"}},e))};if(I.getUserId()===e)return null;if(_.has(e))return o.createElement(It,{size:"small"});if(E.has(e))return o.createElement(xt,{onClick:function(){ln(E.get(e)),a()}},"Open");if(A.has(e))return t("Invited",!0);if("string"==typeof i){var n=I.getRoom(i).getMember(e);if(null!==n)switch(n.membership){case"join":return t("Already joined",!0);case"invite":return t("Already Invited",!0);case"ban":return t("Banned",!1)}}return"string"==typeof i?o.createElement(xt,{onClick:function(){return function(e){return U.apply(this,arguments)}(e)},variant:"primary"},"Invite"):o.createElement(xt,{onClick:function(){return function(e){return P.apply(this,arguments)}(e)},variant:"primary"},"Message")},n=function(e){return b.has(e)?o.createElement(vt,{variant:"b2"},o.createElement("span",{style:{color:"var(--bg-danger)"}},b.get(e))):null},f.map((function(e){var r=e.user_id,i="string"==typeof e.display_name?e.display_name:r;return o.createElement(ac,{key:r,avatarSrc:"string"==typeof e.avatar_url?I.mxcUrlToHttp(e.avatar_url,42,42,"crop"):null,name:i,id:r,options:t(r),desc:n(r)})}))))))}Rc.defaultProps={roomId:void 0},Rc.propTypes={isOpen:l().bool.isRequired,roomId:l().string,onRequestClose:l().func.isRequired};const Ic=Rc;function Mc(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,o=new Array(t);ne.length)&&(t=e.length);for(var n=0,o=new Array(t);ne.length)&&(t=e.length);for(var n=0,o=new Array(t);n{"use strict";e.exports=function(e){if(e)throw e}},58162:(e,t,n)=>{"use strict";var o=n(89509).Buffer;e.exports=function(e){if(e.length>=255)throw new TypeError("Alphabet too long");for(var t=new Uint8Array(256),n=0;n>>0,l=new Uint8Array(a);e[n];){var d=t[e.charCodeAt(n)];if(255===d)return;for(var h=0,p=a-1;(0!==d||h>>0,l[p]=d%256>>>0,d=d/256>>>0;if(0!==d)throw new Error("Non-zero carry");i=h,n++}if(" "!==e[n]){for(var f=a-i;f!==a&&0===l[f];)f++;var g=o.allocUnsafe(r+(a-f));g.fill(0,0,r);for(var m=r;f!==a;)g[m++]=l[f++];return g}}}return{encode:function(t){if((Array.isArray(t)||t instanceof Uint8Array)&&(t=o.from(t)),!o.isBuffer(t))throw new TypeError("Expected Buffer");if(0===t.length)return"";for(var n=0,r=0,i=0,a=t.length;i!==a&&0===t[i];)i++,n++;for(var c=(a-i)*l+1>>>0,d=new Uint8Array(c);i!==a;){for(var h=t[i],p=0,f=c-1;(0!==h||p>>0,d[f]=h%s>>>0,h=h/s>>>0;if(0!==h)throw new Error("Non-zero carry");r=p,i++}for(var g=c-r;g!==c&&0===d[g];)g++;for(var m=u.repeat(n);g{"use strict";t.byteLength=function(e){var t=u(e),n=t[0],o=t[1];return 3*(n+o)/4-o},t.toByteArray=function(e){var t,n,i=u(e),a=i[0],s=i[1],c=new r(function(e,t,n){return 3*(t+n)/4-n}(0,a,s)),l=0,d=s>0?a-4:a;for(n=0;n>16&255,c[l++]=t>>8&255,c[l++]=255&t;return 2===s&&(t=o[e.charCodeAt(n)]<<2|o[e.charCodeAt(n+1)]>>4,c[l++]=255&t),1===s&&(t=o[e.charCodeAt(n)]<<10|o[e.charCodeAt(n+1)]<<4|o[e.charCodeAt(n+2)]>>2,c[l++]=t>>8&255,c[l++]=255&t),c},t.fromByteArray=function(e){for(var t,o=e.length,r=o%3,i=[],a=16383,s=0,u=o-r;su?u:s+a));return 1===r?(t=e[o-1],i.push(n[t>>2]+n[t<<4&63]+"==")):2===r&&(t=(e[o-2]<<8)+e[o-1],i.push(n[t>>10]+n[t>>4&63]+n[t<<2&63]+"=")),i.join("")};for(var n=[],o=[],r="undefined"!=typeof Uint8Array?Uint8Array:Array,i="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",a=0,s=i.length;a0)throw new Error("Invalid string. Length must be a multiple of 4");var n=e.indexOf("=");return-1===n&&(n=t),[n,n===t?0:4-n%4]}function c(e,t,o){for(var r,i,a=[],s=t;s>18&63]+n[i>>12&63]+n[i>>6&63]+n[63&i]);return a.join("")}o["-".charCodeAt(0)]=62,o["_".charCodeAt(0)]=63},10022:(e,t,n)=>{var o=n(97631).Duplex;function r(e){if(!(this instanceof r))return new r(e);if(this._bufs=[],this.length=0,"function"==typeof e){this._callback=e;var t=function(e){this._callback&&(this._callback(e),this._callback=null)}.bind(this);this.on("pipe",(function(e){e.on("error",t)})),this.on("unpipe",(function(e){e.removeListener("error",t)}))}else Buffer.isBuffer(e)?this.append(e):Array.isArray(e)&&e.forEach(function(e){Buffer.isBuffer(e)&&this.append(e)}.bind(this));o.call(this)}n(89539).inherits(r,o),r.prototype._offset=function(e){for(var t,n=0,o=0;othis.length)&&(o=this.length),n>=this.length)return e||new Buffer(0);if(o<=0)return e||new Buffer(0);var r,i,a=!!e,s=this._offset(n),u=o-n,c=u,l=a&&t||0,d=s[1];if(0===n&&o==this.length){if(!a)return Buffer.concat(this._bufs);for(i=0;i(r=this._bufs[i].length-d))){this._bufs[i].copy(e,l,d,d+c);break}this._bufs[i].copy(e,l,d),l+=r,c-=r,d&&(d=0)}return e},r.prototype.toString=function(e,t,n){return this.slice(t,n).toString(e)},r.prototype.consume=function(e){for(;this._bufs.length;){if(!(e>this._bufs[0].length)){this._bufs[0]=this._bufs[0].slice(e),this.length-=e;break}e-=this._bufs[0].length,this.length-=this._bufs[0].length,this._bufs.shift()}return this},r.prototype.duplicate=function(){for(var e=0,t=new r;e{e.exports=Array.isArray||function(e){return"[object Array]"==Object.prototype.toString.call(e)}},6510:(e,t,n)=>{e.exports=s;var o=Object.keys||function(e){var t=[];for(var n in e)t.push(n);return t},r=n(16497);r.inherits=n(35717);var i=n(42813),a=n(79850);function s(e){if(!(this instanceof s))return new s(e);i.call(this,e),a.call(this,e),e&&!1===e.readable&&(this.readable=!1),e&&!1===e.writable&&(this.writable=!1),this.allowHalfOpen=!0,e&&!1===e.allowHalfOpen&&(this.allowHalfOpen=!1),this.once("end",u)}function u(){this.allowHalfOpen||this._writableState.ended||process.nextTick(this.end.bind(this))}r.inherits(s,i),function(e,t){for(var n=0,o=e.length;n{e.exports=i;var o=n(14059),r=n(16497);function i(e){if(!(this instanceof i))return new i(e);o.call(this,e)}r.inherits=n(35717),r.inherits(i,o),i.prototype._transform=function(e,t,n){n(null,e)}},42813:(e,t,n)=>{e.exports=l;var o=n(50430),r=n(48764).Buffer;l.ReadableState=c;var i=n(17187).EventEmitter;i.listenerCount||(i.listenerCount=function(e,t){return e.listeners(t).length});var a,s=n(42830),u=n(16497);function c(e,t){var o=(e=e||{}).highWaterMark;this.highWaterMark=o||0===o?o:16384,this.highWaterMark=~~this.highWaterMark,this.buffer=[],this.length=0,this.pipes=null,this.pipesCount=0,this.flowing=!1,this.ended=!1,this.endEmitted=!1,this.reading=!1,this.calledRead=!1,this.sync=!0,this.needReadable=!1,this.emittedReadable=!1,this.readableListening=!1,this.objectMode=!!e.objectMode,this.defaultEncoding=e.defaultEncoding||"utf8",this.ranOut=!1,this.awaitDrain=0,this.readingMore=!1,this.decoder=null,this.encoding=null,e.encoding&&(a||(a=n(75159).s),this.decoder=new a(e.encoding),this.encoding=e.encoding)}function l(e){if(!(this instanceof l))return new l(e);this._readableState=new c(e,this),this.readable=!0,s.call(this)}function d(e,t,n,o,i){var a=function(e,t){var n=null;return r.isBuffer(t)||"string"==typeof t||null==t||e.objectMode||(n=new TypeError("Invalid non-string/buffer chunk")),n}(t,n);if(a)e.emit("error",a);else if(null==n)t.reading=!1,t.ended||function(e,t){if(t.decoder&&!t.ended){var n=t.decoder.end();n&&n.length&&(t.buffer.push(n),t.length+=t.objectMode?1:n.length)}t.ended=!0,t.length>0?f(e):b(e)}(e,t);else if(t.objectMode||n&&n.length>0)if(t.ended&&!i){var s=new Error("stream.push() after EOF");e.emit("error",s)}else t.endEmitted&&i?(s=new Error("stream.unshift() after end event"),e.emit("error",s)):(!t.decoder||i||o||(n=t.decoder.write(n)),t.length+=t.objectMode?1:n.length,i?t.buffer.unshift(n):(t.reading=!1,t.buffer.push(n)),t.needReadable&&f(e),function(e,t){t.readingMore||(t.readingMore=!0,process.nextTick((function(){!function(e,t){for(var n=t.length;!t.reading&&!t.flowing&&!t.ended&&t.lengtht.highWaterMark&&(t.highWaterMark=function(e){if(e>=h)e=h;else{e--;for(var t=1;t<32;t<<=1)e|=e>>t;e++}return e}(e)),e>t.length?t.ended?t.length:(t.needReadable=!0,0):e)}function f(e){var t=e._readableState;t.needReadable=!1,t.emittedReadable||(t.emittedReadable=!0,t.sync?process.nextTick((function(){g(e)})):g(e))}function g(e){e.emit("readable")}function m(e){var t,n=e._readableState;function o(e,o,r){!1===e.write(t)&&n.awaitDrain++}for(n.awaitDrain=0;n.pipesCount&&null!==(t=e.read());)if(1===n.pipesCount?o(n.pipes):v(n.pipes,o),e.emit("data",t),n.awaitDrain>0)return;if(0===n.pipesCount)return n.flowing=!1,void(i.listenerCount(e,"data")>0&&F(e));n.ranOut=!0}function _(){this._readableState.ranOut&&(this._readableState.ranOut=!1,m(this))}function F(e,t){if(e._readableState.flowing)throw new Error("Cannot switch to old mode now.");var n=t||!1,o=!1;e.readable=!0,e.pipe=s.prototype.pipe,e.on=e.addListener=s.prototype.on,e.on("readable",(function(){var t;for(o=!0;!n&&null!==(t=e.read());)e.emit("data",t);null===t&&(o=!1,e._readableState.needReadable=!0)})),e.pause=function(){n=!0,this.emit("pause")},e.resume=function(){n=!1,o?process.nextTick((function(){e.emit("readable")})):this.read(0),this.emit("resume")},e.emit("readable")}function y(e,t){var n,o=t.buffer,i=t.length,a=!!t.decoder,s=!!t.objectMode;if(0===o.length)return null;if(0===i)n=null;else if(s)n=o.shift();else if(!e||e>=i)n=a?o.join(""):r.concat(o,i),o.length=0;else if(e0)throw new Error("endReadable called on non-empty stream");!t.endEmitted&&t.calledRead&&(t.ended=!0,process.nextTick((function(){t.endEmitted||0!==t.length||(t.endEmitted=!0,e.readable=!1,e.emit("end"))})))}function v(e,t){for(var n=0,o=e.length;n0)&&(t.emittedReadable=!1),0===e&&t.needReadable&&(t.length>=t.highWaterMark||t.ended))return f(this),null;if(0===(e=p(e,t))&&t.ended)return n=null,t.length>0&&t.decoder&&(n=y(e,t),t.length-=n.length),0===t.length&&b(this),n;var r=t.needReadable;return t.length-e<=t.highWaterMark&&(r=!0),(t.ended||t.reading)&&(r=!1),r&&(t.reading=!0,t.sync=!0,0===t.length&&(t.needReadable=!0),this._read(t.highWaterMark),t.sync=!1),r&&!t.reading&&(e=p(o,t)),null===(n=e>0?y(e,t):null)&&(t.needReadable=!0,e=0),t.length-=e,0!==t.length||t.ended||(t.needReadable=!0),t.ended&&!t.endEmitted&&0===t.length&&b(this),n},l.prototype._read=function(e){this.emit("error",new Error("not implemented"))},l.prototype.pipe=function(e,t){var n=this,r=this._readableState;switch(r.pipesCount){case 0:r.pipes=e;break;case 1:r.pipes=[r.pipes,e];break;default:r.pipes.push(e)}r.pipesCount+=1;var a=t&&!1===t.end||e===process.stdout||e===process.stderr?l:u;function s(e){e===n&&l()}function u(){e.end()}r.endEmitted?process.nextTick(a):n.once("end",a),e.on("unpipe",s);var c=function(e){return function(){var t=e._readableState;t.awaitDrain--,0===t.awaitDrain&&m(e)}}(n);function l(){e.removeListener("close",h),e.removeListener("finish",p),e.removeListener("drain",c),e.removeListener("error",d),e.removeListener("unpipe",s),n.removeListener("end",u),n.removeListener("end",l),e._writableState&&!e._writableState.needDrain||c()}function d(t){f(),e.removeListener("error",d),0===i.listenerCount(e,"error")&&e.emit("error",t)}function h(){e.removeListener("finish",p),f()}function p(){e.removeListener("close",h),f()}function f(){n.unpipe(e)}return e.on("drain",c),e._events&&e._events.error?o(e._events.error)?e._events.error.unshift(d):e._events.error=[d,e._events.error]:e.on("error",d),e.once("close",h),e.once("finish",p),e.emit("pipe",n),r.flowing||(this.on("readable",_),r.flowing=!0,process.nextTick((function(){m(n)}))),e},l.prototype.unpipe=function(e){var t=this._readableState;if(0===t.pipesCount)return this;if(1===t.pipesCount)return e&&e!==t.pipes||(e||(e=t.pipes),t.pipes=null,t.pipesCount=0,this.removeListener("readable",_),t.flowing=!1,e&&e.emit("unpipe",this)),this;if(!e){var n=t.pipes,o=t.pipesCount;t.pipes=null,t.pipesCount=0,this.removeListener("readable",_),t.flowing=!1;for(var r=0;r{e.exports=a;var o=n(6510),r=n(16497);function i(e,t){this.afterTransform=function(e,n){return function(e,t,n){var o=e._transformState;o.transforming=!1;var r=o.writecb;if(!r)return e.emit("error",new Error("no writecb in Transform class"));o.writechunk=null,o.writecb=null,null!=n&&e.push(n),r&&r(t);var i=e._readableState;i.reading=!1,(i.needReadable||i.length{e.exports=u;var o=n(48764).Buffer;u.WritableState=s;var r=n(16497);r.inherits=n(35717);var i=n(42830);function a(e,t,n){this.chunk=e,this.encoding=t,this.callback=n}function s(e,t){var n=(e=e||{}).highWaterMark;this.highWaterMark=n||0===n?n:16384,this.objectMode=!!e.objectMode,this.highWaterMark=~~this.highWaterMark,this.needDrain=!1,this.ending=!1,this.ended=!1,this.finished=!1;var o=!1===e.decodeStrings;this.decodeStrings=!o,this.defaultEncoding=e.defaultEncoding||"utf8",this.length=0,this.writing=!1,this.sync=!0,this.bufferProcessing=!1,this.onwrite=function(e){!function(e,t){var n=e._writableState,o=n.sync,r=n.writecb;if(function(e){e.writing=!1,e.writecb=null,e.length-=e.writelen,e.writelen=0}(n),t)!function(e,t,n,o,r){n?process.nextTick((function(){r(o)})):r(o),e._writableState.errorEmitted=!0,e.emit("error",o)}(e,0,o,t,r);else{var i=d(0,n);i||n.bufferProcessing||!n.buffer.length||function(e,t){t.bufferProcessing=!0;for(var n=0;n{var o=n(42830);(t=e.exports=n(42813)).Stream=o,t.Readable=t,t.Writable=n(79850),t.Duplex=n(6510),t.Transform=n(14059),t.PassThrough=n(4586),process.browser||"disable"!==process.env.READABLE_STREAM||(e.exports=n(42830))},75159:(e,t,n)=>{var o=n(48764).Buffer,r=o.isEncoding||function(e){switch(e&&e.toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":case"raw":return!0;default:return!1}},i=t.s=function(e){switch(this.encoding=(e||"utf8").toLowerCase().replace(/[-_]/,""),function(e){if(e&&!r(e))throw new Error("Unknown encoding: "+e)}(e),this.encoding){case"utf8":this.surrogateSize=3;break;case"ucs2":case"utf16le":this.surrogateSize=2,this.detectIncompleteChar=s;break;case"base64":this.surrogateSize=3,this.detectIncompleteChar=u;break;default:return void(this.write=a)}this.charBuffer=new o(6),this.charReceived=0,this.charLength=0};function a(e){return e.toString(this.encoding)}function s(e){this.charReceived=e.length%2,this.charLength=this.charReceived?2:0}function u(e){this.charReceived=e.length%3,this.charLength=this.charReceived?3:0}i.prototype.write=function(e){for(var t="";this.charLength;){var n=e.length>=this.charLength-this.charReceived?this.charLength-this.charReceived:e.length;if(e.copy(this.charBuffer,this.charReceived,0,n),this.charReceived+=n,this.charReceived=55296&&o<=56319)){if(this.charReceived=this.charLength=0,0===e.length)return t;break}this.charLength+=this.surrogateSize,t=""}this.detectIncompleteChar(e);var o,r=e.length;if(this.charLength&&(e.copy(this.charBuffer,0,e.length-this.charReceived,r),r-=this.charReceived),r=(t+=e.toString(this.encoding,0,r)).length-1,(o=t.charCodeAt(r))>=55296&&o<=56319){var i=this.surrogateSize;return this.charLength+=i,this.charReceived+=i,this.charBuffer.copy(this.charBuffer,i,0,i),e.copy(this.charBuffer,0,0,i),t.substring(0,r)}return t},i.prototype.detectIncompleteChar=function(e){for(var t=e.length>=3?3:e.length;t>0;t--){var n=e[e.length-t];if(1==t&&n>>5==6){this.charLength=2;break}if(t<=2&&n>>4==14){this.charLength=3;break}if(t<=3&&n>>3==30){this.charLength=4;break}}this.charReceived=t},i.prototype.end=function(e){var t="";if(e&&e.length&&(t=this.write(e)),this.charReceived){var n=this.charReceived,o=this.charBuffer,r=this.encoding;t+=o.slice(0,n).toString(r)}return t}},13550:function(e,t,n){!function(e,t){"use strict";function o(e,t){if(!e)throw new Error(t||"Assertion failed")}function r(e,t){e.super_=t;var n=function(){};n.prototype=t.prototype,e.prototype=new n,e.prototype.constructor=e}function i(e,t,n){if(i.isBN(e))return e;this.negative=0,this.words=null,this.length=0,this.red=null,null!==e&&("le"!==t&&"be"!==t||(n=t,t=10),this._init(e||0,t||10,n||"be"))}var a;"object"==typeof e?e.exports=i:t.BN=i,i.BN=i,i.wordSize=26;try{a="undefined"!=typeof window&&void 0!==window.Buffer?window.Buffer:n(46601).Buffer}catch(e){}function s(e,t){var n=e.charCodeAt(t);return n>=48&&n<=57?n-48:n>=65&&n<=70?n-55:n>=97&&n<=102?n-87:void o(!1,"Invalid character in "+e)}function u(e,t,n){var o=s(e,n);return n-1>=t&&(o|=s(e,n-1)<<4),o}function c(e,t,n,r){for(var i=0,a=0,s=Math.min(e.length,n),u=t;u=49?c-49+10:c>=17?c-17+10:c,o(c>=0&&a0?e:t},i.min=function(e,t){return e.cmp(t)<0?e:t},i.prototype._init=function(e,t,n){if("number"==typeof e)return this._initNumber(e,t,n);if("object"==typeof e)return this._initArray(e,t,n);"hex"===t&&(t=16),o(t===(0|t)&&t>=2&&t<=36);var r=0;"-"===(e=e.toString().replace(/\s+/g,""))[0]&&(r++,this.negative=1),r=0;r-=3)a=e[r]|e[r-1]<<8|e[r-2]<<16,this.words[i]|=a<>>26-s&67108863,(s+=24)>=26&&(s-=26,i++);else if("le"===n)for(r=0,i=0;r>>26-s&67108863,(s+=24)>=26&&(s-=26,i++);return this._strip()},i.prototype._parseHex=function(e,t,n){this.length=Math.ceil((e.length-t)/6),this.words=new Array(this.length);for(var o=0;o=t;o-=2)r=u(e,t,o)<=18?(i-=18,a+=1,this.words[a]|=r>>>26):i+=8;else for(o=(e.length-t)%2==0?t+1:t;o=18?(i-=18,a+=1,this.words[a]|=r>>>26):i+=8;this._strip()},i.prototype._parseBase=function(e,t,n){this.words=[0],this.length=1;for(var o=0,r=1;r<=67108863;r*=t)o++;o--,r=r/t|0;for(var i=e.length-n,a=i%o,s=Math.min(i,i-a)+n,u=0,l=n;l1&&0===this.words[this.length-1];)this.length--;return this._normSign()},i.prototype._normSign=function(){return 1===this.length&&0===this.words[0]&&(this.negative=0),this},"undefined"!=typeof Symbol&&"function"==typeof Symbol.for)try{i.prototype[Symbol.for("nodejs.util.inspect.custom")]=d}catch(e){i.prototype.inspect=d}else i.prototype.inspect=d;function d(){return(this.red?""}var h=["","0","00","000","0000","00000","000000","0000000","00000000","000000000","0000000000","00000000000","000000000000","0000000000000","00000000000000","000000000000000","0000000000000000","00000000000000000","000000000000000000","0000000000000000000","00000000000000000000","000000000000000000000","0000000000000000000000","00000000000000000000000","000000000000000000000000","0000000000000000000000000"],p=[0,0,25,16,12,11,10,9,8,8,7,7,7,7,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5],f=[0,0,33554432,43046721,16777216,48828125,60466176,40353607,16777216,43046721,1e7,19487171,35831808,62748517,7529536,11390625,16777216,24137569,34012224,47045881,64e6,4084101,5153632,6436343,7962624,9765625,11881376,14348907,17210368,20511149,243e5,28629151,33554432,39135393,45435424,52521875,60466176];function g(e,t,n){n.negative=t.negative^e.negative;var o=e.length+t.length|0;n.length=o,o=o-1|0;var r=0|e.words[0],i=0|t.words[0],a=r*i,s=67108863&a,u=a/67108864|0;n.words[0]=s;for(var c=1;c>>26,d=67108863&u,h=Math.min(c,t.length-1),p=Math.max(0,c-e.length+1);p<=h;p++){var f=c-p|0;l+=(a=(r=0|e.words[f])*(i=0|t.words[p])+d)/67108864|0,d=67108863&a}n.words[c]=0|d,u=0|l}return 0!==u?n.words[c]=0|u:n.length--,n._strip()}i.prototype.toString=function(e,t){var n;if(t=0|t||1,16===(e=e||10)||"hex"===e){n="";for(var r=0,i=0,a=0;a>>24-r&16777215)||a!==this.length-1?h[6-u.length]+u+n:u+n,(r+=2)>=26&&(r-=26,a--)}for(0!==i&&(n=i.toString(16)+n);n.length%t!=0;)n="0"+n;return 0!==this.negative&&(n="-"+n),n}if(e===(0|e)&&e>=2&&e<=36){var c=p[e],l=f[e];n="";var d=this.clone();for(d.negative=0;!d.isZero();){var g=d.modrn(l).toString(e);n=(d=d.idivn(l)).isZero()?g+n:h[c-g.length]+g+n}for(this.isZero()&&(n="0"+n);n.length%t!=0;)n="0"+n;return 0!==this.negative&&(n="-"+n),n}o(!1,"Base should be between 2 and 36")},i.prototype.toNumber=function(){var e=this.words[0];return 2===this.length?e+=67108864*this.words[1]:3===this.length&&1===this.words[2]?e+=4503599627370496+67108864*this.words[1]:this.length>2&&o(!1,"Number can only safely store up to 53 bits"),0!==this.negative?-e:e},i.prototype.toJSON=function(){return this.toString(16,2)},a&&(i.prototype.toBuffer=function(e,t){return this.toArrayLike(a,e,t)}),i.prototype.toArray=function(e,t){return this.toArrayLike(Array,e,t)},i.prototype.toArrayLike=function(e,t,n){this._strip();var r=this.byteLength(),i=n||Math.max(1,r);o(r<=i,"byte array longer than desired length"),o(i>0,"Requested array length <= 0");var a=function(e,t){return e.allocUnsafe?e.allocUnsafe(t):new e(t)}(e,i);return this["_toArrayLike"+("le"===t?"LE":"BE")](a,r),a},i.prototype._toArrayLikeLE=function(e,t){for(var n=0,o=0,r=0,i=0;r>8&255),n>16&255),6===i?(n>24&255),o=0,i=0):(o=a>>>24,i+=2)}if(n=0&&(e[n--]=a>>8&255),n>=0&&(e[n--]=a>>16&255),6===i?(n>=0&&(e[n--]=a>>24&255),o=0,i=0):(o=a>>>24,i+=2)}if(n>=0)for(e[n--]=o;n>=0;)e[n--]=0},Math.clz32?i.prototype._countBits=function(e){return 32-Math.clz32(e)}:i.prototype._countBits=function(e){var t=e,n=0;return t>=4096&&(n+=13,t>>>=13),t>=64&&(n+=7,t>>>=7),t>=8&&(n+=4,t>>>=4),t>=2&&(n+=2,t>>>=2),n+t},i.prototype._zeroBits=function(e){if(0===e)return 26;var t=e,n=0;return 0==(8191&t)&&(n+=13,t>>>=13),0==(127&t)&&(n+=7,t>>>=7),0==(15&t)&&(n+=4,t>>>=4),0==(3&t)&&(n+=2,t>>>=2),0==(1&t)&&n++,n},i.prototype.bitLength=function(){var e=this.words[this.length-1],t=this._countBits(e);return 26*(this.length-1)+t},i.prototype.zeroBits=function(){if(this.isZero())return 0;for(var e=0,t=0;te.length?this.clone().ior(e):e.clone().ior(this)},i.prototype.uor=function(e){return this.length>e.length?this.clone().iuor(e):e.clone().iuor(this)},i.prototype.iuand=function(e){var t;t=this.length>e.length?e:this;for(var n=0;ne.length?this.clone().iand(e):e.clone().iand(this)},i.prototype.uand=function(e){return this.length>e.length?this.clone().iuand(e):e.clone().iuand(this)},i.prototype.iuxor=function(e){var t,n;this.length>e.length?(t=this,n=e):(t=e,n=this);for(var o=0;oe.length?this.clone().ixor(e):e.clone().ixor(this)},i.prototype.uxor=function(e){return this.length>e.length?this.clone().iuxor(e):e.clone().iuxor(this)},i.prototype.inotn=function(e){o("number"==typeof e&&e>=0);var t=0|Math.ceil(e/26),n=e%26;this._expand(t),n>0&&t--;for(var r=0;r0&&(this.words[r]=~this.words[r]&67108863>>26-n),this._strip()},i.prototype.notn=function(e){return this.clone().inotn(e)},i.prototype.setn=function(e,t){o("number"==typeof e&&e>=0);var n=e/26|0,r=e%26;return this._expand(n+1),this.words[n]=t?this.words[n]|1<e.length?(n=this,o=e):(n=e,o=this);for(var r=0,i=0;i>>26;for(;0!==r&&i>>26;if(this.length=n.length,0!==r)this.words[this.length]=r,this.length++;else if(n!==this)for(;ie.length?this.clone().iadd(e):e.clone().iadd(this)},i.prototype.isub=function(e){if(0!==e.negative){e.negative=0;var t=this.iadd(e);return e.negative=1,t._normSign()}if(0!==this.negative)return this.negative=0,this.iadd(e),this.negative=1,this._normSign();var n,o,r=this.cmp(e);if(0===r)return this.negative=0,this.length=1,this.words[0]=0,this;r>0?(n=this,o=e):(n=e,o=this);for(var i=0,a=0;a>26,this.words[a]=67108863&t;for(;0!==i&&a>26,this.words[a]=67108863&t;if(0===i&&a>>13,p=0|a[1],f=8191&p,g=p>>>13,m=0|a[2],_=8191&m,F=m>>>13,y=0|a[3],b=8191&y,v=y>>>13,w=0|a[4],E=8191&w,k=w>>>13,D=0|a[5],S=8191&D,x=D>>>13,C=0|a[6],A=8191&C,T=C>>>13,R=0|a[7],I=8191&R,M=R>>>13,O=0|a[8],B=8191&O,N=O>>>13,L=0|a[9],P=8191&L,U=L>>>13,j=0|s[0],q=8191&j,z=j>>>13,K=0|s[1],G=8191&K,$=K>>>13,H=0|s[2],V=8191&H,W=H>>>13,Y=0|s[3],Z=8191&Y,X=Y>>>13,J=0|s[4],Q=8191&J,ee=J>>>13,te=0|s[5],ne=8191&te,oe=te>>>13,re=0|s[6],ie=8191&re,ae=re>>>13,se=0|s[7],ue=8191&se,ce=se>>>13,le=0|s[8],de=8191&le,he=le>>>13,pe=0|s[9],fe=8191&pe,ge=pe>>>13;n.negative=e.negative^t.negative,n.length=19;var me=(c+(o=Math.imul(d,q))|0)+((8191&(r=(r=Math.imul(d,z))+Math.imul(h,q)|0))<<13)|0;c=((i=Math.imul(h,z))+(r>>>13)|0)+(me>>>26)|0,me&=67108863,o=Math.imul(f,q),r=(r=Math.imul(f,z))+Math.imul(g,q)|0,i=Math.imul(g,z);var _e=(c+(o=o+Math.imul(d,G)|0)|0)+((8191&(r=(r=r+Math.imul(d,$)|0)+Math.imul(h,G)|0))<<13)|0;c=((i=i+Math.imul(h,$)|0)+(r>>>13)|0)+(_e>>>26)|0,_e&=67108863,o=Math.imul(_,q),r=(r=Math.imul(_,z))+Math.imul(F,q)|0,i=Math.imul(F,z),o=o+Math.imul(f,G)|0,r=(r=r+Math.imul(f,$)|0)+Math.imul(g,G)|0,i=i+Math.imul(g,$)|0;var Fe=(c+(o=o+Math.imul(d,V)|0)|0)+((8191&(r=(r=r+Math.imul(d,W)|0)+Math.imul(h,V)|0))<<13)|0;c=((i=i+Math.imul(h,W)|0)+(r>>>13)|0)+(Fe>>>26)|0,Fe&=67108863,o=Math.imul(b,q),r=(r=Math.imul(b,z))+Math.imul(v,q)|0,i=Math.imul(v,z),o=o+Math.imul(_,G)|0,r=(r=r+Math.imul(_,$)|0)+Math.imul(F,G)|0,i=i+Math.imul(F,$)|0,o=o+Math.imul(f,V)|0,r=(r=r+Math.imul(f,W)|0)+Math.imul(g,V)|0,i=i+Math.imul(g,W)|0;var ye=(c+(o=o+Math.imul(d,Z)|0)|0)+((8191&(r=(r=r+Math.imul(d,X)|0)+Math.imul(h,Z)|0))<<13)|0;c=((i=i+Math.imul(h,X)|0)+(r>>>13)|0)+(ye>>>26)|0,ye&=67108863,o=Math.imul(E,q),r=(r=Math.imul(E,z))+Math.imul(k,q)|0,i=Math.imul(k,z),o=o+Math.imul(b,G)|0,r=(r=r+Math.imul(b,$)|0)+Math.imul(v,G)|0,i=i+Math.imul(v,$)|0,o=o+Math.imul(_,V)|0,r=(r=r+Math.imul(_,W)|0)+Math.imul(F,V)|0,i=i+Math.imul(F,W)|0,o=o+Math.imul(f,Z)|0,r=(r=r+Math.imul(f,X)|0)+Math.imul(g,Z)|0,i=i+Math.imul(g,X)|0;var be=(c+(o=o+Math.imul(d,Q)|0)|0)+((8191&(r=(r=r+Math.imul(d,ee)|0)+Math.imul(h,Q)|0))<<13)|0;c=((i=i+Math.imul(h,ee)|0)+(r>>>13)|0)+(be>>>26)|0,be&=67108863,o=Math.imul(S,q),r=(r=Math.imul(S,z))+Math.imul(x,q)|0,i=Math.imul(x,z),o=o+Math.imul(E,G)|0,r=(r=r+Math.imul(E,$)|0)+Math.imul(k,G)|0,i=i+Math.imul(k,$)|0,o=o+Math.imul(b,V)|0,r=(r=r+Math.imul(b,W)|0)+Math.imul(v,V)|0,i=i+Math.imul(v,W)|0,o=o+Math.imul(_,Z)|0,r=(r=r+Math.imul(_,X)|0)+Math.imul(F,Z)|0,i=i+Math.imul(F,X)|0,o=o+Math.imul(f,Q)|0,r=(r=r+Math.imul(f,ee)|0)+Math.imul(g,Q)|0,i=i+Math.imul(g,ee)|0;var ve=(c+(o=o+Math.imul(d,ne)|0)|0)+((8191&(r=(r=r+Math.imul(d,oe)|0)+Math.imul(h,ne)|0))<<13)|0;c=((i=i+Math.imul(h,oe)|0)+(r>>>13)|0)+(ve>>>26)|0,ve&=67108863,o=Math.imul(A,q),r=(r=Math.imul(A,z))+Math.imul(T,q)|0,i=Math.imul(T,z),o=o+Math.imul(S,G)|0,r=(r=r+Math.imul(S,$)|0)+Math.imul(x,G)|0,i=i+Math.imul(x,$)|0,o=o+Math.imul(E,V)|0,r=(r=r+Math.imul(E,W)|0)+Math.imul(k,V)|0,i=i+Math.imul(k,W)|0,o=o+Math.imul(b,Z)|0,r=(r=r+Math.imul(b,X)|0)+Math.imul(v,Z)|0,i=i+Math.imul(v,X)|0,o=o+Math.imul(_,Q)|0,r=(r=r+Math.imul(_,ee)|0)+Math.imul(F,Q)|0,i=i+Math.imul(F,ee)|0,o=o+Math.imul(f,ne)|0,r=(r=r+Math.imul(f,oe)|0)+Math.imul(g,ne)|0,i=i+Math.imul(g,oe)|0;var we=(c+(o=o+Math.imul(d,ie)|0)|0)+((8191&(r=(r=r+Math.imul(d,ae)|0)+Math.imul(h,ie)|0))<<13)|0;c=((i=i+Math.imul(h,ae)|0)+(r>>>13)|0)+(we>>>26)|0,we&=67108863,o=Math.imul(I,q),r=(r=Math.imul(I,z))+Math.imul(M,q)|0,i=Math.imul(M,z),o=o+Math.imul(A,G)|0,r=(r=r+Math.imul(A,$)|0)+Math.imul(T,G)|0,i=i+Math.imul(T,$)|0,o=o+Math.imul(S,V)|0,r=(r=r+Math.imul(S,W)|0)+Math.imul(x,V)|0,i=i+Math.imul(x,W)|0,o=o+Math.imul(E,Z)|0,r=(r=r+Math.imul(E,X)|0)+Math.imul(k,Z)|0,i=i+Math.imul(k,X)|0,o=o+Math.imul(b,Q)|0,r=(r=r+Math.imul(b,ee)|0)+Math.imul(v,Q)|0,i=i+Math.imul(v,ee)|0,o=o+Math.imul(_,ne)|0,r=(r=r+Math.imul(_,oe)|0)+Math.imul(F,ne)|0,i=i+Math.imul(F,oe)|0,o=o+Math.imul(f,ie)|0,r=(r=r+Math.imul(f,ae)|0)+Math.imul(g,ie)|0,i=i+Math.imul(g,ae)|0;var Ee=(c+(o=o+Math.imul(d,ue)|0)|0)+((8191&(r=(r=r+Math.imul(d,ce)|0)+Math.imul(h,ue)|0))<<13)|0;c=((i=i+Math.imul(h,ce)|0)+(r>>>13)|0)+(Ee>>>26)|0,Ee&=67108863,o=Math.imul(B,q),r=(r=Math.imul(B,z))+Math.imul(N,q)|0,i=Math.imul(N,z),o=o+Math.imul(I,G)|0,r=(r=r+Math.imul(I,$)|0)+Math.imul(M,G)|0,i=i+Math.imul(M,$)|0,o=o+Math.imul(A,V)|0,r=(r=r+Math.imul(A,W)|0)+Math.imul(T,V)|0,i=i+Math.imul(T,W)|0,o=o+Math.imul(S,Z)|0,r=(r=r+Math.imul(S,X)|0)+Math.imul(x,Z)|0,i=i+Math.imul(x,X)|0,o=o+Math.imul(E,Q)|0,r=(r=r+Math.imul(E,ee)|0)+Math.imul(k,Q)|0,i=i+Math.imul(k,ee)|0,o=o+Math.imul(b,ne)|0,r=(r=r+Math.imul(b,oe)|0)+Math.imul(v,ne)|0,i=i+Math.imul(v,oe)|0,o=o+Math.imul(_,ie)|0,r=(r=r+Math.imul(_,ae)|0)+Math.imul(F,ie)|0,i=i+Math.imul(F,ae)|0,o=o+Math.imul(f,ue)|0,r=(r=r+Math.imul(f,ce)|0)+Math.imul(g,ue)|0,i=i+Math.imul(g,ce)|0;var ke=(c+(o=o+Math.imul(d,de)|0)|0)+((8191&(r=(r=r+Math.imul(d,he)|0)+Math.imul(h,de)|0))<<13)|0;c=((i=i+Math.imul(h,he)|0)+(r>>>13)|0)+(ke>>>26)|0,ke&=67108863,o=Math.imul(P,q),r=(r=Math.imul(P,z))+Math.imul(U,q)|0,i=Math.imul(U,z),o=o+Math.imul(B,G)|0,r=(r=r+Math.imul(B,$)|0)+Math.imul(N,G)|0,i=i+Math.imul(N,$)|0,o=o+Math.imul(I,V)|0,r=(r=r+Math.imul(I,W)|0)+Math.imul(M,V)|0,i=i+Math.imul(M,W)|0,o=o+Math.imul(A,Z)|0,r=(r=r+Math.imul(A,X)|0)+Math.imul(T,Z)|0,i=i+Math.imul(T,X)|0,o=o+Math.imul(S,Q)|0,r=(r=r+Math.imul(S,ee)|0)+Math.imul(x,Q)|0,i=i+Math.imul(x,ee)|0,o=o+Math.imul(E,ne)|0,r=(r=r+Math.imul(E,oe)|0)+Math.imul(k,ne)|0,i=i+Math.imul(k,oe)|0,o=o+Math.imul(b,ie)|0,r=(r=r+Math.imul(b,ae)|0)+Math.imul(v,ie)|0,i=i+Math.imul(v,ae)|0,o=o+Math.imul(_,ue)|0,r=(r=r+Math.imul(_,ce)|0)+Math.imul(F,ue)|0,i=i+Math.imul(F,ce)|0,o=o+Math.imul(f,de)|0,r=(r=r+Math.imul(f,he)|0)+Math.imul(g,de)|0,i=i+Math.imul(g,he)|0;var De=(c+(o=o+Math.imul(d,fe)|0)|0)+((8191&(r=(r=r+Math.imul(d,ge)|0)+Math.imul(h,fe)|0))<<13)|0;c=((i=i+Math.imul(h,ge)|0)+(r>>>13)|0)+(De>>>26)|0,De&=67108863,o=Math.imul(P,G),r=(r=Math.imul(P,$))+Math.imul(U,G)|0,i=Math.imul(U,$),o=o+Math.imul(B,V)|0,r=(r=r+Math.imul(B,W)|0)+Math.imul(N,V)|0,i=i+Math.imul(N,W)|0,o=o+Math.imul(I,Z)|0,r=(r=r+Math.imul(I,X)|0)+Math.imul(M,Z)|0,i=i+Math.imul(M,X)|0,o=o+Math.imul(A,Q)|0,r=(r=r+Math.imul(A,ee)|0)+Math.imul(T,Q)|0,i=i+Math.imul(T,ee)|0,o=o+Math.imul(S,ne)|0,r=(r=r+Math.imul(S,oe)|0)+Math.imul(x,ne)|0,i=i+Math.imul(x,oe)|0,o=o+Math.imul(E,ie)|0,r=(r=r+Math.imul(E,ae)|0)+Math.imul(k,ie)|0,i=i+Math.imul(k,ae)|0,o=o+Math.imul(b,ue)|0,r=(r=r+Math.imul(b,ce)|0)+Math.imul(v,ue)|0,i=i+Math.imul(v,ce)|0,o=o+Math.imul(_,de)|0,r=(r=r+Math.imul(_,he)|0)+Math.imul(F,de)|0,i=i+Math.imul(F,he)|0;var Se=(c+(o=o+Math.imul(f,fe)|0)|0)+((8191&(r=(r=r+Math.imul(f,ge)|0)+Math.imul(g,fe)|0))<<13)|0;c=((i=i+Math.imul(g,ge)|0)+(r>>>13)|0)+(Se>>>26)|0,Se&=67108863,o=Math.imul(P,V),r=(r=Math.imul(P,W))+Math.imul(U,V)|0,i=Math.imul(U,W),o=o+Math.imul(B,Z)|0,r=(r=r+Math.imul(B,X)|0)+Math.imul(N,Z)|0,i=i+Math.imul(N,X)|0,o=o+Math.imul(I,Q)|0,r=(r=r+Math.imul(I,ee)|0)+Math.imul(M,Q)|0,i=i+Math.imul(M,ee)|0,o=o+Math.imul(A,ne)|0,r=(r=r+Math.imul(A,oe)|0)+Math.imul(T,ne)|0,i=i+Math.imul(T,oe)|0,o=o+Math.imul(S,ie)|0,r=(r=r+Math.imul(S,ae)|0)+Math.imul(x,ie)|0,i=i+Math.imul(x,ae)|0,o=o+Math.imul(E,ue)|0,r=(r=r+Math.imul(E,ce)|0)+Math.imul(k,ue)|0,i=i+Math.imul(k,ce)|0,o=o+Math.imul(b,de)|0,r=(r=r+Math.imul(b,he)|0)+Math.imul(v,de)|0,i=i+Math.imul(v,he)|0;var xe=(c+(o=o+Math.imul(_,fe)|0)|0)+((8191&(r=(r=r+Math.imul(_,ge)|0)+Math.imul(F,fe)|0))<<13)|0;c=((i=i+Math.imul(F,ge)|0)+(r>>>13)|0)+(xe>>>26)|0,xe&=67108863,o=Math.imul(P,Z),r=(r=Math.imul(P,X))+Math.imul(U,Z)|0,i=Math.imul(U,X),o=o+Math.imul(B,Q)|0,r=(r=r+Math.imul(B,ee)|0)+Math.imul(N,Q)|0,i=i+Math.imul(N,ee)|0,o=o+Math.imul(I,ne)|0,r=(r=r+Math.imul(I,oe)|0)+Math.imul(M,ne)|0,i=i+Math.imul(M,oe)|0,o=o+Math.imul(A,ie)|0,r=(r=r+Math.imul(A,ae)|0)+Math.imul(T,ie)|0,i=i+Math.imul(T,ae)|0,o=o+Math.imul(S,ue)|0,r=(r=r+Math.imul(S,ce)|0)+Math.imul(x,ue)|0,i=i+Math.imul(x,ce)|0,o=o+Math.imul(E,de)|0,r=(r=r+Math.imul(E,he)|0)+Math.imul(k,de)|0,i=i+Math.imul(k,he)|0;var Ce=(c+(o=o+Math.imul(b,fe)|0)|0)+((8191&(r=(r=r+Math.imul(b,ge)|0)+Math.imul(v,fe)|0))<<13)|0;c=((i=i+Math.imul(v,ge)|0)+(r>>>13)|0)+(Ce>>>26)|0,Ce&=67108863,o=Math.imul(P,Q),r=(r=Math.imul(P,ee))+Math.imul(U,Q)|0,i=Math.imul(U,ee),o=o+Math.imul(B,ne)|0,r=(r=r+Math.imul(B,oe)|0)+Math.imul(N,ne)|0,i=i+Math.imul(N,oe)|0,o=o+Math.imul(I,ie)|0,r=(r=r+Math.imul(I,ae)|0)+Math.imul(M,ie)|0,i=i+Math.imul(M,ae)|0,o=o+Math.imul(A,ue)|0,r=(r=r+Math.imul(A,ce)|0)+Math.imul(T,ue)|0,i=i+Math.imul(T,ce)|0,o=o+Math.imul(S,de)|0,r=(r=r+Math.imul(S,he)|0)+Math.imul(x,de)|0,i=i+Math.imul(x,he)|0;var Ae=(c+(o=o+Math.imul(E,fe)|0)|0)+((8191&(r=(r=r+Math.imul(E,ge)|0)+Math.imul(k,fe)|0))<<13)|0;c=((i=i+Math.imul(k,ge)|0)+(r>>>13)|0)+(Ae>>>26)|0,Ae&=67108863,o=Math.imul(P,ne),r=(r=Math.imul(P,oe))+Math.imul(U,ne)|0,i=Math.imul(U,oe),o=o+Math.imul(B,ie)|0,r=(r=r+Math.imul(B,ae)|0)+Math.imul(N,ie)|0,i=i+Math.imul(N,ae)|0,o=o+Math.imul(I,ue)|0,r=(r=r+Math.imul(I,ce)|0)+Math.imul(M,ue)|0,i=i+Math.imul(M,ce)|0,o=o+Math.imul(A,de)|0,r=(r=r+Math.imul(A,he)|0)+Math.imul(T,de)|0,i=i+Math.imul(T,he)|0;var Te=(c+(o=o+Math.imul(S,fe)|0)|0)+((8191&(r=(r=r+Math.imul(S,ge)|0)+Math.imul(x,fe)|0))<<13)|0;c=((i=i+Math.imul(x,ge)|0)+(r>>>13)|0)+(Te>>>26)|0,Te&=67108863,o=Math.imul(P,ie),r=(r=Math.imul(P,ae))+Math.imul(U,ie)|0,i=Math.imul(U,ae),o=o+Math.imul(B,ue)|0,r=(r=r+Math.imul(B,ce)|0)+Math.imul(N,ue)|0,i=i+Math.imul(N,ce)|0,o=o+Math.imul(I,de)|0,r=(r=r+Math.imul(I,he)|0)+Math.imul(M,de)|0,i=i+Math.imul(M,he)|0;var Re=(c+(o=o+Math.imul(A,fe)|0)|0)+((8191&(r=(r=r+Math.imul(A,ge)|0)+Math.imul(T,fe)|0))<<13)|0;c=((i=i+Math.imul(T,ge)|0)+(r>>>13)|0)+(Re>>>26)|0,Re&=67108863,o=Math.imul(P,ue),r=(r=Math.imul(P,ce))+Math.imul(U,ue)|0,i=Math.imul(U,ce),o=o+Math.imul(B,de)|0,r=(r=r+Math.imul(B,he)|0)+Math.imul(N,de)|0,i=i+Math.imul(N,he)|0;var Ie=(c+(o=o+Math.imul(I,fe)|0)|0)+((8191&(r=(r=r+Math.imul(I,ge)|0)+Math.imul(M,fe)|0))<<13)|0;c=((i=i+Math.imul(M,ge)|0)+(r>>>13)|0)+(Ie>>>26)|0,Ie&=67108863,o=Math.imul(P,de),r=(r=Math.imul(P,he))+Math.imul(U,de)|0,i=Math.imul(U,he);var Me=(c+(o=o+Math.imul(B,fe)|0)|0)+((8191&(r=(r=r+Math.imul(B,ge)|0)+Math.imul(N,fe)|0))<<13)|0;c=((i=i+Math.imul(N,ge)|0)+(r>>>13)|0)+(Me>>>26)|0,Me&=67108863;var Oe=(c+(o=Math.imul(P,fe))|0)+((8191&(r=(r=Math.imul(P,ge))+Math.imul(U,fe)|0))<<13)|0;return c=((i=Math.imul(U,ge))+(r>>>13)|0)+(Oe>>>26)|0,Oe&=67108863,u[0]=me,u[1]=_e,u[2]=Fe,u[3]=ye,u[4]=be,u[5]=ve,u[6]=we,u[7]=Ee,u[8]=ke,u[9]=De,u[10]=Se,u[11]=xe,u[12]=Ce,u[13]=Ae,u[14]=Te,u[15]=Re,u[16]=Ie,u[17]=Me,u[18]=Oe,0!==c&&(u[19]=c,n.length++),n};function _(e,t,n){n.negative=t.negative^e.negative,n.length=e.length+t.length;for(var o=0,r=0,i=0;i>>26)|0)>>>26,a&=67108863}n.words[i]=s,o=a,a=r}return 0!==o?n.words[i]=o:n.length--,n._strip()}function F(e,t,n){return _(e,t,n)}function y(e,t){this.x=e,this.y=t}Math.imul||(m=g),i.prototype.mulTo=function(e,t){var n=this.length+e.length;return 10===this.length&&10===e.length?m(this,e,t):n<63?g(this,e,t):n<1024?_(this,e,t):F(this,e,t)},y.prototype.makeRBT=function(e){for(var t=new Array(e),n=i.prototype._countBits(e)-1,o=0;o>=1;return o},y.prototype.permute=function(e,t,n,o,r,i){for(var a=0;a>>=1)r++;return 1<>>=13,n[2*a+1]=8191&i,i>>>=13;for(a=2*t;a>=26,n+=i/67108864|0,n+=a>>>26,this.words[r]=67108863&a}return 0!==n&&(this.words[r]=n,this.length++),t?this.ineg():this},i.prototype.muln=function(e){return this.clone().imuln(e)},i.prototype.sqr=function(){return this.mul(this)},i.prototype.isqr=function(){return this.imul(this.clone())},i.prototype.pow=function(e){var t=function(e){for(var t=new Array(e.bitLength()),n=0;n>>r&1}return t}(e);if(0===t.length)return new i(1);for(var n=this,o=0;o=0);var t,n=e%26,r=(e-n)/26,i=67108863>>>26-n<<26-n;if(0!==n){var a=0;for(t=0;t>>26-n}a&&(this.words[t]=a,this.length++)}if(0!==r){for(t=this.length-1;t>=0;t--)this.words[t+r]=this.words[t];for(t=0;t=0),r=t?(t-t%26)/26:0;var i=e%26,a=Math.min((e-i)/26,this.length),s=67108863^67108863>>>i<a)for(this.length-=a,c=0;c=0&&(0!==l||c>=r);c--){var d=0|this.words[c];this.words[c]=l<<26-i|d>>>i,l=d&s}return u&&0!==l&&(u.words[u.length++]=l),0===this.length&&(this.words[0]=0,this.length=1),this._strip()},i.prototype.ishrn=function(e,t,n){return o(0===this.negative),this.iushrn(e,t,n)},i.prototype.shln=function(e){return this.clone().ishln(e)},i.prototype.ushln=function(e){return this.clone().iushln(e)},i.prototype.shrn=function(e){return this.clone().ishrn(e)},i.prototype.ushrn=function(e){return this.clone().iushrn(e)},i.prototype.testn=function(e){o("number"==typeof e&&e>=0);var t=e%26,n=(e-t)/26,r=1<=0);var t=e%26,n=(e-t)/26;if(o(0===this.negative,"imaskn works only with positive numbers"),this.length<=n)return this;if(0!==t&&n++,this.length=Math.min(n,this.length),0!==t){var r=67108863^67108863>>>t<=67108864;t++)this.words[t]-=67108864,t===this.length-1?this.words[t+1]=1:this.words[t+1]++;return this.length=Math.max(this.length,t+1),this},i.prototype.isubn=function(e){if(o("number"==typeof e),o(e<67108864),e<0)return this.iaddn(-e);if(0!==this.negative)return this.negative=0,this.iaddn(e),this.negative=1,this;if(this.words[0]-=e,1===this.length&&this.words[0]<0)this.words[0]=-this.words[0],this.negative=1;else for(var t=0;t>26)-(u/67108864|0),this.words[r+n]=67108863&i}for(;r>26,this.words[r+n]=67108863&i;if(0===s)return this._strip();for(o(-1===s),s=0,r=0;r>26,this.words[r]=67108863&i;return this.negative=1,this._strip()},i.prototype._wordDiv=function(e,t){var n=(this.length,e.length),o=this.clone(),r=e,a=0|r.words[r.length-1];0!=(n=26-this._countBits(a))&&(r=r.ushln(n),o.iushln(n),a=0|r.words[r.length-1]);var s,u=o.length-r.length;if("mod"!==t){(s=new i(null)).length=u+1,s.words=new Array(s.length);for(var c=0;c=0;d--){var h=67108864*(0|o.words[r.length+d])+(0|o.words[r.length+d-1]);for(h=Math.min(h/a|0,67108863),o._ishlnsubmul(r,h,d);0!==o.negative;)h--,o.negative=0,o._ishlnsubmul(r,1,d),o.isZero()||(o.negative^=1);s&&(s.words[d]=h)}return s&&s._strip(),o._strip(),"div"!==t&&0!==n&&o.iushrn(n),{div:s||null,mod:o}},i.prototype.divmod=function(e,t,n){return o(!e.isZero()),this.isZero()?{div:new i(0),mod:new i(0)}:0!==this.negative&&0===e.negative?(s=this.neg().divmod(e,t),"mod"!==t&&(r=s.div.neg()),"div"!==t&&(a=s.mod.neg(),n&&0!==a.negative&&a.iadd(e)),{div:r,mod:a}):0===this.negative&&0!==e.negative?(s=this.divmod(e.neg(),t),"mod"!==t&&(r=s.div.neg()),{div:r,mod:s.mod}):0!=(this.negative&e.negative)?(s=this.neg().divmod(e.neg(),t),"div"!==t&&(a=s.mod.neg(),n&&0!==a.negative&&a.isub(e)),{div:s.div,mod:a}):e.length>this.length||this.cmp(e)<0?{div:new i(0),mod:this}:1===e.length?"div"===t?{div:this.divn(e.words[0]),mod:null}:"mod"===t?{div:null,mod:new i(this.modrn(e.words[0]))}:{div:this.divn(e.words[0]),mod:new i(this.modrn(e.words[0]))}:this._wordDiv(e,t);var r,a,s},i.prototype.div=function(e){return this.divmod(e,"div",!1).div},i.prototype.mod=function(e){return this.divmod(e,"mod",!1).mod},i.prototype.umod=function(e){return this.divmod(e,"mod",!0).mod},i.prototype.divRound=function(e){var t=this.divmod(e);if(t.mod.isZero())return t.div;var n=0!==t.div.negative?t.mod.isub(e):t.mod,o=e.ushrn(1),r=e.andln(1),i=n.cmp(o);return i<0||1===r&&0===i?t.div:0!==t.div.negative?t.div.isubn(1):t.div.iaddn(1)},i.prototype.modrn=function(e){var t=e<0;t&&(e=-e),o(e<=67108863);for(var n=(1<<26)%e,r=0,i=this.length-1;i>=0;i--)r=(n*r+(0|this.words[i]))%e;return t?-r:r},i.prototype.modn=function(e){return this.modrn(e)},i.prototype.idivn=function(e){var t=e<0;t&&(e=-e),o(e<=67108863);for(var n=0,r=this.length-1;r>=0;r--){var i=(0|this.words[r])+67108864*n;this.words[r]=i/e|0,n=i%e}return this._strip(),t?this.ineg():this},i.prototype.divn=function(e){return this.clone().idivn(e)},i.prototype.egcd=function(e){o(0===e.negative),o(!e.isZero());var t=this,n=e.clone();t=0!==t.negative?t.umod(e):t.clone();for(var r=new i(1),a=new i(0),s=new i(0),u=new i(1),c=0;t.isEven()&&n.isEven();)t.iushrn(1),n.iushrn(1),++c;for(var l=n.clone(),d=t.clone();!t.isZero();){for(var h=0,p=1;0==(t.words[0]&p)&&h<26;++h,p<<=1);if(h>0)for(t.iushrn(h);h-- >0;)(r.isOdd()||a.isOdd())&&(r.iadd(l),a.isub(d)),r.iushrn(1),a.iushrn(1);for(var f=0,g=1;0==(n.words[0]&g)&&f<26;++f,g<<=1);if(f>0)for(n.iushrn(f);f-- >0;)(s.isOdd()||u.isOdd())&&(s.iadd(l),u.isub(d)),s.iushrn(1),u.iushrn(1);t.cmp(n)>=0?(t.isub(n),r.isub(s),a.isub(u)):(n.isub(t),s.isub(r),u.isub(a))}return{a:s,b:u,gcd:n.iushln(c)}},i.prototype._invmp=function(e){o(0===e.negative),o(!e.isZero());var t=this,n=e.clone();t=0!==t.negative?t.umod(e):t.clone();for(var r,a=new i(1),s=new i(0),u=n.clone();t.cmpn(1)>0&&n.cmpn(1)>0;){for(var c=0,l=1;0==(t.words[0]&l)&&c<26;++c,l<<=1);if(c>0)for(t.iushrn(c);c-- >0;)a.isOdd()&&a.iadd(u),a.iushrn(1);for(var d=0,h=1;0==(n.words[0]&h)&&d<26;++d,h<<=1);if(d>0)for(n.iushrn(d);d-- >0;)s.isOdd()&&s.iadd(u),s.iushrn(1);t.cmp(n)>=0?(t.isub(n),a.isub(s)):(n.isub(t),s.isub(a))}return(r=0===t.cmpn(1)?a:s).cmpn(0)<0&&r.iadd(e),r},i.prototype.gcd=function(e){if(this.isZero())return e.abs();if(e.isZero())return this.abs();var t=this.clone(),n=e.clone();t.negative=0,n.negative=0;for(var o=0;t.isEven()&&n.isEven();o++)t.iushrn(1),n.iushrn(1);for(;;){for(;t.isEven();)t.iushrn(1);for(;n.isEven();)n.iushrn(1);var r=t.cmp(n);if(r<0){var i=t;t=n,n=i}else if(0===r||0===n.cmpn(1))break;t.isub(n)}return n.iushln(o)},i.prototype.invm=function(e){return this.egcd(e).a.umod(e)},i.prototype.isEven=function(){return 0==(1&this.words[0])},i.prototype.isOdd=function(){return 1==(1&this.words[0])},i.prototype.andln=function(e){return this.words[0]&e},i.prototype.bincn=function(e){o("number"==typeof e);var t=e%26,n=(e-t)/26,r=1<>>26,s&=67108863,this.words[a]=s}return 0!==i&&(this.words[a]=i,this.length++),this},i.prototype.isZero=function(){return 1===this.length&&0===this.words[0]},i.prototype.cmpn=function(e){var t,n=e<0;if(0!==this.negative&&!n)return-1;if(0===this.negative&&n)return 1;if(this._strip(),this.length>1)t=1;else{n&&(e=-e),o(e<=67108863,"Number is too big");var r=0|this.words[0];t=r===e?0:re.length)return 1;if(this.length=0;n--){var o=0|this.words[n],r=0|e.words[n];if(o!==r){or&&(t=1);break}}return t},i.prototype.gtn=function(e){return 1===this.cmpn(e)},i.prototype.gt=function(e){return 1===this.cmp(e)},i.prototype.gten=function(e){return this.cmpn(e)>=0},i.prototype.gte=function(e){return this.cmp(e)>=0},i.prototype.ltn=function(e){return-1===this.cmpn(e)},i.prototype.lt=function(e){return-1===this.cmp(e)},i.prototype.lten=function(e){return this.cmpn(e)<=0},i.prototype.lte=function(e){return this.cmp(e)<=0},i.prototype.eqn=function(e){return 0===this.cmpn(e)},i.prototype.eq=function(e){return 0===this.cmp(e)},i.red=function(e){return new S(e)},i.prototype.toRed=function(e){return o(!this.red,"Already a number in reduction context"),o(0===this.negative,"red works only with positives"),e.convertTo(this)._forceRed(e)},i.prototype.fromRed=function(){return o(this.red,"fromRed works only with numbers in reduction context"),this.red.convertFrom(this)},i.prototype._forceRed=function(e){return this.red=e,this},i.prototype.forceRed=function(e){return o(!this.red,"Already a number in reduction context"),this._forceRed(e)},i.prototype.redAdd=function(e){return o(this.red,"redAdd works only with red numbers"),this.red.add(this,e)},i.prototype.redIAdd=function(e){return o(this.red,"redIAdd works only with red numbers"),this.red.iadd(this,e)},i.prototype.redSub=function(e){return o(this.red,"redSub works only with red numbers"),this.red.sub(this,e)},i.prototype.redISub=function(e){return o(this.red,"redISub works only with red numbers"),this.red.isub(this,e)},i.prototype.redShl=function(e){return o(this.red,"redShl works only with red numbers"),this.red.shl(this,e)},i.prototype.redMul=function(e){return o(this.red,"redMul works only with red numbers"),this.red._verify2(this,e),this.red.mul(this,e)},i.prototype.redIMul=function(e){return o(this.red,"redMul works only with red numbers"),this.red._verify2(this,e),this.red.imul(this,e)},i.prototype.redSqr=function(){return o(this.red,"redSqr works only with red numbers"),this.red._verify1(this),this.red.sqr(this)},i.prototype.redISqr=function(){return o(this.red,"redISqr works only with red numbers"),this.red._verify1(this),this.red.isqr(this)},i.prototype.redSqrt=function(){return o(this.red,"redSqrt works only with red numbers"),this.red._verify1(this),this.red.sqrt(this)},i.prototype.redInvm=function(){return o(this.red,"redInvm works only with red numbers"),this.red._verify1(this),this.red.invm(this)},i.prototype.redNeg=function(){return o(this.red,"redNeg works only with red numbers"),this.red._verify1(this),this.red.neg(this)},i.prototype.redPow=function(e){return o(this.red&&!e.red,"redPow(normalNum)"),this.red._verify1(this),this.red.pow(this,e)};var b={k256:null,p224:null,p192:null,p25519:null};function v(e,t){this.name=e,this.p=new i(t,16),this.n=this.p.bitLength(),this.k=new i(1).iushln(this.n).isub(this.p),this.tmp=this._tmp()}function w(){v.call(this,"k256","ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f")}function E(){v.call(this,"p224","ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001")}function k(){v.call(this,"p192","ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff")}function D(){v.call(this,"25519","7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed")}function S(e){if("string"==typeof e){var t=i._prime(e);this.m=t.p,this.prime=t}else o(e.gtn(1),"modulus must be greater than 1"),this.m=e,this.prime=null}function x(e){S.call(this,e),this.shift=this.m.bitLength(),this.shift%26!=0&&(this.shift+=26-this.shift%26),this.r=new i(1).iushln(this.shift),this.r2=this.imod(this.r.sqr()),this.rinv=this.r._invmp(this.m),this.minv=this.rinv.mul(this.r).isubn(1).div(this.m),this.minv=this.minv.umod(this.r),this.minv=this.r.sub(this.minv)}v.prototype._tmp=function(){var e=new i(null);return e.words=new Array(Math.ceil(this.n/13)),e},v.prototype.ireduce=function(e){var t,n=e;do{this.split(n,this.tmp),t=(n=(n=this.imulK(n)).iadd(this.tmp)).bitLength()}while(t>this.n);var o=t0?n.isub(this.p):void 0!==n.strip?n.strip():n._strip(),n},v.prototype.split=function(e,t){e.iushrn(this.n,0,t)},v.prototype.imulK=function(e){return e.imul(this.k)},r(w,v),w.prototype.split=function(e,t){for(var n=4194303,o=Math.min(e.length,9),r=0;r>>22,i=a}i>>>=22,e.words[r-10]=i,0===i&&e.length>10?e.length-=10:e.length-=9},w.prototype.imulK=function(e){e.words[e.length]=0,e.words[e.length+1]=0,e.length+=2;for(var t=0,n=0;n>>=26,e.words[n]=r,t=o}return 0!==t&&(e.words[e.length++]=t),e},i._prime=function(e){if(b[e])return b[e];var t;if("k256"===e)t=new w;else if("p224"===e)t=new E;else if("p192"===e)t=new k;else{if("p25519"!==e)throw new Error("Unknown prime "+e);t=new D}return b[e]=t,t},S.prototype._verify1=function(e){o(0===e.negative,"red works only with positives"),o(e.red,"red works only with red numbers")},S.prototype._verify2=function(e,t){o(0==(e.negative|t.negative),"red works only with positives"),o(e.red&&e.red===t.red,"red works only with red numbers")},S.prototype.imod=function(e){return this.prime?this.prime.ireduce(e)._forceRed(this):(l(e,e.umod(this.m)._forceRed(this)),e)},S.prototype.neg=function(e){return e.isZero()?e.clone():this.m.sub(e)._forceRed(this)},S.prototype.add=function(e,t){this._verify2(e,t);var n=e.add(t);return n.cmp(this.m)>=0&&n.isub(this.m),n._forceRed(this)},S.prototype.iadd=function(e,t){this._verify2(e,t);var n=e.iadd(t);return n.cmp(this.m)>=0&&n.isub(this.m),n},S.prototype.sub=function(e,t){this._verify2(e,t);var n=e.sub(t);return n.cmpn(0)<0&&n.iadd(this.m),n._forceRed(this)},S.prototype.isub=function(e,t){this._verify2(e,t);var n=e.isub(t);return n.cmpn(0)<0&&n.iadd(this.m),n},S.prototype.shl=function(e,t){return this._verify1(e),this.imod(e.ushln(t))},S.prototype.imul=function(e,t){return this._verify2(e,t),this.imod(e.imul(t))},S.prototype.mul=function(e,t){return this._verify2(e,t),this.imod(e.mul(t))},S.prototype.isqr=function(e){return this.imul(e,e.clone())},S.prototype.sqr=function(e){return this.mul(e,e)},S.prototype.sqrt=function(e){if(e.isZero())return e.clone();var t=this.m.andln(3);if(o(t%2==1),3===t){var n=this.m.add(new i(1)).iushrn(2);return this.pow(e,n)}for(var r=this.m.subn(1),a=0;!r.isZero()&&0===r.andln(1);)a++,r.iushrn(1);o(!r.isZero());var s=new i(1).toRed(this),u=s.redNeg(),c=this.m.subn(1).iushrn(1),l=this.m.bitLength();for(l=new i(2*l*l).toRed(this);0!==this.pow(l,c).cmp(u);)l.redIAdd(u);for(var d=this.pow(l,r),h=this.pow(e,r.addn(1).iushrn(1)),p=this.pow(e,r),f=a;0!==p.cmp(s);){for(var g=p,m=0;0!==g.cmp(s);m++)g=g.redSqr();o(m=0;o--){for(var c=t.words[o],l=u-1;l>=0;l--){var d=c>>l&1;r!==n[0]&&(r=this.sqr(r)),0!==d||0!==a?(a<<=1,a|=d,(4==++s||0===o&&0===l)&&(r=this.mul(r,n[a]),s=0,a=0)):s=0}u=26}return r},S.prototype.convertTo=function(e){var t=e.umod(this.m);return t===e?t.clone():t},S.prototype.convertFrom=function(e){var t=e.clone();return t.red=null,t},i.mont=function(e){return new x(e)},r(x,S),x.prototype.convertTo=function(e){return this.imod(e.ushln(this.shift))},x.prototype.convertFrom=function(e){var t=this.imod(e.mul(this.rinv));return t.red=null,t},x.prototype.imul=function(e,t){if(e.isZero()||t.isZero())return e.words[0]=0,e.length=1,e;var n=e.imul(t),o=n.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m),r=n.isub(o).iushrn(this.shift),i=r;return r.cmp(this.m)>=0?i=r.isub(this.m):r.cmpn(0)<0&&(i=r.iadd(this.m)),i._forceRed(this)},x.prototype.mul=function(e,t){if(e.isZero()||t.isZero())return new i(0)._forceRed(this);var n=e.mul(t),o=n.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m),r=n.isub(o).iushrn(this.shift),a=r;return r.cmp(this.m)>=0?a=r.isub(this.m):r.cmpn(0)<0&&(a=r.iadd(this.m)),a._forceRed(this)},x.prototype.invm=function(e){return this.imod(e._invmp(this.m).mul(this.r2))._forceRed(this)}}(e=n.nmd(e),this)},29931:(e,t,n)=>{var o;function r(e){this.rand=e}if(e.exports=function(e){return o||(o=new r(null)),o.generate(e)},e.exports.Rand=r,r.prototype.generate=function(e){return this._rand(e)},r.prototype._rand=function(e){if(this.rand.getBytes)return this.rand.getBytes(e);for(var t=new Uint8Array(e),n=0;n{function n(e){var t=String.fromCharCode.apply(null,e),n=window.btoa(t),o=e.length,r=4*Math.floor((o+2)/3)+(o+2)%3-2;return n.slice(0,r)}try{t.encryptAttachment=function(e){var t,o,r,i,a;return a=new Uint8Array(16),window.crypto.getRandomValues(a.subarray(0,8)),window.crypto.subtle.generateKey({name:"AES-CTR",length:256},!0,["encrypt","decrypt"]).then((function(e){return t=e,window.crypto.subtle.exportKey("jwk",t)})).then((function(n){return o=n,window.crypto.subtle.encrypt({name:"AES-CTR",counter:a,length:64},t,e)})).then((function(e){return r=e,window.crypto.subtle.digest("SHA-256",r)})).then((function(e){return i=e,{data:r,info:{v:"v2",key:o,iv:n(a),hashes:{sha256:n(new Uint8Array(i))}}}}))},t.decryptAttachment=function(e,t){if(void 0===t||void 0===t.key||void 0===t.iv||void 0===t.hashes||void 0===t.hashes.sha256)throw new Error("Invalid info. Missing info.key, info.iv or info.hashes.sha256 key");var o,r=function(e){for(var t=e+"===".slice(0,(4-e.length%4)%4),n=window.atob(t),o=new Uint8Array(n.length),r=0;r>18&63,n=i>>12&63,o=i>>6&63,r=63&i,l[u++]=a.charAt(t)+a.charAt(n)+a.charAt(o)+a.charAt(r)}while(s299)&&o.error){for(var r in e=new Error("CouchDB error: "+(o.error.reason||o.error.error)),o)e[r]=o[r];return n(e,t,o)}return n(e,t,o)}))},t})?n.apply(t,[]):n)||(e.exports=o)},74497:(e,t,n)=>{var o=n(89509).Buffer;function r(e){o.isBuffer(e)||(e=o.from(e));for(var t=e.length/4|0,n=new Array(t),r=0;r>>24]^l[f>>>16&255]^d[g>>>8&255]^h[255&m]^t[_++],a=c[f>>>24]^l[g>>>16&255]^d[m>>>8&255]^h[255&p]^t[_++],s=c[g>>>24]^l[m>>>16&255]^d[p>>>8&255]^h[255&f]^t[_++],u=c[m>>>24]^l[p>>>16&255]^d[f>>>8&255]^h[255&g]^t[_++],p=i,f=a,g=s,m=u;return i=(o[p>>>24]<<24|o[f>>>16&255]<<16|o[g>>>8&255]<<8|o[255&m])^t[_++],a=(o[f>>>24]<<24|o[g>>>16&255]<<16|o[m>>>8&255]<<8|o[255&p])^t[_++],s=(o[g>>>24]<<24|o[m>>>16&255]<<16|o[p>>>8&255]<<8|o[255&f])^t[_++],u=(o[m>>>24]<<24|o[p>>>16&255]<<16|o[f>>>8&255]<<8|o[255&g])^t[_++],[i>>>=0,a>>>=0,s>>>=0,u>>>=0]}var s=[0,1,2,4,8,16,32,64,128,27,54],u=function(){for(var e=new Array(256),t=0;t<256;t++)e[t]=t<128?t<<1:t<<1^283;for(var n=[],o=[],r=[[],[],[],[]],i=[[],[],[],[]],a=0,s=0,u=0;u<256;++u){var c=s^s<<1^s<<2^s<<3^s<<4;c=c>>>8^255&c^99,n[a]=c,o[c]=a;var l=e[a],d=e[l],h=e[d],p=257*e[c]^16843008*c;r[0][a]=p<<24|p>>>8,r[1][a]=p<<16|p>>>16,r[2][a]=p<<8|p>>>24,r[3][a]=p,p=16843009*h^65537*d^257*l^16843008*a,i[0][c]=p<<24|p>>>8,i[1][c]=p<<16|p>>>16,i[2][c]=p<<8|p>>>24,i[3][c]=p,0===a?a=s=1:(a=l^e[e[e[h^l]]],s^=e[e[s]])}return{SBOX:n,INV_SBOX:o,SUB_MIX:r,INV_SUB_MIX:i}}();function c(e){this._key=r(e),this._reset()}c.blockSize=16,c.keySize=32,c.prototype.blockSize=c.blockSize,c.prototype.keySize=c.keySize,c.prototype._reset=function(){for(var e=this._key,t=e.length,n=t+6,o=4*(n+1),r=[],i=0;i>>24,a=u.SBOX[a>>>24]<<24|u.SBOX[a>>>16&255]<<16|u.SBOX[a>>>8&255]<<8|u.SBOX[255&a],a^=s[i/t|0]<<24):t>6&&i%t==4&&(a=u.SBOX[a>>>24]<<24|u.SBOX[a>>>16&255]<<16|u.SBOX[a>>>8&255]<<8|u.SBOX[255&a]),r[i]=r[i-t]^a}for(var c=[],l=0;l>>24]]^u.INV_SUB_MIX[1][u.SBOX[h>>>16&255]]^u.INV_SUB_MIX[2][u.SBOX[h>>>8&255]]^u.INV_SUB_MIX[3][u.SBOX[255&h]]}this._nRounds=n,this._keySchedule=r,this._invKeySchedule=c},c.prototype.encryptBlockRaw=function(e){return a(e=r(e),this._keySchedule,u.SUB_MIX,u.SBOX,this._nRounds)},c.prototype.encryptBlock=function(e){var t=this.encryptBlockRaw(e),n=o.allocUnsafe(16);return n.writeUInt32BE(t[0],0),n.writeUInt32BE(t[1],4),n.writeUInt32BE(t[2],8),n.writeUInt32BE(t[3],12),n},c.prototype.decryptBlock=function(e){var t=(e=r(e))[1];e[1]=e[3],e[3]=t;var n=a(e,this._invKeySchedule,u.INV_SUB_MIX,u.INV_SBOX,this._nRounds),i=o.allocUnsafe(16);return i.writeUInt32BE(n[0],0),i.writeUInt32BE(n[3],4),i.writeUInt32BE(n[2],8),i.writeUInt32BE(n[1],12),i},c.prototype.scrub=function(){i(this._keySchedule),i(this._invKeySchedule),i(this._key)},e.exports.AES=c},62422:(e,t,n)=>{var o=n(74497),r=n(89509).Buffer,i=n(71027),a=n(35717),s=n(83288),u=n(67295),c=n(20685);function l(e,t,n,a){i.call(this);var u=r.alloc(4,0);this._cipher=new o.AES(t);var l=this._cipher.encryptBlock(u);this._ghash=new s(l),n=function(e,t,n){if(12===t.length)return e._finID=r.concat([t,r.from([0,0,0,1])]),r.concat([t,r.from([0,0,0,2])]);var o=new s(n),i=t.length,a=i%16;o.update(t),a&&(a=16-a,o.update(r.alloc(a,0))),o.update(r.alloc(8,0));var u=8*i,l=r.alloc(8);l.writeUIntBE(u,0,8),o.update(l),e._finID=o.state;var d=r.from(e._finID);return c(d),d}(this,n,l),this._prev=r.from(n),this._cache=r.allocUnsafe(0),this._secCache=r.allocUnsafe(0),this._decrypt=a,this._alen=0,this._len=0,this._mode=e,this._authTag=null,this._called=!1}a(l,i),l.prototype._update=function(e){if(!this._called&&this._alen){var t=16-this._alen%16;t<16&&(t=r.alloc(t,0),this._ghash.update(t))}this._called=!0;var n=this._mode.encrypt(this,e);return this._decrypt?this._ghash.update(e):this._ghash.update(n),this._len+=e.length,n},l.prototype._final=function(){if(this._decrypt&&!this._authTag)throw new Error("Unsupported state or unable to authenticate data");var e=u(this._ghash.final(8*this._alen,8*this._len),this._cipher.encryptBlock(this._finID));if(this._decrypt&&function(e,t){var n=0;e.length!==t.length&&n++;for(var o=Math.min(e.length,t.length),r=0;r{var o=n(71494),r=n(66193),i=n(55415);t.createCipher=t.Cipher=o.createCipher,t.createCipheriv=t.Cipheriv=o.createCipheriv,t.createDecipher=t.Decipher=r.createDecipher,t.createDecipheriv=t.Decipheriv=r.createDecipheriv,t.listCiphers=t.getCiphers=function(){return Object.keys(i)}},66193:(e,t,n)=>{var o=n(62422),r=n(89509).Buffer,i=n(45),a=n(25969),s=n(71027),u=n(74497),c=n(13048);function l(e,t,n){s.call(this),this._cache=new d,this._last=void 0,this._cipher=new u.AES(t),this._prev=r.from(n),this._mode=e,this._autopadding=!0}function d(){this.cache=r.allocUnsafe(0)}function h(e,t,n){var s=i[e.toLowerCase()];if(!s)throw new TypeError("invalid suite type");if("string"==typeof n&&(n=r.from(n)),"GCM"!==s.mode&&n.length!==s.iv)throw new TypeError("invalid iv length "+n.length);if("string"==typeof t&&(t=r.from(t)),t.length!==s.key/8)throw new TypeError("invalid key length "+t.length);return"stream"===s.type?new a(s.module,t,n,!0):"auth"===s.type?new o(s.module,t,n,!0):new l(s.module,t,n)}n(35717)(l,s),l.prototype._update=function(e){var t,n;this._cache.add(e);for(var o=[];t=this._cache.get(this._autopadding);)n=this._mode.decrypt(this,t),o.push(n);return r.concat(o)},l.prototype._final=function(){var e=this._cache.flush();if(this._autopadding)return function(e){var t=e[15];if(t<1||t>16)throw new Error("unable to decrypt data");for(var n=-1;++n16)return t=this.cache.slice(0,16),this.cache=this.cache.slice(16),t}else if(this.cache.length>=16)return t=this.cache.slice(0,16),this.cache=this.cache.slice(16),t;return null},d.prototype.flush=function(){if(this.cache.length)return this.cache},t.createDecipher=function(e,t){var n=i[e.toLowerCase()];if(!n)throw new TypeError("invalid suite type");var o=c(t,!1,n.key,n.iv);return h(e,o.key,o.iv)},t.createDecipheriv=h},71494:(e,t,n)=>{var o=n(45),r=n(62422),i=n(89509).Buffer,a=n(25969),s=n(71027),u=n(74497),c=n(13048);function l(e,t,n){s.call(this),this._cache=new h,this._cipher=new u.AES(t),this._prev=i.from(n),this._mode=e,this._autopadding=!0}n(35717)(l,s),l.prototype._update=function(e){var t,n;this._cache.add(e);for(var o=[];t=this._cache.get();)n=this._mode.encrypt(this,t),o.push(n);return i.concat(o)};var d=i.alloc(16,16);function h(){this.cache=i.allocUnsafe(0)}function p(e,t,n){var s=o[e.toLowerCase()];if(!s)throw new TypeError("invalid suite type");if("string"==typeof t&&(t=i.from(t)),t.length!==s.key/8)throw new TypeError("invalid key length "+t.length);if("string"==typeof n&&(n=i.from(n)),"GCM"!==s.mode&&n.length!==s.iv)throw new TypeError("invalid iv length "+n.length);return"stream"===s.type?new a(s.module,t,n):"auth"===s.type?new r(s.module,t,n):new l(s.module,t,n)}l.prototype._final=function(){var e=this._cache.flush();if(this._autopadding)return e=this._mode.encrypt(this,e),this._cipher.scrub(),e;if(!e.equals(d))throw this._cipher.scrub(),new Error("data not multiple of block length")},l.prototype.setAutoPadding=function(e){return this._autopadding=!!e,this},h.prototype.add=function(e){this.cache=i.concat([this.cache,e])},h.prototype.get=function(){if(this.cache.length>15){var e=this.cache.slice(0,16);return this.cache=this.cache.slice(16),e}return null},h.prototype.flush=function(){for(var e=16-this.cache.length,t=i.allocUnsafe(e),n=-1;++n{var o=n(89509).Buffer,r=o.alloc(16,0);function i(e){var t=o.allocUnsafe(16);return t.writeUInt32BE(e[0]>>>0,0),t.writeUInt32BE(e[1]>>>0,4),t.writeUInt32BE(e[2]>>>0,8),t.writeUInt32BE(e[3]>>>0,12),t}function a(e){this.h=e,this.state=o.alloc(16,0),this.cache=o.allocUnsafe(0)}a.prototype.ghash=function(e){for(var t=-1;++t0;t--)o[t]=o[t]>>>1|(1&o[t-1])<<31;o[0]=o[0]>>>1,n&&(o[0]=o[0]^225<<24)}this.state=i(r)},a.prototype.update=function(e){var t;for(this.cache=o.concat([this.cache,e]);this.cache.length>=16;)t=this.cache.slice(0,16),this.cache=this.cache.slice(16),this.ghash(t)},a.prototype.final=function(e,t){return this.cache.length&&this.ghash(o.concat([this.cache,r],16)),this.ghash(i([0,e,0,t])),this.state},e.exports=a},20685:e=>{e.exports=function(e){for(var t,n=e.length;n--;){if(255!==(t=e.readUInt8(n))){t++,e.writeUInt8(t,n);break}e.writeUInt8(0,n)}}},25292:(e,t,n)=>{var o=n(67295);t.encrypt=function(e,t){var n=o(t,e._prev);return e._prev=e._cipher.encryptBlock(n),e._prev},t.decrypt=function(e,t){var n=e._prev;e._prev=t;var r=e._cipher.decryptBlock(t);return o(r,n)}},86311:(e,t,n)=>{var o=n(89509).Buffer,r=n(67295);function i(e,t,n){var i=t.length,a=r(t,e._cache);return e._cache=e._cache.slice(i),e._prev=o.concat([e._prev,n?t:a]),a}t.encrypt=function(e,t,n){for(var r,a=o.allocUnsafe(0);t.length;){if(0===e._cache.length&&(e._cache=e._cipher.encryptBlock(e._prev),e._prev=o.allocUnsafe(0)),!(e._cache.length<=t.length)){a=o.concat([a,i(e,t,n)]);break}r=e._cache.length,a=o.concat([a,i(e,t.slice(0,r),n)]),t=t.slice(r)}return a}},21510:(e,t,n)=>{var o=n(89509).Buffer;function r(e,t,n){for(var o,r,a=-1,s=0;++a<8;)o=t&1<<7-a?128:0,s+=(128&(r=e._cipher.encryptBlock(e._prev)[0]^o))>>a%8,e._prev=i(e._prev,n?o:r);return s}function i(e,t){var n=e.length,r=-1,i=o.allocUnsafe(e.length);for(e=o.concat([e,o.from([t])]);++r>7;return i}t.encrypt=function(e,t,n){for(var i=t.length,a=o.allocUnsafe(i),s=-1;++s{var o=n(89509).Buffer;function r(e,t,n){var r=e._cipher.encryptBlock(e._prev)[0]^t;return e._prev=o.concat([e._prev.slice(1),o.from([n?t:r])]),r}t.encrypt=function(e,t,n){for(var i=t.length,a=o.allocUnsafe(i),s=-1;++s{var o=n(67295),r=n(89509).Buffer,i=n(20685);function a(e){var t=e._cipher.encryptBlockRaw(e._prev);return i(e._prev),t}t.encrypt=function(e,t){var n=Math.ceil(t.length/16),i=e._cache.length;e._cache=r.concat([e._cache,r.allocUnsafe(16*n)]);for(var s=0;s{t.encrypt=function(e,t){return e._cipher.encryptBlock(t)},t.decrypt=function(e,t){return e._cipher.decryptBlock(t)}},45:(e,t,n)=>{var o={ECB:n(11084),CBC:n(25292),CFB:n(86311),CFB8:n(71964),CFB1:n(21510),OFB:n(18861),CTR:n(96009),GCM:n(96009)},r=n(55415);for(var i in r)r[i].module=o[r[i].mode];e.exports=r},55415:e=>{"use strict";e.exports=JSON.parse('{"aes-128-ecb":{"cipher":"AES","key":128,"iv":0,"mode":"ECB","type":"block"},"aes-192-ecb":{"cipher":"AES","key":192,"iv":0,"mode":"ECB","type":"block"},"aes-256-ecb":{"cipher":"AES","key":256,"iv":0,"mode":"ECB","type":"block"},"aes-128-cbc":{"cipher":"AES","key":128,"iv":16,"mode":"CBC","type":"block"},"aes-192-cbc":{"cipher":"AES","key":192,"iv":16,"mode":"CBC","type":"block"},"aes-256-cbc":{"cipher":"AES","key":256,"iv":16,"mode":"CBC","type":"block"},"aes128":{"cipher":"AES","key":128,"iv":16,"mode":"CBC","type":"block"},"aes192":{"cipher":"AES","key":192,"iv":16,"mode":"CBC","type":"block"},"aes256":{"cipher":"AES","key":256,"iv":16,"mode":"CBC","type":"block"},"aes-128-cfb":{"cipher":"AES","key":128,"iv":16,"mode":"CFB","type":"stream"},"aes-192-cfb":{"cipher":"AES","key":192,"iv":16,"mode":"CFB","type":"stream"},"aes-256-cfb":{"cipher":"AES","key":256,"iv":16,"mode":"CFB","type":"stream"},"aes-128-cfb8":{"cipher":"AES","key":128,"iv":16,"mode":"CFB8","type":"stream"},"aes-192-cfb8":{"cipher":"AES","key":192,"iv":16,"mode":"CFB8","type":"stream"},"aes-256-cfb8":{"cipher":"AES","key":256,"iv":16,"mode":"CFB8","type":"stream"},"aes-128-cfb1":{"cipher":"AES","key":128,"iv":16,"mode":"CFB1","type":"stream"},"aes-192-cfb1":{"cipher":"AES","key":192,"iv":16,"mode":"CFB1","type":"stream"},"aes-256-cfb1":{"cipher":"AES","key":256,"iv":16,"mode":"CFB1","type":"stream"},"aes-128-ofb":{"cipher":"AES","key":128,"iv":16,"mode":"OFB","type":"stream"},"aes-192-ofb":{"cipher":"AES","key":192,"iv":16,"mode":"OFB","type":"stream"},"aes-256-ofb":{"cipher":"AES","key":256,"iv":16,"mode":"OFB","type":"stream"},"aes-128-ctr":{"cipher":"AES","key":128,"iv":16,"mode":"CTR","type":"stream"},"aes-192-ctr":{"cipher":"AES","key":192,"iv":16,"mode":"CTR","type":"stream"},"aes-256-ctr":{"cipher":"AES","key":256,"iv":16,"mode":"CTR","type":"stream"},"aes-128-gcm":{"cipher":"AES","key":128,"iv":12,"mode":"GCM","type":"auth"},"aes-192-gcm":{"cipher":"AES","key":192,"iv":12,"mode":"GCM","type":"auth"},"aes-256-gcm":{"cipher":"AES","key":256,"iv":12,"mode":"GCM","type":"auth"}}')},18861:(e,t,n)=>{var o=n(67295);function r(e){return e._prev=e._cipher.encryptBlock(e._prev),e._prev}t.encrypt=function(e,t){for(;e._cache.length{var o=n(74497),r=n(89509).Buffer,i=n(71027);function a(e,t,n,a){i.call(this),this._cipher=new o.AES(t),this._prev=r.from(n),this._cache=r.allocUnsafe(0),this._secCache=r.allocUnsafe(0),this._decrypt=a,this._mode=e}n(35717)(a,i),a.prototype._update=function(e){return this._mode.encrypt(this,e,this._decrypt)},a.prototype._final=function(){this._cipher.scrub()},e.exports=a},53614:(e,t,n)=>{var o=n(47667),r=n(44696),i=n(45),a=n(99715),s=n(13048);function u(e,t,n){if(e=e.toLowerCase(),i[e])return r.createCipheriv(e,t,n);if(a[e])return new o({key:t,iv:n,mode:e});throw new TypeError("invalid suite type")}function c(e,t,n){if(e=e.toLowerCase(),i[e])return r.createDecipheriv(e,t,n);if(a[e])return new o({key:t,iv:n,mode:e,decrypt:!0});throw new TypeError("invalid suite type")}t.createCipher=t.Cipher=function(e,t){var n,o;if(e=e.toLowerCase(),i[e])n=i[e].key,o=i[e].iv;else{if(!a[e])throw new TypeError("invalid suite type");n=8*a[e].key,o=a[e].iv}var r=s(t,!1,n,o);return u(e,r.key,r.iv)},t.createCipheriv=t.Cipheriv=u,t.createDecipher=t.Decipher=function(e,t){var n,o;if(e=e.toLowerCase(),i[e])n=i[e].key,o=i[e].iv;else{if(!a[e])throw new TypeError("invalid suite type");n=8*a[e].key,o=a[e].iv}var r=s(t,!1,n,o);return c(e,r.key,r.iv)},t.createDecipheriv=t.Decipheriv=c,t.listCiphers=t.getCiphers=function(){return Object.keys(a).concat(r.getCiphers())}},47667:(e,t,n)=>{var o=n(71027),r=n(15251),i=n(35717),a=n(89509).Buffer,s={"des-ede3-cbc":r.CBC.instantiate(r.EDE),"des-ede3":r.EDE,"des-ede-cbc":r.CBC.instantiate(r.EDE),"des-ede":r.EDE,"des-cbc":r.CBC.instantiate(r.DES),"des-ecb":r.DES};function u(e){o.call(this);var t,n=e.mode.toLowerCase(),r=s[n];t=e.decrypt?"decrypt":"encrypt";var i=e.key;a.isBuffer(i)||(i=a.from(i)),"des-ede"!==n&&"des-ede-cbc"!==n||(i=a.concat([i,i.slice(0,8)]));var u=e.iv;a.isBuffer(u)||(u=a.from(u)),this._des=r.create({key:i,iv:u,type:t})}s.des=s["des-cbc"],s.des3=s["des-ede3-cbc"],e.exports=u,i(u,o),u.prototype._update=function(e){return a.from(this._des.update(e))},u.prototype._final=function(){return a.from(this._des.final())}},99715:(e,t)=>{t["des-ecb"]={key:8,iv:0},t["des-cbc"]=t.des={key:8,iv:8},t["des-ede3-cbc"]=t.des3={key:24,iv:8},t["des-ede3"]={key:24,iv:0},t["des-ede-cbc"]={key:16,iv:8},t["des-ede"]={key:16,iv:0}},23384:(e,t,n)=>{var o=n(99558),r=n(34918),i=n(49942),a=r("level-filesystem",{db:o});e.exports=i(a)},23663:(e,t,n)=>{var o=n(13550),r=n(61798);function i(e){var t,n=e.modulus.byteLength();do{t=new o(r(n))}while(t.cmp(e.modulus)>=0||!t.umod(e.prime1)||!t.umod(e.prime2));return t}function a(e,t){var n=function(e){var t=i(e);return{blinder:t.toRed(o.mont(e.modulus)).redPow(new o(e.publicExponent)).fromRed(),unblinder:t.invm(e.modulus)}}(t),r=t.modulus.byteLength(),a=new o(e).mul(n.blinder).umod(t.modulus),s=a.toRed(o.mont(t.prime1)),u=a.toRed(o.mont(t.prime2)),c=t.coefficient,l=t.prime1,d=t.prime2,h=s.redPow(t.exponent1).fromRed(),p=u.redPow(t.exponent2).fromRed(),f=h.isub(p).imul(c).umod(l).imul(d);return p.iadd(f).imul(n.unblinder).umod(t.modulus).toArrayLike(Buffer,"be",r)}a.getr=i,e.exports=a},56042:(e,t,n)=>{e.exports=n(42063)},42063:e=>{"use strict";e.exports=JSON.parse('{"sha224WithRSAEncryption":{"sign":"rsa","hash":"sha224","id":"302d300d06096086480165030402040500041c"},"RSA-SHA224":{"sign":"ecdsa/rsa","hash":"sha224","id":"302d300d06096086480165030402040500041c"},"sha256WithRSAEncryption":{"sign":"rsa","hash":"sha256","id":"3031300d060960864801650304020105000420"},"RSA-SHA256":{"sign":"ecdsa/rsa","hash":"sha256","id":"3031300d060960864801650304020105000420"},"sha384WithRSAEncryption":{"sign":"rsa","hash":"sha384","id":"3041300d060960864801650304020205000430"},"RSA-SHA384":{"sign":"ecdsa/rsa","hash":"sha384","id":"3041300d060960864801650304020205000430"},"sha512WithRSAEncryption":{"sign":"rsa","hash":"sha512","id":"3051300d060960864801650304020305000440"},"RSA-SHA512":{"sign":"ecdsa/rsa","hash":"sha512","id":"3051300d060960864801650304020305000440"},"RSA-SHA1":{"sign":"rsa","hash":"sha1","id":"3021300906052b0e03021a05000414"},"ecdsa-with-SHA1":{"sign":"ecdsa","hash":"sha1","id":""},"sha256":{"sign":"ecdsa","hash":"sha256","id":""},"sha224":{"sign":"ecdsa","hash":"sha224","id":""},"sha384":{"sign":"ecdsa","hash":"sha384","id":""},"sha512":{"sign":"ecdsa","hash":"sha512","id":""},"DSA-SHA":{"sign":"dsa","hash":"sha1","id":""},"DSA-SHA1":{"sign":"dsa","hash":"sha1","id":""},"DSA":{"sign":"dsa","hash":"sha1","id":""},"DSA-WITH-SHA224":{"sign":"dsa","hash":"sha224","id":""},"DSA-SHA224":{"sign":"dsa","hash":"sha224","id":""},"DSA-WITH-SHA256":{"sign":"dsa","hash":"sha256","id":""},"DSA-SHA256":{"sign":"dsa","hash":"sha256","id":""},"DSA-WITH-SHA384":{"sign":"dsa","hash":"sha384","id":""},"DSA-SHA384":{"sign":"dsa","hash":"sha384","id":""},"DSA-WITH-SHA512":{"sign":"dsa","hash":"sha512","id":""},"DSA-SHA512":{"sign":"dsa","hash":"sha512","id":""},"DSA-RIPEMD160":{"sign":"dsa","hash":"rmd160","id":""},"ripemd160WithRSA":{"sign":"rsa","hash":"rmd160","id":"3021300906052b2403020105000414"},"RSA-RIPEMD160":{"sign":"rsa","hash":"rmd160","id":"3021300906052b2403020105000414"},"md5WithRSAEncryption":{"sign":"rsa","hash":"md5","id":"3020300c06082a864886f70d020505000410"},"RSA-MD5":{"sign":"rsa","hash":"md5","id":"3020300c06082a864886f70d020505000410"}}')},42236:e=>{"use strict";e.exports=JSON.parse('{"1.3.132.0.10":"secp256k1","1.3.132.0.33":"p224","1.2.840.10045.3.1.1":"p192","1.2.840.10045.3.1.7":"p256","1.3.132.0.34":"p384","1.3.132.0.35":"p521"}')},64743:(e,t,n)=>{var o=n(89509).Buffer,r=n(23482),i=n(23872),a=n(35717),s=n(82957),u=n(47753),c=n(42063);function l(e){i.Writable.call(this);var t=c[e];if(!t)throw new Error("Unknown message digest");this._hashType=t.hash,this._hash=r(t.hash),this._tag=t.id,this._signType=t.sign}function d(e){i.Writable.call(this);var t=c[e];if(!t)throw new Error("Unknown message digest");this._hash=r(t.hash),this._tag=t.id,this._signType=t.sign}function h(e){return new l(e)}function p(e){return new d(e)}Object.keys(c).forEach((function(e){c[e].id=o.from(c[e].id,"hex"),c[e.toLowerCase()]=c[e]})),a(l,i.Writable),l.prototype._write=function(e,t,n){this._hash.update(e),n()},l.prototype.update=function(e,t){return"string"==typeof e&&(e=o.from(e,t)),this._hash.update(e),this},l.prototype.sign=function(e,t){this.end();var n=this._hash.digest(),o=s(n,e,this._hashType,this._signType,this._tag);return t?o.toString(t):o},a(d,i.Writable),d.prototype._write=function(e,t,n){this._hash.update(e),n()},d.prototype.update=function(e,t){return"string"==typeof e&&(e=o.from(e,t)),this._hash.update(e),this},d.prototype.verify=function(e,t,n){"string"==typeof t&&(t=o.from(t,n)),this.end();var r=this._hash.digest();return u(t,r,e,this._signType,this._tag)},e.exports={Sign:h,Verify:p,createSign:h,createVerify:p}},82957:(e,t,n)=>{var o=n(89509).Buffer,r=n(58355),i=n(23663),a=n(86266).ec,s=n(13550),u=n(70980),c=n(42236);function l(e,t,n,i){if((e=o.from(e.toArray())).length0&&n.ishrn(o),n}function h(e,t,n){var i,a;do{for(i=o.alloc(0);8*i.length{var o=n(89509).Buffer,r=n(13550),i=n(86266).ec,a=n(70980),s=n(42236);function u(e,t){if(e.cmpn(0)<=0)throw new Error("invalid sig");if(e.cmp(t)>=t)throw new Error("invalid sig")}e.exports=function(e,t,n,c,l){var d=a(n);if("ec"===d.type){if("ecdsa"!==c&&"ecdsa/rsa"!==c)throw new Error("wrong public key type");return function(e,t,n){var o=s[n.data.algorithm.curve.join(".")];if(!o)throw new Error("unknown curve "+n.data.algorithm.curve.join("."));var r=new i(o),a=n.data.subjectPrivateKey.data;return r.verify(t,e,a)}(e,t,d)}if("dsa"===d.type){if("dsa"!==c)throw new Error("wrong public key type");return function(e,t,n){var o=n.data.p,i=n.data.q,s=n.data.g,c=n.data.pub_key,l=a.signature.decode(e,"der"),d=l.s,h=l.r;u(d,i),u(h,i);var p=r.mont(o),f=d.invm(i);return 0===s.toRed(p).redPow(new r(t).mul(f).mod(i)).fromRed().mul(c.toRed(p).redPow(h.mul(f).mod(i)).fromRed()).mod(o).mod(i).cmp(h)}(e,t,d)}if("rsa"!==c&&"ecdsa/rsa"!==c)throw new Error("wrong public key type");t=o.concat([l,t]);for(var h=d.modulus.byteLength(),p=[1],f=0;t.length+p.length+2{"use strict";var t={};function n(e,n,o){o||(o=Error);var r=function(e){var t,o;function r(t,o,r){return e.call(this,function(e,t,o){return"string"==typeof n?n:n(e,t,o)}(t,o,r))||this}return o=e,(t=r).prototype=Object.create(o.prototype),t.prototype.constructor=t,t.__proto__=o,r}(o);r.prototype.name=o.name,r.prototype.code=e,t[e]=r}function o(e,t){if(Array.isArray(e)){var n=e.length;return e=e.map((function(e){return String(e)})),n>2?"one of ".concat(t," ").concat(e.slice(0,n-1).join(", "),", or ")+e[n-1]:2===n?"one of ".concat(t," ").concat(e[0]," or ").concat(e[1]):"of ".concat(t," ").concat(e[0])}return"of ".concat(t," ").concat(String(e))}n("ERR_INVALID_OPT_VALUE",(function(e,t){return'The value "'+t+'" is invalid for option "'+e+'"'}),TypeError),n("ERR_INVALID_ARG_TYPE",(function(e,t,n){var r,i,a,s,u;if("string"==typeof t&&(i="not ",t.substr(0,i.length)===i)?(r="must not be",t=t.replace(/^not /,"")):r="must be",function(e,t,n){return(void 0===n||n>e.length)&&(n=e.length),e.substring(n-t.length,n)===t}(e," argument"))a="The ".concat(e," ").concat(r," ").concat(o(t,"type"));else{var c=("number"!=typeof u&&(u=0),u+".".length>(s=e).length||-1===s.indexOf(".",u)?"argument":"property");a='The "'.concat(e,'" ').concat(c," ").concat(r," ").concat(o(t,"type"))}return a+". Received type ".concat(typeof n)}),TypeError),n("ERR_STREAM_PUSH_AFTER_EOF","stream.push() after EOF"),n("ERR_METHOD_NOT_IMPLEMENTED",(function(e){return"The "+e+" method is not implemented"})),n("ERR_STREAM_PREMATURE_CLOSE","Premature close"),n("ERR_STREAM_DESTROYED",(function(e){return"Cannot call "+e+" after a stream was destroyed"})),n("ERR_MULTIPLE_CALLBACK","Callback called multiple times"),n("ERR_STREAM_CANNOT_PIPE","Cannot pipe, not readable"),n("ERR_STREAM_WRITE_AFTER_END","write after end"),n("ERR_STREAM_NULL_VALUES","May not write null values to stream",TypeError),n("ERR_UNKNOWN_ENCODING",(function(e){return"Unknown encoding: "+e}),TypeError),n("ERR_STREAM_UNSHIFT_AFTER_END_EVENT","stream.unshift() after end event"),e.exports.q=t},34390:(e,t,n)=>{"use strict";var o=Object.keys||function(e){var t=[];for(var n in e)t.push(n);return t};e.exports=c;var r=n(44960),i=n(92010);n(35717)(c,r);for(var a=o(i.prototype),s=0;s{"use strict";e.exports=r;var o=n(3912);function r(e){if(!(this instanceof r))return new r(e);o.call(this,e)}n(35717)(r,o),r.prototype._transform=function(e,t,n){n(null,e)}},44960:(e,t,n)=>{"use strict";var o;e.exports=k,k.ReadableState=E,n(17187).EventEmitter;var r,i=function(e,t){return e.listeners(t).length},a=n(59819),s=n(48764).Buffer,u=n.g.Uint8Array||function(){},c=n(56353);r=c&&c.debuglog?c.debuglog("stream"):function(){};var l,d,h,p=n(76633),f=n(75997),g=n(898).getHighWaterMark,m=n(84419).q,_=m.ERR_INVALID_ARG_TYPE,F=m.ERR_STREAM_PUSH_AFTER_EOF,y=m.ERR_METHOD_NOT_IMPLEMENTED,b=m.ERR_STREAM_UNSHIFT_AFTER_END_EVENT;n(35717)(k,a);var v=f.errorOrDestroy,w=["error","close","destroy","pause","resume"];function E(e,t,r){o=o||n(34390),e=e||{},"boolean"!=typeof r&&(r=t instanceof o),this.objectMode=!!e.objectMode,r&&(this.objectMode=this.objectMode||!!e.readableObjectMode),this.highWaterMark=g(this,e,"readableHighWaterMark",r),this.buffer=new p,this.length=0,this.pipes=null,this.pipesCount=0,this.flowing=null,this.ended=!1,this.endEmitted=!1,this.reading=!1,this.sync=!0,this.needReadable=!1,this.emittedReadable=!1,this.readableListening=!1,this.resumeScheduled=!1,this.paused=!0,this.emitClose=!1!==e.emitClose,this.autoDestroy=!!e.autoDestroy,this.destroyed=!1,this.defaultEncoding=e.defaultEncoding||"utf8",this.awaitDrain=0,this.readingMore=!1,this.decoder=null,this.encoding=null,e.encoding&&(l||(l=n(32553).s),this.decoder=new l(e.encoding),this.encoding=e.encoding)}function k(e){if(o=o||n(34390),!(this instanceof k))return new k(e);var t=this instanceof o;this._readableState=new E(e,this,t),this.readable=!0,e&&("function"==typeof e.read&&(this._read=e.read),"function"==typeof e.destroy&&(this._destroy=e.destroy)),a.call(this)}function D(e,t,n,o,i){r("readableAddChunk",t);var a,c=e._readableState;if(null===t)c.reading=!1,function(e,t){if(r("onEofChunk"),!t.ended){if(t.decoder){var n=t.decoder.end();n&&n.length&&(t.buffer.push(n),t.length+=t.objectMode?1:n.length)}t.ended=!0,t.sync?A(e):(t.needReadable=!1,t.emittedReadable||(t.emittedReadable=!0,T(e)))}}(e,c);else if(i||(a=function(e,t){var n,o;return o=t,s.isBuffer(o)||o instanceof u||"string"==typeof t||void 0===t||e.objectMode||(n=new _("chunk",["string","Buffer","Uint8Array"],t)),n}(c,t)),a)v(e,a);else if(c.objectMode||t&&t.length>0)if("string"==typeof t||c.objectMode||Object.getPrototypeOf(t)===s.prototype||(t=function(e){return s.from(e)}(t)),o)c.endEmitted?v(e,new b):S(e,c,t,!0);else if(c.ended)v(e,new F);else{if(c.destroyed)return!1;c.reading=!1,c.decoder&&!n?(t=c.decoder.write(t),c.objectMode||0!==t.length?S(e,c,t,!1):R(e,c)):S(e,c,t,!1)}else o||(c.reading=!1,R(e,c));return!c.ended&&(c.lengtht.highWaterMark&&(t.highWaterMark=function(e){return e>=x?e=x:(e--,e|=e>>>1,e|=e>>>2,e|=e>>>4,e|=e>>>8,e|=e>>>16,e++),e}(e)),e<=t.length?e:t.ended?t.length:(t.needReadable=!0,0))}function A(e){var t=e._readableState;r("emitReadable",t.needReadable,t.emittedReadable),t.needReadable=!1,t.emittedReadable||(r("emitReadable",t.flowing),t.emittedReadable=!0,process.nextTick(T,e))}function T(e){var t=e._readableState;r("emitReadable_",t.destroyed,t.length,t.ended),t.destroyed||!t.length&&!t.ended||(e.emit("readable"),t.emittedReadable=!1),t.needReadable=!t.flowing&&!t.ended&&t.length<=t.highWaterMark,N(e)}function R(e,t){t.readingMore||(t.readingMore=!0,process.nextTick(I,e,t))}function I(e,t){for(;!t.reading&&!t.ended&&(t.length0,t.resumeScheduled&&!t.paused?t.flowing=!0:e.listenerCount("data")>0&&e.resume()}function O(e){r("readable nexttick read 0"),e.read(0)}function B(e,t){r("resume",t.reading),t.reading||e.read(0),t.resumeScheduled=!1,e.emit("resume"),N(e),t.flowing&&!t.reading&&e.read(0)}function N(e){var t=e._readableState;for(r("flow",t.flowing);t.flowing&&null!==e.read(););}function L(e,t){return 0===t.length?null:(t.objectMode?n=t.buffer.shift():!e||e>=t.length?(n=t.decoder?t.buffer.join(""):1===t.buffer.length?t.buffer.first():t.buffer.concat(t.length),t.buffer.clear()):n=t.buffer.consume(e,t.decoder),n);var n}function P(e){var t=e._readableState;r("endReadable",t.endEmitted),t.endEmitted||(t.ended=!0,process.nextTick(U,t,e))}function U(e,t){if(r("endReadableNT",e.endEmitted,e.length),!e.endEmitted&&0===e.length&&(e.endEmitted=!0,t.readable=!1,t.emit("end"),e.autoDestroy)){var n=t._writableState;(!n||n.autoDestroy&&n.finished)&&t.destroy()}}function j(e,t){for(var n=0,o=e.length;n=t.highWaterMark:t.length>0)||t.ended))return r("read: emitReadable",t.length,t.ended),0===t.length&&t.ended?P(this):A(this),null;if(0===(e=C(e,t))&&t.ended)return 0===t.length&&P(this),null;var o,i=t.needReadable;return r("need readable",i),(0===t.length||t.length-e0?L(e,t):null)?(t.needReadable=t.length<=t.highWaterMark,e=0):(t.length-=e,t.awaitDrain=0),0===t.length&&(t.ended||(t.needReadable=!0),n!==e&&t.ended&&P(this)),null!==o&&this.emit("data",o),o},k.prototype._read=function(e){v(this,new y("_read()"))},k.prototype.pipe=function(e,t){var n=this,o=this._readableState;switch(o.pipesCount){case 0:o.pipes=e;break;case 1:o.pipes=[o.pipes,e];break;default:o.pipes.push(e)}o.pipesCount+=1,r("pipe count=%d opts=%j",o.pipesCount,t);var a=t&&!1===t.end||e===process.stdout||e===process.stderr?f:s;function s(){r("onend"),e.end()}o.endEmitted?process.nextTick(a):n.once("end",a),e.on("unpipe",(function t(i,a){r("onunpipe"),i===n&&a&&!1===a.hasUnpiped&&(a.hasUnpiped=!0,r("cleanup"),e.removeListener("close",h),e.removeListener("finish",p),e.removeListener("drain",u),e.removeListener("error",d),e.removeListener("unpipe",t),n.removeListener("end",s),n.removeListener("end",f),n.removeListener("data",l),c=!0,!o.awaitDrain||e._writableState&&!e._writableState.needDrain||u())}));var u=function(e){return function(){var t=e._readableState;r("pipeOnDrain",t.awaitDrain),t.awaitDrain&&t.awaitDrain--,0===t.awaitDrain&&i(e,"data")&&(t.flowing=!0,N(e))}}(n);e.on("drain",u);var c=!1;function l(t){r("ondata");var i=e.write(t);r("dest.write",i),!1===i&&((1===o.pipesCount&&o.pipes===e||o.pipesCount>1&&-1!==j(o.pipes,e))&&!c&&(r("false write response, pause",o.awaitDrain),o.awaitDrain++),n.pause())}function d(t){r("onerror",t),f(),e.removeListener("error",d),0===i(e,"error")&&v(e,t)}function h(){e.removeListener("finish",p),f()}function p(){r("onfinish"),e.removeListener("close",h),f()}function f(){r("unpipe"),n.unpipe(e)}return n.on("data",l),function(e,t,n){if("function"==typeof e.prependListener)return e.prependListener(t,n);e._events&&e._events.error?Array.isArray(e._events.error)?e._events.error.unshift(n):e._events.error=[n,e._events.error]:e.on(t,n)}(e,"error",d),e.once("close",h),e.once("finish",p),e.emit("pipe",n),o.flowing||(r("pipe resume"),n.resume()),e},k.prototype.unpipe=function(e){var t=this._readableState,n={hasUnpiped:!1};if(0===t.pipesCount)return this;if(1===t.pipesCount)return e&&e!==t.pipes||(e||(e=t.pipes),t.pipes=null,t.pipesCount=0,t.flowing=!1,e&&e.emit("unpipe",this,n)),this;if(!e){var o=t.pipes,r=t.pipesCount;t.pipes=null,t.pipesCount=0,t.flowing=!1;for(var i=0;i0,!1!==o.flowing&&this.resume()):"readable"===e&&(o.endEmitted||o.readableListening||(o.readableListening=o.needReadable=!0,o.flowing=!1,o.emittedReadable=!1,r("on readable",o.length,o.reading),o.length?A(this):o.reading||process.nextTick(O,this))),n},k.prototype.addListener=k.prototype.on,k.prototype.removeListener=function(e,t){var n=a.prototype.removeListener.call(this,e,t);return"readable"===e&&process.nextTick(M,this),n},k.prototype.removeAllListeners=function(e){var t=a.prototype.removeAllListeners.apply(this,arguments);return"readable"!==e&&void 0!==e||process.nextTick(M,this),t},k.prototype.resume=function(){var e=this._readableState;return e.flowing||(r("resume"),e.flowing=!e.readableListening,function(e,t){t.resumeScheduled||(t.resumeScheduled=!0,process.nextTick(B,e,t))}(this,e)),e.paused=!1,this},k.prototype.pause=function(){return r("call pause flowing=%j",this._readableState.flowing),!1!==this._readableState.flowing&&(r("pause"),this._readableState.flowing=!1,this.emit("pause")),this._readableState.paused=!0,this},k.prototype.wrap=function(e){var t=this,n=this._readableState,o=!1;for(var i in e.on("end",(function(){if(r("wrapped end"),n.decoder&&!n.ended){var e=n.decoder.end();e&&e.length&&t.push(e)}t.push(null)})),e.on("data",(function(i){r("wrapped data"),n.decoder&&(i=n.decoder.write(i)),n.objectMode&&null==i||(n.objectMode||i&&i.length)&&(t.push(i)||(o=!0,e.pause()))})),e)void 0===this[i]&&"function"==typeof e[i]&&(this[i]=function(t){return function(){return e[t].apply(e,arguments)}}(i));for(var a=0;a{"use strict";e.exports=l;var o=n(84419).q,r=o.ERR_METHOD_NOT_IMPLEMENTED,i=o.ERR_MULTIPLE_CALLBACK,a=o.ERR_TRANSFORM_ALREADY_TRANSFORMING,s=o.ERR_TRANSFORM_WITH_LENGTH_0,u=n(34390);function c(e,t){var n=this._transformState;n.transforming=!1;var o=n.writecb;if(null===o)return this.emit("error",new i);n.writechunk=null,n.writecb=null,null!=t&&this.push(t),o(e);var r=this._readableState;r.reading=!1,(r.needReadable||r.length{"use strict";function o(e){var t=this;this.next=null,this.entry=null,this.finish=function(){!function(e,t,n){var o=e.entry;for(e.entry=null;o;){var r=o.callback;t.pendingcb--,r(undefined),o=o.next}t.corkedRequestsFree.next=e}(t,e)}}var r;e.exports=k,k.WritableState=E;var i,a={deprecate:n(94927)},s=n(59819),u=n(48764).Buffer,c=n.g.Uint8Array||function(){},l=n(75997),d=n(898).getHighWaterMark,h=n(84419).q,p=h.ERR_INVALID_ARG_TYPE,f=h.ERR_METHOD_NOT_IMPLEMENTED,g=h.ERR_MULTIPLE_CALLBACK,m=h.ERR_STREAM_CANNOT_PIPE,_=h.ERR_STREAM_DESTROYED,F=h.ERR_STREAM_NULL_VALUES,y=h.ERR_STREAM_WRITE_AFTER_END,b=h.ERR_UNKNOWN_ENCODING,v=l.errorOrDestroy;function w(){}function E(e,t,i){r=r||n(34390),e=e||{},"boolean"!=typeof i&&(i=t instanceof r),this.objectMode=!!e.objectMode,i&&(this.objectMode=this.objectMode||!!e.writableObjectMode),this.highWaterMark=d(this,e,"writableHighWaterMark",i),this.finalCalled=!1,this.needDrain=!1,this.ending=!1,this.ended=!1,this.finished=!1,this.destroyed=!1;var a=!1===e.decodeStrings;this.decodeStrings=!a,this.defaultEncoding=e.defaultEncoding||"utf8",this.length=0,this.writing=!1,this.corked=0,this.sync=!0,this.bufferProcessing=!1,this.onwrite=function(e){!function(e,t){var n=e._writableState,o=n.sync,r=n.writecb;if("function"!=typeof r)throw new g;if(function(e){e.writing=!1,e.writecb=null,e.length-=e.writelen,e.writelen=0}(n),t)!function(e,t,n,o,r){--t.pendingcb,n?(process.nextTick(r,o),process.nextTick(T,e,t),e._writableState.errorEmitted=!0,v(e,o)):(r(o),e._writableState.errorEmitted=!0,v(e,o),T(e,t))}(e,n,o,t,r);else{var i=C(n)||e.destroyed;i||n.corked||n.bufferProcessing||!n.bufferedRequest||x(e,n),o?process.nextTick(S,e,n,i,r):S(e,n,i,r)}}(t,e)},this.writecb=null,this.writelen=0,this.bufferedRequest=null,this.lastBufferedRequest=null,this.pendingcb=0,this.prefinished=!1,this.errorEmitted=!1,this.emitClose=!1!==e.emitClose,this.autoDestroy=!!e.autoDestroy,this.bufferedRequestCount=0,this.corkedRequestsFree=new o(this)}function k(e){var t=this instanceof(r=r||n(34390));if(!t&&!i.call(k,this))return new k(e);this._writableState=new E(e,this,t),this.writable=!0,e&&("function"==typeof e.write&&(this._write=e.write),"function"==typeof e.writev&&(this._writev=e.writev),"function"==typeof e.destroy&&(this._destroy=e.destroy),"function"==typeof e.final&&(this._final=e.final)),s.call(this)}function D(e,t,n,o,r,i,a){t.writelen=o,t.writecb=a,t.writing=!0,t.sync=!0,t.destroyed?t.onwrite(new _("write")):n?e._writev(r,t.onwrite):e._write(r,i,t.onwrite),t.sync=!1}function S(e,t,n,o){n||function(e,t){0===t.length&&t.needDrain&&(t.needDrain=!1,e.emit("drain"))}(e,t),t.pendingcb--,o(),T(e,t)}function x(e,t){t.bufferProcessing=!0;var n=t.bufferedRequest;if(e._writev&&n&&n.next){var r=t.bufferedRequestCount,i=new Array(r),a=t.corkedRequestsFree;a.entry=n;for(var s=0,u=!0;n;)i[s]=n,n.isBuf||(u=!1),n=n.next,s+=1;i.allBuffers=u,D(e,t,!0,t.length,i,"",a.finish),t.pendingcb++,t.lastBufferedRequest=null,a.next?(t.corkedRequestsFree=a.next,a.next=null):t.corkedRequestsFree=new o(t),t.bufferedRequestCount=0}else{for(;n;){var c=n.chunk,l=n.encoding,d=n.callback;if(D(e,t,!1,t.objectMode?1:c.length,c,l,d),n=n.next,t.bufferedRequestCount--,t.writing)break}null===n&&(t.lastBufferedRequest=null)}t.bufferedRequest=n,t.bufferProcessing=!1}function C(e){return e.ending&&0===e.length&&null===e.bufferedRequest&&!e.finished&&!e.writing}function A(e,t){e._final((function(n){t.pendingcb--,n&&v(e,n),t.prefinished=!0,e.emit("prefinish"),T(e,t)}))}function T(e,t){var n=C(t);if(n&&(function(e,t){t.prefinished||t.finalCalled||("function"!=typeof e._final||t.destroyed?(t.prefinished=!0,e.emit("prefinish")):(t.pendingcb++,t.finalCalled=!0,process.nextTick(A,e,t)))}(e,t),0===t.pendingcb&&(t.finished=!0,e.emit("finish"),t.autoDestroy))){var o=e._readableState;(!o||o.autoDestroy&&o.endEmitted)&&e.destroy()}return n}n(35717)(k,s),E.prototype.getBuffer=function(){for(var e=this.bufferedRequest,t=[];e;)t.push(e),e=e.next;return t},function(){try{Object.defineProperty(E.prototype,"buffer",{get:a.deprecate((function(){return this.getBuffer()}),"_writableState.buffer is deprecated. Use _writableState.getBuffer instead.","DEP0003")})}catch(e){}}(),"function"==typeof Symbol&&Symbol.hasInstance&&"function"==typeof Function.prototype[Symbol.hasInstance]?(i=Function.prototype[Symbol.hasInstance],Object.defineProperty(k,Symbol.hasInstance,{value:function(e){return!!i.call(this,e)||this===k&&e&&e._writableState instanceof E}})):i=function(e){return e instanceof this},k.prototype.pipe=function(){v(this,new m)},k.prototype.write=function(e,t,n){var o,r=this._writableState,i=!1,a=!r.objectMode&&(o=e,u.isBuffer(o)||o instanceof c);return a&&!u.isBuffer(e)&&(e=function(e){return u.from(e)}(e)),"function"==typeof t&&(n=t,t=null),a?t="buffer":t||(t=r.defaultEncoding),"function"!=typeof n&&(n=w),r.ending?function(e,t){var n=new y;v(e,n),process.nextTick(t,n)}(this,n):(a||function(e,t,n,o){var r;return null===n?r=new F:"string"==typeof n||t.objectMode||(r=new p("chunk",["string","Buffer"],n)),!r||(v(e,r),process.nextTick(o,r),!1)}(this,r,e,n))&&(r.pendingcb++,i=function(e,t,n,o,r,i){if(!n){var a=function(e,t,n){return e.objectMode||!1===e.decodeStrings||"string"!=typeof t||(t=u.from(t,n)),t}(t,o,r);o!==a&&(n=!0,r="buffer",o=a)}var s=t.objectMode?1:o.length;t.length+=s;var c=t.length-1))throw new b(e);return this._writableState.defaultEncoding=e,this},Object.defineProperty(k.prototype,"writableBuffer",{enumerable:!1,get:function(){return this._writableState&&this._writableState.getBuffer()}}),Object.defineProperty(k.prototype,"writableHighWaterMark",{enumerable:!1,get:function(){return this._writableState.highWaterMark}}),k.prototype._write=function(e,t,n){n(new f("_write()"))},k.prototype._writev=null,k.prototype.end=function(e,t,n){var o=this._writableState;return"function"==typeof e?(n=e,e=null,t=null):"function"==typeof t&&(n=t,t=null),null!=e&&this.write(e,t),o.corked&&(o.corked=1,this.uncork()),o.ending||function(e,t,n){t.ending=!0,T(e,t),n&&(t.finished?process.nextTick(n):e.once("finish",n)),t.ended=!0,e.writable=!1}(this,o,n),this},Object.defineProperty(k.prototype,"writableLength",{enumerable:!1,get:function(){return this._writableState.length}}),Object.defineProperty(k.prototype,"destroyed",{enumerable:!1,get:function(){return void 0!==this._writableState&&this._writableState.destroyed},set:function(e){this._writableState&&(this._writableState.destroyed=e)}}),k.prototype.destroy=l.destroy,k.prototype._undestroy=l.undestroy,k.prototype._destroy=function(e,t){t(e)}},54887:(e,t,n)=>{"use strict";var o;function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var i=n(5800),a=Symbol("lastResolve"),s=Symbol("lastReject"),u=Symbol("error"),c=Symbol("ended"),l=Symbol("lastPromise"),d=Symbol("handlePromise"),h=Symbol("stream");function p(e,t){return{value:e,done:t}}function f(e){var t=e[a];if(null!==t){var n=e[h].read();null!==n&&(e[l]=null,e[a]=null,e[s]=null,t(p(n,!1)))}}function g(e){process.nextTick(f,e)}var m=Object.getPrototypeOf((function(){})),_=Object.setPrototypeOf((r(o={get stream(){return this[h]},next:function(){var e=this,t=this[u];if(null!==t)return Promise.reject(t);if(this[c])return Promise.resolve(p(void 0,!0));if(this[h].destroyed)return new Promise((function(t,n){process.nextTick((function(){e[u]?n(e[u]):t(p(void 0,!0))}))}));var n,o=this[l];if(o)n=new Promise(function(e,t){return function(n,o){e.then((function(){t[c]?n(p(void 0,!0)):t[d](n,o)}),o)}}(o,this));else{var r=this[h].read();if(null!==r)return Promise.resolve(p(r,!1));n=new Promise(this[d])}return this[l]=n,n}},Symbol.asyncIterator,(function(){return this})),r(o,"return",(function(){var e=this;return new Promise((function(t,n){e[h].destroy(null,(function(e){e?n(e):t(p(void 0,!0))}))}))})),o),m);e.exports=function(e){var t,n=Object.create(_,(r(t={},h,{value:e,writable:!0}),r(t,a,{value:null,writable:!0}),r(t,s,{value:null,writable:!0}),r(t,u,{value:null,writable:!0}),r(t,c,{value:e._readableState.endEmitted,writable:!0}),r(t,d,{value:function(e,t){var o=n[h].read();o?(n[l]=null,n[a]=null,n[s]=null,e(p(o,!1))):(n[a]=e,n[s]=t)},writable:!0}),t));return n[l]=null,i(e,(function(e){if(e&&"ERR_STREAM_PREMATURE_CLOSE"!==e.code){var t=n[s];return null!==t&&(n[l]=null,n[a]=null,n[s]=null,t(e)),void(n[u]=e)}var o=n[a];null!==o&&(n[l]=null,n[a]=null,n[s]=null,o(p(void 0,!0))),n[c]=!0})),e.on("readable",g.bind(null,n)),n}},76633:(e,t,n)=>{"use strict";function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){for(var n=0;n0?this.tail.next=t:this.head=t,this.tail=t,++this.length}},{key:"unshift",value:function(e){var t={data:e,next:this.head};0===this.length&&(this.tail=t),this.head=t,++this.length}},{key:"shift",value:function(){if(0!==this.length){var e=this.head.data;return 1===this.length?this.head=this.tail=null:this.head=this.head.next,--this.length,e}}},{key:"clear",value:function(){this.head=this.tail=null,this.length=0}},{key:"join",value:function(e){if(0===this.length)return"";for(var t=this.head,n=""+t.data;t=t.next;)n+=e+t.data;return n}},{key:"concat",value:function(e){if(0===this.length)return a.alloc(0);for(var t,n,o,r=a.allocUnsafe(e>>>0),i=this.head,s=0;i;)t=i.data,n=r,o=s,a.prototype.copy.call(t,n,o),s+=i.data.length,i=i.next;return r}},{key:"consume",value:function(e,t){var n;return er.length?r.length:e;if(i===r.length?o+=r:o+=r.slice(0,e),0==(e-=i)){i===r.length?(++n,t.next?this.head=t.next:this.head=this.tail=null):(this.head=t,t.data=r.slice(i));break}++n}return this.length-=n,o}},{key:"_getBuffer",value:function(e){var t=a.allocUnsafe(e),n=this.head,o=1;for(n.data.copy(t),e-=n.data.length;n=n.next;){var r=n.data,i=e>r.length?r.length:e;if(r.copy(t,t.length-e,0,i),0==(e-=i)){i===r.length?(++o,n.next?this.head=n.next:this.head=this.tail=null):(this.head=n,n.data=r.slice(i));break}++o}return this.length-=o,t}},{key:u,value:function(e,t){return s(this,function(e){for(var t=1;t{"use strict";function t(e,t){o(e,t),n(e)}function n(e){e._writableState&&!e._writableState.emitClose||e._readableState&&!e._readableState.emitClose||e.emit("close")}function o(e,t){e.emit("error",t)}e.exports={destroy:function(e,r){var i=this,a=this._readableState&&this._readableState.destroyed,s=this._writableState&&this._writableState.destroyed;return a||s?(r?r(e):e&&(this._writableState?this._writableState.errorEmitted||(this._writableState.errorEmitted=!0,process.nextTick(o,this,e)):process.nextTick(o,this,e)),this):(this._readableState&&(this._readableState.destroyed=!0),this._writableState&&(this._writableState.destroyed=!0),this._destroy(e||null,(function(e){!r&&e?i._writableState?i._writableState.errorEmitted?process.nextTick(n,i):(i._writableState.errorEmitted=!0,process.nextTick(t,i,e)):process.nextTick(t,i,e):r?(process.nextTick(n,i),r(e)):process.nextTick(n,i)})),this)},undestroy:function(){this._readableState&&(this._readableState.destroyed=!1,this._readableState.reading=!1,this._readableState.ended=!1,this._readableState.endEmitted=!1),this._writableState&&(this._writableState.destroyed=!1,this._writableState.ended=!1,this._writableState.ending=!1,this._writableState.finalCalled=!1,this._writableState.prefinished=!1,this._writableState.finished=!1,this._writableState.errorEmitted=!1)},errorOrDestroy:function(e,t){var n=e._readableState,o=e._writableState;n&&n.autoDestroy||o&&o.autoDestroy?e.destroy(t):e.emit("error",t)}}},5800:(e,t,n)=>{"use strict";var o=n(84419).q.ERR_STREAM_PREMATURE_CLOSE;function r(){}e.exports=function e(t,n,i){if("function"==typeof n)return e(t,null,n);n||(n={}),i=function(e){var t=!1;return function(){if(!t){t=!0;for(var n=arguments.length,o=new Array(n),r=0;r{e.exports=function(){throw new Error("Readable.from is not available in the browser")}},37065:(e,t,n)=>{"use strict";var o,r=n(84419).q,i=r.ERR_MISSING_ARGS,a=r.ERR_STREAM_DESTROYED;function s(e){if(e)throw e}function u(e,t,r,i){i=function(e){var t=!1;return function(){t||(t=!0,e.apply(void 0,arguments))}}(i);var s=!1;e.on("close",(function(){s=!0})),void 0===o&&(o=n(5800)),o(e,{readable:t,writable:r},(function(e){if(e)return i(e);s=!0,i()}));var u=!1;return function(t){if(!s&&!u)return u=!0,function(e){return e.setHeader&&"function"==typeof e.abort}(e)?e.abort():"function"==typeof e.destroy?e.destroy():void i(t||new a("pipe"))}}function c(e){e()}function l(e,t){return e.pipe(t)}function d(e){return e.length?"function"!=typeof e[e.length-1]?s:e.pop():s}e.exports=function(){for(var e=arguments.length,t=new Array(e),n=0;n0,(function(e){o||(o=e),e&&a.forEach(c),i||(a.forEach(c),r(o))}))}));return t.reduce(l)}},898:(e,t,n)=>{"use strict";var o=n(84419).q.ERR_INVALID_OPT_VALUE;e.exports={getHighWaterMark:function(e,t,n,r){var i=function(e,t,n){return null!=e.highWaterMark?e.highWaterMark:t?e[n]:null}(t,r,n);if(null!=i){if(!isFinite(i)||Math.floor(i)!==i||i<0)throw new o(r?n:"highWaterMark",i);return Math.floor(i)}return e.objectMode?16:16384}}},59819:(e,t,n)=>{e.exports=n(17187).EventEmitter},23872:(e,t,n)=>{(t=e.exports=n(44960)).Stream=t,t.Readable=t,t.Writable=n(92010),t.Duplex=n(34390),t.Transform=n(3912),t.PassThrough=n(41294),t.finished=n(5800),t.pipeline=n(37065)},77191:(e,t,n)=>{var o=n(58162);e.exports=o("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz")},55420:e=>{var t=Object.prototype.toString,n="function"==typeof Buffer.alloc&&"function"==typeof Buffer.allocUnsafe&&"function"==typeof Buffer.from;e.exports=function(e,o,r){if("number"==typeof e)throw new TypeError('"value" argument must not be a number');return i=e,"ArrayBuffer"===t.call(i).slice(8,-1)?function(e,t,o){t>>>=0;var r=e.byteLength-t;if(r<0)throw new RangeError("'offset' is out of bounds");if(void 0===o)o=r;else if((o>>>=0)>r)throw new RangeError("'length' is out of bounds");return n?Buffer.from(e.slice(t,t+o)):new Buffer(new Uint8Array(e.slice(t,t+o)))}(e,o,r):"string"==typeof e?function(e,t){if("string"==typeof t&&""!==t||(t="utf8"),!Buffer.isEncoding(t))throw new TypeError('"encoding" must be a valid string encoding');return n?Buffer.from(e,t):new Buffer(e,t)}(e,o):n?Buffer.from(e):new Buffer(e);var i}},67295:e=>{e.exports=function(e,t){for(var n=Math.min(e.length,t.length),o=new Buffer(n),r=0;r{"use strict";const o=n(79742),r=n(80645),i="function"==typeof Symbol&&"function"==typeof Symbol.for?Symbol.for("nodejs.util.inspect.custom"):null;t.Buffer=u,t.SlowBuffer=function(e){return+e!=e&&(e=0),u.alloc(+e)},t.INSPECT_MAX_BYTES=50;const a=2147483647;function s(e){if(e>a)throw new RangeError('The value "'+e+'" is invalid for option "size"');const t=new Uint8Array(e);return Object.setPrototypeOf(t,u.prototype),t}function u(e,t,n){if("number"==typeof e){if("string"==typeof t)throw new TypeError('The "string" argument must be of type string. Received type number');return d(e)}return c(e,t,n)}function c(e,t,n){if("string"==typeof e)return function(e,t){if("string"==typeof t&&""!==t||(t="utf8"),!u.isEncoding(t))throw new TypeError("Unknown encoding: "+t);const n=0|g(e,t);let o=s(n);const r=o.write(e,t);return r!==n&&(o=o.slice(0,r)),o}(e,t);if(ArrayBuffer.isView(e))return function(e){if(Y(e,Uint8Array)){const t=new Uint8Array(e);return p(t.buffer,t.byteOffset,t.byteLength)}return h(e)}(e);if(null==e)throw new TypeError("The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type "+typeof e);if(Y(e,ArrayBuffer)||e&&Y(e.buffer,ArrayBuffer))return p(e,t,n);if("undefined"!=typeof SharedArrayBuffer&&(Y(e,SharedArrayBuffer)||e&&Y(e.buffer,SharedArrayBuffer)))return p(e,t,n);if("number"==typeof e)throw new TypeError('The "value" argument must not be of type number. Received type number');const o=e.valueOf&&e.valueOf();if(null!=o&&o!==e)return u.from(o,t,n);const r=function(e){if(u.isBuffer(e)){const t=0|f(e.length),n=s(t);return 0===n.length||e.copy(n,0,0,t),n}return void 0!==e.length?"number"!=typeof e.length||Z(e.length)?s(0):h(e):"Buffer"===e.type&&Array.isArray(e.data)?h(e.data):void 0}(e);if(r)return r;if("undefined"!=typeof Symbol&&null!=Symbol.toPrimitive&&"function"==typeof e[Symbol.toPrimitive])return u.from(e[Symbol.toPrimitive]("string"),t,n);throw new TypeError("The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type "+typeof e)}function l(e){if("number"!=typeof e)throw new TypeError('"size" argument must be of type number');if(e<0)throw new RangeError('The value "'+e+'" is invalid for option "size"')}function d(e){return l(e),s(e<0?0:0|f(e))}function h(e){const t=e.length<0?0:0|f(e.length),n=s(t);for(let o=0;o=a)throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+a.toString(16)+" bytes");return 0|e}function g(e,t){if(u.isBuffer(e))return e.length;if(ArrayBuffer.isView(e)||Y(e,ArrayBuffer))return e.byteLength;if("string"!=typeof e)throw new TypeError('The "string" argument must be one of type string, Buffer, or ArrayBuffer. Received type '+typeof e);const n=e.length,o=arguments.length>2&&!0===arguments[2];if(!o&&0===n)return 0;let r=!1;for(;;)switch(t){case"ascii":case"latin1":case"binary":return n;case"utf8":case"utf-8":return H(e).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*n;case"hex":return n>>>1;case"base64":return V(e).length;default:if(r)return o?-1:H(e).length;t=(""+t).toLowerCase(),r=!0}}function m(e,t,n){let o=!1;if((void 0===t||t<0)&&(t=0),t>this.length)return"";if((void 0===n||n>this.length)&&(n=this.length),n<=0)return"";if((n>>>=0)<=(t>>>=0))return"";for(e||(e="utf8");;)switch(e){case"hex":return T(this,t,n);case"utf8":case"utf-8":return S(this,t,n);case"ascii":return C(this,t,n);case"latin1":case"binary":return A(this,t,n);case"base64":return D(this,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return R(this,t,n);default:if(o)throw new TypeError("Unknown encoding: "+e);e=(e+"").toLowerCase(),o=!0}}function _(e,t,n){const o=e[t];e[t]=e[n],e[n]=o}function F(e,t,n,o,r){if(0===e.length)return-1;if("string"==typeof n?(o=n,n=0):n>2147483647?n=2147483647:n<-2147483648&&(n=-2147483648),Z(n=+n)&&(n=r?0:e.length-1),n<0&&(n=e.length+n),n>=e.length){if(r)return-1;n=e.length-1}else if(n<0){if(!r)return-1;n=0}if("string"==typeof t&&(t=u.from(t,o)),u.isBuffer(t))return 0===t.length?-1:y(e,t,n,o,r);if("number"==typeof t)return t&=255,"function"==typeof Uint8Array.prototype.indexOf?r?Uint8Array.prototype.indexOf.call(e,t,n):Uint8Array.prototype.lastIndexOf.call(e,t,n):y(e,[t],n,o,r);throw new TypeError("val must be string, number or Buffer")}function y(e,t,n,o,r){let i,a=1,s=e.length,u=t.length;if(void 0!==o&&("ucs2"===(o=String(o).toLowerCase())||"ucs-2"===o||"utf16le"===o||"utf-16le"===o)){if(e.length<2||t.length<2)return-1;a=2,s/=2,u/=2,n/=2}function c(e,t){return 1===a?e[t]:e.readUInt16BE(t*a)}if(r){let o=-1;for(i=n;is&&(n=s-u),i=n;i>=0;i--){let n=!0;for(let o=0;or&&(o=r):o=r;const i=t.length;let a;for(o>i/2&&(o=i/2),a=0;a>8,r=n%256,i.push(r),i.push(o);return i}(t,e.length-n),e,n,o)}function D(e,t,n){return 0===t&&n===e.length?o.fromByteArray(e):o.fromByteArray(e.slice(t,n))}function S(e,t,n){n=Math.min(e.length,n);const o=[];let r=t;for(;r239?4:t>223?3:t>191?2:1;if(r+a<=n){let n,o,s,u;switch(a){case 1:t<128&&(i=t);break;case 2:n=e[r+1],128==(192&n)&&(u=(31&t)<<6|63&n,u>127&&(i=u));break;case 3:n=e[r+1],o=e[r+2],128==(192&n)&&128==(192&o)&&(u=(15&t)<<12|(63&n)<<6|63&o,u>2047&&(u<55296||u>57343)&&(i=u));break;case 4:n=e[r+1],o=e[r+2],s=e[r+3],128==(192&n)&&128==(192&o)&&128==(192&s)&&(u=(15&t)<<18|(63&n)<<12|(63&o)<<6|63&s,u>65535&&u<1114112&&(i=u))}}null===i?(i=65533,a=1):i>65535&&(i-=65536,o.push(i>>>10&1023|55296),i=56320|1023&i),o.push(i),r+=a}return function(e){const t=e.length;if(t<=x)return String.fromCharCode.apply(String,e);let n="",o=0;for(;oo.length?(u.isBuffer(t)||(t=u.from(t)),t.copy(o,r)):Uint8Array.prototype.set.call(o,t,r);else{if(!u.isBuffer(t))throw new TypeError('"list" argument must be an Array of Buffers');t.copy(o,r)}r+=t.length}return o},u.byteLength=g,u.prototype._isBuffer=!0,u.prototype.swap16=function(){const e=this.length;if(e%2!=0)throw new RangeError("Buffer size must be a multiple of 16-bits");for(let t=0;tn&&(e+=" ... "),""},i&&(u.prototype[i]=u.prototype.inspect),u.prototype.compare=function(e,t,n,o,r){if(Y(e,Uint8Array)&&(e=u.from(e,e.offset,e.byteLength)),!u.isBuffer(e))throw new TypeError('The "target" argument must be one of type Buffer or Uint8Array. Received type '+typeof e);if(void 0===t&&(t=0),void 0===n&&(n=e?e.length:0),void 0===o&&(o=0),void 0===r&&(r=this.length),t<0||n>e.length||o<0||r>this.length)throw new RangeError("out of range index");if(o>=r&&t>=n)return 0;if(o>=r)return-1;if(t>=n)return 1;if(this===e)return 0;let i=(r>>>=0)-(o>>>=0),a=(n>>>=0)-(t>>>=0);const s=Math.min(i,a),c=this.slice(o,r),l=e.slice(t,n);for(let e=0;e>>=0,isFinite(n)?(n>>>=0,void 0===o&&(o="utf8")):(o=n,n=void 0)}const r=this.length-t;if((void 0===n||n>r)&&(n=r),e.length>0&&(n<0||t<0)||t>this.length)throw new RangeError("Attempt to write outside buffer bounds");o||(o="utf8");let i=!1;for(;;)switch(o){case"hex":return b(this,e,t,n);case"utf8":case"utf-8":return v(this,e,t,n);case"ascii":case"latin1":case"binary":return w(this,e,t,n);case"base64":return E(this,e,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return k(this,e,t,n);default:if(i)throw new TypeError("Unknown encoding: "+o);o=(""+o).toLowerCase(),i=!0}},u.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};const x=4096;function C(e,t,n){let o="";n=Math.min(e.length,n);for(let r=t;ro)&&(n=o);let r="";for(let o=t;on)throw new RangeError("Trying to access beyond buffer length")}function M(e,t,n,o,r,i){if(!u.isBuffer(e))throw new TypeError('"buffer" argument must be a Buffer instance');if(t>r||te.length)throw new RangeError("Index out of range")}function O(e,t,n,o,r){z(t,o,r,e,n,7);let i=Number(t&BigInt(4294967295));e[n++]=i,i>>=8,e[n++]=i,i>>=8,e[n++]=i,i>>=8,e[n++]=i;let a=Number(t>>BigInt(32)&BigInt(4294967295));return e[n++]=a,a>>=8,e[n++]=a,a>>=8,e[n++]=a,a>>=8,e[n++]=a,n}function B(e,t,n,o,r){z(t,o,r,e,n,7);let i=Number(t&BigInt(4294967295));e[n+7]=i,i>>=8,e[n+6]=i,i>>=8,e[n+5]=i,i>>=8,e[n+4]=i;let a=Number(t>>BigInt(32)&BigInt(4294967295));return e[n+3]=a,a>>=8,e[n+2]=a,a>>=8,e[n+1]=a,a>>=8,e[n]=a,n+8}function N(e,t,n,o,r,i){if(n+o>e.length)throw new RangeError("Index out of range");if(n<0)throw new RangeError("Index out of range")}function L(e,t,n,o,i){return t=+t,n>>>=0,i||N(e,0,n,4),r.write(e,t,n,o,23,4),n+4}function P(e,t,n,o,i){return t=+t,n>>>=0,i||N(e,0,n,8),r.write(e,t,n,o,52,8),n+8}u.prototype.slice=function(e,t){const n=this.length;(e=~~e)<0?(e+=n)<0&&(e=0):e>n&&(e=n),(t=void 0===t?n:~~t)<0?(t+=n)<0&&(t=0):t>n&&(t=n),t>>=0,t>>>=0,n||I(e,t,this.length);let o=this[e],r=1,i=0;for(;++i>>=0,t>>>=0,n||I(e,t,this.length);let o=this[e+--t],r=1;for(;t>0&&(r*=256);)o+=this[e+--t]*r;return o},u.prototype.readUint8=u.prototype.readUInt8=function(e,t){return e>>>=0,t||I(e,1,this.length),this[e]},u.prototype.readUint16LE=u.prototype.readUInt16LE=function(e,t){return e>>>=0,t||I(e,2,this.length),this[e]|this[e+1]<<8},u.prototype.readUint16BE=u.prototype.readUInt16BE=function(e,t){return e>>>=0,t||I(e,2,this.length),this[e]<<8|this[e+1]},u.prototype.readUint32LE=u.prototype.readUInt32LE=function(e,t){return e>>>=0,t||I(e,4,this.length),(this[e]|this[e+1]<<8|this[e+2]<<16)+16777216*this[e+3]},u.prototype.readUint32BE=u.prototype.readUInt32BE=function(e,t){return e>>>=0,t||I(e,4,this.length),16777216*this[e]+(this[e+1]<<16|this[e+2]<<8|this[e+3])},u.prototype.readBigUInt64LE=J((function(e){K(e>>>=0,"offset");const t=this[e],n=this[e+7];void 0!==t&&void 0!==n||G(e,this.length-8);const o=t+256*this[++e]+65536*this[++e]+this[++e]*2**24,r=this[++e]+256*this[++e]+65536*this[++e]+n*2**24;return BigInt(o)+(BigInt(r)<>>=0,"offset");const t=this[e],n=this[e+7];void 0!==t&&void 0!==n||G(e,this.length-8);const o=t*2**24+65536*this[++e]+256*this[++e]+this[++e],r=this[++e]*2**24+65536*this[++e]+256*this[++e]+n;return(BigInt(o)<>>=0,t>>>=0,n||I(e,t,this.length);let o=this[e],r=1,i=0;for(;++i=r&&(o-=Math.pow(2,8*t)),o},u.prototype.readIntBE=function(e,t,n){e>>>=0,t>>>=0,n||I(e,t,this.length);let o=t,r=1,i=this[e+--o];for(;o>0&&(r*=256);)i+=this[e+--o]*r;return r*=128,i>=r&&(i-=Math.pow(2,8*t)),i},u.prototype.readInt8=function(e,t){return e>>>=0,t||I(e,1,this.length),128&this[e]?-1*(255-this[e]+1):this[e]},u.prototype.readInt16LE=function(e,t){e>>>=0,t||I(e,2,this.length);const n=this[e]|this[e+1]<<8;return 32768&n?4294901760|n:n},u.prototype.readInt16BE=function(e,t){e>>>=0,t||I(e,2,this.length);const n=this[e+1]|this[e]<<8;return 32768&n?4294901760|n:n},u.prototype.readInt32LE=function(e,t){return e>>>=0,t||I(e,4,this.length),this[e]|this[e+1]<<8|this[e+2]<<16|this[e+3]<<24},u.prototype.readInt32BE=function(e,t){return e>>>=0,t||I(e,4,this.length),this[e]<<24|this[e+1]<<16|this[e+2]<<8|this[e+3]},u.prototype.readBigInt64LE=J((function(e){K(e>>>=0,"offset");const t=this[e],n=this[e+7];void 0!==t&&void 0!==n||G(e,this.length-8);const o=this[e+4]+256*this[e+5]+65536*this[e+6]+(n<<24);return(BigInt(o)<>>=0,"offset");const t=this[e],n=this[e+7];void 0!==t&&void 0!==n||G(e,this.length-8);const o=(t<<24)+65536*this[++e]+256*this[++e]+this[++e];return(BigInt(o)<>>=0,t||I(e,4,this.length),r.read(this,e,!0,23,4)},u.prototype.readFloatBE=function(e,t){return e>>>=0,t||I(e,4,this.length),r.read(this,e,!1,23,4)},u.prototype.readDoubleLE=function(e,t){return e>>>=0,t||I(e,8,this.length),r.read(this,e,!0,52,8)},u.prototype.readDoubleBE=function(e,t){return e>>>=0,t||I(e,8,this.length),r.read(this,e,!1,52,8)},u.prototype.writeUintLE=u.prototype.writeUIntLE=function(e,t,n,o){e=+e,t>>>=0,n>>>=0,o||M(this,e,t,n,Math.pow(2,8*n)-1,0);let r=1,i=0;for(this[t]=255&e;++i>>=0,n>>>=0,o||M(this,e,t,n,Math.pow(2,8*n)-1,0);let r=n-1,i=1;for(this[t+r]=255&e;--r>=0&&(i*=256);)this[t+r]=e/i&255;return t+n},u.prototype.writeUint8=u.prototype.writeUInt8=function(e,t,n){return e=+e,t>>>=0,n||M(this,e,t,1,255,0),this[t]=255&e,t+1},u.prototype.writeUint16LE=u.prototype.writeUInt16LE=function(e,t,n){return e=+e,t>>>=0,n||M(this,e,t,2,65535,0),this[t]=255&e,this[t+1]=e>>>8,t+2},u.prototype.writeUint16BE=u.prototype.writeUInt16BE=function(e,t,n){return e=+e,t>>>=0,n||M(this,e,t,2,65535,0),this[t]=e>>>8,this[t+1]=255&e,t+2},u.prototype.writeUint32LE=u.prototype.writeUInt32LE=function(e,t,n){return e=+e,t>>>=0,n||M(this,e,t,4,4294967295,0),this[t+3]=e>>>24,this[t+2]=e>>>16,this[t+1]=e>>>8,this[t]=255&e,t+4},u.prototype.writeUint32BE=u.prototype.writeUInt32BE=function(e,t,n){return e=+e,t>>>=0,n||M(this,e,t,4,4294967295,0),this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e,t+4},u.prototype.writeBigUInt64LE=J((function(e,t=0){return O(this,e,t,BigInt(0),BigInt("0xffffffffffffffff"))})),u.prototype.writeBigUInt64BE=J((function(e,t=0){return B(this,e,t,BigInt(0),BigInt("0xffffffffffffffff"))})),u.prototype.writeIntLE=function(e,t,n,o){if(e=+e,t>>>=0,!o){const o=Math.pow(2,8*n-1);M(this,e,t,n,o-1,-o)}let r=0,i=1,a=0;for(this[t]=255&e;++r>0)-a&255;return t+n},u.prototype.writeIntBE=function(e,t,n,o){if(e=+e,t>>>=0,!o){const o=Math.pow(2,8*n-1);M(this,e,t,n,o-1,-o)}let r=n-1,i=1,a=0;for(this[t+r]=255&e;--r>=0&&(i*=256);)e<0&&0===a&&0!==this[t+r+1]&&(a=1),this[t+r]=(e/i>>0)-a&255;return t+n},u.prototype.writeInt8=function(e,t,n){return e=+e,t>>>=0,n||M(this,e,t,1,127,-128),e<0&&(e=255+e+1),this[t]=255&e,t+1},u.prototype.writeInt16LE=function(e,t,n){return e=+e,t>>>=0,n||M(this,e,t,2,32767,-32768),this[t]=255&e,this[t+1]=e>>>8,t+2},u.prototype.writeInt16BE=function(e,t,n){return e=+e,t>>>=0,n||M(this,e,t,2,32767,-32768),this[t]=e>>>8,this[t+1]=255&e,t+2},u.prototype.writeInt32LE=function(e,t,n){return e=+e,t>>>=0,n||M(this,e,t,4,2147483647,-2147483648),this[t]=255&e,this[t+1]=e>>>8,this[t+2]=e>>>16,this[t+3]=e>>>24,t+4},u.prototype.writeInt32BE=function(e,t,n){return e=+e,t>>>=0,n||M(this,e,t,4,2147483647,-2147483648),e<0&&(e=4294967295+e+1),this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e,t+4},u.prototype.writeBigInt64LE=J((function(e,t=0){return O(this,e,t,-BigInt("0x8000000000000000"),BigInt("0x7fffffffffffffff"))})),u.prototype.writeBigInt64BE=J((function(e,t=0){return B(this,e,t,-BigInt("0x8000000000000000"),BigInt("0x7fffffffffffffff"))})),u.prototype.writeFloatLE=function(e,t,n){return L(this,e,t,!0,n)},u.prototype.writeFloatBE=function(e,t,n){return L(this,e,t,!1,n)},u.prototype.writeDoubleLE=function(e,t,n){return P(this,e,t,!0,n)},u.prototype.writeDoubleBE=function(e,t,n){return P(this,e,t,!1,n)},u.prototype.copy=function(e,t,n,o){if(!u.isBuffer(e))throw new TypeError("argument should be a Buffer");if(n||(n=0),o||0===o||(o=this.length),t>=e.length&&(t=e.length),t||(t=0),o>0&&o=this.length)throw new RangeError("Index out of range");if(o<0)throw new RangeError("sourceEnd out of bounds");o>this.length&&(o=this.length),e.length-t>>=0,n=void 0===n?this.length:n>>>0,e||(e=0),"number"==typeof e)for(r=t;r=o+4;n-=3)t=`_${e.slice(n-3,n)}${t}`;return`${e.slice(0,n)}${t}`}function z(e,t,n,o,r,i){if(e>n||e3?0===t||t===BigInt(0)?`>= 0${o} and < 2${o} ** ${8*(i+1)}${o}`:`>= -(2${o} ** ${8*(i+1)-1}${o}) and < 2 ** ${8*(i+1)-1}${o}`:`>= ${t}${o} and <= ${n}${o}`,new U.ERR_OUT_OF_RANGE("value",r,e)}!function(e,t,n){K(t,"offset"),void 0!==e[t]&&void 0!==e[t+n]||G(t,e.length-(n+1))}(o,r,i)}function K(e,t){if("number"!=typeof e)throw new U.ERR_INVALID_ARG_TYPE(t,"number",e)}function G(e,t,n){if(Math.floor(e)!==e)throw K(e,n),new U.ERR_OUT_OF_RANGE(n||"offset","an integer",e);if(t<0)throw new U.ERR_BUFFER_OUT_OF_BOUNDS;throw new U.ERR_OUT_OF_RANGE(n||"offset",`>= ${n?1:0} and <= ${t}`,e)}j("ERR_BUFFER_OUT_OF_BOUNDS",(function(e){return e?`${e} is outside of buffer bounds`:"Attempt to access memory outside buffer bounds"}),RangeError),j("ERR_INVALID_ARG_TYPE",(function(e,t){return`The "${e}" argument must be of type number. Received type ${typeof t}`}),TypeError),j("ERR_OUT_OF_RANGE",(function(e,t,n){let o=`The value of "${e}" is out of range.`,r=n;return Number.isInteger(n)&&Math.abs(n)>2**32?r=q(String(n)):"bigint"==typeof n&&(r=String(n),(n>BigInt(2)**BigInt(32)||n<-(BigInt(2)**BigInt(32)))&&(r=q(r)),r+="n"),o+=` It must be ${t}. Received ${r}`,o}),RangeError);const $=/[^+/0-9A-Za-z-_]/g;function H(e,t){let n;t=t||1/0;const o=e.length;let r=null;const i=[];for(let a=0;a55295&&n<57344){if(!r){if(n>56319){(t-=3)>-1&&i.push(239,191,189);continue}if(a+1===o){(t-=3)>-1&&i.push(239,191,189);continue}r=n;continue}if(n<56320){(t-=3)>-1&&i.push(239,191,189),r=n;continue}n=65536+(r-55296<<10|n-56320)}else r&&(t-=3)>-1&&i.push(239,191,189);if(r=null,n<128){if((t-=1)<0)break;i.push(n)}else if(n<2048){if((t-=2)<0)break;i.push(n>>6|192,63&n|128)}else if(n<65536){if((t-=3)<0)break;i.push(n>>12|224,n>>6&63|128,63&n|128)}else{if(!(n<1114112))throw new Error("Invalid code point");if((t-=4)<0)break;i.push(n>>18|240,n>>12&63|128,n>>6&63|128,63&n|128)}}return i}function V(e){return o.toByteArray(function(e){if((e=(e=e.split("=")[0]).trim().replace($,"")).length<2)return"";for(;e.length%4!=0;)e+="=";return e}(e))}function W(e,t,n,o){let r;for(r=0;r=t.length||r>=e.length);++r)t[r+n]=e[r];return r}function Y(e,t){return e instanceof t||null!=e&&null!=e.constructor&&null!=e.constructor.name&&e.constructor.name===t.name}function Z(e){return e!=e}const X=function(){const e="0123456789abcdef",t=new Array(256);for(let n=0;n<16;++n){const o=16*n;for(let r=0;r<16;++r)t[o+r]=e[n]+e[r]}return t}();function J(e){return"undefined"==typeof BigInt?Q:e}function Q(){throw new Error("BigInt not supported")}},21924:(e,t,n)=>{"use strict";var o=n(40210),r=n(55559),i=r(o("String.prototype.indexOf"));e.exports=function(e,t){var n=o(e,!!t);return"function"==typeof n&&i(e,".prototype.")>-1?r(n):n}},55559:(e,t,n)=>{"use strict";var o=n(58612),r=n(40210),i=r("%Function.prototype.apply%"),a=r("%Function.prototype.call%"),s=r("%Reflect.apply%",!0)||o.call(a,i),u=r("%Object.getOwnPropertyDescriptor%",!0),c=r("%Object.defineProperty%",!0),l=r("%Math.max%");if(c)try{c({},"a",{value:1})}catch(e){c=null}e.exports=function(e){var t=s(o,a,arguments);if(u&&c){var n=u(t,"length");n.configurable&&c(t,"length",{value:1+l(0,e.length-(arguments.length-1))})}return t};var d=function(){return s(o,i,arguments)};c?c(e.exports,"apply",{value:d}):e.exports.apply=d},30932:e=>{"use strict";e.exports=function(e,t){var n,o=String(e),r=0;if("string"!=typeof t)throw new Error("Expected character");for(n=o.indexOf(t);-1!==n;)r++,n=o.indexOf(t,n+t.length);return r}},16588:e=>{"use strict";e.exports=JSON.parse('{"AElig":"Æ","AMP":"&","Aacute":"Á","Acirc":"Â","Agrave":"À","Aring":"Å","Atilde":"Ã","Auml":"Ä","COPY":"©","Ccedil":"Ç","ETH":"Ð","Eacute":"É","Ecirc":"Ê","Egrave":"È","Euml":"Ë","GT":">","Iacute":"Í","Icirc":"Î","Igrave":"Ì","Iuml":"Ï","LT":"<","Ntilde":"Ñ","Oacute":"Ó","Ocirc":"Ô","Ograve":"Ò","Oslash":"Ø","Otilde":"Õ","Ouml":"Ö","QUOT":"\\"","REG":"®","THORN":"Þ","Uacute":"Ú","Ucirc":"Û","Ugrave":"Ù","Uuml":"Ü","Yacute":"Ý","aacute":"á","acirc":"â","acute":"´","aelig":"æ","agrave":"à","amp":"&","aring":"å","atilde":"ã","auml":"ä","brvbar":"¦","ccedil":"ç","cedil":"¸","cent":"¢","copy":"©","curren":"¤","deg":"°","divide":"÷","eacute":"é","ecirc":"ê","egrave":"è","eth":"ð","euml":"ë","frac12":"½","frac14":"¼","frac34":"¾","gt":">","iacute":"í","icirc":"î","iexcl":"¡","igrave":"ì","iquest":"¿","iuml":"ï","laquo":"«","lt":"<","macr":"¯","micro":"µ","middot":"·","nbsp":" ","not":"¬","ntilde":"ñ","oacute":"ó","ocirc":"ô","ograve":"ò","ordf":"ª","ordm":"º","oslash":"ø","otilde":"õ","ouml":"ö","para":"¶","plusmn":"±","pound":"£","quot":"\\"","raquo":"»","reg":"®","sect":"§","shy":"­","sup1":"¹","sup2":"²","sup3":"³","szlig":"ß","thorn":"þ","times":"×","uacute":"ú","ucirc":"û","ugrave":"ù","uml":"¨","uuml":"ü","yacute":"ý","yen":"¥","yuml":"ÿ"}')},6852:e=>{"use strict";e.exports=JSON.parse('{"0":"�","128":"€","130":"‚","131":"ƒ","132":"„","133":"…","134":"†","135":"‡","136":"ˆ","137":"‰","138":"Š","139":"‹","140":"Œ","142":"Ž","145":"‘","146":"’","147":"“","148":"”","149":"•","150":"–","151":"—","152":"˜","153":"™","154":"š","155":"›","156":"œ","158":"ž","159":"Ÿ"}')},71027:(e,t,n)=>{var o=n(89509).Buffer,r=n(42830).Transform,i=n(32553).s;function a(e){r.call(this),this.hashMode="string"==typeof e,this.hashMode?this[e]=this._finalOrDigest:this.final=this._finalOrDigest,this._final&&(this.__final=this._final,this._final=null),this._decoder=null,this._encoding=null}n(35717)(a,r),a.prototype.update=function(e,t,n){"string"==typeof e&&(e=o.from(e,t));var r=this._update(e);return this.hashMode?this:(n&&(r=this._toString(r,n)),r)},a.prototype.setAutoPadding=function(){},a.prototype.getAuthTag=function(){throw new Error("trying to get auth tag in unsupported state")},a.prototype.setAuthTag=function(){throw new Error("trying to set auth tag in unsupported state")},a.prototype.setAAD=function(){throw new Error("trying to set aad in unsupported state")},a.prototype._transform=function(e,t,n){var o;try{this.hashMode?this._update(e):this.push(this._update(e))}catch(e){o=e}finally{n(o)}},a.prototype._flush=function(e){var t;try{this.push(this.__final())}catch(e){t=e}e(t)},a.prototype._finalOrDigest=function(e){var t=this.__final()||o.alloc(0);return e&&(t=this._toString(t,e,!0)),t},a.prototype._toString=function(e,t,n){if(this._decoder||(this._decoder=new i(t),this._encoding=t),this._encoding!==t)throw new Error("can't switch encodings");var o=this._decoder.write(e);return n&&(o+=this._decoder.end()),o},e.exports=a},16313:e=>{"use strict";function t(e){return Object.prototype.toString.call(e)}function n(e,n,o,r){var i=[],a=[],s="undefined"!=typeof Buffer;return void 0===n&&(n=!0),void 0===o&&(o=1/0),function e(o,u){if(null===o)return null;if(0==u)return o;var c,l,d,h,p;if("object"!=typeof o)return o;if(p=o,Array.isArray(p)||"object"==typeof p&&"[object Array]"===t(p))c=[];else if("object"==typeof(h=o)&&"[object RegExp]"===t(h))c=new RegExp(o.source,function(e){var t="";return e.global&&(t+="g"),e.ignoreCase&&(t+="i"),e.multiline&&(t+="m"),t}(o)),o.lastIndex&&(c.lastIndex=o.lastIndex);else if("object"==typeof(d=o)&&"[object Date]"===t(d))c=new Date(o.getTime());else{if(s&&Buffer.isBuffer(o))return c=new Buffer(o.length),o.copy(c),c;void 0===r?(l=Object.getPrototypeOf(o),c=Object.create(l)):(c=Object.create(r),l=r)}if(n){var f=i.indexOf(o);if(-1!=f)return a[f];i.push(o),a.push(c)}for(var g in o){var m;l&&(m=Object.getOwnPropertyDescriptor(l,g)),m&&null==m.set||(c[g]=e(o[g],u-1))}return c}(e,o)}e.exports=n,n.clonePrototype=function(e){if(null===e)return null;var t=function(){};return t.prototype=e,new t}},56851:(e,t)=>{"use strict";t.parse=function(e){for(var t,n=[],o=String(e||""),r=o.indexOf(","),i=0,a=!1;!a;)-1===r&&(r=o.length,a=!0),!(t=o.slice(i,r).trim())&&a||n.push(t),i=r+1,r=o.indexOf(",",i);return n},t.stringify=function(e,t){var n=t||{},o=!1===n.padLeft?"":" ",r=n.padRight?" ":"";return""===e[e.length-1]&&(e=e.concat("")),e.join(r+","+o).trim()}},31934:e=>{e.exports=function(e,t,n){return((n=window.getComputedStyle)?n(e):e.currentStyle)[t.replace(/-(\w)/gi,(function(e,t){return t.toUpperCase()}))]}},36890:(e,t,n)=>{var o=n(88473).Writable,r=n(35717),i=n(55420);if("undefined"==typeof Uint8Array)var a=n(61666).U2;else a=Uint8Array;function s(e,t){if(!(this instanceof s))return new s(e,t);"function"==typeof e&&(t=e,e={}),e||(e={});var n=e.encoding,r=!1;n?"u8"!==(n=String(n).toLowerCase())&&"uint8"!==n||(n="uint8array"):r=!0,o.call(this,{objectMode:!0}),this.encoding=n,this.shouldInferEncoding=r,t&&this.on("finish",(function(){t(this.getBody())})),this.body=[]}function u(e){return"string"==typeof e||(t=e,/Array\]$/.test(Object.prototype.toString.call(t)))||e&&"function"==typeof e.subarray;var t}e.exports=s,r(s,o),s.prototype._write=function(e,t,n){this.body.push(e),n()},s.prototype.inferEncoding=function(e){var t=void 0===e?this.body[0]:e;return Buffer.isBuffer(t)?"buffer":"undefined"!=typeof Uint8Array&&t instanceof Uint8Array?"uint8array":Array.isArray(t)?"array":"string"==typeof t?"string":"[object Object]"===Object.prototype.toString.call(t)?"object":"buffer"},s.prototype.getBody=function(){return this.encoding||0!==this.body.length?(this.shouldInferEncoding&&(this.encoding=this.inferEncoding()),"array"===this.encoding?function(e){for(var t=[],n=0;n{"use strict";var n=/; *([!#$%&'*+.^_`|~0-9A-Za-z-]+) *= *("(?:[\u000b\u0020\u0021\u0023-\u005b\u005d-\u007e\u0080-\u00ff]|\\[\u000b\u0020-\u00ff])*"|[!#$%&'*+.^_`|~0-9A-Za-z-]+) */g,o=/^[\u000b\u0020-\u007e\u0080-\u00ff]+$/,r=/^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/,i=/\\([\u000b\u0020-\u00ff])/g,a=/([\\"])/g,s=/^[!#$%&'*+.^_`|~0-9A-Za-z-]+\/[!#$%&'*+.^_`|~0-9A-Za-z-]+$/;function u(e){var t=String(e);if(r.test(t))return t;if(t.length>0&&!o.test(t))throw new TypeError("invalid parameter value");return'"'+t.replace(a,"\\$1")+'"'}function c(e){this.parameters=Object.create(null),this.type=e}t.format=function(e){if(!e||"object"!=typeof e)throw new TypeError("argument obj is required");var t=e.parameters,n=e.type;if(!n||!s.test(n))throw new TypeError("invalid type");var o=n;if(t&&"object"==typeof t)for(var i,a=Object.keys(t).sort(),c=0;c{function n(e){return Object.prototype.toString.call(e)}t.isArray=function(e){return Array.isArray?Array.isArray(e):"[object Array]"===n(e)},t.isBoolean=function(e){return"boolean"==typeof e},t.isNull=function(e){return null===e},t.isNullOrUndefined=function(e){return null==e},t.isNumber=function(e){return"number"==typeof e},t.isString=function(e){return"string"==typeof e},t.isSymbol=function(e){return"symbol"==typeof e},t.isUndefined=function(e){return void 0===e},t.isRegExp=function(e){return"[object RegExp]"===n(e)},t.isObject=function(e){return"object"==typeof e&&null!==e},t.isDate=function(e){return"[object Date]"===n(e)},t.isError=function(e){return"[object Error]"===n(e)||e instanceof Error},t.isFunction=function(e){return"function"==typeof e},t.isPrimitive=function(e){return null===e||"boolean"==typeof e||"number"==typeof e||"string"==typeof e||"symbol"==typeof e||void 0===e},t.isBuffer=Buffer.isBuffer},76393:(e,t,n)=>{var o=n(86266),r=n(16426);e.exports=function(e){return new a(e)};var i={secp256k1:{name:"secp256k1",byteLength:32},secp224r1:{name:"p224",byteLength:28},prime256v1:{name:"p256",byteLength:32},prime192v1:{name:"p192",byteLength:24},ed25519:{name:"ed25519",byteLength:32},secp384r1:{name:"p384",byteLength:48},secp521r1:{name:"p521",byteLength:66}};function a(e){this.curveType=i[e],this.curveType||(this.curveType={name:e}),this.curve=new o.ec(this.curveType.name),this.keys=void 0}function s(e,t,n){Array.isArray(e)||(e=e.toArray());var o=new Buffer(e);if(n&&o.length=65&&n<=70?n-55:n>=97&&n<=102?n-87:n-48&15}function u(e,t,n){var o=s(e,n);return n-1>=t&&(o|=s(e,n-1)<<4),o}function c(e,t,n,o){for(var r=0,i=Math.min(e.length,n),a=t;a=49?s-49+10:s>=17?s-17+10:s}return r}i.isBN=function(e){return e instanceof i||null!==e&&"object"==typeof e&&e.constructor.wordSize===i.wordSize&&Array.isArray(e.words)},i.max=function(e,t){return e.cmp(t)>0?e:t},i.min=function(e,t){return e.cmp(t)<0?e:t},i.prototype._init=function(e,t,n){if("number"==typeof e)return this._initNumber(e,t,n);if("object"==typeof e)return this._initArray(e,t,n);"hex"===t&&(t=16),o(t===(0|t)&&t>=2&&t<=36);var r=0;"-"===(e=e.toString().replace(/\s+/g,""))[0]&&(r++,this.negative=1),r=0;r-=3)a=e[r]|e[r-1]<<8|e[r-2]<<16,this.words[i]|=a<>>26-s&67108863,(s+=24)>=26&&(s-=26,i++);else if("le"===n)for(r=0,i=0;r>>26-s&67108863,(s+=24)>=26&&(s-=26,i++);return this.strip()},i.prototype._parseHex=function(e,t,n){this.length=Math.ceil((e.length-t)/6),this.words=new Array(this.length);for(var o=0;o=t;o-=2)r=u(e,t,o)<=18?(i-=18,a+=1,this.words[a]|=r>>>26):i+=8;else for(o=(e.length-t)%2==0?t+1:t;o=18?(i-=18,a+=1,this.words[a]|=r>>>26):i+=8;this.strip()},i.prototype._parseBase=function(e,t,n){this.words=[0],this.length=1;for(var o=0,r=1;r<=67108863;r*=t)o++;o--,r=r/t|0;for(var i=e.length-n,a=i%o,s=Math.min(i,i-a)+n,u=0,l=n;l1&&0===this.words[this.length-1];)this.length--;return this._normSign()},i.prototype._normSign=function(){return 1===this.length&&0===this.words[0]&&(this.negative=0),this},i.prototype.inspect=function(){return(this.red?""};var l=["","0","00","000","0000","00000","000000","0000000","00000000","000000000","0000000000","00000000000","000000000000","0000000000000","00000000000000","000000000000000","0000000000000000","00000000000000000","000000000000000000","0000000000000000000","00000000000000000000","000000000000000000000","0000000000000000000000","00000000000000000000000","000000000000000000000000","0000000000000000000000000"],d=[0,0,25,16,12,11,10,9,8,8,7,7,7,7,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5],h=[0,0,33554432,43046721,16777216,48828125,60466176,40353607,16777216,43046721,1e7,19487171,35831808,62748517,7529536,11390625,16777216,24137569,34012224,47045881,64e6,4084101,5153632,6436343,7962624,9765625,11881376,14348907,17210368,20511149,243e5,28629151,33554432,39135393,45435424,52521875,60466176];function p(e,t,n){n.negative=t.negative^e.negative;var o=e.length+t.length|0;n.length=o,o=o-1|0;var r=0|e.words[0],i=0|t.words[0],a=r*i,s=67108863&a,u=a/67108864|0;n.words[0]=s;for(var c=1;c>>26,d=67108863&u,h=Math.min(c,t.length-1),p=Math.max(0,c-e.length+1);p<=h;p++){var f=c-p|0;l+=(a=(r=0|e.words[f])*(i=0|t.words[p])+d)/67108864|0,d=67108863&a}n.words[c]=0|d,u=0|l}return 0!==u?n.words[c]=0|u:n.length--,n.strip()}i.prototype.toString=function(e,t){var n;if(t=0|t||1,16===(e=e||10)||"hex"===e){n="";for(var r=0,i=0,a=0;a>>24-r&16777215)||a!==this.length-1?l[6-u.length]+u+n:u+n,(r+=2)>=26&&(r-=26,a--)}for(0!==i&&(n=i.toString(16)+n);n.length%t!=0;)n="0"+n;return 0!==this.negative&&(n="-"+n),n}if(e===(0|e)&&e>=2&&e<=36){var c=d[e],p=h[e];n="";var f=this.clone();for(f.negative=0;!f.isZero();){var g=f.modn(p).toString(e);n=(f=f.idivn(p)).isZero()?g+n:l[c-g.length]+g+n}for(this.isZero()&&(n="0"+n);n.length%t!=0;)n="0"+n;return 0!==this.negative&&(n="-"+n),n}o(!1,"Base should be between 2 and 36")},i.prototype.toNumber=function(){var e=this.words[0];return 2===this.length?e+=67108864*this.words[1]:3===this.length&&1===this.words[2]?e+=4503599627370496+67108864*this.words[1]:this.length>2&&o(!1,"Number can only safely store up to 53 bits"),0!==this.negative?-e:e},i.prototype.toJSON=function(){return this.toString(16)},i.prototype.toBuffer=function(e,t){return o(void 0!==a),this.toArrayLike(a,e,t)},i.prototype.toArray=function(e,t){return this.toArrayLike(Array,e,t)},i.prototype.toArrayLike=function(e,t,n){var r=this.byteLength(),i=n||Math.max(1,r);o(r<=i,"byte array longer than desired length"),o(i>0,"Requested array length <= 0"),this.strip();var a,s,u="le"===t,c=new e(i),l=this.clone();if(u){for(s=0;!l.isZero();s++)a=l.andln(255),l.iushrn(8),c[s]=a;for(;s=4096&&(n+=13,t>>>=13),t>=64&&(n+=7,t>>>=7),t>=8&&(n+=4,t>>>=4),t>=2&&(n+=2,t>>>=2),n+t},i.prototype._zeroBits=function(e){if(0===e)return 26;var t=e,n=0;return 0==(8191&t)&&(n+=13,t>>>=13),0==(127&t)&&(n+=7,t>>>=7),0==(15&t)&&(n+=4,t>>>=4),0==(3&t)&&(n+=2,t>>>=2),0==(1&t)&&n++,n},i.prototype.bitLength=function(){var e=this.words[this.length-1],t=this._countBits(e);return 26*(this.length-1)+t},i.prototype.zeroBits=function(){if(this.isZero())return 0;for(var e=0,t=0;te.length?this.clone().ior(e):e.clone().ior(this)},i.prototype.uor=function(e){return this.length>e.length?this.clone().iuor(e):e.clone().iuor(this)},i.prototype.iuand=function(e){var t;t=this.length>e.length?e:this;for(var n=0;ne.length?this.clone().iand(e):e.clone().iand(this)},i.prototype.uand=function(e){return this.length>e.length?this.clone().iuand(e):e.clone().iuand(this)},i.prototype.iuxor=function(e){var t,n;this.length>e.length?(t=this,n=e):(t=e,n=this);for(var o=0;oe.length?this.clone().ixor(e):e.clone().ixor(this)},i.prototype.uxor=function(e){return this.length>e.length?this.clone().iuxor(e):e.clone().iuxor(this)},i.prototype.inotn=function(e){o("number"==typeof e&&e>=0);var t=0|Math.ceil(e/26),n=e%26;this._expand(t),n>0&&t--;for(var r=0;r0&&(this.words[r]=~this.words[r]&67108863>>26-n),this.strip()},i.prototype.notn=function(e){return this.clone().inotn(e)},i.prototype.setn=function(e,t){o("number"==typeof e&&e>=0);var n=e/26|0,r=e%26;return this._expand(n+1),this.words[n]=t?this.words[n]|1<e.length?(n=this,o=e):(n=e,o=this);for(var r=0,i=0;i>>26;for(;0!==r&&i>>26;if(this.length=n.length,0!==r)this.words[this.length]=r,this.length++;else if(n!==this)for(;ie.length?this.clone().iadd(e):e.clone().iadd(this)},i.prototype.isub=function(e){if(0!==e.negative){e.negative=0;var t=this.iadd(e);return e.negative=1,t._normSign()}if(0!==this.negative)return this.negative=0,this.iadd(e),this.negative=1,this._normSign();var n,o,r=this.cmp(e);if(0===r)return this.negative=0,this.length=1,this.words[0]=0,this;r>0?(n=this,o=e):(n=e,o=this);for(var i=0,a=0;a>26,this.words[a]=67108863&t;for(;0!==i&&a>26,this.words[a]=67108863&t;if(0===i&&a>>13,p=0|a[1],f=8191&p,g=p>>>13,m=0|a[2],_=8191&m,F=m>>>13,y=0|a[3],b=8191&y,v=y>>>13,w=0|a[4],E=8191&w,k=w>>>13,D=0|a[5],S=8191&D,x=D>>>13,C=0|a[6],A=8191&C,T=C>>>13,R=0|a[7],I=8191&R,M=R>>>13,O=0|a[8],B=8191&O,N=O>>>13,L=0|a[9],P=8191&L,U=L>>>13,j=0|s[0],q=8191&j,z=j>>>13,K=0|s[1],G=8191&K,$=K>>>13,H=0|s[2],V=8191&H,W=H>>>13,Y=0|s[3],Z=8191&Y,X=Y>>>13,J=0|s[4],Q=8191&J,ee=J>>>13,te=0|s[5],ne=8191&te,oe=te>>>13,re=0|s[6],ie=8191&re,ae=re>>>13,se=0|s[7],ue=8191&se,ce=se>>>13,le=0|s[8],de=8191&le,he=le>>>13,pe=0|s[9],fe=8191&pe,ge=pe>>>13;n.negative=e.negative^t.negative,n.length=19;var me=(c+(o=Math.imul(d,q))|0)+((8191&(r=(r=Math.imul(d,z))+Math.imul(h,q)|0))<<13)|0;c=((i=Math.imul(h,z))+(r>>>13)|0)+(me>>>26)|0,me&=67108863,o=Math.imul(f,q),r=(r=Math.imul(f,z))+Math.imul(g,q)|0,i=Math.imul(g,z);var _e=(c+(o=o+Math.imul(d,G)|0)|0)+((8191&(r=(r=r+Math.imul(d,$)|0)+Math.imul(h,G)|0))<<13)|0;c=((i=i+Math.imul(h,$)|0)+(r>>>13)|0)+(_e>>>26)|0,_e&=67108863,o=Math.imul(_,q),r=(r=Math.imul(_,z))+Math.imul(F,q)|0,i=Math.imul(F,z),o=o+Math.imul(f,G)|0,r=(r=r+Math.imul(f,$)|0)+Math.imul(g,G)|0,i=i+Math.imul(g,$)|0;var Fe=(c+(o=o+Math.imul(d,V)|0)|0)+((8191&(r=(r=r+Math.imul(d,W)|0)+Math.imul(h,V)|0))<<13)|0;c=((i=i+Math.imul(h,W)|0)+(r>>>13)|0)+(Fe>>>26)|0,Fe&=67108863,o=Math.imul(b,q),r=(r=Math.imul(b,z))+Math.imul(v,q)|0,i=Math.imul(v,z),o=o+Math.imul(_,G)|0,r=(r=r+Math.imul(_,$)|0)+Math.imul(F,G)|0,i=i+Math.imul(F,$)|0,o=o+Math.imul(f,V)|0,r=(r=r+Math.imul(f,W)|0)+Math.imul(g,V)|0,i=i+Math.imul(g,W)|0;var ye=(c+(o=o+Math.imul(d,Z)|0)|0)+((8191&(r=(r=r+Math.imul(d,X)|0)+Math.imul(h,Z)|0))<<13)|0;c=((i=i+Math.imul(h,X)|0)+(r>>>13)|0)+(ye>>>26)|0,ye&=67108863,o=Math.imul(E,q),r=(r=Math.imul(E,z))+Math.imul(k,q)|0,i=Math.imul(k,z),o=o+Math.imul(b,G)|0,r=(r=r+Math.imul(b,$)|0)+Math.imul(v,G)|0,i=i+Math.imul(v,$)|0,o=o+Math.imul(_,V)|0,r=(r=r+Math.imul(_,W)|0)+Math.imul(F,V)|0,i=i+Math.imul(F,W)|0,o=o+Math.imul(f,Z)|0,r=(r=r+Math.imul(f,X)|0)+Math.imul(g,Z)|0,i=i+Math.imul(g,X)|0;var be=(c+(o=o+Math.imul(d,Q)|0)|0)+((8191&(r=(r=r+Math.imul(d,ee)|0)+Math.imul(h,Q)|0))<<13)|0;c=((i=i+Math.imul(h,ee)|0)+(r>>>13)|0)+(be>>>26)|0,be&=67108863,o=Math.imul(S,q),r=(r=Math.imul(S,z))+Math.imul(x,q)|0,i=Math.imul(x,z),o=o+Math.imul(E,G)|0,r=(r=r+Math.imul(E,$)|0)+Math.imul(k,G)|0,i=i+Math.imul(k,$)|0,o=o+Math.imul(b,V)|0,r=(r=r+Math.imul(b,W)|0)+Math.imul(v,V)|0,i=i+Math.imul(v,W)|0,o=o+Math.imul(_,Z)|0,r=(r=r+Math.imul(_,X)|0)+Math.imul(F,Z)|0,i=i+Math.imul(F,X)|0,o=o+Math.imul(f,Q)|0,r=(r=r+Math.imul(f,ee)|0)+Math.imul(g,Q)|0,i=i+Math.imul(g,ee)|0;var ve=(c+(o=o+Math.imul(d,ne)|0)|0)+((8191&(r=(r=r+Math.imul(d,oe)|0)+Math.imul(h,ne)|0))<<13)|0;c=((i=i+Math.imul(h,oe)|0)+(r>>>13)|0)+(ve>>>26)|0,ve&=67108863,o=Math.imul(A,q),r=(r=Math.imul(A,z))+Math.imul(T,q)|0,i=Math.imul(T,z),o=o+Math.imul(S,G)|0,r=(r=r+Math.imul(S,$)|0)+Math.imul(x,G)|0,i=i+Math.imul(x,$)|0,o=o+Math.imul(E,V)|0,r=(r=r+Math.imul(E,W)|0)+Math.imul(k,V)|0,i=i+Math.imul(k,W)|0,o=o+Math.imul(b,Z)|0,r=(r=r+Math.imul(b,X)|0)+Math.imul(v,Z)|0,i=i+Math.imul(v,X)|0,o=o+Math.imul(_,Q)|0,r=(r=r+Math.imul(_,ee)|0)+Math.imul(F,Q)|0,i=i+Math.imul(F,ee)|0,o=o+Math.imul(f,ne)|0,r=(r=r+Math.imul(f,oe)|0)+Math.imul(g,ne)|0,i=i+Math.imul(g,oe)|0;var we=(c+(o=o+Math.imul(d,ie)|0)|0)+((8191&(r=(r=r+Math.imul(d,ae)|0)+Math.imul(h,ie)|0))<<13)|0;c=((i=i+Math.imul(h,ae)|0)+(r>>>13)|0)+(we>>>26)|0,we&=67108863,o=Math.imul(I,q),r=(r=Math.imul(I,z))+Math.imul(M,q)|0,i=Math.imul(M,z),o=o+Math.imul(A,G)|0,r=(r=r+Math.imul(A,$)|0)+Math.imul(T,G)|0,i=i+Math.imul(T,$)|0,o=o+Math.imul(S,V)|0,r=(r=r+Math.imul(S,W)|0)+Math.imul(x,V)|0,i=i+Math.imul(x,W)|0,o=o+Math.imul(E,Z)|0,r=(r=r+Math.imul(E,X)|0)+Math.imul(k,Z)|0,i=i+Math.imul(k,X)|0,o=o+Math.imul(b,Q)|0,r=(r=r+Math.imul(b,ee)|0)+Math.imul(v,Q)|0,i=i+Math.imul(v,ee)|0,o=o+Math.imul(_,ne)|0,r=(r=r+Math.imul(_,oe)|0)+Math.imul(F,ne)|0,i=i+Math.imul(F,oe)|0,o=o+Math.imul(f,ie)|0,r=(r=r+Math.imul(f,ae)|0)+Math.imul(g,ie)|0,i=i+Math.imul(g,ae)|0;var Ee=(c+(o=o+Math.imul(d,ue)|0)|0)+((8191&(r=(r=r+Math.imul(d,ce)|0)+Math.imul(h,ue)|0))<<13)|0;c=((i=i+Math.imul(h,ce)|0)+(r>>>13)|0)+(Ee>>>26)|0,Ee&=67108863,o=Math.imul(B,q),r=(r=Math.imul(B,z))+Math.imul(N,q)|0,i=Math.imul(N,z),o=o+Math.imul(I,G)|0,r=(r=r+Math.imul(I,$)|0)+Math.imul(M,G)|0,i=i+Math.imul(M,$)|0,o=o+Math.imul(A,V)|0,r=(r=r+Math.imul(A,W)|0)+Math.imul(T,V)|0,i=i+Math.imul(T,W)|0,o=o+Math.imul(S,Z)|0,r=(r=r+Math.imul(S,X)|0)+Math.imul(x,Z)|0,i=i+Math.imul(x,X)|0,o=o+Math.imul(E,Q)|0,r=(r=r+Math.imul(E,ee)|0)+Math.imul(k,Q)|0,i=i+Math.imul(k,ee)|0,o=o+Math.imul(b,ne)|0,r=(r=r+Math.imul(b,oe)|0)+Math.imul(v,ne)|0,i=i+Math.imul(v,oe)|0,o=o+Math.imul(_,ie)|0,r=(r=r+Math.imul(_,ae)|0)+Math.imul(F,ie)|0,i=i+Math.imul(F,ae)|0,o=o+Math.imul(f,ue)|0,r=(r=r+Math.imul(f,ce)|0)+Math.imul(g,ue)|0,i=i+Math.imul(g,ce)|0;var ke=(c+(o=o+Math.imul(d,de)|0)|0)+((8191&(r=(r=r+Math.imul(d,he)|0)+Math.imul(h,de)|0))<<13)|0;c=((i=i+Math.imul(h,he)|0)+(r>>>13)|0)+(ke>>>26)|0,ke&=67108863,o=Math.imul(P,q),r=(r=Math.imul(P,z))+Math.imul(U,q)|0,i=Math.imul(U,z),o=o+Math.imul(B,G)|0,r=(r=r+Math.imul(B,$)|0)+Math.imul(N,G)|0,i=i+Math.imul(N,$)|0,o=o+Math.imul(I,V)|0,r=(r=r+Math.imul(I,W)|0)+Math.imul(M,V)|0,i=i+Math.imul(M,W)|0,o=o+Math.imul(A,Z)|0,r=(r=r+Math.imul(A,X)|0)+Math.imul(T,Z)|0,i=i+Math.imul(T,X)|0,o=o+Math.imul(S,Q)|0,r=(r=r+Math.imul(S,ee)|0)+Math.imul(x,Q)|0,i=i+Math.imul(x,ee)|0,o=o+Math.imul(E,ne)|0,r=(r=r+Math.imul(E,oe)|0)+Math.imul(k,ne)|0,i=i+Math.imul(k,oe)|0,o=o+Math.imul(b,ie)|0,r=(r=r+Math.imul(b,ae)|0)+Math.imul(v,ie)|0,i=i+Math.imul(v,ae)|0,o=o+Math.imul(_,ue)|0,r=(r=r+Math.imul(_,ce)|0)+Math.imul(F,ue)|0,i=i+Math.imul(F,ce)|0,o=o+Math.imul(f,de)|0,r=(r=r+Math.imul(f,he)|0)+Math.imul(g,de)|0,i=i+Math.imul(g,he)|0;var De=(c+(o=o+Math.imul(d,fe)|0)|0)+((8191&(r=(r=r+Math.imul(d,ge)|0)+Math.imul(h,fe)|0))<<13)|0;c=((i=i+Math.imul(h,ge)|0)+(r>>>13)|0)+(De>>>26)|0,De&=67108863,o=Math.imul(P,G),r=(r=Math.imul(P,$))+Math.imul(U,G)|0,i=Math.imul(U,$),o=o+Math.imul(B,V)|0,r=(r=r+Math.imul(B,W)|0)+Math.imul(N,V)|0,i=i+Math.imul(N,W)|0,o=o+Math.imul(I,Z)|0,r=(r=r+Math.imul(I,X)|0)+Math.imul(M,Z)|0,i=i+Math.imul(M,X)|0,o=o+Math.imul(A,Q)|0,r=(r=r+Math.imul(A,ee)|0)+Math.imul(T,Q)|0,i=i+Math.imul(T,ee)|0,o=o+Math.imul(S,ne)|0,r=(r=r+Math.imul(S,oe)|0)+Math.imul(x,ne)|0,i=i+Math.imul(x,oe)|0,o=o+Math.imul(E,ie)|0,r=(r=r+Math.imul(E,ae)|0)+Math.imul(k,ie)|0,i=i+Math.imul(k,ae)|0,o=o+Math.imul(b,ue)|0,r=(r=r+Math.imul(b,ce)|0)+Math.imul(v,ue)|0,i=i+Math.imul(v,ce)|0,o=o+Math.imul(_,de)|0,r=(r=r+Math.imul(_,he)|0)+Math.imul(F,de)|0,i=i+Math.imul(F,he)|0;var Se=(c+(o=o+Math.imul(f,fe)|0)|0)+((8191&(r=(r=r+Math.imul(f,ge)|0)+Math.imul(g,fe)|0))<<13)|0;c=((i=i+Math.imul(g,ge)|0)+(r>>>13)|0)+(Se>>>26)|0,Se&=67108863,o=Math.imul(P,V),r=(r=Math.imul(P,W))+Math.imul(U,V)|0,i=Math.imul(U,W),o=o+Math.imul(B,Z)|0,r=(r=r+Math.imul(B,X)|0)+Math.imul(N,Z)|0,i=i+Math.imul(N,X)|0,o=o+Math.imul(I,Q)|0,r=(r=r+Math.imul(I,ee)|0)+Math.imul(M,Q)|0,i=i+Math.imul(M,ee)|0,o=o+Math.imul(A,ne)|0,r=(r=r+Math.imul(A,oe)|0)+Math.imul(T,ne)|0,i=i+Math.imul(T,oe)|0,o=o+Math.imul(S,ie)|0,r=(r=r+Math.imul(S,ae)|0)+Math.imul(x,ie)|0,i=i+Math.imul(x,ae)|0,o=o+Math.imul(E,ue)|0,r=(r=r+Math.imul(E,ce)|0)+Math.imul(k,ue)|0,i=i+Math.imul(k,ce)|0,o=o+Math.imul(b,de)|0,r=(r=r+Math.imul(b,he)|0)+Math.imul(v,de)|0,i=i+Math.imul(v,he)|0;var xe=(c+(o=o+Math.imul(_,fe)|0)|0)+((8191&(r=(r=r+Math.imul(_,ge)|0)+Math.imul(F,fe)|0))<<13)|0;c=((i=i+Math.imul(F,ge)|0)+(r>>>13)|0)+(xe>>>26)|0,xe&=67108863,o=Math.imul(P,Z),r=(r=Math.imul(P,X))+Math.imul(U,Z)|0,i=Math.imul(U,X),o=o+Math.imul(B,Q)|0,r=(r=r+Math.imul(B,ee)|0)+Math.imul(N,Q)|0,i=i+Math.imul(N,ee)|0,o=o+Math.imul(I,ne)|0,r=(r=r+Math.imul(I,oe)|0)+Math.imul(M,ne)|0,i=i+Math.imul(M,oe)|0,o=o+Math.imul(A,ie)|0,r=(r=r+Math.imul(A,ae)|0)+Math.imul(T,ie)|0,i=i+Math.imul(T,ae)|0,o=o+Math.imul(S,ue)|0,r=(r=r+Math.imul(S,ce)|0)+Math.imul(x,ue)|0,i=i+Math.imul(x,ce)|0,o=o+Math.imul(E,de)|0,r=(r=r+Math.imul(E,he)|0)+Math.imul(k,de)|0,i=i+Math.imul(k,he)|0;var Ce=(c+(o=o+Math.imul(b,fe)|0)|0)+((8191&(r=(r=r+Math.imul(b,ge)|0)+Math.imul(v,fe)|0))<<13)|0;c=((i=i+Math.imul(v,ge)|0)+(r>>>13)|0)+(Ce>>>26)|0,Ce&=67108863,o=Math.imul(P,Q),r=(r=Math.imul(P,ee))+Math.imul(U,Q)|0,i=Math.imul(U,ee),o=o+Math.imul(B,ne)|0,r=(r=r+Math.imul(B,oe)|0)+Math.imul(N,ne)|0,i=i+Math.imul(N,oe)|0,o=o+Math.imul(I,ie)|0,r=(r=r+Math.imul(I,ae)|0)+Math.imul(M,ie)|0,i=i+Math.imul(M,ae)|0,o=o+Math.imul(A,ue)|0,r=(r=r+Math.imul(A,ce)|0)+Math.imul(T,ue)|0,i=i+Math.imul(T,ce)|0,o=o+Math.imul(S,de)|0,r=(r=r+Math.imul(S,he)|0)+Math.imul(x,de)|0,i=i+Math.imul(x,he)|0;var Ae=(c+(o=o+Math.imul(E,fe)|0)|0)+((8191&(r=(r=r+Math.imul(E,ge)|0)+Math.imul(k,fe)|0))<<13)|0;c=((i=i+Math.imul(k,ge)|0)+(r>>>13)|0)+(Ae>>>26)|0,Ae&=67108863,o=Math.imul(P,ne),r=(r=Math.imul(P,oe))+Math.imul(U,ne)|0,i=Math.imul(U,oe),o=o+Math.imul(B,ie)|0,r=(r=r+Math.imul(B,ae)|0)+Math.imul(N,ie)|0,i=i+Math.imul(N,ae)|0,o=o+Math.imul(I,ue)|0,r=(r=r+Math.imul(I,ce)|0)+Math.imul(M,ue)|0,i=i+Math.imul(M,ce)|0,o=o+Math.imul(A,de)|0,r=(r=r+Math.imul(A,he)|0)+Math.imul(T,de)|0,i=i+Math.imul(T,he)|0;var Te=(c+(o=o+Math.imul(S,fe)|0)|0)+((8191&(r=(r=r+Math.imul(S,ge)|0)+Math.imul(x,fe)|0))<<13)|0;c=((i=i+Math.imul(x,ge)|0)+(r>>>13)|0)+(Te>>>26)|0,Te&=67108863,o=Math.imul(P,ie),r=(r=Math.imul(P,ae))+Math.imul(U,ie)|0,i=Math.imul(U,ae),o=o+Math.imul(B,ue)|0,r=(r=r+Math.imul(B,ce)|0)+Math.imul(N,ue)|0,i=i+Math.imul(N,ce)|0,o=o+Math.imul(I,de)|0,r=(r=r+Math.imul(I,he)|0)+Math.imul(M,de)|0,i=i+Math.imul(M,he)|0;var Re=(c+(o=o+Math.imul(A,fe)|0)|0)+((8191&(r=(r=r+Math.imul(A,ge)|0)+Math.imul(T,fe)|0))<<13)|0;c=((i=i+Math.imul(T,ge)|0)+(r>>>13)|0)+(Re>>>26)|0,Re&=67108863,o=Math.imul(P,ue),r=(r=Math.imul(P,ce))+Math.imul(U,ue)|0,i=Math.imul(U,ce),o=o+Math.imul(B,de)|0,r=(r=r+Math.imul(B,he)|0)+Math.imul(N,de)|0,i=i+Math.imul(N,he)|0;var Ie=(c+(o=o+Math.imul(I,fe)|0)|0)+((8191&(r=(r=r+Math.imul(I,ge)|0)+Math.imul(M,fe)|0))<<13)|0;c=((i=i+Math.imul(M,ge)|0)+(r>>>13)|0)+(Ie>>>26)|0,Ie&=67108863,o=Math.imul(P,de),r=(r=Math.imul(P,he))+Math.imul(U,de)|0,i=Math.imul(U,he);var Me=(c+(o=o+Math.imul(B,fe)|0)|0)+((8191&(r=(r=r+Math.imul(B,ge)|0)+Math.imul(N,fe)|0))<<13)|0;c=((i=i+Math.imul(N,ge)|0)+(r>>>13)|0)+(Me>>>26)|0,Me&=67108863;var Oe=(c+(o=Math.imul(P,fe))|0)+((8191&(r=(r=Math.imul(P,ge))+Math.imul(U,fe)|0))<<13)|0;return c=((i=Math.imul(U,ge))+(r>>>13)|0)+(Oe>>>26)|0,Oe&=67108863,u[0]=me,u[1]=_e,u[2]=Fe,u[3]=ye,u[4]=be,u[5]=ve,u[6]=we,u[7]=Ee,u[8]=ke,u[9]=De,u[10]=Se,u[11]=xe,u[12]=Ce,u[13]=Ae,u[14]=Te,u[15]=Re,u[16]=Ie,u[17]=Me,u[18]=Oe,0!==c&&(u[19]=c,n.length++),n};function g(e,t,n){return(new m).mulp(e,t,n)}function m(e,t){this.x=e,this.y=t}Math.imul||(f=p),i.prototype.mulTo=function(e,t){var n=this.length+e.length;return 10===this.length&&10===e.length?f(this,e,t):n<63?p(this,e,t):n<1024?function(e,t,n){n.negative=t.negative^e.negative,n.length=e.length+t.length;for(var o=0,r=0,i=0;i>>26)|0)>>>26,a&=67108863}n.words[i]=s,o=a,a=r}return 0!==o?n.words[i]=o:n.length--,n.strip()}(this,e,t):g(this,e,t)},m.prototype.makeRBT=function(e){for(var t=new Array(e),n=i.prototype._countBits(e)-1,o=0;o>=1;return o},m.prototype.permute=function(e,t,n,o,r,i){for(var a=0;a>>=1)r++;return 1<>>=13,n[2*a+1]=8191&i,i>>>=13;for(a=2*t;a>=26,t+=r/67108864|0,t+=i>>>26,this.words[n]=67108863&i}return 0!==t&&(this.words[n]=t,this.length++),this},i.prototype.muln=function(e){return this.clone().imuln(e)},i.prototype.sqr=function(){return this.mul(this)},i.prototype.isqr=function(){return this.imul(this.clone())},i.prototype.pow=function(e){var t=function(e){for(var t=new Array(e.bitLength()),n=0;n>>r}return t}(e);if(0===t.length)return new i(1);for(var n=this,o=0;o=0);var t,n=e%26,r=(e-n)/26,i=67108863>>>26-n<<26-n;if(0!==n){var a=0;for(t=0;t>>26-n}a&&(this.words[t]=a,this.length++)}if(0!==r){for(t=this.length-1;t>=0;t--)this.words[t+r]=this.words[t];for(t=0;t=0),r=t?(t-t%26)/26:0;var i=e%26,a=Math.min((e-i)/26,this.length),s=67108863^67108863>>>i<a)for(this.length-=a,c=0;c=0&&(0!==l||c>=r);c--){var d=0|this.words[c];this.words[c]=l<<26-i|d>>>i,l=d&s}return u&&0!==l&&(u.words[u.length++]=l),0===this.length&&(this.words[0]=0,this.length=1),this.strip()},i.prototype.ishrn=function(e,t,n){return o(0===this.negative),this.iushrn(e,t,n)},i.prototype.shln=function(e){return this.clone().ishln(e)},i.prototype.ushln=function(e){return this.clone().iushln(e)},i.prototype.shrn=function(e){return this.clone().ishrn(e)},i.prototype.ushrn=function(e){return this.clone().iushrn(e)},i.prototype.testn=function(e){o("number"==typeof e&&e>=0);var t=e%26,n=(e-t)/26,r=1<=0);var t=e%26,n=(e-t)/26;if(o(0===this.negative,"imaskn works only with positive numbers"),this.length<=n)return this;if(0!==t&&n++,this.length=Math.min(n,this.length),0!==t){var r=67108863^67108863>>>t<=67108864;t++)this.words[t]-=67108864,t===this.length-1?this.words[t+1]=1:this.words[t+1]++;return this.length=Math.max(this.length,t+1),this},i.prototype.isubn=function(e){if(o("number"==typeof e),o(e<67108864),e<0)return this.iaddn(-e);if(0!==this.negative)return this.negative=0,this.iaddn(e),this.negative=1,this;if(this.words[0]-=e,1===this.length&&this.words[0]<0)this.words[0]=-this.words[0],this.negative=1;else for(var t=0;t>26)-(u/67108864|0),this.words[r+n]=67108863&i}for(;r>26,this.words[r+n]=67108863&i;if(0===s)return this.strip();for(o(-1===s),s=0,r=0;r>26,this.words[r]=67108863&i;return this.negative=1,this.strip()},i.prototype._wordDiv=function(e,t){var n=(this.length,e.length),o=this.clone(),r=e,a=0|r.words[r.length-1];0!=(n=26-this._countBits(a))&&(r=r.ushln(n),o.iushln(n),a=0|r.words[r.length-1]);var s,u=o.length-r.length;if("mod"!==t){(s=new i(null)).length=u+1,s.words=new Array(s.length);for(var c=0;c=0;d--){var h=67108864*(0|o.words[r.length+d])+(0|o.words[r.length+d-1]);for(h=Math.min(h/a|0,67108863),o._ishlnsubmul(r,h,d);0!==o.negative;)h--,o.negative=0,o._ishlnsubmul(r,1,d),o.isZero()||(o.negative^=1);s&&(s.words[d]=h)}return s&&s.strip(),o.strip(),"div"!==t&&0!==n&&o.iushrn(n),{div:s||null,mod:o}},i.prototype.divmod=function(e,t,n){return o(!e.isZero()),this.isZero()?{div:new i(0),mod:new i(0)}:0!==this.negative&&0===e.negative?(s=this.neg().divmod(e,t),"mod"!==t&&(r=s.div.neg()),"div"!==t&&(a=s.mod.neg(),n&&0!==a.negative&&a.iadd(e)),{div:r,mod:a}):0===this.negative&&0!==e.negative?(s=this.divmod(e.neg(),t),"mod"!==t&&(r=s.div.neg()),{div:r,mod:s.mod}):0!=(this.negative&e.negative)?(s=this.neg().divmod(e.neg(),t),"div"!==t&&(a=s.mod.neg(),n&&0!==a.negative&&a.isub(e)),{div:s.div,mod:a}):e.length>this.length||this.cmp(e)<0?{div:new i(0),mod:this}:1===e.length?"div"===t?{div:this.divn(e.words[0]),mod:null}:"mod"===t?{div:null,mod:new i(this.modn(e.words[0]))}:{div:this.divn(e.words[0]),mod:new i(this.modn(e.words[0]))}:this._wordDiv(e,t);var r,a,s},i.prototype.div=function(e){return this.divmod(e,"div",!1).div},i.prototype.mod=function(e){return this.divmod(e,"mod",!1).mod},i.prototype.umod=function(e){return this.divmod(e,"mod",!0).mod},i.prototype.divRound=function(e){var t=this.divmod(e);if(t.mod.isZero())return t.div;var n=0!==t.div.negative?t.mod.isub(e):t.mod,o=e.ushrn(1),r=e.andln(1),i=n.cmp(o);return i<0||1===r&&0===i?t.div:0!==t.div.negative?t.div.isubn(1):t.div.iaddn(1)},i.prototype.modn=function(e){o(e<=67108863);for(var t=(1<<26)%e,n=0,r=this.length-1;r>=0;r--)n=(t*n+(0|this.words[r]))%e;return n},i.prototype.idivn=function(e){o(e<=67108863);for(var t=0,n=this.length-1;n>=0;n--){var r=(0|this.words[n])+67108864*t;this.words[n]=r/e|0,t=r%e}return this.strip()},i.prototype.divn=function(e){return this.clone().idivn(e)},i.prototype.egcd=function(e){o(0===e.negative),o(!e.isZero());var t=this,n=e.clone();t=0!==t.negative?t.umod(e):t.clone();for(var r=new i(1),a=new i(0),s=new i(0),u=new i(1),c=0;t.isEven()&&n.isEven();)t.iushrn(1),n.iushrn(1),++c;for(var l=n.clone(),d=t.clone();!t.isZero();){for(var h=0,p=1;0==(t.words[0]&p)&&h<26;++h,p<<=1);if(h>0)for(t.iushrn(h);h-- >0;)(r.isOdd()||a.isOdd())&&(r.iadd(l),a.isub(d)),r.iushrn(1),a.iushrn(1);for(var f=0,g=1;0==(n.words[0]&g)&&f<26;++f,g<<=1);if(f>0)for(n.iushrn(f);f-- >0;)(s.isOdd()||u.isOdd())&&(s.iadd(l),u.isub(d)),s.iushrn(1),u.iushrn(1);t.cmp(n)>=0?(t.isub(n),r.isub(s),a.isub(u)):(n.isub(t),s.isub(r),u.isub(a))}return{a:s,b:u,gcd:n.iushln(c)}},i.prototype._invmp=function(e){o(0===e.negative),o(!e.isZero());var t=this,n=e.clone();t=0!==t.negative?t.umod(e):t.clone();for(var r,a=new i(1),s=new i(0),u=n.clone();t.cmpn(1)>0&&n.cmpn(1)>0;){for(var c=0,l=1;0==(t.words[0]&l)&&c<26;++c,l<<=1);if(c>0)for(t.iushrn(c);c-- >0;)a.isOdd()&&a.iadd(u),a.iushrn(1);for(var d=0,h=1;0==(n.words[0]&h)&&d<26;++d,h<<=1);if(d>0)for(n.iushrn(d);d-- >0;)s.isOdd()&&s.iadd(u),s.iushrn(1);t.cmp(n)>=0?(t.isub(n),a.isub(s)):(n.isub(t),s.isub(a))}return(r=0===t.cmpn(1)?a:s).cmpn(0)<0&&r.iadd(e),r},i.prototype.gcd=function(e){if(this.isZero())return e.abs();if(e.isZero())return this.abs();var t=this.clone(),n=e.clone();t.negative=0,n.negative=0;for(var o=0;t.isEven()&&n.isEven();o++)t.iushrn(1),n.iushrn(1);for(;;){for(;t.isEven();)t.iushrn(1);for(;n.isEven();)n.iushrn(1);var r=t.cmp(n);if(r<0){var i=t;t=n,n=i}else if(0===r||0===n.cmpn(1))break;t.isub(n)}return n.iushln(o)},i.prototype.invm=function(e){return this.egcd(e).a.umod(e)},i.prototype.isEven=function(){return 0==(1&this.words[0])},i.prototype.isOdd=function(){return 1==(1&this.words[0])},i.prototype.andln=function(e){return this.words[0]&e},i.prototype.bincn=function(e){o("number"==typeof e);var t=e%26,n=(e-t)/26,r=1<>>26,s&=67108863,this.words[a]=s}return 0!==i&&(this.words[a]=i,this.length++),this},i.prototype.isZero=function(){return 1===this.length&&0===this.words[0]},i.prototype.cmpn=function(e){var t,n=e<0;if(0!==this.negative&&!n)return-1;if(0===this.negative&&n)return 1;if(this.strip(),this.length>1)t=1;else{n&&(e=-e),o(e<=67108863,"Number is too big");var r=0|this.words[0];t=r===e?0:re.length)return 1;if(this.length=0;n--){var o=0|this.words[n],r=0|e.words[n];if(o!==r){or&&(t=1);break}}return t},i.prototype.gtn=function(e){return 1===this.cmpn(e)},i.prototype.gt=function(e){return 1===this.cmp(e)},i.prototype.gten=function(e){return this.cmpn(e)>=0},i.prototype.gte=function(e){return this.cmp(e)>=0},i.prototype.ltn=function(e){return-1===this.cmpn(e)},i.prototype.lt=function(e){return-1===this.cmp(e)},i.prototype.lten=function(e){return this.cmpn(e)<=0},i.prototype.lte=function(e){return this.cmp(e)<=0},i.prototype.eqn=function(e){return 0===this.cmpn(e)},i.prototype.eq=function(e){return 0===this.cmp(e)},i.red=function(e){return new E(e)},i.prototype.toRed=function(e){return o(!this.red,"Already a number in reduction context"),o(0===this.negative,"red works only with positives"),e.convertTo(this)._forceRed(e)},i.prototype.fromRed=function(){return o(this.red,"fromRed works only with numbers in reduction context"),this.red.convertFrom(this)},i.prototype._forceRed=function(e){return this.red=e,this},i.prototype.forceRed=function(e){return o(!this.red,"Already a number in reduction context"),this._forceRed(e)},i.prototype.redAdd=function(e){return o(this.red,"redAdd works only with red numbers"),this.red.add(this,e)},i.prototype.redIAdd=function(e){return o(this.red,"redIAdd works only with red numbers"),this.red.iadd(this,e)},i.prototype.redSub=function(e){return o(this.red,"redSub works only with red numbers"),this.red.sub(this,e)},i.prototype.redISub=function(e){return o(this.red,"redISub works only with red numbers"),this.red.isub(this,e)},i.prototype.redShl=function(e){return o(this.red,"redShl works only with red numbers"),this.red.shl(this,e)},i.prototype.redMul=function(e){return o(this.red,"redMul works only with red numbers"),this.red._verify2(this,e),this.red.mul(this,e)},i.prototype.redIMul=function(e){return o(this.red,"redMul works only with red numbers"),this.red._verify2(this,e),this.red.imul(this,e)},i.prototype.redSqr=function(){return o(this.red,"redSqr works only with red numbers"),this.red._verify1(this),this.red.sqr(this)},i.prototype.redISqr=function(){return o(this.red,"redISqr works only with red numbers"),this.red._verify1(this),this.red.isqr(this)},i.prototype.redSqrt=function(){return o(this.red,"redSqrt works only with red numbers"),this.red._verify1(this),this.red.sqrt(this)},i.prototype.redInvm=function(){return o(this.red,"redInvm works only with red numbers"),this.red._verify1(this),this.red.invm(this)},i.prototype.redNeg=function(){return o(this.red,"redNeg works only with red numbers"),this.red._verify1(this),this.red.neg(this)},i.prototype.redPow=function(e){return o(this.red&&!e.red,"redPow(normalNum)"),this.red._verify1(this),this.red.pow(this,e)};var _={k256:null,p224:null,p192:null,p25519:null};function F(e,t){this.name=e,this.p=new i(t,16),this.n=this.p.bitLength(),this.k=new i(1).iushln(this.n).isub(this.p),this.tmp=this._tmp()}function y(){F.call(this,"k256","ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f")}function b(){F.call(this,"p224","ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001")}function v(){F.call(this,"p192","ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff")}function w(){F.call(this,"25519","7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed")}function E(e){if("string"==typeof e){var t=i._prime(e);this.m=t.p,this.prime=t}else o(e.gtn(1),"modulus must be greater than 1"),this.m=e,this.prime=null}function k(e){E.call(this,e),this.shift=this.m.bitLength(),this.shift%26!=0&&(this.shift+=26-this.shift%26),this.r=new i(1).iushln(this.shift),this.r2=this.imod(this.r.sqr()),this.rinv=this.r._invmp(this.m),this.minv=this.rinv.mul(this.r).isubn(1).div(this.m),this.minv=this.minv.umod(this.r),this.minv=this.r.sub(this.minv)}F.prototype._tmp=function(){var e=new i(null);return e.words=new Array(Math.ceil(this.n/13)),e},F.prototype.ireduce=function(e){var t,n=e;do{this.split(n,this.tmp),t=(n=(n=this.imulK(n)).iadd(this.tmp)).bitLength()}while(t>this.n);var o=t0?n.isub(this.p):void 0!==n.strip?n.strip():n._strip(),n},F.prototype.split=function(e,t){e.iushrn(this.n,0,t)},F.prototype.imulK=function(e){return e.imul(this.k)},r(y,F),y.prototype.split=function(e,t){for(var n=4194303,o=Math.min(e.length,9),r=0;r>>22,i=a}i>>>=22,e.words[r-10]=i,0===i&&e.length>10?e.length-=10:e.length-=9},y.prototype.imulK=function(e){e.words[e.length]=0,e.words[e.length+1]=0,e.length+=2;for(var t=0,n=0;n>>=26,e.words[n]=r,t=o}return 0!==t&&(e.words[e.length++]=t),e},i._prime=function(e){if(_[e])return _[e];var t;if("k256"===e)t=new y;else if("p224"===e)t=new b;else if("p192"===e)t=new v;else{if("p25519"!==e)throw new Error("Unknown prime "+e);t=new w}return _[e]=t,t},E.prototype._verify1=function(e){o(0===e.negative,"red works only with positives"),o(e.red,"red works only with red numbers")},E.prototype._verify2=function(e,t){o(0==(e.negative|t.negative),"red works only with positives"),o(e.red&&e.red===t.red,"red works only with red numbers")},E.prototype.imod=function(e){return this.prime?this.prime.ireduce(e)._forceRed(this):e.umod(this.m)._forceRed(this)},E.prototype.neg=function(e){return e.isZero()?e.clone():this.m.sub(e)._forceRed(this)},E.prototype.add=function(e,t){this._verify2(e,t);var n=e.add(t);return n.cmp(this.m)>=0&&n.isub(this.m),n._forceRed(this)},E.prototype.iadd=function(e,t){this._verify2(e,t);var n=e.iadd(t);return n.cmp(this.m)>=0&&n.isub(this.m),n},E.prototype.sub=function(e,t){this._verify2(e,t);var n=e.sub(t);return n.cmpn(0)<0&&n.iadd(this.m),n._forceRed(this)},E.prototype.isub=function(e,t){this._verify2(e,t);var n=e.isub(t);return n.cmpn(0)<0&&n.iadd(this.m),n},E.prototype.shl=function(e,t){return this._verify1(e),this.imod(e.ushln(t))},E.prototype.imul=function(e,t){return this._verify2(e,t),this.imod(e.imul(t))},E.prototype.mul=function(e,t){return this._verify2(e,t),this.imod(e.mul(t))},E.prototype.isqr=function(e){return this.imul(e,e.clone())},E.prototype.sqr=function(e){return this.mul(e,e)},E.prototype.sqrt=function(e){if(e.isZero())return e.clone();var t=this.m.andln(3);if(o(t%2==1),3===t){var n=this.m.add(new i(1)).iushrn(2);return this.pow(e,n)}for(var r=this.m.subn(1),a=0;!r.isZero()&&0===r.andln(1);)a++,r.iushrn(1);o(!r.isZero());var s=new i(1).toRed(this),u=s.redNeg(),c=this.m.subn(1).iushrn(1),l=this.m.bitLength();for(l=new i(2*l*l).toRed(this);0!==this.pow(l,c).cmp(u);)l.redIAdd(u);for(var d=this.pow(l,r),h=this.pow(e,r.addn(1).iushrn(1)),p=this.pow(e,r),f=a;0!==p.cmp(s);){for(var g=p,m=0;0!==g.cmp(s);m++)g=g.redSqr();o(m=0;o--){for(var c=t.words[o],l=u-1;l>=0;l--){var d=c>>l&1;r!==n[0]&&(r=this.sqr(r)),0!==d||0!==a?(a<<=1,a|=d,(4==++s||0===o&&0===l)&&(r=this.mul(r,n[a]),s=0,a=0)):s=0}u=26}return r},E.prototype.convertTo=function(e){var t=e.umod(this.m);return t===e?t.clone():t},E.prototype.convertFrom=function(e){var t=e.clone();return t.red=null,t},i.mont=function(e){return new k(e)},r(k,E),k.prototype.convertTo=function(e){return this.imod(e.ushln(this.shift))},k.prototype.convertFrom=function(e){var t=this.imod(e.mul(this.rinv));return t.red=null,t},k.prototype.imul=function(e,t){if(e.isZero()||t.isZero())return e.words[0]=0,e.length=1,e;var n=e.imul(t),o=n.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m),r=n.isub(o).iushrn(this.shift),i=r;return r.cmp(this.m)>=0?i=r.isub(this.m):r.cmpn(0)<0&&(i=r.iadd(this.m)),i._forceRed(this)},k.prototype.mul=function(e,t){if(e.isZero()||t.isZero())return new i(0)._forceRed(this);var n=e.mul(t),o=n.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m),r=n.isub(o).iushrn(this.shift),a=r;return r.cmp(this.m)>=0?a=r.isub(this.m):r.cmpn(0)<0&&(a=r.iadd(this.m)),a._forceRed(this)},k.prototype.invm=function(e){return this.imod(e._invmp(this.m).mul(this.r2))._forceRed(this)}}(e=n.nmd(e),this)},23482:(e,t,n)=>{"use strict";var o=n(35717),r=n(62318),i=n(79785),a=n(89072),s=n(71027);function u(e){s.call(this,"digest"),this._hash=e}o(u,s),u.prototype._update=function(e){this._hash.update(e)},u.prototype._final=function(){return this._hash.digest()},e.exports=function(e){return"md5"===(e=e.toLowerCase())?new r:"rmd160"===e||"ripemd160"===e?new i:new u(a(e))}},78028:(e,t,n)=>{var o=n(62318);e.exports=function(e){return(new o).update(e).digest()}},58355:(e,t,n)=>{"use strict";var o=n(35717),r=n(51031),i=n(71027),a=n(89509).Buffer,s=n(78028),u=n(79785),c=n(89072),l=a.alloc(128);function d(e,t){i.call(this,"digest"),"string"==typeof t&&(t=a.from(t));var n="sha512"===e||"sha384"===e?128:64;this._alg=e,this._key=t,t.length>n?t=("rmd160"===e?new u:c(e)).update(t).digest():t.length{"use strict";var o=n(35717),r=n(89509).Buffer,i=n(71027),a=r.alloc(128),s=64;function u(e,t){i.call(this,"digest"),"string"==typeof t&&(t=r.from(t)),this._alg=e,this._key=t,t.length>s?t=e(t):t.length{"use strict";t.randomBytes=t.rng=t.pseudoRandomBytes=t.prng=n(61798),t.createHash=t.Hash=n(23482),t.createHmac=t.Hmac=n(58355);var o=n(56042),r=Object.keys(o),i=["sha1","sha224","sha256","sha384","sha512","md5","rmd160"].concat(r);t.getHashes=function(){return i};var a=n(25632);t.pbkdf2=a.pbkdf2,t.pbkdf2Sync=a.pbkdf2Sync;var s=n(53614);t.Cipher=s.Cipher,t.createCipher=s.createCipher,t.Cipheriv=s.Cipheriv,t.createCipheriv=s.createCipheriv,t.Decipher=s.Decipher,t.createDecipher=s.createDecipher,t.Decipheriv=s.Decipheriv,t.createDecipheriv=s.createDecipheriv,t.getCiphers=s.getCiphers,t.listCiphers=s.listCiphers;var u=n(62607);t.DiffieHellmanGroup=u.DiffieHellmanGroup,t.createDiffieHellmanGroup=u.createDiffieHellmanGroup,t.getDiffieHellman=u.getDiffieHellman,t.createDiffieHellman=u.createDiffieHellman,t.DiffieHellman=u.DiffieHellman;var c=n(64743);t.createSign=c.createSign,t.Sign=c.Sign,t.createVerify=c.createVerify,t.Verify=c.Verify,t.createECDH=n(76393);var l=n(7900);t.publicEncrypt=l.publicEncrypt,t.privateEncrypt=l.privateEncrypt,t.publicDecrypt=l.publicDecrypt,t.privateDecrypt=l.privateDecrypt;var d=n(77963);t.randomFill=d.randomFill,t.randomFillSync=d.randomFillSync,t.createCredentials=function(){throw new Error(["sorry, createCredentials is not implemented yet","we accept pull requests","https://github.com/crypto-browserify/crypto-browserify"].join("\n"))},t.constants={DH_CHECK_P_NOT_SAFE_PRIME:2,DH_CHECK_P_NOT_PRIME:1,DH_UNABLE_TO_CHECK_GENERATOR:4,DH_NOT_SUITABLE_GENERATOR:8,NPN_ENABLED:1,ALPN_ENABLED:1,RSA_PKCS1_PADDING:1,RSA_SSLV23_PADDING:2,RSA_NO_PADDING:3,RSA_PKCS1_OAEP_PADDING:4,RSA_X931_PADDING:5,RSA_PKCS1_PSS_PADDING:6,POINT_CONVERSION_COMPRESSED:2,POINT_CONVERSION_UNCOMPRESSED:4,POINT_CONVERSION_HYBRID:6}},48116:(e,t,n)=>{"use strict";var o;function r(e){return(r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}!function(i){var a,s,u,c=arguments,l=(a=/d{1,4}|D{3,4}|m{1,4}|yy(?:yy)?|([HhMsTt])\1?|W{1,2}|[LlopSZN]|"[^"]*"|'[^']*'/g,s=/\b(?:[PMCEA][SDP]T|(?:Pacific|Mountain|Central|Eastern|Atlantic) (?:Standard|Daylight|Prevailing) Time|(?:GMT|UTC)(?:[-+]\d{4})?)\b/g,u=/[^-+\dA-Z]/g,function(e,t,n,o){if(1!==c.length||"string"!==g(e)||/\d/.test(e)||(t=e,e=void 0),(e=e||0===e?e:new Date)instanceof Date||(e=new Date(e)),isNaN(e))throw TypeError("Invalid date");var r=(t=String(l.masks[t]||t||l.masks.default)).slice(0,4);"UTC:"!==r&&"GMT:"!==r||(t=t.slice(4),n=!0,"GMT:"===r&&(o=!0));var i=function(){return n?"getUTC":"get"},m=function(){return e[i()+"Date"]()},_=function(){return e[i()+"Day"]()},F=function(){return e[i()+"Month"]()},y=function(){return e[i()+"FullYear"]()},b=function(){return e[i()+"Hours"]()},v=function(){return e[i()+"Minutes"]()},w=function(){return e[i()+"Seconds"]()},E=function(){return e[i()+"Milliseconds"]()},k=function(){return n?0:e.getTimezoneOffset()},D=function(){return p(e)},S={d:function(){return m()},dd:function(){return d(m())},ddd:function(){return l.i18n.dayNames[_()]},DDD:function(){return h({y:y(),m:F(),d:m(),_:i(),dayName:l.i18n.dayNames[_()],short:!0})},dddd:function(){return l.i18n.dayNames[_()+7]},DDDD:function(){return h({y:y(),m:F(),d:m(),_:i(),dayName:l.i18n.dayNames[_()+7]})},m:function(){return F()+1},mm:function(){return d(F()+1)},mmm:function(){return l.i18n.monthNames[F()]},mmmm:function(){return l.i18n.monthNames[F()+12]},yy:function(){return String(y()).slice(2)},yyyy:function(){return d(y(),4)},h:function(){return b()%12||12},hh:function(){return d(b()%12||12)},H:function(){return b()},HH:function(){return d(b())},M:function(){return v()},MM:function(){return d(v())},s:function(){return w()},ss:function(){return d(w())},l:function(){return d(E(),3)},L:function(){return d(Math.floor(E()/10))},t:function(){return b()<12?l.i18n.timeNames[0]:l.i18n.timeNames[1]},tt:function(){return b()<12?l.i18n.timeNames[2]:l.i18n.timeNames[3]},T:function(){return b()<12?l.i18n.timeNames[4]:l.i18n.timeNames[5]},TT:function(){return b()<12?l.i18n.timeNames[6]:l.i18n.timeNames[7]},Z:function(){return o?"GMT":n?"UTC":(String(e).match(s)||[""]).pop().replace(u,"").replace(/GMT\+0000/g,"UTC")},o:function(){return(k()>0?"-":"+")+d(100*Math.floor(Math.abs(k())/60)+Math.abs(k())%60,4)},p:function(){return(k()>0?"-":"+")+d(Math.floor(Math.abs(k())/60),2)+":"+d(Math.floor(Math.abs(k())%60),2)},S:function(){return["th","st","nd","rd"][m()%10>3?0:(m()%100-m()%10!=10)*m()%10]},W:function(){return D()},WW:function(){return d(D())},N:function(){return f(e)}};return t.replace(a,(function(e){return e in S?S[e]():e.slice(1,e.length-1)}))});l.masks={default:"ddd mmm dd yyyy HH:MM:ss",shortDate:"m/d/yy",paddedShortDate:"mm/dd/yyyy",mediumDate:"mmm d, yyyy",longDate:"mmmm d, yyyy",fullDate:"dddd, mmmm d, yyyy",shortTime:"h:MM TT",mediumTime:"h:MM:ss TT",longTime:"h:MM:ss TT Z",isoDate:"yyyy-mm-dd",isoTime:"HH:MM:ss",isoDateTime:"yyyy-mm-dd'T'HH:MM:sso",isoUtcDateTime:"UTC:yyyy-mm-dd'T'HH:MM:ss'Z'",expiresHeaderFormat:"ddd, dd mmm yyyy HH:MM:ss Z"},l.i18n={dayNames:["Sun","Mon","Tue","Wed","Thu","Fri","Sat","Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],monthNames:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec","January","February","March","April","May","June","July","August","September","October","November","December"],timeNames:["a","p","am","pm","A","P","AM","PM"]};var d=function(e,t){for(e=String(e),t=t||2;e.length{var o=n(89539),r=n(32554).NI;function i(e){r.call(this,"string"==typeof e?e:""),this._db=void 0,this._operations=[]}o.inherits(i,r),i.prototype.setDb=function(e){this._db=e,this._operations.forEach((function(t){e[t.method].apply(e,t.args)}))},i.prototype._open=function(e,t){return process.nextTick(t)},i.prototype._operation=function(e,t){if(this._db)return this._db[e].apply(this._db,t);this._operations.push({method:e,args:t})},"put get del batch approximateSize".split(" ").forEach((function(e){i.prototype["_"+e]=function(){this._operation(e,arguments)}})),i.prototype._isBuffer=function(e){return Buffer.isBuffer(e)},i.prototype._iterator=function(){throw new TypeError("not implemented")},e.exports=i},15251:(e,t,n)=>{"use strict";t.utils=n(11278),t.Cipher=n(55756),t.DES=n(70778),t.CBC=n(39051),t.EDE=n(50651)},39051:(e,t,n)=>{"use strict";var o=n(79746),r=n(35717),i={};function a(e){o.equal(e.length,8,"Invalid IV length"),this.iv=new Array(8);for(var t=0;t{"use strict";var o=n(79746);function r(e){this.options=e,this.type=this.options.type,this.blockSize=8,this._init(),this.buffer=new Array(this.blockSize),this.bufferOff=0}e.exports=r,r.prototype._init=function(){},r.prototype.update=function(e){return 0===e.length?[]:"decrypt"===this.type?this._updateDecrypt(e):this._updateEncrypt(e)},r.prototype._buffer=function(e,t){for(var n=Math.min(this.buffer.length-this.bufferOff,e.length-t),o=0;o0;o--)t+=this._buffer(e,t),n+=this._flushBuffer(r,n);return t+=this._buffer(e,t),r},r.prototype.final=function(e){var t,n;return e&&(t=this.update(e)),n="encrypt"===this.type?this._finalEncrypt():this._finalDecrypt(),t?t.concat(n):n},r.prototype._pad=function(e,t){if(0===t)return!1;for(;t{"use strict";var o=n(79746),r=n(35717),i=n(11278),a=n(55756);function s(){this.tmp=new Array(2),this.keys=null}function u(e){a.call(this,e);var t=new s;this._desState=t,this.deriveKeys(t,e.key)}r(u,a),e.exports=u,u.create=function(e){return new u(e)};var c=[1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1];u.prototype.deriveKeys=function(e,t){e.keys=new Array(32),o.equal(t.length,this.blockSize,"Invalid key length");var n=i.readUInt32BE(t,0),r=i.readUInt32BE(t,4);i.pc1(n,r,e.tmp,0),n=e.tmp[0],r=e.tmp[1];for(var a=0;a>>1];n=i.r28shl(n,s),r=i.r28shl(r,s),i.pc2(n,r,e.keys,a)}},u.prototype._update=function(e,t,n,o){var r=this._desState,a=i.readUInt32BE(e,t),s=i.readUInt32BE(e,t+4);i.ip(a,s,r.tmp,0),a=r.tmp[0],s=r.tmp[1],"encrypt"===this.type?this._encrypt(r,a,s,r.tmp,0):this._decrypt(r,a,s,r.tmp,0),a=r.tmp[0],s=r.tmp[1],i.writeUInt32BE(n,a,o),i.writeUInt32BE(n,s,o+4)},u.prototype._pad=function(e,t){for(var n=e.length-t,o=t;o>>0,a=h}i.rip(s,a,o,r)},u.prototype._decrypt=function(e,t,n,o,r){for(var a=n,s=t,u=e.keys.length-2;u>=0;u-=2){var c=e.keys[u],l=e.keys[u+1];i.expand(a,e.tmp,0),c^=e.tmp[0],l^=e.tmp[1];var d=i.substitute(c,l),h=a;a=(s^i.permute(d))>>>0,s=h}i.rip(a,s,o,r)}},50651:(e,t,n)=>{"use strict";var o=n(79746),r=n(35717),i=n(55756),a=n(70778);function s(e,t){o.equal(t.length,24,"Invalid key length");var n=t.slice(0,8),r=t.slice(8,16),i=t.slice(16,24);this.ciphers="encrypt"===e?[a.create({type:"encrypt",key:n}),a.create({type:"decrypt",key:r}),a.create({type:"encrypt",key:i})]:[a.create({type:"decrypt",key:i}),a.create({type:"encrypt",key:r}),a.create({type:"decrypt",key:n})]}function u(e){i.call(this,e);var t=new s(this.type,this.options.key);this._edeState=t}r(u,i),e.exports=u,u.create=function(e){return new u(e)},u.prototype._update=function(e,t,n,o){var r=this._edeState;r.ciphers[0]._update(e,t,n,o),r.ciphers[1]._update(n,o,n,o),r.ciphers[2]._update(n,o,n,o)},u.prototype._pad=a.prototype._pad,u.prototype._unpad=a.prototype._unpad},11278:(e,t)=>{"use strict";t.readUInt32BE=function(e,t){return(e[0+t]<<24|e[1+t]<<16|e[2+t]<<8|e[3+t])>>>0},t.writeUInt32BE=function(e,t,n){e[0+n]=t>>>24,e[1+n]=t>>>16&255,e[2+n]=t>>>8&255,e[3+n]=255&t},t.ip=function(e,t,n,o){for(var r=0,i=0,a=6;a>=0;a-=2){for(var s=0;s<=24;s+=8)r<<=1,r|=t>>>s+a&1;for(s=0;s<=24;s+=8)r<<=1,r|=e>>>s+a&1}for(a=6;a>=0;a-=2){for(s=1;s<=25;s+=8)i<<=1,i|=t>>>s+a&1;for(s=1;s<=25;s+=8)i<<=1,i|=e>>>s+a&1}n[o+0]=r>>>0,n[o+1]=i>>>0},t.rip=function(e,t,n,o){for(var r=0,i=0,a=0;a<4;a++)for(var s=24;s>=0;s-=8)r<<=1,r|=t>>>s+a&1,r<<=1,r|=e>>>s+a&1;for(a=4;a<8;a++)for(s=24;s>=0;s-=8)i<<=1,i|=t>>>s+a&1,i<<=1,i|=e>>>s+a&1;n[o+0]=r>>>0,n[o+1]=i>>>0},t.pc1=function(e,t,n,o){for(var r=0,i=0,a=7;a>=5;a--){for(var s=0;s<=24;s+=8)r<<=1,r|=t>>s+a&1;for(s=0;s<=24;s+=8)r<<=1,r|=e>>s+a&1}for(s=0;s<=24;s+=8)r<<=1,r|=t>>s+a&1;for(a=1;a<=3;a++){for(s=0;s<=24;s+=8)i<<=1,i|=t>>s+a&1;for(s=0;s<=24;s+=8)i<<=1,i|=e>>s+a&1}for(s=0;s<=24;s+=8)i<<=1,i|=e>>s+a&1;n[o+0]=r>>>0,n[o+1]=i>>>0},t.r28shl=function(e,t){return e<>>28-t};var n=[14,11,17,4,27,23,25,0,13,22,7,18,5,9,16,24,2,20,12,21,1,8,15,26,15,4,25,19,9,1,26,16,5,11,23,8,12,7,17,0,22,3,10,14,6,20,27,24];t.pc2=function(e,t,o,r){for(var i=0,a=0,s=n.length>>>1,u=0;u>>n[u]&1;for(u=s;u>>n[u]&1;o[r+0]=i>>>0,o[r+1]=a>>>0},t.expand=function(e,t,n){var o=0,r=0;o=(1&e)<<5|e>>>27;for(var i=23;i>=15;i-=4)o<<=6,o|=e>>>i&63;for(i=11;i>=3;i-=4)r|=e>>>i&63,r<<=6;r|=(31&e)<<1|e>>>31,t[n+0]=o>>>0,t[n+1]=r>>>0};var o=[14,0,4,15,13,7,1,4,2,14,15,2,11,13,8,1,3,10,10,6,6,12,12,11,5,9,9,5,0,3,7,8,4,15,1,12,14,8,8,2,13,4,6,9,2,1,11,7,15,5,12,11,9,3,7,14,3,10,10,0,5,6,0,13,15,3,1,13,8,4,14,7,6,15,11,2,3,8,4,14,9,12,7,0,2,1,13,10,12,6,0,9,5,11,10,5,0,13,14,8,7,10,11,1,10,3,4,15,13,4,1,2,5,11,8,6,12,7,6,12,9,0,3,5,2,14,15,9,10,13,0,7,9,0,14,9,6,3,3,4,15,6,5,10,1,2,13,8,12,5,7,14,11,12,4,11,2,15,8,1,13,1,6,10,4,13,9,0,8,6,15,9,3,8,0,7,11,4,1,15,2,14,12,3,5,11,10,5,14,2,7,12,7,13,13,8,14,11,3,5,0,6,6,15,9,0,10,3,1,4,2,7,8,2,5,12,11,1,12,10,4,14,15,9,10,3,6,15,9,0,0,6,12,10,11,1,7,13,13,8,15,9,1,4,3,5,14,11,5,12,2,7,8,2,4,14,2,14,12,11,4,2,1,12,7,4,10,7,11,13,6,1,8,5,5,0,3,15,15,10,13,3,0,9,14,8,9,6,4,11,2,8,1,12,11,7,10,1,13,14,7,2,8,13,15,6,9,15,12,0,5,9,6,10,3,4,0,5,14,3,12,10,1,15,10,4,15,2,9,7,2,12,6,9,8,5,0,6,13,1,3,13,4,14,14,0,7,11,5,3,11,8,9,4,14,3,15,2,5,12,2,9,8,5,12,15,3,10,7,11,0,14,4,1,10,7,1,6,13,0,11,8,6,13,4,13,11,0,2,11,14,7,15,4,0,9,8,1,13,10,3,14,12,3,9,5,7,12,5,2,10,15,6,8,1,6,1,6,4,11,11,13,13,8,12,1,3,4,7,10,14,7,10,9,15,5,6,0,8,15,0,14,5,2,9,3,2,12,13,1,2,15,8,13,4,8,6,10,15,3,11,7,1,4,10,12,9,5,3,6,14,11,5,0,0,14,12,9,7,2,7,2,11,1,4,14,1,7,9,4,12,10,14,8,2,13,0,15,6,12,10,9,13,0,15,3,3,5,5,6,8,11];t.substitute=function(e,t){for(var n=0,r=0;r<4;r++)n<<=4,n|=o[64*r+(e>>>18-6*r&63)];for(r=0;r<4;r++)n<<=4,n|=o[256+64*r+(t>>>18-6*r&63)];return n>>>0};var r=[16,25,12,11,3,20,4,15,31,17,9,6,27,14,1,22,30,24,8,18,0,5,29,23,13,19,2,26,10,21,28,7];t.permute=function(e){for(var t=0,n=0;n>>r[n]&1;return t>>>0},t.padSplit=function(e,t,n){for(var o=e.toString(2);o.length{var o=n(43590),r=n(61930),i=n(57426),a={binary:!0,hex:!0,base64:!0};t.DiffieHellmanGroup=t.createDiffieHellmanGroup=t.getDiffieHellman=function(e){var t=new Buffer(r[e].prime,"hex"),n=new Buffer(r[e].gen,"hex");return new i(t,n)},t.createDiffieHellman=t.DiffieHellman=function e(t,n,r,s){return Buffer.isBuffer(n)||void 0===a[n]?e(t,"binary",n,r):(n=n||"binary",s=s||"binary",r=r||new Buffer([2]),Buffer.isBuffer(r)||(r=new Buffer(r,s)),"number"==typeof t?new i(o(t,r),r,!0):(Buffer.isBuffer(t)||(t=new Buffer(t,n)),new i(t,r,!0)))}},57426:(e,t,n)=>{var o=n(83620),r=new(n(63047)),i=new o(24),a=new o(11),s=new o(10),u=new o(3),c=new o(7),l=n(43590),d=n(61798);function h(e,t){return t=t||"utf8",Buffer.isBuffer(e)||(e=new Buffer(e,t)),this._pub=new o(e),this}function p(e,t){return t=t||"utf8",Buffer.isBuffer(e)||(e=new Buffer(e,t)),this._priv=new o(e),this}e.exports=g;var f={};function g(e,t,n){this.setGenerator(t),this.__prime=new o(e),this._prime=o.mont(this.__prime),this._primeLen=e.length,this._pub=void 0,this._priv=void 0,this._primeCode=void 0,n?(this.setPublicKey=h,this.setPrivateKey=p):this._primeCode=8}function m(e,t){var n=new Buffer(e.toArray());return t?n.toString(t):n}Object.defineProperty(g.prototype,"verifyError",{enumerable:!0,get:function(){return"number"!=typeof this._primeCode&&(this._primeCode=function(e,t){var n=t.toString("hex"),o=[n,e.toString(16)].join("_");if(o in f)return f[o];var d,h=0;if(e.isEven()||!l.simpleSieve||!l.fermatTest(e)||!r.test(e))return h+=1,h+="02"===n||"05"===n?8:4,f[o]=h,h;switch(r.test(e.shrn(1))||(h+=2),n){case"02":e.mod(i).cmp(a)&&(h+=8);break;case"05":(d=e.mod(s)).cmp(u)&&d.cmp(c)&&(h+=8);break;default:h+=4}return f[o]=h,h}(this.__prime,this.__gen)),this._primeCode}}),g.prototype.generateKeys=function(){return this._priv||(this._priv=new o(d(this._primeLen))),this._pub=this._gen.toRed(this._prime).redPow(this._priv).fromRed(),this.getPublicKey()},g.prototype.computeSecret=function(e){var t=(e=(e=new o(e)).toRed(this._prime)).redPow(this._priv).fromRed(),n=new Buffer(t.toArray()),r=this.getPrime();if(n.length{var o=n(61798);e.exports=F,F.simpleSieve=m,F.fermatTest=_;var r=n(83620),i=new r(24),a=new(n(63047)),s=new r(1),u=new r(2),c=new r(5),l=(new r(16),new r(8),new r(10)),d=new r(3),h=(new r(7),new r(11)),p=new r(4),f=(new r(12),null);function g(){if(null!==f)return f;var e=[];e[0]=2;for(var t=1,n=3;n<1048576;n+=2){for(var o=Math.ceil(Math.sqrt(n)),r=0;re;)n.ishrn(1);if(n.isEven()&&n.iadd(s),n.testn(1)||n.iadd(u),t.cmp(u)){if(!t.cmp(c))for(;n.mod(l).cmp(d);)n.iadd(p)}else for(;n.mod(i).cmp(h);)n.iadd(p);if(m(f=n.shrn(1))&&m(n)&&_(f)&&_(n)&&a.test(f)&&a.test(n))return n}}},61930:e=>{"use strict";e.exports=JSON.parse('{"modp1":{"gen":"02","prime":"ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a63a3620ffffffffffffffff"},"modp2":{"gen":"02","prime":"ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece65381ffffffffffffffff"},"modp5":{"gen":"02","prime":"ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca237327ffffffffffffffff"},"modp14":{"gen":"02","prime":"ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aacaa68ffffffffffffffff"},"modp15":{"gen":"02","prime":"ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aaac42dad33170d04507a33a85521abdf1cba64ecfb850458dbef0a8aea71575d060c7db3970f85a6e1e4c7abf5ae8cdb0933d71e8c94e04a25619dcee3d2261ad2ee6bf12ffa06d98a0864d87602733ec86a64521f2b18177b200cbbe117577a615d6c770988c0bad946e208e24fa074e5ab3143db5bfce0fd108e4b82d120a93ad2caffffffffffffffff"},"modp16":{"gen":"02","prime":"ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aaac42dad33170d04507a33a85521abdf1cba64ecfb850458dbef0a8aea71575d060c7db3970f85a6e1e4c7abf5ae8cdb0933d71e8c94e04a25619dcee3d2261ad2ee6bf12ffa06d98a0864d87602733ec86a64521f2b18177b200cbbe117577a615d6c770988c0bad946e208e24fa074e5ab3143db5bfce0fd108e4b82d120a92108011a723c12a787e6d788719a10bdba5b2699c327186af4e23c1a946834b6150bda2583e9ca2ad44ce8dbbbc2db04de8ef92e8efc141fbecaa6287c59474e6bc05d99b2964fa090c3a2233ba186515be7ed1f612970cee2d7afb81bdd762170481cd0069127d5b05aa993b4ea988d8fddc186ffb7dc90a6c08f4df435c934063199ffffffffffffffff"},"modp17":{"gen":"02","prime":"ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aaac42dad33170d04507a33a85521abdf1cba64ecfb850458dbef0a8aea71575d060c7db3970f85a6e1e4c7abf5ae8cdb0933d71e8c94e04a25619dcee3d2261ad2ee6bf12ffa06d98a0864d87602733ec86a64521f2b18177b200cbbe117577a615d6c770988c0bad946e208e24fa074e5ab3143db5bfce0fd108e4b82d120a92108011a723c12a787e6d788719a10bdba5b2699c327186af4e23c1a946834b6150bda2583e9ca2ad44ce8dbbbc2db04de8ef92e8efc141fbecaa6287c59474e6bc05d99b2964fa090c3a2233ba186515be7ed1f612970cee2d7afb81bdd762170481cd0069127d5b05aa993b4ea988d8fddc186ffb7dc90a6c08f4df435c93402849236c3fab4d27c7026c1d4dcb2602646dec9751e763dba37bdf8ff9406ad9e530ee5db382f413001aeb06a53ed9027d831179727b0865a8918da3edbebcf9b14ed44ce6cbaced4bb1bdb7f1447e6cc254b332051512bd7af426fb8f401378cd2bf5983ca01c64b92ecf032ea15d1721d03f482d7ce6e74fef6d55e702f46980c82b5a84031900b1c9e59e7c97fbec7e8f323a97a7e36cc88be0f1d45b7ff585ac54bd407b22b4154aacc8f6d7ebf48e1d814cc5ed20f8037e0a79715eef29be32806a1d58bb7c5da76f550aa3d8a1fbff0eb19ccb1a313d55cda56c9ec2ef29632387fe8d76e3c0468043e8f663f4860ee12bf2d5b0b7474d6e694f91e6dcc4024ffffffffffffffff"},"modp18":{"gen":"02","prime":"ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aaac42dad33170d04507a33a85521abdf1cba64ecfb850458dbef0a8aea71575d060c7db3970f85a6e1e4c7abf5ae8cdb0933d71e8c94e04a25619dcee3d2261ad2ee6bf12ffa06d98a0864d87602733ec86a64521f2b18177b200cbbe117577a615d6c770988c0bad946e208e24fa074e5ab3143db5bfce0fd108e4b82d120a92108011a723c12a787e6d788719a10bdba5b2699c327186af4e23c1a946834b6150bda2583e9ca2ad44ce8dbbbc2db04de8ef92e8efc141fbecaa6287c59474e6bc05d99b2964fa090c3a2233ba186515be7ed1f612970cee2d7afb81bdd762170481cd0069127d5b05aa993b4ea988d8fddc186ffb7dc90a6c08f4df435c93402849236c3fab4d27c7026c1d4dcb2602646dec9751e763dba37bdf8ff9406ad9e530ee5db382f413001aeb06a53ed9027d831179727b0865a8918da3edbebcf9b14ed44ce6cbaced4bb1bdb7f1447e6cc254b332051512bd7af426fb8f401378cd2bf5983ca01c64b92ecf032ea15d1721d03f482d7ce6e74fef6d55e702f46980c82b5a84031900b1c9e59e7c97fbec7e8f323a97a7e36cc88be0f1d45b7ff585ac54bd407b22b4154aacc8f6d7ebf48e1d814cc5ed20f8037e0a79715eef29be32806a1d58bb7c5da76f550aa3d8a1fbff0eb19ccb1a313d55cda56c9ec2ef29632387fe8d76e3c0468043e8f663f4860ee12bf2d5b0b7474d6e694f91e6dbe115974a3926f12fee5e438777cb6a932df8cd8bec4d073b931ba3bc832b68d9dd300741fa7bf8afc47ed2576f6936ba424663aab639c5ae4f5683423b4742bf1c978238f16cbe39d652de3fdb8befc848ad922222e04a4037c0713eb57a81a23f0c73473fc646cea306b4bcbc8862f8385ddfa9d4b7fa2c087e879683303ed5bdd3a062b3cf5b3a278a66d2a13f83f44f82ddf310ee074ab6a364597e899a0255dc164f31cc50846851df9ab48195ded7ea1b1d510bd7ee74d73faf36bc31ecfa268359046f4eb879f924009438b481c6cd7889a002ed5ee382bc9190da6fc026e479558e4475677e9aa9e3050e2765694dfc81f56e880b96e7160c980dd98edd3dfffffffffffffffff"}}')},83620:function(e,t,n){!function(e,t){"use strict";function o(e,t){if(!e)throw new Error(t||"Assertion failed")}function r(e,t){e.super_=t;var n=function(){};n.prototype=t.prototype,e.prototype=new n,e.prototype.constructor=e}function i(e,t,n){if(i.isBN(e))return e;this.negative=0,this.words=null,this.length=0,this.red=null,null!==e&&("le"!==t&&"be"!==t||(n=t,t=10),this._init(e||0,t||10,n||"be"))}var a;"object"==typeof e?e.exports=i:t.BN=i,i.BN=i,i.wordSize=26;try{a="undefined"!=typeof window&&void 0!==window.Buffer?window.Buffer:n(7748).Buffer}catch(e){}function s(e,t){var n=e.charCodeAt(t);return n>=65&&n<=70?n-55:n>=97&&n<=102?n-87:n-48&15}function u(e,t,n){var o=s(e,n);return n-1>=t&&(o|=s(e,n-1)<<4),o}function c(e,t,n,o){for(var r=0,i=Math.min(e.length,n),a=t;a=49?s-49+10:s>=17?s-17+10:s}return r}i.isBN=function(e){return e instanceof i||null!==e&&"object"==typeof e&&e.constructor.wordSize===i.wordSize&&Array.isArray(e.words)},i.max=function(e,t){return e.cmp(t)>0?e:t},i.min=function(e,t){return e.cmp(t)<0?e:t},i.prototype._init=function(e,t,n){if("number"==typeof e)return this._initNumber(e,t,n);if("object"==typeof e)return this._initArray(e,t,n);"hex"===t&&(t=16),o(t===(0|t)&&t>=2&&t<=36);var r=0;"-"===(e=e.toString().replace(/\s+/g,""))[0]&&(r++,this.negative=1),r=0;r-=3)a=e[r]|e[r-1]<<8|e[r-2]<<16,this.words[i]|=a<>>26-s&67108863,(s+=24)>=26&&(s-=26,i++);else if("le"===n)for(r=0,i=0;r>>26-s&67108863,(s+=24)>=26&&(s-=26,i++);return this.strip()},i.prototype._parseHex=function(e,t,n){this.length=Math.ceil((e.length-t)/6),this.words=new Array(this.length);for(var o=0;o=t;o-=2)r=u(e,t,o)<=18?(i-=18,a+=1,this.words[a]|=r>>>26):i+=8;else for(o=(e.length-t)%2==0?t+1:t;o=18?(i-=18,a+=1,this.words[a]|=r>>>26):i+=8;this.strip()},i.prototype._parseBase=function(e,t,n){this.words=[0],this.length=1;for(var o=0,r=1;r<=67108863;r*=t)o++;o--,r=r/t|0;for(var i=e.length-n,a=i%o,s=Math.min(i,i-a)+n,u=0,l=n;l1&&0===this.words[this.length-1];)this.length--;return this._normSign()},i.prototype._normSign=function(){return 1===this.length&&0===this.words[0]&&(this.negative=0),this},i.prototype.inspect=function(){return(this.red?""};var l=["","0","00","000","0000","00000","000000","0000000","00000000","000000000","0000000000","00000000000","000000000000","0000000000000","00000000000000","000000000000000","0000000000000000","00000000000000000","000000000000000000","0000000000000000000","00000000000000000000","000000000000000000000","0000000000000000000000","00000000000000000000000","000000000000000000000000","0000000000000000000000000"],d=[0,0,25,16,12,11,10,9,8,8,7,7,7,7,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5],h=[0,0,33554432,43046721,16777216,48828125,60466176,40353607,16777216,43046721,1e7,19487171,35831808,62748517,7529536,11390625,16777216,24137569,34012224,47045881,64e6,4084101,5153632,6436343,7962624,9765625,11881376,14348907,17210368,20511149,243e5,28629151,33554432,39135393,45435424,52521875,60466176];function p(e,t,n){n.negative=t.negative^e.negative;var o=e.length+t.length|0;n.length=o,o=o-1|0;var r=0|e.words[0],i=0|t.words[0],a=r*i,s=67108863&a,u=a/67108864|0;n.words[0]=s;for(var c=1;c>>26,d=67108863&u,h=Math.min(c,t.length-1),p=Math.max(0,c-e.length+1);p<=h;p++){var f=c-p|0;l+=(a=(r=0|e.words[f])*(i=0|t.words[p])+d)/67108864|0,d=67108863&a}n.words[c]=0|d,u=0|l}return 0!==u?n.words[c]=0|u:n.length--,n.strip()}i.prototype.toString=function(e,t){var n;if(t=0|t||1,16===(e=e||10)||"hex"===e){n="";for(var r=0,i=0,a=0;a>>24-r&16777215)||a!==this.length-1?l[6-u.length]+u+n:u+n,(r+=2)>=26&&(r-=26,a--)}for(0!==i&&(n=i.toString(16)+n);n.length%t!=0;)n="0"+n;return 0!==this.negative&&(n="-"+n),n}if(e===(0|e)&&e>=2&&e<=36){var c=d[e],p=h[e];n="";var f=this.clone();for(f.negative=0;!f.isZero();){var g=f.modn(p).toString(e);n=(f=f.idivn(p)).isZero()?g+n:l[c-g.length]+g+n}for(this.isZero()&&(n="0"+n);n.length%t!=0;)n="0"+n;return 0!==this.negative&&(n="-"+n),n}o(!1,"Base should be between 2 and 36")},i.prototype.toNumber=function(){var e=this.words[0];return 2===this.length?e+=67108864*this.words[1]:3===this.length&&1===this.words[2]?e+=4503599627370496+67108864*this.words[1]:this.length>2&&o(!1,"Number can only safely store up to 53 bits"),0!==this.negative?-e:e},i.prototype.toJSON=function(){return this.toString(16)},i.prototype.toBuffer=function(e,t){return o(void 0!==a),this.toArrayLike(a,e,t)},i.prototype.toArray=function(e,t){return this.toArrayLike(Array,e,t)},i.prototype.toArrayLike=function(e,t,n){var r=this.byteLength(),i=n||Math.max(1,r);o(r<=i,"byte array longer than desired length"),o(i>0,"Requested array length <= 0"),this.strip();var a,s,u="le"===t,c=new e(i),l=this.clone();if(u){for(s=0;!l.isZero();s++)a=l.andln(255),l.iushrn(8),c[s]=a;for(;s=4096&&(n+=13,t>>>=13),t>=64&&(n+=7,t>>>=7),t>=8&&(n+=4,t>>>=4),t>=2&&(n+=2,t>>>=2),n+t},i.prototype._zeroBits=function(e){if(0===e)return 26;var t=e,n=0;return 0==(8191&t)&&(n+=13,t>>>=13),0==(127&t)&&(n+=7,t>>>=7),0==(15&t)&&(n+=4,t>>>=4),0==(3&t)&&(n+=2,t>>>=2),0==(1&t)&&n++,n},i.prototype.bitLength=function(){var e=this.words[this.length-1],t=this._countBits(e);return 26*(this.length-1)+t},i.prototype.zeroBits=function(){if(this.isZero())return 0;for(var e=0,t=0;te.length?this.clone().ior(e):e.clone().ior(this)},i.prototype.uor=function(e){return this.length>e.length?this.clone().iuor(e):e.clone().iuor(this)},i.prototype.iuand=function(e){var t;t=this.length>e.length?e:this;for(var n=0;ne.length?this.clone().iand(e):e.clone().iand(this)},i.prototype.uand=function(e){return this.length>e.length?this.clone().iuand(e):e.clone().iuand(this)},i.prototype.iuxor=function(e){var t,n;this.length>e.length?(t=this,n=e):(t=e,n=this);for(var o=0;oe.length?this.clone().ixor(e):e.clone().ixor(this)},i.prototype.uxor=function(e){return this.length>e.length?this.clone().iuxor(e):e.clone().iuxor(this)},i.prototype.inotn=function(e){o("number"==typeof e&&e>=0);var t=0|Math.ceil(e/26),n=e%26;this._expand(t),n>0&&t--;for(var r=0;r0&&(this.words[r]=~this.words[r]&67108863>>26-n),this.strip()},i.prototype.notn=function(e){return this.clone().inotn(e)},i.prototype.setn=function(e,t){o("number"==typeof e&&e>=0);var n=e/26|0,r=e%26;return this._expand(n+1),this.words[n]=t?this.words[n]|1<e.length?(n=this,o=e):(n=e,o=this);for(var r=0,i=0;i>>26;for(;0!==r&&i>>26;if(this.length=n.length,0!==r)this.words[this.length]=r,this.length++;else if(n!==this)for(;ie.length?this.clone().iadd(e):e.clone().iadd(this)},i.prototype.isub=function(e){if(0!==e.negative){e.negative=0;var t=this.iadd(e);return e.negative=1,t._normSign()}if(0!==this.negative)return this.negative=0,this.iadd(e),this.negative=1,this._normSign();var n,o,r=this.cmp(e);if(0===r)return this.negative=0,this.length=1,this.words[0]=0,this;r>0?(n=this,o=e):(n=e,o=this);for(var i=0,a=0;a>26,this.words[a]=67108863&t;for(;0!==i&&a>26,this.words[a]=67108863&t;if(0===i&&a>>13,p=0|a[1],f=8191&p,g=p>>>13,m=0|a[2],_=8191&m,F=m>>>13,y=0|a[3],b=8191&y,v=y>>>13,w=0|a[4],E=8191&w,k=w>>>13,D=0|a[5],S=8191&D,x=D>>>13,C=0|a[6],A=8191&C,T=C>>>13,R=0|a[7],I=8191&R,M=R>>>13,O=0|a[8],B=8191&O,N=O>>>13,L=0|a[9],P=8191&L,U=L>>>13,j=0|s[0],q=8191&j,z=j>>>13,K=0|s[1],G=8191&K,$=K>>>13,H=0|s[2],V=8191&H,W=H>>>13,Y=0|s[3],Z=8191&Y,X=Y>>>13,J=0|s[4],Q=8191&J,ee=J>>>13,te=0|s[5],ne=8191&te,oe=te>>>13,re=0|s[6],ie=8191&re,ae=re>>>13,se=0|s[7],ue=8191&se,ce=se>>>13,le=0|s[8],de=8191&le,he=le>>>13,pe=0|s[9],fe=8191&pe,ge=pe>>>13;n.negative=e.negative^t.negative,n.length=19;var me=(c+(o=Math.imul(d,q))|0)+((8191&(r=(r=Math.imul(d,z))+Math.imul(h,q)|0))<<13)|0;c=((i=Math.imul(h,z))+(r>>>13)|0)+(me>>>26)|0,me&=67108863,o=Math.imul(f,q),r=(r=Math.imul(f,z))+Math.imul(g,q)|0,i=Math.imul(g,z);var _e=(c+(o=o+Math.imul(d,G)|0)|0)+((8191&(r=(r=r+Math.imul(d,$)|0)+Math.imul(h,G)|0))<<13)|0;c=((i=i+Math.imul(h,$)|0)+(r>>>13)|0)+(_e>>>26)|0,_e&=67108863,o=Math.imul(_,q),r=(r=Math.imul(_,z))+Math.imul(F,q)|0,i=Math.imul(F,z),o=o+Math.imul(f,G)|0,r=(r=r+Math.imul(f,$)|0)+Math.imul(g,G)|0,i=i+Math.imul(g,$)|0;var Fe=(c+(o=o+Math.imul(d,V)|0)|0)+((8191&(r=(r=r+Math.imul(d,W)|0)+Math.imul(h,V)|0))<<13)|0;c=((i=i+Math.imul(h,W)|0)+(r>>>13)|0)+(Fe>>>26)|0,Fe&=67108863,o=Math.imul(b,q),r=(r=Math.imul(b,z))+Math.imul(v,q)|0,i=Math.imul(v,z),o=o+Math.imul(_,G)|0,r=(r=r+Math.imul(_,$)|0)+Math.imul(F,G)|0,i=i+Math.imul(F,$)|0,o=o+Math.imul(f,V)|0,r=(r=r+Math.imul(f,W)|0)+Math.imul(g,V)|0,i=i+Math.imul(g,W)|0;var ye=(c+(o=o+Math.imul(d,Z)|0)|0)+((8191&(r=(r=r+Math.imul(d,X)|0)+Math.imul(h,Z)|0))<<13)|0;c=((i=i+Math.imul(h,X)|0)+(r>>>13)|0)+(ye>>>26)|0,ye&=67108863,o=Math.imul(E,q),r=(r=Math.imul(E,z))+Math.imul(k,q)|0,i=Math.imul(k,z),o=o+Math.imul(b,G)|0,r=(r=r+Math.imul(b,$)|0)+Math.imul(v,G)|0,i=i+Math.imul(v,$)|0,o=o+Math.imul(_,V)|0,r=(r=r+Math.imul(_,W)|0)+Math.imul(F,V)|0,i=i+Math.imul(F,W)|0,o=o+Math.imul(f,Z)|0,r=(r=r+Math.imul(f,X)|0)+Math.imul(g,Z)|0,i=i+Math.imul(g,X)|0;var be=(c+(o=o+Math.imul(d,Q)|0)|0)+((8191&(r=(r=r+Math.imul(d,ee)|0)+Math.imul(h,Q)|0))<<13)|0;c=((i=i+Math.imul(h,ee)|0)+(r>>>13)|0)+(be>>>26)|0,be&=67108863,o=Math.imul(S,q),r=(r=Math.imul(S,z))+Math.imul(x,q)|0,i=Math.imul(x,z),o=o+Math.imul(E,G)|0,r=(r=r+Math.imul(E,$)|0)+Math.imul(k,G)|0,i=i+Math.imul(k,$)|0,o=o+Math.imul(b,V)|0,r=(r=r+Math.imul(b,W)|0)+Math.imul(v,V)|0,i=i+Math.imul(v,W)|0,o=o+Math.imul(_,Z)|0,r=(r=r+Math.imul(_,X)|0)+Math.imul(F,Z)|0,i=i+Math.imul(F,X)|0,o=o+Math.imul(f,Q)|0,r=(r=r+Math.imul(f,ee)|0)+Math.imul(g,Q)|0,i=i+Math.imul(g,ee)|0;var ve=(c+(o=o+Math.imul(d,ne)|0)|0)+((8191&(r=(r=r+Math.imul(d,oe)|0)+Math.imul(h,ne)|0))<<13)|0;c=((i=i+Math.imul(h,oe)|0)+(r>>>13)|0)+(ve>>>26)|0,ve&=67108863,o=Math.imul(A,q),r=(r=Math.imul(A,z))+Math.imul(T,q)|0,i=Math.imul(T,z),o=o+Math.imul(S,G)|0,r=(r=r+Math.imul(S,$)|0)+Math.imul(x,G)|0,i=i+Math.imul(x,$)|0,o=o+Math.imul(E,V)|0,r=(r=r+Math.imul(E,W)|0)+Math.imul(k,V)|0,i=i+Math.imul(k,W)|0,o=o+Math.imul(b,Z)|0,r=(r=r+Math.imul(b,X)|0)+Math.imul(v,Z)|0,i=i+Math.imul(v,X)|0,o=o+Math.imul(_,Q)|0,r=(r=r+Math.imul(_,ee)|0)+Math.imul(F,Q)|0,i=i+Math.imul(F,ee)|0,o=o+Math.imul(f,ne)|0,r=(r=r+Math.imul(f,oe)|0)+Math.imul(g,ne)|0,i=i+Math.imul(g,oe)|0;var we=(c+(o=o+Math.imul(d,ie)|0)|0)+((8191&(r=(r=r+Math.imul(d,ae)|0)+Math.imul(h,ie)|0))<<13)|0;c=((i=i+Math.imul(h,ae)|0)+(r>>>13)|0)+(we>>>26)|0,we&=67108863,o=Math.imul(I,q),r=(r=Math.imul(I,z))+Math.imul(M,q)|0,i=Math.imul(M,z),o=o+Math.imul(A,G)|0,r=(r=r+Math.imul(A,$)|0)+Math.imul(T,G)|0,i=i+Math.imul(T,$)|0,o=o+Math.imul(S,V)|0,r=(r=r+Math.imul(S,W)|0)+Math.imul(x,V)|0,i=i+Math.imul(x,W)|0,o=o+Math.imul(E,Z)|0,r=(r=r+Math.imul(E,X)|0)+Math.imul(k,Z)|0,i=i+Math.imul(k,X)|0,o=o+Math.imul(b,Q)|0,r=(r=r+Math.imul(b,ee)|0)+Math.imul(v,Q)|0,i=i+Math.imul(v,ee)|0,o=o+Math.imul(_,ne)|0,r=(r=r+Math.imul(_,oe)|0)+Math.imul(F,ne)|0,i=i+Math.imul(F,oe)|0,o=o+Math.imul(f,ie)|0,r=(r=r+Math.imul(f,ae)|0)+Math.imul(g,ie)|0,i=i+Math.imul(g,ae)|0;var Ee=(c+(o=o+Math.imul(d,ue)|0)|0)+((8191&(r=(r=r+Math.imul(d,ce)|0)+Math.imul(h,ue)|0))<<13)|0;c=((i=i+Math.imul(h,ce)|0)+(r>>>13)|0)+(Ee>>>26)|0,Ee&=67108863,o=Math.imul(B,q),r=(r=Math.imul(B,z))+Math.imul(N,q)|0,i=Math.imul(N,z),o=o+Math.imul(I,G)|0,r=(r=r+Math.imul(I,$)|0)+Math.imul(M,G)|0,i=i+Math.imul(M,$)|0,o=o+Math.imul(A,V)|0,r=(r=r+Math.imul(A,W)|0)+Math.imul(T,V)|0,i=i+Math.imul(T,W)|0,o=o+Math.imul(S,Z)|0,r=(r=r+Math.imul(S,X)|0)+Math.imul(x,Z)|0,i=i+Math.imul(x,X)|0,o=o+Math.imul(E,Q)|0,r=(r=r+Math.imul(E,ee)|0)+Math.imul(k,Q)|0,i=i+Math.imul(k,ee)|0,o=o+Math.imul(b,ne)|0,r=(r=r+Math.imul(b,oe)|0)+Math.imul(v,ne)|0,i=i+Math.imul(v,oe)|0,o=o+Math.imul(_,ie)|0,r=(r=r+Math.imul(_,ae)|0)+Math.imul(F,ie)|0,i=i+Math.imul(F,ae)|0,o=o+Math.imul(f,ue)|0,r=(r=r+Math.imul(f,ce)|0)+Math.imul(g,ue)|0,i=i+Math.imul(g,ce)|0;var ke=(c+(o=o+Math.imul(d,de)|0)|0)+((8191&(r=(r=r+Math.imul(d,he)|0)+Math.imul(h,de)|0))<<13)|0;c=((i=i+Math.imul(h,he)|0)+(r>>>13)|0)+(ke>>>26)|0,ke&=67108863,o=Math.imul(P,q),r=(r=Math.imul(P,z))+Math.imul(U,q)|0,i=Math.imul(U,z),o=o+Math.imul(B,G)|0,r=(r=r+Math.imul(B,$)|0)+Math.imul(N,G)|0,i=i+Math.imul(N,$)|0,o=o+Math.imul(I,V)|0,r=(r=r+Math.imul(I,W)|0)+Math.imul(M,V)|0,i=i+Math.imul(M,W)|0,o=o+Math.imul(A,Z)|0,r=(r=r+Math.imul(A,X)|0)+Math.imul(T,Z)|0,i=i+Math.imul(T,X)|0,o=o+Math.imul(S,Q)|0,r=(r=r+Math.imul(S,ee)|0)+Math.imul(x,Q)|0,i=i+Math.imul(x,ee)|0,o=o+Math.imul(E,ne)|0,r=(r=r+Math.imul(E,oe)|0)+Math.imul(k,ne)|0,i=i+Math.imul(k,oe)|0,o=o+Math.imul(b,ie)|0,r=(r=r+Math.imul(b,ae)|0)+Math.imul(v,ie)|0,i=i+Math.imul(v,ae)|0,o=o+Math.imul(_,ue)|0,r=(r=r+Math.imul(_,ce)|0)+Math.imul(F,ue)|0,i=i+Math.imul(F,ce)|0,o=o+Math.imul(f,de)|0,r=(r=r+Math.imul(f,he)|0)+Math.imul(g,de)|0,i=i+Math.imul(g,he)|0;var De=(c+(o=o+Math.imul(d,fe)|0)|0)+((8191&(r=(r=r+Math.imul(d,ge)|0)+Math.imul(h,fe)|0))<<13)|0;c=((i=i+Math.imul(h,ge)|0)+(r>>>13)|0)+(De>>>26)|0,De&=67108863,o=Math.imul(P,G),r=(r=Math.imul(P,$))+Math.imul(U,G)|0,i=Math.imul(U,$),o=o+Math.imul(B,V)|0,r=(r=r+Math.imul(B,W)|0)+Math.imul(N,V)|0,i=i+Math.imul(N,W)|0,o=o+Math.imul(I,Z)|0,r=(r=r+Math.imul(I,X)|0)+Math.imul(M,Z)|0,i=i+Math.imul(M,X)|0,o=o+Math.imul(A,Q)|0,r=(r=r+Math.imul(A,ee)|0)+Math.imul(T,Q)|0,i=i+Math.imul(T,ee)|0,o=o+Math.imul(S,ne)|0,r=(r=r+Math.imul(S,oe)|0)+Math.imul(x,ne)|0,i=i+Math.imul(x,oe)|0,o=o+Math.imul(E,ie)|0,r=(r=r+Math.imul(E,ae)|0)+Math.imul(k,ie)|0,i=i+Math.imul(k,ae)|0,o=o+Math.imul(b,ue)|0,r=(r=r+Math.imul(b,ce)|0)+Math.imul(v,ue)|0,i=i+Math.imul(v,ce)|0,o=o+Math.imul(_,de)|0,r=(r=r+Math.imul(_,he)|0)+Math.imul(F,de)|0,i=i+Math.imul(F,he)|0;var Se=(c+(o=o+Math.imul(f,fe)|0)|0)+((8191&(r=(r=r+Math.imul(f,ge)|0)+Math.imul(g,fe)|0))<<13)|0;c=((i=i+Math.imul(g,ge)|0)+(r>>>13)|0)+(Se>>>26)|0,Se&=67108863,o=Math.imul(P,V),r=(r=Math.imul(P,W))+Math.imul(U,V)|0,i=Math.imul(U,W),o=o+Math.imul(B,Z)|0,r=(r=r+Math.imul(B,X)|0)+Math.imul(N,Z)|0,i=i+Math.imul(N,X)|0,o=o+Math.imul(I,Q)|0,r=(r=r+Math.imul(I,ee)|0)+Math.imul(M,Q)|0,i=i+Math.imul(M,ee)|0,o=o+Math.imul(A,ne)|0,r=(r=r+Math.imul(A,oe)|0)+Math.imul(T,ne)|0,i=i+Math.imul(T,oe)|0,o=o+Math.imul(S,ie)|0,r=(r=r+Math.imul(S,ae)|0)+Math.imul(x,ie)|0,i=i+Math.imul(x,ae)|0,o=o+Math.imul(E,ue)|0,r=(r=r+Math.imul(E,ce)|0)+Math.imul(k,ue)|0,i=i+Math.imul(k,ce)|0,o=o+Math.imul(b,de)|0,r=(r=r+Math.imul(b,he)|0)+Math.imul(v,de)|0,i=i+Math.imul(v,he)|0;var xe=(c+(o=o+Math.imul(_,fe)|0)|0)+((8191&(r=(r=r+Math.imul(_,ge)|0)+Math.imul(F,fe)|0))<<13)|0;c=((i=i+Math.imul(F,ge)|0)+(r>>>13)|0)+(xe>>>26)|0,xe&=67108863,o=Math.imul(P,Z),r=(r=Math.imul(P,X))+Math.imul(U,Z)|0,i=Math.imul(U,X),o=o+Math.imul(B,Q)|0,r=(r=r+Math.imul(B,ee)|0)+Math.imul(N,Q)|0,i=i+Math.imul(N,ee)|0,o=o+Math.imul(I,ne)|0,r=(r=r+Math.imul(I,oe)|0)+Math.imul(M,ne)|0,i=i+Math.imul(M,oe)|0,o=o+Math.imul(A,ie)|0,r=(r=r+Math.imul(A,ae)|0)+Math.imul(T,ie)|0,i=i+Math.imul(T,ae)|0,o=o+Math.imul(S,ue)|0,r=(r=r+Math.imul(S,ce)|0)+Math.imul(x,ue)|0,i=i+Math.imul(x,ce)|0,o=o+Math.imul(E,de)|0,r=(r=r+Math.imul(E,he)|0)+Math.imul(k,de)|0,i=i+Math.imul(k,he)|0;var Ce=(c+(o=o+Math.imul(b,fe)|0)|0)+((8191&(r=(r=r+Math.imul(b,ge)|0)+Math.imul(v,fe)|0))<<13)|0;c=((i=i+Math.imul(v,ge)|0)+(r>>>13)|0)+(Ce>>>26)|0,Ce&=67108863,o=Math.imul(P,Q),r=(r=Math.imul(P,ee))+Math.imul(U,Q)|0,i=Math.imul(U,ee),o=o+Math.imul(B,ne)|0,r=(r=r+Math.imul(B,oe)|0)+Math.imul(N,ne)|0,i=i+Math.imul(N,oe)|0,o=o+Math.imul(I,ie)|0,r=(r=r+Math.imul(I,ae)|0)+Math.imul(M,ie)|0,i=i+Math.imul(M,ae)|0,o=o+Math.imul(A,ue)|0,r=(r=r+Math.imul(A,ce)|0)+Math.imul(T,ue)|0,i=i+Math.imul(T,ce)|0,o=o+Math.imul(S,de)|0,r=(r=r+Math.imul(S,he)|0)+Math.imul(x,de)|0,i=i+Math.imul(x,he)|0;var Ae=(c+(o=o+Math.imul(E,fe)|0)|0)+((8191&(r=(r=r+Math.imul(E,ge)|0)+Math.imul(k,fe)|0))<<13)|0;c=((i=i+Math.imul(k,ge)|0)+(r>>>13)|0)+(Ae>>>26)|0,Ae&=67108863,o=Math.imul(P,ne),r=(r=Math.imul(P,oe))+Math.imul(U,ne)|0,i=Math.imul(U,oe),o=o+Math.imul(B,ie)|0,r=(r=r+Math.imul(B,ae)|0)+Math.imul(N,ie)|0,i=i+Math.imul(N,ae)|0,o=o+Math.imul(I,ue)|0,r=(r=r+Math.imul(I,ce)|0)+Math.imul(M,ue)|0,i=i+Math.imul(M,ce)|0,o=o+Math.imul(A,de)|0,r=(r=r+Math.imul(A,he)|0)+Math.imul(T,de)|0,i=i+Math.imul(T,he)|0;var Te=(c+(o=o+Math.imul(S,fe)|0)|0)+((8191&(r=(r=r+Math.imul(S,ge)|0)+Math.imul(x,fe)|0))<<13)|0;c=((i=i+Math.imul(x,ge)|0)+(r>>>13)|0)+(Te>>>26)|0,Te&=67108863,o=Math.imul(P,ie),r=(r=Math.imul(P,ae))+Math.imul(U,ie)|0,i=Math.imul(U,ae),o=o+Math.imul(B,ue)|0,r=(r=r+Math.imul(B,ce)|0)+Math.imul(N,ue)|0,i=i+Math.imul(N,ce)|0,o=o+Math.imul(I,de)|0,r=(r=r+Math.imul(I,he)|0)+Math.imul(M,de)|0,i=i+Math.imul(M,he)|0;var Re=(c+(o=o+Math.imul(A,fe)|0)|0)+((8191&(r=(r=r+Math.imul(A,ge)|0)+Math.imul(T,fe)|0))<<13)|0;c=((i=i+Math.imul(T,ge)|0)+(r>>>13)|0)+(Re>>>26)|0,Re&=67108863,o=Math.imul(P,ue),r=(r=Math.imul(P,ce))+Math.imul(U,ue)|0,i=Math.imul(U,ce),o=o+Math.imul(B,de)|0,r=(r=r+Math.imul(B,he)|0)+Math.imul(N,de)|0,i=i+Math.imul(N,he)|0;var Ie=(c+(o=o+Math.imul(I,fe)|0)|0)+((8191&(r=(r=r+Math.imul(I,ge)|0)+Math.imul(M,fe)|0))<<13)|0;c=((i=i+Math.imul(M,ge)|0)+(r>>>13)|0)+(Ie>>>26)|0,Ie&=67108863,o=Math.imul(P,de),r=(r=Math.imul(P,he))+Math.imul(U,de)|0,i=Math.imul(U,he);var Me=(c+(o=o+Math.imul(B,fe)|0)|0)+((8191&(r=(r=r+Math.imul(B,ge)|0)+Math.imul(N,fe)|0))<<13)|0;c=((i=i+Math.imul(N,ge)|0)+(r>>>13)|0)+(Me>>>26)|0,Me&=67108863;var Oe=(c+(o=Math.imul(P,fe))|0)+((8191&(r=(r=Math.imul(P,ge))+Math.imul(U,fe)|0))<<13)|0;return c=((i=Math.imul(U,ge))+(r>>>13)|0)+(Oe>>>26)|0,Oe&=67108863,u[0]=me,u[1]=_e,u[2]=Fe,u[3]=ye,u[4]=be,u[5]=ve,u[6]=we,u[7]=Ee,u[8]=ke,u[9]=De,u[10]=Se,u[11]=xe,u[12]=Ce,u[13]=Ae,u[14]=Te,u[15]=Re,u[16]=Ie,u[17]=Me,u[18]=Oe,0!==c&&(u[19]=c,n.length++),n};function g(e,t,n){return(new m).mulp(e,t,n)}function m(e,t){this.x=e,this.y=t}Math.imul||(f=p),i.prototype.mulTo=function(e,t){var n=this.length+e.length;return 10===this.length&&10===e.length?f(this,e,t):n<63?p(this,e,t):n<1024?function(e,t,n){n.negative=t.negative^e.negative,n.length=e.length+t.length;for(var o=0,r=0,i=0;i>>26)|0)>>>26,a&=67108863}n.words[i]=s,o=a,a=r}return 0!==o?n.words[i]=o:n.length--,n.strip()}(this,e,t):g(this,e,t)},m.prototype.makeRBT=function(e){for(var t=new Array(e),n=i.prototype._countBits(e)-1,o=0;o>=1;return o},m.prototype.permute=function(e,t,n,o,r,i){for(var a=0;a>>=1)r++;return 1<>>=13,n[2*a+1]=8191&i,i>>>=13;for(a=2*t;a>=26,t+=r/67108864|0,t+=i>>>26,this.words[n]=67108863&i}return 0!==t&&(this.words[n]=t,this.length++),this},i.prototype.muln=function(e){return this.clone().imuln(e)},i.prototype.sqr=function(){return this.mul(this)},i.prototype.isqr=function(){return this.imul(this.clone())},i.prototype.pow=function(e){var t=function(e){for(var t=new Array(e.bitLength()),n=0;n>>r}return t}(e);if(0===t.length)return new i(1);for(var n=this,o=0;o=0);var t,n=e%26,r=(e-n)/26,i=67108863>>>26-n<<26-n;if(0!==n){var a=0;for(t=0;t>>26-n}a&&(this.words[t]=a,this.length++)}if(0!==r){for(t=this.length-1;t>=0;t--)this.words[t+r]=this.words[t];for(t=0;t=0),r=t?(t-t%26)/26:0;var i=e%26,a=Math.min((e-i)/26,this.length),s=67108863^67108863>>>i<a)for(this.length-=a,c=0;c=0&&(0!==l||c>=r);c--){var d=0|this.words[c];this.words[c]=l<<26-i|d>>>i,l=d&s}return u&&0!==l&&(u.words[u.length++]=l),0===this.length&&(this.words[0]=0,this.length=1),this.strip()},i.prototype.ishrn=function(e,t,n){return o(0===this.negative),this.iushrn(e,t,n)},i.prototype.shln=function(e){return this.clone().ishln(e)},i.prototype.ushln=function(e){return this.clone().iushln(e)},i.prototype.shrn=function(e){return this.clone().ishrn(e)},i.prototype.ushrn=function(e){return this.clone().iushrn(e)},i.prototype.testn=function(e){o("number"==typeof e&&e>=0);var t=e%26,n=(e-t)/26,r=1<=0);var t=e%26,n=(e-t)/26;if(o(0===this.negative,"imaskn works only with positive numbers"),this.length<=n)return this;if(0!==t&&n++,this.length=Math.min(n,this.length),0!==t){var r=67108863^67108863>>>t<=67108864;t++)this.words[t]-=67108864,t===this.length-1?this.words[t+1]=1:this.words[t+1]++;return this.length=Math.max(this.length,t+1),this},i.prototype.isubn=function(e){if(o("number"==typeof e),o(e<67108864),e<0)return this.iaddn(-e);if(0!==this.negative)return this.negative=0,this.iaddn(e),this.negative=1,this;if(this.words[0]-=e,1===this.length&&this.words[0]<0)this.words[0]=-this.words[0],this.negative=1;else for(var t=0;t>26)-(u/67108864|0),this.words[r+n]=67108863&i}for(;r>26,this.words[r+n]=67108863&i;if(0===s)return this.strip();for(o(-1===s),s=0,r=0;r>26,this.words[r]=67108863&i;return this.negative=1,this.strip()},i.prototype._wordDiv=function(e,t){var n=(this.length,e.length),o=this.clone(),r=e,a=0|r.words[r.length-1];0!=(n=26-this._countBits(a))&&(r=r.ushln(n),o.iushln(n),a=0|r.words[r.length-1]);var s,u=o.length-r.length;if("mod"!==t){(s=new i(null)).length=u+1,s.words=new Array(s.length);for(var c=0;c=0;d--){var h=67108864*(0|o.words[r.length+d])+(0|o.words[r.length+d-1]);for(h=Math.min(h/a|0,67108863),o._ishlnsubmul(r,h,d);0!==o.negative;)h--,o.negative=0,o._ishlnsubmul(r,1,d),o.isZero()||(o.negative^=1);s&&(s.words[d]=h)}return s&&s.strip(),o.strip(),"div"!==t&&0!==n&&o.iushrn(n),{div:s||null,mod:o}},i.prototype.divmod=function(e,t,n){return o(!e.isZero()),this.isZero()?{div:new i(0),mod:new i(0)}:0!==this.negative&&0===e.negative?(s=this.neg().divmod(e,t),"mod"!==t&&(r=s.div.neg()),"div"!==t&&(a=s.mod.neg(),n&&0!==a.negative&&a.iadd(e)),{div:r,mod:a}):0===this.negative&&0!==e.negative?(s=this.divmod(e.neg(),t),"mod"!==t&&(r=s.div.neg()),{div:r,mod:s.mod}):0!=(this.negative&e.negative)?(s=this.neg().divmod(e.neg(),t),"div"!==t&&(a=s.mod.neg(),n&&0!==a.negative&&a.isub(e)),{div:s.div,mod:a}):e.length>this.length||this.cmp(e)<0?{div:new i(0),mod:this}:1===e.length?"div"===t?{div:this.divn(e.words[0]),mod:null}:"mod"===t?{div:null,mod:new i(this.modn(e.words[0]))}:{div:this.divn(e.words[0]),mod:new i(this.modn(e.words[0]))}:this._wordDiv(e,t);var r,a,s},i.prototype.div=function(e){return this.divmod(e,"div",!1).div},i.prototype.mod=function(e){return this.divmod(e,"mod",!1).mod},i.prototype.umod=function(e){return this.divmod(e,"mod",!0).mod},i.prototype.divRound=function(e){var t=this.divmod(e);if(t.mod.isZero())return t.div;var n=0!==t.div.negative?t.mod.isub(e):t.mod,o=e.ushrn(1),r=e.andln(1),i=n.cmp(o);return i<0||1===r&&0===i?t.div:0!==t.div.negative?t.div.isubn(1):t.div.iaddn(1)},i.prototype.modn=function(e){o(e<=67108863);for(var t=(1<<26)%e,n=0,r=this.length-1;r>=0;r--)n=(t*n+(0|this.words[r]))%e;return n},i.prototype.idivn=function(e){o(e<=67108863);for(var t=0,n=this.length-1;n>=0;n--){var r=(0|this.words[n])+67108864*t;this.words[n]=r/e|0,t=r%e}return this.strip()},i.prototype.divn=function(e){return this.clone().idivn(e)},i.prototype.egcd=function(e){o(0===e.negative),o(!e.isZero());var t=this,n=e.clone();t=0!==t.negative?t.umod(e):t.clone();for(var r=new i(1),a=new i(0),s=new i(0),u=new i(1),c=0;t.isEven()&&n.isEven();)t.iushrn(1),n.iushrn(1),++c;for(var l=n.clone(),d=t.clone();!t.isZero();){for(var h=0,p=1;0==(t.words[0]&p)&&h<26;++h,p<<=1);if(h>0)for(t.iushrn(h);h-- >0;)(r.isOdd()||a.isOdd())&&(r.iadd(l),a.isub(d)),r.iushrn(1),a.iushrn(1);for(var f=0,g=1;0==(n.words[0]&g)&&f<26;++f,g<<=1);if(f>0)for(n.iushrn(f);f-- >0;)(s.isOdd()||u.isOdd())&&(s.iadd(l),u.isub(d)),s.iushrn(1),u.iushrn(1);t.cmp(n)>=0?(t.isub(n),r.isub(s),a.isub(u)):(n.isub(t),s.isub(r),u.isub(a))}return{a:s,b:u,gcd:n.iushln(c)}},i.prototype._invmp=function(e){o(0===e.negative),o(!e.isZero());var t=this,n=e.clone();t=0!==t.negative?t.umod(e):t.clone();for(var r,a=new i(1),s=new i(0),u=n.clone();t.cmpn(1)>0&&n.cmpn(1)>0;){for(var c=0,l=1;0==(t.words[0]&l)&&c<26;++c,l<<=1);if(c>0)for(t.iushrn(c);c-- >0;)a.isOdd()&&a.iadd(u),a.iushrn(1);for(var d=0,h=1;0==(n.words[0]&h)&&d<26;++d,h<<=1);if(d>0)for(n.iushrn(d);d-- >0;)s.isOdd()&&s.iadd(u),s.iushrn(1);t.cmp(n)>=0?(t.isub(n),a.isub(s)):(n.isub(t),s.isub(a))}return(r=0===t.cmpn(1)?a:s).cmpn(0)<0&&r.iadd(e),r},i.prototype.gcd=function(e){if(this.isZero())return e.abs();if(e.isZero())return this.abs();var t=this.clone(),n=e.clone();t.negative=0,n.negative=0;for(var o=0;t.isEven()&&n.isEven();o++)t.iushrn(1),n.iushrn(1);for(;;){for(;t.isEven();)t.iushrn(1);for(;n.isEven();)n.iushrn(1);var r=t.cmp(n);if(r<0){var i=t;t=n,n=i}else if(0===r||0===n.cmpn(1))break;t.isub(n)}return n.iushln(o)},i.prototype.invm=function(e){return this.egcd(e).a.umod(e)},i.prototype.isEven=function(){return 0==(1&this.words[0])},i.prototype.isOdd=function(){return 1==(1&this.words[0])},i.prototype.andln=function(e){return this.words[0]&e},i.prototype.bincn=function(e){o("number"==typeof e);var t=e%26,n=(e-t)/26,r=1<>>26,s&=67108863,this.words[a]=s}return 0!==i&&(this.words[a]=i,this.length++),this},i.prototype.isZero=function(){return 1===this.length&&0===this.words[0]},i.prototype.cmpn=function(e){var t,n=e<0;if(0!==this.negative&&!n)return-1;if(0===this.negative&&n)return 1;if(this.strip(),this.length>1)t=1;else{n&&(e=-e),o(e<=67108863,"Number is too big");var r=0|this.words[0];t=r===e?0:re.length)return 1;if(this.length=0;n--){var o=0|this.words[n],r=0|e.words[n];if(o!==r){or&&(t=1);break}}return t},i.prototype.gtn=function(e){return 1===this.cmpn(e)},i.prototype.gt=function(e){return 1===this.cmp(e)},i.prototype.gten=function(e){return this.cmpn(e)>=0},i.prototype.gte=function(e){return this.cmp(e)>=0},i.prototype.ltn=function(e){return-1===this.cmpn(e)},i.prototype.lt=function(e){return-1===this.cmp(e)},i.prototype.lten=function(e){return this.cmpn(e)<=0},i.prototype.lte=function(e){return this.cmp(e)<=0},i.prototype.eqn=function(e){return 0===this.cmpn(e)},i.prototype.eq=function(e){return 0===this.cmp(e)},i.red=function(e){return new E(e)},i.prototype.toRed=function(e){return o(!this.red,"Already a number in reduction context"),o(0===this.negative,"red works only with positives"),e.convertTo(this)._forceRed(e)},i.prototype.fromRed=function(){return o(this.red,"fromRed works only with numbers in reduction context"),this.red.convertFrom(this)},i.prototype._forceRed=function(e){return this.red=e,this},i.prototype.forceRed=function(e){return o(!this.red,"Already a number in reduction context"),this._forceRed(e)},i.prototype.redAdd=function(e){return o(this.red,"redAdd works only with red numbers"),this.red.add(this,e)},i.prototype.redIAdd=function(e){return o(this.red,"redIAdd works only with red numbers"),this.red.iadd(this,e)},i.prototype.redSub=function(e){return o(this.red,"redSub works only with red numbers"),this.red.sub(this,e)},i.prototype.redISub=function(e){return o(this.red,"redISub works only with red numbers"),this.red.isub(this,e)},i.prototype.redShl=function(e){return o(this.red,"redShl works only with red numbers"),this.red.shl(this,e)},i.prototype.redMul=function(e){return o(this.red,"redMul works only with red numbers"),this.red._verify2(this,e),this.red.mul(this,e)},i.prototype.redIMul=function(e){return o(this.red,"redMul works only with red numbers"),this.red._verify2(this,e),this.red.imul(this,e)},i.prototype.redSqr=function(){return o(this.red,"redSqr works only with red numbers"),this.red._verify1(this),this.red.sqr(this)},i.prototype.redISqr=function(){return o(this.red,"redISqr works only with red numbers"),this.red._verify1(this),this.red.isqr(this)},i.prototype.redSqrt=function(){return o(this.red,"redSqrt works only with red numbers"),this.red._verify1(this),this.red.sqrt(this)},i.prototype.redInvm=function(){return o(this.red,"redInvm works only with red numbers"),this.red._verify1(this),this.red.invm(this)},i.prototype.redNeg=function(){return o(this.red,"redNeg works only with red numbers"),this.red._verify1(this),this.red.neg(this)},i.prototype.redPow=function(e){return o(this.red&&!e.red,"redPow(normalNum)"),this.red._verify1(this),this.red.pow(this,e)};var _={k256:null,p224:null,p192:null,p25519:null};function F(e,t){this.name=e,this.p=new i(t,16),this.n=this.p.bitLength(),this.k=new i(1).iushln(this.n).isub(this.p),this.tmp=this._tmp()}function y(){F.call(this,"k256","ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f")}function b(){F.call(this,"p224","ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001")}function v(){F.call(this,"p192","ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff")}function w(){F.call(this,"25519","7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed")}function E(e){if("string"==typeof e){var t=i._prime(e);this.m=t.p,this.prime=t}else o(e.gtn(1),"modulus must be greater than 1"),this.m=e,this.prime=null}function k(e){E.call(this,e),this.shift=this.m.bitLength(),this.shift%26!=0&&(this.shift+=26-this.shift%26),this.r=new i(1).iushln(this.shift),this.r2=this.imod(this.r.sqr()),this.rinv=this.r._invmp(this.m),this.minv=this.rinv.mul(this.r).isubn(1).div(this.m),this.minv=this.minv.umod(this.r),this.minv=this.r.sub(this.minv)}F.prototype._tmp=function(){var e=new i(null);return e.words=new Array(Math.ceil(this.n/13)),e},F.prototype.ireduce=function(e){var t,n=e;do{this.split(n,this.tmp),t=(n=(n=this.imulK(n)).iadd(this.tmp)).bitLength()}while(t>this.n);var o=t0?n.isub(this.p):void 0!==n.strip?n.strip():n._strip(),n},F.prototype.split=function(e,t){e.iushrn(this.n,0,t)},F.prototype.imulK=function(e){return e.imul(this.k)},r(y,F),y.prototype.split=function(e,t){for(var n=4194303,o=Math.min(e.length,9),r=0;r>>22,i=a}i>>>=22,e.words[r-10]=i,0===i&&e.length>10?e.length-=10:e.length-=9},y.prototype.imulK=function(e){e.words[e.length]=0,e.words[e.length+1]=0,e.length+=2;for(var t=0,n=0;n>>=26,e.words[n]=r,t=o}return 0!==t&&(e.words[e.length++]=t),e},i._prime=function(e){if(_[e])return _[e];var t;if("k256"===e)t=new y;else if("p224"===e)t=new b;else if("p192"===e)t=new v;else{if("p25519"!==e)throw new Error("Unknown prime "+e);t=new w}return _[e]=t,t},E.prototype._verify1=function(e){o(0===e.negative,"red works only with positives"),o(e.red,"red works only with red numbers")},E.prototype._verify2=function(e,t){o(0==(e.negative|t.negative),"red works only with positives"),o(e.red&&e.red===t.red,"red works only with red numbers")},E.prototype.imod=function(e){return this.prime?this.prime.ireduce(e)._forceRed(this):e.umod(this.m)._forceRed(this)},E.prototype.neg=function(e){return e.isZero()?e.clone():this.m.sub(e)._forceRed(this)},E.prototype.add=function(e,t){this._verify2(e,t);var n=e.add(t);return n.cmp(this.m)>=0&&n.isub(this.m),n._forceRed(this)},E.prototype.iadd=function(e,t){this._verify2(e,t);var n=e.iadd(t);return n.cmp(this.m)>=0&&n.isub(this.m),n},E.prototype.sub=function(e,t){this._verify2(e,t);var n=e.sub(t);return n.cmpn(0)<0&&n.iadd(this.m),n._forceRed(this)},E.prototype.isub=function(e,t){this._verify2(e,t);var n=e.isub(t);return n.cmpn(0)<0&&n.iadd(this.m),n},E.prototype.shl=function(e,t){return this._verify1(e),this.imod(e.ushln(t))},E.prototype.imul=function(e,t){return this._verify2(e,t),this.imod(e.imul(t))},E.prototype.mul=function(e,t){return this._verify2(e,t),this.imod(e.mul(t))},E.prototype.isqr=function(e){return this.imul(e,e.clone())},E.prototype.sqr=function(e){return this.mul(e,e)},E.prototype.sqrt=function(e){if(e.isZero())return e.clone();var t=this.m.andln(3);if(o(t%2==1),3===t){var n=this.m.add(new i(1)).iushrn(2);return this.pow(e,n)}for(var r=this.m.subn(1),a=0;!r.isZero()&&0===r.andln(1);)a++,r.iushrn(1);o(!r.isZero());var s=new i(1).toRed(this),u=s.redNeg(),c=this.m.subn(1).iushrn(1),l=this.m.bitLength();for(l=new i(2*l*l).toRed(this);0!==this.pow(l,c).cmp(u);)l.redIAdd(u);for(var d=this.pow(l,r),h=this.pow(e,r.addn(1).iushrn(1)),p=this.pow(e,r),f=a;0!==p.cmp(s);){for(var g=p,m=0;0!==g.cmp(s);m++)g=g.redSqr();o(m=0;o--){for(var c=t.words[o],l=u-1;l>=0;l--){var d=c>>l&1;r!==n[0]&&(r=this.sqr(r)),0!==d||0!==a?(a<<=1,a|=d,(4==++s||0===o&&0===l)&&(r=this.mul(r,n[a]),s=0,a=0)):s=0}u=26}return r},E.prototype.convertTo=function(e){var t=e.umod(this.m);return t===e?t.clone():t},E.prototype.convertFrom=function(e){var t=e.clone();return t.red=null,t},i.mont=function(e){return new k(e)},r(k,E),k.prototype.convertTo=function(e){return this.imod(e.ushln(this.shift))},k.prototype.convertFrom=function(e){var t=this.imod(e.mul(this.rinv));return t.red=null,t},k.prototype.imul=function(e,t){if(e.isZero()||t.isZero())return e.words[0]=0,e.length=1,e;var n=e.imul(t),o=n.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m),r=n.isub(o).iushrn(this.shift),i=r;return r.cmp(this.m)>=0?i=r.isub(this.m):r.cmpn(0)<0&&(i=r.iadd(this.m)),i._forceRed(this)},k.prototype.mul=function(e,t){if(e.isZero()||t.isZero())return new i(0)._forceRed(this);var n=e.mul(t),o=n.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m),r=n.isub(o).iushrn(this.shift),a=r;return r.cmp(this.m)>=0?a=r.isub(this.m):r.cmpn(0)<0&&(a=r.iadd(this.m)),a._forceRed(this)},k.prototype.invm=function(e){return this.imod(e._invmp(this.m).mul(this.r2))._forceRed(this)}}(e=n.nmd(e),this)},86266:(e,t,n)=>{"use strict";var o=t;o.version=n(17519).i8,o.utils=n(80953),o.rand=n(29931),o.curve=n(88254),o.curves=n(45427),o.ec=n(57954),o.eddsa=n(65980)},4918:(e,t,n)=>{"use strict";var o=n(73785),r=n(80953),i=r.getNAF,a=r.getJSF,s=r.assert;function u(e,t){this.type=e,this.p=new o(t.p,16),this.red=t.prime?o.red(t.prime):o.mont(this.p),this.zero=new o(0).toRed(this.red),this.one=new o(1).toRed(this.red),this.two=new o(2).toRed(this.red),this.n=t.n&&new o(t.n,16),this.g=t.g&&this.pointFromJSON(t.g,t.gRed),this._wnafT1=new Array(4),this._wnafT2=new Array(4),this._wnafT3=new Array(4),this._wnafT4=new Array(4),this._bitLength=this.n?this.n.bitLength():0;var n=this.n&&this.p.div(this.n);!n||n.cmpn(100)>0?this.redN=null:(this._maxwellTrick=!0,this.redN=this.n.toRed(this.red))}function c(e,t){this.curve=e,this.type=t,this.precomputed=null}e.exports=u,u.prototype.point=function(){throw new Error("Not implemented")},u.prototype.validate=function(){throw new Error("Not implemented")},u.prototype._fixedNafMul=function(e,t){s(e.precomputed);var n=e._getDoubles(),o=i(t,1,this._bitLength),r=(1<=a;l--)u=(u<<1)+o[l];c.push(u)}for(var d=this.jpoint(null,null,null),h=this.jpoint(null,null,null),p=r;p>0;p--){for(a=0;a=0;c--){for(var l=0;c>=0&&0===a[c];c--)l++;if(c>=0&&l++,u=u.dblp(l),c<0)break;var d=a[c];s(0!==d),u="affine"===e.type?d>0?u.mixedAdd(r[d-1>>1]):u.mixedAdd(r[-d-1>>1].neg()):d>0?u.add(r[d-1>>1]):u.add(r[-d-1>>1].neg())}return"affine"===e.type?u.toP():u},u.prototype._wnafMulAdd=function(e,t,n,o,r){var s,u,c,l=this._wnafT1,d=this._wnafT2,h=this._wnafT3,p=0;for(s=0;s=1;s-=2){var g=s-1,m=s;if(1===l[g]&&1===l[m]){var _=[t[g],null,null,t[m]];0===t[g].y.cmp(t[m].y)?(_[1]=t[g].add(t[m]),_[2]=t[g].toJ().mixedAdd(t[m].neg())):0===t[g].y.cmp(t[m].y.redNeg())?(_[1]=t[g].toJ().mixedAdd(t[m]),_[2]=t[g].add(t[m].neg())):(_[1]=t[g].toJ().mixedAdd(t[m]),_[2]=t[g].toJ().mixedAdd(t[m].neg()));var F=[-3,-1,-5,-7,0,7,5,1,3],y=a(n[g],n[m]);for(p=Math.max(y[0].length,p),h[g]=new Array(p),h[m]=new Array(p),u=0;u=0;s--){for(var k=0;s>=0;){var D=!0;for(u=0;u=0&&k++,w=w.dblp(k),s<0)break;for(u=0;u0?c=d[u][S-1>>1]:S<0&&(c=d[u][-S-1>>1].neg()),w="affine"===c.type?w.mixedAdd(c):w.add(c))}}for(s=0;s=Math.ceil((e.bitLength()+1)/t.step)},c.prototype._getDoubles=function(e,t){if(this.precomputed&&this.precomputed.doubles)return this.precomputed.doubles;for(var n=[this],o=this,r=0;r{"use strict";var o=n(80953),r=n(73785),i=n(35717),a=n(4918),s=o.assert;function u(e){this.twisted=1!=(0|e.a),this.mOneA=this.twisted&&-1==(0|e.a),this.extended=this.mOneA,a.call(this,"edwards",e),this.a=new r(e.a,16).umod(this.red.m),this.a=this.a.toRed(this.red),this.c=new r(e.c,16).toRed(this.red),this.c2=this.c.redSqr(),this.d=new r(e.d,16).toRed(this.red),this.dd=this.d.redAdd(this.d),s(!this.twisted||0===this.c.fromRed().cmpn(1)),this.oneC=1==(0|e.c)}function c(e,t,n,o,i){a.BasePoint.call(this,e,"projective"),null===t&&null===n&&null===o?(this.x=this.curve.zero,this.y=this.curve.one,this.z=this.curve.one,this.t=this.curve.zero,this.zOne=!0):(this.x=new r(t,16),this.y=new r(n,16),this.z=o?new r(o,16):this.curve.one,this.t=i&&new r(i,16),this.x.red||(this.x=this.x.toRed(this.curve.red)),this.y.red||(this.y=this.y.toRed(this.curve.red)),this.z.red||(this.z=this.z.toRed(this.curve.red)),this.t&&!this.t.red&&(this.t=this.t.toRed(this.curve.red)),this.zOne=this.z===this.curve.one,this.curve.extended&&!this.t&&(this.t=this.x.redMul(this.y),this.zOne||(this.t=this.t.redMul(this.z.redInvm()))))}i(u,a),e.exports=u,u.prototype._mulA=function(e){return this.mOneA?e.redNeg():this.a.redMul(e)},u.prototype._mulC=function(e){return this.oneC?e:this.c.redMul(e)},u.prototype.jpoint=function(e,t,n,o){return this.point(e,t,n,o)},u.prototype.pointFromX=function(e,t){(e=new r(e,16)).red||(e=e.toRed(this.red));var n=e.redSqr(),o=this.c2.redSub(this.a.redMul(n)),i=this.one.redSub(this.c2.redMul(this.d).redMul(n)),a=o.redMul(i.redInvm()),s=a.redSqrt();if(0!==s.redSqr().redSub(a).cmp(this.zero))throw new Error("invalid point");var u=s.fromRed().isOdd();return(t&&!u||!t&&u)&&(s=s.redNeg()),this.point(e,s)},u.prototype.pointFromY=function(e,t){(e=new r(e,16)).red||(e=e.toRed(this.red));var n=e.redSqr(),o=n.redSub(this.c2),i=n.redMul(this.d).redMul(this.c2).redSub(this.a),a=o.redMul(i.redInvm());if(0===a.cmp(this.zero)){if(t)throw new Error("invalid point");return this.point(this.zero,e)}var s=a.redSqrt();if(0!==s.redSqr().redSub(a).cmp(this.zero))throw new Error("invalid point");return s.fromRed().isOdd()!==t&&(s=s.redNeg()),this.point(s,e)},u.prototype.validate=function(e){if(e.isInfinity())return!0;e.normalize();var t=e.x.redSqr(),n=e.y.redSqr(),o=t.redMul(this.a).redAdd(n),r=this.c2.redMul(this.one.redAdd(this.d.redMul(t).redMul(n)));return 0===o.cmp(r)},i(c,a.BasePoint),u.prototype.pointFromJSON=function(e){return c.fromJSON(this,e)},u.prototype.point=function(e,t,n,o){return new c(this,e,t,n,o)},c.fromJSON=function(e,t){return new c(e,t[0],t[1],t[2])},c.prototype.inspect=function(){return this.isInfinity()?"":""},c.prototype.isInfinity=function(){return 0===this.x.cmpn(0)&&(0===this.y.cmp(this.z)||this.zOne&&0===this.y.cmp(this.curve.c))},c.prototype._extDbl=function(){var e=this.x.redSqr(),t=this.y.redSqr(),n=this.z.redSqr();n=n.redIAdd(n);var o=this.curve._mulA(e),r=this.x.redAdd(this.y).redSqr().redISub(e).redISub(t),i=o.redAdd(t),a=i.redSub(n),s=o.redSub(t),u=r.redMul(a),c=i.redMul(s),l=r.redMul(s),d=a.redMul(i);return this.curve.point(u,c,d,l)},c.prototype._projDbl=function(){var e,t,n,o,r,i,a=this.x.redAdd(this.y).redSqr(),s=this.x.redSqr(),u=this.y.redSqr();if(this.curve.twisted){var c=(o=this.curve._mulA(s)).redAdd(u);this.zOne?(e=a.redSub(s).redSub(u).redMul(c.redSub(this.curve.two)),t=c.redMul(o.redSub(u)),n=c.redSqr().redSub(c).redSub(c)):(r=this.z.redSqr(),i=c.redSub(r).redISub(r),e=a.redSub(s).redISub(u).redMul(i),t=c.redMul(o.redSub(u)),n=c.redMul(i))}else o=s.redAdd(u),r=this.curve._mulC(this.z).redSqr(),i=o.redSub(r).redSub(r),e=this.curve._mulC(a.redISub(o)).redMul(i),t=this.curve._mulC(o).redMul(s.redISub(u)),n=o.redMul(i);return this.curve.point(e,t,n)},c.prototype.dbl=function(){return this.isInfinity()?this:this.curve.extended?this._extDbl():this._projDbl()},c.prototype._extAdd=function(e){var t=this.y.redSub(this.x).redMul(e.y.redSub(e.x)),n=this.y.redAdd(this.x).redMul(e.y.redAdd(e.x)),o=this.t.redMul(this.curve.dd).redMul(e.t),r=this.z.redMul(e.z.redAdd(e.z)),i=n.redSub(t),a=r.redSub(o),s=r.redAdd(o),u=n.redAdd(t),c=i.redMul(a),l=s.redMul(u),d=i.redMul(u),h=a.redMul(s);return this.curve.point(c,l,h,d)},c.prototype._projAdd=function(e){var t,n,o=this.z.redMul(e.z),r=o.redSqr(),i=this.x.redMul(e.x),a=this.y.redMul(e.y),s=this.curve.d.redMul(i).redMul(a),u=r.redSub(s),c=r.redAdd(s),l=this.x.redAdd(this.y).redMul(e.x.redAdd(e.y)).redISub(i).redISub(a),d=o.redMul(u).redMul(l);return this.curve.twisted?(t=o.redMul(c).redMul(a.redSub(this.curve._mulA(i))),n=u.redMul(c)):(t=o.redMul(c).redMul(a.redSub(i)),n=this.curve._mulC(u).redMul(c)),this.curve.point(d,t,n)},c.prototype.add=function(e){return this.isInfinity()?e:e.isInfinity()?this:this.curve.extended?this._extAdd(e):this._projAdd(e)},c.prototype.mul=function(e){return this._hasDoubles(e)?this.curve._fixedNafMul(this,e):this.curve._wnafMul(this,e)},c.prototype.mulAdd=function(e,t,n){return this.curve._wnafMulAdd(1,[this,t],[e,n],2,!1)},c.prototype.jmulAdd=function(e,t,n){return this.curve._wnafMulAdd(1,[this,t],[e,n],2,!0)},c.prototype.normalize=function(){if(this.zOne)return this;var e=this.z.redInvm();return this.x=this.x.redMul(e),this.y=this.y.redMul(e),this.t&&(this.t=this.t.redMul(e)),this.z=this.curve.one,this.zOne=!0,this},c.prototype.neg=function(){return this.curve.point(this.x.redNeg(),this.y,this.z,this.t&&this.t.redNeg())},c.prototype.getX=function(){return this.normalize(),this.x.fromRed()},c.prototype.getY=function(){return this.normalize(),this.y.fromRed()},c.prototype.eq=function(e){return this===e||0===this.getX().cmp(e.getX())&&0===this.getY().cmp(e.getY())},c.prototype.eqXToP=function(e){var t=e.toRed(this.curve.red).redMul(this.z);if(0===this.x.cmp(t))return!0;for(var n=e.clone(),o=this.curve.redN.redMul(this.z);;){if(n.iadd(this.curve.n),n.cmp(this.curve.p)>=0)return!1;if(t.redIAdd(o),0===this.x.cmp(t))return!0}},c.prototype.toP=c.prototype.normalize,c.prototype.mixedAdd=c.prototype.add},88254:(e,t,n)=>{"use strict";var o=t;o.base=n(4918),o.short=n(6673),o.mont=n(22881),o.edwards=n(31138)},22881:(e,t,n)=>{"use strict";var o=n(73785),r=n(35717),i=n(4918),a=n(80953);function s(e){i.call(this,"mont",e),this.a=new o(e.a,16).toRed(this.red),this.b=new o(e.b,16).toRed(this.red),this.i4=new o(4).toRed(this.red).redInvm(),this.two=new o(2).toRed(this.red),this.a24=this.i4.redMul(this.a.redAdd(this.two))}function u(e,t,n){i.BasePoint.call(this,e,"projective"),null===t&&null===n?(this.x=this.curve.one,this.z=this.curve.zero):(this.x=new o(t,16),this.z=new o(n,16),this.x.red||(this.x=this.x.toRed(this.curve.red)),this.z.red||(this.z=this.z.toRed(this.curve.red)))}r(s,i),e.exports=s,s.prototype.validate=function(e){var t=e.normalize().x,n=t.redSqr(),o=n.redMul(t).redAdd(n.redMul(this.a)).redAdd(t);return 0===o.redSqrt().redSqr().cmp(o)},r(u,i.BasePoint),s.prototype.decodePoint=function(e,t){return this.point(a.toArray(e,t),1)},s.prototype.point=function(e,t){return new u(this,e,t)},s.prototype.pointFromJSON=function(e){return u.fromJSON(this,e)},u.prototype.precompute=function(){},u.prototype._encode=function(){return this.getX().toArray("be",this.curve.p.byteLength())},u.fromJSON=function(e,t){return new u(e,t[0],t[1]||e.one)},u.prototype.inspect=function(){return this.isInfinity()?"":""},u.prototype.isInfinity=function(){return 0===this.z.cmpn(0)},u.prototype.dbl=function(){var e=this.x.redAdd(this.z).redSqr(),t=this.x.redSub(this.z).redSqr(),n=e.redSub(t),o=e.redMul(t),r=n.redMul(t.redAdd(this.curve.a24.redMul(n)));return this.curve.point(o,r)},u.prototype.add=function(){throw new Error("Not supported on Montgomery curve")},u.prototype.diffAdd=function(e,t){var n=this.x.redAdd(this.z),o=this.x.redSub(this.z),r=e.x.redAdd(e.z),i=e.x.redSub(e.z).redMul(n),a=r.redMul(o),s=t.z.redMul(i.redAdd(a).redSqr()),u=t.x.redMul(i.redISub(a).redSqr());return this.curve.point(s,u)},u.prototype.mul=function(e){for(var t=e.clone(),n=this,o=this.curve.point(null,null),r=[];0!==t.cmpn(0);t.iushrn(1))r.push(t.andln(1));for(var i=r.length-1;i>=0;i--)0===r[i]?(n=n.diffAdd(o,this),o=o.dbl()):(o=n.diffAdd(o,this),n=n.dbl());return o},u.prototype.mulAdd=function(){throw new Error("Not supported on Montgomery curve")},u.prototype.jumlAdd=function(){throw new Error("Not supported on Montgomery curve")},u.prototype.eq=function(e){return 0===this.getX().cmp(e.getX())},u.prototype.normalize=function(){return this.x=this.x.redMul(this.z.redInvm()),this.z=this.curve.one,this},u.prototype.getX=function(){return this.normalize(),this.x.fromRed()}},6673:(e,t,n)=>{"use strict";var o=n(80953),r=n(73785),i=n(35717),a=n(4918),s=o.assert;function u(e){a.call(this,"short",e),this.a=new r(e.a,16).toRed(this.red),this.b=new r(e.b,16).toRed(this.red),this.tinv=this.two.redInvm(),this.zeroA=0===this.a.fromRed().cmpn(0),this.threeA=0===this.a.fromRed().sub(this.p).cmpn(-3),this.endo=this._getEndomorphism(e),this._endoWnafT1=new Array(4),this._endoWnafT2=new Array(4)}function c(e,t,n,o){a.BasePoint.call(this,e,"affine"),null===t&&null===n?(this.x=null,this.y=null,this.inf=!0):(this.x=new r(t,16),this.y=new r(n,16),o&&(this.x.forceRed(this.curve.red),this.y.forceRed(this.curve.red)),this.x.red||(this.x=this.x.toRed(this.curve.red)),this.y.red||(this.y=this.y.toRed(this.curve.red)),this.inf=!1)}function l(e,t,n,o){a.BasePoint.call(this,e,"jacobian"),null===t&&null===n&&null===o?(this.x=this.curve.one,this.y=this.curve.one,this.z=new r(0)):(this.x=new r(t,16),this.y=new r(n,16),this.z=new r(o,16)),this.x.red||(this.x=this.x.toRed(this.curve.red)),this.y.red||(this.y=this.y.toRed(this.curve.red)),this.z.red||(this.z=this.z.toRed(this.curve.red)),this.zOne=this.z===this.curve.one}i(u,a),e.exports=u,u.prototype._getEndomorphism=function(e){if(this.zeroA&&this.g&&this.n&&1===this.p.modn(3)){var t,n;if(e.beta)t=new r(e.beta,16).toRed(this.red);else{var o=this._getEndoRoots(this.p);t=(t=o[0].cmp(o[1])<0?o[0]:o[1]).toRed(this.red)}if(e.lambda)n=new r(e.lambda,16);else{var i=this._getEndoRoots(this.n);0===this.g.mul(i[0]).x.cmp(this.g.x.redMul(t))?n=i[0]:(n=i[1],s(0===this.g.mul(n).x.cmp(this.g.x.redMul(t))))}return{beta:t,lambda:n,basis:e.basis?e.basis.map((function(e){return{a:new r(e.a,16),b:new r(e.b,16)}})):this._getEndoBasis(n)}}},u.prototype._getEndoRoots=function(e){var t=e===this.p?this.red:r.mont(e),n=new r(2).toRed(t).redInvm(),o=n.redNeg(),i=new r(3).toRed(t).redNeg().redSqrt().redMul(n);return[o.redAdd(i).fromRed(),o.redSub(i).fromRed()]},u.prototype._getEndoBasis=function(e){for(var t,n,o,i,a,s,u,c,l,d=this.n.ushrn(Math.floor(this.n.bitLength()/2)),h=e,p=this.n.clone(),f=new r(1),g=new r(0),m=new r(0),_=new r(1),F=0;0!==h.cmpn(0);){var y=p.div(h);c=p.sub(y.mul(h)),l=m.sub(y.mul(f));var b=_.sub(y.mul(g));if(!o&&c.cmp(d)<0)t=u.neg(),n=f,o=c.neg(),i=l;else if(o&&2==++F)break;u=c,p=h,h=c,m=f,f=l,_=g,g=b}a=c.neg(),s=l;var v=o.sqr().add(i.sqr());return a.sqr().add(s.sqr()).cmp(v)>=0&&(a=t,s=n),o.negative&&(o=o.neg(),i=i.neg()),a.negative&&(a=a.neg(),s=s.neg()),[{a:o,b:i},{a,b:s}]},u.prototype._endoSplit=function(e){var t=this.endo.basis,n=t[0],o=t[1],r=o.b.mul(e).divRound(this.n),i=n.b.neg().mul(e).divRound(this.n),a=r.mul(n.a),s=i.mul(o.a),u=r.mul(n.b),c=i.mul(o.b);return{k1:e.sub(a).sub(s),k2:u.add(c).neg()}},u.prototype.pointFromX=function(e,t){(e=new r(e,16)).red||(e=e.toRed(this.red));var n=e.redSqr().redMul(e).redIAdd(e.redMul(this.a)).redIAdd(this.b),o=n.redSqrt();if(0!==o.redSqr().redSub(n).cmp(this.zero))throw new Error("invalid point");var i=o.fromRed().isOdd();return(t&&!i||!t&&i)&&(o=o.redNeg()),this.point(e,o)},u.prototype.validate=function(e){if(e.inf)return!0;var t=e.x,n=e.y,o=this.a.redMul(t),r=t.redSqr().redMul(t).redIAdd(o).redIAdd(this.b);return 0===n.redSqr().redISub(r).cmpn(0)},u.prototype._endoWnafMulAdd=function(e,t,n){for(var o=this._endoWnafT1,r=this._endoWnafT2,i=0;i":""},c.prototype.isInfinity=function(){return this.inf},c.prototype.add=function(e){if(this.inf)return e;if(e.inf)return this;if(this.eq(e))return this.dbl();if(this.neg().eq(e))return this.curve.point(null,null);if(0===this.x.cmp(e.x))return this.curve.point(null,null);var t=this.y.redSub(e.y);0!==t.cmpn(0)&&(t=t.redMul(this.x.redSub(e.x).redInvm()));var n=t.redSqr().redISub(this.x).redISub(e.x),o=t.redMul(this.x.redSub(n)).redISub(this.y);return this.curve.point(n,o)},c.prototype.dbl=function(){if(this.inf)return this;var e=this.y.redAdd(this.y);if(0===e.cmpn(0))return this.curve.point(null,null);var t=this.curve.a,n=this.x.redSqr(),o=e.redInvm(),r=n.redAdd(n).redIAdd(n).redIAdd(t).redMul(o),i=r.redSqr().redISub(this.x.redAdd(this.x)),a=r.redMul(this.x.redSub(i)).redISub(this.y);return this.curve.point(i,a)},c.prototype.getX=function(){return this.x.fromRed()},c.prototype.getY=function(){return this.y.fromRed()},c.prototype.mul=function(e){return e=new r(e,16),this.isInfinity()?this:this._hasDoubles(e)?this.curve._fixedNafMul(this,e):this.curve.endo?this.curve._endoWnafMulAdd([this],[e]):this.curve._wnafMul(this,e)},c.prototype.mulAdd=function(e,t,n){var o=[this,t],r=[e,n];return this.curve.endo?this.curve._endoWnafMulAdd(o,r):this.curve._wnafMulAdd(1,o,r,2)},c.prototype.jmulAdd=function(e,t,n){var o=[this,t],r=[e,n];return this.curve.endo?this.curve._endoWnafMulAdd(o,r,!0):this.curve._wnafMulAdd(1,o,r,2,!0)},c.prototype.eq=function(e){return this===e||this.inf===e.inf&&(this.inf||0===this.x.cmp(e.x)&&0===this.y.cmp(e.y))},c.prototype.neg=function(e){if(this.inf)return this;var t=this.curve.point(this.x,this.y.redNeg());if(e&&this.precomputed){var n=this.precomputed,o=function(e){return e.neg()};t.precomputed={naf:n.naf&&{wnd:n.naf.wnd,points:n.naf.points.map(o)},doubles:n.doubles&&{step:n.doubles.step,points:n.doubles.points.map(o)}}}return t},c.prototype.toJ=function(){return this.inf?this.curve.jpoint(null,null,null):this.curve.jpoint(this.x,this.y,this.curve.one)},i(l,a.BasePoint),u.prototype.jpoint=function(e,t,n){return new l(this,e,t,n)},l.prototype.toP=function(){if(this.isInfinity())return this.curve.point(null,null);var e=this.z.redInvm(),t=e.redSqr(),n=this.x.redMul(t),o=this.y.redMul(t).redMul(e);return this.curve.point(n,o)},l.prototype.neg=function(){return this.curve.jpoint(this.x,this.y.redNeg(),this.z)},l.prototype.add=function(e){if(this.isInfinity())return e;if(e.isInfinity())return this;var t=e.z.redSqr(),n=this.z.redSqr(),o=this.x.redMul(t),r=e.x.redMul(n),i=this.y.redMul(t.redMul(e.z)),a=e.y.redMul(n.redMul(this.z)),s=o.redSub(r),u=i.redSub(a);if(0===s.cmpn(0))return 0!==u.cmpn(0)?this.curve.jpoint(null,null,null):this.dbl();var c=s.redSqr(),l=c.redMul(s),d=o.redMul(c),h=u.redSqr().redIAdd(l).redISub(d).redISub(d),p=u.redMul(d.redISub(h)).redISub(i.redMul(l)),f=this.z.redMul(e.z).redMul(s);return this.curve.jpoint(h,p,f)},l.prototype.mixedAdd=function(e){if(this.isInfinity())return e.toJ();if(e.isInfinity())return this;var t=this.z.redSqr(),n=this.x,o=e.x.redMul(t),r=this.y,i=e.y.redMul(t).redMul(this.z),a=n.redSub(o),s=r.redSub(i);if(0===a.cmpn(0))return 0!==s.cmpn(0)?this.curve.jpoint(null,null,null):this.dbl();var u=a.redSqr(),c=u.redMul(a),l=n.redMul(u),d=s.redSqr().redIAdd(c).redISub(l).redISub(l),h=s.redMul(l.redISub(d)).redISub(r.redMul(c)),p=this.z.redMul(a);return this.curve.jpoint(d,h,p)},l.prototype.dblp=function(e){if(0===e)return this;if(this.isInfinity())return this;if(!e)return this.dbl();var t;if(this.curve.zeroA||this.curve.threeA){var n=this;for(t=0;t=0)return!1;if(n.redIAdd(r),0===this.x.cmp(n))return!0}},l.prototype.inspect=function(){return this.isInfinity()?"":""},l.prototype.isInfinity=function(){return 0===this.z.cmpn(0)}},45427:(e,t,n)=>{"use strict";var o,r=t,i=n(33715),a=n(88254),s=n(80953).assert;function u(e){"short"===e.type?this.curve=new a.short(e):"edwards"===e.type?this.curve=new a.edwards(e):this.curve=new a.mont(e),this.g=this.curve.g,this.n=this.curve.n,this.hash=e.hash,s(this.g.validate(),"Invalid curve"),s(this.g.mul(this.n).isInfinity(),"Invalid curve, G*N != O")}function c(e,t){Object.defineProperty(r,e,{configurable:!0,enumerable:!0,get:function(){var n=new u(t);return Object.defineProperty(r,e,{configurable:!0,enumerable:!0,value:n}),n}})}r.PresetCurve=u,c("p192",{type:"short",prime:"p192",p:"ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff",a:"ffffffff ffffffff ffffffff fffffffe ffffffff fffffffc",b:"64210519 e59c80e7 0fa7e9ab 72243049 feb8deec c146b9b1",n:"ffffffff ffffffff ffffffff 99def836 146bc9b1 b4d22831",hash:i.sha256,gRed:!1,g:["188da80e b03090f6 7cbf20eb 43a18800 f4ff0afd 82ff1012","07192b95 ffc8da78 631011ed 6b24cdd5 73f977a1 1e794811"]}),c("p224",{type:"short",prime:"p224",p:"ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001",a:"ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff fffffffe",b:"b4050a85 0c04b3ab f5413256 5044b0b7 d7bfd8ba 270b3943 2355ffb4",n:"ffffffff ffffffff ffffffff ffff16a2 e0b8f03e 13dd2945 5c5c2a3d",hash:i.sha256,gRed:!1,g:["b70e0cbd 6bb4bf7f 321390b9 4a03c1d3 56c21122 343280d6 115c1d21","bd376388 b5f723fb 4c22dfe6 cd4375a0 5a074764 44d58199 85007e34"]}),c("p256",{type:"short",prime:null,p:"ffffffff 00000001 00000000 00000000 00000000 ffffffff ffffffff ffffffff",a:"ffffffff 00000001 00000000 00000000 00000000 ffffffff ffffffff fffffffc",b:"5ac635d8 aa3a93e7 b3ebbd55 769886bc 651d06b0 cc53b0f6 3bce3c3e 27d2604b",n:"ffffffff 00000000 ffffffff ffffffff bce6faad a7179e84 f3b9cac2 fc632551",hash:i.sha256,gRed:!1,g:["6b17d1f2 e12c4247 f8bce6e5 63a440f2 77037d81 2deb33a0 f4a13945 d898c296","4fe342e2 fe1a7f9b 8ee7eb4a 7c0f9e16 2bce3357 6b315ece cbb64068 37bf51f5"]}),c("p384",{type:"short",prime:null,p:"ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe ffffffff 00000000 00000000 ffffffff",a:"ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe ffffffff 00000000 00000000 fffffffc",b:"b3312fa7 e23ee7e4 988e056b e3f82d19 181d9c6e fe814112 0314088f 5013875a c656398d 8a2ed19d 2a85c8ed d3ec2aef",n:"ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff c7634d81 f4372ddf 581a0db2 48b0a77a ecec196a ccc52973",hash:i.sha384,gRed:!1,g:["aa87ca22 be8b0537 8eb1c71e f320ad74 6e1d3b62 8ba79b98 59f741e0 82542a38 5502f25d bf55296c 3a545e38 72760ab7","3617de4a 96262c6f 5d9e98bf 9292dc29 f8f41dbd 289a147c e9da3113 b5f0b8c0 0a60b1ce 1d7e819d 7a431d7c 90ea0e5f"]}),c("p521",{type:"short",prime:null,p:"000001ff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff",a:"000001ff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffc",b:"00000051 953eb961 8e1c9a1f 929a21a0 b68540ee a2da725b 99b315f3 b8b48991 8ef109e1 56193951 ec7e937b 1652c0bd 3bb1bf07 3573df88 3d2c34f1 ef451fd4 6b503f00",n:"000001ff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffa 51868783 bf2f966b 7fcc0148 f709a5d0 3bb5c9b8 899c47ae bb6fb71e 91386409",hash:i.sha512,gRed:!1,g:["000000c6 858e06b7 0404e9cd 9e3ecb66 2395b442 9c648139 053fb521 f828af60 6b4d3dba a14b5e77 efe75928 fe1dc127 a2ffa8de 3348b3c1 856a429b f97e7e31 c2e5bd66","00000118 39296a78 9a3bc004 5c8a5fb4 2c7d1bd9 98f54449 579b4468 17afbd17 273e662c 97ee7299 5ef42640 c550b901 3fad0761 353c7086 a272c240 88be9476 9fd16650"]}),c("curve25519",{type:"mont",prime:"p25519",p:"7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed",a:"76d06",b:"1",n:"1000000000000000 0000000000000000 14def9dea2f79cd6 5812631a5cf5d3ed",hash:i.sha256,gRed:!1,g:["9"]}),c("ed25519",{type:"edwards",prime:"p25519",p:"7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed",a:"-1",c:"1",d:"52036cee2b6ffe73 8cc740797779e898 00700a4d4141d8ab 75eb4dca135978a3",n:"1000000000000000 0000000000000000 14def9dea2f79cd6 5812631a5cf5d3ed",hash:i.sha256,gRed:!1,g:["216936d3cd6e53fec0a4e231fdd6dc5c692cc7609525a7b2c9562d608f25d51a","6666666666666666666666666666666666666666666666666666666666666658"]});try{o=n(91037)}catch(e){o=void 0}c("secp256k1",{type:"short",prime:"k256",p:"ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f",a:"0",b:"7",n:"ffffffff ffffffff ffffffff fffffffe baaedce6 af48a03b bfd25e8c d0364141",h:"1",hash:i.sha256,beta:"7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee",lambda:"5363ad4cc05c30e0a5261c028812645a122e22ea20816678df02967c1b23bd72",basis:[{a:"3086d221a7d46bcde86c90e49284eb15",b:"-e4437ed6010e88286f547fa90abfe4c3"},{a:"114ca50f7a8e2f3f657c1108d9d44cfd8",b:"3086d221a7d46bcde86c90e49284eb15"}],gRed:!1,g:["79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798","483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8",o]})},57954:(e,t,n)=>{"use strict";var o=n(73785),r=n(2156),i=n(80953),a=n(45427),s=n(29931),u=i.assert,c=n(31251),l=n(90611);function d(e){if(!(this instanceof d))return new d(e);"string"==typeof e&&(u(Object.prototype.hasOwnProperty.call(a,e),"Unknown curve "+e),e=a[e]),e instanceof a.PresetCurve&&(e={curve:e}),this.curve=e.curve.curve,this.n=this.curve.n,this.nh=this.n.ushrn(1),this.g=this.curve.g,this.g=e.curve.g,this.g.precompute(e.curve.n.bitLength()+1),this.hash=e.hash||e.curve.hash}e.exports=d,d.prototype.keyPair=function(e){return new c(this,e)},d.prototype.keyFromPrivate=function(e,t){return c.fromPrivate(this,e,t)},d.prototype.keyFromPublic=function(e,t){return c.fromPublic(this,e,t)},d.prototype.genKeyPair=function(e){e||(e={});for(var t=new r({hash:this.hash,pers:e.pers,persEnc:e.persEnc||"utf8",entropy:e.entropy||s(this.hash.hmacStrength),entropyEnc:e.entropy&&e.entropyEnc||"utf8",nonce:this.n.toArray()}),n=this.n.byteLength(),i=this.n.sub(new o(2));;){var a=new o(t.generate(n));if(!(a.cmp(i)>0))return a.iaddn(1),this.keyFromPrivate(a)}},d.prototype._truncateToN=function(e,t){var n=8*e.byteLength()-this.n.bitLength();return n>0&&(e=e.ushrn(n)),!t&&e.cmp(this.n)>=0?e.sub(this.n):e},d.prototype.sign=function(e,t,n,i){"object"==typeof n&&(i=n,n=null),i||(i={}),t=this.keyFromPrivate(t,n),e=this._truncateToN(new o(e,16));for(var a=this.n.byteLength(),s=t.getPrivate().toArray("be",a),u=e.toArray("be",a),c=new r({hash:this.hash,entropy:s,nonce:u,pers:i.pers,persEnc:i.persEnc||"utf8"}),d=this.n.sub(new o(1)),h=0;;h++){var p=i.k?i.k(h):new o(c.generate(this.n.byteLength()));if(!((p=this._truncateToN(p,!0)).cmpn(1)<=0||p.cmp(d)>=0)){var f=this.g.mul(p);if(!f.isInfinity()){var g=f.getX(),m=g.umod(this.n);if(0!==m.cmpn(0)){var _=p.invm(this.n).mul(m.mul(t.getPrivate()).iadd(e));if(0!==(_=_.umod(this.n)).cmpn(0)){var F=(f.getY().isOdd()?1:0)|(0!==g.cmp(m)?2:0);return i.canonical&&_.cmp(this.nh)>0&&(_=this.n.sub(_),F^=1),new l({r:m,s:_,recoveryParam:F})}}}}}},d.prototype.verify=function(e,t,n,r){e=this._truncateToN(new o(e,16)),n=this.keyFromPublic(n,r);var i=(t=new l(t,"hex")).r,a=t.s;if(i.cmpn(1)<0||i.cmp(this.n)>=0)return!1;if(a.cmpn(1)<0||a.cmp(this.n)>=0)return!1;var s,u=a.invm(this.n),c=u.mul(e).umod(this.n),d=u.mul(i).umod(this.n);return this.curve._maxwellTrick?!(s=this.g.jmulAdd(c,n.getPublic(),d)).isInfinity()&&s.eqXToP(i):!(s=this.g.mulAdd(c,n.getPublic(),d)).isInfinity()&&0===s.getX().umod(this.n).cmp(i)},d.prototype.recoverPubKey=function(e,t,n,r){u((3&n)===n,"The recovery param is more than two bits"),t=new l(t,r);var i=this.n,a=new o(e),s=t.r,c=t.s,d=1&n,h=n>>1;if(s.cmp(this.curve.p.umod(this.curve.n))>=0&&h)throw new Error("Unable to find sencond key candinate");s=h?this.curve.pointFromX(s.add(this.curve.n),d):this.curve.pointFromX(s,d);var p=t.r.invm(i),f=i.sub(a).mul(p).umod(i),g=c.mul(p).umod(i);return this.g.mulAdd(f,s,g)},d.prototype.getKeyRecoveryParam=function(e,t,n,o){if(null!==(t=new l(t,o)).recoveryParam)return t.recoveryParam;for(var r=0;r<4;r++){var i;try{i=this.recoverPubKey(e,t,r)}catch(e){continue}if(i.eq(n))return r}throw new Error("Unable to find valid recovery factor")}},31251:(e,t,n)=>{"use strict";var o=n(73785),r=n(80953).assert;function i(e,t){this.ec=e,this.priv=null,this.pub=null,t.priv&&this._importPrivate(t.priv,t.privEnc),t.pub&&this._importPublic(t.pub,t.pubEnc)}e.exports=i,i.fromPublic=function(e,t,n){return t instanceof i?t:new i(e,{pub:t,pubEnc:n})},i.fromPrivate=function(e,t,n){return t instanceof i?t:new i(e,{priv:t,privEnc:n})},i.prototype.validate=function(){var e=this.getPublic();return e.isInfinity()?{result:!1,reason:"Invalid public key"}:e.validate()?e.mul(this.ec.curve.n).isInfinity()?{result:!0,reason:null}:{result:!1,reason:"Public key * N != O"}:{result:!1,reason:"Public key is not a point"}},i.prototype.getPublic=function(e,t){return"string"==typeof e&&(t=e,e=null),this.pub||(this.pub=this.ec.g.mul(this.priv)),t?this.pub.encode(t,e):this.pub},i.prototype.getPrivate=function(e){return"hex"===e?this.priv.toString(16,2):this.priv},i.prototype._importPrivate=function(e,t){this.priv=new o(e,t||16),this.priv=this.priv.umod(this.ec.curve.n)},i.prototype._importPublic=function(e,t){if(e.x||e.y)return"mont"===this.ec.curve.type?r(e.x,"Need x coordinate"):"short"!==this.ec.curve.type&&"edwards"!==this.ec.curve.type||r(e.x&&e.y,"Need both x and y coordinate"),void(this.pub=this.ec.curve.point(e.x,e.y));this.pub=this.ec.curve.decodePoint(e,t)},i.prototype.derive=function(e){return e.validate()||r(e.validate(),"public point not validated"),e.mul(this.priv).getX()},i.prototype.sign=function(e,t,n){return this.ec.sign(e,this,t,n)},i.prototype.verify=function(e,t){return this.ec.verify(e,t,this)},i.prototype.inspect=function(){return""}},90611:(e,t,n)=>{"use strict";var o=n(73785),r=n(80953),i=r.assert;function a(e,t){if(e instanceof a)return e;this._importDER(e,t)||(i(e.r&&e.s,"Signature without r or s"),this.r=new o(e.r,16),this.s=new o(e.s,16),void 0===e.recoveryParam?this.recoveryParam=null:this.recoveryParam=e.recoveryParam)}function s(){this.place=0}function u(e,t){var n=e[t.place++];if(!(128&n))return n;var o=15&n;if(0===o||o>4)return!1;for(var r=0,i=0,a=t.place;i>>=0;return!(r<=127)&&(t.place=a,r)}function c(e){for(var t=0,n=e.length-1;!e[t]&&!(128&e[t+1])&&t>>3);for(e.push(128|n);--n;)e.push(t>>>(n<<3)&255);e.push(t)}}e.exports=a,a.prototype._importDER=function(e,t){e=r.toArray(e,t);var n=new s;if(48!==e[n.place++])return!1;var i=u(e,n);if(!1===i)return!1;if(i+n.place!==e.length)return!1;if(2!==e[n.place++])return!1;var a=u(e,n);if(!1===a)return!1;var c=e.slice(n.place,a+n.place);if(n.place+=a,2!==e[n.place++])return!1;var l=u(e,n);if(!1===l)return!1;if(e.length!==l+n.place)return!1;var d=e.slice(n.place,l+n.place);if(0===c[0]){if(!(128&c[1]))return!1;c=c.slice(1)}if(0===d[0]){if(!(128&d[1]))return!1;d=d.slice(1)}return this.r=new o(c),this.s=new o(d),this.recoveryParam=null,!0},a.prototype.toDER=function(e){var t=this.r.toArray(),n=this.s.toArray();for(128&t[0]&&(t=[0].concat(t)),128&n[0]&&(n=[0].concat(n)),t=c(t),n=c(n);!(n[0]||128&n[1]);)n=n.slice(1);var o=[2];l(o,t.length),(o=o.concat(t)).push(2),l(o,n.length);var i=o.concat(n),a=[48];return l(a,i.length),a=a.concat(i),r.encode(a,e)}},65980:(e,t,n)=>{"use strict";var o=n(33715),r=n(45427),i=n(80953),a=i.assert,s=i.parseBytes,u=n(79087),c=n(23622);function l(e){if(a("ed25519"===e,"only tested with ed25519 so far"),!(this instanceof l))return new l(e);e=r[e].curve,this.curve=e,this.g=e.g,this.g.precompute(e.n.bitLength()+1),this.pointClass=e.point().constructor,this.encodingLength=Math.ceil(e.n.bitLength()/8),this.hash=o.sha512}e.exports=l,l.prototype.sign=function(e,t){e=s(e);var n=this.keyFromSecret(t),o=this.hashInt(n.messagePrefix(),e),r=this.g.mul(o),i=this.encodePoint(r),a=this.hashInt(i,n.pubBytes(),e).mul(n.priv()),u=o.add(a).umod(this.curve.n);return this.makeSignature({R:r,S:u,Rencoded:i})},l.prototype.verify=function(e,t,n){e=s(e),t=this.makeSignature(t);var o=this.keyFromPublic(n),r=this.hashInt(t.Rencoded(),o.pubBytes(),e),i=this.g.mul(t.S());return t.R().add(o.pub().mul(r)).eq(i)},l.prototype.hashInt=function(){for(var e=this.hash(),t=0;t{"use strict";var o=n(80953),r=o.assert,i=o.parseBytes,a=o.cachedProperty;function s(e,t){this.eddsa=e,this._secret=i(t.secret),e.isPoint(t.pub)?this._pub=t.pub:this._pubBytes=i(t.pub)}s.fromPublic=function(e,t){return t instanceof s?t:new s(e,{pub:t})},s.fromSecret=function(e,t){return t instanceof s?t:new s(e,{secret:t})},s.prototype.secret=function(){return this._secret},a(s,"pubBytes",(function(){return this.eddsa.encodePoint(this.pub())})),a(s,"pub",(function(){return this._pubBytes?this.eddsa.decodePoint(this._pubBytes):this.eddsa.g.mul(this.priv())})),a(s,"privBytes",(function(){var e=this.eddsa,t=this.hash(),n=e.encodingLength-1,o=t.slice(0,e.encodingLength);return o[0]&=248,o[n]&=127,o[n]|=64,o})),a(s,"priv",(function(){return this.eddsa.decodeInt(this.privBytes())})),a(s,"hash",(function(){return this.eddsa.hash().update(this.secret()).digest()})),a(s,"messagePrefix",(function(){return this.hash().slice(this.eddsa.encodingLength)})),s.prototype.sign=function(e){return r(this._secret,"KeyPair can only verify"),this.eddsa.sign(e,this)},s.prototype.verify=function(e,t){return this.eddsa.verify(e,t,this)},s.prototype.getSecret=function(e){return r(this._secret,"KeyPair is public only"),o.encode(this.secret(),e)},s.prototype.getPublic=function(e){return o.encode(this.pubBytes(),e)},e.exports=s},23622:(e,t,n)=>{"use strict";var o=n(73785),r=n(80953),i=r.assert,a=r.cachedProperty,s=r.parseBytes;function u(e,t){this.eddsa=e,"object"!=typeof t&&(t=s(t)),Array.isArray(t)&&(t={R:t.slice(0,e.encodingLength),S:t.slice(e.encodingLength)}),i(t.R&&t.S,"Signature without R or S"),e.isPoint(t.R)&&(this._R=t.R),t.S instanceof o&&(this._S=t.S),this._Rencoded=Array.isArray(t.R)?t.R:t.Rencoded,this._Sencoded=Array.isArray(t.S)?t.S:t.Sencoded}a(u,"S",(function(){return this.eddsa.decodeInt(this.Sencoded())})),a(u,"R",(function(){return this.eddsa.decodePoint(this.Rencoded())})),a(u,"Rencoded",(function(){return this.eddsa.encodePoint(this.R())})),a(u,"Sencoded",(function(){return this.eddsa.encodeInt(this.S())})),u.prototype.toBytes=function(){return this.Rencoded().concat(this.Sencoded())},u.prototype.toHex=function(){return r.encode(this.toBytes(),"hex").toUpperCase()},e.exports=u},91037:e=>{e.exports={doubles:{step:4,points:[["e60fce93b59e9ec53011aabc21c23e97b2a31369b87a5ae9c44ee89e2a6dec0a","f7e3507399e595929db99f34f57937101296891e44d23f0be1f32cce69616821"],["8282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508","11f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf"],["175e159f728b865a72f99cc6c6fc846de0b93833fd2222ed73fce5b551e5b739","d3506e0d9e3c79eba4ef97a51ff71f5eacb5955add24345c6efa6ffee9fed695"],["363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640","4e273adfc732221953b445397f3363145b9a89008199ecb62003c7f3bee9de9"],["8b4b5f165df3c2be8c6244b5b745638843e4a781a15bcd1b69f79a55dffdf80c","4aad0a6f68d308b4b3fbd7813ab0da04f9e336546162ee56b3eff0c65fd4fd36"],["723cbaa6e5db996d6bf771c00bd548c7b700dbffa6c0e77bcb6115925232fcda","96e867b5595cc498a921137488824d6e2660a0653779494801dc069d9eb39f5f"],["eebfa4d493bebf98ba5feec812c2d3b50947961237a919839a533eca0e7dd7fa","5d9a8ca3970ef0f269ee7edaf178089d9ae4cdc3a711f712ddfd4fdae1de8999"],["100f44da696e71672791d0a09b7bde459f1215a29b3c03bfefd7835b39a48db0","cdd9e13192a00b772ec8f3300c090666b7ff4a18ff5195ac0fbd5cd62bc65a09"],["e1031be262c7ed1b1dc9227a4a04c017a77f8d4464f3b3852c8acde6e534fd2d","9d7061928940405e6bb6a4176597535af292dd419e1ced79a44f18f29456a00d"],["feea6cae46d55b530ac2839f143bd7ec5cf8b266a41d6af52d5e688d9094696d","e57c6b6c97dce1bab06e4e12bf3ecd5c981c8957cc41442d3155debf18090088"],["da67a91d91049cdcb367be4be6ffca3cfeed657d808583de33fa978bc1ec6cb1","9bacaa35481642bc41f463f7ec9780e5dec7adc508f740a17e9ea8e27a68be1d"],["53904faa0b334cdda6e000935ef22151ec08d0f7bb11069f57545ccc1a37b7c0","5bc087d0bc80106d88c9eccac20d3c1c13999981e14434699dcb096b022771c8"],["8e7bcd0bd35983a7719cca7764ca906779b53a043a9b8bcaeff959f43ad86047","10b7770b2a3da4b3940310420ca9514579e88e2e47fd68b3ea10047e8460372a"],["385eed34c1cdff21e6d0818689b81bde71a7f4f18397e6690a841e1599c43862","283bebc3e8ea23f56701de19e9ebf4576b304eec2086dc8cc0458fe5542e5453"],["6f9d9b803ecf191637c73a4413dfa180fddf84a5947fbc9c606ed86c3fac3a7","7c80c68e603059ba69b8e2a30e45c4d47ea4dd2f5c281002d86890603a842160"],["3322d401243c4e2582a2147c104d6ecbf774d163db0f5e5313b7e0e742d0e6bd","56e70797e9664ef5bfb019bc4ddaf9b72805f63ea2873af624f3a2e96c28b2a0"],["85672c7d2de0b7da2bd1770d89665868741b3f9af7643397721d74d28134ab83","7c481b9b5b43b2eb6374049bfa62c2e5e77f17fcc5298f44c8e3094f790313a6"],["948bf809b1988a46b06c9f1919413b10f9226c60f668832ffd959af60c82a0a","53a562856dcb6646dc6b74c5d1c3418c6d4dff08c97cd2bed4cb7f88d8c8e589"],["6260ce7f461801c34f067ce0f02873a8f1b0e44dfc69752accecd819f38fd8e8","bc2da82b6fa5b571a7f09049776a1ef7ecd292238051c198c1a84e95b2b4ae17"],["e5037de0afc1d8d43d8348414bbf4103043ec8f575bfdc432953cc8d2037fa2d","4571534baa94d3b5f9f98d09fb990bddbd5f5b03ec481f10e0e5dc841d755bda"],["e06372b0f4a207adf5ea905e8f1771b4e7e8dbd1c6a6c5b725866a0ae4fce725","7a908974bce18cfe12a27bb2ad5a488cd7484a7787104870b27034f94eee31dd"],["213c7a715cd5d45358d0bbf9dc0ce02204b10bdde2a3f58540ad6908d0559754","4b6dad0b5ae462507013ad06245ba190bb4850f5f36a7eeddff2c27534b458f2"],["4e7c272a7af4b34e8dbb9352a5419a87e2838c70adc62cddf0cc3a3b08fbd53c","17749c766c9d0b18e16fd09f6def681b530b9614bff7dd33e0b3941817dcaae6"],["fea74e3dbe778b1b10f238ad61686aa5c76e3db2be43057632427e2840fb27b6","6e0568db9b0b13297cf674deccb6af93126b596b973f7b77701d3db7f23cb96f"],["76e64113f677cf0e10a2570d599968d31544e179b760432952c02a4417bdde39","c90ddf8dee4e95cf577066d70681f0d35e2a33d2b56d2032b4b1752d1901ac01"],["c738c56b03b2abe1e8281baa743f8f9a8f7cc643df26cbee3ab150242bcbb891","893fb578951ad2537f718f2eacbfbbbb82314eef7880cfe917e735d9699a84c3"],["d895626548b65b81e264c7637c972877d1d72e5f3a925014372e9f6588f6c14b","febfaa38f2bc7eae728ec60818c340eb03428d632bb067e179363ed75d7d991f"],["b8da94032a957518eb0f6433571e8761ceffc73693e84edd49150a564f676e03","2804dfa44805a1e4d7c99cc9762808b092cc584d95ff3b511488e4e74efdf6e7"],["e80fea14441fb33a7d8adab9475d7fab2019effb5156a792f1a11778e3c0df5d","eed1de7f638e00771e89768ca3ca94472d155e80af322ea9fcb4291b6ac9ec78"],["a301697bdfcd704313ba48e51d567543f2a182031efd6915ddc07bbcc4e16070","7370f91cfb67e4f5081809fa25d40f9b1735dbf7c0a11a130c0d1a041e177ea1"],["90ad85b389d6b936463f9d0512678de208cc330b11307fffab7ac63e3fb04ed4","e507a3620a38261affdcbd9427222b839aefabe1582894d991d4d48cb6ef150"],["8f68b9d2f63b5f339239c1ad981f162ee88c5678723ea3351b7b444c9ec4c0da","662a9f2dba063986de1d90c2b6be215dbbea2cfe95510bfdf23cbf79501fff82"],["e4f3fb0176af85d65ff99ff9198c36091f48e86503681e3e6686fd5053231e11","1e63633ad0ef4f1c1661a6d0ea02b7286cc7e74ec951d1c9822c38576feb73bc"],["8c00fa9b18ebf331eb961537a45a4266c7034f2f0d4e1d0716fb6eae20eae29e","efa47267fea521a1a9dc343a3736c974c2fadafa81e36c54e7d2a4c66702414b"],["e7a26ce69dd4829f3e10cec0a9e98ed3143d084f308b92c0997fddfc60cb3e41","2a758e300fa7984b471b006a1aafbb18d0a6b2c0420e83e20e8a9421cf2cfd51"],["b6459e0ee3662ec8d23540c223bcbdc571cbcb967d79424f3cf29eb3de6b80ef","67c876d06f3e06de1dadf16e5661db3c4b3ae6d48e35b2ff30bf0b61a71ba45"],["d68a80c8280bb840793234aa118f06231d6f1fc67e73c5a5deda0f5b496943e8","db8ba9fff4b586d00c4b1f9177b0e28b5b0e7b8f7845295a294c84266b133120"],["324aed7df65c804252dc0270907a30b09612aeb973449cea4095980fc28d3d5d","648a365774b61f2ff130c0c35aec1f4f19213b0c7e332843967224af96ab7c84"],["4df9c14919cde61f6d51dfdbe5fee5dceec4143ba8d1ca888e8bd373fd054c96","35ec51092d8728050974c23a1d85d4b5d506cdc288490192ebac06cad10d5d"],["9c3919a84a474870faed8a9c1cc66021523489054d7f0308cbfc99c8ac1f98cd","ddb84f0f4a4ddd57584f044bf260e641905326f76c64c8e6be7e5e03d4fc599d"],["6057170b1dd12fdf8de05f281d8e06bb91e1493a8b91d4cc5a21382120a959e5","9a1af0b26a6a4807add9a2daf71df262465152bc3ee24c65e899be932385a2a8"],["a576df8e23a08411421439a4518da31880cef0fba7d4df12b1a6973eecb94266","40a6bf20e76640b2c92b97afe58cd82c432e10a7f514d9f3ee8be11ae1b28ec8"],["7778a78c28dec3e30a05fe9629de8c38bb30d1f5cf9a3a208f763889be58ad71","34626d9ab5a5b22ff7098e12f2ff580087b38411ff24ac563b513fc1fd9f43ac"],["928955ee637a84463729fd30e7afd2ed5f96274e5ad7e5cb09eda9c06d903ac","c25621003d3f42a827b78a13093a95eeac3d26efa8a8d83fc5180e935bcd091f"],["85d0fef3ec6db109399064f3a0e3b2855645b4a907ad354527aae75163d82751","1f03648413a38c0be29d496e582cf5663e8751e96877331582c237a24eb1f962"],["ff2b0dce97eece97c1c9b6041798b85dfdfb6d8882da20308f5404824526087e","493d13fef524ba188af4c4dc54d07936c7b7ed6fb90e2ceb2c951e01f0c29907"],["827fbbe4b1e880ea9ed2b2e6301b212b57f1ee148cd6dd28780e5e2cf856e241","c60f9c923c727b0b71bef2c67d1d12687ff7a63186903166d605b68baec293ec"],["eaa649f21f51bdbae7be4ae34ce6e5217a58fdce7f47f9aa7f3b58fa2120e2b3","be3279ed5bbbb03ac69a80f89879aa5a01a6b965f13f7e59d47a5305ba5ad93d"],["e4a42d43c5cf169d9391df6decf42ee541b6d8f0c9a137401e23632dda34d24f","4d9f92e716d1c73526fc99ccfb8ad34ce886eedfa8d8e4f13a7f7131deba9414"],["1ec80fef360cbdd954160fadab352b6b92b53576a88fea4947173b9d4300bf19","aeefe93756b5340d2f3a4958a7abbf5e0146e77f6295a07b671cdc1cc107cefd"],["146a778c04670c2f91b00af4680dfa8bce3490717d58ba889ddb5928366642be","b318e0ec3354028add669827f9d4b2870aaa971d2f7e5ed1d0b297483d83efd0"],["fa50c0f61d22e5f07e3acebb1aa07b128d0012209a28b9776d76a8793180eef9","6b84c6922397eba9b72cd2872281a68a5e683293a57a213b38cd8d7d3f4f2811"],["da1d61d0ca721a11b1a5bf6b7d88e8421a288ab5d5bba5220e53d32b5f067ec2","8157f55a7c99306c79c0766161c91e2966a73899d279b48a655fba0f1ad836f1"],["a8e282ff0c9706907215ff98e8fd416615311de0446f1e062a73b0610d064e13","7f97355b8db81c09abfb7f3c5b2515888b679a3e50dd6bd6cef7c73111f4cc0c"],["174a53b9c9a285872d39e56e6913cab15d59b1fa512508c022f382de8319497c","ccc9dc37abfc9c1657b4155f2c47f9e6646b3a1d8cb9854383da13ac079afa73"],["959396981943785c3d3e57edf5018cdbe039e730e4918b3d884fdff09475b7ba","2e7e552888c331dd8ba0386a4b9cd6849c653f64c8709385e9b8abf87524f2fd"],["d2a63a50ae401e56d645a1153b109a8fcca0a43d561fba2dbb51340c9d82b151","e82d86fb6443fcb7565aee58b2948220a70f750af484ca52d4142174dcf89405"],["64587e2335471eb890ee7896d7cfdc866bacbdbd3839317b3436f9b45617e073","d99fcdd5bf6902e2ae96dd6447c299a185b90a39133aeab358299e5e9faf6589"],["8481bde0e4e4d885b3a546d3e549de042f0aa6cea250e7fd358d6c86dd45e458","38ee7b8cba5404dd84a25bf39cecb2ca900a79c42b262e556d64b1b59779057e"],["13464a57a78102aa62b6979ae817f4637ffcfed3c4b1ce30bcd6303f6caf666b","69be159004614580ef7e433453ccb0ca48f300a81d0942e13f495a907f6ecc27"],["bc4a9df5b713fe2e9aef430bcc1dc97a0cd9ccede2f28588cada3a0d2d83f366","d3a81ca6e785c06383937adf4b798caa6e8a9fbfa547b16d758d666581f33c1"],["8c28a97bf8298bc0d23d8c749452a32e694b65e30a9472a3954ab30fe5324caa","40a30463a3305193378fedf31f7cc0eb7ae784f0451cb9459e71dc73cbef9482"],["8ea9666139527a8c1dd94ce4f071fd23c8b350c5a4bb33748c4ba111faccae0","620efabbc8ee2782e24e7c0cfb95c5d735b783be9cf0f8e955af34a30e62b945"],["dd3625faef5ba06074669716bbd3788d89bdde815959968092f76cc4eb9a9787","7a188fa3520e30d461da2501045731ca941461982883395937f68d00c644a573"],["f710d79d9eb962297e4f6232b40e8f7feb2bc63814614d692c12de752408221e","ea98e67232d3b3295d3b535532115ccac8612c721851617526ae47a9c77bfc82"]]},naf:{wnd:7,points:[["f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9","388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e672"],["2f8bde4d1a07209355b4a7250a5c5128e88b84bddc619ab7cba8d569b240efe4","d8ac222636e5e3d6d4dba9dda6c9c426f788271bab0d6840dca87d3aa6ac62d6"],["5cbdf0646e5db4eaa398f365f2ea7a0e3d419b7e0330e39ce92bddedcac4f9bc","6aebca40ba255960a3178d6d861a54dba813d0b813fde7b5a5082628087264da"],["acd484e2f0c7f65309ad178a9f559abde09796974c57e714c35f110dfc27ccbe","cc338921b0a7d9fd64380971763b61e9add888a4375f8e0f05cc262ac64f9c37"],["774ae7f858a9411e5ef4246b70c65aac5649980be5c17891bbec17895da008cb","d984a032eb6b5e190243dd56d7b7b365372db1e2dff9d6a8301d74c9c953c61b"],["f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8","ab0902e8d880a89758212eb65cdaf473a1a06da521fa91f29b5cb52db03ed81"],["d7924d4f7d43ea965a465ae3095ff41131e5946f3c85f79e44adbcf8e27e080e","581e2872a86c72a683842ec228cc6defea40af2bd896d3a5c504dc9ff6a26b58"],["defdea4cdb677750a420fee807eacf21eb9898ae79b9768766e4faa04a2d4a34","4211ab0694635168e997b0ead2a93daeced1f4a04a95c0f6cfb199f69e56eb77"],["2b4ea0a797a443d293ef5cff444f4979f06acfebd7e86d277475656138385b6c","85e89bc037945d93b343083b5a1c86131a01f60c50269763b570c854e5c09b7a"],["352bbf4a4cdd12564f93fa332ce333301d9ad40271f8107181340aef25be59d5","321eb4075348f534d59c18259dda3e1f4a1b3b2e71b1039c67bd3d8bcf81998c"],["2fa2104d6b38d11b0230010559879124e42ab8dfeff5ff29dc9cdadd4ecacc3f","2de1068295dd865b64569335bd5dd80181d70ecfc882648423ba76b532b7d67"],["9248279b09b4d68dab21a9b066edda83263c3d84e09572e269ca0cd7f5453714","73016f7bf234aade5d1aa71bdea2b1ff3fc0de2a887912ffe54a32ce97cb3402"],["daed4f2be3a8bf278e70132fb0beb7522f570e144bf615c07e996d443dee8729","a69dce4a7d6c98e8d4a1aca87ef8d7003f83c230f3afa726ab40e52290be1c55"],["c44d12c7065d812e8acf28d7cbb19f9011ecd9e9fdf281b0e6a3b5e87d22e7db","2119a460ce326cdc76c45926c982fdac0e106e861edf61c5a039063f0e0e6482"],["6a245bf6dc698504c89a20cfded60853152b695336c28063b61c65cbd269e6b4","e022cf42c2bd4a708b3f5126f16a24ad8b33ba48d0423b6efd5e6348100d8a82"],["1697ffa6fd9de627c077e3d2fe541084ce13300b0bec1146f95ae57f0d0bd6a5","b9c398f186806f5d27561506e4557433a2cf15009e498ae7adee9d63d01b2396"],["605bdb019981718b986d0f07e834cb0d9deb8360ffb7f61df982345ef27a7479","2972d2de4f8d20681a78d93ec96fe23c26bfae84fb14db43b01e1e9056b8c49"],["62d14dab4150bf497402fdc45a215e10dcb01c354959b10cfe31c7e9d87ff33d","80fc06bd8cc5b01098088a1950eed0db01aa132967ab472235f5642483b25eaf"],["80c60ad0040f27dade5b4b06c408e56b2c50e9f56b9b8b425e555c2f86308b6f","1c38303f1cc5c30f26e66bad7fe72f70a65eed4cbe7024eb1aa01f56430bd57a"],["7a9375ad6167ad54aa74c6348cc54d344cc5dc9487d847049d5eabb0fa03c8fb","d0e3fa9eca8726909559e0d79269046bdc59ea10c70ce2b02d499ec224dc7f7"],["d528ecd9b696b54c907a9ed045447a79bb408ec39b68df504bb51f459bc3ffc9","eecf41253136e5f99966f21881fd656ebc4345405c520dbc063465b521409933"],["49370a4b5f43412ea25f514e8ecdad05266115e4a7ecb1387231808f8b45963","758f3f41afd6ed428b3081b0512fd62a54c3f3afbb5b6764b653052a12949c9a"],["77f230936ee88cbbd73df930d64702ef881d811e0e1498e2f1c13eb1fc345d74","958ef42a7886b6400a08266e9ba1b37896c95330d97077cbbe8eb3c7671c60d6"],["f2dac991cc4ce4b9ea44887e5c7c0bce58c80074ab9d4dbaeb28531b7739f530","e0dedc9b3b2f8dad4da1f32dec2531df9eb5fbeb0598e4fd1a117dba703a3c37"],["463b3d9f662621fb1b4be8fbbe2520125a216cdfc9dae3debcba4850c690d45b","5ed430d78c296c3543114306dd8622d7c622e27c970a1de31cb377b01af7307e"],["f16f804244e46e2a09232d4aff3b59976b98fac14328a2d1a32496b49998f247","cedabd9b82203f7e13d206fcdf4e33d92a6c53c26e5cce26d6579962c4e31df6"],["caf754272dc84563b0352b7a14311af55d245315ace27c65369e15f7151d41d1","cb474660ef35f5f2a41b643fa5e460575f4fa9b7962232a5c32f908318a04476"],["2600ca4b282cb986f85d0f1709979d8b44a09c07cb86d7c124497bc86f082120","4119b88753c15bd6a693b03fcddbb45d5ac6be74ab5f0ef44b0be9475a7e4b40"],["7635ca72d7e8432c338ec53cd12220bc01c48685e24f7dc8c602a7746998e435","91b649609489d613d1d5e590f78e6d74ecfc061d57048bad9e76f302c5b9c61"],["754e3239f325570cdbbf4a87deee8a66b7f2b33479d468fbc1a50743bf56cc18","673fb86e5bda30fb3cd0ed304ea49a023ee33d0197a695d0c5d98093c536683"],["e3e6bd1071a1e96aff57859c82d570f0330800661d1c952f9fe2694691d9b9e8","59c9e0bba394e76f40c0aa58379a3cb6a5a2283993e90c4167002af4920e37f5"],["186b483d056a033826ae73d88f732985c4ccb1f32ba35f4b4cc47fdcf04aa6eb","3b952d32c67cf77e2e17446e204180ab21fb8090895138b4a4a797f86e80888b"],["df9d70a6b9876ce544c98561f4be4f725442e6d2b737d9c91a8321724ce0963f","55eb2dafd84d6ccd5f862b785dc39d4ab157222720ef9da217b8c45cf2ba2417"],["5edd5cc23c51e87a497ca815d5dce0f8ab52554f849ed8995de64c5f34ce7143","efae9c8dbc14130661e8cec030c89ad0c13c66c0d17a2905cdc706ab7399a868"],["290798c2b6476830da12fe02287e9e777aa3fba1c355b17a722d362f84614fba","e38da76dcd440621988d00bcf79af25d5b29c094db2a23146d003afd41943e7a"],["af3c423a95d9f5b3054754efa150ac39cd29552fe360257362dfdecef4053b45","f98a3fd831eb2b749a93b0e6f35cfb40c8cd5aa667a15581bc2feded498fd9c6"],["766dbb24d134e745cccaa28c99bf274906bb66b26dcf98df8d2fed50d884249a","744b1152eacbe5e38dcc887980da38b897584a65fa06cedd2c924f97cbac5996"],["59dbf46f8c94759ba21277c33784f41645f7b44f6c596a58ce92e666191abe3e","c534ad44175fbc300f4ea6ce648309a042ce739a7919798cd85e216c4a307f6e"],["f13ada95103c4537305e691e74e9a4a8dd647e711a95e73cb62dc6018cfd87b8","e13817b44ee14de663bf4bc808341f326949e21a6a75c2570778419bdaf5733d"],["7754b4fa0e8aced06d4167a2c59cca4cda1869c06ebadfb6488550015a88522c","30e93e864e669d82224b967c3020b8fa8d1e4e350b6cbcc537a48b57841163a2"],["948dcadf5990e048aa3874d46abef9d701858f95de8041d2a6828c99e2262519","e491a42537f6e597d5d28a3224b1bc25df9154efbd2ef1d2cbba2cae5347d57e"],["7962414450c76c1689c7b48f8202ec37fb224cf5ac0bfa1570328a8a3d7c77ab","100b610ec4ffb4760d5c1fc133ef6f6b12507a051f04ac5760afa5b29db83437"],["3514087834964b54b15b160644d915485a16977225b8847bb0dd085137ec47ca","ef0afbb2056205448e1652c48e8127fc6039e77c15c2378b7e7d15a0de293311"],["d3cc30ad6b483e4bc79ce2c9dd8bc54993e947eb8df787b442943d3f7b527eaf","8b378a22d827278d89c5e9be8f9508ae3c2ad46290358630afb34db04eede0a4"],["1624d84780732860ce1c78fcbfefe08b2b29823db913f6493975ba0ff4847610","68651cf9b6da903e0914448c6cd9d4ca896878f5282be4c8cc06e2a404078575"],["733ce80da955a8a26902c95633e62a985192474b5af207da6df7b4fd5fc61cd4","f5435a2bd2badf7d485a4d8b8db9fcce3e1ef8e0201e4578c54673bc1dc5ea1d"],["15d9441254945064cf1a1c33bbd3b49f8966c5092171e699ef258dfab81c045c","d56eb30b69463e7234f5137b73b84177434800bacebfc685fc37bbe9efe4070d"],["a1d0fcf2ec9de675b612136e5ce70d271c21417c9d2b8aaaac138599d0717940","edd77f50bcb5a3cab2e90737309667f2641462a54070f3d519212d39c197a629"],["e22fbe15c0af8ccc5780c0735f84dbe9a790badee8245c06c7ca37331cb36980","a855babad5cd60c88b430a69f53a1a7a38289154964799be43d06d77d31da06"],["311091dd9860e8e20ee13473c1155f5f69635e394704eaa74009452246cfa9b3","66db656f87d1f04fffd1f04788c06830871ec5a64feee685bd80f0b1286d8374"],["34c1fd04d301be89b31c0442d3e6ac24883928b45a9340781867d4232ec2dbdf","9414685e97b1b5954bd46f730174136d57f1ceeb487443dc5321857ba73abee"],["f219ea5d6b54701c1c14de5b557eb42a8d13f3abbcd08affcc2a5e6b049b8d63","4cb95957e83d40b0f73af4544cccf6b1f4b08d3c07b27fb8d8c2962a400766d1"],["d7b8740f74a8fbaab1f683db8f45de26543a5490bca627087236912469a0b448","fa77968128d9c92ee1010f337ad4717eff15db5ed3c049b3411e0315eaa4593b"],["32d31c222f8f6f0ef86f7c98d3a3335ead5bcd32abdd94289fe4d3091aa824bf","5f3032f5892156e39ccd3d7915b9e1da2e6dac9e6f26e961118d14b8462e1661"],["7461f371914ab32671045a155d9831ea8793d77cd59592c4340f86cbc18347b5","8ec0ba238b96bec0cbdddcae0aa442542eee1ff50c986ea6b39847b3cc092ff6"],["ee079adb1df1860074356a25aa38206a6d716b2c3e67453d287698bad7b2b2d6","8dc2412aafe3be5c4c5f37e0ecc5f9f6a446989af04c4e25ebaac479ec1c8c1e"],["16ec93e447ec83f0467b18302ee620f7e65de331874c9dc72bfd8616ba9da6b5","5e4631150e62fb40d0e8c2a7ca5804a39d58186a50e497139626778e25b0674d"],["eaa5f980c245f6f038978290afa70b6bd8855897f98b6aa485b96065d537bd99","f65f5d3e292c2e0819a528391c994624d784869d7e6ea67fb18041024edc07dc"],["78c9407544ac132692ee1910a02439958ae04877151342ea96c4b6b35a49f51","f3e0319169eb9b85d5404795539a5e68fa1fbd583c064d2462b675f194a3ddb4"],["494f4be219a1a77016dcd838431aea0001cdc8ae7a6fc688726578d9702857a5","42242a969283a5f339ba7f075e36ba2af925ce30d767ed6e55f4b031880d562c"],["a598a8030da6d86c6bc7f2f5144ea549d28211ea58faa70ebf4c1e665c1fe9b5","204b5d6f84822c307e4b4a7140737aec23fc63b65b35f86a10026dbd2d864e6b"],["c41916365abb2b5d09192f5f2dbeafec208f020f12570a184dbadc3e58595997","4f14351d0087efa49d245b328984989d5caf9450f34bfc0ed16e96b58fa9913"],["841d6063a586fa475a724604da03bc5b92a2e0d2e0a36acfe4c73a5514742881","73867f59c0659e81904f9a1c7543698e62562d6744c169ce7a36de01a8d6154"],["5e95bb399a6971d376026947f89bde2f282b33810928be4ded112ac4d70e20d5","39f23f366809085beebfc71181313775a99c9aed7d8ba38b161384c746012865"],["36e4641a53948fd476c39f8a99fd974e5ec07564b5315d8bf99471bca0ef2f66","d2424b1b1abe4eb8164227b085c9aa9456ea13493fd563e06fd51cf5694c78fc"],["336581ea7bfbbb290c191a2f507a41cf5643842170e914faeab27c2c579f726","ead12168595fe1be99252129b6e56b3391f7ab1410cd1e0ef3dcdcabd2fda224"],["8ab89816dadfd6b6a1f2634fcf00ec8403781025ed6890c4849742706bd43ede","6fdcef09f2f6d0a044e654aef624136f503d459c3e89845858a47a9129cdd24e"],["1e33f1a746c9c5778133344d9299fcaa20b0938e8acff2544bb40284b8c5fb94","60660257dd11b3aa9c8ed618d24edff2306d320f1d03010e33a7d2057f3b3b6"],["85b7c1dcb3cec1b7ee7f30ded79dd20a0ed1f4cc18cbcfcfa410361fd8f08f31","3d98a9cdd026dd43f39048f25a8847f4fcafad1895d7a633c6fed3c35e999511"],["29df9fbd8d9e46509275f4b125d6d45d7fbe9a3b878a7af872a2800661ac5f51","b4c4fe99c775a606e2d8862179139ffda61dc861c019e55cd2876eb2a27d84b"],["a0b1cae06b0a847a3fea6e671aaf8adfdfe58ca2f768105c8082b2e449fce252","ae434102edde0958ec4b19d917a6a28e6b72da1834aff0e650f049503a296cf2"],["4e8ceafb9b3e9a136dc7ff67e840295b499dfb3b2133e4ba113f2e4c0e121e5","cf2174118c8b6d7a4b48f6d534ce5c79422c086a63460502b827ce62a326683c"],["d24a44e047e19b6f5afb81c7ca2f69080a5076689a010919f42725c2b789a33b","6fb8d5591b466f8fc63db50f1c0f1c69013f996887b8244d2cdec417afea8fa3"],["ea01606a7a6c9cdd249fdfcfacb99584001edd28abbab77b5104e98e8e3b35d4","322af4908c7312b0cfbfe369f7a7b3cdb7d4494bc2823700cfd652188a3ea98d"],["af8addbf2b661c8a6c6328655eb96651252007d8c5ea31be4ad196de8ce2131f","6749e67c029b85f52a034eafd096836b2520818680e26ac8f3dfbcdb71749700"],["e3ae1974566ca06cc516d47e0fb165a674a3dabcfca15e722f0e3450f45889","2aeabe7e4531510116217f07bf4d07300de97e4874f81f533420a72eeb0bd6a4"],["591ee355313d99721cf6993ffed1e3e301993ff3ed258802075ea8ced397e246","b0ea558a113c30bea60fc4775460c7901ff0b053d25ca2bdeee98f1a4be5d196"],["11396d55fda54c49f19aa97318d8da61fa8584e47b084945077cf03255b52984","998c74a8cd45ac01289d5833a7beb4744ff536b01b257be4c5767bea93ea57a4"],["3c5d2a1ba39c5a1790000738c9e0c40b8dcdfd5468754b6405540157e017aa7a","b2284279995a34e2f9d4de7396fc18b80f9b8b9fdd270f6661f79ca4c81bd257"],["cc8704b8a60a0defa3a99a7299f2e9c3fbc395afb04ac078425ef8a1793cc030","bdd46039feed17881d1e0862db347f8cf395b74fc4bcdc4e940b74e3ac1f1b13"],["c533e4f7ea8555aacd9777ac5cad29b97dd4defccc53ee7ea204119b2889b197","6f0a256bc5efdf429a2fb6242f1a43a2d9b925bb4a4b3a26bb8e0f45eb596096"],["c14f8f2ccb27d6f109f6d08d03cc96a69ba8c34eec07bbcf566d48e33da6593","c359d6923bb398f7fd4473e16fe1c28475b740dd098075e6c0e8649113dc3a38"],["a6cbc3046bc6a450bac24789fa17115a4c9739ed75f8f21ce441f72e0b90e6ef","21ae7f4680e889bb130619e2c0f95a360ceb573c70603139862afd617fa9b9f"],["347d6d9a02c48927ebfb86c1359b1caf130a3c0267d11ce6344b39f99d43cc38","60ea7f61a353524d1c987f6ecec92f086d565ab687870cb12689ff1e31c74448"],["da6545d2181db8d983f7dcb375ef5866d47c67b1bf31c8cf855ef7437b72656a","49b96715ab6878a79e78f07ce5680c5d6673051b4935bd897fea824b77dc208a"],["c40747cc9d012cb1a13b8148309c6de7ec25d6945d657146b9d5994b8feb1111","5ca560753be2a12fc6de6caf2cb489565db936156b9514e1bb5e83037e0fa2d4"],["4e42c8ec82c99798ccf3a610be870e78338c7f713348bd34c8203ef4037f3502","7571d74ee5e0fb92a7a8b33a07783341a5492144cc54bcc40a94473693606437"],["3775ab7089bc6af823aba2e1af70b236d251cadb0c86743287522a1b3b0dedea","be52d107bcfa09d8bcb9736a828cfa7fac8db17bf7a76a2c42ad961409018cf7"],["cee31cbf7e34ec379d94fb814d3d775ad954595d1314ba8846959e3e82f74e26","8fd64a14c06b589c26b947ae2bcf6bfa0149ef0be14ed4d80f448a01c43b1c6d"],["b4f9eaea09b6917619f6ea6a4eb5464efddb58fd45b1ebefcdc1a01d08b47986","39e5c9925b5a54b07433a4f18c61726f8bb131c012ca542eb24a8ac07200682a"],["d4263dfc3d2df923a0179a48966d30ce84e2515afc3dccc1b77907792ebcc60e","62dfaf07a0f78feb30e30d6295853ce189e127760ad6cf7fae164e122a208d54"],["48457524820fa65a4f8d35eb6930857c0032acc0a4a2de422233eeda897612c4","25a748ab367979d98733c38a1fa1c2e7dc6cc07db2d60a9ae7a76aaa49bd0f77"],["dfeeef1881101f2cb11644f3a2afdfc2045e19919152923f367a1767c11cceda","ecfb7056cf1de042f9420bab396793c0c390bde74b4bbdff16a83ae09a9a7517"],["6d7ef6b17543f8373c573f44e1f389835d89bcbc6062ced36c82df83b8fae859","cd450ec335438986dfefa10c57fea9bcc521a0959b2d80bbf74b190dca712d10"],["e75605d59102a5a2684500d3b991f2e3f3c88b93225547035af25af66e04541f","f5c54754a8f71ee540b9b48728473e314f729ac5308b06938360990e2bfad125"],["eb98660f4c4dfaa06a2be453d5020bc99a0c2e60abe388457dd43fefb1ed620c","6cb9a8876d9cb8520609af3add26cd20a0a7cd8a9411131ce85f44100099223e"],["13e87b027d8514d35939f2e6892b19922154596941888336dc3563e3b8dba942","fef5a3c68059a6dec5d624114bf1e91aac2b9da568d6abeb2570d55646b8adf1"],["ee163026e9fd6fe017c38f06a5be6fc125424b371ce2708e7bf4491691e5764a","1acb250f255dd61c43d94ccc670d0f58f49ae3fa15b96623e5430da0ad6c62b2"],["b268f5ef9ad51e4d78de3a750c2dc89b1e626d43505867999932e5db33af3d80","5f310d4b3c99b9ebb19f77d41c1dee018cf0d34fd4191614003e945a1216e423"],["ff07f3118a9df035e9fad85eb6c7bfe42b02f01ca99ceea3bf7ffdba93c4750d","438136d603e858a3a5c440c38eccbaddc1d2942114e2eddd4740d098ced1f0d8"],["8d8b9855c7c052a34146fd20ffb658bea4b9f69e0d825ebec16e8c3ce2b526a1","cdb559eedc2d79f926baf44fb84ea4d44bcf50fee51d7ceb30e2e7f463036758"],["52db0b5384dfbf05bfa9d472d7ae26dfe4b851ceca91b1eba54263180da32b63","c3b997d050ee5d423ebaf66a6db9f57b3180c902875679de924b69d84a7b375"],["e62f9490d3d51da6395efd24e80919cc7d0f29c3f3fa48c6fff543becbd43352","6d89ad7ba4876b0b22c2ca280c682862f342c8591f1daf5170e07bfd9ccafa7d"],["7f30ea2476b399b4957509c88f77d0191afa2ff5cb7b14fd6d8e7d65aaab1193","ca5ef7d4b231c94c3b15389a5f6311e9daff7bb67b103e9880ef4bff637acaec"],["5098ff1e1d9f14fb46a210fada6c903fef0fb7b4a1dd1d9ac60a0361800b7a00","9731141d81fc8f8084d37c6e7542006b3ee1b40d60dfe5362a5b132fd17ddc0"],["32b78c7de9ee512a72895be6b9cbefa6e2f3c4ccce445c96b9f2c81e2778ad58","ee1849f513df71e32efc3896ee28260c73bb80547ae2275ba497237794c8753c"],["e2cb74fddc8e9fbcd076eef2a7c72b0ce37d50f08269dfc074b581550547a4f7","d3aa2ed71c9dd2247a62df062736eb0baddea9e36122d2be8641abcb005cc4a4"],["8438447566d4d7bedadc299496ab357426009a35f235cb141be0d99cd10ae3a8","c4e1020916980a4da5d01ac5e6ad330734ef0d7906631c4f2390426b2edd791f"],["4162d488b89402039b584c6fc6c308870587d9c46f660b878ab65c82c711d67e","67163e903236289f776f22c25fb8a3afc1732f2b84b4e95dbda47ae5a0852649"],["3fad3fa84caf0f34f0f89bfd2dcf54fc175d767aec3e50684f3ba4a4bf5f683d","cd1bc7cb6cc407bb2f0ca647c718a730cf71872e7d0d2a53fa20efcdfe61826"],["674f2600a3007a00568c1a7ce05d0816c1fb84bf1370798f1c69532faeb1a86b","299d21f9413f33b3edf43b257004580b70db57da0b182259e09eecc69e0d38a5"],["d32f4da54ade74abb81b815ad1fb3b263d82d6c692714bcff87d29bd5ee9f08f","f9429e738b8e53b968e99016c059707782e14f4535359d582fc416910b3eea87"],["30e4e670435385556e593657135845d36fbb6931f72b08cb1ed954f1e3ce3ff6","462f9bce619898638499350113bbc9b10a878d35da70740dc695a559eb88db7b"],["be2062003c51cc3004682904330e4dee7f3dcd10b01e580bf1971b04d4cad297","62188bc49d61e5428573d48a74e1c655b1c61090905682a0d5558ed72dccb9bc"],["93144423ace3451ed29e0fb9ac2af211cb6e84a601df5993c419859fff5df04a","7c10dfb164c3425f5c71a3f9d7992038f1065224f72bb9d1d902a6d13037b47c"],["b015f8044f5fcbdcf21ca26d6c34fb8197829205c7b7d2a7cb66418c157b112c","ab8c1e086d04e813744a655b2df8d5f83b3cdc6faa3088c1d3aea1454e3a1d5f"],["d5e9e1da649d97d89e4868117a465a3a4f8a18de57a140d36b3f2af341a21b52","4cb04437f391ed73111a13cc1d4dd0db1693465c2240480d8955e8592f27447a"],["d3ae41047dd7ca065dbf8ed77b992439983005cd72e16d6f996a5316d36966bb","bd1aeb21ad22ebb22a10f0303417c6d964f8cdd7df0aca614b10dc14d125ac46"],["463e2763d885f958fc66cdd22800f0a487197d0a82e377b49f80af87c897b065","bfefacdb0e5d0fd7df3a311a94de062b26b80c61fbc97508b79992671ef7ca7f"],["7985fdfd127c0567c6f53ec1bb63ec3158e597c40bfe747c83cddfc910641917","603c12daf3d9862ef2b25fe1de289aed24ed291e0ec6708703a5bd567f32ed03"],["74a1ad6b5f76e39db2dd249410eac7f99e74c59cb83d2d0ed5ff1543da7703e9","cc6157ef18c9c63cd6193d83631bbea0093e0968942e8c33d5737fd790e0db08"],["30682a50703375f602d416664ba19b7fc9bab42c72747463a71d0896b22f6da3","553e04f6b018b4fa6c8f39e7f311d3176290d0e0f19ca73f17714d9977a22ff8"],["9e2158f0d7c0d5f26c3791efefa79597654e7a2b2464f52b1ee6c1347769ef57","712fcdd1b9053f09003a3481fa7762e9ffd7c8ef35a38509e2fbf2629008373"],["176e26989a43c9cfeba4029c202538c28172e566e3c4fce7322857f3be327d66","ed8cc9d04b29eb877d270b4878dc43c19aefd31f4eee09ee7b47834c1fa4b1c3"],["75d46efea3771e6e68abb89a13ad747ecf1892393dfc4f1b7004788c50374da8","9852390a99507679fd0b86fd2b39a868d7efc22151346e1a3ca4726586a6bed8"],["809a20c67d64900ffb698c4c825f6d5f2310fb0451c869345b7319f645605721","9e994980d9917e22b76b061927fa04143d096ccc54963e6a5ebfa5f3f8e286c1"],["1b38903a43f7f114ed4500b4eac7083fdefece1cf29c63528d563446f972c180","4036edc931a60ae889353f77fd53de4a2708b26b6f5da72ad3394119daf408f9"]]}}},80953:(e,t,n)=>{"use strict";var o=t,r=n(73785),i=n(79746),a=n(34504);o.assert=i,o.toArray=a.toArray,o.zero2=a.zero2,o.toHex=a.toHex,o.encode=a.encode,o.getNAF=function(e,t,n){var o=new Array(Math.max(e.bitLength(),n)+1);o.fill(0);for(var r=1<(r>>1)-1?(r>>1)-u:u,i.isubn(s)):s=0,o[a]=s,i.iushrn(1)}return o},o.getJSF=function(e,t){var n=[[],[]];e=e.clone(),t=t.clone();for(var o,r=0,i=0;e.cmpn(-r)>0||t.cmpn(-i)>0;){var a,s,u=e.andln(3)+r&3,c=t.andln(3)+i&3;3===u&&(u=-1),3===c&&(c=-1),a=0==(1&u)?0:3!=(o=e.andln(7)+r&7)&&5!==o||2!==c?u:-u,n[0].push(a),s=0==(1&c)?0:3!=(o=t.andln(7)+i&7)&&5!==o||2!==u?c:-c,n[1].push(s),2*r===a+1&&(r=1-r),2*i===s+1&&(i=1-i),e.iushrn(1),t.iushrn(1)}return n},o.cachedProperty=function(e,t,n){var o="_"+t;e.prototype[t]=function(){return void 0!==this[o]?this[o]:this[o]=n.call(this)}},o.parseBytes=function(e){return"string"==typeof e?o.toArray(e,"hex"):e},o.intFromLE=function(e){return new r(e,"hex","le")}},73785:function(e,t,n){!function(e,t){"use strict";function o(e,t){if(!e)throw new Error(t||"Assertion failed")}function r(e,t){e.super_=t;var n=function(){};n.prototype=t.prototype,e.prototype=new n,e.prototype.constructor=e}function i(e,t,n){if(i.isBN(e))return e;this.negative=0,this.words=null,this.length=0,this.red=null,null!==e&&("le"!==t&&"be"!==t||(n=t,t=10),this._init(e||0,t||10,n||"be"))}var a;"object"==typeof e?e.exports=i:t.BN=i,i.BN=i,i.wordSize=26;try{a="undefined"!=typeof window&&void 0!==window.Buffer?window.Buffer:n(85568).Buffer}catch(e){}function s(e,t){var n=e.charCodeAt(t);return n>=65&&n<=70?n-55:n>=97&&n<=102?n-87:n-48&15}function u(e,t,n){var o=s(e,n);return n-1>=t&&(o|=s(e,n-1)<<4),o}function c(e,t,n,o){for(var r=0,i=Math.min(e.length,n),a=t;a=49?s-49+10:s>=17?s-17+10:s}return r}i.isBN=function(e){return e instanceof i||null!==e&&"object"==typeof e&&e.constructor.wordSize===i.wordSize&&Array.isArray(e.words)},i.max=function(e,t){return e.cmp(t)>0?e:t},i.min=function(e,t){return e.cmp(t)<0?e:t},i.prototype._init=function(e,t,n){if("number"==typeof e)return this._initNumber(e,t,n);if("object"==typeof e)return this._initArray(e,t,n);"hex"===t&&(t=16),o(t===(0|t)&&t>=2&&t<=36);var r=0;"-"===(e=e.toString().replace(/\s+/g,""))[0]&&(r++,this.negative=1),r=0;r-=3)a=e[r]|e[r-1]<<8|e[r-2]<<16,this.words[i]|=a<>>26-s&67108863,(s+=24)>=26&&(s-=26,i++);else if("le"===n)for(r=0,i=0;r>>26-s&67108863,(s+=24)>=26&&(s-=26,i++);return this.strip()},i.prototype._parseHex=function(e,t,n){this.length=Math.ceil((e.length-t)/6),this.words=new Array(this.length);for(var o=0;o=t;o-=2)r=u(e,t,o)<=18?(i-=18,a+=1,this.words[a]|=r>>>26):i+=8;else for(o=(e.length-t)%2==0?t+1:t;o=18?(i-=18,a+=1,this.words[a]|=r>>>26):i+=8;this.strip()},i.prototype._parseBase=function(e,t,n){this.words=[0],this.length=1;for(var o=0,r=1;r<=67108863;r*=t)o++;o--,r=r/t|0;for(var i=e.length-n,a=i%o,s=Math.min(i,i-a)+n,u=0,l=n;l1&&0===this.words[this.length-1];)this.length--;return this._normSign()},i.prototype._normSign=function(){return 1===this.length&&0===this.words[0]&&(this.negative=0),this},i.prototype.inspect=function(){return(this.red?""};var l=["","0","00","000","0000","00000","000000","0000000","00000000","000000000","0000000000","00000000000","000000000000","0000000000000","00000000000000","000000000000000","0000000000000000","00000000000000000","000000000000000000","0000000000000000000","00000000000000000000","000000000000000000000","0000000000000000000000","00000000000000000000000","000000000000000000000000","0000000000000000000000000"],d=[0,0,25,16,12,11,10,9,8,8,7,7,7,7,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5],h=[0,0,33554432,43046721,16777216,48828125,60466176,40353607,16777216,43046721,1e7,19487171,35831808,62748517,7529536,11390625,16777216,24137569,34012224,47045881,64e6,4084101,5153632,6436343,7962624,9765625,11881376,14348907,17210368,20511149,243e5,28629151,33554432,39135393,45435424,52521875,60466176];function p(e,t,n){n.negative=t.negative^e.negative;var o=e.length+t.length|0;n.length=o,o=o-1|0;var r=0|e.words[0],i=0|t.words[0],a=r*i,s=67108863&a,u=a/67108864|0;n.words[0]=s;for(var c=1;c>>26,d=67108863&u,h=Math.min(c,t.length-1),p=Math.max(0,c-e.length+1);p<=h;p++){var f=c-p|0;l+=(a=(r=0|e.words[f])*(i=0|t.words[p])+d)/67108864|0,d=67108863&a}n.words[c]=0|d,u=0|l}return 0!==u?n.words[c]=0|u:n.length--,n.strip()}i.prototype.toString=function(e,t){var n;if(t=0|t||1,16===(e=e||10)||"hex"===e){n="";for(var r=0,i=0,a=0;a>>24-r&16777215)||a!==this.length-1?l[6-u.length]+u+n:u+n,(r+=2)>=26&&(r-=26,a--)}for(0!==i&&(n=i.toString(16)+n);n.length%t!=0;)n="0"+n;return 0!==this.negative&&(n="-"+n),n}if(e===(0|e)&&e>=2&&e<=36){var c=d[e],p=h[e];n="";var f=this.clone();for(f.negative=0;!f.isZero();){var g=f.modn(p).toString(e);n=(f=f.idivn(p)).isZero()?g+n:l[c-g.length]+g+n}for(this.isZero()&&(n="0"+n);n.length%t!=0;)n="0"+n;return 0!==this.negative&&(n="-"+n),n}o(!1,"Base should be between 2 and 36")},i.prototype.toNumber=function(){var e=this.words[0];return 2===this.length?e+=67108864*this.words[1]:3===this.length&&1===this.words[2]?e+=4503599627370496+67108864*this.words[1]:this.length>2&&o(!1,"Number can only safely store up to 53 bits"),0!==this.negative?-e:e},i.prototype.toJSON=function(){return this.toString(16)},i.prototype.toBuffer=function(e,t){return o(void 0!==a),this.toArrayLike(a,e,t)},i.prototype.toArray=function(e,t){return this.toArrayLike(Array,e,t)},i.prototype.toArrayLike=function(e,t,n){var r=this.byteLength(),i=n||Math.max(1,r);o(r<=i,"byte array longer than desired length"),o(i>0,"Requested array length <= 0"),this.strip();var a,s,u="le"===t,c=new e(i),l=this.clone();if(u){for(s=0;!l.isZero();s++)a=l.andln(255),l.iushrn(8),c[s]=a;for(;s=4096&&(n+=13,t>>>=13),t>=64&&(n+=7,t>>>=7),t>=8&&(n+=4,t>>>=4),t>=2&&(n+=2,t>>>=2),n+t},i.prototype._zeroBits=function(e){if(0===e)return 26;var t=e,n=0;return 0==(8191&t)&&(n+=13,t>>>=13),0==(127&t)&&(n+=7,t>>>=7),0==(15&t)&&(n+=4,t>>>=4),0==(3&t)&&(n+=2,t>>>=2),0==(1&t)&&n++,n},i.prototype.bitLength=function(){var e=this.words[this.length-1],t=this._countBits(e);return 26*(this.length-1)+t},i.prototype.zeroBits=function(){if(this.isZero())return 0;for(var e=0,t=0;te.length?this.clone().ior(e):e.clone().ior(this)},i.prototype.uor=function(e){return this.length>e.length?this.clone().iuor(e):e.clone().iuor(this)},i.prototype.iuand=function(e){var t;t=this.length>e.length?e:this;for(var n=0;ne.length?this.clone().iand(e):e.clone().iand(this)},i.prototype.uand=function(e){return this.length>e.length?this.clone().iuand(e):e.clone().iuand(this)},i.prototype.iuxor=function(e){var t,n;this.length>e.length?(t=this,n=e):(t=e,n=this);for(var o=0;oe.length?this.clone().ixor(e):e.clone().ixor(this)},i.prototype.uxor=function(e){return this.length>e.length?this.clone().iuxor(e):e.clone().iuxor(this)},i.prototype.inotn=function(e){o("number"==typeof e&&e>=0);var t=0|Math.ceil(e/26),n=e%26;this._expand(t),n>0&&t--;for(var r=0;r0&&(this.words[r]=~this.words[r]&67108863>>26-n),this.strip()},i.prototype.notn=function(e){return this.clone().inotn(e)},i.prototype.setn=function(e,t){o("number"==typeof e&&e>=0);var n=e/26|0,r=e%26;return this._expand(n+1),this.words[n]=t?this.words[n]|1<e.length?(n=this,o=e):(n=e,o=this);for(var r=0,i=0;i>>26;for(;0!==r&&i>>26;if(this.length=n.length,0!==r)this.words[this.length]=r,this.length++;else if(n!==this)for(;ie.length?this.clone().iadd(e):e.clone().iadd(this)},i.prototype.isub=function(e){if(0!==e.negative){e.negative=0;var t=this.iadd(e);return e.negative=1,t._normSign()}if(0!==this.negative)return this.negative=0,this.iadd(e),this.negative=1,this._normSign();var n,o,r=this.cmp(e);if(0===r)return this.negative=0,this.length=1,this.words[0]=0,this;r>0?(n=this,o=e):(n=e,o=this);for(var i=0,a=0;a>26,this.words[a]=67108863&t;for(;0!==i&&a>26,this.words[a]=67108863&t;if(0===i&&a>>13,p=0|a[1],f=8191&p,g=p>>>13,m=0|a[2],_=8191&m,F=m>>>13,y=0|a[3],b=8191&y,v=y>>>13,w=0|a[4],E=8191&w,k=w>>>13,D=0|a[5],S=8191&D,x=D>>>13,C=0|a[6],A=8191&C,T=C>>>13,R=0|a[7],I=8191&R,M=R>>>13,O=0|a[8],B=8191&O,N=O>>>13,L=0|a[9],P=8191&L,U=L>>>13,j=0|s[0],q=8191&j,z=j>>>13,K=0|s[1],G=8191&K,$=K>>>13,H=0|s[2],V=8191&H,W=H>>>13,Y=0|s[3],Z=8191&Y,X=Y>>>13,J=0|s[4],Q=8191&J,ee=J>>>13,te=0|s[5],ne=8191&te,oe=te>>>13,re=0|s[6],ie=8191&re,ae=re>>>13,se=0|s[7],ue=8191&se,ce=se>>>13,le=0|s[8],de=8191&le,he=le>>>13,pe=0|s[9],fe=8191&pe,ge=pe>>>13;n.negative=e.negative^t.negative,n.length=19;var me=(c+(o=Math.imul(d,q))|0)+((8191&(r=(r=Math.imul(d,z))+Math.imul(h,q)|0))<<13)|0;c=((i=Math.imul(h,z))+(r>>>13)|0)+(me>>>26)|0,me&=67108863,o=Math.imul(f,q),r=(r=Math.imul(f,z))+Math.imul(g,q)|0,i=Math.imul(g,z);var _e=(c+(o=o+Math.imul(d,G)|0)|0)+((8191&(r=(r=r+Math.imul(d,$)|0)+Math.imul(h,G)|0))<<13)|0;c=((i=i+Math.imul(h,$)|0)+(r>>>13)|0)+(_e>>>26)|0,_e&=67108863,o=Math.imul(_,q),r=(r=Math.imul(_,z))+Math.imul(F,q)|0,i=Math.imul(F,z),o=o+Math.imul(f,G)|0,r=(r=r+Math.imul(f,$)|0)+Math.imul(g,G)|0,i=i+Math.imul(g,$)|0;var Fe=(c+(o=o+Math.imul(d,V)|0)|0)+((8191&(r=(r=r+Math.imul(d,W)|0)+Math.imul(h,V)|0))<<13)|0;c=((i=i+Math.imul(h,W)|0)+(r>>>13)|0)+(Fe>>>26)|0,Fe&=67108863,o=Math.imul(b,q),r=(r=Math.imul(b,z))+Math.imul(v,q)|0,i=Math.imul(v,z),o=o+Math.imul(_,G)|0,r=(r=r+Math.imul(_,$)|0)+Math.imul(F,G)|0,i=i+Math.imul(F,$)|0,o=o+Math.imul(f,V)|0,r=(r=r+Math.imul(f,W)|0)+Math.imul(g,V)|0,i=i+Math.imul(g,W)|0;var ye=(c+(o=o+Math.imul(d,Z)|0)|0)+((8191&(r=(r=r+Math.imul(d,X)|0)+Math.imul(h,Z)|0))<<13)|0;c=((i=i+Math.imul(h,X)|0)+(r>>>13)|0)+(ye>>>26)|0,ye&=67108863,o=Math.imul(E,q),r=(r=Math.imul(E,z))+Math.imul(k,q)|0,i=Math.imul(k,z),o=o+Math.imul(b,G)|0,r=(r=r+Math.imul(b,$)|0)+Math.imul(v,G)|0,i=i+Math.imul(v,$)|0,o=o+Math.imul(_,V)|0,r=(r=r+Math.imul(_,W)|0)+Math.imul(F,V)|0,i=i+Math.imul(F,W)|0,o=o+Math.imul(f,Z)|0,r=(r=r+Math.imul(f,X)|0)+Math.imul(g,Z)|0,i=i+Math.imul(g,X)|0;var be=(c+(o=o+Math.imul(d,Q)|0)|0)+((8191&(r=(r=r+Math.imul(d,ee)|0)+Math.imul(h,Q)|0))<<13)|0;c=((i=i+Math.imul(h,ee)|0)+(r>>>13)|0)+(be>>>26)|0,be&=67108863,o=Math.imul(S,q),r=(r=Math.imul(S,z))+Math.imul(x,q)|0,i=Math.imul(x,z),o=o+Math.imul(E,G)|0,r=(r=r+Math.imul(E,$)|0)+Math.imul(k,G)|0,i=i+Math.imul(k,$)|0,o=o+Math.imul(b,V)|0,r=(r=r+Math.imul(b,W)|0)+Math.imul(v,V)|0,i=i+Math.imul(v,W)|0,o=o+Math.imul(_,Z)|0,r=(r=r+Math.imul(_,X)|0)+Math.imul(F,Z)|0,i=i+Math.imul(F,X)|0,o=o+Math.imul(f,Q)|0,r=(r=r+Math.imul(f,ee)|0)+Math.imul(g,Q)|0,i=i+Math.imul(g,ee)|0;var ve=(c+(o=o+Math.imul(d,ne)|0)|0)+((8191&(r=(r=r+Math.imul(d,oe)|0)+Math.imul(h,ne)|0))<<13)|0;c=((i=i+Math.imul(h,oe)|0)+(r>>>13)|0)+(ve>>>26)|0,ve&=67108863,o=Math.imul(A,q),r=(r=Math.imul(A,z))+Math.imul(T,q)|0,i=Math.imul(T,z),o=o+Math.imul(S,G)|0,r=(r=r+Math.imul(S,$)|0)+Math.imul(x,G)|0,i=i+Math.imul(x,$)|0,o=o+Math.imul(E,V)|0,r=(r=r+Math.imul(E,W)|0)+Math.imul(k,V)|0,i=i+Math.imul(k,W)|0,o=o+Math.imul(b,Z)|0,r=(r=r+Math.imul(b,X)|0)+Math.imul(v,Z)|0,i=i+Math.imul(v,X)|0,o=o+Math.imul(_,Q)|0,r=(r=r+Math.imul(_,ee)|0)+Math.imul(F,Q)|0,i=i+Math.imul(F,ee)|0,o=o+Math.imul(f,ne)|0,r=(r=r+Math.imul(f,oe)|0)+Math.imul(g,ne)|0,i=i+Math.imul(g,oe)|0;var we=(c+(o=o+Math.imul(d,ie)|0)|0)+((8191&(r=(r=r+Math.imul(d,ae)|0)+Math.imul(h,ie)|0))<<13)|0;c=((i=i+Math.imul(h,ae)|0)+(r>>>13)|0)+(we>>>26)|0,we&=67108863,o=Math.imul(I,q),r=(r=Math.imul(I,z))+Math.imul(M,q)|0,i=Math.imul(M,z),o=o+Math.imul(A,G)|0,r=(r=r+Math.imul(A,$)|0)+Math.imul(T,G)|0,i=i+Math.imul(T,$)|0,o=o+Math.imul(S,V)|0,r=(r=r+Math.imul(S,W)|0)+Math.imul(x,V)|0,i=i+Math.imul(x,W)|0,o=o+Math.imul(E,Z)|0,r=(r=r+Math.imul(E,X)|0)+Math.imul(k,Z)|0,i=i+Math.imul(k,X)|0,o=o+Math.imul(b,Q)|0,r=(r=r+Math.imul(b,ee)|0)+Math.imul(v,Q)|0,i=i+Math.imul(v,ee)|0,o=o+Math.imul(_,ne)|0,r=(r=r+Math.imul(_,oe)|0)+Math.imul(F,ne)|0,i=i+Math.imul(F,oe)|0,o=o+Math.imul(f,ie)|0,r=(r=r+Math.imul(f,ae)|0)+Math.imul(g,ie)|0,i=i+Math.imul(g,ae)|0;var Ee=(c+(o=o+Math.imul(d,ue)|0)|0)+((8191&(r=(r=r+Math.imul(d,ce)|0)+Math.imul(h,ue)|0))<<13)|0;c=((i=i+Math.imul(h,ce)|0)+(r>>>13)|0)+(Ee>>>26)|0,Ee&=67108863,o=Math.imul(B,q),r=(r=Math.imul(B,z))+Math.imul(N,q)|0,i=Math.imul(N,z),o=o+Math.imul(I,G)|0,r=(r=r+Math.imul(I,$)|0)+Math.imul(M,G)|0,i=i+Math.imul(M,$)|0,o=o+Math.imul(A,V)|0,r=(r=r+Math.imul(A,W)|0)+Math.imul(T,V)|0,i=i+Math.imul(T,W)|0,o=o+Math.imul(S,Z)|0,r=(r=r+Math.imul(S,X)|0)+Math.imul(x,Z)|0,i=i+Math.imul(x,X)|0,o=o+Math.imul(E,Q)|0,r=(r=r+Math.imul(E,ee)|0)+Math.imul(k,Q)|0,i=i+Math.imul(k,ee)|0,o=o+Math.imul(b,ne)|0,r=(r=r+Math.imul(b,oe)|0)+Math.imul(v,ne)|0,i=i+Math.imul(v,oe)|0,o=o+Math.imul(_,ie)|0,r=(r=r+Math.imul(_,ae)|0)+Math.imul(F,ie)|0,i=i+Math.imul(F,ae)|0,o=o+Math.imul(f,ue)|0,r=(r=r+Math.imul(f,ce)|0)+Math.imul(g,ue)|0,i=i+Math.imul(g,ce)|0;var ke=(c+(o=o+Math.imul(d,de)|0)|0)+((8191&(r=(r=r+Math.imul(d,he)|0)+Math.imul(h,de)|0))<<13)|0;c=((i=i+Math.imul(h,he)|0)+(r>>>13)|0)+(ke>>>26)|0,ke&=67108863,o=Math.imul(P,q),r=(r=Math.imul(P,z))+Math.imul(U,q)|0,i=Math.imul(U,z),o=o+Math.imul(B,G)|0,r=(r=r+Math.imul(B,$)|0)+Math.imul(N,G)|0,i=i+Math.imul(N,$)|0,o=o+Math.imul(I,V)|0,r=(r=r+Math.imul(I,W)|0)+Math.imul(M,V)|0,i=i+Math.imul(M,W)|0,o=o+Math.imul(A,Z)|0,r=(r=r+Math.imul(A,X)|0)+Math.imul(T,Z)|0,i=i+Math.imul(T,X)|0,o=o+Math.imul(S,Q)|0,r=(r=r+Math.imul(S,ee)|0)+Math.imul(x,Q)|0,i=i+Math.imul(x,ee)|0,o=o+Math.imul(E,ne)|0,r=(r=r+Math.imul(E,oe)|0)+Math.imul(k,ne)|0,i=i+Math.imul(k,oe)|0,o=o+Math.imul(b,ie)|0,r=(r=r+Math.imul(b,ae)|0)+Math.imul(v,ie)|0,i=i+Math.imul(v,ae)|0,o=o+Math.imul(_,ue)|0,r=(r=r+Math.imul(_,ce)|0)+Math.imul(F,ue)|0,i=i+Math.imul(F,ce)|0,o=o+Math.imul(f,de)|0,r=(r=r+Math.imul(f,he)|0)+Math.imul(g,de)|0,i=i+Math.imul(g,he)|0;var De=(c+(o=o+Math.imul(d,fe)|0)|0)+((8191&(r=(r=r+Math.imul(d,ge)|0)+Math.imul(h,fe)|0))<<13)|0;c=((i=i+Math.imul(h,ge)|0)+(r>>>13)|0)+(De>>>26)|0,De&=67108863,o=Math.imul(P,G),r=(r=Math.imul(P,$))+Math.imul(U,G)|0,i=Math.imul(U,$),o=o+Math.imul(B,V)|0,r=(r=r+Math.imul(B,W)|0)+Math.imul(N,V)|0,i=i+Math.imul(N,W)|0,o=o+Math.imul(I,Z)|0,r=(r=r+Math.imul(I,X)|0)+Math.imul(M,Z)|0,i=i+Math.imul(M,X)|0,o=o+Math.imul(A,Q)|0,r=(r=r+Math.imul(A,ee)|0)+Math.imul(T,Q)|0,i=i+Math.imul(T,ee)|0,o=o+Math.imul(S,ne)|0,r=(r=r+Math.imul(S,oe)|0)+Math.imul(x,ne)|0,i=i+Math.imul(x,oe)|0,o=o+Math.imul(E,ie)|0,r=(r=r+Math.imul(E,ae)|0)+Math.imul(k,ie)|0,i=i+Math.imul(k,ae)|0,o=o+Math.imul(b,ue)|0,r=(r=r+Math.imul(b,ce)|0)+Math.imul(v,ue)|0,i=i+Math.imul(v,ce)|0,o=o+Math.imul(_,de)|0,r=(r=r+Math.imul(_,he)|0)+Math.imul(F,de)|0,i=i+Math.imul(F,he)|0;var Se=(c+(o=o+Math.imul(f,fe)|0)|0)+((8191&(r=(r=r+Math.imul(f,ge)|0)+Math.imul(g,fe)|0))<<13)|0;c=((i=i+Math.imul(g,ge)|0)+(r>>>13)|0)+(Se>>>26)|0,Se&=67108863,o=Math.imul(P,V),r=(r=Math.imul(P,W))+Math.imul(U,V)|0,i=Math.imul(U,W),o=o+Math.imul(B,Z)|0,r=(r=r+Math.imul(B,X)|0)+Math.imul(N,Z)|0,i=i+Math.imul(N,X)|0,o=o+Math.imul(I,Q)|0,r=(r=r+Math.imul(I,ee)|0)+Math.imul(M,Q)|0,i=i+Math.imul(M,ee)|0,o=o+Math.imul(A,ne)|0,r=(r=r+Math.imul(A,oe)|0)+Math.imul(T,ne)|0,i=i+Math.imul(T,oe)|0,o=o+Math.imul(S,ie)|0,r=(r=r+Math.imul(S,ae)|0)+Math.imul(x,ie)|0,i=i+Math.imul(x,ae)|0,o=o+Math.imul(E,ue)|0,r=(r=r+Math.imul(E,ce)|0)+Math.imul(k,ue)|0,i=i+Math.imul(k,ce)|0,o=o+Math.imul(b,de)|0,r=(r=r+Math.imul(b,he)|0)+Math.imul(v,de)|0,i=i+Math.imul(v,he)|0;var xe=(c+(o=o+Math.imul(_,fe)|0)|0)+((8191&(r=(r=r+Math.imul(_,ge)|0)+Math.imul(F,fe)|0))<<13)|0;c=((i=i+Math.imul(F,ge)|0)+(r>>>13)|0)+(xe>>>26)|0,xe&=67108863,o=Math.imul(P,Z),r=(r=Math.imul(P,X))+Math.imul(U,Z)|0,i=Math.imul(U,X),o=o+Math.imul(B,Q)|0,r=(r=r+Math.imul(B,ee)|0)+Math.imul(N,Q)|0,i=i+Math.imul(N,ee)|0,o=o+Math.imul(I,ne)|0,r=(r=r+Math.imul(I,oe)|0)+Math.imul(M,ne)|0,i=i+Math.imul(M,oe)|0,o=o+Math.imul(A,ie)|0,r=(r=r+Math.imul(A,ae)|0)+Math.imul(T,ie)|0,i=i+Math.imul(T,ae)|0,o=o+Math.imul(S,ue)|0,r=(r=r+Math.imul(S,ce)|0)+Math.imul(x,ue)|0,i=i+Math.imul(x,ce)|0,o=o+Math.imul(E,de)|0,r=(r=r+Math.imul(E,he)|0)+Math.imul(k,de)|0,i=i+Math.imul(k,he)|0;var Ce=(c+(o=o+Math.imul(b,fe)|0)|0)+((8191&(r=(r=r+Math.imul(b,ge)|0)+Math.imul(v,fe)|0))<<13)|0;c=((i=i+Math.imul(v,ge)|0)+(r>>>13)|0)+(Ce>>>26)|0,Ce&=67108863,o=Math.imul(P,Q),r=(r=Math.imul(P,ee))+Math.imul(U,Q)|0,i=Math.imul(U,ee),o=o+Math.imul(B,ne)|0,r=(r=r+Math.imul(B,oe)|0)+Math.imul(N,ne)|0,i=i+Math.imul(N,oe)|0,o=o+Math.imul(I,ie)|0,r=(r=r+Math.imul(I,ae)|0)+Math.imul(M,ie)|0,i=i+Math.imul(M,ae)|0,o=o+Math.imul(A,ue)|0,r=(r=r+Math.imul(A,ce)|0)+Math.imul(T,ue)|0,i=i+Math.imul(T,ce)|0,o=o+Math.imul(S,de)|0,r=(r=r+Math.imul(S,he)|0)+Math.imul(x,de)|0,i=i+Math.imul(x,he)|0;var Ae=(c+(o=o+Math.imul(E,fe)|0)|0)+((8191&(r=(r=r+Math.imul(E,ge)|0)+Math.imul(k,fe)|0))<<13)|0;c=((i=i+Math.imul(k,ge)|0)+(r>>>13)|0)+(Ae>>>26)|0,Ae&=67108863,o=Math.imul(P,ne),r=(r=Math.imul(P,oe))+Math.imul(U,ne)|0,i=Math.imul(U,oe),o=o+Math.imul(B,ie)|0,r=(r=r+Math.imul(B,ae)|0)+Math.imul(N,ie)|0,i=i+Math.imul(N,ae)|0,o=o+Math.imul(I,ue)|0,r=(r=r+Math.imul(I,ce)|0)+Math.imul(M,ue)|0,i=i+Math.imul(M,ce)|0,o=o+Math.imul(A,de)|0,r=(r=r+Math.imul(A,he)|0)+Math.imul(T,de)|0,i=i+Math.imul(T,he)|0;var Te=(c+(o=o+Math.imul(S,fe)|0)|0)+((8191&(r=(r=r+Math.imul(S,ge)|0)+Math.imul(x,fe)|0))<<13)|0;c=((i=i+Math.imul(x,ge)|0)+(r>>>13)|0)+(Te>>>26)|0,Te&=67108863,o=Math.imul(P,ie),r=(r=Math.imul(P,ae))+Math.imul(U,ie)|0,i=Math.imul(U,ae),o=o+Math.imul(B,ue)|0,r=(r=r+Math.imul(B,ce)|0)+Math.imul(N,ue)|0,i=i+Math.imul(N,ce)|0,o=o+Math.imul(I,de)|0,r=(r=r+Math.imul(I,he)|0)+Math.imul(M,de)|0,i=i+Math.imul(M,he)|0;var Re=(c+(o=o+Math.imul(A,fe)|0)|0)+((8191&(r=(r=r+Math.imul(A,ge)|0)+Math.imul(T,fe)|0))<<13)|0;c=((i=i+Math.imul(T,ge)|0)+(r>>>13)|0)+(Re>>>26)|0,Re&=67108863,o=Math.imul(P,ue),r=(r=Math.imul(P,ce))+Math.imul(U,ue)|0,i=Math.imul(U,ce),o=o+Math.imul(B,de)|0,r=(r=r+Math.imul(B,he)|0)+Math.imul(N,de)|0,i=i+Math.imul(N,he)|0;var Ie=(c+(o=o+Math.imul(I,fe)|0)|0)+((8191&(r=(r=r+Math.imul(I,ge)|0)+Math.imul(M,fe)|0))<<13)|0;c=((i=i+Math.imul(M,ge)|0)+(r>>>13)|0)+(Ie>>>26)|0,Ie&=67108863,o=Math.imul(P,de),r=(r=Math.imul(P,he))+Math.imul(U,de)|0,i=Math.imul(U,he);var Me=(c+(o=o+Math.imul(B,fe)|0)|0)+((8191&(r=(r=r+Math.imul(B,ge)|0)+Math.imul(N,fe)|0))<<13)|0;c=((i=i+Math.imul(N,ge)|0)+(r>>>13)|0)+(Me>>>26)|0,Me&=67108863;var Oe=(c+(o=Math.imul(P,fe))|0)+((8191&(r=(r=Math.imul(P,ge))+Math.imul(U,fe)|0))<<13)|0;return c=((i=Math.imul(U,ge))+(r>>>13)|0)+(Oe>>>26)|0,Oe&=67108863,u[0]=me,u[1]=_e,u[2]=Fe,u[3]=ye,u[4]=be,u[5]=ve,u[6]=we,u[7]=Ee,u[8]=ke,u[9]=De,u[10]=Se,u[11]=xe,u[12]=Ce,u[13]=Ae,u[14]=Te,u[15]=Re,u[16]=Ie,u[17]=Me,u[18]=Oe,0!==c&&(u[19]=c,n.length++),n};function g(e,t,n){return(new m).mulp(e,t,n)}function m(e,t){this.x=e,this.y=t}Math.imul||(f=p),i.prototype.mulTo=function(e,t){var n=this.length+e.length;return 10===this.length&&10===e.length?f(this,e,t):n<63?p(this,e,t):n<1024?function(e,t,n){n.negative=t.negative^e.negative,n.length=e.length+t.length;for(var o=0,r=0,i=0;i>>26)|0)>>>26,a&=67108863}n.words[i]=s,o=a,a=r}return 0!==o?n.words[i]=o:n.length--,n.strip()}(this,e,t):g(this,e,t)},m.prototype.makeRBT=function(e){for(var t=new Array(e),n=i.prototype._countBits(e)-1,o=0;o>=1;return o},m.prototype.permute=function(e,t,n,o,r,i){for(var a=0;a>>=1)r++;return 1<>>=13,n[2*a+1]=8191&i,i>>>=13;for(a=2*t;a>=26,t+=r/67108864|0,t+=i>>>26,this.words[n]=67108863&i}return 0!==t&&(this.words[n]=t,this.length++),this},i.prototype.muln=function(e){return this.clone().imuln(e)},i.prototype.sqr=function(){return this.mul(this)},i.prototype.isqr=function(){return this.imul(this.clone())},i.prototype.pow=function(e){var t=function(e){for(var t=new Array(e.bitLength()),n=0;n>>r}return t}(e);if(0===t.length)return new i(1);for(var n=this,o=0;o=0);var t,n=e%26,r=(e-n)/26,i=67108863>>>26-n<<26-n;if(0!==n){var a=0;for(t=0;t>>26-n}a&&(this.words[t]=a,this.length++)}if(0!==r){for(t=this.length-1;t>=0;t--)this.words[t+r]=this.words[t];for(t=0;t=0),r=t?(t-t%26)/26:0;var i=e%26,a=Math.min((e-i)/26,this.length),s=67108863^67108863>>>i<a)for(this.length-=a,c=0;c=0&&(0!==l||c>=r);c--){var d=0|this.words[c];this.words[c]=l<<26-i|d>>>i,l=d&s}return u&&0!==l&&(u.words[u.length++]=l),0===this.length&&(this.words[0]=0,this.length=1),this.strip()},i.prototype.ishrn=function(e,t,n){return o(0===this.negative),this.iushrn(e,t,n)},i.prototype.shln=function(e){return this.clone().ishln(e)},i.prototype.ushln=function(e){return this.clone().iushln(e)},i.prototype.shrn=function(e){return this.clone().ishrn(e)},i.prototype.ushrn=function(e){return this.clone().iushrn(e)},i.prototype.testn=function(e){o("number"==typeof e&&e>=0);var t=e%26,n=(e-t)/26,r=1<=0);var t=e%26,n=(e-t)/26;if(o(0===this.negative,"imaskn works only with positive numbers"),this.length<=n)return this;if(0!==t&&n++,this.length=Math.min(n,this.length),0!==t){var r=67108863^67108863>>>t<=67108864;t++)this.words[t]-=67108864,t===this.length-1?this.words[t+1]=1:this.words[t+1]++;return this.length=Math.max(this.length,t+1),this},i.prototype.isubn=function(e){if(o("number"==typeof e),o(e<67108864),e<0)return this.iaddn(-e);if(0!==this.negative)return this.negative=0,this.iaddn(e),this.negative=1,this;if(this.words[0]-=e,1===this.length&&this.words[0]<0)this.words[0]=-this.words[0],this.negative=1;else for(var t=0;t>26)-(u/67108864|0),this.words[r+n]=67108863&i}for(;r>26,this.words[r+n]=67108863&i;if(0===s)return this.strip();for(o(-1===s),s=0,r=0;r>26,this.words[r]=67108863&i;return this.negative=1,this.strip()},i.prototype._wordDiv=function(e,t){var n=(this.length,e.length),o=this.clone(),r=e,a=0|r.words[r.length-1];0!=(n=26-this._countBits(a))&&(r=r.ushln(n),o.iushln(n),a=0|r.words[r.length-1]);var s,u=o.length-r.length;if("mod"!==t){(s=new i(null)).length=u+1,s.words=new Array(s.length);for(var c=0;c=0;d--){var h=67108864*(0|o.words[r.length+d])+(0|o.words[r.length+d-1]);for(h=Math.min(h/a|0,67108863),o._ishlnsubmul(r,h,d);0!==o.negative;)h--,o.negative=0,o._ishlnsubmul(r,1,d),o.isZero()||(o.negative^=1);s&&(s.words[d]=h)}return s&&s.strip(),o.strip(),"div"!==t&&0!==n&&o.iushrn(n),{div:s||null,mod:o}},i.prototype.divmod=function(e,t,n){return o(!e.isZero()),this.isZero()?{div:new i(0),mod:new i(0)}:0!==this.negative&&0===e.negative?(s=this.neg().divmod(e,t),"mod"!==t&&(r=s.div.neg()),"div"!==t&&(a=s.mod.neg(),n&&0!==a.negative&&a.iadd(e)),{div:r,mod:a}):0===this.negative&&0!==e.negative?(s=this.divmod(e.neg(),t),"mod"!==t&&(r=s.div.neg()),{div:r,mod:s.mod}):0!=(this.negative&e.negative)?(s=this.neg().divmod(e.neg(),t),"div"!==t&&(a=s.mod.neg(),n&&0!==a.negative&&a.isub(e)),{div:s.div,mod:a}):e.length>this.length||this.cmp(e)<0?{div:new i(0),mod:this}:1===e.length?"div"===t?{div:this.divn(e.words[0]),mod:null}:"mod"===t?{div:null,mod:new i(this.modn(e.words[0]))}:{div:this.divn(e.words[0]),mod:new i(this.modn(e.words[0]))}:this._wordDiv(e,t);var r,a,s},i.prototype.div=function(e){return this.divmod(e,"div",!1).div},i.prototype.mod=function(e){return this.divmod(e,"mod",!1).mod},i.prototype.umod=function(e){return this.divmod(e,"mod",!0).mod},i.prototype.divRound=function(e){var t=this.divmod(e);if(t.mod.isZero())return t.div;var n=0!==t.div.negative?t.mod.isub(e):t.mod,o=e.ushrn(1),r=e.andln(1),i=n.cmp(o);return i<0||1===r&&0===i?t.div:0!==t.div.negative?t.div.isubn(1):t.div.iaddn(1)},i.prototype.modn=function(e){o(e<=67108863);for(var t=(1<<26)%e,n=0,r=this.length-1;r>=0;r--)n=(t*n+(0|this.words[r]))%e;return n},i.prototype.idivn=function(e){o(e<=67108863);for(var t=0,n=this.length-1;n>=0;n--){var r=(0|this.words[n])+67108864*t;this.words[n]=r/e|0,t=r%e}return this.strip()},i.prototype.divn=function(e){return this.clone().idivn(e)},i.prototype.egcd=function(e){o(0===e.negative),o(!e.isZero());var t=this,n=e.clone();t=0!==t.negative?t.umod(e):t.clone();for(var r=new i(1),a=new i(0),s=new i(0),u=new i(1),c=0;t.isEven()&&n.isEven();)t.iushrn(1),n.iushrn(1),++c;for(var l=n.clone(),d=t.clone();!t.isZero();){for(var h=0,p=1;0==(t.words[0]&p)&&h<26;++h,p<<=1);if(h>0)for(t.iushrn(h);h-- >0;)(r.isOdd()||a.isOdd())&&(r.iadd(l),a.isub(d)),r.iushrn(1),a.iushrn(1);for(var f=0,g=1;0==(n.words[0]&g)&&f<26;++f,g<<=1);if(f>0)for(n.iushrn(f);f-- >0;)(s.isOdd()||u.isOdd())&&(s.iadd(l),u.isub(d)),s.iushrn(1),u.iushrn(1);t.cmp(n)>=0?(t.isub(n),r.isub(s),a.isub(u)):(n.isub(t),s.isub(r),u.isub(a))}return{a:s,b:u,gcd:n.iushln(c)}},i.prototype._invmp=function(e){o(0===e.negative),o(!e.isZero());var t=this,n=e.clone();t=0!==t.negative?t.umod(e):t.clone();for(var r,a=new i(1),s=new i(0),u=n.clone();t.cmpn(1)>0&&n.cmpn(1)>0;){for(var c=0,l=1;0==(t.words[0]&l)&&c<26;++c,l<<=1);if(c>0)for(t.iushrn(c);c-- >0;)a.isOdd()&&a.iadd(u),a.iushrn(1);for(var d=0,h=1;0==(n.words[0]&h)&&d<26;++d,h<<=1);if(d>0)for(n.iushrn(d);d-- >0;)s.isOdd()&&s.iadd(u),s.iushrn(1);t.cmp(n)>=0?(t.isub(n),a.isub(s)):(n.isub(t),s.isub(a))}return(r=0===t.cmpn(1)?a:s).cmpn(0)<0&&r.iadd(e),r},i.prototype.gcd=function(e){if(this.isZero())return e.abs();if(e.isZero())return this.abs();var t=this.clone(),n=e.clone();t.negative=0,n.negative=0;for(var o=0;t.isEven()&&n.isEven();o++)t.iushrn(1),n.iushrn(1);for(;;){for(;t.isEven();)t.iushrn(1);for(;n.isEven();)n.iushrn(1);var r=t.cmp(n);if(r<0){var i=t;t=n,n=i}else if(0===r||0===n.cmpn(1))break;t.isub(n)}return n.iushln(o)},i.prototype.invm=function(e){return this.egcd(e).a.umod(e)},i.prototype.isEven=function(){return 0==(1&this.words[0])},i.prototype.isOdd=function(){return 1==(1&this.words[0])},i.prototype.andln=function(e){return this.words[0]&e},i.prototype.bincn=function(e){o("number"==typeof e);var t=e%26,n=(e-t)/26,r=1<>>26,s&=67108863,this.words[a]=s}return 0!==i&&(this.words[a]=i,this.length++),this},i.prototype.isZero=function(){return 1===this.length&&0===this.words[0]},i.prototype.cmpn=function(e){var t,n=e<0;if(0!==this.negative&&!n)return-1;if(0===this.negative&&n)return 1;if(this.strip(),this.length>1)t=1;else{n&&(e=-e),o(e<=67108863,"Number is too big");var r=0|this.words[0];t=r===e?0:re.length)return 1;if(this.length=0;n--){var o=0|this.words[n],r=0|e.words[n];if(o!==r){or&&(t=1);break}}return t},i.prototype.gtn=function(e){return 1===this.cmpn(e)},i.prototype.gt=function(e){return 1===this.cmp(e)},i.prototype.gten=function(e){return this.cmpn(e)>=0},i.prototype.gte=function(e){return this.cmp(e)>=0},i.prototype.ltn=function(e){return-1===this.cmpn(e)},i.prototype.lt=function(e){return-1===this.cmp(e)},i.prototype.lten=function(e){return this.cmpn(e)<=0},i.prototype.lte=function(e){return this.cmp(e)<=0},i.prototype.eqn=function(e){return 0===this.cmpn(e)},i.prototype.eq=function(e){return 0===this.cmp(e)},i.red=function(e){return new E(e)},i.prototype.toRed=function(e){return o(!this.red,"Already a number in reduction context"),o(0===this.negative,"red works only with positives"),e.convertTo(this)._forceRed(e)},i.prototype.fromRed=function(){return o(this.red,"fromRed works only with numbers in reduction context"),this.red.convertFrom(this)},i.prototype._forceRed=function(e){return this.red=e,this},i.prototype.forceRed=function(e){return o(!this.red,"Already a number in reduction context"),this._forceRed(e)},i.prototype.redAdd=function(e){return o(this.red,"redAdd works only with red numbers"),this.red.add(this,e)},i.prototype.redIAdd=function(e){return o(this.red,"redIAdd works only with red numbers"),this.red.iadd(this,e)},i.prototype.redSub=function(e){return o(this.red,"redSub works only with red numbers"),this.red.sub(this,e)},i.prototype.redISub=function(e){return o(this.red,"redISub works only with red numbers"),this.red.isub(this,e)},i.prototype.redShl=function(e){return o(this.red,"redShl works only with red numbers"),this.red.shl(this,e)},i.prototype.redMul=function(e){return o(this.red,"redMul works only with red numbers"),this.red._verify2(this,e),this.red.mul(this,e)},i.prototype.redIMul=function(e){return o(this.red,"redMul works only with red numbers"),this.red._verify2(this,e),this.red.imul(this,e)},i.prototype.redSqr=function(){return o(this.red,"redSqr works only with red numbers"),this.red._verify1(this),this.red.sqr(this)},i.prototype.redISqr=function(){return o(this.red,"redISqr works only with red numbers"),this.red._verify1(this),this.red.isqr(this)},i.prototype.redSqrt=function(){return o(this.red,"redSqrt works only with red numbers"),this.red._verify1(this),this.red.sqrt(this)},i.prototype.redInvm=function(){return o(this.red,"redInvm works only with red numbers"),this.red._verify1(this),this.red.invm(this)},i.prototype.redNeg=function(){return o(this.red,"redNeg works only with red numbers"),this.red._verify1(this),this.red.neg(this)},i.prototype.redPow=function(e){return o(this.red&&!e.red,"redPow(normalNum)"),this.red._verify1(this),this.red.pow(this,e)};var _={k256:null,p224:null,p192:null,p25519:null};function F(e,t){this.name=e,this.p=new i(t,16),this.n=this.p.bitLength(),this.k=new i(1).iushln(this.n).isub(this.p),this.tmp=this._tmp()}function y(){F.call(this,"k256","ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f")}function b(){F.call(this,"p224","ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001")}function v(){F.call(this,"p192","ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff")}function w(){F.call(this,"25519","7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed")}function E(e){if("string"==typeof e){var t=i._prime(e);this.m=t.p,this.prime=t}else o(e.gtn(1),"modulus must be greater than 1"),this.m=e,this.prime=null}function k(e){E.call(this,e),this.shift=this.m.bitLength(),this.shift%26!=0&&(this.shift+=26-this.shift%26),this.r=new i(1).iushln(this.shift),this.r2=this.imod(this.r.sqr()),this.rinv=this.r._invmp(this.m),this.minv=this.rinv.mul(this.r).isubn(1).div(this.m),this.minv=this.minv.umod(this.r),this.minv=this.r.sub(this.minv)}F.prototype._tmp=function(){var e=new i(null);return e.words=new Array(Math.ceil(this.n/13)),e},F.prototype.ireduce=function(e){var t,n=e;do{this.split(n,this.tmp),t=(n=(n=this.imulK(n)).iadd(this.tmp)).bitLength()}while(t>this.n);var o=t0?n.isub(this.p):void 0!==n.strip?n.strip():n._strip(),n},F.prototype.split=function(e,t){e.iushrn(this.n,0,t)},F.prototype.imulK=function(e){return e.imul(this.k)},r(y,F),y.prototype.split=function(e,t){for(var n=4194303,o=Math.min(e.length,9),r=0;r>>22,i=a}i>>>=22,e.words[r-10]=i,0===i&&e.length>10?e.length-=10:e.length-=9},y.prototype.imulK=function(e){e.words[e.length]=0,e.words[e.length+1]=0,e.length+=2;for(var t=0,n=0;n>>=26,e.words[n]=r,t=o}return 0!==t&&(e.words[e.length++]=t),e},i._prime=function(e){if(_[e])return _[e];var t;if("k256"===e)t=new y;else if("p224"===e)t=new b;else if("p192"===e)t=new v;else{if("p25519"!==e)throw new Error("Unknown prime "+e);t=new w}return _[e]=t,t},E.prototype._verify1=function(e){o(0===e.negative,"red works only with positives"),o(e.red,"red works only with red numbers")},E.prototype._verify2=function(e,t){o(0==(e.negative|t.negative),"red works only with positives"),o(e.red&&e.red===t.red,"red works only with red numbers")},E.prototype.imod=function(e){return this.prime?this.prime.ireduce(e)._forceRed(this):e.umod(this.m)._forceRed(this)},E.prototype.neg=function(e){return e.isZero()?e.clone():this.m.sub(e)._forceRed(this)},E.prototype.add=function(e,t){this._verify2(e,t);var n=e.add(t);return n.cmp(this.m)>=0&&n.isub(this.m),n._forceRed(this)},E.prototype.iadd=function(e,t){this._verify2(e,t);var n=e.iadd(t);return n.cmp(this.m)>=0&&n.isub(this.m),n},E.prototype.sub=function(e,t){this._verify2(e,t);var n=e.sub(t);return n.cmpn(0)<0&&n.iadd(this.m),n._forceRed(this)},E.prototype.isub=function(e,t){this._verify2(e,t);var n=e.isub(t);return n.cmpn(0)<0&&n.iadd(this.m),n},E.prototype.shl=function(e,t){return this._verify1(e),this.imod(e.ushln(t))},E.prototype.imul=function(e,t){return this._verify2(e,t),this.imod(e.imul(t))},E.prototype.mul=function(e,t){return this._verify2(e,t),this.imod(e.mul(t))},E.prototype.isqr=function(e){return this.imul(e,e.clone())},E.prototype.sqr=function(e){return this.mul(e,e)},E.prototype.sqrt=function(e){if(e.isZero())return e.clone();var t=this.m.andln(3);if(o(t%2==1),3===t){var n=this.m.add(new i(1)).iushrn(2);return this.pow(e,n)}for(var r=this.m.subn(1),a=0;!r.isZero()&&0===r.andln(1);)a++,r.iushrn(1);o(!r.isZero());var s=new i(1).toRed(this),u=s.redNeg(),c=this.m.subn(1).iushrn(1),l=this.m.bitLength();for(l=new i(2*l*l).toRed(this);0!==this.pow(l,c).cmp(u);)l.redIAdd(u);for(var d=this.pow(l,r),h=this.pow(e,r.addn(1).iushrn(1)),p=this.pow(e,r),f=a;0!==p.cmp(s);){for(var g=p,m=0;0!==g.cmp(s);m++)g=g.redSqr();o(m=0;o--){for(var c=t.words[o],l=u-1;l>=0;l--){var d=c>>l&1;r!==n[0]&&(r=this.sqr(r)),0!==d||0!==a?(a<<=1,a|=d,(4==++s||0===o&&0===l)&&(r=this.mul(r,n[a]),s=0,a=0)):s=0}u=26}return r},E.prototype.convertTo=function(e){var t=e.umod(this.m);return t===e?t.clone():t},E.prototype.convertFrom=function(e){var t=e.clone();return t.red=null,t},i.mont=function(e){return new k(e)},r(k,E),k.prototype.convertTo=function(e){return this.imod(e.ushln(this.shift))},k.prototype.convertFrom=function(e){var t=this.imod(e.mul(this.rinv));return t.red=null,t},k.prototype.imul=function(e,t){if(e.isZero()||t.isZero())return e.words[0]=0,e.length=1,e;var n=e.imul(t),o=n.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m),r=n.isub(o).iushrn(this.shift),i=r;return r.cmp(this.m)>=0?i=r.isub(this.m):r.cmpn(0)<0&&(i=r.iadd(this.m)),i._forceRed(this)},k.prototype.mul=function(e,t){if(e.isZero()||t.isZero())return new i(0)._forceRed(this);var n=e.mul(t),o=n.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m),r=n.isub(o).iushrn(this.shift),a=r;return r.cmp(this.m)>=0?a=r.isub(this.m):r.cmpn(0)<0&&(a=r.iadd(this.m)),a._forceRed(this)},k.prototype.invm=function(e){return this.imod(e._invmp(this.m).mul(this.r2))._forceRed(this)}}(e=n.nmd(e),this)},17519:e=>{"use strict";e.exports={i8:"6.5.4"}},76555:(e,t,n)=>{var o=n(90233);function r(e,t,n){t&&"string"!=typeof t&&(t=t.message||t.name),o(this,{type:e,name:e,cause:"string"!=typeof t?t:n,message:t},"ewr")}function i(e,t){Error.call(this),Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor),r.call(this,"CustomError",e,t)}i.prototype=new Error,e.exports=function(e){var t=function(t,n){return function(e,t,n){var o=function(n,i){r.call(this,t,n,i),"FilesystemError"==t&&(this.code=this.cause.code,this.path=this.cause.path,this.errno=this.cause.errno,this.message=(e.errno[this.cause.errno]?e.errno[this.cause.errno].description:this.cause.message)+(this.cause.path?" ["+this.cause.path+"]":"")),Error.call(this),Error.captureStackTrace&&Error.captureStackTrace(this,o)};return o.prototype=n?new n:new i,o}(e,t,n)};return{CustomError:i,FilesystemError:t("FilesystemError"),createError:t}}},47138:(e,t,n)=>{var o=e.exports.all=[{errno:-2,code:"ENOENT",description:"no such file or directory"},{errno:-1,code:"UNKNOWN",description:"unknown error"},{errno:0,code:"OK",description:"success"},{errno:1,code:"EOF",description:"end of file"},{errno:2,code:"EADDRINFO",description:"getaddrinfo error"},{errno:3,code:"EACCES",description:"permission denied"},{errno:4,code:"EAGAIN",description:"resource temporarily unavailable"},{errno:5,code:"EADDRINUSE",description:"address already in use"},{errno:6,code:"EADDRNOTAVAIL",description:"address not available"},{errno:7,code:"EAFNOSUPPORT",description:"address family not supported"},{errno:8,code:"EALREADY",description:"connection already in progress"},{errno:9,code:"EBADF",description:"bad file descriptor"},{errno:10,code:"EBUSY",description:"resource busy or locked"},{errno:11,code:"ECONNABORTED",description:"software caused connection abort"},{errno:12,code:"ECONNREFUSED",description:"connection refused"},{errno:13,code:"ECONNRESET",description:"connection reset by peer"},{errno:14,code:"EDESTADDRREQ",description:"destination address required"},{errno:15,code:"EFAULT",description:"bad address in system call argument"},{errno:16,code:"EHOSTUNREACH",description:"host is unreachable"},{errno:17,code:"EINTR",description:"interrupted system call"},{errno:18,code:"EINVAL",description:"invalid argument"},{errno:19,code:"EISCONN",description:"socket is already connected"},{errno:20,code:"EMFILE",description:"too many open files"},{errno:21,code:"EMSGSIZE",description:"message too long"},{errno:22,code:"ENETDOWN",description:"network is down"},{errno:23,code:"ENETUNREACH",description:"network is unreachable"},{errno:24,code:"ENFILE",description:"file table overflow"},{errno:25,code:"ENOBUFS",description:"no buffer space available"},{errno:26,code:"ENOMEM",description:"not enough memory"},{errno:27,code:"ENOTDIR",description:"not a directory"},{errno:28,code:"EISDIR",description:"illegal operation on a directory"},{errno:29,code:"ENONET",description:"machine is not on the network"},{errno:31,code:"ENOTCONN",description:"socket is not connected"},{errno:32,code:"ENOTSOCK",description:"socket operation on non-socket"},{errno:33,code:"ENOTSUP",description:"operation not supported on socket"},{errno:34,code:"ENOENT",description:"no such file or directory"},{errno:35,code:"ENOSYS",description:"function not implemented"},{errno:36,code:"EPIPE",description:"broken pipe"},{errno:37,code:"EPROTO",description:"protocol error"},{errno:38,code:"EPROTONOSUPPORT",description:"protocol not supported"},{errno:39,code:"EPROTOTYPE",description:"protocol wrong type for socket"},{errno:40,code:"ETIMEDOUT",description:"connection timed out"},{errno:41,code:"ECHARSET",description:"invalid Unicode character"},{errno:42,code:"EAIFAMNOSUPPORT",description:"address family for hostname not supported"},{errno:44,code:"EAISERVICE",description:"servname not supported for ai_socktype"},{errno:45,code:"EAISOCKTYPE",description:"ai_socktype not supported"},{errno:46,code:"ESHUTDOWN",description:"cannot send after transport endpoint shutdown"},{errno:47,code:"EEXIST",description:"file already exists"},{errno:48,code:"ESRCH",description:"no such process"},{errno:49,code:"ENAMETOOLONG",description:"name too long"},{errno:50,code:"EPERM",description:"operation not permitted"},{errno:51,code:"ELOOP",description:"too many symbolic links encountered"},{errno:52,code:"EXDEV",description:"cross-device link not permitted"},{errno:53,code:"ENOTEMPTY",description:"directory not empty"},{errno:54,code:"ENOSPC",description:"no space left on device"},{errno:55,code:"EIO",description:"i/o error"},{errno:56,code:"EROFS",description:"read-only file system"},{errno:57,code:"ENODEV",description:"no such device"},{errno:58,code:"ESPIPE",description:"invalid seek"},{errno:59,code:"ECANCELED",description:"operation canceled"}];e.exports.errno={},e.exports.code={},o.forEach((function(t){e.exports.errno[t.errno]=t,e.exports.code[t.code]=t})),e.exports.custom=n(76555)(e.exports),e.exports.create=e.exports.custom.createError},94079:(e,t,n)=>{"use strict";var o=n(40210)("%Object.getOwnPropertyDescriptor%");if(o)try{o([],"length")}catch(e){o=null}e.exports=o},17187:e=>{"use strict";var t,n="object"==typeof Reflect?Reflect:null,o=n&&"function"==typeof n.apply?n.apply:function(e,t,n){return Function.prototype.apply.call(e,t,n)};t=n&&"function"==typeof n.ownKeys?n.ownKeys:Object.getOwnPropertySymbols?function(e){return Object.getOwnPropertyNames(e).concat(Object.getOwnPropertySymbols(e))}:function(e){return Object.getOwnPropertyNames(e)};var r=Number.isNaN||function(e){return e!=e};function i(){i.init.call(this)}e.exports=i,e.exports.once=function(e,t){return new Promise((function(n,o){function r(n){e.removeListener(t,i),o(n)}function i(){"function"==typeof e.removeListener&&e.removeListener("error",r),n([].slice.call(arguments))}g(e,t,i,{once:!0}),"error"!==t&&function(e,t,n){"function"==typeof e.on&&g(e,"error",t,{once:!0})}(e,r)}))},i.EventEmitter=i,i.prototype._events=void 0,i.prototype._eventsCount=0,i.prototype._maxListeners=void 0;var a=10;function s(e){if("function"!=typeof e)throw new TypeError('The "listener" argument must be of type Function. Received type '+typeof e)}function u(e){return void 0===e._maxListeners?i.defaultMaxListeners:e._maxListeners}function c(e,t,n,o){var r,i,a,c;if(s(n),void 0===(i=e._events)?(i=e._events=Object.create(null),e._eventsCount=0):(void 0!==i.newListener&&(e.emit("newListener",t,n.listener?n.listener:n),i=e._events),a=i[t]),void 0===a)a=i[t]=n,++e._eventsCount;else if("function"==typeof a?a=i[t]=o?[n,a]:[a,n]:o?a.unshift(n):a.push(n),(r=u(e))>0&&a.length>r&&!a.warned){a.warned=!0;var l=new Error("Possible EventEmitter memory leak detected. "+a.length+" "+String(t)+" listeners added. Use emitter.setMaxListeners() to increase limit");l.name="MaxListenersExceededWarning",l.emitter=e,l.type=t,l.count=a.length,c=l,console&&console.warn&&console.warn(c)}return e}function l(){if(!this.fired)return this.target.removeListener(this.type,this.wrapFn),this.fired=!0,0===arguments.length?this.listener.call(this.target):this.listener.apply(this.target,arguments)}function d(e,t,n){var o={fired:!1,wrapFn:void 0,target:e,type:t,listener:n},r=l.bind(o);return r.listener=n,o.wrapFn=r,r}function h(e,t,n){var o=e._events;if(void 0===o)return[];var r=o[t];return void 0===r?[]:"function"==typeof r?n?[r.listener||r]:[r]:n?function(e){for(var t=new Array(e.length),n=0;n0&&(a=t[0]),a instanceof Error)throw a;var s=new Error("Unhandled error."+(a?" ("+a.message+")":""));throw s.context=a,s}var u=i[e];if(void 0===u)return!1;if("function"==typeof u)o(u,this,t);else{var c=u.length,l=f(u,c);for(n=0;n=0;i--)if(n[i]===t||n[i].listener===t){a=n[i].listener,r=i;break}if(r<0)return this;0===r?n.shift():function(e,t){for(;t+1=0;o--)this.removeListener(e,t[o]);return this},i.prototype.listeners=function(e){return h(this,e,!0)},i.prototype.rawListeners=function(e){return h(this,e,!1)},i.listenerCount=function(e,t){return"function"==typeof e.listenerCount?e.listenerCount(t):p.call(e,t)},i.prototype.listenerCount=p,i.prototype.eventNames=function(){return this._eventsCount>0?t(this._events):[]}},13048:(e,t,n)=>{var o=n(89509).Buffer,r=n(62318);e.exports=function(e,t,n,i){if(o.isBuffer(e)||(e=o.from(e,"binary")),t&&(o.isBuffer(t)||(t=o.from(t,"binary")),8!==t.length))throw new RangeError("salt should be Buffer with 8 byte length");for(var a=n/8,s=o.alloc(a),u=o.alloc(i||0),c=o.alloc(0);a>0||i>0;){var l=new r;l.update(c),l.update(e),t&&l.update(t),c=l.digest();var d=0;if(a>0){var h=s.length-a;d=Math.min(a,c.length),c.copy(s,h,0,d),a-=d}if(d0){var p=u.length-i,f=Math.min(i,c.length-d);c.copy(u,p,d,d+f),i-=f}}return c.fill(0),{key:s,iv:u}}},58875:(e,t,n)=>{var o;!function(){"use strict";var r=!("undefined"==typeof window||!window.document||!window.document.createElement),i={canUseDOM:r,canUseWorkers:"undefined"!=typeof Worker,canUseEventListeners:r&&!(!window.addEventListener&&!window.attachEvent),canUseViewport:r&&!!window.screen};void 0===(o=function(){return i}.call(t,n,t,e))||(e.exports=o)}()},94470:e=>{"use strict";var t=Object.prototype.hasOwnProperty,n=Object.prototype.toString,o=Object.defineProperty,r=Object.getOwnPropertyDescriptor,i=function(e){return"function"==typeof Array.isArray?Array.isArray(e):"[object Array]"===n.call(e)},a=function(e){if(!e||"[object Object]"!==n.call(e))return!1;var o,r=t.call(e,"constructor"),i=e.constructor&&e.constructor.prototype&&t.call(e.constructor.prototype,"isPrototypeOf");if(e.constructor&&!r&&!i)return!1;for(o in e);return void 0===o||t.call(e,o)},s=function(e,t){o&&"__proto__"===t.name?o(e,t.name,{enumerable:!0,configurable:!0,value:t.newValue,writable:!0}):e[t.name]=t.newValue},u=function(e,n){if("__proto__"===n){if(!t.call(e,n))return;if(r)return r(e,n).value}return e[n]};e.exports=function e(){var t,n,o,r,c,l,d=arguments[0],h=1,p=arguments.length,f=!1;for("boolean"==typeof d&&(f=d,d=arguments[1]||{},h=2),(null==d||"object"!=typeof d&&"function"!=typeof d)&&(d={});h{"use strict";e.exports=function(e,t){for(var n=arguments.length,o=new Array(n>2?n-2:0),r=2;r{e.exports.Dispatcher=n(61063)},61063:(e,t,n)=>{"use strict";function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var r=n(73759),i=function(){function e(){o(this,"_callbacks",void 0),o(this,"_isDispatching",void 0),o(this,"_isHandled",void 0),o(this,"_isPending",void 0),o(this,"_lastID",void 0),o(this,"_pendingPayload",void 0),this._callbacks={},this._isDispatching=!1,this._isHandled={},this._isPending={},this._lastID=1}var t=e.prototype;return t.register=function(e){var t="ID_"+this._lastID++;return this._callbacks[t]=e,t},t.unregister=function(e){this._callbacks[e]||r(!1),delete this._callbacks[e]},t.waitFor=function(e){this._isDispatching||r(!1);for(var t=0;t{var t=Object.prototype.hasOwnProperty,n=Object.prototype.toString;e.exports=function(e,o,r){if("[object Function]"!==n.call(o))throw new TypeError("iterator must be a function");var i=e.length;if(i===+i)for(var a=0;a{"use strict";var t="Function.prototype.bind called on incompatible ",n=Array.prototype.slice,o=Object.prototype.toString,r="[object Function]";e.exports=function(e){var i=this;if("function"!=typeof i||o.call(i)!==r)throw new TypeError(t+i);for(var a,s=n.call(arguments,1),u=function(){if(this instanceof a){var t=i.apply(this,s.concat(n.call(arguments)));return Object(t)===t?t:this}return i.apply(e,s.concat(n.call(arguments)))},c=Math.max(0,i.length-s.length),l=[],d=0;d{"use strict";var o=n(17648);e.exports=Function.prototype.bind||o},35673:(e,t,n)=>{var o=n(26272),r=n(79941),i=n(18673),a=new Buffer(0),s=function(){},u=function(e){return"function"==typeof e?e:function(t){t(null,e)}},c=function(e,t){var n=!1,o=!1;return e._read=function(){n=!0},e.destroy=function(){o=!0},t((function(t,r){if(t)return e.emit("error",t);var i=function(){for(var t;null!==(t=r.read());)n=!1,e.push(t)};if(r.on("readable",(function(){n&&i()})),r.on("end",(function(){i(),e.push(null)})),r.on("error",(function(t){e.emit("error",t)})),r.on("close",(function(){i(),process.nextTick((function(){e.emit("close")}))})),e._read=function(){n=!0,i()},e.destroy=function(){o||(o=!0,r.destroy&&r.destroy())},o)return o=!1,void e.destroy();n&&i()})),e},l=function(e,t){var n=s,o=!1;return e._write=function(e,t,o){n=o},e.destroy=function(){o=!0},e.write(a),t((function(t,r){if(t)return e.emit("error",t);r.on("close",(function(){e.emit("close")})),r.on("error",(function(t){e.emit("error",t)})),e._write=function(e,t,n){if(e===a)return n();r.write(e,t,n)};var i=e.emit;if(r.on("finish",(function(){i.call(e,"finish")})),e.destroy=function(){o||(o=!0,r.destroy&&r.destroy())},e.emit=function(t){if("finish"!==t)return i.apply(e,arguments);r.end()},o)return o=!1,void e.destroy();n()})),e};t.readable=function(e,n){return 1===arguments.length?t.readable(null,e):(e||(e={}),c(new r(e),u(n)))},t.writable=function(e,n){return 1===arguments.length?t.writable(null,e):(e||(e={}),l(new o(e),u(n)))},t.duplex=function(e,n,o){if(2===arguments.length)return t.duplex(null,e,n);e||(e={});var r=new i(e);return l(r,u(n)),c(r,u(o)),r}},23419:e=>{e.exports=Array.isArray||function(e){return"[object Array]"==Object.prototype.toString.call(e)}},18673:(e,t,n)=>{e.exports=n(55410)},55410:(e,t,n)=>{e.exports=s;var o=Object.keys||function(e){var t=[];for(var n in e)t.push(n);return t},r=n(16497);r.inherits=n(35717);var i=n(93558),a=n(9315);function s(e){if(!(this instanceof s))return new s(e);i.call(this,e),a.call(this,e),e&&!1===e.readable&&(this.readable=!1),e&&!1===e.writable&&(this.writable=!1),this.allowHalfOpen=!0,e&&!1===e.allowHalfOpen&&(this.allowHalfOpen=!1),this.once("end",u)}function u(){this.allowHalfOpen||this._writableState.ended||process.nextTick(this.end.bind(this))}r.inherits(s,i),function(e,t){for(var n=0,o=e.length;n{e.exports=i;var o=n(12590),r=n(16497);function i(e){if(!(this instanceof i))return new i(e);o.call(this,e)}r.inherits=n(35717),r.inherits(i,o),i.prototype._transform=function(e,t,n){n(null,e)}},93558:(e,t,n)=>{e.exports=l;var o=n(23419),r=n(48764).Buffer;l.ReadableState=c;var i=n(17187).EventEmitter;i.listenerCount||(i.listenerCount=function(e,t){return e.listeners(t).length});var a,s=n(42830),u=n(16497);function c(e,t){var o=(e=e||{}).highWaterMark;this.highWaterMark=o||0===o?o:16384,this.highWaterMark=~~this.highWaterMark,this.buffer=[],this.length=0,this.pipes=null,this.pipesCount=0,this.flowing=!1,this.ended=!1,this.endEmitted=!1,this.reading=!1,this.calledRead=!1,this.sync=!0,this.needReadable=!1,this.emittedReadable=!1,this.readableListening=!1,this.objectMode=!!e.objectMode,this.defaultEncoding=e.defaultEncoding||"utf8",this.ranOut=!1,this.awaitDrain=0,this.readingMore=!1,this.decoder=null,this.encoding=null,e.encoding&&(a||(a=n(26250).s),this.decoder=new a(e.encoding),this.encoding=e.encoding)}function l(e){if(!(this instanceof l))return new l(e);this._readableState=new c(e,this),this.readable=!0,s.call(this)}function d(e,t,n,o,i){var a=function(e,t){var n=null;return r.isBuffer(t)||"string"==typeof t||null==t||e.objectMode||(n=new TypeError("Invalid non-string/buffer chunk")),n}(t,n);if(a)e.emit("error",a);else if(null==n)t.reading=!1,t.ended||function(e,t){if(t.decoder&&!t.ended){var n=t.decoder.end();n&&n.length&&(t.buffer.push(n),t.length+=t.objectMode?1:n.length)}t.ended=!0,t.length>0?f(e):b(e)}(e,t);else if(t.objectMode||n&&n.length>0)if(t.ended&&!i){var s=new Error("stream.push() after EOF");e.emit("error",s)}else t.endEmitted&&i?(s=new Error("stream.unshift() after end event"),e.emit("error",s)):(!t.decoder||i||o||(n=t.decoder.write(n)),t.length+=t.objectMode?1:n.length,i?t.buffer.unshift(n):(t.reading=!1,t.buffer.push(n)),t.needReadable&&f(e),function(e,t){t.readingMore||(t.readingMore=!0,process.nextTick((function(){!function(e,t){for(var n=t.length;!t.reading&&!t.flowing&&!t.ended&&t.lengtht.highWaterMark&&(t.highWaterMark=function(e){if(e>=h)e=h;else{e--;for(var t=1;t<32;t<<=1)e|=e>>t;e++}return e}(e)),e>t.length?t.ended?t.length:(t.needReadable=!0,0):e)}function f(e){var t=e._readableState;t.needReadable=!1,t.emittedReadable||(t.emittedReadable=!0,t.sync?process.nextTick((function(){g(e)})):g(e))}function g(e){e.emit("readable")}function m(e){var t,n=e._readableState;function o(e,o,r){!1===e.write(t)&&n.awaitDrain++}for(n.awaitDrain=0;n.pipesCount&&null!==(t=e.read());)if(1===n.pipesCount?o(n.pipes):v(n.pipes,o),e.emit("data",t),n.awaitDrain>0)return;if(0===n.pipesCount)return n.flowing=!1,void(i.listenerCount(e,"data")>0&&F(e));n.ranOut=!0}function _(){this._readableState.ranOut&&(this._readableState.ranOut=!1,m(this))}function F(e,t){if(e._readableState.flowing)throw new Error("Cannot switch to old mode now.");var n=t||!1,o=!1;e.readable=!0,e.pipe=s.prototype.pipe,e.on=e.addListener=s.prototype.on,e.on("readable",(function(){var t;for(o=!0;!n&&null!==(t=e.read());)e.emit("data",t);null===t&&(o=!1,e._readableState.needReadable=!0)})),e.pause=function(){n=!0,this.emit("pause")},e.resume=function(){n=!1,o?process.nextTick((function(){e.emit("readable")})):this.read(0),this.emit("resume")},e.emit("readable")}function y(e,t){var n,o=t.buffer,i=t.length,a=!!t.decoder,s=!!t.objectMode;if(0===o.length)return null;if(0===i)n=null;else if(s)n=o.shift();else if(!e||e>=i)n=a?o.join(""):r.concat(o,i),o.length=0;else if(e0)throw new Error("endReadable called on non-empty stream");!t.endEmitted&&t.calledRead&&(t.ended=!0,process.nextTick((function(){t.endEmitted||0!==t.length||(t.endEmitted=!0,e.readable=!1,e.emit("end"))})))}function v(e,t){for(var n=0,o=e.length;n0)&&(t.emittedReadable=!1),0===e&&t.needReadable&&(t.length>=t.highWaterMark||t.ended))return f(this),null;if(0===(e=p(e,t))&&t.ended)return n=null,t.length>0&&t.decoder&&(n=y(e,t),t.length-=n.length),0===t.length&&b(this),n;var r=t.needReadable;return t.length-e<=t.highWaterMark&&(r=!0),(t.ended||t.reading)&&(r=!1),r&&(t.reading=!0,t.sync=!0,0===t.length&&(t.needReadable=!0),this._read(t.highWaterMark),t.sync=!1),r&&!t.reading&&(e=p(o,t)),null===(n=e>0?y(e,t):null)&&(t.needReadable=!0,e=0),t.length-=e,0!==t.length||t.ended||(t.needReadable=!0),t.ended&&!t.endEmitted&&0===t.length&&b(this),n},l.prototype._read=function(e){this.emit("error",new Error("not implemented"))},l.prototype.pipe=function(e,t){var n=this,r=this._readableState;switch(r.pipesCount){case 0:r.pipes=e;break;case 1:r.pipes=[r.pipes,e];break;default:r.pipes.push(e)}r.pipesCount+=1;var a=t&&!1===t.end||e===process.stdout||e===process.stderr?l:u;function s(e){e===n&&l()}function u(){e.end()}r.endEmitted?process.nextTick(a):n.once("end",a),e.on("unpipe",s);var c=function(e){return function(){var t=e._readableState;t.awaitDrain--,0===t.awaitDrain&&m(e)}}(n);function l(){e.removeListener("close",h),e.removeListener("finish",p),e.removeListener("drain",c),e.removeListener("error",d),e.removeListener("unpipe",s),n.removeListener("end",u),n.removeListener("end",l),e._writableState&&!e._writableState.needDrain||c()}function d(t){f(),e.removeListener("error",d),0===i.listenerCount(e,"error")&&e.emit("error",t)}function h(){e.removeListener("finish",p),f()}function p(){e.removeListener("close",h),f()}function f(){n.unpipe(e)}return e.on("drain",c),e._events&&e._events.error?o(e._events.error)?e._events.error.unshift(d):e._events.error=[d,e._events.error]:e.on("error",d),e.once("close",h),e.once("finish",p),e.emit("pipe",n),r.flowing||(this.on("readable",_),r.flowing=!0,process.nextTick((function(){m(n)}))),e},l.prototype.unpipe=function(e){var t=this._readableState;if(0===t.pipesCount)return this;if(1===t.pipesCount)return e&&e!==t.pipes||(e||(e=t.pipes),t.pipes=null,t.pipesCount=0,this.removeListener("readable",_),t.flowing=!1,e&&e.emit("unpipe",this)),this;if(!e){var n=t.pipes,o=t.pipesCount;t.pipes=null,t.pipesCount=0,this.removeListener("readable",_),t.flowing=!1;for(var r=0;r{e.exports=a;var o=n(55410),r=n(16497);function i(e,t){this.afterTransform=function(e,n){return function(e,t,n){var o=e._transformState;o.transforming=!1;var r=o.writecb;if(!r)return e.emit("error",new Error("no writecb in Transform class"));o.writechunk=null,o.writecb=null,null!=n&&e.push(n),r&&r(t);var i=e._readableState;i.reading=!1,(i.needReadable||i.length{e.exports=u;var o=n(48764).Buffer;u.WritableState=s;var r=n(16497);r.inherits=n(35717);var i=n(42830);function a(e,t,n){this.chunk=e,this.encoding=t,this.callback=n}function s(e,t){var n=(e=e||{}).highWaterMark;this.highWaterMark=n||0===n?n:16384,this.objectMode=!!e.objectMode,this.highWaterMark=~~this.highWaterMark,this.needDrain=!1,this.ending=!1,this.ended=!1,this.finished=!1;var o=!1===e.decodeStrings;this.decodeStrings=!o,this.defaultEncoding=e.defaultEncoding||"utf8",this.length=0,this.writing=!1,this.sync=!0,this.bufferProcessing=!1,this.onwrite=function(e){!function(e,t){var n=e._writableState,o=n.sync,r=n.writecb;if(function(e){e.writing=!1,e.writecb=null,e.length-=e.writelen,e.writelen=0}(n),t)!function(e,t,n,o,r){n?process.nextTick((function(){r(o)})):r(o),e._writableState.errorEmitted=!0,e.emit("error",o)}(e,0,o,t,r);else{var i=d(0,n);i||n.bufferProcessing||!n.buffer.length||function(e,t){t.bufferProcessing=!0;for(var n=0;n{var o=n(42830);(t=e.exports=n(93558)).Stream=o,t.Readable=t,t.Writable=n(9315),t.Duplex=n(55410),t.Transform=n(12590),t.PassThrough=n(88449),process.browser||"disable"!==process.env.READABLE_STREAM||(e.exports=n(42830))},26272:(e,t,n)=>{e.exports=n(9315)},26250:(e,t,n)=>{var o=n(48764).Buffer,r=o.isEncoding||function(e){switch(e&&e.toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":case"raw":return!0;default:return!1}},i=t.s=function(e){switch(this.encoding=(e||"utf8").toLowerCase().replace(/[-_]/,""),function(e){if(e&&!r(e))throw new Error("Unknown encoding: "+e)}(e),this.encoding){case"utf8":this.surrogateSize=3;break;case"ucs2":case"utf16le":this.surrogateSize=2,this.detectIncompleteChar=s;break;case"base64":this.surrogateSize=3,this.detectIncompleteChar=u;break;default:return void(this.write=a)}this.charBuffer=new o(6),this.charReceived=0,this.charLength=0};function a(e){return e.toString(this.encoding)}function s(e){this.charReceived=e.length%2,this.charLength=this.charReceived?2:0}function u(e){this.charReceived=e.length%3,this.charLength=this.charReceived?3:0}i.prototype.write=function(e){for(var t="";this.charLength;){var n=e.length>=this.charLength-this.charReceived?this.charLength-this.charReceived:e.length;if(e.copy(this.charBuffer,this.charReceived,0,n),this.charReceived+=n,this.charReceived=55296&&o<=56319)){if(this.charReceived=this.charLength=0,0===e.length)return t;break}this.charLength+=this.surrogateSize,t=""}this.detectIncompleteChar(e);var o,r=e.length;if(this.charLength&&(e.copy(this.charBuffer,0,e.length-this.charReceived,r),r-=this.charReceived),r=(t+=e.toString(this.encoding,0,r)).length-1,(o=t.charCodeAt(r))>=55296&&o<=56319){var i=this.surrogateSize;return this.charLength+=i,this.charReceived+=i,this.charBuffer.copy(this.charBuffer,i,0,i),e.copy(this.charBuffer,0,0,i),t.substring(0,r)}return t},i.prototype.detectIncompleteChar=function(e){for(var t=e.length>=3?3:e.length;t>0;t--){var n=e[e.length-t];if(1==t&&n>>5==6){this.charLength=2;break}if(t<=2&&n>>4==14){this.charLength=3;break}if(t<=3&&n>>3==30){this.charLength=4;break}}this.charReceived=t},i.prototype.end=function(e){var t="";if(e&&e.length&&(t=this.write(e)),this.charReceived){var n=this.charReceived,o=this.charBuffer,r=this.encoding;t+=o.slice(0,n).toString(r)}return t}},40210:(e,t,n)=>{"use strict";var o,r=SyntaxError,i=Function,a=TypeError,s=function(e){try{return i('"use strict"; return ('+e+").constructor;")()}catch(e){}},u=Object.getOwnPropertyDescriptor;if(u)try{u({},"")}catch(e){u=null}var c=function(){throw new a},l=u?function(){try{return c}catch(e){try{return u(arguments,"callee").get}catch(e){return c}}}():c,d=n(41405)(),h=Object.getPrototypeOf||function(e){return e.__proto__},p={},f="undefined"==typeof Uint8Array?o:h(Uint8Array),g={"%AggregateError%":"undefined"==typeof AggregateError?o:AggregateError,"%Array%":Array,"%ArrayBuffer%":"undefined"==typeof ArrayBuffer?o:ArrayBuffer,"%ArrayIteratorPrototype%":d?h([][Symbol.iterator]()):o,"%AsyncFromSyncIteratorPrototype%":o,"%AsyncFunction%":p,"%AsyncGenerator%":p,"%AsyncGeneratorFunction%":p,"%AsyncIteratorPrototype%":p,"%Atomics%":"undefined"==typeof Atomics?o:Atomics,"%BigInt%":"undefined"==typeof BigInt?o:BigInt,"%Boolean%":Boolean,"%DataView%":"undefined"==typeof DataView?o:DataView,"%Date%":Date,"%decodeURI%":decodeURI,"%decodeURIComponent%":decodeURIComponent,"%encodeURI%":encodeURI,"%encodeURIComponent%":encodeURIComponent,"%Error%":Error,"%eval%":eval,"%EvalError%":EvalError,"%Float32Array%":"undefined"==typeof Float32Array?o:Float32Array,"%Float64Array%":"undefined"==typeof Float64Array?o:Float64Array,"%FinalizationRegistry%":"undefined"==typeof FinalizationRegistry?o:FinalizationRegistry,"%Function%":i,"%GeneratorFunction%":p,"%Int8Array%":"undefined"==typeof Int8Array?o:Int8Array,"%Int16Array%":"undefined"==typeof Int16Array?o:Int16Array,"%Int32Array%":"undefined"==typeof Int32Array?o:Int32Array,"%isFinite%":isFinite,"%isNaN%":isNaN,"%IteratorPrototype%":d?h(h([][Symbol.iterator]())):o,"%JSON%":"object"==typeof JSON?JSON:o,"%Map%":"undefined"==typeof Map?o:Map,"%MapIteratorPrototype%":"undefined"!=typeof Map&&d?h((new Map)[Symbol.iterator]()):o,"%Math%":Math,"%Number%":Number,"%Object%":Object,"%parseFloat%":parseFloat,"%parseInt%":parseInt,"%Promise%":"undefined"==typeof Promise?o:Promise,"%Proxy%":"undefined"==typeof Proxy?o:Proxy,"%RangeError%":RangeError,"%ReferenceError%":ReferenceError,"%Reflect%":"undefined"==typeof Reflect?o:Reflect,"%RegExp%":RegExp,"%Set%":"undefined"==typeof Set?o:Set,"%SetIteratorPrototype%":"undefined"!=typeof Set&&d?h((new Set)[Symbol.iterator]()):o,"%SharedArrayBuffer%":"undefined"==typeof SharedArrayBuffer?o:SharedArrayBuffer,"%String%":String,"%StringIteratorPrototype%":d?h(""[Symbol.iterator]()):o,"%Symbol%":d?Symbol:o,"%SyntaxError%":r,"%ThrowTypeError%":l,"%TypedArray%":f,"%TypeError%":a,"%Uint8Array%":"undefined"==typeof Uint8Array?o:Uint8Array,"%Uint8ClampedArray%":"undefined"==typeof Uint8ClampedArray?o:Uint8ClampedArray,"%Uint16Array%":"undefined"==typeof Uint16Array?o:Uint16Array,"%Uint32Array%":"undefined"==typeof Uint32Array?o:Uint32Array,"%URIError%":URIError,"%WeakMap%":"undefined"==typeof WeakMap?o:WeakMap,"%WeakRef%":"undefined"==typeof WeakRef?o:WeakRef,"%WeakSet%":"undefined"==typeof WeakSet?o:WeakSet},m=function e(t){var n;if("%AsyncFunction%"===t)n=s("async function () {}");else if("%GeneratorFunction%"===t)n=s("function* () {}");else if("%AsyncGeneratorFunction%"===t)n=s("async function* () {}");else if("%AsyncGenerator%"===t){var o=e("%AsyncGeneratorFunction%");o&&(n=o.prototype)}else if("%AsyncIteratorPrototype%"===t){var r=e("%AsyncGenerator%");r&&(n=h(r.prototype))}return g[t]=n,n},_={"%ArrayBufferPrototype%":["ArrayBuffer","prototype"],"%ArrayPrototype%":["Array","prototype"],"%ArrayProto_entries%":["Array","prototype","entries"],"%ArrayProto_forEach%":["Array","prototype","forEach"],"%ArrayProto_keys%":["Array","prototype","keys"],"%ArrayProto_values%":["Array","prototype","values"],"%AsyncFunctionPrototype%":["AsyncFunction","prototype"],"%AsyncGenerator%":["AsyncGeneratorFunction","prototype"],"%AsyncGeneratorPrototype%":["AsyncGeneratorFunction","prototype","prototype"],"%BooleanPrototype%":["Boolean","prototype"],"%DataViewPrototype%":["DataView","prototype"],"%DatePrototype%":["Date","prototype"],"%ErrorPrototype%":["Error","prototype"],"%EvalErrorPrototype%":["EvalError","prototype"],"%Float32ArrayPrototype%":["Float32Array","prototype"],"%Float64ArrayPrototype%":["Float64Array","prototype"],"%FunctionPrototype%":["Function","prototype"],"%Generator%":["GeneratorFunction","prototype"],"%GeneratorPrototype%":["GeneratorFunction","prototype","prototype"],"%Int8ArrayPrototype%":["Int8Array","prototype"],"%Int16ArrayPrototype%":["Int16Array","prototype"],"%Int32ArrayPrototype%":["Int32Array","prototype"],"%JSONParse%":["JSON","parse"],"%JSONStringify%":["JSON","stringify"],"%MapPrototype%":["Map","prototype"],"%NumberPrototype%":["Number","prototype"],"%ObjectPrototype%":["Object","prototype"],"%ObjProto_toString%":["Object","prototype","toString"],"%ObjProto_valueOf%":["Object","prototype","valueOf"],"%PromisePrototype%":["Promise","prototype"],"%PromiseProto_then%":["Promise","prototype","then"],"%Promise_all%":["Promise","all"],"%Promise_reject%":["Promise","reject"],"%Promise_resolve%":["Promise","resolve"],"%RangeErrorPrototype%":["RangeError","prototype"],"%ReferenceErrorPrototype%":["ReferenceError","prototype"],"%RegExpPrototype%":["RegExp","prototype"],"%SetPrototype%":["Set","prototype"],"%SharedArrayBufferPrototype%":["SharedArrayBuffer","prototype"],"%StringPrototype%":["String","prototype"],"%SymbolPrototype%":["Symbol","prototype"],"%SyntaxErrorPrototype%":["SyntaxError","prototype"],"%TypedArrayPrototype%":["TypedArray","prototype"],"%TypeErrorPrototype%":["TypeError","prototype"],"%Uint8ArrayPrototype%":["Uint8Array","prototype"],"%Uint8ClampedArrayPrototype%":["Uint8ClampedArray","prototype"],"%Uint16ArrayPrototype%":["Uint16Array","prototype"],"%Uint32ArrayPrototype%":["Uint32Array","prototype"],"%URIErrorPrototype%":["URIError","prototype"],"%WeakMapPrototype%":["WeakMap","prototype"],"%WeakSetPrototype%":["WeakSet","prototype"]},F=n(58612),y=n(17642),b=F.call(Function.call,Array.prototype.concat),v=F.call(Function.apply,Array.prototype.splice),w=F.call(Function.call,String.prototype.replace),E=F.call(Function.call,String.prototype.slice),k=/[^%.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|%$))/g,D=/\\(\\)?/g,S=function(e){var t=E(e,0,1),n=E(e,-1);if("%"===t&&"%"!==n)throw new r("invalid intrinsic syntax, expected closing `%`");if("%"===n&&"%"!==t)throw new r("invalid intrinsic syntax, expected opening `%`");var o=[];return w(e,k,(function(e,t,n,r){o[o.length]=n?w(r,D,"$1"):t||e})),o},x=function(e,t){var n,o=e;if(y(_,o)&&(o="%"+(n=_[o])[0]+"%"),y(g,o)){var i=g[o];if(i===p&&(i=m(o)),void 0===i&&!t)throw new a("intrinsic "+e+" exists, but is not available. Please file an issue!");return{alias:n,name:o,value:i}}throw new r("intrinsic "+e+" does not exist!")};e.exports=function(e,t){if("string"!=typeof e||0===e.length)throw new a("intrinsic name must be a non-empty string");if(arguments.length>1&&"boolean"!=typeof t)throw new a('"allowMissing" argument must be a boolean');var n=S(e),o=n.length>0?n[0]:"",i=x("%"+o+"%",t),s=i.name,c=i.value,l=!1,d=i.alias;d&&(o=d[0],v(n,b([0,1],d)));for(var h=1,p=!0;h=n.length){var F=u(c,f);c=(p=!!F)&&"get"in F&&!("originalValue"in F.get)?F.get:c[f]}else p=y(c,f),c=c[f];p&&!l&&(g[s]=c)}}return c}},41405:(e,t,n)=>{"use strict";var o="undefined"!=typeof Symbol&&Symbol,r=n(55419);e.exports=function(){return"function"==typeof o&&"function"==typeof Symbol&&"symbol"==typeof o("foo")&&"symbol"==typeof Symbol("bar")&&r()}},55419:e=>{"use strict";e.exports=function(){if("function"!=typeof Symbol||"function"!=typeof Object.getOwnPropertySymbols)return!1;if("symbol"==typeof Symbol.iterator)return!0;var e={},t=Symbol("test"),n=Object(t);if("string"==typeof t)return!1;if("[object Symbol]"!==Object.prototype.toString.call(t))return!1;if("[object Symbol]"!==Object.prototype.toString.call(n))return!1;for(t in e[t]=42,e)return!1;if("function"==typeof Object.keys&&0!==Object.keys(e).length)return!1;if("function"==typeof Object.getOwnPropertyNames&&0!==Object.getOwnPropertyNames(e).length)return!1;var o=Object.getOwnPropertySymbols(e);if(1!==o.length||o[0]!==t)return!1;if(!Object.prototype.propertyIsEnumerable.call(e,t))return!1;if("function"==typeof Object.getOwnPropertyDescriptor){var r=Object.getOwnPropertyDescriptor(e,t);if(42!==r.value||!0!==r.enumerable)return!1}return!0}},17642:(e,t,n)=>{"use strict";var o=n(58612);e.exports=o.call(Function.call,Object.prototype.hasOwnProperty)},3349:(e,t,n)=>{"use strict";var o=n(89509).Buffer,r=n(70326).Transform;function i(e){r.call(this),this._block=o.allocUnsafe(e),this._blockSize=e,this._blockOffset=0,this._length=[0,0,0,0],this._finalized=!1}n(35717)(i,r),i.prototype._transform=function(e,t,n){var o=null;try{this.update(e,t)}catch(e){o=e}n(o)},i.prototype._flush=function(e){var t=null;try{this.push(this.digest())}catch(e){t=e}e(t)},i.prototype.update=function(e,t){if(function(e,t){if(!o.isBuffer(e)&&"string"!=typeof e)throw new TypeError("Data must be a string or a buffer")}(e),this._finalized)throw new Error("Digest already called");o.isBuffer(e)||(e=o.from(e,t));for(var n=this._block,r=0;this._blockOffset+e.length-r>=this._blockSize;){for(var i=this._blockOffset;i0;++a)this._length[a]+=s,(s=this._length[a]/4294967296|0)>0&&(this._length[a]-=4294967296*s);return this},i.prototype._update=function(){throw new Error("_update is not implemented")},i.prototype.digest=function(e){if(this._finalized)throw new Error("Digest already called");this._finalized=!0;var t=this._digest();void 0!==e&&(t=t.toString(e)),this._block.fill(0),this._blockOffset=0;for(var n=0;n<4;++n)this._length[n]=0;return t},i.prototype._digest=function(){throw new Error("_digest is not implemented")},e.exports=i},9786:e=>{"use strict";var t={};function n(e,n,o){o||(o=Error);var r=function(e){var t,o;function r(t,o,r){return e.call(this,function(e,t,o){return"string"==typeof n?n:n(e,t,o)}(t,o,r))||this}return o=e,(t=r).prototype=Object.create(o.prototype),t.prototype.constructor=t,t.__proto__=o,r}(o);r.prototype.name=o.name,r.prototype.code=e,t[e]=r}function o(e,t){if(Array.isArray(e)){var n=e.length;return e=e.map((function(e){return String(e)})),n>2?"one of ".concat(t," ").concat(e.slice(0,n-1).join(", "),", or ")+e[n-1]:2===n?"one of ".concat(t," ").concat(e[0]," or ").concat(e[1]):"of ".concat(t," ").concat(e[0])}return"of ".concat(t," ").concat(String(e))}n("ERR_INVALID_OPT_VALUE",(function(e,t){return'The value "'+t+'" is invalid for option "'+e+'"'}),TypeError),n("ERR_INVALID_ARG_TYPE",(function(e,t,n){var r,i,a,s,u;if("string"==typeof t&&(i="not ",t.substr(0,i.length)===i)?(r="must not be",t=t.replace(/^not /,"")):r="must be",function(e,t,n){return(void 0===n||n>e.length)&&(n=e.length),e.substring(n-t.length,n)===t}(e," argument"))a="The ".concat(e," ").concat(r," ").concat(o(t,"type"));else{var c=("number"!=typeof u&&(u=0),u+".".length>(s=e).length||-1===s.indexOf(".",u)?"argument":"property");a='The "'.concat(e,'" ').concat(c," ").concat(r," ").concat(o(t,"type"))}return a+". Received type ".concat(typeof n)}),TypeError),n("ERR_STREAM_PUSH_AFTER_EOF","stream.push() after EOF"),n("ERR_METHOD_NOT_IMPLEMENTED",(function(e){return"The "+e+" method is not implemented"})),n("ERR_STREAM_PREMATURE_CLOSE","Premature close"),n("ERR_STREAM_DESTROYED",(function(e){return"Cannot call "+e+" after a stream was destroyed"})),n("ERR_MULTIPLE_CALLBACK","Callback called multiple times"),n("ERR_STREAM_CANNOT_PIPE","Cannot pipe, not readable"),n("ERR_STREAM_WRITE_AFTER_END","write after end"),n("ERR_STREAM_NULL_VALUES","May not write null values to stream",TypeError),n("ERR_UNKNOWN_ENCODING",(function(e){return"Unknown encoding: "+e}),TypeError),n("ERR_STREAM_UNSHIFT_AFTER_END_EVENT","stream.unshift() after end event"),e.exports.q=t},62910:(e,t,n)=>{"use strict";var o=Object.keys||function(e){var t=[];for(var n in e)t.push(n);return t};e.exports=c;var r=n(76748),i=n(70469);n(35717)(c,r);for(var a=o(i.prototype),s=0;s{"use strict";e.exports=r;var o=n(70421);function r(e){if(!(this instanceof r))return new r(e);o.call(this,e)}n(35717)(r,o),r.prototype._transform=function(e,t,n){n(null,e)}},76748:(e,t,n)=>{"use strict";var o;e.exports=k,k.ReadableState=E,n(17187).EventEmitter;var r,i=function(e,t){return e.listeners(t).length},a=n(50677),s=n(48764).Buffer,u=n.g.Uint8Array||function(){},c=n(31616);r=c&&c.debuglog?c.debuglog("stream"):function(){};var l,d,h,p=n(98354),f=n(35072),g=n(31222).getHighWaterMark,m=n(9786).q,_=m.ERR_INVALID_ARG_TYPE,F=m.ERR_STREAM_PUSH_AFTER_EOF,y=m.ERR_METHOD_NOT_IMPLEMENTED,b=m.ERR_STREAM_UNSHIFT_AFTER_END_EVENT;n(35717)(k,a);var v=f.errorOrDestroy,w=["error","close","destroy","pause","resume"];function E(e,t,r){o=o||n(62910),e=e||{},"boolean"!=typeof r&&(r=t instanceof o),this.objectMode=!!e.objectMode,r&&(this.objectMode=this.objectMode||!!e.readableObjectMode),this.highWaterMark=g(this,e,"readableHighWaterMark",r),this.buffer=new p,this.length=0,this.pipes=null,this.pipesCount=0,this.flowing=null,this.ended=!1,this.endEmitted=!1,this.reading=!1,this.sync=!0,this.needReadable=!1,this.emittedReadable=!1,this.readableListening=!1,this.resumeScheduled=!1,this.paused=!0,this.emitClose=!1!==e.emitClose,this.autoDestroy=!!e.autoDestroy,this.destroyed=!1,this.defaultEncoding=e.defaultEncoding||"utf8",this.awaitDrain=0,this.readingMore=!1,this.decoder=null,this.encoding=null,e.encoding&&(l||(l=n(32553).s),this.decoder=new l(e.encoding),this.encoding=e.encoding)}function k(e){if(o=o||n(62910),!(this instanceof k))return new k(e);var t=this instanceof o;this._readableState=new E(e,this,t),this.readable=!0,e&&("function"==typeof e.read&&(this._read=e.read),"function"==typeof e.destroy&&(this._destroy=e.destroy)),a.call(this)}function D(e,t,n,o,i){r("readableAddChunk",t);var a,c=e._readableState;if(null===t)c.reading=!1,function(e,t){if(r("onEofChunk"),!t.ended){if(t.decoder){var n=t.decoder.end();n&&n.length&&(t.buffer.push(n),t.length+=t.objectMode?1:n.length)}t.ended=!0,t.sync?A(e):(t.needReadable=!1,t.emittedReadable||(t.emittedReadable=!0,T(e)))}}(e,c);else if(i||(a=function(e,t){var n,o;return o=t,s.isBuffer(o)||o instanceof u||"string"==typeof t||void 0===t||e.objectMode||(n=new _("chunk",["string","Buffer","Uint8Array"],t)),n}(c,t)),a)v(e,a);else if(c.objectMode||t&&t.length>0)if("string"==typeof t||c.objectMode||Object.getPrototypeOf(t)===s.prototype||(t=function(e){return s.from(e)}(t)),o)c.endEmitted?v(e,new b):S(e,c,t,!0);else if(c.ended)v(e,new F);else{if(c.destroyed)return!1;c.reading=!1,c.decoder&&!n?(t=c.decoder.write(t),c.objectMode||0!==t.length?S(e,c,t,!1):R(e,c)):S(e,c,t,!1)}else o||(c.reading=!1,R(e,c));return!c.ended&&(c.lengtht.highWaterMark&&(t.highWaterMark=function(e){return e>=x?e=x:(e--,e|=e>>>1,e|=e>>>2,e|=e>>>4,e|=e>>>8,e|=e>>>16,e++),e}(e)),e<=t.length?e:t.ended?t.length:(t.needReadable=!0,0))}function A(e){var t=e._readableState;r("emitReadable",t.needReadable,t.emittedReadable),t.needReadable=!1,t.emittedReadable||(r("emitReadable",t.flowing),t.emittedReadable=!0,process.nextTick(T,e))}function T(e){var t=e._readableState;r("emitReadable_",t.destroyed,t.length,t.ended),t.destroyed||!t.length&&!t.ended||(e.emit("readable"),t.emittedReadable=!1),t.needReadable=!t.flowing&&!t.ended&&t.length<=t.highWaterMark,N(e)}function R(e,t){t.readingMore||(t.readingMore=!0,process.nextTick(I,e,t))}function I(e,t){for(;!t.reading&&!t.ended&&(t.length0,t.resumeScheduled&&!t.paused?t.flowing=!0:e.listenerCount("data")>0&&e.resume()}function O(e){r("readable nexttick read 0"),e.read(0)}function B(e,t){r("resume",t.reading),t.reading||e.read(0),t.resumeScheduled=!1,e.emit("resume"),N(e),t.flowing&&!t.reading&&e.read(0)}function N(e){var t=e._readableState;for(r("flow",t.flowing);t.flowing&&null!==e.read(););}function L(e,t){return 0===t.length?null:(t.objectMode?n=t.buffer.shift():!e||e>=t.length?(n=t.decoder?t.buffer.join(""):1===t.buffer.length?t.buffer.first():t.buffer.concat(t.length),t.buffer.clear()):n=t.buffer.consume(e,t.decoder),n);var n}function P(e){var t=e._readableState;r("endReadable",t.endEmitted),t.endEmitted||(t.ended=!0,process.nextTick(U,t,e))}function U(e,t){if(r("endReadableNT",e.endEmitted,e.length),!e.endEmitted&&0===e.length&&(e.endEmitted=!0,t.readable=!1,t.emit("end"),e.autoDestroy)){var n=t._writableState;(!n||n.autoDestroy&&n.finished)&&t.destroy()}}function j(e,t){for(var n=0,o=e.length;n=t.highWaterMark:t.length>0)||t.ended))return r("read: emitReadable",t.length,t.ended),0===t.length&&t.ended?P(this):A(this),null;if(0===(e=C(e,t))&&t.ended)return 0===t.length&&P(this),null;var o,i=t.needReadable;return r("need readable",i),(0===t.length||t.length-e0?L(e,t):null)?(t.needReadable=t.length<=t.highWaterMark,e=0):(t.length-=e,t.awaitDrain=0),0===t.length&&(t.ended||(t.needReadable=!0),n!==e&&t.ended&&P(this)),null!==o&&this.emit("data",o),o},k.prototype._read=function(e){v(this,new y("_read()"))},k.prototype.pipe=function(e,t){var n=this,o=this._readableState;switch(o.pipesCount){case 0:o.pipes=e;break;case 1:o.pipes=[o.pipes,e];break;default:o.pipes.push(e)}o.pipesCount+=1,r("pipe count=%d opts=%j",o.pipesCount,t);var a=t&&!1===t.end||e===process.stdout||e===process.stderr?f:s;function s(){r("onend"),e.end()}o.endEmitted?process.nextTick(a):n.once("end",a),e.on("unpipe",(function t(i,a){r("onunpipe"),i===n&&a&&!1===a.hasUnpiped&&(a.hasUnpiped=!0,r("cleanup"),e.removeListener("close",h),e.removeListener("finish",p),e.removeListener("drain",u),e.removeListener("error",d),e.removeListener("unpipe",t),n.removeListener("end",s),n.removeListener("end",f),n.removeListener("data",l),c=!0,!o.awaitDrain||e._writableState&&!e._writableState.needDrain||u())}));var u=function(e){return function(){var t=e._readableState;r("pipeOnDrain",t.awaitDrain),t.awaitDrain&&t.awaitDrain--,0===t.awaitDrain&&i(e,"data")&&(t.flowing=!0,N(e))}}(n);e.on("drain",u);var c=!1;function l(t){r("ondata");var i=e.write(t);r("dest.write",i),!1===i&&((1===o.pipesCount&&o.pipes===e||o.pipesCount>1&&-1!==j(o.pipes,e))&&!c&&(r("false write response, pause",o.awaitDrain),o.awaitDrain++),n.pause())}function d(t){r("onerror",t),f(),e.removeListener("error",d),0===i(e,"error")&&v(e,t)}function h(){e.removeListener("finish",p),f()}function p(){r("onfinish"),e.removeListener("close",h),f()}function f(){r("unpipe"),n.unpipe(e)}return n.on("data",l),function(e,t,n){if("function"==typeof e.prependListener)return e.prependListener(t,n);e._events&&e._events.error?Array.isArray(e._events.error)?e._events.error.unshift(n):e._events.error=[n,e._events.error]:e.on(t,n)}(e,"error",d),e.once("close",h),e.once("finish",p),e.emit("pipe",n),o.flowing||(r("pipe resume"),n.resume()),e},k.prototype.unpipe=function(e){var t=this._readableState,n={hasUnpiped:!1};if(0===t.pipesCount)return this;if(1===t.pipesCount)return e&&e!==t.pipes||(e||(e=t.pipes),t.pipes=null,t.pipesCount=0,t.flowing=!1,e&&e.emit("unpipe",this,n)),this;if(!e){var o=t.pipes,r=t.pipesCount;t.pipes=null,t.pipesCount=0,t.flowing=!1;for(var i=0;i0,!1!==o.flowing&&this.resume()):"readable"===e&&(o.endEmitted||o.readableListening||(o.readableListening=o.needReadable=!0,o.flowing=!1,o.emittedReadable=!1,r("on readable",o.length,o.reading),o.length?A(this):o.reading||process.nextTick(O,this))),n},k.prototype.addListener=k.prototype.on,k.prototype.removeListener=function(e,t){var n=a.prototype.removeListener.call(this,e,t);return"readable"===e&&process.nextTick(M,this),n},k.prototype.removeAllListeners=function(e){var t=a.prototype.removeAllListeners.apply(this,arguments);return"readable"!==e&&void 0!==e||process.nextTick(M,this),t},k.prototype.resume=function(){var e=this._readableState;return e.flowing||(r("resume"),e.flowing=!e.readableListening,function(e,t){t.resumeScheduled||(t.resumeScheduled=!0,process.nextTick(B,e,t))}(this,e)),e.paused=!1,this},k.prototype.pause=function(){return r("call pause flowing=%j",this._readableState.flowing),!1!==this._readableState.flowing&&(r("pause"),this._readableState.flowing=!1,this.emit("pause")),this._readableState.paused=!0,this},k.prototype.wrap=function(e){var t=this,n=this._readableState,o=!1;for(var i in e.on("end",(function(){if(r("wrapped end"),n.decoder&&!n.ended){var e=n.decoder.end();e&&e.length&&t.push(e)}t.push(null)})),e.on("data",(function(i){r("wrapped data"),n.decoder&&(i=n.decoder.write(i)),n.objectMode&&null==i||(n.objectMode||i&&i.length)&&(t.push(i)||(o=!0,e.pause()))})),e)void 0===this[i]&&"function"==typeof e[i]&&(this[i]=function(t){return function(){return e[t].apply(e,arguments)}}(i));for(var a=0;a{"use strict";e.exports=l;var o=n(9786).q,r=o.ERR_METHOD_NOT_IMPLEMENTED,i=o.ERR_MULTIPLE_CALLBACK,a=o.ERR_TRANSFORM_ALREADY_TRANSFORMING,s=o.ERR_TRANSFORM_WITH_LENGTH_0,u=n(62910);function c(e,t){var n=this._transformState;n.transforming=!1;var o=n.writecb;if(null===o)return this.emit("error",new i);n.writechunk=null,n.writecb=null,null!=t&&this.push(t),o(e);var r=this._readableState;r.reading=!1,(r.needReadable||r.length{"use strict";function o(e){var t=this;this.next=null,this.entry=null,this.finish=function(){!function(e,t,n){var o=e.entry;for(e.entry=null;o;){var r=o.callback;t.pendingcb--,r(undefined),o=o.next}t.corkedRequestsFree.next=e}(t,e)}}var r;e.exports=k,k.WritableState=E;var i,a={deprecate:n(94927)},s=n(50677),u=n(48764).Buffer,c=n.g.Uint8Array||function(){},l=n(35072),d=n(31222).getHighWaterMark,h=n(9786).q,p=h.ERR_INVALID_ARG_TYPE,f=h.ERR_METHOD_NOT_IMPLEMENTED,g=h.ERR_MULTIPLE_CALLBACK,m=h.ERR_STREAM_CANNOT_PIPE,_=h.ERR_STREAM_DESTROYED,F=h.ERR_STREAM_NULL_VALUES,y=h.ERR_STREAM_WRITE_AFTER_END,b=h.ERR_UNKNOWN_ENCODING,v=l.errorOrDestroy;function w(){}function E(e,t,i){r=r||n(62910),e=e||{},"boolean"!=typeof i&&(i=t instanceof r),this.objectMode=!!e.objectMode,i&&(this.objectMode=this.objectMode||!!e.writableObjectMode),this.highWaterMark=d(this,e,"writableHighWaterMark",i),this.finalCalled=!1,this.needDrain=!1,this.ending=!1,this.ended=!1,this.finished=!1,this.destroyed=!1;var a=!1===e.decodeStrings;this.decodeStrings=!a,this.defaultEncoding=e.defaultEncoding||"utf8",this.length=0,this.writing=!1,this.corked=0,this.sync=!0,this.bufferProcessing=!1,this.onwrite=function(e){!function(e,t){var n=e._writableState,o=n.sync,r=n.writecb;if("function"!=typeof r)throw new g;if(function(e){e.writing=!1,e.writecb=null,e.length-=e.writelen,e.writelen=0}(n),t)!function(e,t,n,o,r){--t.pendingcb,n?(process.nextTick(r,o),process.nextTick(T,e,t),e._writableState.errorEmitted=!0,v(e,o)):(r(o),e._writableState.errorEmitted=!0,v(e,o),T(e,t))}(e,n,o,t,r);else{var i=C(n)||e.destroyed;i||n.corked||n.bufferProcessing||!n.bufferedRequest||x(e,n),o?process.nextTick(S,e,n,i,r):S(e,n,i,r)}}(t,e)},this.writecb=null,this.writelen=0,this.bufferedRequest=null,this.lastBufferedRequest=null,this.pendingcb=0,this.prefinished=!1,this.errorEmitted=!1,this.emitClose=!1!==e.emitClose,this.autoDestroy=!!e.autoDestroy,this.bufferedRequestCount=0,this.corkedRequestsFree=new o(this)}function k(e){var t=this instanceof(r=r||n(62910));if(!t&&!i.call(k,this))return new k(e);this._writableState=new E(e,this,t),this.writable=!0,e&&("function"==typeof e.write&&(this._write=e.write),"function"==typeof e.writev&&(this._writev=e.writev),"function"==typeof e.destroy&&(this._destroy=e.destroy),"function"==typeof e.final&&(this._final=e.final)),s.call(this)}function D(e,t,n,o,r,i,a){t.writelen=o,t.writecb=a,t.writing=!0,t.sync=!0,t.destroyed?t.onwrite(new _("write")):n?e._writev(r,t.onwrite):e._write(r,i,t.onwrite),t.sync=!1}function S(e,t,n,o){n||function(e,t){0===t.length&&t.needDrain&&(t.needDrain=!1,e.emit("drain"))}(e,t),t.pendingcb--,o(),T(e,t)}function x(e,t){t.bufferProcessing=!0;var n=t.bufferedRequest;if(e._writev&&n&&n.next){var r=t.bufferedRequestCount,i=new Array(r),a=t.corkedRequestsFree;a.entry=n;for(var s=0,u=!0;n;)i[s]=n,n.isBuf||(u=!1),n=n.next,s+=1;i.allBuffers=u,D(e,t,!0,t.length,i,"",a.finish),t.pendingcb++,t.lastBufferedRequest=null,a.next?(t.corkedRequestsFree=a.next,a.next=null):t.corkedRequestsFree=new o(t),t.bufferedRequestCount=0}else{for(;n;){var c=n.chunk,l=n.encoding,d=n.callback;if(D(e,t,!1,t.objectMode?1:c.length,c,l,d),n=n.next,t.bufferedRequestCount--,t.writing)break}null===n&&(t.lastBufferedRequest=null)}t.bufferedRequest=n,t.bufferProcessing=!1}function C(e){return e.ending&&0===e.length&&null===e.bufferedRequest&&!e.finished&&!e.writing}function A(e,t){e._final((function(n){t.pendingcb--,n&&v(e,n),t.prefinished=!0,e.emit("prefinish"),T(e,t)}))}function T(e,t){var n=C(t);if(n&&(function(e,t){t.prefinished||t.finalCalled||("function"!=typeof e._final||t.destroyed?(t.prefinished=!0,e.emit("prefinish")):(t.pendingcb++,t.finalCalled=!0,process.nextTick(A,e,t)))}(e,t),0===t.pendingcb&&(t.finished=!0,e.emit("finish"),t.autoDestroy))){var o=e._readableState;(!o||o.autoDestroy&&o.endEmitted)&&e.destroy()}return n}n(35717)(k,s),E.prototype.getBuffer=function(){for(var e=this.bufferedRequest,t=[];e;)t.push(e),e=e.next;return t},function(){try{Object.defineProperty(E.prototype,"buffer",{get:a.deprecate((function(){return this.getBuffer()}),"_writableState.buffer is deprecated. Use _writableState.getBuffer instead.","DEP0003")})}catch(e){}}(),"function"==typeof Symbol&&Symbol.hasInstance&&"function"==typeof Function.prototype[Symbol.hasInstance]?(i=Function.prototype[Symbol.hasInstance],Object.defineProperty(k,Symbol.hasInstance,{value:function(e){return!!i.call(this,e)||this===k&&e&&e._writableState instanceof E}})):i=function(e){return e instanceof this},k.prototype.pipe=function(){v(this,new m)},k.prototype.write=function(e,t,n){var o,r=this._writableState,i=!1,a=!r.objectMode&&(o=e,u.isBuffer(o)||o instanceof c);return a&&!u.isBuffer(e)&&(e=function(e){return u.from(e)}(e)),"function"==typeof t&&(n=t,t=null),a?t="buffer":t||(t=r.defaultEncoding),"function"!=typeof n&&(n=w),r.ending?function(e,t){var n=new y;v(e,n),process.nextTick(t,n)}(this,n):(a||function(e,t,n,o){var r;return null===n?r=new F:"string"==typeof n||t.objectMode||(r=new p("chunk",["string","Buffer"],n)),!r||(v(e,r),process.nextTick(o,r),!1)}(this,r,e,n))&&(r.pendingcb++,i=function(e,t,n,o,r,i){if(!n){var a=function(e,t,n){return e.objectMode||!1===e.decodeStrings||"string"!=typeof t||(t=u.from(t,n)),t}(t,o,r);o!==a&&(n=!0,r="buffer",o=a)}var s=t.objectMode?1:o.length;t.length+=s;var c=t.length-1))throw new b(e);return this._writableState.defaultEncoding=e,this},Object.defineProperty(k.prototype,"writableBuffer",{enumerable:!1,get:function(){return this._writableState&&this._writableState.getBuffer()}}),Object.defineProperty(k.prototype,"writableHighWaterMark",{enumerable:!1,get:function(){return this._writableState.highWaterMark}}),k.prototype._write=function(e,t,n){n(new f("_write()"))},k.prototype._writev=null,k.prototype.end=function(e,t,n){var o=this._writableState;return"function"==typeof e?(n=e,e=null,t=null):"function"==typeof t&&(n=t,t=null),null!=e&&this.write(e,t),o.corked&&(o.corked=1,this.uncork()),o.ending||function(e,t,n){t.ending=!0,T(e,t),n&&(t.finished?process.nextTick(n):e.once("finish",n)),t.ended=!0,e.writable=!1}(this,o,n),this},Object.defineProperty(k.prototype,"writableLength",{enumerable:!1,get:function(){return this._writableState.length}}),Object.defineProperty(k.prototype,"destroyed",{enumerable:!1,get:function(){return void 0!==this._writableState&&this._writableState.destroyed},set:function(e){this._writableState&&(this._writableState.destroyed=e)}}),k.prototype.destroy=l.destroy,k.prototype._undestroy=l.undestroy,k.prototype._destroy=function(e,t){t(e)}},30527:(e,t,n)=>{"use strict";var o;function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var i=n(28640),a=Symbol("lastResolve"),s=Symbol("lastReject"),u=Symbol("error"),c=Symbol("ended"),l=Symbol("lastPromise"),d=Symbol("handlePromise"),h=Symbol("stream");function p(e,t){return{value:e,done:t}}function f(e){var t=e[a];if(null!==t){var n=e[h].read();null!==n&&(e[l]=null,e[a]=null,e[s]=null,t(p(n,!1)))}}function g(e){process.nextTick(f,e)}var m=Object.getPrototypeOf((function(){})),_=Object.setPrototypeOf((r(o={get stream(){return this[h]},next:function(){var e=this,t=this[u];if(null!==t)return Promise.reject(t);if(this[c])return Promise.resolve(p(void 0,!0));if(this[h].destroyed)return new Promise((function(t,n){process.nextTick((function(){e[u]?n(e[u]):t(p(void 0,!0))}))}));var n,o=this[l];if(o)n=new Promise(function(e,t){return function(n,o){e.then((function(){t[c]?n(p(void 0,!0)):t[d](n,o)}),o)}}(o,this));else{var r=this[h].read();if(null!==r)return Promise.resolve(p(r,!1));n=new Promise(this[d])}return this[l]=n,n}},Symbol.asyncIterator,(function(){return this})),r(o,"return",(function(){var e=this;return new Promise((function(t,n){e[h].destroy(null,(function(e){e?n(e):t(p(void 0,!0))}))}))})),o),m);e.exports=function(e){var t,n=Object.create(_,(r(t={},h,{value:e,writable:!0}),r(t,a,{value:null,writable:!0}),r(t,s,{value:null,writable:!0}),r(t,u,{value:null,writable:!0}),r(t,c,{value:e._readableState.endEmitted,writable:!0}),r(t,d,{value:function(e,t){var o=n[h].read();o?(n[l]=null,n[a]=null,n[s]=null,e(p(o,!1))):(n[a]=e,n[s]=t)},writable:!0}),t));return n[l]=null,i(e,(function(e){if(e&&"ERR_STREAM_PREMATURE_CLOSE"!==e.code){var t=n[s];return null!==t&&(n[l]=null,n[a]=null,n[s]=null,t(e)),void(n[u]=e)}var o=n[a];null!==o&&(n[l]=null,n[a]=null,n[s]=null,o(p(void 0,!0))),n[c]=!0})),e.on("readable",g.bind(null,n)),n}},98354:(e,t,n)=>{"use strict";function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){for(var n=0;n0?this.tail.next=t:this.head=t,this.tail=t,++this.length}},{key:"unshift",value:function(e){var t={data:e,next:this.head};0===this.length&&(this.tail=t),this.head=t,++this.length}},{key:"shift",value:function(){if(0!==this.length){var e=this.head.data;return 1===this.length?this.head=this.tail=null:this.head=this.head.next,--this.length,e}}},{key:"clear",value:function(){this.head=this.tail=null,this.length=0}},{key:"join",value:function(e){if(0===this.length)return"";for(var t=this.head,n=""+t.data;t=t.next;)n+=e+t.data;return n}},{key:"concat",value:function(e){if(0===this.length)return a.alloc(0);for(var t,n,o,r=a.allocUnsafe(e>>>0),i=this.head,s=0;i;)t=i.data,n=r,o=s,a.prototype.copy.call(t,n,o),s+=i.data.length,i=i.next;return r}},{key:"consume",value:function(e,t){var n;return er.length?r.length:e;if(i===r.length?o+=r:o+=r.slice(0,e),0==(e-=i)){i===r.length?(++n,t.next?this.head=t.next:this.head=this.tail=null):(this.head=t,t.data=r.slice(i));break}++n}return this.length-=n,o}},{key:"_getBuffer",value:function(e){var t=a.allocUnsafe(e),n=this.head,o=1;for(n.data.copy(t),e-=n.data.length;n=n.next;){var r=n.data,i=e>r.length?r.length:e;if(r.copy(t,t.length-e,0,i),0==(e-=i)){i===r.length?(++o,n.next?this.head=n.next:this.head=this.tail=null):(this.head=n,n.data=r.slice(i));break}++o}return this.length-=o,t}},{key:u,value:function(e,t){return s(this,function(e){for(var t=1;t{"use strict";function t(e,t){o(e,t),n(e)}function n(e){e._writableState&&!e._writableState.emitClose||e._readableState&&!e._readableState.emitClose||e.emit("close")}function o(e,t){e.emit("error",t)}e.exports={destroy:function(e,r){var i=this,a=this._readableState&&this._readableState.destroyed,s=this._writableState&&this._writableState.destroyed;return a||s?(r?r(e):e&&(this._writableState?this._writableState.errorEmitted||(this._writableState.errorEmitted=!0,process.nextTick(o,this,e)):process.nextTick(o,this,e)),this):(this._readableState&&(this._readableState.destroyed=!0),this._writableState&&(this._writableState.destroyed=!0),this._destroy(e||null,(function(e){!r&&e?i._writableState?i._writableState.errorEmitted?process.nextTick(n,i):(i._writableState.errorEmitted=!0,process.nextTick(t,i,e)):process.nextTick(t,i,e):r?(process.nextTick(n,i),r(e)):process.nextTick(n,i)})),this)},undestroy:function(){this._readableState&&(this._readableState.destroyed=!1,this._readableState.reading=!1,this._readableState.ended=!1,this._readableState.endEmitted=!1),this._writableState&&(this._writableState.destroyed=!1,this._writableState.ended=!1,this._writableState.ending=!1,this._writableState.finalCalled=!1,this._writableState.prefinished=!1,this._writableState.finished=!1,this._writableState.errorEmitted=!1)},errorOrDestroy:function(e,t){var n=e._readableState,o=e._writableState;n&&n.autoDestroy||o&&o.autoDestroy?e.destroy(t):e.emit("error",t)}}},28640:(e,t,n)=>{"use strict";var o=n(9786).q.ERR_STREAM_PREMATURE_CLOSE;function r(){}e.exports=function e(t,n,i){if("function"==typeof n)return e(t,null,n);n||(n={}),i=function(e){var t=!1;return function(){if(!t){t=!0;for(var n=arguments.length,o=new Array(n),r=0;r{e.exports=function(){throw new Error("Readable.from is not available in the browser")}},64218:(e,t,n)=>{"use strict";var o,r=n(9786).q,i=r.ERR_MISSING_ARGS,a=r.ERR_STREAM_DESTROYED;function s(e){if(e)throw e}function u(e,t,r,i){i=function(e){var t=!1;return function(){t||(t=!0,e.apply(void 0,arguments))}}(i);var s=!1;e.on("close",(function(){s=!0})),void 0===o&&(o=n(28640)),o(e,{readable:t,writable:r},(function(e){if(e)return i(e);s=!0,i()}));var u=!1;return function(t){if(!s&&!u)return u=!0,function(e){return e.setHeader&&"function"==typeof e.abort}(e)?e.abort():"function"==typeof e.destroy?e.destroy():void i(t||new a("pipe"))}}function c(e){e()}function l(e,t){return e.pipe(t)}function d(e){return e.length?"function"!=typeof e[e.length-1]?s:e.pop():s}e.exports=function(){for(var e=arguments.length,t=new Array(e),n=0;n0,(function(e){o||(o=e),e&&a.forEach(c),i||(a.forEach(c),r(o))}))}));return t.reduce(l)}},31222:(e,t,n)=>{"use strict";var o=n(9786).q.ERR_INVALID_OPT_VALUE;e.exports={getHighWaterMark:function(e,t,n,r){var i=function(e,t,n){return null!=e.highWaterMark?e.highWaterMark:t?e[n]:null}(t,r,n);if(null!=i){if(!isFinite(i)||Math.floor(i)!==i||i<0)throw new o(r?n:"highWaterMark",i);return Math.floor(i)}return e.objectMode?16:16384}}},50677:(e,t,n)=>{e.exports=n(17187).EventEmitter},70326:(e,t,n)=>{(t=e.exports=n(76748)).Stream=t,t.Readable=t,t.Writable=n(70469),t.Duplex=n(62910),t.Transform=n(70421),t.PassThrough=n(58994),t.finished=n(28640),t.pipeline=n(64218)},33715:(e,t,n)=>{var o=t;o.utils=n(26436),o.common=n(95772),o.sha=n(89041),o.ripemd=n(12949),o.hmac=n(52344),o.sha1=o.sha.sha1,o.sha256=o.sha.sha256,o.sha224=o.sha.sha224,o.sha384=o.sha.sha384,o.sha512=o.sha.sha512,o.ripemd160=o.ripemd.ripemd160},95772:(e,t,n)=>{"use strict";var o=n(26436),r=n(79746);function i(){this.pending=null,this.pendingTotal=0,this.blockSize=this.constructor.blockSize,this.outSize=this.constructor.outSize,this.hmacStrength=this.constructor.hmacStrength,this.padLength=this.constructor.padLength/8,this.endian="big",this._delta8=this.blockSize/8,this._delta32=this.blockSize/32}t.BlockHash=i,i.prototype.update=function(e,t){if(e=o.toArray(e,t),this.pending?this.pending=this.pending.concat(e):this.pending=e,this.pendingTotal+=e.length,this.pending.length>=this._delta8){var n=(e=this.pending).length%this._delta8;this.pending=e.slice(e.length-n,e.length),0===this.pending.length&&(this.pending=null),e=o.join32(e,0,e.length-n,this.endian);for(var r=0;r>>24&255,o[r++]=e>>>16&255,o[r++]=e>>>8&255,o[r++]=255&e}else for(o[r++]=255&e,o[r++]=e>>>8&255,o[r++]=e>>>16&255,o[r++]=e>>>24&255,o[r++]=0,o[r++]=0,o[r++]=0,o[r++]=0,i=8;i{"use strict";var o=n(26436),r=n(79746);function i(e,t,n){if(!(this instanceof i))return new i(e,t,n);this.Hash=e,this.blockSize=e.blockSize/8,this.outSize=e.outSize/8,this.inner=null,this.outer=null,this._init(o.toArray(t,n))}e.exports=i,i.prototype._init=function(e){e.length>this.blockSize&&(e=(new this.Hash).update(e).digest()),r(e.length<=this.blockSize);for(var t=e.length;t{"use strict";var o=n(26436),r=n(95772),i=o.rotl32,a=o.sum32,s=o.sum32_3,u=o.sum32_4,c=r.BlockHash;function l(){if(!(this instanceof l))return new l;c.call(this),this.h=[1732584193,4023233417,2562383102,271733878,3285377520],this.endian="little"}function d(e,t,n,o){return e<=15?t^n^o:e<=31?t&n|~t&o:e<=47?(t|~n)^o:e<=63?t&o|n&~o:t^(n|~o)}function h(e){return e<=15?0:e<=31?1518500249:e<=47?1859775393:e<=63?2400959708:2840853838}function p(e){return e<=15?1352829926:e<=31?1548603684:e<=47?1836072691:e<=63?2053994217:0}o.inherits(l,c),t.ripemd160=l,l.blockSize=512,l.outSize=160,l.hmacStrength=192,l.padLength=64,l.prototype._update=function(e,t){for(var n=this.h[0],o=this.h[1],r=this.h[2],c=this.h[3],l=this.h[4],F=n,y=o,b=r,v=c,w=l,E=0;E<80;E++){var k=a(i(u(n,d(E,o,r,c),e[f[E]+t],h(E)),m[E]),l);n=l,l=c,c=i(r,10),r=o,o=k,k=a(i(u(F,d(79-E,y,b,v),e[g[E]+t],p(E)),_[E]),w),F=w,w=v,v=i(b,10),b=y,y=k}k=s(this.h[1],r,v),this.h[1]=s(this.h[2],c,w),this.h[2]=s(this.h[3],l,F),this.h[3]=s(this.h[4],n,y),this.h[4]=s(this.h[0],o,b),this.h[0]=k},l.prototype._digest=function(e){return"hex"===e?o.toHex32(this.h,"little"):o.split32(this.h,"little")};var f=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,7,4,13,1,10,6,15,3,12,0,9,5,2,14,11,8,3,10,14,4,9,15,8,1,2,7,0,6,13,11,5,12,1,9,11,10,0,8,12,4,13,3,7,15,14,5,6,2,4,0,5,9,7,12,2,10,14,1,3,8,11,6,15,13],g=[5,14,7,0,9,2,11,4,13,6,15,8,1,10,3,12,6,11,3,7,0,13,5,10,14,15,8,12,4,9,1,2,15,5,1,3,7,14,6,9,11,8,12,2,10,0,4,13,8,6,4,1,3,11,15,0,5,12,2,13,9,7,10,14,12,15,10,4,1,5,8,7,6,2,13,14,0,3,9,11],m=[11,14,15,12,5,8,7,9,11,13,14,15,6,7,9,8,7,6,8,13,11,9,7,15,7,12,15,9,11,7,13,12,11,13,6,7,14,9,13,15,14,8,13,6,5,12,7,5,11,12,14,15,14,15,9,8,9,14,5,6,8,6,5,12,9,15,5,11,6,8,13,12,5,12,13,14,11,8,5,6],_=[8,9,9,11,13,15,15,5,7,7,8,11,14,14,12,6,9,13,15,7,12,8,9,11,7,7,12,7,6,15,13,11,9,7,15,11,8,6,6,14,12,13,5,14,13,13,7,5,15,5,8,11,14,14,6,14,6,9,12,9,12,5,15,8,8,5,12,9,12,5,14,6,8,13,6,5,15,13,11,11]},89041:(e,t,n)=>{"use strict";t.sha1=n(84761),t.sha224=n(10799),t.sha256=n(89344),t.sha384=n(80772),t.sha512=n(45900)},84761:(e,t,n)=>{"use strict";var o=n(26436),r=n(95772),i=n(37038),a=o.rotl32,s=o.sum32,u=o.sum32_5,c=i.ft_1,l=r.BlockHash,d=[1518500249,1859775393,2400959708,3395469782];function h(){if(!(this instanceof h))return new h;l.call(this),this.h=[1732584193,4023233417,2562383102,271733878,3285377520],this.W=new Array(80)}o.inherits(h,l),e.exports=h,h.blockSize=512,h.outSize=160,h.hmacStrength=80,h.padLength=64,h.prototype._update=function(e,t){for(var n=this.W,o=0;o<16;o++)n[o]=e[t+o];for(;o{"use strict";var o=n(26436),r=n(89344);function i(){if(!(this instanceof i))return new i;r.call(this),this.h=[3238371032,914150663,812702999,4144912697,4290775857,1750603025,1694076839,3204075428]}o.inherits(i,r),e.exports=i,i.blockSize=512,i.outSize=224,i.hmacStrength=192,i.padLength=64,i.prototype._digest=function(e){return"hex"===e?o.toHex32(this.h.slice(0,7),"big"):o.split32(this.h.slice(0,7),"big")}},89344:(e,t,n)=>{"use strict";var o=n(26436),r=n(95772),i=n(37038),a=n(79746),s=o.sum32,u=o.sum32_4,c=o.sum32_5,l=i.ch32,d=i.maj32,h=i.s0_256,p=i.s1_256,f=i.g0_256,g=i.g1_256,m=r.BlockHash,_=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298];function F(){if(!(this instanceof F))return new F;m.call(this),this.h=[1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225],this.k=_,this.W=new Array(64)}o.inherits(F,m),e.exports=F,F.blockSize=512,F.outSize=256,F.hmacStrength=192,F.padLength=64,F.prototype._update=function(e,t){for(var n=this.W,o=0;o<16;o++)n[o]=e[t+o];for(;o{"use strict";var o=n(26436),r=n(45900);function i(){if(!(this instanceof i))return new i;r.call(this),this.h=[3418070365,3238371032,1654270250,914150663,2438529370,812702999,355462360,4144912697,1731405415,4290775857,2394180231,1750603025,3675008525,1694076839,1203062813,3204075428]}o.inherits(i,r),e.exports=i,i.blockSize=1024,i.outSize=384,i.hmacStrength=192,i.padLength=128,i.prototype._digest=function(e){return"hex"===e?o.toHex32(this.h.slice(0,12),"big"):o.split32(this.h.slice(0,12),"big")}},45900:(e,t,n)=>{"use strict";var o=n(26436),r=n(95772),i=n(79746),a=o.rotr64_hi,s=o.rotr64_lo,u=o.shr64_hi,c=o.shr64_lo,l=o.sum64,d=o.sum64_hi,h=o.sum64_lo,p=o.sum64_4_hi,f=o.sum64_4_lo,g=o.sum64_5_hi,m=o.sum64_5_lo,_=r.BlockHash,F=[1116352408,3609767458,1899447441,602891725,3049323471,3964484399,3921009573,2173295548,961987163,4081628472,1508970993,3053834265,2453635748,2937671579,2870763221,3664609560,3624381080,2734883394,310598401,1164996542,607225278,1323610764,1426881987,3590304994,1925078388,4068182383,2162078206,991336113,2614888103,633803317,3248222580,3479774868,3835390401,2666613458,4022224774,944711139,264347078,2341262773,604807628,2007800933,770255983,1495990901,1249150122,1856431235,1555081692,3175218132,1996064986,2198950837,2554220882,3999719339,2821834349,766784016,2952996808,2566594879,3210313671,3203337956,3336571891,1034457026,3584528711,2466948901,113926993,3758326383,338241895,168717936,666307205,1188179964,773529912,1546045734,1294757372,1522805485,1396182291,2643833823,1695183700,2343527390,1986661051,1014477480,2177026350,1206759142,2456956037,344077627,2730485921,1290863460,2820302411,3158454273,3259730800,3505952657,3345764771,106217008,3516065817,3606008344,3600352804,1432725776,4094571909,1467031594,275423344,851169720,430227734,3100823752,506948616,1363258195,659060556,3750685593,883997877,3785050280,958139571,3318307427,1322822218,3812723403,1537002063,2003034995,1747873779,3602036899,1955562222,1575990012,2024104815,1125592928,2227730452,2716904306,2361852424,442776044,2428436474,593698344,2756734187,3733110249,3204031479,2999351573,3329325298,3815920427,3391569614,3928383900,3515267271,566280711,3940187606,3454069534,4118630271,4000239992,116418474,1914138554,174292421,2731055270,289380356,3203993006,460393269,320620315,685471733,587496836,852142971,1086792851,1017036298,365543100,1126000580,2618297676,1288033470,3409855158,1501505948,4234509866,1607167915,987167468,1816402316,1246189591];function y(){if(!(this instanceof y))return new y;_.call(this),this.h=[1779033703,4089235720,3144134277,2227873595,1013904242,4271175723,2773480762,1595750129,1359893119,2917565137,2600822924,725511199,528734635,4215389547,1541459225,327033209],this.k=F,this.W=new Array(160)}function b(e,t,n,o,r){var i=e&n^~e&r;return i<0&&(i+=4294967296),i}function v(e,t,n,o,r,i){var a=t&o^~t&i;return a<0&&(a+=4294967296),a}function w(e,t,n,o,r){var i=e&n^e&r^n&r;return i<0&&(i+=4294967296),i}function E(e,t,n,o,r,i){var a=t&o^t&i^o&i;return a<0&&(a+=4294967296),a}function k(e,t){var n=a(e,t,28)^a(t,e,2)^a(t,e,7);return n<0&&(n+=4294967296),n}function D(e,t){var n=s(e,t,28)^s(t,e,2)^s(t,e,7);return n<0&&(n+=4294967296),n}function S(e,t){var n=s(e,t,14)^s(e,t,18)^s(t,e,9);return n<0&&(n+=4294967296),n}function x(e,t){var n=a(e,t,1)^a(e,t,8)^u(e,t,7);return n<0&&(n+=4294967296),n}function C(e,t){var n=s(e,t,1)^s(e,t,8)^c(e,t,7);return n<0&&(n+=4294967296),n}function A(e,t){var n=s(e,t,19)^s(t,e,29)^c(e,t,6);return n<0&&(n+=4294967296),n}o.inherits(y,_),e.exports=y,y.blockSize=1024,y.outSize=512,y.hmacStrength=192,y.padLength=128,y.prototype._prepareBlock=function(e,t){for(var n=this.W,o=0;o<32;o++)n[o]=e[t+o];for(;o{"use strict";var o=n(26436).rotr32;function r(e,t,n){return e&t^~e&n}function i(e,t,n){return e&t^e&n^t&n}function a(e,t,n){return e^t^n}t.ft_1=function(e,t,n,o){return 0===e?r(t,n,o):1===e||3===e?a(t,n,o):2===e?i(t,n,o):void 0},t.ch32=r,t.maj32=i,t.p32=a,t.s0_256=function(e){return o(e,2)^o(e,13)^o(e,22)},t.s1_256=function(e){return o(e,6)^o(e,11)^o(e,25)},t.g0_256=function(e){return o(e,7)^o(e,18)^e>>>3},t.g1_256=function(e){return o(e,17)^o(e,19)^e>>>10}},26436:(e,t,n)=>{"use strict";var o=n(79746),r=n(35717);function i(e,t){return 55296==(64512&e.charCodeAt(t))&&!(t<0||t+1>=e.length)&&56320==(64512&e.charCodeAt(t+1))}function a(e){return(e>>>24|e>>>8&65280|e<<8&16711680|(255&e)<<24)>>>0}function s(e){return 1===e.length?"0"+e:e}function u(e){return 7===e.length?"0"+e:6===e.length?"00"+e:5===e.length?"000"+e:4===e.length?"0000"+e:3===e.length?"00000"+e:2===e.length?"000000"+e:1===e.length?"0000000"+e:e}t.inherits=r,t.toArray=function(e,t){if(Array.isArray(e))return e.slice();if(!e)return[];var n=[];if("string"==typeof e)if(t){if("hex"===t)for((e=e.replace(/[^a-z0-9]+/gi,"")).length%2!=0&&(e="0"+e),r=0;r>6|192,n[o++]=63&a|128):i(e,r)?(a=65536+((1023&a)<<10)+(1023&e.charCodeAt(++r)),n[o++]=a>>18|240,n[o++]=a>>12&63|128,n[o++]=a>>6&63|128,n[o++]=63&a|128):(n[o++]=a>>12|224,n[o++]=a>>6&63|128,n[o++]=63&a|128)}else for(r=0;r>>0}return a},t.split32=function(e,t){for(var n=new Array(4*e.length),o=0,r=0;o>>24,n[r+1]=i>>>16&255,n[r+2]=i>>>8&255,n[r+3]=255&i):(n[r+3]=i>>>24,n[r+2]=i>>>16&255,n[r+1]=i>>>8&255,n[r]=255&i)}return n},t.rotr32=function(e,t){return e>>>t|e<<32-t},t.rotl32=function(e,t){return e<>>32-t},t.sum32=function(e,t){return e+t>>>0},t.sum32_3=function(e,t,n){return e+t+n>>>0},t.sum32_4=function(e,t,n,o){return e+t+n+o>>>0},t.sum32_5=function(e,t,n,o,r){return e+t+n+o+r>>>0},t.sum64=function(e,t,n,o){var r=e[t],i=o+e[t+1]>>>0,a=(i>>0,e[t+1]=i},t.sum64_hi=function(e,t,n,o){return(t+o>>>0>>0},t.sum64_lo=function(e,t,n,o){return t+o>>>0},t.sum64_4_hi=function(e,t,n,o,r,i,a,s){var u=0,c=t;return u+=(c=c+o>>>0)>>0)>>0)>>0},t.sum64_4_lo=function(e,t,n,o,r,i,a,s){return t+o+i+s>>>0},t.sum64_5_hi=function(e,t,n,o,r,i,a,s,u,c){var l=0,d=t;return l+=(d=d+o>>>0)>>0)>>0)>>0)>>0},t.sum64_5_lo=function(e,t,n,o,r,i,a,s,u,c){return t+o+i+s+c>>>0},t.rotr64_hi=function(e,t,n){return(t<<32-n|e>>>n)>>>0},t.rotr64_lo=function(e,t,n){return(e<<32-n|t>>>n)>>>0},t.shr64_hi=function(e,t,n){return e>>>n},t.shr64_lo=function(e,t,n){return(e<<32-n|t>>>n)>>>0}},78892:e=>{"use strict";e.exports=function(e,n){for(var o,r,i,a=e||"",s=n||"div",u={},c=0;c{"use strict";var o=n(99560),r=n(66632),i=n(78892),a=n(36582).parse,s=n(56851).parse;e.exports=function(e,t,n){var r=n?function(e){for(var t,n=e.length,o=-1,r={};++o{"use strict";var o=n(97247),r=n(62686)(o,"div");r.displayName="html",e.exports=r},31742:(e,t,n)=>{"use strict";e.exports=n(52579)},2156:(e,t,n)=>{"use strict";var o=n(33715),r=n(34504),i=n(79746);function a(e){if(!(this instanceof a))return new a(e);this.hash=e.hash,this.predResist=!!e.predResist,this.outLen=this.hash.outSize,this.minEntropy=e.minEntropy||this.hash.hmacStrength,this._reseed=null,this.reseedInterval=null,this.K=null,this.V=null;var t=r.toArray(e.entropy,e.entropyEnc||"hex"),n=r.toArray(e.nonce,e.nonceEnc||"hex"),o=r.toArray(e.pers,e.persEnc||"hex");i(t.length>=this.minEntropy/8,"Not enough entropy. Minimum is: "+this.minEntropy+" bits"),this._init(t,n,o)}e.exports=a,a.prototype._init=function(e,t,n){var o=e.concat(t).concat(n);this.K=new Array(this.outLen/8),this.V=new Array(this.outLen/8);for(var r=0;r=this.minEntropy/8,"Not enough entropy. Minimum is: "+this.minEntropy+" bits"),this._update(e.concat(n||[])),this._reseed=1},a.prototype.generate=function(e,t,n,o){if(this._reseed>this.reseedInterval)throw new Error("Reseed is required");"string"!=typeof t&&(o=n,n=t,t=null),n&&(n=r.toArray(n,o||"hex"),this._update(n));for(var i=[];i.length{"use strict";var o=n(59864),r={childContextTypes:!0,contextType:!0,contextTypes:!0,defaultProps:!0,displayName:!0,getDefaultProps:!0,getDerivedStateFromError:!0,getDerivedStateFromProps:!0,mixins:!0,propTypes:!0,type:!0},i={name:!0,length:!0,prototype:!0,caller:!0,callee:!0,arguments:!0,arity:!0},a={$$typeof:!0,compare:!0,defaultProps:!0,displayName:!0,propTypes:!0,type:!0},s={};function u(e){return o.isMemo(e)?a:s[e.$$typeof]||r}s[o.ForwardRef]={$$typeof:!0,render:!0,defaultProps:!0,displayName:!0,propTypes:!0},s[o.Memo]=a;var c=Object.defineProperty,l=Object.getOwnPropertyNames,d=Object.getOwnPropertySymbols,h=Object.getOwnPropertyDescriptor,p=Object.getPrototypeOf,f=Object.prototype;e.exports=function e(t,n,o){if("string"!=typeof n){if(f){var r=p(n);r&&r!==f&&e(t,r,o)}var a=l(n);d&&(a=a.concat(d(n)));for(var s=u(t),g=u(n),m=0;m{e.exports={CASE_SENSITIVE_TAG_NAMES:["animateMotion","animateTransform","clipPath","feBlend","feColorMatrix","feComponentTransfer","feComposite","feConvolveMatrix","feDiffuseLighting","feDisplacementMap","feDropShadow","feFlood","feFuncA","feFuncB","feFuncG","feFuncR","feGaussainBlur","feImage","feMerge","feMergeNode","feMorphology","feOffset","fePointLight","feSpecularLighting","feSpotLight","feTile","feTurbulence","foreignObject","linearGradient","radialGradient","textPath"]}},38276:(e,t,n)=>{var o="html",r="head",i="body",a=/<([a-zA-Z]+[0-9]?)/,s=//i,u=//i,c=function(){throw new Error("This browser does not support `document.implementation.createHTMLDocument`")},l=function(){throw new Error("This browser does not support `DOMParser.prototype.parseFromString`")};if("function"==typeof window.DOMParser){var d=new window.DOMParser;c=l=function(e,t){return t&&(e="<"+t+">"+e+""),d.parseFromString(e,"text/html")}}if(document.implementation){var h=n(1507).isIE,p=document.implementation.createHTMLDocument(h()?"html-dom-parser":void 0);c=function(e,t){return t?(p.documentElement.getElementsByTagName(t)[0].innerHTML=e,p):(p.documentElement.innerHTML=e,p)}}var f,g=document.createElement("template");g.content&&(f=function(e){return g.innerHTML=e,g.content.childNodes}),e.exports=function(e){var t,n,d,h,p=e.match(a);switch(p&&p[1]&&(t=p[1].toLowerCase()),t){case o:return n=l(e),s.test(e)||(d=n.getElementsByTagName(r)[0])&&d.parentNode.removeChild(d),u.test(e)||(d=n.getElementsByTagName(i)[0])&&d.parentNode.removeChild(d),n.getElementsByTagName(o);case r:case i:return h=c(e).getElementsByTagName(t),u.test(e)&&s.test(e)?h[0].parentNode.childNodes:h;default:return f?f(e):c(e,i).getElementsByTagName(i)[0].childNodes}}},14152:(e,t,n)=>{var o=n(38276),r=n(1507).formatDOM,i=/<(![a-zA-Z\s]+)>/;e.exports=function(e){if("string"!=typeof e)throw new TypeError("First argument must be a string");if(""===e)return[];var t,n=e.match(i);return n&&n[1]&&(t=n[1]),r(o(e),null,t)}},1507:(e,t,n)=>{for(var o,r=n(60885),i=n(21642),a=r.CASE_SENSITIVE_TAG_NAMES,s=i.Comment,u=i.Element,c=i.ProcessingInstruction,l=i.Text,d={},h=0,p=a.length;h{"use strict";var n;Object.defineProperty(t,"__esModule",{value:!0}),t.Doctype=t.CDATA=t.Tag=t.Style=t.Script=t.Comment=t.Directive=t.Text=t.Root=t.isTag=t.ElementType=void 0,function(e){e.Root="root",e.Text="text",e.Directive="directive",e.Comment="comment",e.Script="script",e.Style="style",e.Tag="tag",e.CDATA="cdata",e.Doctype="doctype"}(n=t.ElementType||(t.ElementType={})),t.isTag=function(e){return e.type===n.Tag||e.type===n.Script||e.type===n.Style},t.Root=n.Root,t.Text=n.Text,t.Directive=n.Directive,t.Comment=n.Comment,t.Script=n.Script,t.Style=n.Style,t.Tag=n.Tag,t.CDATA=n.CDATA,t.Doctype=n.Doctype},21642:function(e,t,n){"use strict";var o,r=this&&this.__extends||(o=function(e,t){return(o=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])})(e,t)},function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");function n(){this.constructor=e}o(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}),i=this&&this.__assign||function(){return(i=Object.assign||function(e){for(var t,n=1,o=arguments.length;n0?this.children[this.children.length-1]:null},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"childNodes",{get:function(){return this.children},set:function(e){this.children=e},enumerable:!1,configurable:!0}),t}(u);t.NodeWithChildren=p;var f=function(e){function t(t){return e.call(this,a.ElementType.Root,t)||this}return r(t,e),t}(p);t.Document=f;var g=function(e){function t(t,n,o,r){void 0===o&&(o=[]),void 0===r&&(r="script"===t?a.ElementType.Script:"style"===t?a.ElementType.Style:a.ElementType.Tag);var i=e.call(this,r,o)||this;return i.name=t,i.attribs=n,i}return r(t,e),Object.defineProperty(t.prototype,"tagName",{get:function(){return this.name},set:function(e){this.name=e},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"attributes",{get:function(){var e=this;return Object.keys(this.attribs).map((function(t){var n,o;return{name:t,value:e.attribs[t],namespace:null===(n=e["x-attribsNamespace"])||void 0===n?void 0:n[t],prefix:null===(o=e["x-attribsPrefix"])||void 0===o?void 0:o[t]}}))},enumerable:!1,configurable:!0}),t}(p);function m(e){return a.isTag(e)}function _(e){return e.type===a.ElementType.CDATA}function F(e){return e.type===a.ElementType.Text}function y(e){return e.type===a.ElementType.Comment}function b(e){return e.type===a.ElementType.Directive}function v(e){return e.type===a.ElementType.Root}function w(e,t){var n;if(void 0===t&&(t=!1),F(e))n=new l(e.data);else if(y(e))n=new d(e.data);else if(m(e)){var o=t?E(e.children):[],r=new g(e.name,i({},e.attribs),o);o.forEach((function(e){return e.parent=r})),e["x-attribsNamespace"]&&(r["x-attribsNamespace"]=i({},e["x-attribsNamespace"])),e["x-attribsPrefix"]&&(r["x-attribsPrefix"]=i({},e["x-attribsPrefix"])),n=r}else if(_(e)){o=t?E(e.children):[];var s=new p(a.ElementType.CDATA,o);o.forEach((function(e){return e.parent=s})),n=s}else if(v(e)){o=t?E(e.children):[];var u=new f(o);o.forEach((function(e){return e.parent=u})),e["x-mode"]&&(u["x-mode"]=e["x-mode"]),n=u}else{if(!b(e))throw new Error("Not implemented yet: "+e.type);var c=new h(e.name,e.data);null!=e["x-name"]&&(c["x-name"]=e["x-name"],c["x-publicId"]=e["x-publicId"],c["x-systemId"]=e["x-systemId"]),n=c}return n.startIndex=e.startIndex,n.endIndex=e.endIndex,n}function E(e){for(var t=e.map((function(e){return w(e,!0)})),n=1;n{var o=n(53670),r=n(50484),i=n(14152),a={lowerCaseAttributeNames:!1};function s(e,t){if("string"!=typeof e)throw new TypeError("First argument must be a string");return""===e?[]:o(i(e,(t=t||{}).htmlparser2||a),t)}s.domToReact=o,s.htmlToDOM=i,s.attributesToProps=r,e.exports=s,e.exports.default=s},50484:(e,t,n)=>{var o=n(32686),r=n(74606),i=r.setStyleProp,a=o.html,s=o.svg,u=o.isCustomAttribute,c=Object.prototype.hasOwnProperty;e.exports=function(e){var t,n,o,l;e=e||{};var d={};for(t in e)o=e[t],u(t)?d[t]=o:(n=t.toLowerCase(),c.call(a,n)?d[(l=a[n]).propertyName]=!!(l.hasBooleanValue||l.hasOverloadedBooleanValue&&!o)||o:c.call(s,t)?d[(l=s[t]).propertyName]=o:r.PRESERVE_CUSTOM_ATTRIBUTES&&(d[t]=o));return i(e.style,d),d}},53670:(e,t,n)=>{var o=n(67294),r=n(50484),i=n(74606),a=i.setStyleProp;function s(e){return i.PRESERVE_CUSTOM_ATTRIBUTES&&"tag"===e.type&&i.isCustomComponent(e.name,e.attribs)}e.exports=function e(t,n){for(var i,u,c,l,d=(n=n||{}).library||o,h=d.cloneElement,p=d.createElement,f=d.isValidElement,g=[],m="function"==typeof n.replace,_=n.trim,F=0,y=t.length;F1&&(u=h(u,{key:u.key||F})),g.push(u);else if("text"!==i.type){switch(c=i.attribs,s(i)?a(c.style,c):c&&(c=r(c)),l=null,i.type){case"script":case"style":i.children[0]&&(c.dangerouslySetInnerHTML={__html:i.children[0].data});break;case"tag":"textarea"===i.name&&i.children[0]?c.defaultValue=i.children[0].data:i.children&&i.children.length&&(l=e(i.children,n));break;default:continue}y>1&&(c.key=F),g.push(p(i.name,c,l))}else _?i.data.trim()&&g.push(i.data):g.push(i.data);return 1===g.length?g[0]:g}},74606:(e,t,n)=>{var o=n(67294),r=n(41476).default,i={reactCompat:!0},a=o.version.split(".")[0]>=16;e.exports={PRESERVE_CUSTOM_ATTRIBUTES:a,invertObject:function(e,t){if(!e||"object"!=typeof e)throw new TypeError("First argument must be an object");var n,o,r="function"==typeof t,i={},a={};for(n in e)o=e[n],r&&(i=t(n,o))&&2===i.length?a[i[0]]=i[1]:"string"==typeof o&&(a[o]=n);return a},isCustomComponent:function(e,t){if(-1===e.indexOf("-"))return t&&"string"==typeof t.is;switch(e){case"annotation-xml":case"color-profile":case"font-face":case"font-face-src":case"font-face-uri":case"font-face-format":case"font-face-name":case"missing-glyph":return!1;default:return!0}},setStyleProp:function(e,t){null!=e&&(t.style=r(e,i))}}},89043:function(e,t,n){var o,r;!function(i,a,s){"use strict";void 0===(r="function"==typeof(o=function(){var e=function(e){throw e},t=function(){},n={storeName:"Store",storePrefix:"IDBWrapper-",dbVersion:1,keyPath:"id",autoIncrement:!0,onStoreReady:function(){},onError:e,indexes:[],implementationPreference:["indexedDB","webkitIndexedDB","mozIndexedDB","shimIndexedDB"]},o=function(e,t){for(var o in void 0===t&&"function"==typeof e&&(t=e),"[object Object]"!=Object.prototype.toString.call(e)&&(e={}),n)this[o]=void 0!==e[o]?e[o]:n[o];this.dbName=this.storePrefix+this.storeName,this.dbVersion=parseInt(this.dbVersion,10)||1,t&&(this.onStoreReady=t);var r="object"==typeof window?window:self,i=this.implementationPreference.filter((function(e){return e in r}));this.implementation=i[0],this.idb=r[this.implementation],this.keyRange=r.IDBKeyRange||r.webkitIDBKeyRange||r.mozIDBKeyRange,this.consts={READ_ONLY:"readonly",READ_WRITE:"readwrite",VERSION_CHANGE:"versionchange",NEXT:"next",NEXT_NO_DUPLICATE:"nextunique",PREV:"prev",PREV_NO_DUPLICATE:"prevunique"},this.openDB()},r={constructor:o,version:"1.7.2",db:null,dbName:null,dbVersion:null,store:null,storeName:null,storePrefix:null,keyPath:null,autoIncrement:null,indexes:null,implementationPreference:null,implementation:"",onStoreReady:null,onError:null,_insertIdCount:0,openDB:function(){var e=this.idb.open(this.dbName,this.dbVersion),t=!1;e.onerror=function(e){if(function(e){return"error"in e.target?"VersionError"==e.target.error.name:"errorCode"in e.target&&12==e.target.errorCode}(e))this.onError(new Error("The version number provided is lower than the existing one."));else{var t;if(e.target.error)t=e.target.error;else{var n="IndexedDB unknown error occurred when opening DB "+this.dbName+" version "+this.dbVersion;"errorCode"in e.target&&(n+=" with error code "+e.target.errorCode),t=new Error(n)}this.onError(t)}}.bind(this),e.onsuccess=function(e){if(!t)if(this.db)this.onStoreReady();else if(this.db=e.target.result,"string"!=typeof this.db.version)if(this.db.objectStoreNames.contains(this.storeName)){var n=this.db.transaction([this.storeName],this.consts.READ_ONLY);this.store=n.objectStore(this.storeName);var o=Array.prototype.slice.call(this.getIndexList());this.indexes.forEach((function(e){var n=e.name;if(!n)return t=!0,void this.onError(new Error("Cannot create index: No index name given."));if(this.normalizeIndexData(e),this.hasIndex(n)){var r=this.store.index(n);this.indexComplies(r,e)||(t=!0,this.onError(new Error('Cannot modify index "'+n+'" for current version. Please bump version number to '+(this.dbVersion+1)+"."))),o.splice(o.indexOf(n),1)}else t=!0,this.onError(new Error('Cannot create new index "'+n+'" for current version. Please bump version number to '+(this.dbVersion+1)+"."))}),this),o.length&&(t=!0,this.onError(new Error('Cannot delete index(es) "'+o.toString()+'" for current version. Please bump version number to '+(this.dbVersion+1)+"."))),t||this.onStoreReady()}else this.onError(new Error("Object store couldn't be created."));else this.onError(new Error("The IndexedDB implementation in this browser is outdated. Please upgrade your browser."))}.bind(this),e.onupgradeneeded=function(e){if(this.db=e.target.result,this.db.objectStoreNames.contains(this.storeName))this.store=e.target.transaction.objectStore(this.storeName);else{var n={autoIncrement:this.autoIncrement};null!==this.keyPath&&(n.keyPath=this.keyPath),this.store=this.db.createObjectStore(this.storeName,n)}var o=Array.prototype.slice.call(this.getIndexList());this.indexes.forEach((function(e){var n=e.name;if(n||(t=!0,this.onError(new Error("Cannot create index: No index name given."))),this.normalizeIndexData(e),this.hasIndex(n)){var r=this.store.index(n);this.indexComplies(r,e)||(this.store.deleteIndex(n),this.store.createIndex(n,e.keyPath,{unique:e.unique,multiEntry:e.multiEntry})),o.splice(o.indexOf(n),1)}else this.store.createIndex(n,e.keyPath,{unique:e.unique,multiEntry:e.multiEntry})}),this),o.length&&o.forEach((function(e){this.store.deleteIndex(e)}),this)}.bind(this)},deleteDatabase:function(e,t){if(this.idb.deleteDatabase){this.db.close();var n=this.idb.deleteDatabase(this.dbName);n.onsuccess=e,n.onerror=t}else t(new Error("Browser does not support IndexedDB deleteDatabase!"))},put:function(n,o,r,i){null!==this.keyPath&&(i=r,r=o,o=n),i||(i=e),r||(r=t);var a,s=!1,u=null,c=this.db.transaction([this.storeName],this.consts.READ_WRITE);return c.oncomplete=function(){(s?r:i)(u)},c.onabort=i,c.onerror=i,null!==this.keyPath?(this._addIdPropertyIfNeeded(o),a=c.objectStore(this.storeName).put(o)):a=c.objectStore(this.storeName).put(o,n),a.onsuccess=function(e){s=!0,u=e.target.result},a.onerror=i,c},get:function(n,o,r){r||(r=e),o||(o=t);var i=!1,a=null,s=this.db.transaction([this.storeName],this.consts.READ_ONLY);s.oncomplete=function(){(i?o:r)(a)},s.onabort=r,s.onerror=r;var u=s.objectStore(this.storeName).get(n);return u.onsuccess=function(e){i=!0,a=e.target.result},u.onerror=r,s},remove:function(n,o,r){r||(r=e),o||(o=t);var i=!1,a=null,s=this.db.transaction([this.storeName],this.consts.READ_WRITE);s.oncomplete=function(){(i?o:r)(a)},s.onabort=r,s.onerror=r;var u=s.objectStore(this.storeName).delete(n);return u.onsuccess=function(e){i=!0,a=e.target.result},u.onerror=r,s},batch:function(n,o,r){if(r||(r=e),o||(o=t),"[object Array]"!=Object.prototype.toString.call(n))r(new Error("dataArray argument must be of type Array."));else if(0===n.length)return o(!0);var i=n.length,a=!1,s=!1,u=this.db.transaction([this.storeName],this.consts.READ_WRITE);u.oncomplete=function(){(s?o:r)(s)},u.onabort=r,u.onerror=r;var c=function(){0!=--i||a||(a=!0,s=!0)};return n.forEach((function(e){var t=e.type,n=e.key,o=e.value,i=function(e){u.abort(),a||(a=!0,r(e,t,n))};if("remove"==t){var s=u.objectStore(this.storeName).delete(n);s.onsuccess=c,s.onerror=i}else if("put"==t){var l;null!==this.keyPath?(this._addIdPropertyIfNeeded(o),l=u.objectStore(this.storeName).put(o)):l=u.objectStore(this.storeName).put(o,n),l.onsuccess=c,l.onerror=i}}),this),u},putBatch:function(e,t,n){var o=e.map((function(e){return{type:"put",value:e}}));return this.batch(o,t,n)},upsertBatch:function(n,o,r,i){"function"==typeof o&&(i=r=o,o={}),i||(i=e),r||(r=t),o||(o={}),"[object Array]"!=Object.prototype.toString.call(n)&&i(new Error("dataArray argument must be of type Array."));var a=o.keyField||this.keyPath,s=n.length,u=!1,c=!1,l=0,d=this.db.transaction([this.storeName],this.consts.READ_WRITE);d.oncomplete=function(){c?r(n):i(!1)},d.onabort=i,d.onerror=i;var h=function(e){n[l++][a]=e.target.result,0!=--s||u||(u=!0,c=!0)};return n.forEach((function(e){var t,n=e.key;null!==this.keyPath?(this._addIdPropertyIfNeeded(e),t=d.objectStore(this.storeName).put(e)):t=d.objectStore(this.storeName).put(e,n),t.onsuccess=h,t.onerror=function(e){d.abort(),u||(u=!0,i(e))}}),this),d},removeBatch:function(e,t,n){var o=e.map((function(e){return{type:"remove",key:e}}));return this.batch(o,t,n)},getBatch:function(n,o,r,i){if(r||(r=e),o||(o=t),i||(i="sparse"),"[object Array]"!=Object.prototype.toString.call(n))r(new Error("keyArray argument must be of type Array."));else if(0===n.length)return o([]);var a=[],s=n.length,u=!1,c=null,l=this.db.transaction([this.storeName],this.consts.READ_ONLY);l.oncomplete=function(){(u?o:r)(c)},l.onabort=r,l.onerror=r;var d=function(e){e.target.result||"dense"==i?a.push(e.target.result):"sparse"==i&&a.length++,0==--s&&(u=!0,c=a)};return n.forEach((function(e){var t=l.objectStore(this.storeName).get(e);t.onsuccess=d,t.onerror=function(e){c=e,r(e),l.abort()}}),this),l},getAll:function(n,o){o||(o=e),n||(n=t);var r=this.db.transaction([this.storeName],this.consts.READ_ONLY),i=r.objectStore(this.storeName);return i.getAll?this._getAllNative(r,i,n,o):this._getAllCursor(r,i,n,o),r},_getAllNative:function(e,t,n,o){var r=!1,i=null;e.oncomplete=function(){(r?n:o)(i)},e.onabort=o,e.onerror=o;var a=t.getAll();a.onsuccess=function(e){r=!0,i=e.target.result},a.onerror=o},_getAllCursor:function(e,t,n,o){var r=[],i=!1,a=null;e.oncomplete=function(){(i?n:o)(a)},e.onabort=o,e.onerror=o;var s=t.openCursor();s.onsuccess=function(e){var t=e.target.result;t?(r.push(t.value),t.continue()):(i=!0,a=r)},s.onError=o},clear:function(n,o){o||(o=e),n||(n=t);var r=!1,i=null,a=this.db.transaction([this.storeName],this.consts.READ_WRITE);a.oncomplete=function(){(r?n:o)(i)},a.onabort=o,a.onerror=o;var s=a.objectStore(this.storeName).clear();return s.onsuccess=function(e){r=!0,i=e.target.result},s.onerror=o,a},_addIdPropertyIfNeeded:function(e){void 0===e[this.keyPath]&&(e[this.keyPath]=this._insertIdCount+++Date.now())},getIndexList:function(){return this.store.indexNames},hasIndex:function(e){return this.store.indexNames.contains(e)},normalizeIndexData:function(e){e.keyPath=e.keyPath||e.name,e.unique=!!e.unique,e.multiEntry=!!e.multiEntry},indexComplies:function(e,t){return["keyPath","unique","multiEntry"].every((function(n){if("multiEntry"==n&&void 0===e[n]&&!1===t[n])return!0;if("keyPath"==n&&"[object Array]"==Object.prototype.toString.call(t[n])){var o=t.keyPath,r=e.keyPath;if("string"==typeof r)return o.toString()==r;if("function"!=typeof r.contains&&"function"!=typeof r.indexOf)return!1;if(r.length!==o.length)return!1;for(var i=0,a=o.length;i{t.read=function(e,t,n,o,r){var i,a,s=8*r-o-1,u=(1<>1,l=-7,d=n?r-1:0,h=n?-1:1,p=e[t+d];for(d+=h,i=p&(1<<-l)-1,p>>=-l,l+=s;l>0;i=256*i+e[t+d],d+=h,l-=8);for(a=i&(1<<-l)-1,i>>=-l,l+=o;l>0;a=256*a+e[t+d],d+=h,l-=8);if(0===i)i=1-c;else{if(i===u)return a?NaN:1/0*(p?-1:1);a+=Math.pow(2,o),i-=c}return(p?-1:1)*a*Math.pow(2,i-o)},t.write=function(e,t,n,o,r,i){var a,s,u,c=8*i-r-1,l=(1<>1,h=23===r?Math.pow(2,-24)-Math.pow(2,-77):0,p=o?0:i-1,f=o?1:-1,g=t<0||0===t&&1/t<0?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(s=isNaN(t)?1:0,a=l):(a=Math.floor(Math.log(t)/Math.LN2),t*(u=Math.pow(2,-a))<1&&(a--,u*=2),(t+=a+d>=1?h/u:h*Math.pow(2,1-d))*u>=2&&(a++,u/=2),a+d>=l?(s=0,a=l):a+d>=1?(s=(t*u-1)*Math.pow(2,r),a+=d):(s=t*Math.pow(2,d-1)*Math.pow(2,r),a=0));r>=8;e[n+p]=255&s,p+=f,s/=256,r-=8);for(a=a<0;e[n+p]=255&a,p+=f,a/=256,c-=8);e[n+p-f]|=128*g}},35717:e=>{"function"==typeof Object.create?e.exports=function(e,t){t&&(e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}))}:e.exports=function(e,t){if(t){e.super_=t;var n=function(){};n.prototype=t.prototype,e.prototype=new n,e.prototype.constructor=e}}},18139:e=>{var t=/\/\*[^*]*\*+([^/*][^*]*\*+)*\//g,n=/\n/g,o=/^\s*/,r=/^(\*?[-#/*\\\w]+(\[[0-9a-z_-]+\])?)\s*/,i=/^:\s*/,a=/^((?:'(?:\\'|.)*?'|"(?:\\"|.)*?"|\([^)]*?\)|[^};])+)/,s=/^[;\s]*/,u=/^\s+|\s+$/g,c="";function l(e){return e?e.replace(u,c):c}e.exports=function(e,u){if("string"!=typeof e)throw new TypeError("First argument must be a string");if(!e)return[];u=u||{};var d=1,h=1;function p(e){var t=e.match(n);t&&(d+=t.length);var o=e.lastIndexOf("\n");h=~o?e.length-o:h+e.length}function f(){var e={line:d,column:h};return function(t){return t.position=new g(e),y(),t}}function g(e){this.start=e,this.end={line:d,column:h},this.source=u.source}g.prototype.content=e;var m=[];function _(t){var n=new Error(u.source+":"+d+":"+h+": "+t);if(n.reason=t,n.filename=u.source,n.line=d,n.column=h,n.source=e,!u.silent)throw n;m.push(n)}function F(t){var n=t.exec(e);if(n){var o=n[0];return p(o),e=e.slice(o.length),n}}function y(){F(o)}function b(e){var t;for(e=e||[];t=v();)!1!==t&&e.push(t);return e}function v(){var t=f();if("/"==e.charAt(0)&&"*"==e.charAt(1)){for(var n=2;c!=e.charAt(n)&&("*"!=e.charAt(n)||"/"!=e.charAt(n+1));)++n;if(n+=2,c===e.charAt(n-1))return _("End of comment missing");var o=e.slice(2,n-2);return h+=2,p(o),e=e.slice(n),h+=2,t({type:"comment",comment:o})}}function w(){var e=f(),n=F(r);if(n){if(v(),!F(i))return _("property missing ':'");var o=F(a),u=e({type:"declaration",property:l(n[0].replace(t,c)),value:o?l(o[0].replace(t,c)):c});return F(s),u}}return y(),function(){var e,t=[];for(b(t);e=w();)!1!==e&&(t.push(e),b(t));return t}()}},46260:e=>{"use strict";e.exports=function(e){var t="string"==typeof e?e.charCodeAt(0):e;return t>=97&&t<=122||t>=65&&t<=90}},7961:(e,t,n)=>{"use strict";var o=n(46260),r=n(46195);e.exports=function(e){return o(e)||r(e)}},82584:(e,t,n)=>{"use strict";var o="function"==typeof Symbol&&"symbol"==typeof Symbol.toStringTag,r=n(21924)("Object.prototype.toString"),i=function(e){return!(o&&e&&"object"==typeof e&&Symbol.toStringTag in e)&&"[object Arguments]"===r(e)},a=function(e){return!!i(e)||null!==e&&"object"==typeof e&&"number"==typeof e.length&&e.length>=0&&"[object Array]"!==r(e)&&"[object Function]"===r(e.callee)},s=function(){return i(arguments)}();i.isLegacyArguments=a,e.exports=s?i:a},46195:e=>{"use strict";e.exports=function(e){var t="string"==typeof e?e.charCodeAt(0):e;return t>=48&&t<=57}},48662:e=>{"use strict";var t=Object.prototype.toString,n=Function.prototype.toString,o=/^\s*(?:function)?\*/,r="function"==typeof Symbol&&"symbol"==typeof Symbol.toStringTag,i=Object.getPrototypeOf,a=function(){if(!r)return!1;try{return Function("return function*() {}")()}catch(e){}}(),s=!(!i||!a)&&i(a);e.exports=function(e){return"function"==typeof e&&(!!o.test(n.call(e))||(r?i&&i(e)===s:"[object GeneratorFunction]"===t.call(e)))}},79480:e=>{"use strict";e.exports=function(e){var t="string"==typeof e?e.charCodeAt(0):e;return t>=97&&t<=102||t>=65&&t<=70||t>=48&&t<=57}},33310:e=>{"use strict";e.exports=e=>{if("[object Object]"!==Object.prototype.toString.call(e))return!1;const t=Object.getPrototypeOf(e);return null===t||t===Object.prototype}},85692:(e,t,n)=>{"use strict";var o=n(49804),r=n(16314),i=n(21924),a=i("Object.prototype.toString"),s=n(41405)()&&"symbol"==typeof Symbol.toStringTag,u=r(),c=i("Array.prototype.indexOf",!0)||function(e,t){for(var n=0;n-1}return!!h&&function(e){var t=!1;return o(d,(function(n,o){if(!t)try{t=n.call(e)===o}catch(e){}})),t}(e)}},65452:e=>{var t=Object.prototype,n=t.hasOwnProperty,o=t.toString,r=function(e){return e!=e},i={boolean:1,number:1,string:1,undefined:1},a=e.exports={};a.a=a.type=function(e,t){return typeof e===t},a.defined=function(e){return void 0!==e},a.empty=function(e){var t,r=o.call(e);if("[object Array]"===r||"[object Arguments]"===r)return 0===e.length;if("[object Object]"===r){for(t in e)if(n.call(e,t))return!1;return!0}return"[object String]"===r&&""===e},a.equal=function(e,t){var n,r=o.call(e);if(r!==o.call(t))return!1;if("[object Object]"===r){for(n in e)if(!a.equal(e[n],t[n]))return!1;return!0}if("[object Array]"===r){if((n=e.length)!==t.length)return!1;for(;--n;)if(!a.equal(e[n],t[n]))return!1;return!0}return"[object Function]"===r?e.prototype===t.prototype:"[object Date]"===r?e.getTime()===t.getTime():e===t},a.hosted=function(e,t){var n=typeof t[e];return"object"===n?!!t[e]:!i[n]},a.instance=a.instanceof=function(e,t){return e instanceof t},a.null=function(e){return null===e},a.undefined=function(e){return void 0===e},a.arguments=function(e){var t="[object Arguments]"===o.call(e),n=!a.array(e)&&a.arraylike(e)&&a.object(e)&&a.fn(e.callee);return t||n},a.array=function(e){return"[object Array]"===o.call(e)},a.arguments.empty=function(e){return a.arguments(e)&&0===e.length},a.array.empty=function(e){return a.array(e)&&0===e.length},a.arraylike=function(e){return!!e&&!a.boolean(e)&&n.call(e,"length")&&isFinite(e.length)&&a.number(e.length)&&e.length>=0},a.boolean=function(e){return"[object Boolean]"===o.call(e)},a.false=function(e){return a.boolean(e)&&(!1===e||!1===e.valueOf())},a.true=function(e){return a.boolean(e)&&(!0===e||!0===e.valueOf())},a.date=function(e){return"[object Date]"===o.call(e)},a.element=function(e){return void 0!==e&&"undefined"!=typeof HTMLElement&&e instanceof HTMLElement&&1===e.nodeType},a.error=function(e){return"[object Error]"===o.call(e)},a.fn=a.function=function(e){return"undefined"!=typeof window&&e===window.alert||"[object Function]"===o.call(e)},a.number=function(e){return"[object Number]"===o.call(e)},a.infinite=function(e){return e===1/0||e===-1/0},a.decimal=function(e){return a.number(e)&&!r(e)&&!a.infinite(e)&&e%1!=0},a.divisibleBy=function(e,t){var n=a.infinite(e),o=a.infinite(t),i=a.number(e)&&!r(e)&&a.number(t)&&!r(t)&&0!==t;return n||o||i&&e%t==0},a.int=function(e){return a.number(e)&&!r(e)&&e%1==0},a.maximum=function(e,t){if(r(e))throw new TypeError("NaN is not a valid value");if(!a.arraylike(t))throw new TypeError("second argument must be array-like");for(var n=t.length;--n>=0;)if(e=0;)if(e>t[n])return!1;return!0},a.nan=function(e){return!a.number(e)||e!=e},a.even=function(e){return a.infinite(e)||a.number(e)&&e==e&&e%2==0},a.odd=function(e){return a.infinite(e)||a.number(e)&&e==e&&e%2!=0},a.ge=function(e,t){if(r(e)||r(t))throw new TypeError("NaN is not a valid value");return!a.infinite(e)&&!a.infinite(t)&&e>=t},a.gt=function(e,t){if(r(e)||r(t))throw new TypeError("NaN is not a valid value");return!a.infinite(e)&&!a.infinite(t)&&e>t},a.le=function(e,t){if(r(e)||r(t))throw new TypeError("NaN is not a valid value");return!a.infinite(e)&&!a.infinite(t)&&e<=t},a.lt=function(e,t){if(r(e)||r(t))throw new TypeError("NaN is not a valid value");return!a.infinite(e)&&!a.infinite(t)&&e=t&&e<=n},a.object=function(e){return e&&"[object Object]"===o.call(e)},a.hash=function(e){return a.object(e)&&e.constructor===Object&&!e.nodeType&&!e.setInterval},a.regexp=function(e){return"[object RegExp]"===o.call(e)},a.string=function(e){return"[object String]"===o.call(e)}},5826:e=>{var t={}.toString;e.exports=Array.isArray||function(e){return"[object Array]"==t.call(e)}},35086:(e,t,n)=>{var o=n(48764).Buffer;e.exports=function(e){return o.isBuffer(e)||/\[object (.+Array|Array.+)\]/.test(Object.prototype.toString.call(e))}},69334:(e,t,n)=>{var o=n(57785),r=n(2638),i=n(51753),a=n(89539),s=n(30778),u=new Buffer(0),c={encode:function(e){return"string"==typeof e?e=new Buffer(e):e},decode:function(e){return Buffer.isBuffer(e)?e:new Buffer(e)},buffer:!0,type:"raw"},l=function(){},d=function(e){return e=e.toString(16),"00000000".slice(0,-e.length)+e};e.exports=function(e,t){t||(t={});var n={},h=t.blockSize||65536,p=t.batch||100,f=new Buffer(h);e.put("\0","ignore",l);var g={},m=function(e,t){if(!(this instanceof m))return new m(e,t);t||(t={}),this.name=e,this.blocks=[],this.batch=[],this.bytesWritten=0,this.truncate=!t.append,this.append=t.append,this._shouldInitAppend=this.append&&void 0===t.start,this._destroyed=!1,this._init(t.start||0),o.call(this)};a.inherits(m,o),m.prototype._init=function(e){this.blockIndex=e/h|0,this.blockOffset=e-this.blockIndex*h,this.blockLength=this.blockOffset},m.prototype._flush=function(t){if(!this.batch.length)return t();var n=this.batch[this.batch.length-1].key,o=this.batch;if(this.batch=[],!this.truncate)return e.batch(o,t);this.truncate=!1,this._truncate(o,n,t)},m.prototype._truncate=function(t,n,o){o=s(o);var r=[],i=e.createKeyStream({start:n,end:this.name+"ÿÿ"});i.on("error",o),i.on("data",(function(e){r.push({type:"del",key:e})})),i.on("end",(function(){r.push.apply(r,t),e.batch(r,o)}))},m.prototype._writeBlock=function(t){var n=1===this.blocks.length?this.blocks[0]:Buffer.concat(this.blocks,this.blockLength-this.blockOffset),o=this.blockIndex,r=this.blockOffset,i=this;this.blockOffset=0,this.blockLength=0,this.blockIndex++,this.blocks=[];var a=this.name+"ÿ"+d(o),s=function(e,t,n){return e.length&&i.batch.push({type:"put",key:a,value:e,valueEncoding:c}),!t&&i.batch.lengthi&&(o=e.slice(i),e=e.slice(0,i)),this.bytesWritten+=e.length,this.blockLength+=e.length,this.blocks.push(e),e.lengtho._missing&&(e=e.slice(0,o._missing)),o._missing-=e.length,o._pause(!o.push(e)),!o._missing))};this._reader.on("data",(function(e){for(;e.key>u;)if(!l(f))return;l(e.value)})),this._reader.on("error",(function(e){o.emit("error",e)})),this._reader.on("end",(function(){o.push(null)})),r.call(this)};return a.inherits(_,r),_.prototype.destroy=function(){this._destroyed||(this._destroyed=!0,this._reader.destroy(),process.nextTick(this.emit.bind(this,"close")))},_.prototype._pause=function(e){this._paused!==e&&(this._paused=e,this._paused?this._reader.pause():this._reader.resume())},_.prototype._read=function(){this._pause(!1)},n.remove=function(t,n){n=s(n||l);var o=[],r=e.createKeyStream({start:t+"ÿ",end:t+"ÿÿ"});r.on("error",n),r.on("data",(function(e){o.push({type:"del",key:e})})),r.on("end",(function(){e.batch(o,n)}))},n.size=function(t,n){i.last(e,{start:t+"ÿ",end:t+"ÿÿ",valueEncoding:c},(function(e,o,r){return e&&"range not found"===e.message?n(null,0):e?n(e):o.slice(0,t.length+1)!==t+"ÿ"?n(null,0):void n(null,parseInt(o.toString().slice(t.length+1),16)*h+r.length)}))},n.write=function(e,t,o,r){if("function"==typeof o)return n.write(e,t,null,o);o||(o={}),r||(r=l);var i=n.createWriteStream(e,o);i.on("error",r),i.on("finish",(function(){r()})),i.write(t),i.end()},n.read=function(e,t,o){if("function"==typeof t)return n.read(e,null,t);t||(t={});var r=n.createReadStream(e,t),i=[];r.on("error",o),r.on("data",(function(e){i.push(e)})),r.on("end",(function(){o(null,1===i.length?i[0]:Buffer.concat(i))}))},n.createReadStream=function(e,t){return new _(e,t)},n.createWriteStream=function(e,t){return new m(e,t)},n}},79141:e=>{e.exports=Array.isArray||function(e){return"[object Array]"==Object.prototype.toString.call(e)}},79435:(e,t,n)=>{e.exports=s;var o=Object.keys||function(e){var t=[];for(var n in e)t.push(n);return t},r=n(16497);r.inherits=n(35717);var i=n(67496),a=n(60091);function s(e){if(!(this instanceof s))return new s(e);i.call(this,e),a.call(this,e),e&&!1===e.readable&&(this.readable=!1),e&&!1===e.writable&&(this.writable=!1),this.allowHalfOpen=!0,e&&!1===e.allowHalfOpen&&(this.allowHalfOpen=!1),this.once("end",u)}function u(){this.allowHalfOpen||this._writableState.ended||process.nextTick(this.end.bind(this))}r.inherits(s,i),function(e,t){for(var n=0,o=e.length;n{e.exports=i;var o=n(84987),r=n(16497);function i(e){if(!(this instanceof i))return new i(e);o.call(this,e)}r.inherits=n(35717),r.inherits(i,o),i.prototype._transform=function(e,t,n){n(null,e)}},67496:(e,t,n)=>{e.exports=d;var o=n(79141),r=n(48764).Buffer;d.ReadableState=l;var i=n(17187).EventEmitter;i.listenerCount||(i.listenerCount=function(e,t){return e.listeners(t).length});var a,s=n(42830),u=n(16497);u.inherits=n(35717);var c=n(6297);function l(e,t){var o=n(79435),r=(e=e||{}).highWaterMark,i=e.objectMode?16:16384;this.highWaterMark=r||0===r?r:i,this.highWaterMark=~~this.highWaterMark,this.buffer=[],this.length=0,this.pipes=null,this.pipesCount=0,this.flowing=null,this.ended=!1,this.endEmitted=!1,this.reading=!1,this.sync=!0,this.needReadable=!1,this.emittedReadable=!1,this.readableListening=!1,this.objectMode=!!e.objectMode,t instanceof o&&(this.objectMode=this.objectMode||!!e.readableObjectMode),this.defaultEncoding=e.defaultEncoding||"utf8",this.ranOut=!1,this.awaitDrain=0,this.readingMore=!1,this.decoder=null,this.encoding=null,e.encoding&&(a||(a=n(50981).s),this.decoder=new a(e.encoding),this.encoding=e.encoding)}function d(e){if(n(79435),!(this instanceof d))return new d(e);this._readableState=new l(e,this),this.readable=!0,s.call(this)}function h(e,t,n,o,r){var i=function(e,t){var n=null;return u.isBuffer(t)||u.isString(t)||u.isNullOrUndefined(t)||e.objectMode||(n=new TypeError("Invalid non-string/buffer chunk")),n}(t,n);if(i)e.emit("error",i);else if(u.isNullOrUndefined(n))t.reading=!1,t.ended||function(e,t){if(t.decoder&&!t.ended){var n=t.decoder.end();n&&n.length&&(t.buffer.push(n),t.length+=t.objectMode?1:n.length)}t.ended=!0,g(e)}(e,t);else if(t.objectMode||n&&n.length>0)if(t.ended&&!r){var a=new Error("stream.push() after EOF");e.emit("error",a)}else t.endEmitted&&r?(a=new Error("stream.unshift() after end event"),e.emit("error",a)):(!t.decoder||r||o||(n=t.decoder.write(n)),r||(t.reading=!1),t.flowing&&0===t.length&&!t.sync?(e.emit("data",n),e.read(0)):(t.length+=t.objectMode?1:n.length,r?t.buffer.unshift(n):t.buffer.push(n),t.needReadable&&g(e)),function(e,t){t.readingMore||(t.readingMore=!0,process.nextTick((function(){!function(e,t){for(var n=t.length;!t.reading&&!t.flowing&&!t.ended&&t.lengtht.highWaterMark&&(t.highWaterMark=function(e){if(e>=p)e=p;else{e--;for(var t=1;t<32;t<<=1)e|=e>>t;e++}return e}(e)),e>t.length?t.ended?t.length:(t.needReadable=!0,0):e)}function g(e){var t=e._readableState;t.needReadable=!1,t.emittedReadable||(c("emitReadable",t.flowing),t.emittedReadable=!0,t.sync?process.nextTick((function(){m(e)})):m(e))}function m(e){c("emit readable"),e.emit("readable"),_(e)}function _(e){var t=e._readableState;if(c("flow",t.flowing),t.flowing)do{var n=e.read()}while(null!==n&&t.flowing)}function F(e,t){var n,o=t.buffer,i=t.length,a=!!t.decoder,s=!!t.objectMode;if(0===o.length)return null;if(0===i)n=null;else if(s)n=o.shift();else if(!e||e>=i)n=a?o.join(""):r.concat(o,i),o.length=0;else if(e0)throw new Error("endReadable called on non-empty stream");t.endEmitted||(t.ended=!0,process.nextTick((function(){t.endEmitted||0!==t.length||(t.endEmitted=!0,e.readable=!1,e.emit("end"))})))}d.prototype.read=function(e){c("read",e);var t=this._readableState,n=e;if((!u.isNumber(e)||e>0)&&(t.emittedReadable=!1),0===e&&t.needReadable&&(t.length>=t.highWaterMark||t.ended))return c("read: emitReadable",t.length,t.ended),0===t.length&&t.ended?y(this):g(this),null;if(0===(e=f(e,t))&&t.ended)return 0===t.length&&y(this),null;var o,r=t.needReadable;return c("need readable",r),(0===t.length||t.length-e0?F(e,t):null,u.isNull(o)&&(t.needReadable=!0,e=0),t.length-=e,0!==t.length||t.ended||(t.needReadable=!0),n!==e&&t.ended&&0===t.length&&y(this),u.isNull(o)||this.emit("data",o),o},d.prototype._read=function(e){this.emit("error",new Error("not implemented"))},d.prototype.pipe=function(e,t){var n=this,r=this._readableState;switch(r.pipesCount){case 0:r.pipes=e;break;case 1:r.pipes=[r.pipes,e];break;default:r.pipes.push(e)}r.pipesCount+=1,c("pipe count=%d opts=%j",r.pipesCount,t);var a=t&&!1===t.end||e===process.stdout||e===process.stderr?d:u;function s(e){c("onunpipe"),e===n&&d()}function u(){c("onend"),e.end()}r.endEmitted?process.nextTick(a):n.once("end",a),e.on("unpipe",s);var l=function(e){return function(){var t=e._readableState;c("pipeOnDrain",t.awaitDrain),t.awaitDrain&&t.awaitDrain--,0===t.awaitDrain&&i.listenerCount(e,"data")&&(t.flowing=!0,_(e))}}(n);function d(){c("cleanup"),e.removeListener("close",f),e.removeListener("finish",g),e.removeListener("drain",l),e.removeListener("error",p),e.removeListener("unpipe",s),n.removeListener("end",u),n.removeListener("end",d),n.removeListener("data",h),!r.awaitDrain||e._writableState&&!e._writableState.needDrain||l()}function h(t){c("ondata"),!1===e.write(t)&&(c("false write response, pause",n._readableState.awaitDrain),n._readableState.awaitDrain++,n.pause())}function p(t){c("onerror",t),m(),e.removeListener("error",p),0===i.listenerCount(e,"error")&&e.emit("error",t)}function f(){e.removeListener("finish",g),m()}function g(){c("onfinish"),e.removeListener("close",f),m()}function m(){c("unpipe"),n.unpipe(e)}return e.on("drain",l),n.on("data",h),e._events&&e._events.error?o(e._events.error)?e._events.error.unshift(p):e._events.error=[p,e._events.error]:e.on("error",p),e.once("close",f),e.once("finish",g),e.emit("pipe",n),r.flowing||(c("pipe resume"),n.resume()),e},d.prototype.unpipe=function(e){var t=this._readableState;if(0===t.pipesCount)return this;if(1===t.pipesCount)return e&&e!==t.pipes||(e||(e=t.pipes),t.pipes=null,t.pipesCount=0,t.flowing=!1,e&&e.emit("unpipe",this)),this;if(!e){var n=t.pipes,o=t.pipesCount;t.pipes=null,t.pipesCount=0,t.flowing=!1;for(var r=0;r{e.exports=a;var o=n(79435),r=n(16497);function i(e,t){this.afterTransform=function(e,n){return function(e,t,n){var o=e._transformState;o.transforming=!1;var i=o.writecb;if(!i)return e.emit("error",new Error("no writecb in Transform class"));o.writechunk=null,o.writecb=null,r.isNullOrUndefined(n)||e.push(n),i&&i(t);var a=e._readableState;a.reading=!1,(a.needReadable||a.length{e.exports=u;var o=n(48764).Buffer;u.WritableState=s;var r=n(16497);r.inherits=n(35717);var i=n(42830);function a(e,t,n){this.chunk=e,this.encoding=t,this.callback=n}function s(e,t){var o=n(79435),r=(e=e||{}).highWaterMark,i=e.objectMode?16:16384;this.highWaterMark=r||0===r?r:i,this.objectMode=!!e.objectMode,t instanceof o&&(this.objectMode=this.objectMode||!!e.writableObjectMode),this.highWaterMark=~~this.highWaterMark,this.needDrain=!1,this.ending=!1,this.ended=!1,this.finished=!1;var a=!1===e.decodeStrings;this.decodeStrings=!a,this.defaultEncoding=e.defaultEncoding||"utf8",this.length=0,this.writing=!1,this.corked=0,this.sync=!0,this.bufferProcessing=!1,this.onwrite=function(e){!function(e,t){var n=e._writableState,o=n.sync,r=n.writecb;if(function(e){e.writing=!1,e.writecb=null,e.length-=e.writelen,e.writelen=0}(n),t)!function(e,t,n,o,r){n?process.nextTick((function(){t.pendingcb--,r(o)})):(t.pendingcb--,r(o)),e._writableState.errorEmitted=!0,e.emit("error",o)}(e,n,o,t,r);else{var i=h(0,n);i||n.corked||n.bufferProcessing||!n.buffer.length||d(e,n),o?process.nextTick((function(){l(e,n,i,r)})):l(e,n,i,r)}}(t,e)},this.writecb=null,this.writelen=0,this.buffer=[],this.pendingcb=0,this.prefinished=!1,this.errorEmitted=!1}function u(e){var t=n(79435);if(!(this instanceof u||this instanceof t))return new u(e);this._writableState=new s(e,this),this.writable=!0,i.call(this)}function c(e,t,n,o,r,i,a){t.writelen=o,t.writecb=a,t.writing=!0,t.sync=!0,n?e._writev(r,t.onwrite):e._write(r,i,t.onwrite),t.sync=!1}function l(e,t,n,o){n||function(e,t){0===t.length&&t.needDrain&&(t.needDrain=!1,e.emit("drain"))}(e,t),t.pendingcb--,o(),f(e,t)}function d(e,t){if(t.bufferProcessing=!0,e._writev&&t.buffer.length>1){for(var n=[],o=0;o{(t=e.exports=n(67496)).Stream=n(42830),t.Readable=t,t.Writable=n(60091),t.Duplex=n(79435),t.Transform=n(84987),t.PassThrough=n(1474),process.browser||"disable"!==process.env.READABLE_STREAM||(e.exports=n(42830))},57785:(e,t,n)=>{e.exports=n(60091)},50981:(e,t,n)=>{var o=n(48764).Buffer,r=o.isEncoding||function(e){switch(e&&e.toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":case"raw":return!0;default:return!1}},i=t.s=function(e){switch(this.encoding=(e||"utf8").toLowerCase().replace(/[-_]/,""),function(e){if(e&&!r(e))throw new Error("Unknown encoding: "+e)}(e),this.encoding){case"utf8":this.surrogateSize=3;break;case"ucs2":case"utf16le":this.surrogateSize=2,this.detectIncompleteChar=s;break;case"base64":this.surrogateSize=3,this.detectIncompleteChar=u;break;default:return void(this.write=a)}this.charBuffer=new o(6),this.charReceived=0,this.charLength=0};function a(e){return e.toString(this.encoding)}function s(e){this.charReceived=e.length%2,this.charLength=this.charReceived?2:0}function u(e){this.charReceived=e.length%3,this.charLength=this.charReceived?3:0}i.prototype.write=function(e){for(var t="";this.charLength;){var n=e.length>=this.charLength-this.charReceived?this.charLength-this.charReceived:e.length;if(e.copy(this.charBuffer,this.charReceived,0,n),this.charReceived+=n,this.charReceived=55296&&o<=56319)){if(this.charReceived=this.charLength=0,0===e.length)return t;break}this.charLength+=this.surrogateSize,t=""}this.detectIncompleteChar(e);var o,r=e.length;if(this.charLength&&(e.copy(this.charBuffer,0,e.length-this.charReceived,r),r-=this.charReceived),r=(t+=e.toString(this.encoding,0,r)).length-1,(o=t.charCodeAt(r))>=55296&&o<=56319){var i=this.surrogateSize;return this.charLength+=i,this.charReceived+=i,this.charBuffer.copy(this.charBuffer,i,0,i),e.copy(this.charBuffer,0,0,i),t.substring(0,r)}return t},i.prototype.detectIncompleteChar=function(e){for(var t=e.length>=3?3:e.length;t>0;t--){var n=e[e.length-t];if(1==t&&n>>5==6){this.charLength=2;break}if(t<=2&&n>>4==14){this.charLength=3;break}if(t<=3&&n>>3==30){this.charLength=4;break}}this.charReceived=t},i.prototype.end=function(e){var t="";if(e&&e.length&&(t=this.write(e)),this.charReceived){var n=this.charReceived,o=this.charBuffer,r=this.encoding;t+=o.slice(0,n).toString(r)}return t}},2950:(e,t,n)=>{var o=n(47138);Object.keys(o.code).forEach((function(e){var n=o.code[e];t[e]=function(t){var o=new Error(e+", "+n.description+(t?" '"+t+"'":""));return o.errno=n.errno,o.code=e,o.path=t,o}}))},49942:(e,t,n)=>{var o=n(35673),r=n(98673),i=n(69334),a=n(51753),s=n(30778),u=n(39530),c=n(2950),l=n(68781),d=n(36975),h=function(e,t,n){process.nextTick((function(){e(t,n)}))},p=function(){};e.exports=function(e,t){var n={};e=r(e);var f=i(e.sublevel("blobs"),t),g=l(e.sublevel("stats")),m=e.sublevel("links"),_=d(),F=[],y=Date.now();n.mkdir=function(e,t,o){if("function"==typeof t)return n.mkdir(e,null,t);t||(t=u(777)),o||(o=p),g.follow(e,(function(e,n,r){return e&&"ENOENT"!==e.code?o(e):n?o(c.EEXIST(r)):void g.put(r,{type:"directory",mode:t,size:4096},_.cb(r,o))}))},n.rmdir=function(e,t){t||(t=p),g.follow(e,(function(e,o,r){if(e)return t(e);n.readdir(r,(function(e,n){return e?t(e):n.length?t(c.ENOTEMPTY(r)):void g.del(r,_.cb(r,t))}))}))},n.readdir=function(e,t){g.follow(e,(function(e,n,o){return e?t(e):n?n.isDirectory()?void g.list(o,t):t(c.ENOTDIR(o)):t(c.ENOENT(o))}))};var b=function(e,t,n){t(e,(function(e,t,o){if(e)return n(e);if(!t.isFile())return n(null,t);var r=t&&t.blob||o;f.size(r,(function(e,o){if(e)return n(e);t.size=o,n(null,t)}))}))};n.stat=function(e,t){b(e,g.follow,t)},n.lstat=function(e,t){b(e,g.get,t)},n.exists=function(e,t){g.follow(e,(function(e){t(!e)}))};var v=function(e,t,n,o){o||(o=p),t(e,(function(e,t,r){if(e)return o(e);g.update(r,{mode:n},_.cb(r,o))}))};n.chmod=function(e,t,n){v(e,g.follow,t,n)},n.lchmod=function(e,t,n){v(e,g.get,t,n)};var w=function(e,t,n,o,r){r||(r=p),t(e,(function(e,t,i){if(e)return r(e);g.update(i,{uid:n,gid:o},_.cb(i,r))}))};return n.chown=function(e,t,n,o){w(e,g.follow,t,n,o)},n.lchown=function(e,t,n,o){w(e,g.get,t,n,o)},n.utimes=function(e,t,n,o){o||(o=p),g.follow(e,(function(e,r,i){if(e)return o(e);var a={};t&&(a.atime=t),n&&(a.mtime=n),g.update(i,a,_.cb(i,o))}))},n.rename=function(e,t,o){o||(o=p),g.follow(e,(function(e,r,i){if(e)return o(e);var a=function(){o=_.cb(t,_.cb(i,o)),g.put(t,r,(function(e){if(e)return o(e);g.del(i,o)}))};g.follow(t,(function(e,t,s){return e&&"ENOENT"!==e.code?o(e):t?r.isDirectory()!==t.isDirectory()?o(c.EISDIR(i)):void(t.isDirectory()?n.readdir(s,(function(e,t){return e?o(e):t.length?o(c.ENOTEMPTY(i)):void a()})):a()):a()}))}))},n.realpath=function(e,t,o){if("function"==typeof t)return n.realpath(e,null,t);g.follow(e,(function(e,t,n){if(e)return o(e);o(null,n)}))},n.writeFile=function(e,t,o,r){if("function"==typeof o)return n.writeFile(e,t,null,o);"string"==typeof o&&(o={encoding:o}),o||(o={}),r||(r=p),Buffer.isBuffer(t)||(t=new Buffer(t,o.encoding||"utf-8"));var i=o.flags||"w";o.append="w"!==i[0],g.follow(e,(function(e,n,a){if(e&&"ENOENT"!==e.code)return r(e);if(n&&n.isDirectory())return r(c.EISDIR(a));if(n&&"x"===i[1])return r(c.EEXIST(a));var s=n&&n.blob||a;g.writable(a,(function(e){if(e)return r(e);f.write(s,t,o,(function(e){if(e)return r(e);g.put(a,{ctime:n&&n.ctime,mtime:new Date,mode:o.mode||u(666),type:"file"},_.cb(a,r))}))}))}))},n.appendFile=function(e,t,o,r){if("function"==typeof o)return n.appendFile(e,t,null,o);"string"==typeof o&&(o={encoding:o}),o||(o={}),o.flags="a",n.writeFile(e,t,o,r)},n.unlink=function(e,t){t||(t=p),g.get(e,(function(e,n,o){if(e)return t(e);if(n.isDirectory())return t(c.EISDIR(o));var r=function(e){a(m,{start:e+"ÿ",end:e+"ÿÿ"},(function(n){if(n)return f.remove(e,t);t()}))};g.del(o,_.cb(o,(function(e){return e?t(e):n.link?(i=n.link.slice(0,n.link.indexOf("ÿ")),void m.del(n.link,(function(e){if(e)return t(e);r(i)}))):void m.del(o+"ÿ",(function(e){if(e)return t(e);r(o)}));var i})))}))},n.readFile=function(e,t,o){if("function"==typeof t)return n.readFile(e,null,t);"string"==typeof t&&(t={encoding:t}),t||(t={}),t.encoding,t.flag,g.follow(e,(function(e,n,r){if(e)return o(e);if(n.isDirectory())return o(c.EISDIR(r));var i=n&&n.blob||r;f.read(i,(function(e,n){if(e)return o(e);o(null,t.encoding?n.toString(t.encoding):n)}))}))},n.createReadStream=function(e,t){t||(t={});var n=!1,r=o.readable((function(o){g.follow(e,(function(e,i,a){if(e)return o(e);if(i.isDirectory())return o(c.EISDIR(a));var s=i&&i.blob||a,u=f.createReadStream(s,t);r.emit("open"),u.on("end",(function(){process.nextTick((function(){n||r.emit("close")}))})),o(null,u)}))}));return r.on("close",(function(){n=!0})),r},n.createWriteStream=function(e,t){t||(t={});var n=t.flags||"w",r=!1,i=t.mode||u(666);t.append="a"===n[0];var a=o.writable((function(o){g.follow(e,(function(e,s,u){if(e&&"ENOENT"!==e.code)return o(e);if(s&&s.isDirectory())return o(c.EISDIR(u));if(s&&"x"===n[1])return o(c.EEXIST(u));var l=s&&s.blob||u;g.writable(l,(function(e){if(e)return o(e);var n={ctime:s?s.ctime:new Date,mtime:new Date,mode:i,type:"file"};g.put(u,n,(function(e){if(e)return o(e);var i=f.createWriteStream(l,t);a.emit("open"),i.on("finish",(function(){n.mtime=new Date,g.put(u,n,(function(){_.change(u),r||a.emit("close")}))})),o(null,i)}))}))}))}));return a.on("close",(function(){r=!0})),a},n.truncate=function(e,t,n){g.follow(e,(function(e,o,r){if(e)return n(e);var i=o&&o.blob||r;f.size(i,(function(e,o){if(e)return n(e);g.writable(r,(function(e){if(e)return n(e);if(n=s(_.cb(r,n)),!t)return f.remove(i,n);var a=f.createWriteStream(i,{start:o{var o=n(26470),r=n(30778),i=n(36890),a=n(39530),s=n(86705),u=n(78779),c=n(2950),l=s({type:"directory",mode:a(777),size:4096}),d=function(e){return e="/"===e[0]?e:"/"+e,"/"===(e=o.normalize(e))?e:"/"===e[e.length-1]?e.slice(0,-1):e},h=function(e){var t=e.split("/").length.toString(36);return"0000000000".slice(t.length)+t+e};e.exports=function(e){var t={};return t.normalize=d,t.get=function(t,n){if("/"===(t=d(t)))return process.nextTick(n.bind(null,null,l,"/"));e.get(h(t),{valueEncoding:"json"},(function(e,o){return e&&e.notFound?n(c.ENOENT(t),null,t):e?n(e,null,t):void n(null,s(o),t)}))},t.writable=function(e,n){if("/"===(e=d(e)))return process.nextTick(n.bind(null,c.EPERM(e)));t.follow(o.dirname(e),(function(t,o){return t?n(t):o.isDirectory()?void n(null,e):n(c.ENOTDIR(e))}))},t.list=function(t,n){t=d(t);var o=h("/"===t?t:t+"/"),a=e.createKeyStream({start:o,end:o+"ÿ"});n=r(n),a.on("error",n),a.pipe(i({encoding:"object"},(function(e){e=e.map((function(e){return e.split("/").pop()})),n(null,e)})))},t.follow=function(e,n){!function(e,n){var r="/",i=e.split("/").slice(1),a=function(){t.get(o.join(r,i.shift()),(function(t,o,s){return t?n(t,o,e):(r=o.target||s,i.length?void a():n(null,o,s))}))};a()}(d(e),(function e(o,r,i){return o?n(o,null,i):r.target?t.get(r.target,e):void n(null,s(r),i)}))},t.update=function(e,n,o){t.get(e,(function(e,r,i){return e?o(e):"/"===i?o(c.EPERM(i)):void t.put(i,u(r,n),o)}))},t.put=function(n,o,r){t.writable(n,(function(t,n){if(t)return r(t);e.put(h(n),s(o),{valueEncoding:"json"},r)}))},t.del=function(t,n){if("/"===(t=d(t)))return process.nextTick(n.bind(null,c.EPERM(t)));e.del(h(t),n)},t}},86705:e=>{var t=function(e){return e?"string"==typeof e?new Date(e):e:new Date},n=function(e){this.uid=e.uid||0,this.gid=e.gid||0,this.mode=e.mode||0,this.size=e.size||0,this.mtime=t(e.mtime),this.atime=t(e.atime),this.ctime=t(e.ctime),this.type=e.type,this.target=e.target,this.link=e.link,this.blob=e.blob};n.prototype.isDirectory=function(){return"directory"===this.type},n.prototype.isFile=function(){return"file"===this.type},n.prototype.isBlockDevice=function(){return!1},n.prototype.isCharacterDevice=function(){return!1},n.prototype.isSymbolicLink=function(){return"symlink"===this.type},n.prototype.isFIFO=function(){return!1},n.prototype.isSocket=function(){return!1},e.exports=function(e){return new n(e)}},36975:(e,t,n)=>{var o=n(17187);e.exports=function(){var e={},t=new o.EventEmitter;return t.watch=function(t,n){return e[t]||(e[t]=new o.EventEmitter,e[t].setMaxListeners(0)),n&&e[t].on("change",n),e[t]},t.watcher=function(e,n){var r=new o.EventEmitter,i=function(){r.emit("change","change",e)};return t.watch(e,i),n&&r.on("change",n),r.close=function(){t.unwatch(e,i)},r},t.unwatch=function(t,n){e[t]&&(n?e[t].removeListener("change",n):e[t].removeAllListeners("change"),e[t].listeners("change").length||delete e[t])},t.change=function(n){e[n]&&e[n].emit("change"),t.emit("change",n)},t.cb=function(e,n){return function(o,r){e&&t.change(e),n&&n(o,r)}},t}},80767:e=>{e.exports=function(e){var t=e.reverse,n=e.end,o=e.start,r=[o,n];return null!=o&&null!=n&&r.sort(),t&&(r=r.reverse()),e.start=r[0],e.end=r[1],e}},11798:(e,t,n)=>{var o=n(21889);e.exports=function(e){if(!e.hooks){var t=[],n=[];e.hooks={post:function(e,n){n||(n=e,e="");var r={test:o.checker(e),hook:n};return t.push(r),u(t,r)},pre:function(e,t){t||(t=e,e="");var r={test:o.checker(e),hook:t,safe:!1!==e.safe};return n.push(r),u(n,r)},posthooks:t,prehooks:n},e.on("put",(function(e,t){c({type:"put",key:e,value:t})})),e.on("del",(function(e,t){c({type:"del",key:e,value:t})})),e.on("batch",(function(e){e.forEach(c)}));var r=e.put,i=e.del,a=e.batch;e.put=function(e,t,n,o){return l(!1,[{key:e,value:t,type:"put"}],n,o)},e.del=function(e,t,n){return l(!1,[{key:e,type:"del"}],t,n)},e.batch=function(e,t,n){return l(!0,e,t,n)}}function s(e){return e&&("string"==typeof e?e:"string"==typeof e.prefix?e.prefix:"function"==typeof e.prefix?e.prefix():"")}function u(e,t){return function(){var n=e.indexOf(t);return!!~n&&(e.splice(n,1),!0)}}function c(e){e&&e.type&&t.forEach((function(t){t.test(e.key)&&t.hook(e)}))}function l(t,o,u,c){try{o.forEach((function e(t,r){n.forEach((function(n){if(n.test(String(t.key))){var i={add:function(t,i){if(void 0===t)return this;if(!1===t)return delete o[r];var a=s(t.prefix)||s(i)||n.prefix||"";if(a&&(t.prefix=a),t.key=a+t.key,n.safe&&n.test(String(t.key)))throw new Error("prehook cannot insert into own range");var u=t.keyEncoding||function(e){if(e&&e._getKeyEncoding)return e._getKeyEncoding(e)}(t.prefix),c=t.valueEncoding||function(e){if(e&&e._getValueEncoding)return e._getValueEncoding(e)}(t.prefix);return u&&(t.keyEncoding=u),c&&(t.valueEncoding=c),o.push(t),e(t,o.length-1),this},put:function(e,t){return"object"==typeof e&&(e.type="put"),this.add(e,t)},del:function(e,t){return"object"==typeof e&&(e.type="del"),this.add(e,t)},veto:function(){return this.add(!1)}};n.hook.call(i,t,i.add,o)}}))}))}catch(e){return(c||u)(e)}if(1==(o=o.filter((function(e){return e&&e.type}))).length&&!t){var l=o[0];return"put"==l.type?r.call(e,l.key,l.value,u,c):i.call(e,l.key,u,c)}return a.call(e,o,u,c)}}},99558:(e,t,n)=>{e.exports=l;var o=n(89043),r=n(32554).NI,i=n(89539),a=n(43016),s=n(35086),u=n(86093),c=n(65054);function l(e){if(!(this instanceof l))return new l(e);if(!e)throw new Error("constructor requires at least a location argument");this.IDBOptions={},this.location=e}i.inherits(l,r),l.prototype._open=function(e,t){var n=this,r={storeName:this.location,autoIncrement:!1,keyPath:null,onStoreReady:function(){t&&t(null,n.idb)},onError:function(e){t&&t(e)}};u(r,e),this.IDBOptions=r,this.idb=new o(r)},l.prototype._get=function(e,t,n){this.idb.get(e,(function(o){if(void 0===o)return n(new Error("NotFound"));var r=!0;return!1===t.asBuffer&&(r=!1),t.raw&&(r=!1),r&&(o=o instanceof Uint8Array?c(o):new Buffer(String(o))),n(null,o,e)}),n)},l.prototype._del=function(e,t,n){this.idb.remove(e,n,n)},l.prototype._put=function(e,t,n,o){t instanceof ArrayBuffer&&(t=c(new Uint8Array(t)));var r=this.convertEncoding(e,t,n);Buffer.isBuffer(r.value)&&("function"==typeof t.toArrayBuffer?r.value=new Uint8Array(t.toArrayBuffer()):r.value=new Uint8Array(t)),this.idb.put(r.key,r.value,(function(){o()}),o)},l.prototype.convertEncoding=function(e,t,n){if(n.raw)return{key:e,value:t};if(t){var o=t.toString();"NaN"===o&&(t="NaN")}var r=n.valueEncoding,i={key:e,value:t};return!t||r&&"binary"===r||"object"!=typeof i.value&&(i.value=o),i},l.prototype.iterator=function(e){return"object"!=typeof e&&(e={}),new a(this.idb,e)},l.prototype._batch=function(e,t,n){var o,r,i,a,s=[];if(0===e.length)return setTimeout(n,0);for(o=0;o{var o=n(89539),r=n(32554).YI,i=n(82303);function a(e,t){t||(t={}),this.options=t,r.call(this,e),this._order=t.reverse?"DESC":"ASC",this._limit=t.limit,this._count=0,this._done=!1;var n=i.lowerBound(t),o=i.upperBound(t);try{this._keyRange=n||o?this.db.makeKeyRange({lower:n,upper:o,excludeLower:i.lowerBoundExclusive(t),excludeUpper:i.upperBoundExclusive(t)}):null}catch(e){this._keyRangeError=!0}this.callback=null}e.exports=a,o.inherits(a,r),a.prototype.createIterator=function(){var e=this;e.iterator=e.db.iterate((function(){e.onItem.apply(e,arguments)}),{keyRange:e._keyRange,autoContinue:!1,order:e._order,onError:function(e){console.log("horrible error",e)}})},a.prototype.onItem=function(e,t,n){if(!t&&this.callback)return this.callback(),void(this.callback=!1);var o=!0;this._limit&&this._limit>0&&this._count++>=this._limit&&(o=!1),o&&this.callback(!1,t.key,t.value),t&&t.continue()},a.prototype._next=function(e){return e?this._keyRangeError?e():(this._started||(this.createIterator(),this._started=!0),void(this.callback=e)):new Error("next() requires a callback argument")}},3732:e=>{var t=Object.prototype.hasOwnProperty,n=Object.prototype.toString,o=function(e){var t="function"==typeof e&&!(e instanceof RegExp)||"[object Function]"===n.call(e);return t||"undefined"==typeof window||(t=e===window.setTimeout||e===window.alert||e===window.confirm||e===window.prompt),t};e.exports=function(e,n){if(!o(n))throw new TypeError("iterator must be a function");var r,i,a="string"==typeof e,s=e.length,u=arguments.length>2?arguments[2]:null;if(s===+s)for(r=0;r{e.exports=Object.keys||n(23533)},70426:e=>{var t=Object.prototype.toString;e.exports=function(e){var n=t.call(e),o="[object Arguments]"===n;return o||(o="[object Array]"!==n&&null!==e&&"object"==typeof e&&"number"==typeof e.length&&e.length>=0&&"[object Function]"===t.call(e.callee)),o}},23533:(e,t,n)=>{!function(){"use strict";var t,o=Object.prototype.hasOwnProperty,r=Object.prototype.toString,i=n(3732),a=n(70426),s=!{toString:null}.propertyIsEnumerable("toString"),u=function(){}.propertyIsEnumerable("prototype"),c=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"];t=function(e){var t=null!==e&&"object"==typeof e,n="[object Function]"===r.call(e),l=a(e),d=[];if(!t&&!n&&!l)throw new TypeError("Object.keys called on a non-object");if(l)i(e,(function(e){d.push(e)}));else{var h,p=u&&n;for(h in e)p&&"prototype"===h||!o.call(e,h)||d.push(h)}if(s){var f=e.constructor,g=f&&f.prototype===e;i(c,(function(t){g&&"constructor"===t||!o.call(e,t)||d.push(t)}))}return d},e.exports=t}()},14992:e=>{e.exports=function(e){return null!==e&&("object"==typeof e||"function"==typeof e)}},86093:(e,t,n)=>{var o=n(59693),r=n(14992);e.exports=function(){for(var e={},t=0;t{var o=n(80767);function r(e,t,n){var o,r,i;t.limit=t.reverse?2:1,o=e.createReadStream(t),r=function(e,o){if(t.reverse&&o&&t.start&&o.key.toString()>t.start)return!1;"error"==e?n(o):"end"==e?n(new Error("range not found"),null,null):n(null,o.key,o.value)},i=[],["data","error","end"].forEach((function(e){function t(t){!1!==r(e,t)&&i.forEach((function(e){e()}))}o.on(e,t),i.push((function(){o.removeListener(e,t)}))}))}(t=e.exports=r).first=function(e,t,n){return n||(n=t,t={}),t.reverse=!1,r(e,o(t),n)},t.last=function(e,t,n){return n||(n=t,t={}),t.start,t.reverse=!0,r(e,o(t),(function(o,i,a){if(o){var s=t.start;t.start=null,r(e,t,(function(e,r,i){if(!r)return n(o,null,null);var a=r.toString();a<=s&&(!t.end||a>=t.end)?n(e,r,i):n(o,null,null)}))}else n(o,i,a)}))}},76338:e=>{function t(e,t,n,o){var r={type:e,key:t,value:n,options:o};return o&&o.prefix&&(r.prefix=o.prefix,delete o.prefix),this._operations.push(r),this}function n(e){this._operations=[],this._sdb=e,this.put=t.bind(this,"put"),this.del=t.bind(this,"del")}var o=n.prototype;o.clear=function(){this._operations=[]},o.write=function(e){this._sdb.batch(this._operations,e)},e.exports=n},98673:(e,t,n)=>{n(17187).EventEmitter,process.nextTick;var o=n(97202),r=n(76338),i=n(97780),a=n(11798);e.exports=function(e,t){function n(){}n.prototype=e;var s=new n;if(s.sublevel)return s;var u=(t=t||{}).sep=t.sep||"ÿ";function c(e){return function(t){return(t=i(t=t||{})).reverse?t.start=t.start||u:t.end=t.end||u,e.call(s,t)}}s._options=t,a(s),s.sublevels={},s.sublevel=function(e,t){return s.sublevels[e]?s.sublevels[e]:new o(s,e,t||this._options)},s.methods={},s.prefix=function(e){return""+(e||"")},s.pre=function(e,t){return t||(t=e,e={max:u}),s.hooks.pre(e,t)},s.post=function(e,t){return t||(t=e,e={max:u}),s.hooks.post(e,t)},s.readStream=s.createReadStream=c(s.createReadStream),s.keyStream=s.createKeyStream=c(s.createKeyStream),s.valuesStream=s.createValueStream=c(s.createValueStream);var l=s.batch;return s.batch=function(e,t,n){if(!Array.isArray(e))return new r(s);e.forEach((function(e){e.prefix&&("function"==typeof e.prefix.prefix?e.key=e.prefix.prefix(e.key):"string"==typeof e.prefix&&(e.key=e.prefix+e.key))})),l.call(s,e,t,n)},s}},97780:(e,t,n)=>{var o=n(16313);e.exports=function(e){var t=(e=o(e)).reverse,n=e.max||e.end,r=e.min||e.start,i=[r,n];return null!=r&&null!=n&&i.sort(),t&&(i=i.reverse()),e.start=i[0],e.end=i[1],delete e.min,delete e.max,e}},11012:(e,t,n)=>{e.exports=Object.keys||n(44784)},44784:(e,t,n)=>{!function(){"use strict";var t,o=Object.prototype.hasOwnProperty,r=n(65452),i=n(49804),a=!{toString:null}.propertyIsEnumerable("toString"),s=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"];t=function(e){if(!r.object(e)&&!r.array(e))throw new TypeError("Object.keys called on a non-object");var t,n=[];for(t in e)o.call(e,t)&&n.push(t);return a&&i(s,(function(t){o.call(e,t)&&n.push(t)})),n},e.exports=t}()},83312:e=>{e.exports=function(e){return null!==e&&("object"==typeof e||"function"==typeof e)}},71686:(e,t,n)=>{var o=n(11012),r=n(83312);e.exports=function(){for(var e={},t=0;t{var o=n(17187).EventEmitter,r=n(89539).inherits,i=n(21889),a=n(97780),s=n(71686),u=n(76338);function c(e,t,n){if("string"==typeof n&&(console.error("db.sublevel(name, seperator) is depreciated"),console.error("use db.sublevel(name, {sep: separator})) if you must"),n={sep:n}),!(this instanceof c))return new c(e,t,n);if(!e)throw new Error("must provide db");if(!t)throw new Error("must provide prefix");(n=n||{}).sep=n.sep||"ÿ",this._parent=e,this._options=n,this.options=n,this._prefix=t,this._root=d(this),e.sublevels[t]=this,this.sublevels={},this.methods={};var o=this;this.hooks={pre:function(){return o.pre.apply(o,arguments)},post:function(){return o.post.apply(o,arguments)}}}r(c,o);var l=c.prototype;function d(e){return e._parent?d(e._parent):e}l._key=function(e){var t=this._options.sep;return t+this._prefix+t+e},l._getOptsAndCb=function(e,t){return"function"==typeof e&&(t=e,e={}),{opts:s(e,this._options),cb:t}},l.sublevel=function(e,t){return this.sublevels[e]?this.sublevels[e]:new c(this,e,t||this._options)},l.put=function(e,t,n,o){var r=this._getOptsAndCb(n,o);this._root.put(this.prefix(e),t,r.opts,r.cb)},l.get=function(e,t,n){var o=this._getOptsAndCb(t,n);this._root.get(this.prefix(e),o.opts,o.cb)},l.del=function(e,t,n){var o=this._getOptsAndCb(t,n);this._root.del(this.prefix(e),o.opts,o.cb)},l.batch=function(e,t,n){if(!Array.isArray(e))return new u(this);var o=this,r=this._getOptsAndCb(t,n);e.forEach((function(e){"string"==typeof e.prefix?e.key=e.prefix+e.key:e.key=(e.prefix||o).prefix(e.key),e.prefix&&(e.prefix=null)})),this._root.batch(e,r.opts,r.cb)},l._getKeyEncoding=function(){return this.options.keyEncoding?this.options.keyEncoding:this._parent&&this._parent._getKeyEncoding?this._parent._getKeyEncoding():void 0},l._getValueEncoding=function(){return this.options.valueEncoding?this.options.valueEncoding:this._parent&&this._parent._getValueEncoding?this._parent._getValueEncoding():void 0},l.prefix=function(e){var t=this._options.sep;return this._parent.prefix()+t+this._prefix+t+(e||"")},l.keyStream=l.createKeyStream=function(e){return(e=e||{}).keys=!0,e.values=!1,this.createReadStream(e)},l.valueStream=l.createValueStream=function(e){return(e=e||{}).keys=!1,e.values=!0,e.keys=!1,this.createReadStream(e)},l.readStream=l.createReadStream=function(e){e=e||{};var t=d(this),n=this.prefix(),o=i.prefix(e,n);!function(e,t){["valueEncoding","encoding","keyEncoding","reverse","values","keys","limit","fillCache"].forEach((function(n){t.hasOwnProperty(n)&&(e[n]=t[n])}))}(o,s(e,this._options));var r=t.createReadStream(o);if(!1===o.values){var a;if(a=r.read)r.read=function(e){var t=a.call(this,e);return t&&(t=t.substring(n.length)),t};else{var u=r.emit;r.emit=function(e,t){"data"===e?u.call(this,"data",t.substring(n.length)):u.call(this,e,t)}}return r}return!1===o.keys||((a=r.read)?r.read=function(e){var t=a.call(this,e);return t&&(t.key=t.key.substring(n.length)),t}:r.on("data",(function(e){e.key=e.key.substring(n.length)}))),r},l.writeStream=l.createWriteStream=function(){var e=d(this),t=this.prefix(),n=e.createWriteStream.apply(e,arguments),o=n.write,r=this._options.encoding,i=this._options.valueEncoding,a=this._options.keyEncoding,s=!r&&!i&&!a;return n.write=s?function(e){return e.key=t+e.key,o.call(n,e)}:function(e){return e.key=t+e.key,r&&void 0===e.encoding&&(e.encoding=r),i&&void 0===e.valueEncoding&&(e.valueEncoding=i),a&&void 0===e.keyEncoding&&(e.keyEncoding=a),o.call(n,e)},n},l.approximateSize=function(){var e=d(db);return e.approximateSize.apply(e,arguments)},l.pre=function(e,t){t||(t=e,e=null),e=i.prefix(e,this.prefix(),this._options.sep);var n=d(this._parent),o=this.prefix();return n.hooks.pre(a(e),(function(e,n,r){t({key:e.key.substring(o.length),value:e.value,type:e.type},(function(e,t){n(e,e.prefix?t:t||o)}),r)}))},l.post=function(e,t){t||(t=e,e=null);var n=d(this._parent),o=this.prefix();return e=i.prefix(e,o,this._options.sep),n.hooks.post(a(e),(function(e){t({key:e.key.substring(o.length),value:e.value,type:e.type})}))},e.exports=c},48133:(e,t,n)=>{var o=n(63368),r=n(86667).WriteError,i=o.getOptions,a=o.dispatchError;function s(e){this._levelup=e,this.batch=e.db.batch(),this.ops=[]}s.prototype.put=function(e,t,n){n=i(this._levelup,n);var a=o.encodeKey(e,n),s=o.encodeValue(t,n);try{this.batch.put(a,s)}catch(e){throw new r(e)}return this.ops.push({type:"put",key:a,value:s}),this},s.prototype.del=function(e,t){t=i(this._levelup,t);var n=o.encodeKey(e,t);try{this.batch.del(n)}catch(e){throw new r(e)}return this.ops.push({type:"del",key:n}),this},s.prototype.clear=function(){try{this.batch.clear()}catch(e){throw new r(e)}return this.ops=[],this},s.prototype.write=function(e){var t=this._levelup,n=this.ops;try{this.batch.write((function(o){if(o)return a(t,new r(o),e);t.emit("batch",n),e&&e()}))}catch(e){throw new r(e)}},e.exports=s},86667:(e,t,n)=>{var o=n(47138).create,r=o("LevelUPError"),i=o("NotFoundError",r);i.prototype.notFound=!0,i.prototype.status=404,e.exports={LevelUPError:r,InitializationError:o("InitializationError",r),OpenError:o("OpenError",r),ReadError:o("ReadError",r),WriteError:o("WriteError",r),NotFoundError:i,EncodingError:o("EncodingError",r)}},34918:(e,t,n)=>{var o=n(17187).EventEmitter,r=n(89539).inherits,i=n(47357),a=n(30115),s=n(66944),u=n(86667).WriteError,c=n(86667).ReadError,l=n(86667).NotFoundError,d=n(86667).OpenError,h=n(86667).EncodingError,p=n(86667).InitializationError,f=n(83209),g=n(53028),m=n(63368),_=n(48133),F=m.getOptions,y=m.defaultOptions,b=m.getLevelDOWN,v=m.dispatchError;function w(e,t){return"function"==typeof e?e:t}function E(e,t,n){if(!(this instanceof E))return new E(e,t,n);var r;if(o.call(this),this.setMaxListeners(1/0),"function"==typeof e?((t="object"==typeof t?t:{}).db=e,e=null):"object"==typeof e&&"function"==typeof e.db&&(t=e,e=null),"function"==typeof t&&(n=t,t={}),(!t||"function"!=typeof t.db)&&"string"!=typeof e){if(r=new p("Must provide a location for the database"),n)return process.nextTick((function(){n(r)}));throw r}t=F(this,t),this.options=i(y,t),this._status="new",a(this,"location",e,"e"),this.open(n)}function k(e){return function(t,n){b()[e](t,n||function(){})}}r(E,o),E.prototype.open=function(e){var t,n,o=this;return this.isOpen()?(e&&process.nextTick((function(){e(null,o)})),this):this._isOpening()?e&&this.once("open",(function(){e(null,o)})):(this.emit("opening"),this._status="opening",this.db=new s(this.location),t=this.options.db||b(),void(n=t(this.location)).open(this.options,(function(t){if(t)return v(o,new d(t),e);o.db.setDb(n),o.db=n,o._status="open",e&&e(null,o),o.emit("open"),o.emit("ready")})))},E.prototype.close=function(e){var t=this;if(this.isOpen())this._status="closing",this.db.close((function(){t._status="closed",t.emit("closed"),e&&e.apply(null,arguments)})),this.emit("closing"),this.db=null;else{if("closed"==this._status&&e)return process.nextTick(e);"closing"==this._status&&e?this.once("closed",e):this._isOpening()&&this.once("open",(function(){t.close(e)}))}},E.prototype.isOpen=function(){return"open"==this._status},E.prototype._isOpening=function(){return"opening"==this._status},E.prototype.isClosed=function(){return/^clos/.test(this._status)},E.prototype.get=function(e,t,n){var o,r=this;return"function"!=typeof(n=w(t,n))?v(this,new c("get() requires key and callback arguments")):this._isOpening()||this.isOpen()?(t=m.getOptions(this,t),o=m.encodeKey(e,t),t.asBuffer=m.isValueAsBuffer(t),void this.db.get(o,t,(function(o,i){if(o)return o=/notfound/i.test(o)?new l("Key not found in database ["+e+"]",o):new c(o),v(r,o,n);if(n){try{i=m.decodeValue(i,t)}catch(e){return n(new h(e))}n(null,i)}}))):v(this,new c("Database is not open"),n)},E.prototype.put=function(e,t,n,o){var r,i,a=this;return o=w(n,o),null==e||null==t?v(this,new u("put() requires key and value arguments"),o):this._isOpening()||this.isOpen()?(n=F(this,n),r=m.encodeKey(e,n),i=m.encodeValue(t,n),void this.db.put(r,i,n,(function(n){if(n)return v(a,new u(n),o);a.emit("put",e,t),o&&o()}))):v(this,new u("Database is not open"),o)},E.prototype.del=function(e,t,n){var o,r=this;return n=w(t,n),null==e?v(this,new u("del() requires a key argument"),n):this._isOpening()||this.isOpen()?(t=F(this,t),o=m.encodeKey(e,t),void this.db.del(o,t,(function(t){if(t)return v(r,new u(t),n);r.emit("del",e),n&&n()}))):v(this,new u("Database is not open"),n)},E.prototype.batch=function(e,t,n){var o,r,i,a=this;return arguments.length?(n=w(t,n),Array.isArray(e)?this._isOpening()||this.isOpen()?(t=F(this,t),o=t.keyEncoding,r=t.valueEncoding,i=e.map((function(e){if(void 0===e.type||void 0===e.key)return{};var n,i=e.keyEncoding||o,a=e.valueEncoding||e.encoding||r;return"utf8"!=i&&"binary"!=i||"utf8"!=a&&"binary"!=a?(n={type:e.type,key:m.encodeKey(e.key,t,e)},void 0!==e.value&&(n.value=m.encodeValue(e.value,t,e)),n):e})),void this.db.batch(i,t,(function(t){if(t)return v(a,new u(t),n);a.emit("batch",e),n&&n()}))):v(this,new u("Database is not open"),n):v(this,new u("batch() requires an array argument"),n)):new _(this)},E.prototype.approximateSize=function(e,t,n){var o,r,i=this;return null==e||null==t||"function"!=typeof n?v(this,new c("approximateSize() requires start, end and callback arguments"),n):(o=m.encodeKey(e,this.options),r=m.encodeKey(t,this.options),this._isOpening()||this.isOpen()?void this.db.approximateSize(o,r,(function(e,t){if(e)return v(i,new d(e),n);n&&n(null,t)})):v(this,new u("Database is not open"),n))},E.prototype.readStream=E.prototype.createReadStream=function(e){var t=this;return e=i(this.options,e),new f(e,this,(function(e){return t.db.iterator(e)}))},E.prototype.keyStream=E.prototype.createKeyStream=function(e){return this.createReadStream(i(e,{keys:!0,values:!1}))},E.prototype.valueStream=E.prototype.createValueStream=function(e){return this.createReadStream(i(e,{keys:!1,values:!0}))},E.prototype.writeStream=E.prototype.createWriteStream=function(e){return new g(i(e),this)},E.prototype.toString=function(){return"LevelUP"},e.exports=E,e.exports.copy=m.copy,e.exports.destroy=k("destroy"),e.exports.repair=k("repair")},83209:(e,t,n)=>{var o=n(11892).Readable,r=n(89539).inherits,i=n(47357),a=n(86667).EncodingError,s=n(63368),u={keys:!0,values:!0},c=function(e,t){return{key:s.decodeKey(e,this._options),value:s.decodeValue(t,this._options)}},l=function(e){return s.decodeKey(e,this._options)},d=function(e,t){return s.decodeValue(t,this._options)},h=function(){return null};function p(e,t,n){if(!(this instanceof p))return new p(e,t,n);o.call(this,{objectMode:!0,highWaterMark:e.highWaterMark}),this._db=t,e=this._options=i(u,e),this._keyEncoding=e.keyEncoding||e.encoding,this._valueEncoding=e.valueEncoding||e.encoding,void 0!==this._options.start&&(this._options.start=s.encodeKey(this._options.start,this._options)),void 0!==this._options.end&&(this._options.end=s.encodeKey(this._options.end,this._options)),"number"!=typeof this._options.limit&&(this._options.limit=-1),this._options.keyAsBuffer=s.isKeyAsBuffer(this._options),this._options.valueAsBuffer=s.isValueAsBuffer(this._options),this._makeData=this._options.keys&&this._options.values?c:this._options.keys?l:this._options.values?d:h;var r=this;this._db.isOpen()?this._iterator=n(this._options):this._db.once("ready",(function(){r._destroyed||(r._iterator=n(r._options))}))}r(p,o),p.prototype._read=function e(){var t=this;if(!t._db.isOpen())return t._db.once("ready",(function(){e.call(t)}));t._destroyed||t._iterator.next((function(e,n,o){if(e||void 0===n&&void 0===o)return e||t._destroyed||t.push(null),t._cleanup(e);try{o=t._makeData(n,o)}catch(e){return t._cleanup(new a(e))}t._destroyed||t.push(o)}))},p.prototype._cleanup=function(e){if(!this._destroyed){this._destroyed=!0;var t=this;e&&t.emit("error",e),t._iterator?t._iterator.end((function(){t._iterator=null,t.emit("close")})):t.emit("close")}},p.prototype.destroy=function(){this._cleanup()},p.prototype.toString=function(){return"LevelUP.ReadStream"},e.exports=p},63368:(e,t,n)=>{var o,r,i=n(47357),a=n(86667).LevelUPError,s=["hex","utf8","utf-8","ascii","binary","base64","ucs2","ucs-2","utf16le","utf-16le"],u={createIfMissing:!0,errorIfExists:!1,keyEncoding:"utf8",valueEncoding:"utf8",compression:!0},c=function(){function e(e){return null==e||Buffer.isBuffer(e)}var t={};return t.utf8=t["utf-8"]={encode:function(t){return e(t)?t:String(t)},decode:function(e){return e},buffer:!1,type:"utf8"},t.json={encode:JSON.stringify,decode:JSON.parse,buffer:!1,type:"json"},s.forEach((function(n){t[n]||(t[n]={encode:function(t){return e(t)?t:new Buffer(t,n)},decode:function(e){return process.browser?e.toString(n):e},buffer:!0,type:n})})),t}(),l=(r={},s.forEach((function(e){r[e]={valueEncoding:e}})),r);function d(e,t){var n=t&&t.keyEncoding||e.keyEncoding||"utf8";return c[n]||n}function h(e,t){var n=t&&(t.valueEncoding||t.encoding)||e.valueEncoding||e.encoding||"utf8";return c[n]||n}e.exports={defaultOptions:u,copy:function(e,t,n){e.readStream().pipe(t.writeStream()).on("close",n||function(){}).on("error",n||function(e){throw e})},getOptions:function(e,t){var n="string"==typeof t;return!n&&t&&t.encoding&&!t.valueEncoding&&(t.valueEncoding=t.encoding),i(e&&e.options||{},n?l[t]||l[u.valueEncoding]:t)},getLevelDOWN:function(){if(o)return o;var e,t=n(68232).v6.ct,r="Could not locate LevelDOWN, try `npm install leveldown`";try{e=n(94093).version}catch(e){throw new a(r)}if(!n(61695).satisfies(e,t))throw new a("Installed version of LevelDOWN ("+e+") does not match required version ("+t+")");try{return o=n(70131)}catch(e){throw new a(r)}},dispatchError:function(e,t,n){return"function"==typeof n?n(t):e.emit("error",t)},encodeKey:function(e,t,n){return d(t,n).encode(e)},encodeValue:function(e,t,n){return h(t,n).encode(e)},isValueAsBuffer:function(e,t){return h(e,t).buffer},isKeyAsBuffer:function(e,t){return d(e,t).buffer},decodeValue:function(e,t){return h(t).decode(e)},decodeKey:function(e,t){return d(t).decode(e)}}},53028:(e,t,n)=>{var o=n(42830).Stream,r=n(89539).inherits,i=n(47357),a=n(10022),s=n.g.setImmediate||process.nextTick,u=n(63368).getOptions,c={type:"put"};function l(e,t){if(!(this instanceof l))return new l(e,t);o.call(this),this._options=i(c,u(t,e)),this._db=t,this._buffer=[],this._status="init",this._end=!1,this.writable=!0,this.readable=!1;var n=this,r=function(){n.writable&&(n._status="ready",n.emit("ready"),n._process())};t.isOpen()?s(r):t.once("ready",r)}r(l,o),l.prototype.write=function(e){return!(!this.writable||(this._buffer.push(e),"init"!=this._status&&this._processDelayed(),this._options.maxBufferLength&&this._buffer.length>this._options.maxBufferLength&&(this._writeBlock=!0,1)))},l.prototype.end=function(e){var t=this;e&&this.write(e),s((function(){t._end=!0,t._process()}))},l.prototype.destroy=function(){this.writable=!1,this.end()},l.prototype.destroySoon=function(){this.end()},l.prototype.add=function(e){if(e.props)return e.props.Directory?e.pipe(this._db.writeStream(this._options)):(e.props.File||e.File||"File"==e.type)&&this._write(e),!0},l.prototype._processDelayed=function(){var e=this;s((function(){e._process()}))},l.prototype._process=function(){var e,t=this;if("ready"==t._status||!t.writable)return t._buffer.length&&t.writable?(t._status="writing",e=t._buffer,t._buffer=[],t._db.batch(e.map((function(e){return{type:e.type||t._options.type,key:e.key,value:e.value,keyEncoding:e.keyEncoding||t._options.keyEncoding,valueEncoding:e.valueEncoding||e.encoding||t._options.valueEncoding}})),(function(e){if(t.writable){if("closed"!=t._status&&(t._status="ready"),e)return t.writable=!1,t.emit("error",e);t._process()}})),void(t._writeBlock&&(t._writeBlock=!1,t.emit("drain")))):void(t._end&&"closed"!=t._status&&(t._status="closed",t.writable=!1,t.emit("close")));t._buffer.length&&"closed"!=t._status&&t._processDelayed()},l.prototype._write=function(e){var t=e.path||e.props.path,n=this;t&&e.pipe(a((function(e,o){if(e)return n.writable=!1,n.emit("error",e);n._options.fstreamRoot&&t.indexOf(n._options.fstreamRoot)>-1&&(t=t.substr(n._options.fstreamRoot.length+1)),n.write({key:t,value:o.slice(0)})})))},l.prototype.toString=function(){return"LevelUP.WriteStream"},e.exports=l},65238:e=>{e.exports=Array.isArray||function(e){return"[object Array]"==Object.prototype.toString.call(e)}},30115:function(e){var t;t=function(){var e="function"==typeof Object.defineProperty?function(e,t,n){return Object.defineProperty(e,t,n),e}:function(e,t,n){return e[t]=n.value,e};return function(t,n,o,r){var i;if(r=function(e,t){var n="object"==typeof t,o=!n&&"string"==typeof t,r=function(e){return n?!!t[e]:!!o&&t.indexOf(e[0])>-1};return{enumerable:r("enumerable"),configurable:r("configurable"),writable:r("writable"),value:e}}(o,r),"object"==typeof n){for(i in n)Object.hasOwnProperty.call(n,i)&&(r.value=n[i],e(t,i,r));return t}return e(t,n,r)}},e.exports?e.exports=t():this.prr=t()},32422:(e,t,n)=>{e.exports=s;var o=Object.keys||function(e){var t=[];for(var n in e)t.push(n);return t},r=n(16497);r.inherits=n(35717);var i=n(66810),a=n(54160);function s(e){if(!(this instanceof s))return new s(e);i.call(this,e),a.call(this,e),e&&!1===e.readable&&(this.readable=!1),e&&!1===e.writable&&(this.writable=!1),this.allowHalfOpen=!0,e&&!1===e.allowHalfOpen&&(this.allowHalfOpen=!1),this.once("end",u)}function u(){this.allowHalfOpen||this._writableState.ended||process.nextTick(this.end.bind(this))}r.inherits(s,i),function(e,t){for(var n=0,o=e.length;n{e.exports=i;var o=n(31036),r=n(16497);function i(e){if(!(this instanceof i))return new i(e);o.call(this,e)}r.inherits=n(35717),r.inherits(i,o),i.prototype._transform=function(e,t,n){n(null,e)}},66810:(e,t,n)=>{e.exports=l;var o=n(65238),r=n(48764).Buffer;l.ReadableState=c;var i=n(17187).EventEmitter;i.listenerCount||(i.listenerCount=function(e,t){return e.listeners(t).length});var a,s=n(42830),u=n(16497);function c(e,t){var o=(e=e||{}).highWaterMark;this.highWaterMark=o||0===o?o:16384,this.highWaterMark=~~this.highWaterMark,this.buffer=[],this.length=0,this.pipes=null,this.pipesCount=0,this.flowing=!1,this.ended=!1,this.endEmitted=!1,this.reading=!1,this.calledRead=!1,this.sync=!0,this.needReadable=!1,this.emittedReadable=!1,this.readableListening=!1,this.objectMode=!!e.objectMode,this.defaultEncoding=e.defaultEncoding||"utf8",this.ranOut=!1,this.awaitDrain=0,this.readingMore=!1,this.decoder=null,this.encoding=null,e.encoding&&(a||(a=n(45951).s),this.decoder=new a(e.encoding),this.encoding=e.encoding)}function l(e){if(!(this instanceof l))return new l(e);this._readableState=new c(e,this),this.readable=!0,s.call(this)}function d(e,t,n,o,i){var a=function(e,t){var n=null;return r.isBuffer(t)||"string"==typeof t||null==t||e.objectMode||(n=new TypeError("Invalid non-string/buffer chunk")),n}(t,n);if(a)e.emit("error",a);else if(null==n)t.reading=!1,t.ended||function(e,t){if(t.decoder&&!t.ended){var n=t.decoder.end();n&&n.length&&(t.buffer.push(n),t.length+=t.objectMode?1:n.length)}t.ended=!0,t.length>0?f(e):b(e)}(e,t);else if(t.objectMode||n&&n.length>0)if(t.ended&&!i){var s=new Error("stream.push() after EOF");e.emit("error",s)}else t.endEmitted&&i?(s=new Error("stream.unshift() after end event"),e.emit("error",s)):(!t.decoder||i||o||(n=t.decoder.write(n)),t.length+=t.objectMode?1:n.length,i?t.buffer.unshift(n):(t.reading=!1,t.buffer.push(n)),t.needReadable&&f(e),function(e,t){t.readingMore||(t.readingMore=!0,process.nextTick((function(){!function(e,t){for(var n=t.length;!t.reading&&!t.flowing&&!t.ended&&t.lengtht.highWaterMark&&(t.highWaterMark=function(e){if(e>=h)e=h;else{e--;for(var t=1;t<32;t<<=1)e|=e>>t;e++}return e}(e)),e>t.length?t.ended?t.length:(t.needReadable=!0,0):e)}function f(e){var t=e._readableState;t.needReadable=!1,t.emittedReadable||(t.emittedReadable=!0,t.sync?process.nextTick((function(){g(e)})):g(e))}function g(e){e.emit("readable")}function m(e){var t,n=e._readableState;function o(e,o,r){!1===e.write(t)&&n.awaitDrain++}for(n.awaitDrain=0;n.pipesCount&&null!==(t=e.read());)if(1===n.pipesCount?o(n.pipes):v(n.pipes,o),e.emit("data",t),n.awaitDrain>0)return;if(0===n.pipesCount)return n.flowing=!1,void(i.listenerCount(e,"data")>0&&F(e));n.ranOut=!0}function _(){this._readableState.ranOut&&(this._readableState.ranOut=!1,m(this))}function F(e,t){if(e._readableState.flowing)throw new Error("Cannot switch to old mode now.");var n=t||!1,o=!1;e.readable=!0,e.pipe=s.prototype.pipe,e.on=e.addListener=s.prototype.on,e.on("readable",(function(){var t;for(o=!0;!n&&null!==(t=e.read());)e.emit("data",t);null===t&&(o=!1,e._readableState.needReadable=!0)})),e.pause=function(){n=!0,this.emit("pause")},e.resume=function(){n=!1,o?process.nextTick((function(){e.emit("readable")})):this.read(0),this.emit("resume")},e.emit("readable")}function y(e,t){var n,o=t.buffer,i=t.length,a=!!t.decoder,s=!!t.objectMode;if(0===o.length)return null;if(0===i)n=null;else if(s)n=o.shift();else if(!e||e>=i)n=a?o.join(""):r.concat(o,i),o.length=0;else if(e0)throw new Error("endReadable called on non-empty stream");!t.endEmitted&&t.calledRead&&(t.ended=!0,process.nextTick((function(){t.endEmitted||0!==t.length||(t.endEmitted=!0,e.readable=!1,e.emit("end"))})))}function v(e,t){for(var n=0,o=e.length;n0)&&(t.emittedReadable=!1),0===e&&t.needReadable&&(t.length>=t.highWaterMark||t.ended))return f(this),null;if(0===(e=p(e,t))&&t.ended)return n=null,t.length>0&&t.decoder&&(n=y(e,t),t.length-=n.length),0===t.length&&b(this),n;var r=t.needReadable;return t.length-e<=t.highWaterMark&&(r=!0),(t.ended||t.reading)&&(r=!1),r&&(t.reading=!0,t.sync=!0,0===t.length&&(t.needReadable=!0),this._read(t.highWaterMark),t.sync=!1),r&&!t.reading&&(e=p(o,t)),null===(n=e>0?y(e,t):null)&&(t.needReadable=!0,e=0),t.length-=e,0!==t.length||t.ended||(t.needReadable=!0),t.ended&&!t.endEmitted&&0===t.length&&b(this),n},l.prototype._read=function(e){this.emit("error",new Error("not implemented"))},l.prototype.pipe=function(e,t){var n=this,r=this._readableState;switch(r.pipesCount){case 0:r.pipes=e;break;case 1:r.pipes=[r.pipes,e];break;default:r.pipes.push(e)}r.pipesCount+=1;var a=t&&!1===t.end||e===process.stdout||e===process.stderr?l:u;function s(e){e===n&&l()}function u(){e.end()}r.endEmitted?process.nextTick(a):n.once("end",a),e.on("unpipe",s);var c=function(e){return function(){var t=e._readableState;t.awaitDrain--,0===t.awaitDrain&&m(e)}}(n);function l(){e.removeListener("close",h),e.removeListener("finish",p),e.removeListener("drain",c),e.removeListener("error",d),e.removeListener("unpipe",s),n.removeListener("end",u),n.removeListener("end",l),e._writableState&&!e._writableState.needDrain||c()}function d(t){f(),e.removeListener("error",d),0===i.listenerCount(e,"error")&&e.emit("error",t)}function h(){e.removeListener("finish",p),f()}function p(){e.removeListener("close",h),f()}function f(){n.unpipe(e)}return e.on("drain",c),e._events&&e._events.error?o(e._events.error)?e._events.error.unshift(d):e._events.error=[d,e._events.error]:e.on("error",d),e.once("close",h),e.once("finish",p),e.emit("pipe",n),r.flowing||(this.on("readable",_),r.flowing=!0,process.nextTick((function(){m(n)}))),e},l.prototype.unpipe=function(e){var t=this._readableState;if(0===t.pipesCount)return this;if(1===t.pipesCount)return e&&e!==t.pipes||(e||(e=t.pipes),t.pipes=null,t.pipesCount=0,this.removeListener("readable",_),t.flowing=!1,e&&e.emit("unpipe",this)),this;if(!e){var n=t.pipes,o=t.pipesCount;t.pipes=null,t.pipesCount=0,this.removeListener("readable",_),t.flowing=!1;for(var r=0;r{e.exports=a;var o=n(32422),r=n(16497);function i(e,t){this.afterTransform=function(e,n){return function(e,t,n){var o=e._transformState;o.transforming=!1;var r=o.writecb;if(!r)return e.emit("error",new Error("no writecb in Transform class"));o.writechunk=null,o.writecb=null,null!=n&&e.push(n),r&&r(t);var i=e._readableState;i.reading=!1,(i.needReadable||i.length{e.exports=u;var o=n(48764).Buffer;u.WritableState=s;var r=n(16497);r.inherits=n(35717);var i=n(42830);function a(e,t,n){this.chunk=e,this.encoding=t,this.callback=n}function s(e,t){var n=(e=e||{}).highWaterMark;this.highWaterMark=n||0===n?n:16384,this.objectMode=!!e.objectMode,this.highWaterMark=~~this.highWaterMark,this.needDrain=!1,this.ending=!1,this.ended=!1,this.finished=!1;var o=!1===e.decodeStrings;this.decodeStrings=!o,this.defaultEncoding=e.defaultEncoding||"utf8",this.length=0,this.writing=!1,this.sync=!0,this.bufferProcessing=!1,this.onwrite=function(e){!function(e,t){var n=e._writableState,o=n.sync,r=n.writecb;if(function(e){e.writing=!1,e.writecb=null,e.length-=e.writelen,e.writelen=0}(n),t)!function(e,t,n,o,r){n?process.nextTick((function(){r(o)})):r(o),e._writableState.errorEmitted=!0,e.emit("error",o)}(e,0,o,t,r);else{var i=d(0,n);i||n.bufferProcessing||!n.buffer.length||function(e,t){t.bufferProcessing=!0;for(var n=0;n{var o=n(42830);(t=e.exports=n(66810)).Stream=o,t.Readable=t,t.Writable=n(54160),t.Duplex=n(32422),t.Transform=n(31036),t.PassThrough=n(78264),process.browser||"disable"!==process.env.READABLE_STREAM||(e.exports=n(42830))},45951:(e,t,n)=>{var o=n(48764).Buffer,r=o.isEncoding||function(e){switch(e&&e.toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":case"raw":return!0;default:return!1}},i=t.s=function(e){switch(this.encoding=(e||"utf8").toLowerCase().replace(/[-_]/,""),function(e){if(e&&!r(e))throw new Error("Unknown encoding: "+e)}(e),this.encoding){case"utf8":this.surrogateSize=3;break;case"ucs2":case"utf16le":this.surrogateSize=2,this.detectIncompleteChar=s;break;case"base64":this.surrogateSize=3,this.detectIncompleteChar=u;break;default:return void(this.write=a)}this.charBuffer=new o(6),this.charReceived=0,this.charLength=0};function a(e){return e.toString(this.encoding)}function s(e){this.charReceived=e.length%2,this.charLength=this.charReceived?2:0}function u(e){this.charReceived=e.length%3,this.charLength=this.charReceived?3:0}i.prototype.write=function(e){for(var t="";this.charLength;){var n=e.length>=this.charLength-this.charReceived?this.charLength-this.charReceived:e.length;if(e.copy(this.charBuffer,this.charReceived,0,n),this.charReceived+=n,this.charReceived=55296&&o<=56319)){if(this.charReceived=this.charLength=0,0===e.length)return t;break}this.charLength+=this.surrogateSize,t=""}this.detectIncompleteChar(e);var o,r=e.length;if(this.charLength&&(e.copy(this.charBuffer,0,e.length-this.charReceived,r),r-=this.charReceived),r=(t+=e.toString(this.encoding,0,r)).length-1,(o=t.charCodeAt(r))>=55296&&o<=56319){var i=this.surrogateSize;return this.charLength+=i,this.charReceived+=i,this.charBuffer.copy(this.charBuffer,i,0,i),e.copy(this.charBuffer,0,0,i),t.substring(0,r)}return t},i.prototype.detectIncompleteChar=function(e){for(var t=e.length>=3?3:e.length;t>0;t--){var n=e[e.length-t];if(1==t&&n>>5==6){this.charLength=2;break}if(t<=2&&n>>4==14){this.charLength=3;break}if(t<=3&&n>>3==30){this.charLength=4;break}}this.charReceived=t},i.prototype.end=function(e){var t="";if(e&&e.length&&(t=this.write(e)),this.charReceived){var n=this.charReceived,o=this.charBuffer,r=this.encoding;t+=o.slice(0,n).toString(r)}return t}},47357:e=>{e.exports=function(){for(var e={},t=0;t{"use strict";e.exports=JSON.parse('{"v6":{"ct":"~0.10.0"}}')},58303:(e,t,n)=>{var o=n(31934);e.exports=function(e){var t=o(e,"line-height"),n=parseFloat(t,10);if(t===n+""){var r=e.style.lineHeight;e.style.lineHeight=t+"em",t=o(e,"line-height"),n=parseFloat(t,10),r?e.style.lineHeight=r:delete e.style.lineHeight}if(-1!==t.indexOf("pt")?(n*=4,n/=3):-1!==t.indexOf("mm")?(n*=96,n/=25.4):-1!==t.indexOf("cm")?(n*=96,n/=2.54):-1!==t.indexOf("in")?n*=96:-1!==t.indexOf("pc")&&(n*=16),n=Math.round(n),"normal"===t){var i=e.nodeName,a=document.createElement(i);a.innerHTML=" ","TEXTAREA"===i.toUpperCase()&&a.setAttribute("rows","1");var s=o(e,"font-size");a.style.fontSize=s,a.style.padding="0px",a.style.border="0px";var u=document.body;u.appendChild(a),n=a.offsetHeight,u.removeChild(a)}return n}},87100:(e,t,n)=>{"use strict";var o=n(67294),r=n(8425);function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function a(e,t){for(var n=0;ne.length)&&(t=e.length);for(var n=0,o=new Array(t);n2&&void 0!==arguments[2]?arguments[2]:0;if(0===o.Children.count(e.props.children))return e;var r=[];o.Children.forEach(e.props.children,(function(e){"string"==typeof e?(n+=1,r.push.apply(r,l(p(e,t)))):o.isValidElement(e)?"string"==typeof e.type&&t.ignoreTags.indexOf(e.type.toUpperCase())>=0?r.push(e):r.push(f(e,t,++n)):r.push(e)}));var i={key:"linkified-element-".concat(n)};for(var a in e.props)i[a]=e.props[a];return o.cloneElement(e,i,r)}var g=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&u(e,t)}(p,e);var t,n,r,l,d=(r=p,l=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,t=s(r);if(l){var n=s(this).constructor;e=Reflect.construct(t,arguments,n)}else e=t.apply(this,arguments);return c(this,e)});function p(){return i(this,p),d.apply(this,arguments)}return t=p,(n=[{key:"render",value:function(){var e={key:"linkified-element-0"};for(var t in this.props)"options"!==t&&"tagName"!==t&&(e[t]=this.props[t]);var n=new h(this.props.options),r=this.props.tagName||"span";return f(o.createElement(r,e),n,0)}}])&&a(t.prototype,n),p}(o.Component);e.exports=g},8425:(e,t)=>{"use strict";function n(e){this.j={},this.jr=[],this.jd=null,this.t=e}Object.defineProperty(t,"__esModule",{value:!0}),n.prototype={accepts:function(){return!!this.t},tt:function(e,t){if(t&&t.j)return this.j[e]=t,t;var n=t,r=this.j[e];if(r)return n&&(r.t=n),r;r=o();var i=s(this,e);return i?(Object.assign(r.j,i.j),r.jr.append(i.jr),r.jr=i.jd,r.t=n||i.t):r.t=n,this.j[e]=r,r}};var o=function(){return new n},r=function(e){return new n(e)},i=function(e,t,n){e.j[t]||(e.j[t]=n)},a=function(e,t,n){e.jr.push([t,n])},s=function(e,t){var n=e.j[t];if(n)return n;for(var o=0;o=s)return[];for(;a0&&void 0!==arguments[0]?arguments[0]:[],t=o(),n=r(y),s=r(d),P=o(),G=r(x),$=[[z,s],[j,s],[q,s]],H=function(){var e=r(d);return e.j={"-":P},e.jr=[].concat($),e},V=function(e){var t=H();return t.t=e,t};c(t,[["@",r(f)],[".",r(m)],["+",r(b)],["#",r(v)],["?",r(w)],["/",r(E)],["_",r(k)],[":",r(g)],["{",r(C)],["[",r(A)],["<",r(T)],["(",r(R)],["}",r(I)],["]",r(M)],[">",r(O)],[")",r(B)],["&",r(N)]]),u(t,[",",";","!",'"',"'"],r(_)),i(t,"\n",r(F)),a(t,K,G),i(G,"\n",o()),a(G,K,G);for(var W=0;W2&&void 0!==arguments[2]?arguments[2]:{},o=Object.create(e.prototype);for(var r in n)o[r]=n[r];o.constructor=t,t.prototype=o}(Z,n,t),n}Z.prototype={t:"token",isLink:!1,toString:function(){return this.v},toHref:function(){return this.toString()},startIndex:function(){return this.tk[0].s},endIndex:function(){return this.tk[this.tk.length-1].e},toObject:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:H.defaultProtocol;return{type:this.t,value:this.v,isLink:this.isLink,href:this.toHref(e),start:this.startIndex(),end:this.endIndex()}}};var J=X("email",{isLink:!0}),Q=X("email",{isLink:!0,toHref:function(){return"mailto:"+this.toString()}}),ee=X("text"),te=X("nl"),ne=X("url",{isLink:!0,toHref:function(){for(var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:H.defaultProtocol,t=this.tk,n=!1,o=!1,r=[],i=0;t[i].t===D;)n=!0,r.push(t[i].v),i++;for(;t[i].t===E;)o=!0,r.push(t[i].v),i++;for(;i=0&&p++,r++,d++;if(p<0)for(var f=r-d;f0&&(i.push(ie(ee,t,a)),a=[]),r-=p,d-=p;var g=h.t,m=n.slice(r-d,r);i.push(ie(g,t,m))}}return a.length>0&&i.push(ie(ee,t,a)),i}(se.parser.start,e,function(e,t){for(var n=Array.from(t.replace(/[A-Z]/g,(function(e){return e.toLowerCase()}))),o=n.length,r=[],i=0,a=0;a=0&&(h+=n[a].length,p++),l+=n[a].length,i+=n[a].length,a++;h<0||(i-=h,a-=p,l-=h,r.push({t:d.t,v:t.substr(i-l,l),s:i-l,e:i}))}return r}(se.scanner.start,e))}t.find=function(e){for(var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null,n=ce(e),o=[],r=0;r1&&void 0!==arguments[1]?arguments[1]:null,n=ce(e);return 1===n.length&&n[0].isLink&&(!t||n[0].t===t)},t.tokenize=ce},28175:(e,t,n)=>{e.exports=n(87100)},2043:function(e,t,n){var o,r;!function(i,a){"use strict";void 0===(r="function"==typeof(o=function(){var e=function(){},t="undefined",n=typeof window!==t&&typeof window.navigator!==t&&/Trident\/|MSIE /.test(window.navigator.userAgent),o=["trace","debug","info","warn","error"];function r(e,t){var n=e[t];if("function"==typeof n.bind)return n.bind(e);try{return Function.prototype.bind.call(n,e)}catch(t){return function(){return Function.prototype.apply.apply(n,[e,arguments])}}}function i(){console.log&&(console.log.apply?console.log.apply(console,arguments):Function.prototype.apply.apply(console.log,[console,arguments])),console.trace&&console.trace()}function a(o){return"debug"===o&&(o="log"),typeof console!==t&&("trace"===o&&n?i:void 0!==console[o]?r(console,o):void 0!==console.log?r(console,"log"):e)}function s(t,n){for(var r=0;r=0&&n<=a.levels.SILENT))throw"log.setLevel() called with invalid level: "+n;if(i=n,!1!==r&&function(e){var n=(o[e]||"silent").toUpperCase();if(typeof window!==t&&u){try{return void(window.localStorage[u]=n)}catch(e){}try{window.document.cookie=encodeURIComponent(u)+"="+n+";"}catch(e){}}}(n),s.call(a,n,e),typeof console===t&&n{function n(e){return void 0!==e&&""!==e}function o(e,t){return Object.hasOwnProperty.call(e,t)}function r(e,t){return Object.hasOwnProperty.call(e,t)&&t}t.compare=function(e,t){if(Buffer.isBuffer(e)){for(var n=Math.min(e.length,t.length),o=0;ot?1:0};var i=t.lowerBoundKey=function(e){return r(e,"gt")||r(e,"gte")||r(e,"min")||(e.reverse?r(e,"end"):r(e,"start"))||void 0},a=t.lowerBound=function(e,t){var n=i(e);return n?e[n]:t},s=t.lowerBoundInclusive=function(e){return!o(e,"gt")},u=t.upperBoundInclusive=function(e){return!o(e,"lt")},c=t.lowerBoundExclusive=function(e){return!s(e)},l=t.upperBoundExclusive=function(e){return!u(e)},d=t.upperBoundKey=function(e){return r(e,"lt")||r(e,"lte")||r(e,"max")||(e.reverse?r(e,"start"):r(e,"end"))||void 0},h=t.upperBound=function(e,t){var n=d(e);return n?e[n]:t};function p(e){return e}t.start=function(e,t){return e.reverse?h(e,t):a(e,t)},t.end=function(e,t){return e.reverse?a(e,t):h(e,t)},t.startInclusive=function(e){return e.reverse?u(e):s(e)},t.endInclusive=function(e){return e.reverse?s(e):u(e)},t.toLtgt=function(e,n,r,i,a){n=n||{},r=r||p;var s=arguments.length>3,u=t.lowerBoundKey(e),c=t.upperBoundKey(e);return u?"gt"===u?n.gt=r(e.gt,!1):n.gte=r(e[u],!1):s&&(n.gte=r(i,!1)),c?"lt"===c?n.lt=r(e.lt,!0):n.lte=r(e[c],!0):s&&(n.lte=r(a,!0)),null!=e.reverse&&(n.reverse=!!e.reverse),o(n,"max")&&delete n.max,o(n,"min")&&delete n.min,o(n,"start")&&delete n.start,o(n,"end")&&delete n.end,n},t.contains=function(e,o,r){r=r||t.compare;var i=a(e);if(n(i)&&((s=r(o,i))<0||0===s&&c(e)))return!1;var s,u=h(e);return!n(u)||!((s=r(o,u))>0||0===s&&l(e))},t.filter=function(e,n){return function(o){return t.contains(e,o,n)}}},78234:(e,t,n)=>{"use strict";var o=n(96464);e.exports=function(e,t){for(var n,l,d,h,p,f,g,m,_,F,y,b,v=t||{},w=!1!==v.padding,E=!1!==v.delimiterStart,k=!1!==v.delimiterEnd,D=(v.align||[]).concat(),S=!1!==v.alignDelimiters,x=[],C=v.stringLength||u,A=-1,T=e.length,R=[],I=[],M=[],O=[],B=[],N=0;++AN&&(N=d);++lh)&&(B[l]=p)),M.push(f);R[A]=M,I[A]=O}if(l=-1,d=N,"object"==typeof D&&"length"in D)for(;++lB[l]&&(B[l]=p),O[l]=p),M[l]=f;for(R.splice(1,0,M),I.splice(1,0,O),A=-1,T=R.length,g=[];++A{"use strict";let n,o,r;Object.defineProperty(t,"__esModule",{value:!0}),t.RoomType=t.RoomCreateTypeField=t.MsgType=t.EventType=void 0,t.EventType=n,function(e){e.RoomCanonicalAlias="m.room.canonical_alias",e.RoomCreate="m.room.create",e.RoomJoinRules="m.room.join_rules",e.RoomMember="m.room.member",e.RoomThirdPartyInvite="m.room.third_party_invite",e.RoomPowerLevels="m.room.power_levels",e.RoomName="m.room.name",e.RoomTopic="m.room.topic",e.RoomAvatar="m.room.avatar",e.RoomPinnedEvents="m.room.pinned_events",e.RoomEncryption="m.room.encryption",e.RoomHistoryVisibility="m.room.history_visibility",e.RoomGuestAccess="m.room.guest_access",e.RoomServerAcl="m.room.server_acl",e.RoomTombstone="m.room.tombstone",e.RoomAliases="m.room.aliases",e.SpaceChild="m.space.child",e.SpaceParent="m.space.parent",e.RoomRedaction="m.room.redaction",e.RoomMessage="m.room.message",e.RoomMessageEncrypted="m.room.encrypted",e.Sticker="m.sticker",e.CallInvite="m.call.invite",e.CallCandidates="m.call.candidates",e.CallAnswer="m.call.answer",e.CallHangup="m.call.hangup",e.CallReject="m.call.reject",e.CallSelectAnswer="m.call.select_answer",e.CallNegotiate="m.call.negotiate",e.CallReplaces="m.call.replaces",e.CallAssertedIdentity="m.call.asserted_identity",e.CallAssertedIdentityPrefix="org.matrix.call.asserted_identity",e.KeyVerificationRequest="m.key.verification.request",e.KeyVerificationStart="m.key.verification.start",e.KeyVerificationCancel="m.key.verification.cancel",e.KeyVerificationMac="m.key.verification.mac",e.KeyVerificationDone="m.key.verification.done",e.RoomMessageFeedback="m.room.message.feedback",e.Reaction="m.reaction",e.Typing="m.typing",e.Receipt="m.receipt",e.Presence="m.presence",e.FullyRead="m.fully_read",e.Tag="m.tag",e.PushRules="m.push_rules",e.Direct="m.direct",e.IgnoredUserList="m.ignored_user_list",e.RoomKey="m.room_key",e.RoomKeyRequest="m.room_key_request",e.ForwardedRoomKey="m.forwarded_room_key",e.Dummy="m.dummy"}(n||(t.EventType=n={})),t.MsgType=o,function(e){e.Text="m.text",e.Emote="m.emote",e.Notice="m.notice",e.Image="m.image",e.File="m.file",e.Audio="m.audio",e.Location="m.location",e.Video="m.video"}(o||(t.MsgType=o={})),t.RoomCreateTypeField="type",t.RoomType=r,function(e){e.Space="m.space"}(r||(t.RoomType=r={}))},20771:(e,t,n)=>{"use strict";var o=n(95318);Object.defineProperty(t,"__esModule",{value:!0}),t.ReEmitter=void 0;var r=o(n(59713));t.ReEmitter=class{constructor(e){(0,r.default)(this,"target",void 0),this.target=e}reEmit(e,t){for(const n of t){const t=(...t)=>{"error"===n&&0===this.target.listenerCount("error")||this.target.emit(n,...t,e)};e.on(n,t)}}}},79118:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.AutoDiscovery=void 0;var o=n(7434),r=n(8575);class i{static get ERROR_INVALID(){return"Invalid homeserver discovery response"}static get ERROR_GENERIC_FAILURE(){return"Failed to get autodiscovery configuration from server"}static get ERROR_INVALID_HS_BASE_URL(){return"Invalid base_url for m.homeserver"}static get ERROR_INVALID_HOMESERVER(){return"Homeserver URL does not appear to be a valid Matrix homeserver"}static get ERROR_INVALID_IS_BASE_URL(){return"Invalid base_url for m.identity_server"}static get ERROR_INVALID_IDENTITY_SERVER(){return"Identity server URL does not appear to be a valid identity server"}static get ERROR_INVALID_IS(){return"Invalid identity server discovery response"}static get ERROR_MISSING_WELLKNOWN(){return"No .well-known JSON file found"}static get ERROR_INVALID_JSON(){return"Invalid JSON"}static get ALL_ERRORS(){return[i.ERROR_INVALID,i.ERROR_GENERIC_FAILURE,i.ERROR_INVALID_HS_BASE_URL,i.ERROR_INVALID_HOMESERVER,i.ERROR_INVALID_IS_BASE_URL,i.ERROR_INVALID_IDENTITY_SERVER,i.ERROR_INVALID_IS,i.ERROR_MISSING_WELLKNOWN,i.ERROR_INVALID_JSON]}static get FAIL_ERROR(){return"FAIL_ERROR"}static get FAIL_PROMPT(){return"FAIL_PROMPT"}static get PROMPT(){return"PROMPT"}static get SUCCESS(){return"SUCCESS"}static async fromDiscoveryConfig(e){const t={"m.homeserver":{state:i.FAIL_ERROR,error:i.ERROR_INVALID,base_url:null},"m.identity_server":{state:i.PROMPT,error:null,base_url:null}};if(!e||!e["m.homeserver"])return o.logger.error("No m.homeserver key in config"),t["m.homeserver"].state=i.FAIL_PROMPT,t["m.homeserver"].error=i.ERROR_INVALID,Promise.resolve(t);if(!e["m.homeserver"].base_url)return o.logger.error("No m.homeserver base_url in config"),t["m.homeserver"].state=i.FAIL_PROMPT,t["m.homeserver"].error=i.ERROR_INVALID_HS_BASE_URL,Promise.resolve(t);const n=this._sanitizeWellKnownUrl(e["m.homeserver"].base_url);if(!n)return o.logger.error("Invalid base_url for m.homeserver"),t["m.homeserver"].error=i.ERROR_INVALID_HS_BASE_URL,Promise.resolve(t);const r=await this._fetchWellKnownObject(`${n}/_matrix/client/versions`);if(!r||!r.raw.versions)return o.logger.error("Invalid /versions response"),t["m.homeserver"].error=i.ERROR_INVALID_HOMESERVER,t["m.homeserver"].base_url=n,Promise.resolve(t);t["m.homeserver"]={state:i.SUCCESS,error:null,base_url:n};let a="";if(e["m.identity_server"]){const n={"m.homeserver":t["m.homeserver"],"m.identity_server":{state:i.FAIL_PROMPT,error:i.ERROR_INVALID_IS,base_url:null}};if(a=this._sanitizeWellKnownUrl(e["m.identity_server"].base_url),!a)return o.logger.error("Invalid base_url for m.identity_server"),n["m.identity_server"].error=i.ERROR_INVALID_IS_BASE_URL,Promise.resolve(n);const r=await this._fetchWellKnownObject(`${a}/_matrix/identity/api/v1`);if(!r||!r.raw||"SUCCESS"!==r.action)return o.logger.error("Invalid /api/v1 response"),n["m.identity_server"].error=i.ERROR_INVALID_IDENTITY_SERVER,n["m.identity_server"].base_url=a,Promise.resolve(n)}return a&&a.length>0&&(t["m.identity_server"]={state:i.SUCCESS,error:null,base_url:a}),Object.keys(e).map((n=>{if("m.homeserver"===n||"m.identity_server"===n){const o=["error","state","base_url"];for(const r of Object.keys(e[n]))o.includes(r)||(t[n][r]=e[n][r])}else t[n]=e[n]})),Promise.resolve(t)}static async findClientConfig(e){if(!e||"string"!=typeof e||0===e.length)throw new Error("'domain' must be a string of non-zero length");const t={"m.homeserver":{state:i.FAIL_ERROR,error:i.ERROR_INVALID,base_url:null},"m.identity_server":{state:i.PROMPT,error:null,base_url:null}},n=await this._fetchWellKnownObject(`https://${e}/.well-known/matrix/client`);return n&&"SUCCESS"===n.action?i.fromDiscoveryConfig(n.raw):(o.logger.error("No response or error when parsing .well-known"),n.reason&&o.logger.error(n.reason),"IGNORE"===n.action?t["m.homeserver"]={state:i.PROMPT,error:null,base_url:null}:(t["m.homeserver"].state=i.FAIL_PROMPT,t["m.homeserver"].error=i.ERROR_INVALID),Promise.resolve(t))}static async getRawClientConfig(e){if(!e||"string"!=typeof e||0===e.length)throw new Error("'domain' must be a string of non-zero length");const t=await this._fetchWellKnownObject(`https://${e}/.well-known/matrix/client`);return t&&t.raw||{}}static _sanitizeWellKnownUrl(e){if(!e)return!1;try{let t=null;try{t=r.URL?new r.URL(e):new URL(e)}catch(n){t=new URL(e)}if(!t||!t.hostname)return!1;if("http:"!==t.protocol&&"https:"!==t.protocol)return!1;const n=t.port?`:${t.port}`:"",o=t.pathname?t.pathname:"";let i=`${t.protocol}//${t.hostname}${n}${o}`;return i.endsWith("/")&&(i=i.substring(0,i.length-1)),i}catch(e){return o.logger.error(e),!1}}static async _fetchWellKnownObject(e){return new Promise((function(t,o){const r=n(48070).getRequest();if(!r)throw new Error("No request library available");r({method:"GET",uri:e,timeout:5e3},((e,n,o)=>{if(e||n&&(n.statusCode<200||n.statusCode>=300)){let o="FAIL_PROMPT",r=(e?e.message:null)||"General failure";return n&&404===n.statusCode&&(o="IGNORE",r=i.ERROR_MISSING_WELLKNOWN),void t({raw:{},action:o,reason:r,error:e})}try{t({raw:JSON.parse(o),action:"SUCCESS"})}catch(e){let n=i.ERROR_INVALID;"SyntaxError"===e.name&&(n=i.ERROR_INVALID_JSON),t({raw:{},action:"FAIL_PROMPT",reason:n,error:e})}}))}))}}t.AutoDiscovery=i},22246:(e,t,n)=>{"use strict";var o=n(20862);Object.defineProperty(t,"__esModule",{value:!0}),t.MatrixBaseApis=l;var r=n(91415),i=n(7434),a=n(31707),s=o(n(3102)),u=n(17715);function c(e,t){switch(e){case r.SERVICE_TYPES.IS:return t+u.PREFIX_IDENTITY_V2+"/terms";case r.SERVICE_TYPES.IM:return t+"/_matrix/integrations/v1/terms";default:throw new Error("Unsupported service type")}}function l(e){s.checkObjectHasKeys(e,["baseUrl","request"]),this.baseUrl=e.baseUrl,this.idBaseUrl=e.idBaseUrl,this.identityServer=e.identityServer;const t={baseUrl:e.baseUrl,idBaseUrl:e.idBaseUrl,accessToken:e.accessToken,request:e.request,prefix:u.PREFIX_R0,onlyData:!0,extraParams:e.queryParams,localTimeoutMs:e.localTimeoutMs,useAuthorizationHeader:e.useAuthorizationHeader};this._http=new u.MatrixHttpApi(this,t),this._txnCtr=0}l.prototype.getHomeserverUrl=function(){return this.baseUrl},l.prototype.getIdentityServerUrl=function(e=!1){return e&&(this.idBaseUrl.startsWith("http://")||this.idBaseUrl.startsWith("https://"))?this.idBaseUrl.split("://")[1]:this.idBaseUrl},l.prototype.setIdentityServerUrl=function(e){this.idBaseUrl=s.ensureNoTrailingSlash(e),this._http.setIdBaseUrl(this.idBaseUrl)},l.prototype.getAccessToken=function(){return this._http.opts.accessToken||null},l.prototype.isLoggedIn=function(){return void 0!==this._http.opts.accessToken},l.prototype.makeTxnId=function(){return"m"+(new Date).getTime()+"."+this._txnCtr++},l.prototype.isUsernameAvailable=function(e){return this._http.authedRequest(void 0,"GET","/register/available",{username:e}).then((e=>e.available))},l.prototype.register=function(e,t,n,o,r,i,a,s){!0===r?r={email:!0}:null==r&&(r={}),"function"==typeof a&&(s=a,a=void 0),n&&(o.session=n);const u={auth:o};return null!=e&&(u.username=e),null!=t&&(u.password=t),r.email&&(u.bind_email=!0),r.msisdn&&(u.bind_msisdn=!0),null!=i&&(u.guest_access_token=i),null!=a&&(u.inhibit_login=a),null!=t&&(u.x_show_msisdn=!0),this.registerRequest(u,void 0,s)},l.prototype.registerGuest=function(e,t){return(e=e||{}).body=e.body||{},this.registerRequest(e.body,"guest",t)},l.prototype.registerRequest=function(e,t,n){const o={};return t&&(o.kind=t),this._http.request(n,"POST","/register",o,e)},l.prototype.loginFlows=function(e){return this._http.request(e,"GET","/login")},l.prototype.login=function(e,t,n){const o={type:e};return s.extend(o,t),this._http.authedRequest(((e,t)=>{t&&t.access_token&&t.user_id&&(this._http.opts.accessToken=t.access_token,this.credentials={userId:t.user_id}),n&&n(e,t)}),"POST","/login",void 0,o)},l.prototype.loginWithPassword=function(e,t,n){return this.login("m.login.password",{user:e,password:t},n)},l.prototype.loginWithSAML2=function(e,t){return this.login("m.login.saml2",{relay_state:e},t)},l.prototype.getCasLoginUrl=function(e){return this.getSsoLoginUrl(e,"cas")},l.prototype.getSsoLoginUrl=function(e,t,n){void 0===t&&(t="sso");let o="/login/"+t+"/redirect";return n&&(o+="/"+n),this._http.getUrl(o,{redirectUrl:e},u.PREFIX_R0)},l.prototype.loginWithToken=function(e,t){return this.login("m.login.token",{token:e},t)},l.prototype.logout=function(e){return this._http.authedRequest(e,"POST","/logout")},l.prototype.deactivateAccount=function(e,t){if("function"==typeof t)throw new Error("deactivateAccount no longer accepts a callback parameter");const n={};return e&&(n.auth=e),void 0!==t&&(n.erase=t),this._http.authedRequest(void 0,"POST","/account/deactivate",void 0,n)},l.prototype.getFallbackAuthUrl=function(e,t){const n=s.encodeUri("/auth/$loginType/fallback/web",{$loginType:e});return this._http.getUrl(n,{session:t},u.PREFIX_R0)},l.prototype.createRoom=async function(e,t){const n=(e.invite_3pid||[]).filter((e=>!e.id_access_token));if(n.length>0&&this.identityServer&&this.identityServer.getAccessToken&&await this.doesServerAcceptIdentityAccessToken()){const e=await this.identityServer.getAccessToken();if(e)for(const t of n)t.id_access_token=e}return this._http.authedRequest(t,"POST","/createRoom",void 0,e)},l.prototype.fetchRelations=async function(e,t,n,o,r){const i={};r.from&&(i.from=r.from);const a=s.encodeParams(i),c=s.encodeUri("/rooms/$roomId/relations/$eventId/$relationType/$eventType?"+a,{$roomId:e,$eventId:t,$relationType:n,$eventType:o});return await this._http.authedRequest(void 0,"GET",c,null,null,{prefix:u.PREFIX_UNSTABLE})},l.prototype.roomState=function(e,t){const n=s.encodeUri("/rooms/$roomId/state",{$roomId:e});return this._http.authedRequest(t,"GET",n)},l.prototype.fetchRoomEvent=function(e,t,n){const o=s.encodeUri("/rooms/$roomId/event/$eventId",{$roomId:e,$eventId:t});return this._http.authedRequest(n,"GET",o)},l.prototype.members=function(e,t,n,o,r){const i={};t&&(i.membership=t),n&&(i.not_membership=n),o&&(i.at=o);const a=s.encodeParams(i),u=s.encodeUri("/rooms/$roomId/members?"+a,{$roomId:e});return this._http.authedRequest(r,"GET",u)},l.prototype.upgradeRoom=function(e,t){const n=s.encodeUri("/rooms/$roomId/upgrade",{$roomId:e});return this._http.authedRequest(void 0,"POST",n,void 0,{new_version:t})},l.prototype.getGroupSummary=function(e){const t=s.encodeUri("/groups/$groupId/summary",{$groupId:e});return this._http.authedRequest(void 0,"GET",t)},l.prototype.getGroupProfile=function(e){const t=s.encodeUri("/groups/$groupId/profile",{$groupId:e});return this._http.authedRequest(void 0,"GET",t)},l.prototype.setGroupProfile=function(e,t){const n=s.encodeUri("/groups/$groupId/profile",{$groupId:e});return this._http.authedRequest(void 0,"POST",n,void 0,t)},l.prototype.setGroupJoinPolicy=function(e,t){const n=s.encodeUri("/groups/$groupId/settings/m.join_policy",{$groupId:e});return this._http.authedRequest(void 0,"PUT",n,void 0,{"m.join_policy":t})},l.prototype.getGroupUsers=function(e){const t=s.encodeUri("/groups/$groupId/users",{$groupId:e});return this._http.authedRequest(void 0,"GET",t)},l.prototype.getGroupInvitedUsers=function(e){const t=s.encodeUri("/groups/$groupId/invited_users",{$groupId:e});return this._http.authedRequest(void 0,"GET",t)},l.prototype.getGroupRooms=function(e){const t=s.encodeUri("/groups/$groupId/rooms",{$groupId:e});return this._http.authedRequest(void 0,"GET",t)},l.prototype.inviteUserToGroup=function(e,t){const n=s.encodeUri("/groups/$groupId/admin/users/invite/$userId",{$groupId:e,$userId:t});return this._http.authedRequest(void 0,"PUT",n,void 0,{})},l.prototype.removeUserFromGroup=function(e,t){const n=s.encodeUri("/groups/$groupId/admin/users/remove/$userId",{$groupId:e,$userId:t});return this._http.authedRequest(void 0,"PUT",n,void 0,{})},l.prototype.addUserToGroupSummary=function(e,t,n){const o=s.encodeUri(n?"/groups/$groupId/summary/$roleId/users/$userId":"/groups/$groupId/summary/users/$userId",{$groupId:e,$roleId:n,$userId:t});return this._http.authedRequest(void 0,"PUT",o,void 0,{})},l.prototype.removeUserFromGroupSummary=function(e,t){const n=s.encodeUri("/groups/$groupId/summary/users/$userId",{$groupId:e,$userId:t});return this._http.authedRequest(void 0,"DELETE",n,void 0,{})},l.prototype.addRoomToGroupSummary=function(e,t,n){const o=s.encodeUri(n?"/groups/$groupId/summary/$categoryId/rooms/$roomId":"/groups/$groupId/summary/rooms/$roomId",{$groupId:e,$categoryId:n,$roomId:t});return this._http.authedRequest(void 0,"PUT",o,void 0,{})},l.prototype.removeRoomFromGroupSummary=function(e,t){const n=s.encodeUri("/groups/$groupId/summary/rooms/$roomId",{$groupId:e,$roomId:t});return this._http.authedRequest(void 0,"DELETE",n,void 0,{})},l.prototype.addRoomToGroup=function(e,t,n){void 0===n&&(n=!0);const o=s.encodeUri("/groups/$groupId/admin/rooms/$roomId",{$groupId:e,$roomId:t});return this._http.authedRequest(void 0,"PUT",o,void 0,{"m.visibility":{type:n?"public":"private"}})},l.prototype.updateGroupRoomVisibility=function(e,t,n){const o=s.encodeUri("/groups/$groupId/admin/rooms/$roomId/config/m.visibility",{$groupId:e,$roomId:t});return this._http.authedRequest(void 0,"PUT",o,void 0,{type:n?"public":"private"})},l.prototype.removeRoomFromGroup=function(e,t){const n=s.encodeUri("/groups/$groupId/admin/rooms/$roomId",{$groupId:e,$roomId:t});return this._http.authedRequest(void 0,"DELETE",n,void 0,{})},l.prototype.acceptGroupInvite=function(e,t=null){const n=s.encodeUri("/groups/$groupId/self/accept_invite",{$groupId:e});return this._http.authedRequest(void 0,"PUT",n,void 0,t||{})},l.prototype.joinGroup=function(e){const t=s.encodeUri("/groups/$groupId/self/join",{$groupId:e});return this._http.authedRequest(void 0,"PUT",t,void 0,{})},l.prototype.leaveGroup=function(e){const t=s.encodeUri("/groups/$groupId/self/leave",{$groupId:e});return this._http.authedRequest(void 0,"PUT",t,void 0,{})},l.prototype.getJoinedGroups=function(){const e=s.encodeUri("/joined_groups");return this._http.authedRequest(void 0,"GET",e)},l.prototype.createGroup=function(e){const t=s.encodeUri("/create_group");return this._http.authedRequest(void 0,"POST",t,void 0,e)},l.prototype.getPublicisedGroups=function(e){const t=s.encodeUri("/publicised_groups");return this._http.authedRequest(void 0,"POST",t,void 0,{user_ids:e})},l.prototype.setGroupPublicity=function(e,t){const n=s.encodeUri("/groups/$groupId/self/update_publicity",{$groupId:e});return this._http.authedRequest(void 0,"PUT",n,void 0,{publicise:t})},l.prototype.getStateEvent=function(e,t,n,o){const r={$roomId:e,$eventType:t,$stateKey:n};let i=s.encodeUri("/rooms/$roomId/state/$eventType",r);return void 0!==n&&(i=s.encodeUri(i+"/$stateKey",r)),this._http.authedRequest(o,"GET",i)},l.prototype.sendStateEvent=function(e,t,n,o,r){const i={$roomId:e,$eventType:t,$stateKey:o};let a=s.encodeUri("/rooms/$roomId/state/$eventType",i);return void 0!==o&&(a=s.encodeUri(a+"/$stateKey",i)),this._http.authedRequest(r,"PUT",a,void 0,n)},l.prototype.roomInitialSync=function(e,t,n){s.isFunction(t)&&(n=t,t=void 0);const o=s.encodeUri("/rooms/$roomId/initialSync",{$roomId:e});return t||(t=30),this._http.authedRequest(n,"GET",o,{limit:t})},l.prototype.setRoomReadMarkersHttpRequest=function(e,t,n,o){const r=s.encodeUri("/rooms/$roomId/read_markers",{$roomId:e}),i={"m.fully_read":t,"m.read":n,"m.hidden":Boolean(!!o&&o.hidden)};return this._http.authedRequest(void 0,"POST",r,void 0,i)},l.prototype.getJoinedRooms=function(){const e=s.encodeUri("/joined_rooms");return this._http.authedRequest(void 0,"GET",e)},l.prototype.getJoinedRoomMembers=function(e){const t=s.encodeUri("/rooms/$roomId/joined_members",{$roomId:e});return this._http.authedRequest(void 0,"GET",t)},l.prototype.publicRooms=function(e,t){"function"==typeof e&&(t=e,e={}),void 0===e&&(e={});const n={};return e.server&&(n.server=e.server,delete e.server),0===Object.keys(e).length&&0===Object.keys(n).length?this._http.authedRequest(t,"GET","/publicRooms"):this._http.authedRequest(t,"POST","/publicRooms",n,e)},l.prototype.createAlias=function(e,t,n){const o=s.encodeUri("/directory/room/$alias",{$alias:e}),r={room_id:t};return this._http.authedRequest(n,"PUT",o,void 0,r)},l.prototype.deleteAlias=function(e,t){const n=s.encodeUri("/directory/room/$alias",{$alias:e});return this._http.authedRequest(t,"DELETE",n,void 0,void 0)},l.prototype.unstableGetLocalAliases=function(e,t){const n=s.encodeUri("/rooms/$roomId/aliases",{$roomId:e}),o=u.PREFIX_UNSTABLE+"/org.matrix.msc2432";return this._http.authedRequest(t,"GET",n,null,null,{prefix:o})},l.prototype.getRoomIdForAlias=function(e,t){const n=s.encodeUri("/directory/room/$alias",{$alias:e});return this._http.authedRequest(t,"GET",n)},l.prototype.resolveRoomAlias=function(e,t){const n=s.encodeUri("/directory/room/$alias",{$alias:e});return this._http.request(t,"GET",n)},l.prototype.getRoomDirectoryVisibility=function(e,t){const n=s.encodeUri("/directory/list/room/$roomId",{$roomId:e});return this._http.authedRequest(t,"GET",n)},l.prototype.setRoomDirectoryVisibility=function(e,t,n){const o=s.encodeUri("/directory/list/room/$roomId",{$roomId:e});return this._http.authedRequest(n,"PUT",o,void 0,{visibility:t})},l.prototype.setRoomDirectoryVisibilityAppService=function(e,t,n,o){const r=s.encodeUri("/directory/list/appservice/$networkId/$roomId",{$networkId:e,$roomId:t});return this._http.authedRequest(o,"PUT",r,void 0,{visibility:n})},l.prototype.searchUserDirectory=function(e){const t={search_term:e.term};return void 0!==e.limit&&(t.limit=e.limit),this._http.authedRequest(void 0,"POST","/user_directory/search",void 0,t)},l.prototype.uploadContent=function(e,t){return this._http.uploadContent(e,t)},l.prototype.cancelUpload=function(e){return this._http.cancelUpload(e)},l.prototype.getCurrentUploads=function(){return this._http.getCurrentUploads()},l.prototype.getProfileInfo=function(e,t,n){s.isFunction(t)&&(n=t,t=void 0);const o=t?s.encodeUri("/profile/$userId/$info",{$userId:e,$info:t}):s.encodeUri("/profile/$userId",{$userId:e});return this._http.authedRequest(n,"GET",o)},l.prototype.getThreePids=function(e){return this._http.authedRequest(e,"GET","/account/3pid",void 0,void 0)},l.prototype.addThreePid=function(e,t,n){const o={threePidCreds:e,bind:t};return this._http.authedRequest(n,"POST","/account/3pid",null,o)},l.prototype.addThreePidOnly=async function(e){const t=await this.isVersionSupported("r0.6.0")?u.PREFIX_R0:u.PREFIX_UNSTABLE;return this._http.authedRequest(void 0,"POST","/account/3pid/add",null,e,{prefix:t})},l.prototype.bindThreePid=async function(e){const t=await this.isVersionSupported("r0.6.0")?u.PREFIX_R0:u.PREFIX_UNSTABLE;return this._http.authedRequest(void 0,"POST","/account/3pid/bind",null,e,{prefix:t})},l.prototype.unbindThreePid=async function(e,t){const n={medium:e,address:t,id_server:this.getIdentityServerUrl(!0)},o=await this.isVersionSupported("r0.6.0")?u.PREFIX_R0:u.PREFIX_UNSTABLE;return this._http.authedRequest(void 0,"POST","/account/3pid/unbind",null,n,{prefix:o})},l.prototype.deleteThreePid=function(e,t){const n={medium:e,address:t};return this._http.authedRequest(void 0,"POST","/account/3pid/delete",null,n)},l.prototype.setPassword=function(e,t,n){const o={auth:e,new_password:t};return this._http.authedRequest(n,"POST","/account/password",null,o)},l.prototype.getDevices=function(){return this._http.authedRequest(void 0,"GET","/devices",void 0,void 0)},l.prototype.getDevice=function(e){const t=s.encodeUri("/devices/$device_id",{$device_id:e});return this._http.authedRequest(void 0,"GET",t,void 0,void 0)},l.prototype.setDeviceDetails=function(e,t){const n=s.encodeUri("/devices/$device_id",{$device_id:e});return this._http.authedRequest(void 0,"PUT",n,void 0,t)},l.prototype.deleteDevice=function(e,t){const n=s.encodeUri("/devices/$device_id",{$device_id:e}),o={};return t&&(o.auth=t),this._http.authedRequest(void 0,"DELETE",n,void 0,o)},l.prototype.deleteMultipleDevices=function(e,t){const n={devices:e};return t&&(n.auth=t),this._http.authedRequest(void 0,"POST","/delete_devices",void 0,n)},l.prototype.getPushers=function(e){return this._http.authedRequest(e,"GET","/pushers",void 0,void 0)},l.prototype.setPusher=function(e,t){return this._http.authedRequest(t,"POST","/pushers/set",null,e)},l.prototype.getPushRules=function(e){return this._http.authedRequest(e,"GET","/pushrules/").then((e=>a.PushProcessor.rewriteDefaultRules(e)))},l.prototype.addPushRule=function(e,t,n,o,r){const i=s.encodeUri("/pushrules/"+e+"/$kind/$ruleId",{$kind:t,$ruleId:n});return this._http.authedRequest(r,"PUT",i,void 0,o)},l.prototype.deletePushRule=function(e,t,n,o){const r=s.encodeUri("/pushrules/"+e+"/$kind/$ruleId",{$kind:t,$ruleId:n});return this._http.authedRequest(o,"DELETE",r)},l.prototype.setPushRuleEnabled=function(e,t,n,o,r){const i=s.encodeUri("/pushrules/"+e+"/$kind/$ruleId/enabled",{$kind:t,$ruleId:n});return this._http.authedRequest(r,"PUT",i,void 0,{enabled:o})},l.prototype.setPushRuleActions=function(e,t,n,o,r){const i=s.encodeUri("/pushrules/"+e+"/$kind/$ruleId/actions",{$kind:t,$ruleId:n});return this._http.authedRequest(r,"PUT",i,void 0,{actions:o})},l.prototype.search=function(e,t){const n={};return e.next_batch&&(n.next_batch=e.next_batch),this._http.authedRequest(t,"POST","/search",n,e.body)},l.prototype.uploadKeysRequest=function(e,t,n){return this._http.authedRequest(n,"POST","/keys/upload",void 0,e)},l.prototype.uploadKeySignatures=function(e){return this._http.authedRequest(void 0,"POST","/keys/signatures/upload",void 0,e,{prefix:u.PREFIX_UNSTABLE})},l.prototype.downloadKeysForUsers=function(e,t){if(s.isFunction(t))throw new Error("downloadKeysForUsers no longer accepts a callback parameter");const n={device_keys:{}};return"token"in(t=t||{})&&(n.token=t.token),e.forEach((e=>{n.device_keys[e]=[]})),this._http.authedRequest(void 0,"POST","/keys/query",void 0,n)},l.prototype.claimOneTimeKeys=function(e,t,n){const o={};void 0===t&&(t="signed_curve25519");for(let n=0;n{const n=e[0].toLowerCase(),r=e[1].toLowerCase(),a=t.sha256(`${n} ${r} ${o.pepper}`).replace(/\+/g,"-").replace(/\//g,"_");return i[a]=e[0],a})),o.algorithm="sha256"}else{if(!r.algorithms.includes("none"))throw new Error("Unsupported identity server: unknown hash algorithm");o.addresses=e.map((e=>{const t=`${e[0].toLowerCase()} ${e[1].toLowerCase()}`;return i[t]=e[0],t})),o.algorithm="none"}const a=await this._http.idServerRequest(void 0,"POST","/lookup",o,u.PREFIX_IDENTITY_V2,t);if(!a||!a.mappings)return[];const s=[];for(const e of Object.keys(a.mappings)){const t=a.mappings[e],n=i[e];if(!n)throw new Error("Identity server returned more results than expected");s.push({address:n,mxid:t})}return s},l.prototype.lookupThreePid=async function(e,t,n,o){const r=(await this.identityHashedLookup([[t,e]],o)).find((e=>e.address===t));if(!r)return n&&n(null,{}),{};const i={address:t,medium:e,mxid:r.mxid};return n&&n(null,i),i},l.prototype.bulkLookupThreePids=async function(e,t){const n=await this.identityHashedLookup(e.map((e=>[e[1],e[0]])),t),o=[];for(const t of n){const n=e.find((e=>e[1]===t.address));if(!n)throw new Error("Identity sever returned unexpected results");o.push([n[0],t.address,t.mxid])}return{threepids:o}},l.prototype.getIdentityAccount=function(e){return this._http.idServerRequest(void 0,"GET","/account",void 0,u.PREFIX_IDENTITY_V2,e)},l.prototype.sendToDevice=function(e,t,n){const o=s.encodeUri("/sendToDevice/$eventType/$txnId",{$eventType:e,$txnId:n||this.makeTxnId()}),r={messages:t},a=Object.keys(t).reduce(((e,n)=>(e[n]=Object.keys(t[n]),e)),{});return i.logger.log(`PUT ${o}`,a),this._http.authedRequest(void 0,"PUT",o,void 0,r)},l.prototype.getThirdpartyProtocols=function(){return this._http.authedRequest(void 0,"GET","/thirdparty/protocols",void 0,void 0).then((e=>{if(!e||"object"!=typeof e)throw new Error(`/thirdparty/protocols did not return an object: ${e}`);return e}))},l.prototype.getThirdpartyLocation=function(e,t){const n=s.encodeUri("/thirdparty/location/$protocol",{$protocol:e});return this._http.authedRequest(void 0,"GET",n,t,void 0)},l.prototype.getThirdpartyUser=function(e,t){const n=s.encodeUri("/thirdparty/user/$protocol",{$protocol:e});return this._http.authedRequest(void 0,"GET",n,t,void 0)},l.prototype.getTerms=function(e,t){const n=c(e,t);return this._http.requestOtherUrl(void 0,"GET",n)},l.prototype.agreeToTerms=function(e,t,n,o){const r=c(e,t),i={Authorization:"Bearer "+n};return this._http.requestOtherUrl(void 0,"POST",r,null,{user_accepts:o},{headers:i})},l.prototype.reportEvent=function(e,t,n,o){const r=s.encodeUri("/rooms/$roomId/report/$eventId",{$roomId:e,$eventId:t});return this._http.authedRequest(void 0,"POST",r,null,{score:n,reason:o})},l.prototype.getSpaceSummary=function(e,t,n,o,r,i){const a=s.encodeUri("/rooms/$roomId/spaces",{$roomId:e});return this._http.authedRequest(void 0,"POST",a,null,{max_rooms_per_space:t,suggested_only:n,auto_join_only:o,limit:r,batch:i},{prefix:"/_matrix/client/unstable/org.matrix.msc2946"})}},8743:(e,t,n)=>{"use strict";var o=n(95318),r=n(20862);Object.defineProperty(t,"__esModule",{value:!0});var i={};t.default=void 0;var a=r(n(48070));Object.keys(a).forEach((function(e){"default"!==e&&"__esModule"!==e&&(Object.prototype.hasOwnProperty.call(i,e)||e in t&&t[e]===a[e]||Object.defineProperty(t,e,{enumerable:!0,get:function(){return a[e]}}))}));var s=o(n(24770)),u=o(n(80129));let c;a.request((function(e,t){return e.qs=u.default.stringify(e.qs||{},e.qsStringifyOptions),(0,s.default)(e,t)}));try{c=n.g.indexedDB}catch(e){}c&&a.setCryptoStoreFactory((function(){return new a.IndexedDBCryptoStore(c,"matrix-js-sdk:crypto")}));var l=a;t.default=l,n.g.matrixcs=a},62168:(e,t,n)=>{"use strict";var o=n(20862),r=n(95318);Object.defineProperty(t,"__esModule",{value:!0}),t.MatrixClient=N,t.CRYPTO_ENABLED=void 0;var i=r(n(8575)),a=n(17187),s=n(22246),u=n(27906),c=n(64551),l=n(24369),d=n(88910),h=n(41398),p=n(25641),f=n(59679),g=n(62931),m=o(n(3102)),_=n(17715),F=n(73667),y=o(n(44656)),b=o(n(32772)),v=n(20771),w=n(40635),E=n(7434),k=n(12600),D=n(34077),S=n(91597),x=n(98401),C=n(31707),A=n(83998),T=n(79118),R=n(54830);const I=(0,k.isCryptoAvailable)();t.CRYPTO_ENABLED=I;const M=6e5;function O(e,t,n){const o=[];for(const[r,i]of Object.entries(e))try{const e=B(i,t);e.session_id=r,e.room_id=n,o.push(e)}catch(e){E.logger.log("Failed to decrypt megolm session from backup",e)}return o}function B(e,t){return JSON.parse(t.decrypt(e.session_data.ephemeral,e.session_data.mac,e.session_data.ciphertext))}function N(e){e.baseUrl=m.ensureNoTrailingSlash(e.baseUrl),e.idBaseUrl=m.ensureNoTrailingSlash(e.idBaseUrl),s.MatrixBaseApis.call(this,e),this.olmVersion=null,this.reEmitter=new v.ReEmitter(this),this.usingExternalCrypto=e.usingExternalCrypto,this.store=e.store||new p.StubStore,this.deviceId=e.deviceId||null;const t=e.userId||null;if(this.credentials={userId:t},e.deviceToImport?this.deviceId?E.logger.warn("not importing device because device ID is provided to constructor independently of exported data"):this.credentials.userId?E.logger.warn("not importing device because user ID is provided to constructor independently of exported data"):e.deviceToImport.deviceId?(this.deviceId=e.deviceToImport.deviceId,this.credentials.userId=e.deviceToImport.userId,this._exportedOlmDeviceToImport=e.deviceToImport.olmDevice):E.logger.warn("not importing device because no device ID in exported data"):e.pickleKey&&(this.pickleKey=e.pickleKey),this.scheduler=e.scheduler,this.scheduler){const e=this;this.scheduler.setProcessFunction((async function(t){const n=e.getRoom(t.getRoomId());t.status!==l.EventStatus.SENDING&&j(n,t,l.EventStatus.SENDING);const o=await q(e,t);return n&&n.updatePendingEvent(t,l.EventStatus.SENT,o.event_id),o}))}this.clientRunning=!1;const n=(0,f.createNewMatrixCall)(this);this._supportsVoip=!1,n?(this._callEventHandler=new g.CallEventHandler(this),this._supportsVoip=!0,this.on("sync",this._startCallEventHandler)):this._callEventHandler=null,this._syncingRetry=null,this._syncApi=null,this._peekSync=null,this._isGuest=!1,this._ongoingScrollbacks={},this.timelineSupport=Boolean(e.timelineSupport),this.urlPreviewCache={},this._notifTimelineSet=null,this.unstableClientRelationAggregation=!!e.unstableClientRelationAggregation,this._crypto=null,this._cryptoStore=e.cryptoStore,this._sessionStore=e.sessionStore,this._verificationMethods=e.verificationMethods,this._cryptoCallbacks=e.cryptoCallbacks||{},this._forceTURN=e.forceTURN||!1,this._iceCandidatePoolSize=void 0===e.iceCandidatePoolSize?0:e.iceCandidatePoolSize,this._supportsCallTransfer=e.supportsCallTransfer||!1,this._fallbackICEServerAllowed=e.fallbackICEServerAllowed||!1,this._roomList=new w.RoomList(this._cryptoStore),this._pushProcessor=new C.PushProcessor(this),this._serverVersionsPromise=null,this._cachedCapabilities=null,this._clientWellKnown=void 0,this._clientWellKnownPromise=void 0,this._turnServers=[],this._turnServersExpiry=0,this._checkTurnServersIntervalID=null,this.on("Event.decrypted",(e=>{const t=e.getPushActions(),n=this._pushProcessor.actionsForEvent(e);e.setPushActions(n);const o=this.getRoom(e.getRoomId());if(!o)return;const r=o.getUnreadNotificationCount("highlight"),i=!(!t||!t.tweaks||!t.tweaks.highlight),a=!(!n||!n.tweaks||!n.tweaks.highlight);if((i!==a||r>0)&&!o.hasUserReadEvent(this.getUserId(),e.getId())){let e=r;a&&!i&&e++,!a&&i&&e--,o.setUnreadNotificationCount("highlight",e),o.getUnreadNotificationCount("total"){if(t&&this.isRoomEncrypted(t.roomId)){const n=e.getContent();if(!(Object.keys(n).filter((e=>Object.keys(n[e]["m.read"]).includes(this.getUserId()))).length>0))return;const o=20,r=t.getLiveTimeline().getEvents();let i=0;for(let e=r.length-1;e>=0;e--){if(e===r.length-o)return;const n=r[e];if(t.hasUserReadEvent(this.getUserId(),n.getId()))break;const a=this.getPushActionsForEvent(n);i+=a.tweaks&&a.tweaks.highlight?1:0}t.setUnreadNotificationCount("highlight",i)}}))}async function L(e,t,n,o,r,i){if(!e._crypto)throw new Error("End-to-End encryption disabled");await e._crypto.setDeviceVerification(t,n,o,r,i)}function P(e,t){for(const n of t)e.prototype[n]=function(...e){if(!this._crypto)throw new Error("End-to-end encryption disabled");return this._crypto[n](...e)}}function U(e,t,n,o){return Promise.resolve().then((function(){const o=function(e,t,n){if(t.isEncrypted())return null;if(!e.isRoomEncrypted(t.getRoomId()))return null;if(!e._crypto&&e.usingExternalCrypto)return null;if("m.reaction"===t.getType())return null;if(!e._crypto)throw new Error("This room is configured to use encryption, but your client does not support encryption.");return e._crypto.encryptEvent(t,n)}(e,n,t);return o?(j(t,n,l.EventStatus.ENCRYPTING),o.then((()=>{j(t,n,l.EventStatus.SENDING)}))):null})).then((function(){let o;return e.scheduler&&(o=e.scheduler.queueEvent(n),o&&e.scheduler.getQueueForEvent(n).length>1&&j(t,n,l.EventStatus.QUEUED)),o||(o=q(e,n),t&&(o=o.then((e=>(t.updatePendingEvent(n,l.EventStatus.SENT,e.event_id),e))))),o})).then((function(e){return o&&o(null,e),e}),(function(e){E.logger.error("Error sending event",e.stack||e);try{n.error=e,j(t,n,l.EventStatus.NOT_SENT),e.event=n,o&&o(e)}catch(t){E.logger.error("Exception in error handler!",t.stack||e)}throw e}))}function j(e,t,n){e?e.updatePendingEvent(t,n):t.setStatus(n)}function q(e,t){let n=t.getTxnId();n||(n=e.makeTxnId(),t.setTxnId(n));const o={$roomId:t.getRoomId(),$eventType:t.getWireType(),$stateKey:t.getStateKey(),$txnId:n};let r;if(t.isState()){let e="/rooms/$roomId/state/$eventType";t.getStateKey()&&t.getStateKey().length>0&&(e="/rooms/$roomId/state/$eventType/$stateKey"),r=m.encodeUri(e,o)}else if(t.isRedaction()){const e="/rooms/$roomId/redact/$redactsEventId/$txnId";r=m.encodeUri(e,Object.assign({$redactsEventId:t.event.redacts},o))}else r=m.encodeUri("/rooms/$roomId/send/$eventType/$txnId",o);return e._http.authedRequest(void 0,"PUT",r,void 0,t.getWireContent()).then((e=>(E.logger.log(`Event sent to ${t.getRoomId()} with event id ${e.event_id}`),e)))}function z(e,t,n,o,r,i){m.isFunction(r)&&(i=r,r=void 0);const a=m.encodeUri("/rooms/$room_id/$membership",{$room_id:t,$membership:o});return e._http.authedRequest(i,"POST",a,void 0,{user_id:n,reason:r})}function K(e,t,n){e&&e(n),t(n)}function G(e,t,n){e&&e(null,n),t(n)}function $(e,t={}){const n=Boolean(t.preventReEmit),o=!1!==t.decrypt;return function(t){const r=new l.MatrixEvent(t);return r.isEncrypted()&&(n||e.reEmitter.reEmit(r,["Event.decrypted"]),o&&e.decryptEventIfNeeded(r)),n||e.reEmitter.reEmit(r,["Event.replaced"]),r}}m.inherits(N,a.EventEmitter),m.extend(N.prototype,s.MatrixBaseApis.prototype),N.prototype.rehydrateDevice=async function(){if(this._crypto)throw new Error("Cannot rehydrate device after crypto is initialized");if(!this._cryptoCallbacks.getDehydrationKey)return;const e=await this.getDehydratedDevice();if(!e)return;if(!e.device_data||!e.device_id)return void E.logger.info("no dehydrated device found");const t=new n.g.Olm.Account;try{const n=e.device_data;if(n.algorithm!==R.DEHYDRATION_ALGORITHM)return void E.logger.warn("Wrong algorithm for dehydrated device");E.logger.log("unpickling dehydrated device");const o=await this._cryptoCallbacks.getDehydrationKey(n,(e=>{t.unpickle(new Uint8Array(e),n.account)}));if(t.unpickle(o,n.account),E.logger.log("unpickled device"),!0===(await this._http.authedRequest(void 0,"POST","/dehydrated_device/claim",void 0,{device_id:e.device_id},{prefix:"/_matrix/client/unstable/org.matrix.msc2697.v2"})).success){this.deviceId=e.device_id,E.logger.info("using dehydrated device");const n=this.pickleKey||"DEFAULT_KEY";return this._exportedOlmDeviceToImport={pickledAccount:t.pickle(n),sessions:[],pickleKey:n},t.free(),this.deviceId}return t.free(),void E.logger.info("not using dehydrated device")}catch(e){t.free(),E.logger.warn("could not unpickle",e)}},N.prototype.getDehydratedDevice=async function(){try{return await this._http.authedRequest(void 0,"GET","/dehydrated_device",void 0,void 0,{prefix:"/_matrix/client/unstable/org.matrix.msc2697.v2"})}catch(e){return void E.logger.info("could not get dehydrated device",e.toString())}},N.prototype.setDehydrationKey=async function(e,t={},n){if(this._crypto)return await this._crypto._dehydrationManager.setKeyAndQueueDehydration(e,t,n);E.logger.warn("not dehydrating device if crypto is not enabled")},N.prototype.createDehydratedDevice=async function(e,t={},n){if(this._crypto)return await this._crypto._dehydrationManager.setKey(e,t,n),await this._crypto._dehydrationManager.dehydrateDevice();E.logger.warn("not dehydrating device if crypto is not enabled")},N.prototype.exportDevice=async function(){if(this._crypto)return{userId:this.credentials.userId,deviceId:this.deviceId,olmDevice:await this._crypto._olmDevice.export()};E.logger.warn("not exporting device if crypto is not enabled")},N.prototype.clearStores=function(){if(this._clientRunning)throw new Error("Cannot clear stores while client is running");const e=[];return e.push(this.store.deleteAllData()),this._cryptoStore&&e.push(this._cryptoStore.deleteAllData()),Promise.all(e)},N.prototype.getUserId=function(){return this.credentials&&this.credentials.userId?this.credentials.userId:null},N.prototype.getDomain=function(){return this.credentials&&this.credentials.userId?this.credentials.userId.replace(/^.*?:/,""):null},N.prototype.getUserIdLocalpart=function(){return this.credentials&&this.credentials.userId?this.credentials.userId.split(":")[0].substring(1):null},N.prototype.getDeviceId=function(){return this.deviceId},N.prototype.supportsVoip=function(){return this._supportsVoip},N.prototype.setForceTURN=function(e){this._forceTURN=e},N.prototype.setSupportsCallTransfer=function(e){this._supportsCallTransfer=e},N.prototype.createCall=function(e){return(0,f.createNewMatrixCall)(this,e)},N.prototype.getSyncState=function(){return this._syncApi?this._syncApi.getSyncState():null},N.prototype.getSyncStateData=function(){return this._syncApi?this._syncApi.getSyncStateData():null},N.prototype.isInitialSyncComplete=function(){const e=this.getSyncState();return!!e&&("PREPARED"===e||"SYNCING"===e)},N.prototype.isGuest=function(){return this._isGuest},N.prototype.getScheduler=function(){return this.scheduler},N.prototype.setGuest=function(e){this._isGuest=e},N.prototype.retryImmediately=function(){return this._syncApi.retryImmediately()},N.prototype.getNotifTimelineSet=function(){return this._notifTimelineSet},N.prototype.setNotifTimelineSet=function(e){this._notifTimelineSet=e},N.prototype.getCapabilities=function(e=!1){const t=(new Date).getTime();return this._cachedCapabilities&&!e&&t(E.logger.error(e),null))).then((e=>{e||(e={});const n=e.capabilities||{},o=Object.keys(n).length?216e5:6e4+5e3*Math.random();return this._cachedCapabilities={capabilities:n,expiration:t+o},E.logger.log("Caching capabilities: ",n),n}))},N.prototype.initCrypto=async function(){if(!(0,k.isCryptoAvailable)())throw new Error("End-to-end encryption not supported in this js-sdk build: did you remember to load the olm library?");if(this._crypto)return void E.logger.warn("Attempt to re-initialise e2e encryption on MatrixClient");if(!this._sessionStore)throw new Error("Cannot enable encryption: no sessionStore provided");if(!this._cryptoStore)throw new Error("Cannot enable encryption: no cryptoStore provided");E.logger.log("Crypto: Starting up crypto store..."),await this._cryptoStore.startup(),E.logger.log("Crypto: initialising roomlist..."),await this._roomList.init();const e=this.getUserId();if(null===e)throw new Error("Cannot enable encryption on MatrixClient with unknown userId: ensure userId is passed in createClient().");if(null===this.deviceId)throw new Error("Cannot enable encryption on MatrixClient with unknown deviceId: ensure deviceId is passed in createClient().");const t=new k.Crypto(this,this._sessionStore,e,this.deviceId,this.store,this._cryptoStore,this._roomList,this._verificationMethods);this.reEmitter.reEmit(t,["crypto.keyBackupFailed","crypto.keyBackupSessionsRemaining","crypto.roomKeyRequest","crypto.roomKeyRequestCancellation","crypto.warning","crypto.devicesUpdated","crypto.willUpdateDevices","deviceVerificationChanged","userTrustStatusChanged","crossSigning.keysChanged"]),E.logger.log("Crypto: initialising crypto object..."),await t.init({exportedOlmDevice:this._exportedOlmDeviceToImport,pickleKey:this.pickleKey}),delete this._exportedOlmDeviceToImport,this.olmVersion=k.Crypto.getOlmVersion(),t.registerEventHandlers(this),this._crypto=t},N.prototype.isCryptoEnabled=function(){return null!==this._crypto},N.prototype.getDeviceEd25519Key=function(){return this._crypto?this._crypto.getDeviceEd25519Key():null},N.prototype.getDeviceCurve25519Key=function(){return this._crypto?this._crypto.getDeviceCurve25519Key():null},N.prototype.uploadKeys=function(){if(null===this._crypto)throw new Error("End-to-end encryption disabled");return this._crypto.uploadDeviceKeys()},N.prototype.downloadKeys=function(e,t){return null===this._crypto?Promise.reject(new Error("End-to-end encryption disabled")):this._crypto.downloadKeys(e,t)},N.prototype.getStoredDevicesForUser=function(e){if(null===this._crypto)throw new Error("End-to-end encryption disabled");return this._crypto.getStoredDevicesForUser(e)||[]},N.prototype.getStoredDevice=function(e,t){if(null===this._crypto)throw new Error("End-to-end encryption disabled");return this._crypto.getStoredDevice(e,t)||null},N.prototype.setDeviceVerified=function(e,t,n){void 0===n&&(n=!0);const o=L(this,e,t,n,null);return e==this.credentials.userId&&this._crypto.checkKeyBackup(),o},N.prototype.setDeviceBlocked=function(e,t,n){return void 0===n&&(n=!0),L(this,e,t,null,n)},N.prototype.setDeviceKnown=function(e,t,n){return void 0===n&&(n=!0),L(this,e,t,null,null,n)},N.prototype.requestVerificationDM=function(e,t){if(null===this._crypto)throw new Error("End-to-end encryption disabled");return this._crypto.requestVerificationDM(e,t)},N.prototype.findVerificationRequestDMInProgress=function(e){if(null===this._crypto)throw new Error("End-to-end encryption disabled");return this._crypto.findVerificationRequestDMInProgress(e)},N.prototype.getVerificationRequestsToDeviceInProgress=function(e){if(null===this._crypto)throw new Error("End-to-end encryption disabled");return this._crypto.getVerificationRequestsToDeviceInProgress(e)},N.prototype.requestVerification=function(e,t){if(null===this._crypto)throw new Error("End-to-end encryption disabled");return this._crypto.requestVerification(e,t)},N.prototype.beginKeyVerification=function(e,t,n){if(null===this._crypto)throw new Error("End-to-end encryption disabled");return this._crypto.beginKeyVerification(e,t,n)},N.prototype.setGlobalBlacklistUnverifiedDevices=function(e){if(null===this._crypto)throw new Error("End-to-end encryption disabled");this._crypto.setGlobalBlacklistUnverifiedDevices(e)},N.prototype.getGlobalBlacklistUnverifiedDevices=function(){if(null===this._crypto)throw new Error("End-to-end encryption disabled");return this._crypto.getGlobalBlacklistUnverifiedDevices()},N.prototype.setGlobalErrorOnUnknownDevices=function(e){if(null===this._crypto)throw new Error("End-to-end encryption disabled");this._crypto.setGlobalErrorOnUnknownDevices(e)},N.prototype.getGlobalErrorOnUnknownDevices=function(){if(null===this._crypto)throw new Error("End-to-end encryption disabled");return this._crypto.getGlobalErrorOnUnknownDevices()},P(N,["getCrossSigningId","getStoredCrossSigningForUser","checkUserTrust","checkDeviceTrust","checkOwnCrossSigningTrust","checkCrossSigningPrivateKey","legacyDeviceVerification","prepareToEncrypt","isCrossSigningReady","bootstrapCrossSigning","getCryptoTrustCrossSignedDevices","setCryptoTrustCrossSignedDevices","countSessionsNeedingBackup"]),P(N,["getEventEncryptionInfo","createRecoveryKeyFromPassphrase","isSecretStorageReady","bootstrapSecretStorage","addSecretStorageKey","hasSecretStorageKey","storeSecret","getSecret","isSecretStored","requestSecret","getDefaultSecretStorageKeyId","setDefaultSecretStorageKeyId","checkSecretStorageKey","checkSecretStoragePrivateKey"]),N.prototype.getEventSenderDeviceInfo=async function(e){return this._crypto?this._crypto.getEventSenderDeviceInfo(e):null},N.prototype.isEventSenderVerified=async function(e){const t=await this.getEventSenderDeviceInfo(e);return!!t&&t.isVerified()},N.prototype.cancelAndResendEventRoomKeyRequest=function(e){return e.cancelAndResendKeyRequest(this._crypto,this.getUserId())},N.prototype.setRoomEncryption=function(e,t){if(!this._crypto)throw new Error("End-to-End encryption disabled");return this._crypto.setRoomEncryption(e,t)},N.prototype.isRoomEncrypted=function(e){const t=this.getRoom(e);return!!t&&(!!t.currentState.getStateEvents("m.room.encryption","")||this._roomList.isRoomEncrypted(e))},N.prototype.forceDiscardSession=function(e){if(!this._crypto)throw new Error("End-to-End encryption disabled");this._crypto.forceDiscardSession(e)},N.prototype.exportRoomKeys=function(){return this._crypto?this._crypto.exportRoomKeys():Promise.reject(new Error("End-to-end encryption disabled"))},N.prototype.importRoomKeys=function(e,t){if(!this._crypto)throw new Error("End-to-end encryption disabled");return this._crypto.importRoomKeys(e,t)},N.prototype.checkKeyBackup=function(){return this._crypto.checkKeyBackup()},N.prototype.getKeyBackupVersion=function(){return this._http.authedRequest(void 0,"GET","/room_keys/version",void 0,void 0,{prefix:_.PREFIX_UNSTABLE}).then((e=>{if(e.algorithm!==b.MEGOLM_BACKUP_ALGORITHM){const t="Unknown backup algorithm: "+e.algorithm;return Promise.reject(t)}if("object"==typeof e.auth_data&&e.auth_data.public_key)return e;{const e="Invalid backup data returned";return Promise.reject(e)}})).catch((e=>{if("M_NOT_FOUND"===e.errcode)return null;throw e}))},N.prototype.isKeyBackupTrusted=function(e){return this._crypto.isKeyBackupTrusted(e)},N.prototype.getKeyBackupEnabled=function(){if(null===this._crypto)throw new Error("End-to-end encryption disabled");return this._crypto._checkedForBackup?Boolean(this._crypto.backupKey):null},N.prototype.enableKeyBackup=function(e){if(null===this._crypto)throw new Error("End-to-end encryption disabled");this._crypto.backupInfo=e,this._crypto.backupKey&&this._crypto.backupKey.free(),this._crypto.backupKey=new n.g.Olm.PkEncryption,this._crypto.backupKey.set_recipient_key(e.auth_data.public_key),this.emit("crypto.keyBackupStatus",!0),this._crypto.scheduleKeyBackupSend()},N.prototype.disableKeyBackup=function(){if(null===this._crypto)throw new Error("End-to-end encryption disabled");this._crypto.backupInfo=null,this._crypto.backupKey&&this._crypto.backupKey.free(),this._crypto.backupKey=null,this.emit("crypto.keyBackupStatus",!1)},N.prototype.prepareKeyBackupVersion=async function(e,{secureSecretStorage:t=!1}={}){if(null===this._crypto)throw new Error("End-to-end encryption disabled");const{keyInfo:n,encodedPrivateKey:o,privateKey:r}=await this.createRecoveryKeyFromPassphrase(e);t&&(await this.storeSecret("m.megolm_backup.v1",(0,b.encodeBase64)(r)),E.logger.info("Key backup private key stored in secret storage"));const i={public_key:n.pubkey};return n.passphrase&&(i.private_key_salt=n.passphrase.salt,i.private_key_iterations=n.passphrase.iterations),{algorithm:b.MEGOLM_BACKUP_ALGORITHM,auth_data:i,recovery_key:o}},N.prototype.isKeyBackupKeyStored=async function(){return this.isSecretStored("m.megolm_backup.v1",!1)},N.prototype.createKeyBackupVersion=async function(e){if(null===this._crypto)throw new Error("End-to-end encryption disabled");const t={algorithm:e.algorithm,auth_data:e.auth_data};await this._crypto._signObject(t.auth_data),this._cryptoCallbacks.getCrossSigningKey&&this._crypto._crossSigningInfo.getId()&&await this._crypto._crossSigningInfo.signObject(t.auth_data,"master");const n=await this._http.authedRequest(void 0,"POST","/room_keys/version",void 0,t,{prefix:_.PREFIX_UNSTABLE});return await this.checkKeyBackup(),this.getKeyBackupEnabled()||E.logger.error("Key backup not usable even though we just created it"),n},N.prototype.deleteKeyBackupVersion=function(e){if(null===this._crypto)throw new Error("End-to-end encryption disabled");this._crypto.backupInfo&&this._crypto.backupInfo.version===e&&this.disableKeyBackup();const t=m.encodeUri("/room_keys/version/$version",{$version:e});return this._http.authedRequest(void 0,"DELETE",t,void 0,void 0,{prefix:_.PREFIX_UNSTABLE})},N.prototype._makeKeyBackupPath=function(e,t,n){let o;return o=void 0!==t?m.encodeUri("/room_keys/keys/$roomId/$sessionId",{$roomId:e,$sessionId:t}):void 0!==e?m.encodeUri("/room_keys/keys/$roomId",{$roomId:e}):"/room_keys/keys",{path:o,queryData:void 0===n?void 0:{version:n}}},N.prototype.sendKeyBackup=function(e,t,n,o){if(null===this._crypto)throw new Error("End-to-end encryption disabled");const r=this._makeKeyBackupPath(e,t,n);return this._http.authedRequest(void 0,"PUT",r.path,r.queryData,o,{prefix:_.PREFIX_UNSTABLE})},N.prototype.scheduleAllGroupSessionsForBackup=async function(){if(null===this._crypto)throw new Error("End-to-end encryption disabled");await this._crypto.scheduleAllGroupSessionsForBackup()},N.prototype.flagAllGroupSessionsForBackup=function(){if(null===this._crypto)throw new Error("End-to-end encryption disabled");return this._crypto.flagAllGroupSessionsForBackup()},N.prototype.isValidRecoveryKey=function(e){try{return(0,D.decodeRecoveryKey)(e),!0}catch(e){return!1}},N.prototype.keyBackupKeyFromPassword=function(e,t){return(0,S.keyFromAuthData)(t.auth_data,e)},N.prototype.keyBackupKeyFromRecoveryKey=function(e){return(0,D.decodeRecoveryKey)(e)},N.RESTORE_BACKUP_ERROR_BAD_KEY="RESTORE_BACKUP_ERROR_BAD_KEY",N.prototype.restoreKeyBackupWithPassword=async function(e,t,n,o,r){const i=await(0,S.keyFromAuthData)(o.auth_data,e);return this._restoreKeyBackup(i,t,n,o,r)},N.prototype.restoreKeyBackupWithSecretStorage=async function(e,t,n,o){const r=await this.getSecret("m.megolm_backup.v1"),i=(0,k.fixBackupKey)(r);if(i){const[e]=await this._crypto.getSecretStorageKey();await this.storeSecret("m.megolm_backup.v1",i,[e])}const a=(0,b.decodeBase64)(i||r);return this._restoreKeyBackup(a,t,n,e,o)},N.prototype.restoreKeyBackupWithRecoveryKey=function(e,t,n,o,r){const i=(0,D.decodeRecoveryKey)(e);return this._restoreKeyBackup(i,t,n,o,r)},N.prototype.restoreKeyBackupWithCache=async function(e,t,n,o){const r=await this._crypto.getSessionBackupPrivateKey();if(!r)throw new Error("Couldn't get key");return this._restoreKeyBackup(r,e,t,n,o)},N.prototype._restoreKeyBackup=function(e,t,o,r,{cacheCompleteCallback:i,progressCallback:a}={}){if(null===this._crypto)throw new Error("End-to-end encryption disabled");let s=0,u=[];const c=this._makeKeyBackupPath(t,o,r.version),l=new n.g.Olm.PkDecryption;let d;try{d=l.init_with_private_key(e)}catch(e){throw l.free(),e}return d!==r.auth_data.public_key?Promise.reject({errcode:N.RESTORE_BACKUP_ERROR_BAD_KEY}):(this._crypto.storeSessionBackupPrivateKey(e).catch((e=>{E.logger.warn("Error caching session backup key:",e)})).then(i),a&&a({stage:"fetch"}),this._http.authedRequest(void 0,"GET",c.path,c.queryData,void 0,{prefix:_.PREFIX_UNSTABLE}).then((e=>{if(e.rooms)for(const[t,n]of Object.entries(e.rooms)){if(!n.sessions)continue;s+=Object.keys(n.sessions).length;const e=O(n.sessions,l,t);for(const n of e)n.room_id=t,u.push(n)}else if(e.sessions)s=Object.keys(e.sessions).length,u=O(e.sessions,l,t);else{s=1;try{const n=B(e,l);n.room_id=t,n.session_id=o,u.push(n)}catch(e){E.logger.log("Failed to decrypt megolm session from backup",e)}}return this.importRoomKeys(u,{progressCallback:a,untrusted:!0,source:"backup"})})).then((()=>this._crypto.setTrustedBackupPubKey(d))).then((()=>({total:s,imported:u.length}))).finally((()=>{l.free()})))},N.prototype.deleteKeysFromBackup=function(e,t,n){if(null===this._crypto)throw new Error("End-to-end encryption disabled");const o=this._makeKeyBackupPath(e,t,n);return this._http.authedRequest(void 0,"DELETE",o.path,o.queryData,void 0,{prefix:_.PREFIX_UNSTABLE})},N.prototype.sendSharedHistoryKeys=async function(e,t){if(null===this._crypto)throw new Error("End-to-end encryption disabled");const n=this._roomList.getRoomEncryption(e);if(!n)return void E.logger.error("Unknown room. Not sharing decryption keys");const o=await this._crypto.downloadKeys(t),r={};for(const[e,t]of Object.entries(o))r[e]=Object.values(t);const i=this._crypto._getRoomDecryptor(e,n.algorithm);i.sendSharedHistoryInboundSessions?await i.sendSharedHistoryInboundSessions(r):E.logger.warning("Algorithm does not support sharing previous keys",n.algorithm)},N.prototype.getGroup=function(e){return this.store.getGroup(e)},N.prototype.getGroups=function(){return this.store.getGroups()},N.prototype.getMediaConfig=function(e){return this._http.authedRequest(e,"GET","/config",void 0,void 0,{prefix:_.PREFIX_MEDIA_R0})},N.prototype.getRoom=function(e){return this.store.getRoom(e)},N.prototype.getRooms=function(){return this.store.getRooms()},N.prototype.getVisibleRooms=function(){const e=this.store.getRooms(),t=new Set;for(const n of e){const e=n.currentState.getStateEvents("m.room.create","");if(e){const n=e.getContent().predecessor;n&&n.room_id&&t.add(n.room_id)}}return e.filter((e=>!e.currentState.getStateEvents("m.room.tombstone","")||!t.has(e.roomId)))},N.prototype.getUser=function(e){return this.store.getUser(e)},N.prototype.getUsers=function(){return this.store.getUsers()},N.prototype.setAccountData=function(e,t,n){const o=m.encodeUri("/user/$userId/account_data/$type",{$userId:this.credentials.userId,$type:e}),r=(0,_.retryNetworkOperation)(5,(()=>this._http.authedRequest(void 0,"PUT",o,void 0,t)));return n&&r.then((e=>n(null,e)),n),r},N.prototype.getAccountData=function(e){return this.store.getAccountData(e)},N.prototype.getAccountDataFromServer=async function(e){if(this.isInitialSyncComplete()){const t=this.store.getAccountData(e);return t?t.getContent():null}const t=m.encodeUri("/user/$userId/account_data/$type",{$userId:this.credentials.userId,$type:e});try{return await this._http.authedRequest(void 0,"GET",t,void 0)}catch(e){if(e.data&&"M_NOT_FOUND"===e.data.errcode)return null;throw e}},N.prototype.getIgnoredUsers=function(){const e=this.getAccountData("m.ignored_user_list");return e&&e.getContent()&&e.getContent().ignored_users?Object.keys(e.getContent().ignored_users):[]},N.prototype.setIgnoredUsers=function(e,t){const n={ignored_users:{}};return e.map((e=>n.ignored_users[e]={})),this.setAccountData("m.ignored_user_list",n,t)},N.prototype.isUserIgnored=function(e){return-1!==this.getIgnoredUsers().indexOf(e)},N.prototype.joinRoom=function(e,t,n){if(m.isFunction(t))throw new Error("Expected 'opts' object, got function.");void 0===(t=t||{}).syncRoom&&(t.syncRoom=!0);const o=this.getRoom(e);if(o&&o.hasMembershipState(this.credentials.userId,"join"))return Promise.resolve(o);let r=Promise.resolve();t.inviteSignUrl&&(r=this._http.requestOtherUrl(void 0,"POST",t.inviteSignUrl,{mxid:this.credentials.userId}));const i={};t.viaServers&&(i.server_name=t.viaServers);const a={qsStringifyOptions:{arrayFormat:"repeat"}},s=this;return new Promise(((o,u)=>{r.then((function(t){const n={};t&&(n.third_party_signed=t);const o=m.encodeUri("/join/$roomid",{$roomid:e});return s._http.authedRequest(void 0,"POST",o,i,n,a)})).then((function(e){const n=e.room_id,o=new c.SyncApi(s,s._clientOpts).createRoom(n);return t.syncRoom,Promise.resolve(o)})).then((function(e){G(n,o,e)}),(function(e){K(n,u,e)}))}))},N.prototype.resendEvent=function(e,t){return j(t,e,l.EventStatus.SENDING),U(this,t,e)},N.prototype.cancelPendingEvent=function(e){if([l.EventStatus.QUEUED,l.EventStatus.NOT_SENT].indexOf(e.status)<0)throw new Error("cannot cancel an event with status "+e.status);this.scheduler&&this.scheduler.removeEventFromQueue(e),j(this.getRoom(e.getRoomId()),e,l.EventStatus.CANCELLED)},N.prototype.setRoomName=function(e,t,n){return this.sendStateEvent(e,"m.room.name",{name:t},void 0,n)},N.prototype.setRoomTopic=function(e,t,n){return this.sendStateEvent(e,"m.room.topic",{topic:t},void 0,n)},N.prototype.getRoomTags=function(e,t){const n=m.encodeUri("/user/$userId/rooms/$roomId/tags/",{$userId:this.credentials.userId,$roomId:e});return this._http.authedRequest(t,"GET",n,void 0)},N.prototype.setRoomTag=function(e,t,n,o){const r=m.encodeUri("/user/$userId/rooms/$roomId/tags/$tag",{$userId:this.credentials.userId,$roomId:e,$tag:t});return this._http.authedRequest(o,"PUT",r,void 0,n)},N.prototype.deleteRoomTag=function(e,t,n){const o=m.encodeUri("/user/$userId/rooms/$roomId/tags/$tag",{$userId:this.credentials.userId,$roomId:e,$tag:t});return this._http.authedRequest(n,"DELETE",o,void 0,void 0)},N.prototype.setRoomAccountData=function(e,t,n,o){const r=m.encodeUri("/user/$userId/rooms/$roomId/account_data/$type",{$userId:this.credentials.userId,$roomId:e,$type:t});return this._http.authedRequest(o,"PUT",r,void 0,n)},N.prototype.setPowerLevel=function(e,t,n,o,r){let i={users:{}};o&&"m.room.power_levels"===o.getType()&&(i=m.deepCopy(o.getContent())),i.users[t]=n;const a=m.encodeUri("/rooms/$roomId/state/m.room.power_levels",{$roomId:e});return this._http.authedRequest(r,"PUT",a,void 0,i)},N.prototype.sendEvent=function(e,t,n,o,r){return this._sendCompleteEvent(e,{type:t,content:n},o,r)},N.prototype._sendCompleteEvent=function(e,t,n,o){m.isFunction(n)&&(o=n,n=void 0),n||(n=this.makeTxnId());const r=new l.MatrixEvent(Object.assign(t,{event_id:"~"+e+":"+n,user_id:this.credentials.userId,sender:this.credentials.userId,room_id:e,origin_server_ts:(new Date).getTime()})),i=this.getRoom(e),a=r.getAssociatedId();if(a&&a.startsWith("~")){const e=i.getPendingEvents().find((e=>e.getId()===a));e.once("Event.localEventIdReplaced",(()=>{r.updateAssociatedId(e.getId())}))}const s=r.getType();return E.logger.log(`sendEvent of type ${s} in ${e} with txnId ${n}`),r.setTxnId(n),r.setStatus(l.EventStatus.SENDING),i&&i.addPendingEvent(r,n),r.status===l.EventStatus.NOT_SENT?Promise.reject(new Error("Event blocked by other events not yet sent")):U(this,i,r,o)},N.prototype.redactEvent=function(e,t,n,o){const r=("object"==typeof o?o:{}).reason,i="function"==typeof o?o:void 0;return this._sendCompleteEvent(e,{type:"m.room.redaction",content:{reason:r},redacts:t},n,i)},N.prototype.sendMessage=function(e,t,n,o){return m.isFunction(n)&&(o=n,n=void 0),this.sendEvent(e,"m.room.message",t,n,o)},N.prototype.sendTextMessage=function(e,t,n,o){const r=y.makeTextMessage(t);return this.sendMessage(e,r,n,o)},N.prototype.sendNotice=function(e,t,n,o){const r=y.makeNotice(t);return this.sendMessage(e,r,n,o)},N.prototype.sendEmoteMessage=function(e,t,n,o){const r=y.makeEmoteMessage(t);return this.sendMessage(e,r,n,o)},N.prototype.sendImageMessage=function(e,t,n,o,r){m.isFunction(o)&&(r=o,o=void 0),o||(o="Image");const i={msgtype:"m.image",url:t,info:n,body:o};return this.sendMessage(e,i,r)},N.prototype.sendStickerMessage=function(e,t,n,o,r){m.isFunction(o)&&(r=o,o=void 0),o||(o="Sticker");const i={url:t,info:n,body:o};return this.sendEvent(e,"m.sticker",i,r,void 0)},N.prototype.sendHtmlMessage=function(e,t,n,o){const r=y.makeHtmlMessage(t,n);return this.sendMessage(e,r,o)},N.prototype.sendHtmlNotice=function(e,t,n,o){const r=y.makeHtmlNotice(t,n);return this.sendMessage(e,r,o)},N.prototype.sendHtmlEmote=function(e,t,n,o){const r=y.makeHtmlEmote(t,n);return this.sendMessage(e,r,o)},N.prototype.sendReceipt=function(e,t,n,o){if("function"==typeof n&&(o=n,n={}),this.isGuest())return Promise.resolve({});const r=m.encodeUri("/rooms/$roomId/receipt/$receiptType/$eventId",{$roomId:e.getRoomId(),$receiptType:t,$eventId:e.getId()}),i=this._http.authedRequest(o,"POST",r,void 0,n||{}),a=this.getRoom(e.getRoomId());return a&&a._addLocalEchoReceipt(this.credentials.userId,e,t),i},N.prototype.sendReadReceipt=async function(e,t,n){"function"==typeof t&&(n=t,t={}),t||(t={});const o=e.getId(),r=this.getRoom(e.getRoomId());if(r&&r.hasPendingEvent(o))throw new Error(`Cannot set read receipt to a pending event (${o})`);const i={"m.hidden":Boolean(t.hidden)};return this.sendReceipt(e,"m.read",i,n)},N.prototype.setRoomReadMarkers=async function(e,t,n,o){const r=this.getRoom(e);if(r&&r.hasPendingEvent(t))throw new Error(`Cannot set read marker to a pending event (${t})`);let i;if(n){if(i=n.getId(),r&&r.hasPendingEvent(i))throw new Error(`Cannot set read receipt to a pending event (${i})`);r&&r._addLocalEchoReceipt(this.credentials.userId,n,"m.read")}return this.setRoomReadMarkersHttpRequest(e,t,i,o)},N.prototype.getUrlPreview=function(e,t,n){const o=(t=6e4*Math.floor(t/6e4))+"_"+e,r=this.urlPreviewCache[o];if(r)return n&&r.then(n).catch(n),r;const i=this._http.authedRequest(n,"GET","/preview_url",{url:e,ts:t},void 0,{prefix:_.PREFIX_MEDIA_R0});return this.urlPreviewCache[o]=i,i},N.prototype.sendTyping=function(e,t,n,o){if(this.isGuest())return Promise.resolve({});const r=m.encodeUri("/rooms/$roomId/typing/$userId",{$roomId:e,$userId:this.credentials.userId}),i={typing:t};return t&&(i.timeout=n||2e4),this._http.authedRequest(o,"PUT",r,void 0,i)},N.prototype.getRoomUpgradeHistory=function(e,t=!1){let n=this.getRoom(e);if(!n)return[];const o=[n];let r=n.currentState.getStateEvents("m.room.create","");for(;r;){E.logger.log(`Looking at ${r.getId()}`);const e=r.getContent().predecessor;if(!e||!e.room_id)break;{E.logger.log(`Looking at predecessor ${e.room_id}`);const n=this.getRoom(e.room_id);if(!n)break;if(t){const e=n.currentState.getStateEvents("m.room.tombstone","");if(!e||e.getContent().replacement_room!==n.roomId)break}o.splice(0,0,n),r=n.currentState.getStateEvents("m.room.create","")}}let i=n.currentState.getStateEvents("m.room.tombstone","");for(;i;){const e=this.getRoom(i.getContent().replacement_room);if(!e)break;if(e.roomId===n.roomId)break;if(t){if(r=e.currentState.getStateEvents("m.room.create",""),!r||!r.getContent().predecessor)break;if(r.getContent().predecessor.room_id!==n.roomId)break}if(o.push(e),new Set(o.map((e=>e.roomId))).sizethis.leave(e).then((()=>{r[e]=null})).catch((t=>(r[e]=t,null)));for(const e of o)i.push(a(e.roomId));return Promise.all(i).then((()=>r))},N.prototype.ban=function(e,t,n,o){return z(this,e,t,"ban",n,o)},N.prototype.forget=function(e,t,n){void 0===t&&(t=!0);const o=z(this,e,void 0,"forget",void 0,n);if(!t)return o;const r=this;return o.then((function(t){return r.store.removeRoom(e),r.emit("deleteRoom",e),t}))},N.prototype.unban=function(e,t,n){const o=m.encodeUri("/rooms/$roomId/unban",{$roomId:e}),r={user_id:t};return this._http.authedRequest(n,"POST",o,void 0,r)},N.prototype.kick=function(e,t,n,o){return function(e,t,n,o,r,i){m.isFunction(r)&&(i=r,r=void 0);const a=m.encodeUri("/rooms/$roomId/state/m.room.member/$userId",{$roomId:t,$userId:n});return e._http.authedRequest(i,"PUT",a,void 0,{membership:"leave",reason:r})}(this,e,t,0,n,o)},N.prototype.getPushActionsForEvent=function(e){return e.getPushActions()||e.setPushActions(this._pushProcessor.actionsForEvent(e)),e.getPushActions()},N.prototype.setProfileInfo=function(e,t,n){const o=m.encodeUri("/profile/$userId/$info",{$userId:this.credentials.userId,$info:e});return this._http.authedRequest(n,"PUT",o,void 0,t)},N.prototype.setDisplayName=async function(e,t){const n=await this.setProfileInfo("displayname",{displayname:e},t),o=this.getUser(this.getUserId());return o&&(o.displayName=e,o.emit("User.displayName",o.events.presence,o)),n},N.prototype.setAvatarUrl=async function(e,t){const n=await this.setProfileInfo("avatar_url",{avatar_url:e},t),o=this.getUser(this.getUserId());return o&&(o.avatarUrl=e,o.emit("User.avatarUrl",o.events.presence,o)),n},N.prototype.mxcUrlToHttp=function(e,t,n,o,r){return(0,F.getHttpUriForMxc)(this.baseUrl,e,t,n,o,r)},N.prototype._unstable_setStatusMessage=function(e){const t="im.vector.user_status";return Promise.all(this.getRooms().map((n=>{const o="join"===n.getMyMembership(),r=2===n.getInvitedAndJoinedMemberCount();return o&&r&&n.currentState.mayClientSendStateEvent(t,this)?this.sendStateEvent(n.roomId,t,{status:e},this.getUserId()):Promise.resolve()})))},N.prototype.setPresence=function(e,t){const n=m.encodeUri("/presence/$userId/status",{$userId:this.credentials.userId});if("string"==typeof e&&(e={presence:e}),-1==["offline","online","unavailable"].indexOf(e.presence))throw new Error("Bad presence value: "+e.presence);return this._http.authedRequest(t,"PUT",n,void 0,e)},N.prototype.getPresence=function(e,t){const n=m.encodeUri("/presence/$userId/status",{$userId:e});return this._http.authedRequest(t,"GET",n,void 0,void 0)},N.prototype.scrollback=function(e,t,n){m.isFunction(t)&&(n=t,t=void 0),t=t||30;let o=0,r=this._ongoingScrollbacks[e.roomId]||{};if(r.promise)return r.promise;if(r.errorTs){const e=Date.now()-r.errorTs;o=Math.max(3e3-e,0)}if(null===e.oldState.paginationToken)return Promise.resolve(e);const i=this.store.scrollback(e,t).length;if(i===t)return Promise.resolve(e);t-=i;const a=this,s=new Promise(((r,i)=>{(0,m.sleep)(o).then((function(){return a._createMessagesRequest(e.roomId,e.oldState.paginationToken,t,"b")})).then((function(t){const o=t.chunk.map($(a));if(t.state){const n=t.state.map($(a));e.currentState.setUnknownStateEvents(n)}e.addEventsToTimeline(o,!0,e.getLiveTimeline()),e.oldState.paginationToken=t.end,0===t.chunk.length&&(e.oldState.paginationToken=null),a.store.storeEvents(e,o,t.end,!0),a._ongoingScrollbacks[e.roomId]=null,G(n,r,e)}),(function(t){a._ongoingScrollbacks[e.roomId]={errorTs:Date.now()},K(n,i,t)}))}));return r={promise:s,errorTs:null},this._ongoingScrollbacks[e.roomId]=r,s},N.prototype.getEventTimeline=function(e,t){if(!this.timelineSupport)throw new Error("timeline support is disabled. Set the 'timelineSupport' parameter to true when creating MatrixClient to enable it.");if(e.getTimelineForEvent(t))return Promise.resolve(e.getTimelineForEvent(t));const n=m.encodeUri("/rooms/$roomId/context/$eventId",{$roomId:e.room.roomId,$eventId:t});let o;this._clientOpts.lazyLoadMembers&&(o={filter:JSON.stringify(u.Filter.LAZY_LOADING_MESSAGES_FILTER)});const r=this;return r._http.authedRequest(void 0,"GET",n,o).then((function(n){if(!n.event)throw new Error("'event' not in '/context' result - homeserver too old?");if(e.getTimelineForEvent(t))return e.getTimelineForEvent(t);n.events_after.reverse();const o=n.events_after.concat([n.event]).concat(n.events_before).map(r.getEventMapper());let i=e.getTimelineForEvent(o[0].getId());if(i){const e=n.state.map(r.getEventMapper());i.getState(d.EventTimeline.BACKWARDS).setUnknownStateEvents(e)}else i=e.addTimeline(),i.initialiseState(n.state.map(r.getEventMapper())),i.getState(d.EventTimeline.FORWARDS).paginationToken=n.end;return e.addEventsToTimeline(o,!0,i,n.start),e.getTimelineForEvent(t)||i}))},N.prototype._createMessagesRequest=function(e,t,n,o,r){const i=m.encodeUri("/rooms/$roomId/messages",{$roomId:e});void 0===n&&(n=30);const a={from:t,limit:n,dir:o};let s=null;return this._clientOpts.lazyLoadMembers&&(s=Object.assign({},u.Filter.LAZY_LOADING_MESSAGES_FILTER)),r&&(s=s||{},Object.assign(s,r.getRoomTimelineFilterComponent())),s&&(a.filter=JSON.stringify(s)),this._http.authedRequest(void 0,"GET",i,a)},N.prototype.paginateEventTimeline=function(e,t){const n=e.getTimelineSet()===this._notifTimelineSet,o=(t=t||{}).backwards||!1;if(n&&!o)throw new Error("paginateNotifTimeline can only paginate backwards");const r=o?d.EventTimeline.BACKWARDS:d.EventTimeline.FORWARDS,i=e.getPaginationToken(r);if(!i)return Promise.resolve(!1);const a=e._paginationRequests[r];if(a)return a;let s,u,c;const l=this;if(n)s="/notifications",u={limit:"limit"in t?t.limit:30,only:"highlight"},i&&"end"!==i&&(u.from=i),c=this._http.authedRequest(void 0,"GET","/notifications",u,void 0).then((function(t){const n=t.next_token,i=[];for(let e=0;e{r.then((function(){o.getPushRules().then((function(t){o.pushRules=t,e()}),(function(e){t(e)}))}),(function(e){o.getPushRules().then((function(n){o.pushRules=n,t(e)}),(function(n){t(e)}))}))}))},N.prototype.searchMessageText=function(e,t){const n={search_term:e.query};return"keys"in e&&(n.keys=e.keys),this.search({body:{search_categories:{room_events:n}}},t)},N.prototype.searchRoomEvents=function(e){const t={search_categories:{room_events:{search_term:e.term,filter:e.filter,order_by:"recent",event_context:{before_limit:1,after_limit:1,include_profile:!0}}}},n={_query:t,results:[],highlights:[]};return this.search({body:t}).then(this._processRoomEventsSearch.bind(this,n))},N.prototype.backPaginateRoomEventsSearch=function(e){if(!e.next_batch)return Promise.reject(new Error("Cannot backpaginate event search any further"));if(e.pendingRequest)return e.pendingRequest;const t={body:e._query,next_batch:e.next_batch},n=this.search(t).then(this._processRoomEventsSearch.bind(this,e)).finally((function(){e.pendingRequest=null}));return e.pendingRequest=n,n},N.prototype._processRoomEventsSearch=function(e,t){const n=t.search_categories.room_events;e.count=n.count,e.next_batch=n.next_batch;const o={};n.highlights.forEach((function(e){o[e]=1})),e.highlights.forEach((function(e){o[e]=1})),e.highlights=Object.keys(o);const r=n.results?n.results.length:0;for(let t=0;tM)E.logger.debug("TURN creds are valid for another "+t+" ms: not fetching new ones."),e=!0;else{E.logger.debug("Fetching new TURN credentials");try{const t=await this.turnServer();if(t.uris){E.logger.log("Got TURN URIs: "+t.uris+" refresh in "+t.ttl+" secs");const n={urls:t.uris,username:t.username,credential:t.password};this._turnServers=[n],this._turnServersExpiry=Date.now()+1e3*t.ttl,e=!0}}catch(e){E.logger.error("Failed to get TURN URIs",e),403===e.httpStatus&&(E.logger.info("TURN access unavailable for this account: stopping credentials checks"),null!==this._checkTurnServersIntervalID&&n.g.clearInterval(this._checkTurnServersIntervalID),this._checkTurnServersIntervalID=null)}}return e},N.prototype.setFallbackICEServerAllowed=function(e){this._fallbackICEServerAllowed=e},N.prototype.isFallbackICEServerAllowed=function(){return this._fallbackICEServerAllowed},N.prototype.isSynapseAdministrator=function(){const e=m.encodeUri("/_synapse/admin/v1/users/$userId/admin",{$userId:this.getUserId()});return this._http.authedRequest(void 0,"GET",e,void 0,void 0,{prefix:""}).then((e=>e.admin))},N.prototype.whoisSynapseUser=function(e){const t=m.encodeUri("/_synapse/admin/v1/whois/$userId",{$userId:e});return this._http.authedRequest(void 0,"GET",t,void 0,void 0,{prefix:""})},N.prototype.deactivateSynapseUser=function(e){const t=m.encodeUri("/_synapse/admin/v1/deactivate/$userId",{$userId:e});return this._http.authedRequest(void 0,"POST",t,void 0,void 0,{prefix:""})},N.prototype.startClient=async function(e){if(this.clientRunning)return;this.clientRunning=!0,"number"==typeof e&&(e={initialSyncLimit:e});const t=this.getUserId();t&&this.store.storeUser(new A.User(t)),this._crypto&&(this._crypto.uploadDeviceKeys(),this._crypto.start()),this._supportsVoip&&(this._checkTurnServersIntervalID=setInterval((()=>{this._checkTurnServers()}),M),this._checkTurnServers()),this._syncApi&&(E.logger.error("Still have sync object whilst not running: stopping old one"),this._syncApi.stop()),(e=Object.assign({},e)).crypto=this._crypto,e.canResetEntireTimeline=e=>!!this._canResetTimelineCallback&&this._canResetTimelineCallback(e),this._clientOpts=e,this._syncApi=new c.SyncApi(this,e),this._syncApi.sync(),void 0!==e.clientWellKnownPollPeriod&&(this._clientWellKnownIntervalID=setInterval((()=>{this._fetchClientWellKnown()}),1e3*e.clientWellKnownPollPeriod),this._fetchClientWellKnown())},N.prototype._fetchClientWellKnown=async function(){this._clientWellKnownPromise=T.AutoDiscovery.getRawClientConfig(this.getDomain()),this._clientWellKnown=await this._clientWellKnownPromise,this.emit("WellKnown.client",this._clientWellKnown)},N.prototype.getClientWellKnown=function(){return this._clientWellKnown},N.prototype.waitForClientWellKnown=function(){return this._clientWellKnownPromise},N.prototype._storeClientOptions=function(){const e=["boolean","string","number"],t=Object.entries(this._clientOpts).filter((([t,n])=>e.includes(typeof n))).reduce(((e,[t,n])=>(e[t]=n,e)),{});return this.store.storeClientOptions(t)},N.prototype._unstable_getSharedRooms=async function(e){if(!await this.doesServerSupportUnstableFeature("uk.half-shot.msc2666"))throw Error("Server does not support shared_rooms API");const t=m.encodeUri("/uk.half-shot.msc2666/user/shared_rooms/$userId",{$userId:e});return(await this._http.authedRequest(void 0,"GET",t,void 0,void 0,{prefix:_.PREFIX_UNSTABLE})).joined},N.prototype.stopClient=function(){E.logger.log("stopping MatrixClient"),this.clientRunning=!1,this._syncApi&&(this._syncApi.stop(),this._syncApi=null),this._crypto&&this._crypto.stop(),this._peekSync&&this._peekSync.stopPeeking(),this._callEventHandler&&(this._callEventHandler.stop(),this._callEventHandler=null),n.g.clearInterval(this._checkTurnServersIntervalID),void 0!==this._clientWellKnownIntervalID&&n.g.clearInterval(this._clientWellKnownIntervalID)},N.prototype.getVersions=function(){return this._serverVersionsPromise||(this._serverVersionsPromise=this._http.request(void 0,"GET","/_matrix/client/versions",void 0,void 0,{prefix:""}).catch((e=>{throw this._serverVersionsPromise=null,e}))),this._serverVersionsPromise},N.prototype.isVersionSupported=async function(e){const{versions:t}=await this.getVersions();return t&&t.includes(e)},N.prototype.doesServerSupportLazyLoading=async function(){const e=await this.getVersions();if(!e)return!1;const t=e.versions,n=e.unstable_features;return t&&t.includes("r0.5.0")||n&&n["m.lazy_load_members"]},N.prototype.doesServerRequireIdServerParam=async function(){const e=await this.getVersions();if(!e)return!0;const t=e.versions;if(t&&t.includes("r0.6.0"))return!1;const n=e.unstable_features;return!n||void 0===n["m.require_identity_server"]||n["m.require_identity_server"]},N.prototype.doesServerAcceptIdentityAccessToken=async function(){const e=await this.getVersions();if(!e)return!1;const t=e.versions,n=e.unstable_features;return t&&t.includes("r0.6.0")||n&&n["m.id_access_token"]},N.prototype.doesServerSupportSeparateAddAndBind=async function(){const e=await this.getVersions();if(!e)return!1;const t=e.versions,n=e.unstable_features;return t&&t.includes("r0.6.0")||n&&n["m.separate_add_and_bind"]},N.prototype.doesServerSupportUnstableFeature=async function(e){const t=await this.getVersions();if(!t)return!1;const n=t.unstable_features;return n&&!!n[e]},N.prototype.doesServerForceEncryptionForPreset=async function(e){const t=await this.getVersions();if(!t)return!1;const n=t.unstable_features;return n&&!!n[`io.element.e2ee_forced.${e}`]},N.prototype.hasLazyLoadMembersEnabled=function(){return!!this._clientOpts.lazyLoadMembers},N.prototype.setCanResetTimelineCallback=function(e){this._canResetTimelineCallback=e},N.prototype.getCanResetTimelineCallback=function(){return this._canResetTimelineCallback},N.prototype.relations=async function(e,t,n,o,r={}){const i=function(e,t,n){return"m.reaction"===n?n:e.isRoomEncrypted(t)?"m.room.encrypted":n}(this,e,o),a=await this.fetchRelations(e,t,n,i,r),s=this.getEventMapper();let u;a.original_event&&(u=s(a.original_event));let c=a.chunk.map(s);if("m.room.encrypted"===i){const e=u?c.concat(u):c;await Promise.all(e.map((e=>new Promise((t=>e.once("Event.decrypted",t)))))),c=c.filter((e=>e.getType()===o))}return u&&"m.replace"===n&&(c=c.filter((e=>e.getSender()===u.getSender()))),{originalEvent:u,events:c,nextBatch:a.next_batch}},N.prototype.getEventMapper=function(e){return $(this,e)},N.prototype.getCrossSigningCacheCallbacks=function(){return this._crypto&&this._crypto._crossSigningInfo.getCacheCallbacks()},N.prototype.generateClientSecret=function(){return(0,x.randomString)(32)},N.prototype.decryptEventIfNeeded=function(e,t){return e.shouldAttemptDecryption()&&e.attemptDecryption(this._crypto,t),e.isBeingDecrypted()?e._decryptionPromise:Promise.resolve()}},44656:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.makeHtmlMessage=function(e,t){return{msgtype:"m.text",format:"org.matrix.custom.html",body:e,formatted_body:t}},t.makeHtmlNotice=function(e,t){return{msgtype:"m.notice",format:"org.matrix.custom.html",body:e,formatted_body:t}},t.makeHtmlEmote=function(e,t){return{msgtype:"m.emote",format:"org.matrix.custom.html",body:e,formatted_body:t}},t.makeTextMessage=function(e){return{msgtype:"m.text",body:e}},t.makeNotice=function(e){return{msgtype:"m.notice",body:e}},t.makeEmoteMessage=function(e){return{msgtype:"m.emote",body:e}}},73667:(e,t,n)=>{"use strict";var o=n(20862);Object.defineProperty(t,"__esModule",{value:!0}),t.getHttpUriForMxc=function(e,t,n,o,i,a){if("string"!=typeof t||!t)return"";if(0!==t.indexOf("mxc://"))return a?t:"";let s=t.slice(6),u="/_matrix/media/r0/download/";const c={};n&&(c.width=Math.round(n)),o&&(c.height=Math.round(o)),i&&(c.method=i),Object.keys(c).length>0&&(u="/_matrix/media/r0/thumbnail/");const l=s.indexOf("#");let d="";return l>=0&&(d=s.substr(l),s=s.substr(0,l)),e+u+s+(0===Object.keys(c).length?"":"?"+r.encodeParams(c))+d};var r=o(n(3102))},3075:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.createCryptoStoreCacheCallbacks=function(e,t){return{getCrossSigningKeyCache:async function(n,r){const i=await new Promise((t=>e.doTxn("readonly",[a.IndexedDBCryptoStore.STORE_ACCOUNT],(o=>{e.getSecretStorePrivateKey(o,t,n)}))));if(i&&i.ciphertext){const e=Buffer.from(t._pickleKey),r=await(0,s.decryptAES)(i,e,n);return(0,o.decodeBase64)(r)}return i},storeCrossSigningKeyCache:async function(n,r){if(!(r instanceof Uint8Array))throw new Error(`storeCrossSigningKeyCache expects Uint8Array, got ${r}`);const i=Buffer.from(t._pickleKey);return r=await(0,s.encryptAES)((0,o.encodeBase64)(r),i,n),e.doTxn("readwrite",[a.IndexedDBCryptoStore.STORE_ACCOUNT],(t=>{e.storeSecretStorePrivateKey(t,n,r)}))}}},t.requestKeysDuringVerification=async function(e,t,n){if(e.getUserId()===t)return i.logger.log("Cross-signing: Self-verification done; requesting keys"),new Promise(((t,r)=>{const a=e,s=a._crypto._crossSigningInfo,u=new c(s.userId,{getCrossSigningKey:async e=>{i.logger.debug("Cross-signing: requesting secret",e,n);const{promise:t}=a.requestSecret(`m.cross_signing.${e}`,[n]),r=await t,s=(0,o.decodeBase64)(r);return Uint8Array.from(s)}},s._cacheCallbacks);u.keys=s.keys;const l=new Promise(((e,t)=>{setTimeout(e,6e4,new Error("Timeout"))})),d=new Promise((async e=>{if(!await a._crypto.getSessionBackupPrivateKey()){i.logger.info("No cached backup key found. Requesting...");const e=a.requestSecret("m.megolm_backup.v1",[n]),t=await e.promise;i.logger.info("Got key backup key, decoding...");const r=(0,o.decodeBase64)(t);i.logger.info("Decoded backup key, storing..."),a._crypto.storeSessionBackupPrivateKey(Uint8Array.from(r)),i.logger.info("Backup key stored. Starting backup restore...");const s=await a.getKeyBackupVersion();a.restoreKeyBackupWithCache(void 0,void 0,s).then((()=>{i.logger.info("Backup restored.")}))}e()}));return Promise.race([Promise.all([u.getCrossSigningKey("master"),u.getCrossSigningKey("self_signing"),u.getCrossSigningKey("user_signing"),d]),l]).then(t,r)})).catch((e=>{i.logger.warn("Cross-signing: failure while requesting keys:",e)}))},t.DeviceTrustLevel=t.UserTrustLevel=t.CrossSigningLevel=t.CrossSigningInfo=void 0;var o=n(32772),r=n(17187),i=n(7434),a=n(57585),s=n(2611);function u(e){return Object.values(e.keys)[0]}class c extends r.EventEmitter{constructor(e,t,n){super(),Object.defineProperty(this,"userId",{enumerable:!0,value:e}),this._callbacks=t||{},this._cacheCallbacks=n||{},this.keys={},this.firstUse=!0,this.crossSigningVerifiedBefore=!1}static fromStorage(e,t){const n=new c(t);for(const t in e)e.hasOwnProperty(t)&&(n[t]=e[t]);return n}toStorage(){return{keys:this.keys,firstUse:this.firstUse,crossSigningVerifiedBefore:this.crossSigningVerifiedBefore}}async getCrossSigningKey(e,t){const o=["master","self_signing","user_signing"].indexOf(e)>=0;if(!this._callbacks.getCrossSigningKey)throw new Error("No getCrossSigningKey callback supplied");function r(e){if(!e)return;const o=new n.g.Olm.PkSigning,r=o.init_with_seed(e);if(r===t)return[r,o];o.free()}let i;void 0===t&&(t=this.getId(e)),this._cacheCallbacks.getCrossSigningKeyCache&&o&&(i=await this._cacheCallbacks.getCrossSigningKeyCache(e,t));const a=r(i);if(a)return a;i=await this._callbacks.getCrossSigningKey(e,t);const s=r(i);if(s)return this._cacheCallbacks.storeCrossSigningKeyCache&&o&&await this._cacheCallbacks.storeCrossSigningKeyCache(e,i),s;if(!i)throw new Error("getCrossSigningKey callback for "+e+" returned falsey");throw new Error("Key type "+e+" from getCrossSigningKey callback did not match")}async isStoredInSecretStorage(e){const t=await e.isStored("m.cross_signing.master",!1)||{};function n(e){for(const n of Object.keys(t))e[n]||delete t[n]}for(const t of["self_signing","user_signing"])n(await e.isStored(`m.cross_signing.${t}`,!1)||{});return Object.keys(t).length?t:null}static async storeInSecretStorage(e,t){for(const[n,r]of e){const e=(0,o.encodeBase64)(r);await t.store(`m.cross_signing.${n}`,e)}}static async getFromSecretStorage(e,t){const n=await t.get(`m.cross_signing.${e}`);return n?(0,o.decodeBase64)(n):null}async isStoredInKeyCache(e){const t=this._cacheCallbacks;if(!t)return!1;const n=e?[e]:["master","self_signing","user_signing"];for(const e of n)if(!await t.getCrossSigningKeyCache(e))return!1;return!0}async getCrossSigningKeysFromCache(){const e=new Map,t=this._cacheCallbacks;if(!t)return e;for(const n of["master","self_signing","user_signing"]){const o=await t.getCrossSigningKeyCache(n);o&&e.set(n,o)}return e}getId(e){return e=e||"master",this.keys[e]?u(this.keys[e]):null}async resetKeys(e){if(!this._callbacks.saveCrossSigningKeys)throw new Error("No saveCrossSigningKeys callback supplied");if(void 0===e||e&l.MASTER||!this.keys.master)e=l.MASTER|l.USER_SIGNING|l.SELF_SIGNING;else if(0===e)return;const t={},r={};let i,a;try{if(e&l.MASTER?(i=new n.g.Olm.PkSigning,t.master=i.generate_seed(),a=i.init_with_seed(t.master),r.master={user_id:this.userId,usage:["master"],keys:{["ed25519:"+a]:a}}):[a,i]=await this.getCrossSigningKey("master"),e&l.SELF_SIGNING){const e=new n.g.Olm.PkSigning;try{t.self_signing=e.generate_seed();const n=e.init_with_seed(t.self_signing);r.self_signing={user_id:this.userId,usage:["self_signing"],keys:{["ed25519:"+n]:n}},(0,o.pkSign)(r.self_signing,i,this.userId,a)}finally{e.free()}}if(e&l.USER_SIGNING){const e=new n.g.Olm.PkSigning;try{t.user_signing=e.generate_seed();const n=e.init_with_seed(t.user_signing);r.user_signing={user_id:this.userId,usage:["user_signing"],keys:{["ed25519:"+n]:n}},(0,o.pkSign)(r.user_signing,i,this.userId,a)}finally{e.free()}}Object.assign(this.keys,r),this._callbacks.saveCrossSigningKeys(t)}finally{i&&i.free()}}clearKeys(){this.keys={}}setKeys(e){const t={};if(e.master){if(e.master.user_id!==this.userId){const t="Mismatched user ID "+e.master.user_id+" in master key from "+this.userId;throw i.logger.error(t),new Error(t)}this.keys.master?u(e.master)!==this.getId()&&(this.firstUse=!1):this.firstUse=!0,t.master=e.master}else{if(!this.keys.master)throw new Error("Tried to set cross-signing keys without a master key");t.master=this.keys.master}const n=u(t.master);if(e.user_signing){if(e.user_signing.user_id!==this.userId){const t="Mismatched user ID "+e.master.user_id+" in user_signing key from "+this.userId;throw i.logger.error(t),new Error(t)}try{(0,o.pkVerify)(e.user_signing,n,this.userId)}catch(e){throw i.logger.error("invalid signature on user-signing key"),e}}if(e.self_signing){if(e.self_signing.user_id!==this.userId){const t="Mismatched user ID "+e.master.user_id+" in self_signing key from "+this.userId;throw i.logger.error(t),new Error(t)}try{(0,o.pkVerify)(e.self_signing,n,this.userId)}catch(e){throw i.logger.error("invalid signature on self-signing key"),e}}e.master&&(this.keys.master=e.master,this.keys.self_signing=null,this.keys.user_signing=null),e.self_signing&&(this.keys.self_signing=e.self_signing),e.user_signing&&(this.keys.user_signing=e.user_signing)}updateCrossSigningVerifiedBefore(e){!this.crossSigningVerifiedBefore&&e&&(this.crossSigningVerifiedBefore=!0)}async signObject(e,t){if(!this.keys[t])throw new Error("Attempted to sign with "+t+" key but no such key present");const[n,r]=await this.getCrossSigningKey(t);try{return(0,o.pkSign)(e,r,this.userId,n),e}finally{r.free()}}async signUser(e){if(this.keys.user_signing)return this.signObject(e.keys.master,"user_signing");i.logger.info("No user signing key: not signing user")}async signDevice(e,t){if(e!==this.userId)throw new Error(`Trying to sign ${e}'s device; can only sign our own device`);if(this.keys.self_signing)return this.signObject({algorithms:t.algorithms,keys:t.keys,device_id:t.deviceId,user_id:e},"self_signing");i.logger.info("No self signing key: not signing device")}checkUserTrust(e){if(this.userId===e.userId&&this.getId()&&this.getId()===e.getId()&&this.getId("self_signing")&&this.getId("self_signing")===e.getId("self_signing"))return new d(!0,!0,this.firstUse);if(!this.keys.user_signing)return new d(!1,!1,e.firstUse);let t;const n=e.keys.master,r=this.getId("user_signing");try{(0,o.pkVerify)(n,r,this.userId),t=!0}catch(e){t=!1}return new d(t,e.crossSigningVerifiedBefore,e.firstUse)}checkDeviceTrust(e,t,n,r){const i=this.checkUserTrust(e),a=e.keys.self_signing;if(!a)return new h(!1,!1,n,r);const s=function(e,t){return{algorithms:e.algorithms,keys:e.keys,device_id:e.deviceId,user_id:t,signatures:e.signatures}}(t,e.userId);try{return(0,o.pkVerify)(a,e.getId(),e.userId),(0,o.pkVerify)(s,u(a),e.userId),h.fromUserTrustLevel(i,n,r)}catch(e){return new h(!1,!1,n,r)}}getCacheCallbacks(){return this._cacheCallbacks}}t.CrossSigningInfo=c;const l={MASTER:4,USER_SIGNING:2,SELF_SIGNING:1};t.CrossSigningLevel=l;class d{constructor(e,t,n){this._crossSigningVerified=e,this._crossSigningVerifiedBefore=t,this._tofu=n}isVerified(){return this.isCrossSigningVerified()}isCrossSigningVerified(){return this._crossSigningVerified}wasCrossSigningVerified(){return this._crossSigningVerifiedBefore}isTofu(){return this._tofu}}t.UserTrustLevel=d;class h{constructor(e,t,n,o){this._crossSigningVerified=e,this._tofu=t,this._localVerified=n,this._trustCrossSignedDevices=o}static fromUserTrustLevel(e,t,n){return new h(e._crossSigningVerified,e._tofu,t,n)}isVerified(){return Boolean(this.isLocallyVerified()||this._trustCrossSignedDevices&&this.isCrossSigningVerified())}isCrossSigningVerified(){return this._crossSigningVerified}isLocallyVerified(){return this._localVerified}isTofu(){return this._tofu}}t.DeviceTrustLevel=h},36670:(e,t,n)=>{"use strict";var o=n(20862);Object.defineProperty(t,"__esModule",{value:!0}),t.DeviceList=void 0;var r=n(17187),i=n(7434),a=n(23272),s=n(3075),u=o(n(32772)),c=n(57585),l=n(3102);class d extends r.EventEmitter{constructor(e,t,n,o=250){super(),this._cryptoStore=t,this._devices={},this._crossSigningInfo={},this._userByIdentityKey={},this._deviceTrackingStatus={},this._syncToken=null,this._serialiser=new h(e,n,this),this._keyDownloadsInProgressByUser={},this._keyDownloadChunkSize=o,this._dirty=!1,this._savePromise=null,this._resolveSavePromise=null,this._savePromiseTime=null,this._saveTimer=null,this._hasFetched=null}async load(){await this._cryptoStore.doTxn("readonly",[c.IndexedDBCryptoStore.STORE_DEVICE_DATA],(e=>{this._cryptoStore.getEndToEndDeviceData(e,(e=>{this._hasFetched=Boolean(e&&e.devices),this._devices=e?e.devices:{},this._crossSigningInfo=e&&e.crossSigningInfo||{},this._deviceTrackingStatus=e?e.trackingStatus:{},this._syncToken=e?e.syncToken:null,this._userByIdentityKey={};for(const e of Object.keys(this._devices)){const t=this._devices[e];for(const n of Object.keys(t)){const o=t[n].keys["curve25519:"+n];void 0!==o&&(this._userByIdentityKey[o]=e)}}}))}));for(const e of Object.keys(this._deviceTrackingStatus))2==this._deviceTrackingStatus[e]&&(this._deviceTrackingStatus[e]=1)}stop(){null!==this._saveTimer&&clearTimeout(this._saveTimer)}async saveIfDirty(e){if(!this._dirty)return Promise.resolve(!1);void 0===e&&(e=500);const t=Date.now+e;this._savePromiseTime&&t{this._resolveSavePromise=e})),this._savePromise=n),null===this._saveTimer){const n=this._resolveSavePromise;this._savePromiseTime=t,this._saveTimer=setTimeout((()=>{i.logger.log("Saving device tracking data",this._syncToken),this._savePromiseTime=null,this._saveTimer=null,this._savePromise=null,this._resolveSavePromise=null,this._cryptoStore.doTxn("readwrite",[c.IndexedDBCryptoStore.STORE_DEVICE_DATA],(e=>{this._cryptoStore.storeEndToEndDeviceData({devices:this._devices,crossSigningInfo:this._crossSigningInfo,trackingStatus:this._deviceTrackingStatus,syncToken:this._syncToken},e)})).then((()=>{this._dirty=!1,n()}),(e=>{i.logger.error("Failed to save device tracking data",this._syncToken),i.logger.error(e)}))}),e)}return n}getSyncToken(){return this._syncToken}setSyncToken(e){this._syncToken=e}downloadKeys(e,t){const n=[],o=[];if(e.forEach((e=>{const r=this._deviceTrackingStatus[e];this._keyDownloadsInProgressByUser[e]?(i.logger.log(`downloadKeys: already have a download in progress for ${e}: awaiting its result`),o.push(this._keyDownloadsInProgressByUser[e])):(t||3!=r)&&n.push(e)})),0!=n.length){i.logger.log("downloadKeys: downloading for",n);const e=this._doKeyDownload(n);o.push(e)}return 0===o.length&&i.logger.log("downloadKeys: already have all necessary keys"),Promise.all(o).then((()=>this._getDevicesFromStore(e)))}_getDevicesFromStore(e){const t={},n=this;return e.map((function(e){t[e]={},(n.getStoredDevicesForUser(e)||[]).map((function(n){t[e][n.deviceId]=n}))})),t}getKnownUserIds(){return Object.keys(this._devices)}getStoredDevicesForUser(e){const t=this._devices[e];if(!t)return null;const n=[];for(const e in t)t.hasOwnProperty(e)&&n.push(a.DeviceInfo.fromStorage(t[e],e));return n}getRawStoredDevicesForUser(e){return this._devices[e]}getStoredCrossSigningForUser(e){return this._crossSigningInfo[e]?s.CrossSigningInfo.fromStorage(this._crossSigningInfo[e],e):null}storeCrossSigningForUser(e,t){this._crossSigningInfo[e]=t,this._dirty=!0}getStoredDevice(e,t){const n=this._devices[e];if(n&&n[t])return a.DeviceInfo.fromStorage(n[t],t)}getUserByIdentityKey(e,t){return e!==u.OLM_ALGORITHM&&e!==u.MEGOLM_ALGORITHM?null:this._userByIdentityKey[t]}getDeviceByIdentityKey(e,t){const n=this.getUserByIdentityKey(e,t);if(!n)return null;const o=this._devices[n];if(!o)return null;for(const e in o){if(!o.hasOwnProperty(e))continue;const n=o[e];for(const o in n.keys)if(n.keys.hasOwnProperty(o)&&0===o.indexOf("curve25519:")&&n.keys[o]==t)return a.DeviceInfo.fromStorage(n,e)}return null}storeDevicesForUser(e,t){if(void 0!==this._devices[e])for(const[t,n]of Object.entries(this._devices[e])){const e=n.keys["curve25519:"+t];delete this._userByIdentityKey[e]}this._devices[e]=t;for(const[n,o]of Object.entries(t)){const t=o.keys["curve25519:"+n];this._userByIdentityKey[t]=e}this._dirty=!0}startTrackingDeviceList(e){if("string"!=typeof e)throw new Error("userId must be a string; was "+e);this._deviceTrackingStatus[e]||(i.logger.log("Now tracking device list for "+e),this._deviceTrackingStatus[e]=1,this._dirty=!0)}stopTrackingDeviceList(e){this._deviceTrackingStatus[e]&&(i.logger.log("No longer tracking device list for "+e),this._deviceTrackingStatus[e]=0,this._dirty=!0)}stopTrackingAllDeviceLists(){for(const e of Object.keys(this._deviceTrackingStatus))this._deviceTrackingStatus[e]=0;this._dirty=!0}invalidateUserDeviceList(e){this._deviceTrackingStatus[e]&&(i.logger.log("Marking device list outdated for",e),this._deviceTrackingStatus[e]=1,this._dirty=!0)}refreshOutdatedDeviceLists(){this.saveIfDirty();const e=[];for(const t of Object.keys(this._deviceTrackingStatus))1==this._deviceTrackingStatus[t]&&e.push(t);return this._doKeyDownload(e)}_setRawStoredDevicesForUser(e,t){if(void 0!==this._devices[e])for(const[t,n]of Object.entries(this._devices[e])){const e=n.keys["curve25519:"+t];delete this._userByIdentityKey[e]}this._devices[e]=t;for(const[n,o]of Object.entries(t)){const t=o.keys["curve25519:"+n];this._userByIdentityKey[t]=e}}setRawStoredCrossSigningForUser(e,t){this._crossSigningInfo[e]=t}_doKeyDownload(e){if(0===e.length)return Promise.resolve();const t=this._serialiser.updateDevicesForUsers(e,this._syncToken).then((()=>{n(!0)}),(t=>{throw i.logger.error("Error downloading keys for "+e+":",t),n(!1),t}));e.forEach((e=>{this._keyDownloadsInProgressByUser[e]=t,1==this._deviceTrackingStatus[e]&&(this._deviceTrackingStatus[e]=2)}));const n=n=>{this.emit("crypto.willUpdateDevices",e,!this._hasFetched),e.forEach((e=>{this._dirty=!0,this._keyDownloadsInProgressByUser[e]===t?(delete this._keyDownloadsInProgressByUser[e],2==this._deviceTrackingStatus[e]&&(n?(this._deviceTrackingStatus[e]=3,i.logger.log("Device list for",e,"now up to date")):this._deviceTrackingStatus[e]=1)):i.logger.log("Another update in the queue for",e,"- not marking up-to-date")})),this.saveIfDirty(),this.emit("crypto.devicesUpdated",e,!this._hasFetched),this._hasFetched=!0};return t}}t.DeviceList=d;class h{constructor(e,t,n){this._baseApis=e,this._olmDevice=t,this._deviceList=n,this._downloadInProgress=!1,this._keyDownloadsQueuedByUser={},this._queuedQueryDeferred=null,this._syncToken=null}updateDevicesForUsers(e,t){return e.forEach((e=>{this._keyDownloadsQueuedByUser[e]=!0})),this._queuedQueryDeferred||(this._queuedQueryDeferred=(0,l.defer)()),this._syncToken=t,this._downloadInProgress?(i.logger.log("Queued key download for",e),this._queuedQueryDeferred.promise):this._doQueuedQueries()}_doQueuedQueries(){if(this._downloadInProgress)throw new Error("DeviceListUpdateSerialiser._doQueuedQueries called with request active");const e=Object.keys(this._keyDownloadsQueuedByUser);this._keyDownloadsQueuedByUser={};const t=this._queuedQueryDeferred;this._queuedQueryDeferred=null,i.logger.log("Starting key download for",e),this._downloadInProgress=!0;const n={};this._syncToken&&(n.token=this._syncToken);const o=[];for(let t=0;tthis._baseApis.downloadKeysForUsers(r,n)))}return(0,l.chunkPromises)(o,3).then((async t=>{const n=Object.assign({},...t.map((e=>e.device_keys||{}))),o=Object.assign({},...t.map((e=>e.master_keys||{}))),r=Object.assign({},...t.map((e=>e.self_signing_keys||{}))),a=Object.assign({},...t.map((e=>e.user_signing_keys||{})));for(const t of e){await(0,l.sleep)(5);try{await this._processQueryResponseForUser(t,n[t],{master:o[t],self_signing:r[t],user_signing:a[t]})}catch(e){i.logger.error(`Error processing keys for ${t}:`,e)}}})).then((()=>{i.logger.log("Completed key download for "+e),this._downloadInProgress=!1,t.resolve(),this._queuedQueryDeferred&&this._doQueuedQueries()}),(n=>{i.logger.warn("Error downloading keys for "+e+":",n),this._downloadInProgress=!1,t.reject(n)})),t.promise}async _processQueryResponseForUser(e,t,n){i.logger.log("got device keys for "+e+":",t),i.logger.log("got cross-signing keys for "+e+":",n);{const n={},o=this._deviceList.getRawStoredDevicesForUser(e);o&&Object.keys(o).forEach((e=>{const t=a.DeviceInfo.fromStorage(o[e],e);n[e]=t})),await async function(e,t,n,o,r,a){let s=!1;for(const e in n)if(n.hasOwnProperty(e)&&!(e in o)){if(t===r&&e===a){i.logger.warn(`Local device ${e} missing from sync, skipping removal`);continue}i.logger.log("Device "+t+":"+e+" has been removed"),delete n[e],s=!0}for(const r in o){if(!o.hasOwnProperty(r))continue;const a=o[r];a.user_id===t?a.device_id===r?await p(e,n,a)&&(s=!0):i.logger.warn("Mismatched device_id "+a.device_id+" in keys from "+t+":"+r):i.logger.warn("Mismatched user_id "+a.user_id+" in keys from "+t+":"+r)}return s}(this._olmDevice,e,n,t||{},this._baseApis.getUserId(),this._baseApis.deviceId);const r={};Object.keys(n).forEach((e=>{r[e]=n[e].toStorage()})),this._deviceList._setRawStoredDevicesForUser(e,r)}if(n&&(n.master||n.self_signing||n.user_signing)){const t=this._deviceList.getStoredCrossSigningForUser(e)||new s.CrossSigningInfo(e);t.setKeys(n),this._deviceList.setRawStoredCrossSigningForUser(e,t.toStorage()),this._deviceList.emit("userCrossSigningUpdated",e)}}}async function p(e,t,n){if(!n.keys)return!1;const o=n.device_id,r=n.user_id,s="ed25519:"+o,c=n.keys[s];if(!c)return i.logger.warn("Device "+r+":"+o+" has no ed25519 key"),!1;const l=n.unsigned||{},d=n.signatures||{};try{await u.verifySignature(e,n,r,o,c)}catch(e){return i.logger.warn("Unable to verify signature on device "+r+":"+o+":"+e),!1}let h;if(o in t){if(h=t[o],h.getFingerprint()!=c)return i.logger.warn("Ed25519 key for device "+r+":"+o+" has changed"),!1}else t[o]=h=new a.DeviceInfo(o);return h.keys=n.keys||{},h.algorithms=n.algorithms||[],h.unsigned=l,h.signatures=d,!0}},70636:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.EncryptionSetupOperation=t.EncryptionSetupBuilder=void 0;var o=n(7434),r=n(24369),i=n(17187),a=n(3075),s=n(57585),u=n(17715);t.EncryptionSetupBuilder=class{constructor(e,t){this.accountDataClientAdapter=new l(e),this.crossSigningCallbacks=new d,this.ssssCryptoCallbacks=new h(t),this._crossSigningKeys=null,this._keySignatures=null,this._keyBackupInfo=null}addCrossSigningKeys(e,t){this._crossSigningKeys={authUpload:e,keys:t}}addSessionBackup(e){this._keyBackupInfo=e}addSessionBackupPrivateKeyToCache(e){this._sessionBackupPrivateKey=e}addKeySignature(e,t,n){this._keySignatures||(this._keySignatures={});const o=this._keySignatures[e]||{};this._keySignatures[e]=o,o[t]=n}setAccountData(e,t){return this.accountDataClientAdapter.setAccountData(e,t)}buildOperation(){const e=this.accountDataClientAdapter._values;return new c(e,this._crossSigningKeys,this._keyBackupInfo,this._keySignatures)}async persist(e){if(this._crossSigningKeys){const t=(0,a.createCryptoStoreCacheCallbacks)(e._cryptoStore,e._olmDevice);for(const e of["master","self_signing","user_signing"]){o.logger.log(`Cache ${e} cross-signing private key locally`);const n=this.crossSigningCallbacks.privateKeys.get(e);await t.storeCrossSigningKeyCache(e,n)}await e._cryptoStore.doTxn("readwrite",[s.IndexedDBCryptoStore.STORE_ACCOUNT],(t=>{e._cryptoStore.storeCrossSigningKeys(t,this._crossSigningKeys.keys)}))}this._sessionBackupPrivateKey&&await e.storeSessionBackupPrivateKey(this._sessionBackupPrivateKey)}};class c{constructor(e,t,n,o){this._accountData=e,this._crossSigningKeys=t,this._keyBackupInfo=n,this._keySignatures=o}async apply(e){const t=e._baseApis;if(this._crossSigningKeys){const n={};for(const[e,t]of Object.entries(this._crossSigningKeys.keys))n[e+"_key"]=t;await this._crossSigningKeys.authUpload((e=>t.uploadDeviceSigningKeys(e,n))),e._crossSigningInfo.setKeys(this._crossSigningKeys.keys)}if(this._accountData)for(const[e,n]of this._accountData)await t.setAccountData(e,n);this._keySignatures&&await t.uploadKeySignatures(this._keySignatures),this._keyBackupInfo&&(this._keyBackupInfo.version?await t._http.authedRequest(void 0,"PUT","/room_keys/version/"+this._keyBackupInfo.version,void 0,{algorithm:this._keyBackupInfo.algorithm,auth_data:this._keyBackupInfo.auth_data},{prefix:u.PREFIX_UNSTABLE}):await t._http.authedRequest(void 0,"POST","/room_keys/version",void 0,this._keyBackupInfo,{prefix:u.PREFIX_UNSTABLE}))}}t.EncryptionSetupOperation=c;class l extends i.EventEmitter{constructor(e){super(),this._existingValues=e,this._values=new Map}getAccountDataFromServer(e){return Promise.resolve(this.getAccountData(e))}getAccountData(e){const t=this._values.get(e);if(t)return t;const n=this._existingValues[e];return n?n.getContent():null}setAccountData(e,t){const n=this._values.get(e);return this._values.set(e,t),Promise.resolve().then((()=>{const o=new r.MatrixEvent({type:e,content:t});this.emit("accountData",o,n)}))}}class d{constructor(){this.privateKeys=new Map}getCrossSigningKeyCache(e,t){return this.getCrossSigningKey(e,t)}storeCrossSigningKeyCache(e,t){return this.privateKeys.set(e,t),Promise.resolve()}getCrossSigningKey(e,t){return Promise.resolve(this.privateKeys.get(e))}saveCrossSigningKeys(e){for(const[t,n]of Object.entries(e))this.privateKeys.set(t,n)}}class h{constructor(e){this._privateKeys=new Map,this._delegateCryptoCallbacks=e}async getSecretStorageKey({keys:e},t){for(const t of Object.keys(e)){const e=this._privateKeys.get(t);if(e)return[t,e]}if(this._delegateCryptoCallbacks){const n=await this._delegateCryptoCallbacks.getSecretStorageKey({keys:e},t);if(n){const[e,t]=n;this._privateKeys.set(e,t)}return n}}addPrivateKey(e,t,n){this._privateKeys.set(e,n),this._delegateCryptoCallbacks&&this._delegateCryptoCallbacks.cacheSecretStorageKey&&this._delegateCryptoCallbacks.cacheSecretStorageKey(e,t,n)}}},72573:(e,t,n)=>{"use strict";var o=n(20862);Object.defineProperty(t,"__esModule",{value:!0}),t.OlmDevice=u,t.WITHHELD_MESSAGES=void 0;var r=n(7434),i=n(57585),a=o(n(91994));function s(e){if(void 0===e)throw new Error("payloadString undefined");if(e.length>49152){const t=new Error("Message too long ("+e.length+" bytes). The maximum for an encrypted message is 49152 bytes.");throw t.data={errcode:"M_TOO_LARGE",error:"Payload too large for encrypted message"},t}}function u(e){this._cryptoStore=e,this._pickleKey="DEFAULT_KEY",this.deviceCurve25519Key=null,this.deviceEd25519Key=null,this._maxOneTimeKeys=null,this._outboundGroupSessionStore={},this._inboundGroupSessionMessageIndexes={},this._sessionsInProgress={},this._olmPrekeyPromise=Promise.resolve()}u.prototype.init=async function(e={}){let t;const o=new n.g.Olm.Account,{pickleKey:a,fromExportedDevice:s}=e;try{s?(a&&r.logger.warn("ignoring opts.pickleKey because opts.fromExportedDevice is present."),this._pickleKey=s.pickleKey,await async function(e,t,n,o){await t.doTxn("readwrite",[i.IndexedDBCryptoStore.STORE_ACCOUNT,i.IndexedDBCryptoStore.STORE_SESSIONS],(n=>{t.storeAccount(n,e.pickledAccount),e.sessions.forEach((e=>{const{deviceKey:o,sessionId:r}=e,i={session:e.session,lastReceivedMessageTs:e.lastReceivedMessageTs};t.storeEndToEndSession(o,r,i,n)}))})),o.unpickle(n,e.pickledAccount)}(s,this._cryptoStore,this._pickleKey,o)):(a&&(this._pickleKey=a),await async function(e,t,n){await e.doTxn("readwrite",[i.IndexedDBCryptoStore.STORE_ACCOUNT],(o=>{e.getAccount(o,(r=>{null!==r?n.unpickle(t,r):(n.create(),r=n.pickle(t),e.storeAccount(o,r))}))}))}(this._cryptoStore,this._pickleKey,o)),t=JSON.parse(o.identity_keys()),this._maxOneTimeKeys=o.max_number_of_one_time_keys()}finally{o.free()}this.deviceCurve25519Key=t.curve25519,this.deviceEd25519Key=t.ed25519},u.getOlmVersion=function(){return n.g.Olm.get_library_version()},u.prototype._getAccount=function(e,t){this._cryptoStore.getAccount(e,(e=>{const o=new n.g.Olm.Account;try{o.unpickle(this._pickleKey,e),t(o)}finally{o.free()}}))},u.prototype._storeAccount=function(e,t){this._cryptoStore.storeAccount(e,t.pickle(this._pickleKey))},u.prototype.export=async function(){const e={pickleKey:this._pickleKey};return await this._cryptoStore.doTxn("readonly",[i.IndexedDBCryptoStore.STORE_ACCOUNT,i.IndexedDBCryptoStore.STORE_SESSIONS],(t=>{this._cryptoStore.getAccount(t,(t=>{e.pickledAccount=t})),e.sessions=[],this._cryptoStore.getAllEndToEndSessions(t,(t=>{e.sessions.push(t)}))})),e},u.prototype._getSession=function(e,t,n,o){this._cryptoStore.getEndToEndSession(e,t,n,(e=>{this._unpickleSession(e,o)}))},u.prototype._unpickleSession=function(e,t){const o=new n.g.Olm.Session;try{o.unpickle(this._pickleKey,e.session),t(Object.assign({},e,{session:o}))}finally{o.free()}},u.prototype._saveSession=function(e,t,n){const o=t.session.session_id(),r=Object.assign(t,{session:t.session.pickle(this._pickleKey)});this._cryptoStore.storeEndToEndSession(e,o,r,n)},u.prototype._getUtility=function(e){const t=new n.g.Olm.Utility;try{return e(t)}finally{t.free()}},u.prototype.sign=async function(e){let t;return await this._cryptoStore.doTxn("readonly",[i.IndexedDBCryptoStore.STORE_ACCOUNT],(n=>{this._getAccount(n,(n=>{t=n.sign(e)}))})),t},u.prototype.getOneTimeKeys=async function(){let e;return await this._cryptoStore.doTxn("readonly",[i.IndexedDBCryptoStore.STORE_ACCOUNT],(t=>{this._getAccount(t,(t=>{e=JSON.parse(t.one_time_keys())}))})),e},u.prototype.maxNumberOfOneTimeKeys=function(){return this._maxOneTimeKeys},u.prototype.markKeysAsPublished=async function(){await this._cryptoStore.doTxn("readwrite",[i.IndexedDBCryptoStore.STORE_ACCOUNT],(e=>{this._getAccount(e,(t=>{t.mark_keys_as_published(),this._storeAccount(e,t)}))}))},u.prototype.generateOneTimeKeys=function(e){return this._cryptoStore.doTxn("readwrite",[i.IndexedDBCryptoStore.STORE_ACCOUNT],(t=>{this._getAccount(t,(n=>{n.generate_one_time_keys(e),this._storeAccount(t,n)}))}))},u.prototype.generateFallbackKey=async function(){await this._cryptoStore.doTxn("readwrite",[i.IndexedDBCryptoStore.STORE_ACCOUNT],(e=>{this._getAccount(e,(t=>{t.generate_fallback_key(),this._storeAccount(e,t)}))}))},u.prototype.getFallbackKey=async function(){let e;return await this._cryptoStore.doTxn("readonly",[i.IndexedDBCryptoStore.STORE_ACCOUNT],(t=>{this._getAccount(t,(t=>{e=JSON.parse(t.fallback_key())}))})),e},u.prototype.createOutboundSession=async function(e,t){let o;return await this._cryptoStore.doTxn("readwrite",[i.IndexedDBCryptoStore.STORE_ACCOUNT,i.IndexedDBCryptoStore.STORE_SESSIONS],(r=>{this._getAccount(r,(i=>{const a=new n.g.Olm.Session;try{a.create_outbound(i,e,t),o=a.session_id(),this._storeAccount(r,i);const n={session:a,lastReceivedMessageTs:Date.now()};this._saveSession(e,n,r)}finally{a.free()}}))}),r.logger.withPrefix("[createOutboundSession]")),o},u.prototype.createInboundSession=async function(e,t,o){if(0!==t)throw new Error("Need messageType == 0 to create inbound session");let a;return await this._cryptoStore.doTxn("readwrite",[i.IndexedDBCryptoStore.STORE_ACCOUNT,i.IndexedDBCryptoStore.STORE_SESSIONS],(r=>{this._getAccount(r,(i=>{const s=new n.g.Olm.Session;try{s.create_inbound_from(i,e,o),i.remove_one_time_keys(s),this._storeAccount(r,i);const n=s.decrypt(t,o),u={session:s,lastReceivedMessageTs:Date.now()};this._saveSession(e,u,r),a={payload:n,session_id:s.session_id()}}finally{s.free()}}))}),r.logger.withPrefix("[createInboundSession]")),a},u.prototype.getSessionIdsForDevice=async function(e){const t=r.logger.withPrefix("[getSessionIdsForDevice]");if(this._sessionsInProgress[e]){t.debug(`Waiting for Olm session for ${e} to be created`);try{await this._sessionsInProgress[e]}catch(e){}}let n;return await this._cryptoStore.doTxn("readonly",[i.IndexedDBCryptoStore.STORE_SESSIONS],(t=>{this._cryptoStore.getEndToEndSessions(e,t,(e=>{n=Object.keys(e)}))}),t),n},u.prototype.getSessionIdForDevice=async function(e,t,n){const o=await this.getSessionInfoForDevice(e,t,n);if(0===o.length)return null;let r=0;for(let e=1;ea||n===a&&t.sessionId{this._cryptoStore.getEndToEndSessions(e,t,(e=>{const t=Object.keys(e).sort();for(const n of t)this._unpickleSession(e[n],(e=>{o.push({lastReceivedMessageTs:e.lastReceivedMessageTs,hasReceivedMessage:e.session.has_received_message(),sessionId:n})}))}))}),n),o},u.prototype.encryptMessage=async function(e,t,n){let o;return s(n),await this._cryptoStore.doTxn("readwrite",[i.IndexedDBCryptoStore.STORE_SESSIONS],(i=>{this._getSession(e,t,i,(a=>{const s=a.session.describe();r.logger.log("encryptMessage: Olm Session ID "+t+" to "+e+": "+s),o=a.session.encrypt(n),this._saveSession(e,a,i)}))}),r.logger.withPrefix("[encryptMessage]")),o},u.prototype.decryptMessage=async function(e,t,n,o){let a;return await this._cryptoStore.doTxn("readwrite",[i.IndexedDBCryptoStore.STORE_SESSIONS],(i=>{this._getSession(e,t,i,(s=>{const u=s.session.describe();r.logger.log("decryptMessage: Olm Session ID "+t+" from "+e+": "+u),a=s.session.decrypt(n,o),s.lastReceivedMessageTs=Date.now(),this._saveSession(e,s,i)}))}),r.logger.withPrefix("[decryptMessage]")),a},u.prototype.matchesSession=async function(e,t,n,o){if(0!==n)return!1;let a;return await this._cryptoStore.doTxn("readonly",[i.IndexedDBCryptoStore.STORE_SESSIONS],(n=>{this._getSession(e,t,n,(e=>{a=e.session.matches_inbound(o)}))}),r.logger.withPrefix("[matchesSession]")),a},u.prototype.recordSessionProblem=async function(e,t,n){await this._cryptoStore.storeEndToEndSessionProblem(e,t,n)},u.prototype.sessionMayHaveProblems=async function(e,t){return await this._cryptoStore.getEndToEndSessionProblem(e,t)},u.prototype.filterOutNotifiedErrorDevices=async function(e){return await this._cryptoStore.filterOutNotifiedErrorDevices(e)},u.prototype._saveOutboundGroupSession=function(e){const t=e.pickle(this._pickleKey);this._outboundGroupSessionStore[e.session_id()]=t},u.prototype._getOutboundGroupSession=function(e,t){const o=this._outboundGroupSessionStore[e];if(void 0===o)throw new Error("Unknown outbound group session "+e);const r=new n.g.Olm.OutboundGroupSession;try{return r.unpickle(this._pickleKey,o),t(r)}finally{r.free()}},u.prototype.createOutboundGroupSession=function(){const e=new n.g.Olm.OutboundGroupSession;try{return e.create(),this._saveOutboundGroupSession(e),e.session_id()}finally{e.free()}},u.prototype.encryptGroupMessage=function(e,t){const n=this;return r.logger.log(`encrypting msg with megolm session ${e}`),s(t),this._getOutboundGroupSession(e,(function(e){const o=e.encrypt(t);return n._saveOutboundGroupSession(e),o}))},u.prototype.getOutboundGroupSessionKey=function(e){return this._getOutboundGroupSession(e,(function(e){return{chain_index:e.message_index(),key:e.session_key()}}))},u.prototype._unpickleInboundGroupSession=function(e,t){const o=new n.g.Olm.InboundGroupSession;try{return o.unpickle(this._pickleKey,e.session),t(o)}finally{o.free()}},u.prototype._getInboundGroupSession=function(e,t,n,o,r){this._cryptoStore.getEndToEndInboundGroupSession(t,n,o,((t,n)=>{if(null!==t){if(null!==e&&e!==t.room_id)throw new Error("Mismatched room_id for inbound group session (expected "+t.room_id+", was "+e+")");this._unpickleInboundGroupSession(t,(e=>{r(e,t,n)}))}else r(null,null,n)}))},u.prototype.addInboundGroupSession=async function(e,t,o,a,s,u,c,l={}){await this._cryptoStore.doTxn("readwrite",[i.IndexedDBCryptoStore.STORE_INBOUND_GROUP_SESSIONS,i.IndexedDBCryptoStore.STORE_INBOUND_GROUP_SESSIONS_WITHHELD,i.IndexedDBCryptoStore.STORE_SHARED_HISTORY_INBOUND_GROUP_SESSIONS],(i=>{this._getInboundGroupSession(e,t,a,i,((d,h)=>{const p=new n.g.Olm.InboundGroupSession;try{if(c?p.import_session(s):p.create(s),a!=p.session_id())throw new Error("Mismatched group session ID from senderKey: "+t);if(d&&(r.logger.log("Update for megolm session "+t+"/"+a),d.first_known_index()<=p.first_known_index()&&(d.first_known_index()!=p.first_known_index()||l.untrusted||!h.untrusted)))return void r.logger.log(`Keeping existing megolm session ${a}`);r.logger.info("Storing megolm session "+t+"/"+a+" with first index "+p.first_known_index());const n=Object.assign({},l,{room_id:e,session:p.pickle(this._pickleKey),keysClaimed:u,forwardingCurve25519KeyChain:o});this._cryptoStore.storeEndToEndInboundGroupSession(t,a,n,i),!d&&l.sharedHistory&&this._cryptoStore.addSharedHistoryInboundGroupSession(e,t,a,i)}finally{p.free()}}))}),r.logger.withPrefix("[addInboundGroupSession]"))},u.prototype.addInboundGroupSessionWithheld=async function(e,t,n,o,r){await this._cryptoStore.doTxn("readwrite",[i.IndexedDBCryptoStore.STORE_INBOUND_GROUP_SESSIONS_WITHHELD],(i=>{this._cryptoStore.storeEndToEndInboundGroupSessionWithheld(t,n,{room_id:e,code:o,reason:r},i)}))};const c={"m.unverified":"The sender has disabled encrypting to unverified devices.","m.blacklisted":"The sender has blocked you.","m.unauthorised":"You are not authorised to read the message.","m.no_olm":"Unable to establish a secure channel."};function l(e){return e.code&&e.code in c?c[e.code]:e.reason?e.reason:"decryption key withheld"}t.WITHHELD_MESSAGES=c,u.prototype.decryptGroupMessage=async function(e,t,n,o,s,u){let c,d;if(await this._cryptoStore.doTxn("readwrite",[i.IndexedDBCryptoStore.STORE_INBOUND_GROUP_SESSIONS,i.IndexedDBCryptoStore.STORE_INBOUND_GROUP_SESSIONS_WITHHELD],(r=>{this._getInboundGroupSession(e,t,n,r,((e,i,h)=>{if(null===e)return h&&(d=new a.DecryptionError("MEGOLM_UNKNOWN_INBOUND_SESSION_ID",l(h),{session:t+"|"+n})),void(c=null);let p;try{p=e.decrypt(o)}catch(e){return void(d=e&&"OLM.UNKNOWN_MESSAGE_INDEX"===e.message&&h?new a.DecryptionError("MEGOLM_UNKNOWN_INBOUND_SESSION_ID",l(h),{session:t+"|"+n}):e)}let f=p.plaintext;if(void 0===f)f=p;else{const e=t+"|"+n+"|"+p.message_index;if(e in this._inboundGroupSessionMessageIndexes){const t=this._inboundGroupSessionMessageIndexes[e];if(t.id!==s||t.timestamp!==u)return void(d=new Error("Duplicate message index, possible replay attack: "+e))}this._inboundGroupSessionMessageIndexes[e]={id:s,timestamp:u}}i.session=e.pickle(this._pickleKey),this._cryptoStore.storeEndToEndInboundGroupSession(t,n,i,r),c={result:f,keysClaimed:i.keysClaimed||{},senderKey:t,forwardingCurve25519KeyChain:i.forwardingCurve25519KeyChain||[],untrusted:i.untrusted}}))}),r.logger.withPrefix("[decryptGroupMessage]")),d)throw d;return c},u.prototype.hasInboundSessionKeys=async function(e,t,n){let o;return await this._cryptoStore.doTxn("readonly",[i.IndexedDBCryptoStore.STORE_INBOUND_GROUP_SESSIONS,i.IndexedDBCryptoStore.STORE_INBOUND_GROUP_SESSIONS_WITHHELD],(i=>{this._cryptoStore.getEndToEndInboundGroupSession(t,n,i,(i=>{null!==i?e!==i.room_id?(r.logger.warn(`requested keys for inbound group session ${t}|${n}, with incorrect room_id (expected ${i.room_id}, was ${e})`),o=!1):o=!0:o=!1}))}),r.logger.withPrefix("[hasInboundSessionKeys]")),o},u.prototype.getInboundGroupSessionKey=async function(e,t,n,o){let a;return await this._cryptoStore.doTxn("readonly",[i.IndexedDBCryptoStore.STORE_INBOUND_GROUP_SESSIONS,i.IndexedDBCryptoStore.STORE_INBOUND_GROUP_SESSIONS_WITHHELD],(r=>{this._getInboundGroupSession(e,t,n,r,((e,t)=>{if(null===e)return void(a=null);void 0===o&&(o=e.first_known_index());const n=e.export_session(o),r=(t.keysClaimed||{}).ed25519||null;a={chain_index:o,key:n,forwarding_curve25519_key_chain:t.forwardingCurve25519KeyChain||[],sender_claimed_ed25519_key:r,shared_history:t.sharedHistory||!1}}))}),r.logger.withPrefix("[getInboundGroupSessionKey]")),a},u.prototype.exportInboundGroupSession=function(e,t,n){return this._unpickleInboundGroupSession(n,(o=>{const r=o.first_known_index();return{sender_key:e,sender_claimed_keys:n.keysClaimed,room_id:n.room_id,session_id:t,session_key:o.export_session(r),forwarding_curve25519_key_chain:o.forwardingCurve25519KeyChain||[],first_known_index:o.first_known_index(),"org.matrix.msc3061.shared_history":n.sharedHistory||!1}}))},u.prototype.getSharedHistoryInboundGroupSessions=async function(e){let t;return await this._cryptoStore.doTxn("readonly",[i.IndexedDBCryptoStore.STORE_SHARED_HISTORY_INBOUND_GROUP_SESSIONS],(n=>{t=this._cryptoStore.getSharedHistoryInboundGroupSessions(e,n)}),r.logger.withPrefix("[getSharedHistoryInboundGroupSessionsForRoom]")),t},u.prototype.verifySignature=function(e,t,n){this._getUtility((function(o){o.ed25519_verify(e,t,n)}))}},66617:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.OutgoingRoomKeyRequestManager=t.ROOM_KEY_REQUEST_STATES=void 0;var o=n(7434);const r={UNSENT:0,SENT:1,CANCELLATION_PENDING:2,CANCELLATION_PENDING_AND_WILL_RESEND:3};function i(e){return e.room_id+" / "+e.session_id}function a(e){return"["+e.map((e=>`${e.userId}:${e.deviceId}`)).join(",")+"]"}t.ROOM_KEY_REQUEST_STATES=r,t.OutgoingRoomKeyRequestManager=class{constructor(e,t,n){this._baseApis=e,this._deviceId=t,this._cryptoStore=n,this._sendOutgoingRoomKeyRequestsTimer=null,this._sendOutgoingRoomKeyRequestsRunning=!1,this._clientRunning=!1}start(){this._clientRunning=!0}stop(){o.logger.log("stopping OutgoingRoomKeyRequestManager"),this._clientRunning=!1}sendQueuedRequests(){this._startTimer()}async queueRoomKeyRequest(e,t,n=!1){const i=await this._cryptoStore.getOutgoingRoomKeyRequest(e);if(i)switch(i.state){case r.CANCELLATION_PENDING_AND_WILL_RESEND:case r.UNSENT:return;case r.CANCELLATION_PENDING:{const e=n?r.CANCELLATION_PENDING_AND_WILL_RESEND:r.SENT;await this._cryptoStore.updateOutgoingRoomKeyRequest(i.requestId,r.CANCELLATION_PENDING,{state:e,cancellationTxnId:this._baseApis.makeTxnId()});break}case r.SENT:if(n){const a=r.CANCELLATION_PENDING_AND_WILL_RESEND,s=await this._cryptoStore.updateOutgoingRoomKeyRequest(i.requestId,r.SENT,{state:a,cancellationTxnId:this._baseApis.makeTxnId(),requestTxnId:this._baseApis.makeTxnId()});if(!s)return await this.queueRoomKeyRequest(e,t,n);try{await this._sendOutgoingRoomKeyRequestCancellation(s,!0)}catch(e){o.logger.error("Error sending room key request cancellation; will retry later.",e)}}break;default:throw new Error("unhandled state: "+i.state)}else await this._cryptoStore.getOrAddOutgoingRoomKeyRequest({requestBody:e,recipients:t,requestId:this._baseApis.makeTxnId(),state:r.UNSENT})}cancelRoomKeyRequest(e){return this._cryptoStore.getOutgoingRoomKeyRequest(e).then((t=>{if(t)switch(t.state){case r.CANCELLATION_PENDING:case r.CANCELLATION_PENDING_AND_WILL_RESEND:return;case r.UNSENT:return o.logger.log("deleting unnecessary room key request for "+i(e)),this._cryptoStore.deleteOutgoingRoomKeyRequest(t.requestId,r.UNSENT);case r.SENT:return this._cryptoStore.updateOutgoingRoomKeyRequest(t.requestId,r.SENT,{state:r.CANCELLATION_PENDING,cancellationTxnId:this._baseApis.makeTxnId()}).then((t=>{t?this._sendOutgoingRoomKeyRequestCancellation(t).catch((e=>{o.logger.error("Error sending room key request cancellation; will retry later.",e),this._startTimer()})):o.logger.log("Tried to cancel room key request for "+i(e)+" but it was already cancelled in another tab")}));default:throw new Error("unhandled state: "+t.state)}}))}getOutgoingSentRoomKeyRequest(e,t){return this._cryptoStore.getOutgoingRoomKeyRequestsByTarget(e,t,[r.SENT])}async cancelAndResendAllOutgoingRequests(){const e=await this._cryptoStore.getAllOutgoingRoomKeyRequestsByState(r.SENT);return Promise.all(e.map((({requestBody:e,recipients:t})=>this.queueRoomKeyRequest(e,t,!0))))}_startTimer(){this._sendOutgoingRoomKeyRequestsTimer||(this._sendOutgoingRoomKeyRequestsTimer=n.g.setTimeout((()=>{if(this._sendOutgoingRoomKeyRequestsRunning)throw new Error("RoomKeyRequestSend already in progress!");this._sendOutgoingRoomKeyRequestsRunning=!0,this._sendOutgoingRoomKeyRequests().finally((()=>{this._sendOutgoingRoomKeyRequestsRunning=!1})).catch((e=>{o.logger.warn(`error in OutgoingRoomKeyRequestManager: ${e}`)}))}),500))}_sendOutgoingRoomKeyRequests(){return this._clientRunning?this._cryptoStore.getOutgoingRoomKeyRequestByState([r.CANCELLATION_PENDING,r.CANCELLATION_PENDING_AND_WILL_RESEND,r.UNSENT]).then((e=>{if(!e)return void(this._sendOutgoingRoomKeyRequestsTimer=null);let t;switch(e.state){case r.UNSENT:t=this._sendOutgoingRoomKeyRequest(e);break;case r.CANCELLATION_PENDING:t=this._sendOutgoingRoomKeyRequestCancellation(e);break;case r.CANCELLATION_PENDING_AND_WILL_RESEND:t=this._sendOutgoingRoomKeyRequestCancellation(e,!0)}return t.then((()=>this._sendOutgoingRoomKeyRequests())).catch((e=>{o.logger.error("Error sending room key request; will retry later.",e),this._sendOutgoingRoomKeyRequestsTimer=null}))})):(this._sendOutgoingRoomKeyRequestsTimer=null,Promise.resolve())}_sendOutgoingRoomKeyRequest(e){o.logger.log(`Requesting keys for ${i(e.requestBody)} from ${a(e.recipients)}(id ${e.requestId})`);const t={action:"request",requesting_device_id:this._deviceId,request_id:e.requestId,body:e.requestBody};return this._sendMessageToDevices(t,e.recipients,e.requestTxnId||e.requestId).then((()=>this._cryptoStore.updateOutgoingRoomKeyRequest(e.requestId,r.UNSENT,{state:r.SENT})))}_sendOutgoingRoomKeyRequestCancellation(e,t){o.logger.log(`Sending cancellation for key request for ${i(e.requestBody)} to ${a(e.recipients)} (cancellation id ${e.cancellationTxnId})`);const n={action:"request_cancellation",requesting_device_id:this._deviceId,request_id:e.requestId};return this._sendMessageToDevices(n,e.recipients,e.cancellationTxnId).then((()=>t?this._cryptoStore.updateOutgoingRoomKeyRequest(e.requestId,r.CANCELLATION_PENDING_AND_WILL_RESEND,{state:r.UNSENT}):this._cryptoStore.deleteOutgoingRoomKeyRequest(e.requestId,r.CANCELLATION_PENDING)))}_sendMessageToDevices(e,t,n){const o={};for(const n of t)o[n.userId]||(o[n.userId]={}),o[n.userId][n.deviceId]=e;return this._baseApis.sendToDevice("m.room_key_request",o,n)}}},40635:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.RoomList=void 0;var o=n(57585);t.RoomList=class{constructor(e){this._cryptoStore=e,this._roomEncryption={}}async init(){await this._cryptoStore.doTxn("readwrite",[o.IndexedDBCryptoStore.STORE_ROOMS],(e=>{this._cryptoStore.getEndToEndRooms(e,(e=>{this._roomEncryption=e}))}))}getRoomEncryption(e){return this._roomEncryption[e]||null}isRoomEncrypted(e){return Boolean(this.getRoomEncryption(e))}async setRoomEncryption(e,t){this._roomEncryption[e]=t,await this._cryptoStore.doTxn("readwrite",[o.IndexedDBCryptoStore.STORE_ROOMS],(n=>{this._cryptoStore.storeEndToEndRoom(e,t,n)}))}}},44823:(e,t,n)=>{"use strict";var o=n(20862);Object.defineProperty(t,"__esModule",{value:!0}),t.SecretStorage=t.SECRET_STORAGE_ALGORITHM_V1_AES=void 0;var r=n(17187),i=n(7434),a=o(n(32772)),s=n(98401),u=n(2611);const c="m.secret_storage.v1.aes-hmac-sha2";t.SECRET_STORAGE_ALGORITHM_V1_AES=c;class l extends r.EventEmitter{constructor(e,t){super(),this._baseApis=e,this._cryptoCallbacks=t,this._requests={},this._incomingRequests={}}async getDefaultKeyId(){const e=await this._baseApis.getAccountDataFromServer("m.secret_storage.default_key");return e?e.key:null}setDefaultKeyId(e){return new Promise((async(t,n)=>{const o=n=>{"m.secret_storage.default_key"===n.getType()&&n.getContent().key===e&&(this._baseApis.removeListener("accountData",o),t())};this._baseApis.on("accountData",o);try{await this._baseApis.setAccountData("m.secret_storage.default_key",{key:e})}catch(e){this._baseApis.removeListener("accountData",o),n(e)}}))}async addKey(e,t,n){const o={algorithm:e};if(t||(t={}),t.name&&(o.name=t.name),e!==c)throw new Error(`Unknown key algorithm ${t.algorithm}`);if(t.passphrase&&(o.passphrase=t.passphrase),t.key){const{iv:e,mac:n}=await l._calculateKeyCheck(t.key);o.iv=e,o.mac=n}if(!n)do{n=(0,s.randomString)(32)}while(await this._baseApis.getAccountDataFromServer(`m.secret_storage.key.${n}`));return await this._baseApis.setAccountData(`m.secret_storage.key.${n}`,o),{keyId:n,keyInfo:o}}async getKey(e){if(e||(e=await this.getDefaultKeyId()),!e)return null;const t=await this._baseApis.getAccountDataFromServer("m.secret_storage.key."+e);return t?[e,t]:null}async hasKey(e){return!!await this.getKey(e)}async checkKey(e,t){if(t.algorithm===c){if(t.mac){const{mac:n}=await l._calculateKeyCheck(e,t.iv);return t.mac.replace(/=+$/g,"")===n.replace(/=+$/g,"")}return!0}throw new Error("Unknown algorithm")}static async _calculateKeyCheck(e,t){return await(0,u.encryptAES)("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0",e,"",t)}async store(e,t,n){const o={};if(!n){const e=await this.getDefaultKeyId();if(!e)throw new Error("No keys specified and no default key present");n=[e]}if(0===n.length)throw new Error("Zero keys given to encrypt with!");for(const r of n){const n=await this._baseApis.getAccountDataFromServer("m.secret_storage.key."+r);if(!n)throw new Error("Unknown key: "+r);if(n.algorithm===c){const i={[r]:n},[,a]=await this._getSecretStorageKey(i,e);o[r]=await a.encrypt(t)}else i.logger.warn("unknown algorithm for secret storage key "+r+": "+n.algorithm)}await this._baseApis.setAccountData(e,{encrypted:o})}async _fixupStoredSecret(e,t){const n=Object.keys(t);return 1===n.length&&"encrypted"!==n[0]&&t[n[0]].passthrough&&await this.hasKey(n[0])?(i.logger.log("Fixing up passthrough secret: "+e),await this.storePassthrough(e,n[0]),await this._baseApis.getAccountDataFromServer(e)):null}async get(e){let t=await this._baseApis.getAccountDataFromServer(e);if(!t)return;if(!t.encrypted&&(t=await this._fixupStoredSecret(e,t),!t||!t.encrypted))throw new Error("Content is not encrypted!");const n={};for(const e of Object.keys(t.encrypted)){const o=await this._baseApis.getAccountDataFromServer("m.secret_storage.key."+e),r=t.encrypted[e];o.algorithm===c&&r.iv&&r.ciphertext&&r.mac&&(n[e]=o)}if(0===Object.keys(n).length)throw new Error(`Could not decrypt ${e} because none of the keys it is encrypted with are for a supported algorithm`);let o,r;try{[o,r]=await this._getSecretStorageKey(n,e);const i=t.encrypted[o];return i.passthrough?(0,a.encodeBase64)(r.get_private_key()):await r.decrypt(i)}finally{r&&r.free&&r.free()}}async isStored(e,t){let n=await this._baseApis.getAccountDataFromServer(e);if(!n)return null;if(!n.encrypted&&(n=await this._fixupStoredSecret(e,n),!n||!n.encrypted))return null;void 0===t&&(t=!0);const o={};for(const e of Object.keys(n.encrypted)){const t=await this._baseApis.getAccountDataFromServer("m.secret_storage.key."+e);if(!t)continue;const r=n.encrypted[e];t.algorithm===c&&r.iv&&r.ciphertext&&r.mac&&(o[e]=t)}return Object.keys(o).length?o:null}request(e,t){const n=this._baseApis.makeTxnId(),o=this._requests[n]={name:e,devices:t},r=new Promise(((e,t)=>{o.resolve=e,o.reject=t})),a={name:e,action:"request",requesting_device_id:this._baseApis.deviceId,request_id:n},s={};for(const e of t)s[e]=a;return i.logger.info(`Request secret ${e} from ${t}, id ${n}`),this._baseApis.sendToDevice("m.secret.request",{[this._baseApis.getUserId()]:s}),{request_id:n,promise:r,cancel:e=>{const r={action:"request_cancellation",requesting_device_id:this._baseApis.deviceId,request_id:n},i={};for(const e of t)i[e]=r;this._baseApis.sendToDevice("m.secret.request",{[this._baseApis.getUserId()]:i}),o.reject(new Error(e||"Cancelled"))}}}async _onRequestReceived(e){const t=e.getSender(),n=e.getContent();if(t!==this._baseApis.getUserId()||!(n.name&&n.action&&n.requesting_device_id&&n.request_id))return;const o=n.requesting_device_id;if("request_cancellation"===n.action)this._incomingRequests[o]&&this._incomingRequests[o][n.request_id]&&(i.logger.info("received request cancellation for secret ("+t+", "+o+", "+n.request_id+")"),this.baseApis.emit("crypto.secrets.requestCancelled",{user_id:t,device_id:o,request_id:n.request_id}));else if("request"===n.action){if(o===this._baseApis.deviceId)return;if(i.logger.info("received request for secret ("+t+", "+o+", "+n.request_id+")"),!this._cryptoCallbacks.onSecretRequested)return;const e=await this._cryptoCallbacks.onSecretRequested(t,o,n.request_id,n.name,this._baseApis.checkDeviceTrust(t,o));if(e){i.logger.info(`Preparing ${n.name} secret for ${o}`);const r={type:"m.secret.send",content:{request_id:n.request_id,secret:e}},s={algorithm:a.OLM_ALGORITHM,sender_key:this._baseApis._crypto._olmDevice.deviceCurve25519Key,ciphertext:{}};await a.ensureOlmSessionsForDevices(this._baseApis._crypto._olmDevice,this._baseApis,{[t]:[this._baseApis.getStoredDevice(t,o)]}),await a.encryptMessageForDevice(s.ciphertext,this._baseApis.getUserId(),this._baseApis.deviceId,this._baseApis._crypto._olmDevice,t,this._baseApis.getStoredDevice(t,o),r);const u={[t]:{[o]:s}};i.logger.info(`Sending ${n.name} secret for ${o}`),this._baseApis.sendToDevice("m.room.encrypted",u)}else i.logger.info(`Request denied for ${n.name} secret for ${o}`)}}_onSecretReceived(e){if(e.getSender()!==this._baseApis.getUserId())return;const t=e.getContent();i.logger.log("got secret share for request",t.request_id);const n=this._requests[t.request_id];if(n){const o=this._baseApis._crypto._deviceList.getDeviceByIdentityKey(a.OLM_ALGORITHM,e.getSenderKey());if(!o)return void i.logger.log("secret share from unknown device with key",e.getSenderKey());if(!n.devices.includes(o.deviceId))return void i.logger.log("unsolicited secret share from device",o.deviceId);i.logger.log(`Successfully received secret ${n.name} from ${o.deviceId}`),n.resolve(t.secret)}}async _getSecretStorageKey(e,t){if(!this._cryptoCallbacks.getSecretStorageKey)throw new Error("No getSecretStorageKey callback supplied");const n=await this._cryptoCallbacks.getSecretStorageKey({keys:e},t);if(!n)throw new Error("getSecretStorageKey callback returned falsey");if(n.length<2)throw new Error("getSecretStorageKey callback returned invalid data");const[o,r]=n;if(!e[o])throw new Error("App returned unknown key from getSecretStorageKey!");if(e[o].algorithm===c)return[o,{encrypt:async function(e){return await(0,u.encryptAES)(e,r,t)},decrypt:async function(e){return await(0,u.decryptAES)(e,r,t)}}];throw new Error("Unknown key type: "+e[o].algorithm)}}t.SecretStorage=l},2611:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.encryptAES=function(...e){return i?async function(e,t,n,o){let a;o?a=(0,r.decodeBase64)(o):(a=new Uint8Array(16),window.crypto.getRandomValues(a)),a[8]&=127;const[s,c]=await u(t,n),l=(new TextEncoder).encode(e),d=await i.encrypt({name:"AES-CTR",counter:a,length:64},s,l),h=await i.sign({name:"HMAC"},c,d);return{iv:(0,r.encodeBase64)(a),ciphertext:(0,r.encodeBase64)(d),mac:(0,r.encodeBase64)(h)}}(...e):async function(e,t,n,i){const a=(0,o.getCrypto)();if(!a)throw new Error("No usable crypto implementation");let u;u=i?(0,r.decodeBase64)(i):a.randomBytes(16),u[8]&=127;const[c,l]=s(t,n),d=a.createCipheriv("aes-256-ctr",c,u),h=d.update(e,"utf-8","base64")+d.final("base64"),p=a.createHmac("sha256",l).update(h,"base64").digest("base64");return{iv:(0,r.encodeBase64)(u),ciphertext:h,mac:p}}(...e)},t.decryptAES=function(...e){return i?async function(e,t,n){const[o,a]=await u(t,n),s=(0,r.decodeBase64)(e.ciphertext);if(!await i.verify({name:"HMAC"},a,(0,r.decodeBase64)(e.mac),s))throw new Error(`Error decrypting secret ${n}: bad MAC`);const c=await i.decrypt({name:"AES-CTR",counter:(0,r.decodeBase64)(e.iv),length:64},o,s);return(new TextDecoder).decode(new Uint8Array(c))}(...e):async function(e,t,n){const i=(0,o.getCrypto)();if(!i)throw new Error("No usable crypto implementation");const[a,u]=s(t,n);if(i.createHmac("sha256",u).update(e.ciphertext,"base64").digest("base64").replace(/=+$/g,"")!==e.mac.replace(/=+$/g,""))throw new Error(`Error decrypting secret ${n}: bad MAC`);const c=i.createDecipheriv("aes-256-ctr",a,(0,r.decodeBase64)(e.iv));return c.update(e.ciphertext,"base64","utf-8")+c.final("utf-8")}(...e)};var o=n(3102),r=n(32772);const i="undefined"!=typeof window&&window.crypto?window.crypto.subtle||window.crypto.webkitSubtle:null,a=new Uint8Array(8);function s(e,t){const n=(0,o.getCrypto)(),r=n.createHmac("sha256",a).update(e).digest(),i=Buffer.alloc(1,1),s=n.createHmac("sha256",r).update(t,"utf-8").update(i).digest();return i[0]=2,[s,n.createHmac("sha256",r).update(s).update(t,"utf-8").update(i).digest()]}async function u(e,t){const n=await i.importKey("raw",e,{name:"HKDF"},!1,["deriveBits"]),o=await i.deriveBits({name:"HKDF",salt:a,info:(new TextEncoder).encode(t),hash:"SHA-256"},n,512),r=o.slice(0,32),s=o.slice(32),u=i.importKey("raw",r,{name:"AES-CTR"},!1,["encrypt","decrypt"]),c=i.importKey("raw",s,{name:"HMAC",hash:{name:"SHA-256"}},!1,["sign","verify"]);return await Promise.all([u,c])}},21897:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.registerAlgorithm=function(e,t,r){n[e]=t,o[e]=r},t.UnknownDeviceError=t.DecryptionError=t.DecryptionAlgorithm=t.EncryptionAlgorithm=t.DECRYPTION_CLASSES=t.ENCRYPTION_CLASSES=void 0;const n={};t.ENCRYPTION_CLASSES=n;const o={};t.DECRYPTION_CLASSES=o,t.EncryptionAlgorithm=class{constructor(e){this._userId=e.userId,this._deviceId=e.deviceId,this._crypto=e.crypto,this._olmDevice=e.olmDevice,this._baseApis=e.baseApis,this._roomId=e.roomId}prepareToEncrypt(e){}onRoomMembership(e,t,n){}},t.DecryptionAlgorithm=class{constructor(e){this._userId=e.userId,this._crypto=e.crypto,this._olmDevice=e.olmDevice,this._baseApis=e.baseApis,this._roomId=e.roomId}onRoomKeyEvent(e){}importRoomKey(e){}hasKeysForKeyRequest(e){return Promise.resolve(!1)}shareKeysWithDevice(e){throw new Error("shareKeysWithDevice not supported for this DecryptionAlgorithm")}async retryDecryptionFromSender(e){}};class r extends Error{constructor(e,t,n){super(t),this.code=e,this.name="DecryptionError",this.detailedString=function(e,t){let n=e.name+"[msg: "+e.message;return t&&(n+=", "+Object.keys(t).map((e=>e+": "+t[e])).join(", ")),n+="]",n}(this,n)}}t.DecryptionError=r;class i extends Error{constructor(e,t){super(e),this.name="UnknownDeviceError",this.devices=t}}t.UnknownDeviceError=i},91994:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),n(23072),n(17125);var o=n(21897);Object.keys(o).forEach((function(e){"default"!==e&&"__esModule"!==e&&(e in t&&t[e]===o[e]||Object.defineProperty(t,e,{enumerable:!0,get:function(){return o[e]}}))}))},17125:(e,t,n)=>{"use strict";var o=n(20862),r=n(7434),i=o(n(3102)),a=o(n(32772)),s=n(21897),u=n(72573);function c(e,t=!1){this.sessionId=e,this.useCount=0,this.creationTime=(new Date).getTime(),this.sharedWithDevices={},this.blockedDevicesNotified={},this.sharedHistory=t}function l(e){(0,i.polyfillSuper)(this,s.EncryptionAlgorithm,e),this._setupPromise=Promise.resolve(),this._outboundSessions={},this._sessionRotationPeriodMsgs=100,this._sessionRotationPeriodMs=6048e5,void 0!==e.config.rotation_period_ms&&(this._sessionRotationPeriodMs=e.config.rotation_period_ms),void 0!==e.config.rotation_period_msgs&&(this._sessionRotationPeriodMsgs=e.config.rotation_period_msgs)}function d(e){(0,i.polyfillSuper)(this,s.DecryptionAlgorithm,e),this._pendingEvents={},this.olmlib=a}c.prototype.needsRotation=function(e,t){const n=(new Date).getTime()-this.creationTime;return(this.useCount>=e||n>=t)&&(r.logger.log("Rotating megolm session after "+this.useCount+" messages, "+n+"ms"),!0)},c.prototype.markSharedWithDevice=function(e,t,n){this.sharedWithDevices[e]||(this.sharedWithDevices[e]={}),this.sharedWithDevices[e][t]=n},c.prototype.markNotifiedBlockedDevice=function(e,t){this.blockedDevicesNotified[e]||(this.blockedDevicesNotified[e]={}),this.blockedDevicesNotified[e][t]=!0},c.prototype.sharedWithTooManyDevices=function(e){for(const t in this.sharedWithDevices)if(this.sharedWithDevices.hasOwnProperty(t)){if(!e.hasOwnProperty(t))return r.logger.log("Starting new megolm session because we shared with "+t),!0;for(const n in this.sharedWithDevices[t])if(this.sharedWithDevices[t].hasOwnProperty(n)&&!e[t].hasOwnProperty(n))return r.logger.log("Starting new megolm session because we shared with "+t+":"+n),!0}},i.inherits(l,s.EncryptionAlgorithm),l.prototype._ensureOutboundSession=async function(e,t,n,o){let i;function s(){return i}const u=this._setupPromise.then((async s=>{i=s;const u=function(e){const t=e.currentState&&e.currentState.getStateEvents("m.room.history_visibility",""),n=t&&t.getContent()&&t.getContent().history_visibility;return["world_readable","shared"].includes(n)}(e);i&&u!==i.sharedHistory&&(i=null),i&&i.needsRotation(this._sessionRotationPeriodMsgs,this._sessionRotationPeriodMs)&&(r.logger.log("Starting new megolm session because we need to rotate."),i=null),i&&i.sharedWithTooManyDevices(t)&&(i=null),i||(r.logger.log(`Starting new megolm session for room ${this._roomId}`),i=await this._prepareNewSession(u),r.logger.log(`Started new megolm session ${i.sessionId} for room ${this._roomId}`),this._outboundSessions[i.sessionId]=i);const c={};for(const[e,n]of Object.entries(t))for(const[t,o]of Object.entries(n))o.getIdentityKey()!=this._olmDevice.deviceCurve25519Key&&(i.sharedWithDevices[e]&&void 0!==i.sharedWithDevices[e][t]||(c[e]=c[e]||[],c[e].push(o)));const l=this._olmDevice.getOutboundGroupSessionKey(i.sessionId),d={type:"m.room_key",content:{algorithm:a.MEGOLM_ALGORITHM,room_id:this._roomId,session_id:i.sessionId,session_key:l.key,chain_index:l.chain_index,"org.matrix.msc3061.shared_history":u}},[h,p]=await a.getExistingOlmSessions(this._olmDevice,this._baseApis,c);await Promise.all([(async()=>{r.logger.debug(`Sharing keys with existing Olm sessions in ${this._roomId}`),await this._shareKeyWithOlmSessions(i,l,d,p),r.logger.debug(`Shared keys with existing Olm sessions in ${this._roomId}`)})(),(async()=>{r.logger.debug(`Sharing keys (start phase 1) with new Olm sessions in ${this._roomId}`);const e=[],t=Date.now(),n=[];await this._shareKeyWithDevices(i,l,d,h,e,o?1e4:2e3,n),r.logger.debug(`Shared keys (end phase 1) with new Olm sessions in ${this._roomId}`),!o&&Date.now()-t<1e4?(async()=>{const t={},o=new Set;for(const e of n)o.add(e);const a=[];for(const{userId:n,deviceInfo:r}of e){const e=n.slice(n.indexOf(":")+1);o.has(e)?(t[n]=t[n]||[],t[n].push(r)):a.push({userId:n,deviceInfo:r})}r.logger.debug(`Sharing keys (start phase 2) with new Olm sessions in ${this._roomId}`),await this._shareKeyWithDevices(i,l,d,t,a,3e4),r.logger.debug(`Shared keys (end phase 2) with new Olm sessions in ${this._roomId}`),await this._notifyFailedOlmDevices(i,l,a)})():await this._notifyFailedOlmDevices(i,l,e),r.logger.debug(`Shared keys (all phases done) with new Olm sessions in ${this._roomId}`)})(),(async()=>{r.logger.debug(`Notifying blocked devices in ${this._roomId}`);const e={};let t=0;for(const[o,r]of Object.entries(n))for(const[n,a]of Object.entries(r))i.blockedDevicesNotified[o]&&void 0!==i.blockedDevicesNotified[o][n]||(e[o]=e[o]||{},e[o][n]={device:a},t++);await this._notifyBlockedDevices(i,e),r.logger.debug(`Notified ${t} blocked devices in ${this._roomId}`)})()])}));return u.catch((e=>{r.logger.error(`Failed to ensure outbound session in ${this._roomId}`,e)})),this._setupPromise=u.then(s,s),u.then(s)},l.prototype._prepareNewSession=async function(e){const t=this._olmDevice.createOutboundGroupSession(),n=this._olmDevice.getOutboundGroupSessionKey(t);return await this._olmDevice.addInboundGroupSession(this._roomId,this._olmDevice.deviceCurve25519Key,[],t,n.key,{ed25519:this._olmDevice.deviceEd25519Key},!1,{sharedHistory:e}),this._crypto.backupGroupSession(this._roomId,this._olmDevice.deviceCurve25519Key,[],t,n.key),new c(t,e)},l.prototype._getDevicesWithoutSessions=function(e,t,n){n=n||[];for(const[o,r]of Object.entries(t)){const t=e[o];for(const e of r){const r=e.deviceId;t[r].sessionId||(n.push({userId:o,deviceInfo:e}),delete t[r])}}return n},l.prototype._splitDevices=function(e){let t=[];const n=[t];for(const[o,r]of Object.entries(e)){for(const e of Object.values(r))t.push({userId:o,deviceInfo:e.device});t.length>20&&(t=[],n.push(t))}return 0===t.length&&n.pop(),n},l.prototype._encryptAndSendKeysToDevices=function(e,t,n,o){const i={},s=[];for(let e=0;e{for(const e of Object.keys(i)){for(const t of Object.keys(i[e]))0===Object.keys(i[e][t].ciphertext).length&&(r.logger.log("No ciphertext for device "+e+":"+t+": pruning"),delete i[e][t]);0===Object.keys(i[e]).length&&(r.logger.log("Pruned all devices for user "+e),delete i[e])}if(0!==Object.keys(i).length)return this._baseApis.sendToDevice("m.room.encrypted",i).then((()=>{for(const n of Object.keys(i))for(const o of Object.keys(i[n]))e.markSharedWithDevice(n,o,t)}));r.logger.log("No users left to send to: aborting")}))},l.prototype._sendBlockedNotificationsToDevices=async function(e,t,n){const o={};for(const e of t){const t=e.userId,r=e.deviceInfo,i=r.deviceInfo.deviceId,a=Object.assign({},n);a.code=r.code,a.reason=r.reason,"m.no_olm"===a.code&&(delete a.room_id,delete a.session_id),o[t]||(o[t]={}),o[t][i]=a}await this._baseApis.sendToDevice("org.matrix.room_key.withheld",o);for(const t of Object.keys(o))for(const n of Object.keys(o[t]))e.markNotifiedBlockedDevice(t,n)},l.prototype.reshareKeyWithDevice=async function(e,t,n,o){const i=this._outboundSessions[t];if(!i)return void r.logger.debug(`megolm session ${t} not found: not re-sharing keys`);if(void 0===i.sharedWithDevices[n])return void r.logger.debug(`megolm session ${t} never shared with user ${n}`);const s=i.sharedWithDevices[n][o.deviceId];if(void 0===s)return void r.logger.debug("megolm session ID "+t+" never shared with device "+n+":"+o.deviceId);const u=await this._olmDevice.getInboundGroupSessionKey(this._roomId,e,t,s);if(!u)return void r.logger.warn(`No inbound session key found for megolm ${t}: not re-sharing keys`);await a.ensureOlmSessionsForDevices(this._olmDevice,this._baseApis,{[n]:[o]});const c={type:"m.forwarded_room_key",content:{algorithm:a.MEGOLM_ALGORITHM,room_id:this._roomId,session_id:t,session_key:u.key,chain_index:u.chain_index,sender_key:e,sender_claimed_ed25519_key:u.sender_claimed_ed25519_key,forwarding_curve25519_key_chain:u.forwarding_curve25519_key_chain,"org.matrix.msc3061.shared_history":u.shared_history||!1}},l={algorithm:a.OLM_ALGORITHM,sender_key:this._olmDevice.deviceCurve25519Key,ciphertext:{}};await a.encryptMessageForDevice(l.ciphertext,this._userId,this._deviceId,this._olmDevice,n,o,c),await this._baseApis.sendToDevice("m.room.encrypted",{[n]:{[o.deviceId]:l}}),r.logger.debug(`Re-shared key for megolm session ${t} with ${n}:${o.deviceId}`)},l.prototype._shareKeyWithDevices=async function(e,t,n,o,i,s,u){r.logger.debug(`Ensuring Olm sessions for devices in ${this._roomId}`);const c=await a.ensureOlmSessionsForDevices(this._olmDevice,this._baseApis,o,s,u,r.logger.withPrefix(`[${this._roomId}]`));r.logger.debug(`Ensured Olm sessions for devices in ${this._roomId}`),this._getDevicesWithoutSessions(c,o,i),r.logger.debug(`Sharing keys with Olm sessions in ${this._roomId}`),await this._shareKeyWithOlmSessions(e,t,n,c),r.logger.debug(`Shared keys with Olm sessions in ${this._roomId}`)},l.prototype._shareKeyWithOlmSessions=async function(e,t,n,o){const i=this._splitDevices(o);for(let o=0;o{try{r.logger.debug(`Getting devices in ${this._roomId}`);const[t,n]=await this._getDevicesInRoom(e);this._crypto.getGlobalErrorOnUnknownDevices()&&this._removeUnknownDevices(t),r.logger.debug(`Ensuring outbound session in ${this._roomId}`),await this._ensureOutboundSession(e,t,n,!0),r.logger.debug(`Ready to encrypt events for ${this._roomId}`)}catch(e){r.logger.error(`Failed to prepare to encrypt events for ${this._roomId}`,e)}finally{delete this.encryptionPreparationMetadata,delete this.encryptionPreparation}})()},l.prototype.encryptMessage=async function(e,t,n){if(r.logger.log(`Starting to encrypt event for ${this._roomId}`),this.encryptionPreparation)try{await this.encryptionPreparation}catch(e){}const[o,i]=await this._getDevicesInRoom(e);this._crypto.getGlobalErrorOnUnknownDevices()&&this._checkForUnknownDevices(o);const s=await this._ensureOutboundSession(e,o,i),u={room_id:this._roomId,type:t,content:n},c=this._olmDevice.encryptGroupMessage(s.sessionId,JSON.stringify(u)),l={algorithm:a.MEGOLM_ALGORITHM,sender_key:this._olmDevice.deviceCurve25519Key,ciphertext:c,session_id:s.sessionId,device_id:this._deviceId};return s.useCount++,l},l.prototype.forceDiscardSession=function(){this._setupPromise=this._setupPromise.then((()=>null))},l.prototype._checkForUnknownDevices=function(e){const t={};if(Object.keys(e).forEach((n=>{Object.keys(e[n]).forEach((o=>{const r=e[n][o];r.isUnverified()&&!r.isKnown()&&(t[n]||(t[n]={}),t[n][o]=r)}))})),Object.keys(t).length)throw new s.UnknownDeviceError("This room contains unknown devices which have not been verified. We strongly recommend you verify them before continuing.",t)},l.prototype._removeUnknownDevices=function(e){for(const[t,n]of Object.entries(e)){for(const[e,t]of Object.entries(n))t.isUnverified()&&!t.isKnown()&&delete n[e];0===Object.keys(n).length&&delete e[t]}},l.prototype._getDevicesInRoom=async function(e){const t=(await e.getEncryptionTargetMembers()).map((function(e){return e.userId}));let n=this._crypto.getGlobalBlacklistUnverifiedDevices();"boolean"==typeof e.getBlacklistUnverifiedDevices()&&(n=e.getBlacklistUnverifiedDevices());const o=await this._crypto.downloadKeys(t,!1),r={};for(const e in o){if(!o.hasOwnProperty(e))continue;const t=o[e];for(const o in t){if(!t.hasOwnProperty(o))continue;const i=this._crypto.checkDeviceTrust(e,o);if(t[o].isBlocked()||!i.isVerified()&&n){r[e]||(r[e]={});const n=t[o].isBlocked()?{code:"m.blacklisted",reason:u.WITHHELD_MESSAGES["m.blacklisted"]}:{code:"m.unverified",reason:u.WITHHELD_MESSAGES["m.unverified"]};n.deviceInfo=t[o],r[e][o]=n,delete t[o]}}}return[o,r]},i.inherits(d,s.DecryptionAlgorithm);const h={no_olm:"The sender was unable to establish a secure channel.",unknown:"The secure channel with the sender was corrupted."};d.prototype.decryptEvent=async function(e){const t=e.getWireContent();if(!t.sender_key||!t.session_id||!t.ciphertext)throw new s.DecryptionError("MEGOLM_MISSING_FIELDS","Missing fields in input");let n;this._addEventToPendingList(e);try{n=await this._olmDevice.decryptGroupMessage(e.getRoomId(),t.sender_key,t.session_id,t.ciphertext,e.getId(),e.getTs())}catch(n){if("DecryptionError"===n.name)throw n;let o="OLM_DECRYPT_GROUP_MESSAGE_ERROR";throw n&&"OLM.UNKNOWN_MESSAGE_INDEX"===n.message&&(this._requestKeysForEvent(e),o="OLM_UNKNOWN_MESSAGE_INDEX"),new s.DecryptionError(o,n?n.toString():"Unknown Error: Error is undefined",{session:t.sender_key+"|"+t.session_id})}if(null===n){this._requestKeysForEvent(e);const n=await this._olmDevice.sessionMayHaveProblems(t.sender_key,e.getTs()-12e4);if(n){let e=h[n.type]||h.unknown;throw n.fixed&&(e+=" Trying to create a new secure channel and re-requesting the keys."),new s.DecryptionError("MEGOLM_UNKNOWN_INBOUND_SESSION_ID",e,{session:t.sender_key+"|"+t.session_id})}throw new s.DecryptionError("MEGOLM_UNKNOWN_INBOUND_SESSION_ID","The sender's device has not sent us the keys for this message.",{session:t.sender_key+"|"+t.session_id})}this._removeEventFromPendingList(e);const o=JSON.parse(n.result);if(o.room_id!==e.getRoomId())throw new s.DecryptionError("MEGOLM_BAD_ROOM","Message intended for room "+o.room_id);return{clearEvent:o,senderCurve25519Key:n.senderKey,claimedEd25519Key:n.keysClaimed.ed25519,forwardingCurve25519KeyChain:n.forwardingCurve25519KeyChain,untrusted:n.untrusted}},d.prototype._requestKeysForEvent=function(e){const t=e.getWireContent(),n=e.getKeyRequestRecipients(this._userId);this._crypto.requestRoomKey({room_id:e.getRoomId(),algorithm:t.algorithm,sender_key:t.sender_key,session_id:t.session_id},n)},d.prototype._addEventToPendingList=function(e){const t=e.getWireContent(),n=t.sender_key,o=t.session_id;this._pendingEvents[n]||(this._pendingEvents[n]=new Map);const r=this._pendingEvents[n];r.has(o)||r.set(o,new Set),r.get(o).add(e)},d.prototype._removeEventFromPendingList=function(e){const t=e.getWireContent(),n=t.sender_key,o=t.session_id,r=this._pendingEvents[n],i=r&&r.get(o);i&&(i.delete(e),0===i.size&&r.delete(n),0===r.size&&delete this._pendingEvents[n])},d.prototype.onRoomKeyEvent=function(e){const t=e.getContent(),n=t.session_id;let o,i=e.getSenderKey(),a=[],s=!1;if(!t.room_id||!n||!t.session_key)return void r.logger.error("key event is missing fields");if(!i)return void r.logger.error("key event has no sender key (not encrypted?)");if("m.forwarded_room_key"==e.getType()){if(s=!0,a=t.forwarding_curve25519_key_chain,Array.isArray(a)||(a=[]),a=a.slice(),a.push(i),i=t.sender_key,!i)return void r.logger.error("forwarded_room_key event is missing sender_key field");const e=t.sender_claimed_ed25519_key;if(!e)return void r.logger.error("forwarded_room_key_event is missing sender_claimed_ed25519_key field");o={ed25519:e}}else o=e.getKeysClaimed();const u={};return t["org.matrix.msc3061.shared_history"]&&(u.sharedHistory=!0),this._olmDevice.addInboundGroupSession(t.room_id,i,a,n,t.session_key,o,s,u).then((()=>{this._retryDecryption(i,n).then((e=>{e&&this._crypto.cancelRoomKeyRequest({algorithm:t.algorithm,room_id:t.room_id,session_id:t.session_id,sender_key:i})}))})).then((()=>{this._crypto.backupGroupSession(t.room_id,i,a,t.session_id,t.session_key,o,s)})).catch((e=>{r.logger.error(`Error handling m.room_key_event: ${e}`)}))},d.prototype.onRoomKeyWithheldEvent=async function(e){const t=e.getContent(),n=t.sender_key;if("m.no_olm"===t.code){const o=e.getSender();if(r.logger.warn(`${o}:${n} was unable to establish an olm session with us`),await this._olmDevice.getSessionIdForDevice(n))return r.logger.debug("New session already created. Not creating a new one."),await this._olmDevice.recordSessionProblem(n,"no_olm",!0),void this.retryDecryptionFromSender(n);let i=this._crypto._deviceList.getDeviceByIdentityKey(t.algorithm,n);if(!i&&(await this._crypto.downloadKeys([o],!1),i=this._crypto._deviceList.getDeviceByIdentityKey(t.algorithm,n),!i))return r.logger.info("Couldn't find device for identity key "+n+": not establishing session"),await this._olmDevice.recordSessionProblem(n,"no_olm",!1),void this.retryDecryptionFromSender(n);await a.ensureOlmSessionsForDevices(this._olmDevice,this._baseApis,{[o]:[i]},!1);const s={algorithm:a.OLM_ALGORITHM,sender_key:this._olmDevice.deviceCurve25519Key,ciphertext:{}};await a.encryptMessageForDevice(s.ciphertext,this._userId,this._deviceId,this._olmDevice,o,i,{type:"m.dummy"}),await this._olmDevice.recordSessionProblem(n,"no_olm",!0),this.retryDecryptionFromSender(n),await this._baseApis.sendToDevice("m.room.encrypted",{[o]:{[i.deviceId]:s}})}else await this._olmDevice.addInboundGroupSessionWithheld(t.room_id,n,t.session_id,t.code,t.reason)},d.prototype.hasKeysForKeyRequest=function(e){const t=e.requestBody;return this._olmDevice.hasInboundSessionKeys(t.room_id,t.sender_key,t.session_id)},d.prototype.shareKeysWithDevice=function(e){const t=e.userId,n=e.deviceId,o=this._crypto.getStoredDevice(t,n),i=e.requestBody;this.olmlib.ensureOlmSessionsForDevices(this._olmDevice,this._baseApis,{[t]:[o]}).then((e=>e[t][n].sessionId?(r.logger.log("sharing keys for session "+i.sender_key+"|"+i.session_id+" with device "+t+":"+n),this._buildKeyForwardingMessage(i.room_id,i.sender_key,i.session_id)):null)).then((e=>{const r={algorithm:a.OLM_ALGORITHM,sender_key:this._olmDevice.deviceCurve25519Key,ciphertext:{}};return this.olmlib.encryptMessageForDevice(r.ciphertext,this._userId,this._deviceId,this._olmDevice,t,o,e).then((()=>{const e={[t]:{[n]:r}};return this._baseApis.sendToDevice("m.room.encrypted",e)}))}))},d.prototype._buildKeyForwardingMessage=async function(e,t,n){const o=await this._olmDevice.getInboundGroupSessionKey(e,t,n);return{type:"m.forwarded_room_key",content:{algorithm:a.MEGOLM_ALGORITHM,room_id:e,sender_key:t,sender_claimed_ed25519_key:o.sender_claimed_ed25519_key,session_id:n,session_key:o.key,chain_index:o.chain_index,forwarding_curve25519_key_chain:o.forwarding_curve25519_key_chain,"org.matrix.msc3061.shared_history":o.shared_history||!1}}},d.prototype.importRoomKey=function(e,t={}){const n={};return t.untrusted&&(n.untrusted=!0),e["org.matrix.msc3061.shared_history"]&&(n.sharedHistory=!0),this._olmDevice.addInboundGroupSession(e.room_id,e.sender_key,e.forwarding_curve25519_key_chain,e.session_id,e.session_key,e.sender_claimed_keys,!0,n).then((()=>{"backup"!==t.source&&this._crypto.backupGroupSession(e.room_id,e.sender_key,e.forwarding_curve25519_key_chain,e.session_id,e.session_key,e.sender_claimed_keys,!0).catch((e=>{r.logger.log("Failed to back up megolm session",e)})),this._retryDecryption(e.sender_key,e.session_id)}))},d.prototype._retryDecryption=async function(e,t){const n=this._pendingEvents[e];if(!n)return!0;const o=n.get(t);return!o||(r.logger.debug("Retrying decryption on events",[...o]),await Promise.all([...o].map((async e=>{try{await e.attemptDecryption(this._crypto,{isRetry:!0})}catch(e){}}))),!(this._pendingEvents[e]||{})[t])},d.prototype.retryDecryptionFromSender=async function(e){const t=this._pendingEvents[e];return!t||(delete this._pendingEvents[e],await Promise.all([...t].map((async([e,t])=>{await Promise.all([...t].map((async e=>{try{await e.attemptDecryption(this._crypto)}catch(e){}})))}))),!this._pendingEvents[e])},d.prototype.sendSharedHistoryInboundSessions=async function(e){await a.ensureOlmSessionsForDevices(this._olmDevice,this._baseApis,e),r.logger.log("sendSharedHistoryInboundSessions to users",Object.keys(e));const t=await this._olmDevice.getSharedHistoryInboundGroupSessions(this._roomId);r.logger.log("shared-history sessions",t);for(const[n,o]of t){const t=await this._buildKeyForwardingMessage(this._roomId,n,o),i=[],s={};for(const[n,o]of Object.entries(e)){s[n]={};for(const e of o){const o={algorithm:a.OLM_ALGORITHM,sender_key:this._olmDevice.deviceCurve25519Key,ciphertext:{}};s[n][e.deviceId]=o,i.push(a.encryptMessageForDevice(o.ciphertext,this._userId,this._deviceId,this._olmDevice,n,e,t))}}await Promise.all(i);for(const e of Object.keys(s)){for(const t of Object.keys(s[e]))0===Object.keys(s[e][t].ciphertext).length&&(r.logger.log("No ciphertext for device "+e+":"+t+": pruning"),delete s[e][t]);0===Object.keys(s[e]).length&&(r.logger.log("Pruned all devices for user "+e),delete s[e])}if(0===Object.keys(s).length)return void r.logger.log("No users left to send to: aborting");await this._baseApis.sendToDevice("m.room.encrypted",s)}},(0,s.registerAlgorithm)(a.MEGOLM_ALGORITHM,l,d)},23072:(e,t,n)=>{"use strict";var o=n(20862),r=n(7434),i=o(n(3102)),a=o(n(32772)),s=n(23272),u=n(21897);const c=s.DeviceInfo.DeviceVerification;function l(e){(0,i.polyfillSuper)(this,u.EncryptionAlgorithm,e),this._sessionPrepared=!1,this._prepPromise=null}function d(e){(0,i.polyfillSuper)(this,u.DecryptionAlgorithm,e)}i.inherits(l,u.EncryptionAlgorithm),l.prototype._ensureSession=function(e){if(this._prepPromise)return this._prepPromise;if(this._sessionPrepared)return Promise.resolve();const t=this;return this._prepPromise=t._crypto.downloadKeys(e).then((function(n){return t._crypto.ensureOlmSessionsForUsers(e)})).then((function(){t._sessionPrepared=!0})).finally((function(){t._prepPromise=null})),this._prepPromise},l.prototype.encryptMessage=async function(e,t,n){const o=(await e.getEncryptionTargetMembers()).map((function(e){return e.userId})),r=this;await this._ensureSession(o);const i={room_id:e.roomId,type:t,content:n},s={algorithm:a.OLM_ALGORITHM,sender_key:r._olmDevice.deviceCurve25519Key,ciphertext:{}},u=[];for(let e=0;es))},i.inherits(d,u.DecryptionAlgorithm),d.prototype.decryptEvent=async function(e){const t=e.getWireContent(),n=t.sender_key,o=t.ciphertext;if(!o)throw new u.DecryptionError("OLM_MISSING_CIPHERTEXT","Missing ciphertext");if(!(this._olmDevice.deviceCurve25519Key in o))throw new u.DecryptionError("OLM_NOT_INCLUDED_IN_RECIPIENTS","Not included in recipients");const r=o[this._olmDevice.deviceCurve25519Key];let i;try{i=await this._decryptMessage(n,r)}catch(e){throw new u.DecryptionError("OLM_BAD_ENCRYPTED_MESSAGE","Bad Encrypted Message",{sender:n,err:e})}const a=JSON.parse(i);if(a.recipient!=this._userId)throw new u.DecryptionError("OLM_BAD_RECIPIENT","Message was intented for "+a.recipient);if(a.recipient_keys.ed25519!=this._olmDevice.deviceEd25519Key)throw new u.DecryptionError("OLM_BAD_RECIPIENT_KEY","Message not intended for this device",{intended:a.recipient_keys.ed25519,our_key:this._olmDevice.deviceEd25519Key});if(a.sender!=e.getSender())throw new u.DecryptionError("OLM_FORWARDED_MESSAGE","Message forwarded from "+a.sender,{reported_sender:e.getSender()});if(a.room_id!==e.getRoomId())throw new u.DecryptionError("OLM_BAD_ROOM","Message intended for room "+a.room_id,{reported_room:e.room_id});return{clearEvent:a,senderCurve25519Key:n,claimedEd25519Key:(a.keys||{}).ed25519||null}},d.prototype._decryptMessage=async function(e,t){if(0!==t.type)return this._reallyDecryptMessage(e,t);{const n=this._olmDevice._olmPrekeyPromise.then((()=>this._reallyDecryptMessage(e,t)));return this._olmDevice._olmPrekeyPromise=n.catch((()=>{})),await n}},d.prototype._reallyDecryptMessage=async function(e,t){const n=await this._olmDevice.getSessionIdsForDevice(e),o={};for(let i=0;i{"use strict";var o=n(95318);Object.defineProperty(t,"__esModule",{value:!0}),t.DehydrationManager=t.DEHYDRATION_ALGORITHM=void 0;var r=o(n(59713)),i=n(32772),a=n(57585),s=n(2611),u=o(n(69141)),c=n(7434);const l="org.matrix.msc2697.v1.olm.libolm_pickle";t.DEHYDRATION_ALGORITHM=l;const d=6048e5;t.DehydrationManager=class{constructor(e){this.crypto=e,(0,r.default)(this,"inProgress",!1),(0,r.default)(this,"timeoutId",void 0),(0,r.default)(this,"key",void 0),(0,r.default)(this,"keyInfo",void 0),(0,r.default)(this,"deviceDisplayName",void 0),this.getDehydrationKeyFromCache()}async getDehydrationKeyFromCache(){return await this.crypto._cryptoStore.doTxn("readonly",[a.IndexedDBCryptoStore.STORE_ACCOUNT],(e=>{this.crypto._cryptoStore.getSecretStorePrivateKey(e,(async e=>{if(e){const{key:t,keyInfo:o,deviceDisplayName:r,time:a}=e,u=Buffer.from(this.crypto._olmDevice._pickleKey),c=await(0,s.decryptAES)(t,u,l);this.key=(0,i.decodeBase64)(c),this.keyInfo=o,this.deviceDisplayName=r;const h=Date.now(),p=Math.max(1,a+d-h);this.timeoutId=n.g.setTimeout(this.dehydrateDevice.bind(this),p)}}),"dehydration")}))}async setKeyAndQueueDehydration(e,t={},n){await this.setKey(e,t,n)||this.dehydrateDevice()}async setKey(e,t={},o){if(!e)return this.timeoutId&&(n.g.clearTimeout(this.timeoutId),this.timeoutId=void 0),await this.crypto._cryptoStore.doTxn("readwrite",[a.IndexedDBCryptoStore.STORE_ACCOUNT],(e=>{this.crypto._cryptoStore.storeSecretStorePrivateKey(e,"dehydration",null)})),this.key=void 0,void(this.keyInfo=void 0);let r=this.key&&e.length==this.key.length;for(let t=0;r&&t{this.crypto._cryptoStore.storeSecretStorePrivateKey(e,"dehydration",{keyInfo:this.keyInfo,key:t,deviceDisplayName:this.deviceDisplayName,time:Date.now()})})),c.logger.log("Attempting to dehydrate device"),c.logger.log("Creating account");const o=new n.g.Olm.Account;o.create();const r=JSON.parse(o.identity_keys()),h=o.max_number_of_one_time_keys();o.generate_one_time_keys(h/2),o.generate_fallback_key();const p=JSON.parse(o.one_time_keys()),f=JSON.parse(o.fallback_key());o.mark_keys_as_published();const g=o.pickle(new Uint8Array(this.key)),m={algorithm:l,account:g};this.keyInfo.passphrase&&(m.passphrase=this.keyInfo.passphrase),c.logger.log("Uploading account to server");const _=(await this.crypto._baseApis._http.authedRequest(void 0,"PUT","/dehydrated_device",void 0,{device_data:m,initial_device_display_name:this.deviceDisplayName},{prefix:"/_matrix/client/unstable/org.matrix.msc2697.v2"})).device_id;c.logger.log("Preparing device keys",_);const F={algorithms:this.crypto._supportedAlgorithms,device_id:_,user_id:this.crypto._userId,keys:{[`ed25519:${_}`]:r.ed25519,[`curve25519:${_}`]:r.curve25519}},y=o.sign(u.default.stringify(F));F.signatures={[this.crypto._userId]:{[`ed25519:${_}`]:y}},this.crypto._crossSigningInfo.getId("self_signing")&&await this.crypto._crossSigningInfo.signObject(F,"self_signing"),c.logger.log("Preparing one-time keys");const b={};for(const[e,t]of Object.entries(p.curve25519)){const n={key:t},r=o.sign(u.default.stringify(n));n.signatures={[this.crypto._userId]:{[`ed25519:${_}`]:r}},b[`signed_curve25519:${e}`]=n}c.logger.log("Preparing fallback keys");const v={};for(const[e,t]of Object.entries(f.curve25519)){const n={key:t,fallback:!0},r=o.sign(u.default.stringify(n));n.signatures={[this.crypto._userId]:{[`ed25519:${_}`]:r}},v[`signed_curve25519:${e}`]=n}return c.logger.log("Uploading keys to server"),await this.crypto._baseApis._http.authedRequest(void 0,"POST","/keys/upload/"+encodeURI(_),void 0,{device_keys:F,one_time_keys:b,"org.matrix.msc2732.fallback_keys":v}),c.logger.log("Done dehydrating"),this.timeoutId=n.g.setTimeout(this.dehydrateDevice.bind(this),d),_}finally{this.inProgress=!1}}}stop(){this.timeoutId&&(n.g.clearTimeout(this.timeoutId),this.timeoutId=void 0)}}},23272:(e,t)=>{"use strict";function n(e){Object.defineProperty(this,"deviceId",{enumerable:!0,value:e}),this.algorithms=[],this.keys={},this.verified=o.UNVERIFIED,this.known=!1,this.unsigned={},this.signatures={}}Object.defineProperty(t,"__esModule",{value:!0}),t.DeviceInfo=n,n.fromStorage=function(e,t){const o=new n(t);for(const t in e)e.hasOwnProperty(t)&&(o[t]=e[t]);return o},n.prototype.toStorage=function(){return{algorithms:this.algorithms,keys:this.keys,verified:this.verified,known:this.known,unsigned:this.unsigned,signatures:this.signatures}},n.prototype.getFingerprint=function(){return this.keys["ed25519:"+this.deviceId]},n.prototype.getIdentityKey=function(){return this.keys["curve25519:"+this.deviceId]},n.prototype.getDisplayName=function(){return this.unsigned.device_display_name||null},n.prototype.isBlocked=function(){return this.verified==o.BLOCKED},n.prototype.isVerified=function(){return this.verified==o.VERIFIED},n.prototype.isUnverified=function(){return this.verified==o.UNVERIFIED},n.prototype.isKnown=function(){return 1==this.known},n.DeviceVerification={VERIFIED:1,UNVERIFIED:0,BLOCKED:-1};const o=n.DeviceVerification},12600:(e,t,n)=>{"use strict";var o=n(20862),r=n(95318);Object.defineProperty(t,"__esModule",{value:!0}),t.isCryptoAvailable=function(){return Boolean(n.g.Olm)},t.Crypto=B,t.fixBackupKey=N,t.verificationMethods=void 0;var i=r(n(69141)),a=n(17187),s=n(20771),u=n(7434),c=o(n(3102)),l=n(72573),d=o(n(32772)),h=n(36670),p=n(23272),f=o(n(91994)),g=n(3075),m=n(70636),_=n(44823),F=n(66617),y=n(57585),b=n(51696),v=n(56381),w=n(91597),E=n(34077),k=n(85279),D=n(22842),S=n(89588),x=n(4028),C=n(19489),A=n(2611),T=n(54830),R=n(24369);const I=p.DeviceInfo.DeviceVerification,M={[b.ReciprocateQRCode.NAME]:b.ReciprocateQRCode,[v.SAS.NAME]:v.SAS,[b.SHOW_QR_CODE_METHOD]:x.IllegalMethod,[b.SCAN_QR_CODE_METHOD]:x.IllegalMethod},O={RECIPROCATE_QR_CODE:b.ReciprocateQRCode.NAME,SAS:v.SAS.NAME};function B(e,t,n,o,r,i,a,c){if(this._onDeviceListUserCrossSigningUpdated=this._onDeviceListUserCrossSigningUpdated.bind(this),this._trustCrossSignedDevices=!0,this._reEmitter=new s.ReEmitter(this),this._baseApis=e,this._sessionStore=t,this._userId=n,this._deviceId=o,this._clientStore=r,this._cryptoStore=i,this._roomList=a,c){this._verificationMethods=new Map;for(const e of c)"string"==typeof e?M[e]&&this._verificationMethods.set(e,M[e]):e.NAME?this._verificationMethods.set(e.NAME,e):u.logger.warn(`Excluding unknown verification method ${e}`)}else this._verificationMethods=M;this.backupInfo=null,this.backupKey=null,this._checkedForBackup=!1,this._sendingBackups=!1,this._olmDevice=new l.OlmDevice(i),this._deviceList=new h.DeviceList(e,i,this._olmDevice),this._deviceList.on("userCrossSigningUpdated",this._onDeviceListUserCrossSigningUpdated),this._reEmitter.reEmit(this._deviceList,["crypto.devicesUpdated","crypto.willUpdateDevices"]),this._lastOneTimeKeyCheck=null,this._oneTimeKeyCheckInProgress=!1,this._roomEncryptors={},this._roomDecryptors={},this._supportedAlgorithms=Object.keys(f.DECRYPTION_CLASSES),this._deviceKeys={},this._globalBlacklistUnverifiedDevices=!1,this._globalErrorOnUnknownDevices=!0,this._outgoingRoomKeyRequestManager=new F.OutgoingRoomKeyRequestManager(e,this._deviceId,this._cryptoStore),this._receivedRoomKeyRequests=[],this._receivedRoomKeyRequestCancellations=[],this._processingRoomKeyRequests=!1,this._lazyLoadMembers=!1,this._roomDeviceTrackingState={},this._lastNewSessionForced={},this._toDeviceVerificationRequests=new S.ToDeviceRequests,this._inRoomVerificationRequests=new D.InRoomRequests,this._sendKeyRequestsImmediately=!1;const d=this._baseApis._cryptoCallbacks||{},p=(0,g.createCryptoStoreCacheCallbacks)(i,this._olmDevice);this._crossSigningInfo=new g.CrossSigningInfo(n,d,p),this._secretStorage=new _.SecretStorage(e,d),this._dehydrationManager=new T.DehydrationManager(this),!d.getCrossSigningKey&&d.getSecretStorageKey&&(d.getCrossSigningKey=async e=>g.CrossSigningInfo.getFromSecretStorage(e,this._secretStorage))}function N(e){if("string"!=typeof e||e.indexOf(",")<0)return null;const t=Uint8Array.from(e.split(","),(e=>parseInt(e)));return d.encodeBase64(t)}async function L(e){const t=[],n={};if(e.getNeedsNewFallback()){const o=await e._olmDevice.getFallbackKey();for(const[r,i]of Object.entries(o.curve25519)){const o={key:i,fallback:!0};n["signed_curve25519:"+r]=o,t.push(e._signObject(o))}e.setNeedsNewFallback(!1)}const o=await e._olmDevice.getOneTimeKeys(),r={};for(const n in o.curve25519)if(o.curve25519.hasOwnProperty(n)){const i={key:o.curve25519[n]};r["signed_curve25519:"+n]=i,t.push(e._signObject(i))}await Promise.all(t);const i=await e._baseApis.uploadKeysRequest({one_time_keys:r,"org.matrix.msc2732.fallback_keys":n});return await e._olmDevice.markKeysAsPublished(),i}t.verificationMethods=O,c.inherits(B,a.EventEmitter),B.prototype.init=async function(e){const{exportedOlmDevice:t,pickleKey:o}=e||{};u.logger.log("Crypto: initialising Olm..."),await n.g.Olm.init(),u.logger.log(t?"Crypto: initialising Olm device from exported device...":"Crypto: initialising Olm device..."),await this._olmDevice.init({fromExportedDevice:t,pickleKey:o}),u.logger.log("Crypto: loading device list..."),await this._deviceList.load(),this._deviceKeys["ed25519:"+this._deviceId]=this._olmDevice.deviceEd25519Key,this._deviceKeys["curve25519:"+this._deviceId]=this._olmDevice.deviceCurve25519Key,u.logger.log("Crypto: fetching own devices...");let r=this._deviceList.getRawStoredDevicesForUser(this._userId);if(r||(r={}),!r[this._deviceId]){u.logger.log("Crypto: adding this device to the store...");const e={keys:this._deviceKeys,algorithms:this._supportedAlgorithms,verified:I.VERIFIED,known:!0};r[this._deviceId]=e,this._deviceList.storeDevicesForUser(this._userId,r),this._deviceList.saveIfDirty()}await this._cryptoStore.doTxn("readonly",[y.IndexedDBCryptoStore.STORE_ACCOUNT],(e=>{this._cryptoStore.getCrossSigningKeys(e,(e=>{e&&0!==Object.keys(e).length&&(u.logger.log("Loaded cross-signing public keys from crypto store"),this._crossSigningInfo.setKeys(e))}))})),this._deviceList.startTrackingDeviceList(this._userId),u.logger.log("Crypto: checking for key backup..."),this._checkAndStartKeyBackup()},B.prototype.getCryptoTrustCrossSignedDevices=function(){return this._trustCrossSignedDevices},B.prototype.setCryptoTrustCrossSignedDevices=function(e){this._trustCrossSignedDevices=e;for(const e of this._deviceList.getKnownUserIds()){const t=this._deviceList.getRawStoredDevicesForUser(e);for(const n of Object.keys(t)){const t=this.checkDeviceTrust(e,n);if(!t.isLocallyVerified()&&t.isCrossSigningVerified()){const t=this._deviceList.getStoredDevice(e,n);this.emit("deviceVerificationChanged",e,n,t)}}}},B.prototype.createRecoveryKeyFromPassphrase=async function(e){const t=new n.g.Olm.PkDecryption;try{const n={};if(e){const o=await(0,w.keyFromPassphrase)(e);n.passphrase={algorithm:"m.pbkdf2",iterations:o.iterations,salt:o.salt},n.pubkey=t.init_with_private_key(o.key)}else n.pubkey=t.generate_key();const o=t.get_private_key();return{keyInfo:n,encodedPrivateKey:(0,E.encodeRecoveryKey)(o),privateKey:o}}finally{t&&t.free()}},B.prototype.isCrossSigningReady=async function(){const e=this._crossSigningInfo.getId(),t=await this._crossSigningInfo.isStoredInKeyCache()||await this._crossSigningInfo.isStoredInSecretStorage(this._secretStorage);return!(!e||!t)},B.prototype.isSecretStorageReady=async function(){const e=await this._secretStorage.hasKey(),t=await this._crossSigningInfo.isStoredInSecretStorage(this._secretStorage),n=!this._baseApis.getKeyBackupEnabled()||this._baseApis.isKeyBackupKeyStored();return!!(e&&t&&n)},B.prototype.bootstrapCrossSigning=async function({authUploadDeviceSigningKeys:e,setupNewCrossSigning:t}={}){u.logger.log("Bootstrapping cross-signing");const n=this._baseApis._cryptoCallbacks,o=new m.EncryptionSetupBuilder(this._baseApis.store.accountData,n),r=new g.CrossSigningInfo(this._userId,o.crossSigningCallbacks,o.crossSigningCallbacks),i=this._crossSigningInfo.getId(),a=await this._crossSigningInfo.isStoredInKeyCache(),s=await this._crossSigningInfo.isStoredInSecretStorage(this._secretStorage),c=a||s;u.logger.log({setupNewCrossSigning:t,publicKeysOnDevice:i,privateKeysInCache:a,privateKeysInStorage:s,privateKeysExistSomewhere:c}),!c||t?(u.logger.log("Cross-signing private keys not found locally or in secret storage, creating new keys"),await(async()=>{r.resetKeys(),await this._signObject(r.keys.master),o.addCrossSigningKeys(e,r.keys);const t=this._deviceList.getStoredDevice(this._userId,this._deviceId),n=await r.signDevice(this._userId,t);o.addKeySignature(this._userId,this._deviceId,n),this.backupInfo&&(await r.signObject(this.backupInfo.auth_data,"master"),o.addSessionBackup(this.backupInfo))})()):i&&a?u.logger.log("Cross-signing public keys trusted and private keys found locally"):s&&(u.logger.log("Cross-signing private keys not found locally, but they are available in secret storage, reading storage and caching locally"),await this.checkOwnCrossSigningTrust({allowPrivateKeyRequests:!0}));const l=o.crossSigningCallbacks.privateKeys;if(l.size&&!this._baseApis._cryptoCallbacks.saveCrossSigningKeys){const e=new _.SecretStorage(o.accountDataClientAdapter,o.ssssCryptoCallbacks);await e.hasKey()&&(u.logger.log("Storing new cross-signing private keys in secret storage"),await g.CrossSigningInfo.storeInSecretStorage(l,e))}const d=o.buildOperation();await d.apply(this),await o.persist(this),u.logger.log("Cross-signing ready")},B.prototype.bootstrapSecretStorage=async function({createSecretStorageKey:e=(async()=>({})),keyBackupInfo:t,setupNewKeyBackup:n,setupNewSecretStorage:o,getKeyBackupPassphrase:r}={}){u.logger.log("Bootstrapping Secure Secret Storage");const i=this._baseApis._cryptoCallbacks,a=new m.EncryptionSetupBuilder(this._baseApis.store.accountData,i),s=new _.SecretStorage(a.accountDataClientAdapter,a.ssssCryptoCallbacks);let c=null;const l=async(e,t)=>{e=e||{},t&&(e.key=t);const{keyId:n,keyInfo:o}=await s.addKey(_.SECRET_STORAGE_ALGORITHM_V1_AES,e);return t&&a.ssssCryptoCallbacks.addPrivateKey(n,o,t),await s.setDefaultKeyId(n),n},h=async e=>{if(this._crossSigningInfo.getId()&&await this._crossSigningInfo.isStoredInKeyCache("master"))try{u.logger.log("Adding cross-signing signature to key backup"),await this._crossSigningInfo.signObject(e,"master")}catch(e){u.logger.error("Signing key backup with cross-signing keys failed",e)}else u.logger.warn("Cross-signing keys not available, skipping signature on key backup")},p=await this.getSecretStorageKey(),[f,F]=p||[null,null],y=!o&&F&&F.algorithm===_.SECRET_STORAGE_ALGORITHM_V1_AES;if(u.logger.log({keyBackupInfo:t,setupNewKeyBackup:n,setupNewSecretStorage:o,storageExists:y,oldKeyInfo:F}),y||t)if(!y&&t){u.logger.log("Secret storage does not exist, using key backup key");const e=await this.getSessionBackupPrivateKey()||await r(),n={};t.auth_data.private_key_salt&&t.auth_data.private_key_iterations&&(n.passphrase={algorithm:"m.pbkdf2",iterations:t.auth_data.private_key_iterations,salt:t.auth_data.private_key_salt,bits:256}),c=await l(n,e),await s.store("m.megolm_backup.v1",d.encodeBase64(e),[c]),await h(t.auth_data),a.addSessionBackup(t)}else u.logger.log("Secret storage exists"),F&&F.algorithm===_.SECRET_STORAGE_ALGORITHM_V1_AES&&await(async(e,t)=>{if(!t.mac){const n=await this._baseApis._cryptoCallbacks.getSecretStorageKey({keys:{[e]:t}},"");if(n){const o=n[1];a.ssssCryptoCallbacks.addPrivateKey(e,t,o);const{iv:r,mac:i}=await _.SecretStorage._calculateKeyCheck(o);t.iv=r,t.mac=i,await a.setAccountData(`m.secret_storage.key.${e}`,t)}}})(f,F);else{u.logger.log("Secret storage does not exist, creating new storage key");const{keyInfo:t,privateKey:n}=await e();c=await l(t,n)}if(!this._baseApis._cryptoCallbacks.saveCrossSigningKeys&&await this.isCrossSigningReady()&&(c||!await this._crossSigningInfo.isStoredInSecretStorage(s))){u.logger.log("Copying cross-signing private keys from cache to secret storage");const e=await this._crossSigningInfo.getCrossSigningKeysFromCache();await g.CrossSigningInfo.storeInSecretStorage(e,s)}if(n&&!t){u.logger.log("Creating new message key backup version");const e=await this._baseApis.prepareKeyBackupVersion(null,{secureSecretStorage:!1}),t=(0,E.decodeRecoveryKey)(e.recovery_key);await s.store("m.megolm_backup.v1",d.encodeBase64(t));const n={algorithm:e.algorithm,auth_data:e.auth_data};await h(n.auth_data),await this._signObject(n.auth_data),a.addSessionBackup(n)}const b=await s.get("m.megolm_backup.v1");if(b){u.logger.info("Got session backup key from secret storage: caching");const e=N(b);e&&await s.store("m.megolm_backup.v1",e,[c||f]);const t=new Uint8Array(d.decodeBase64(e||b));await a.addSessionBackupPrivateKeyToCache(t)}const v=a.buildOperation();await v.apply(this),await a.persist(this),u.logger.log("Secure Secret Storage ready")},B.prototype.addSecretStorageKey=function(e,t,n){return this._secretStorage.addKey(e,t,n)},B.prototype.hasSecretStorageKey=function(e){return this._secretStorage.hasKey(e)},B.prototype.getSecretStorageKey=function(e){return this._secretStorage.getKey(e)},B.prototype.storeSecret=function(e,t,n){return this._secretStorage.store(e,t,n)},B.prototype.getSecret=function(e){return this._secretStorage.get(e)},B.prototype.isSecretStored=function(e,t){return this._secretStorage.isStored(e,t)},B.prototype.requestSecret=function(e,t){return t||(t=Object.keys(this._deviceList.getRawStoredDevicesForUser(this._userId))),this._secretStorage.request(e,t)},B.prototype.getDefaultSecretStorageKeyId=function(){return this._secretStorage.getDefaultKeyId()},B.prototype.setDefaultSecretStorageKeyId=function(e){return this._secretStorage.setDefaultKeyId(e)},B.prototype.checkSecretStorageKey=function(e,t){return this._secretStorage.checkKey(e,t)},B.prototype.checkSecretStoragePrivateKey=function(e,t){let o=null;try{return o=new n.g.Olm.PkDecryption,o.init_with_private_key(e)===t}finally{o&&o.free()}},B.prototype.getSessionBackupPrivateKey=async function(){let e=await new Promise((e=>{this._cryptoStore.doTxn("readonly",[y.IndexedDBCryptoStore.STORE_ACCOUNT],(t=>{this._cryptoStore.getSecretStorePrivateKey(t,e,"m.megolm_backup.v1")}))}));if(e&&"string"==typeof e&&(e=new Uint8Array(d.decodeBase64(N(e)||e)),await this.storeSessionBackupPrivateKey(e)),e&&e.ciphertext){const t=Buffer.from(this._olmDevice._pickleKey),n=await(0,A.decryptAES)(e,t,"m.megolm_backup.v1");e=d.decodeBase64(n)}return e},B.prototype.storeSessionBackupPrivateKey=async function(e){if(!(e instanceof Uint8Array))throw new Error(`storeSessionBackupPrivateKey expects Uint8Array, got ${e}`);const t=Buffer.from(this._olmDevice._pickleKey);return e=await(0,A.encryptAES)(d.encodeBase64(e),t,"m.megolm_backup.v1"),this._cryptoStore.doTxn("readwrite",[y.IndexedDBCryptoStore.STORE_ACCOUNT],(t=>{this._cryptoStore.storeSecretStorePrivateKey(t,"m.megolm_backup.v1",e)}))},B.prototype.checkCrossSigningPrivateKey=function(e,t){let o=null;try{return o=new n.g.Olm.PkSigning,o.init_with_seed(e)===t}finally{o&&o.free()}},B.prototype._afterCrossSigningLocalKeyChange=async function(){u.logger.info("Starting cross-signing key change post-processing");const e=this._deviceList.getStoredDevice(this._userId,this._deviceId),t=await this._crossSigningInfo.signDevice(this._userId,e);u.logger.info(`Starting background key sig upload for ${this._deviceId}`);const n=({shouldEmit:e})=>this._baseApis.uploadKeySignatures({[this._userId]:{[this._deviceId]:t}}).then((t=>{const{failures:o}=t||{};if(Object.keys(o||[]).length>0)throw e&&this._baseApis.emit("crypto.keySignatureUploadFailure",o,"_afterCrossSigningLocalKeyChange",n),new C.KeySignatureUploadError("Key upload failed",{failures:o});u.logger.info(`Finished background key sig upload for ${this._deviceId}`)})).catch((e=>{u.logger.error(`Error during background key sig upload for ${this._deviceId}`,e)}));n({shouldEmit:!0});const o=this._baseApis._cryptoCallbacks.shouldUpgradeDeviceVerifications;if(o){u.logger.info("Starting device verification upgrade");const e={};for(const[t,n]of Object.entries(this._deviceList._crossSigningInfo)){const o=await this._checkForDeviceVerificationUpgrade(t,g.CrossSigningInfo.fromStorage(n,t));o&&(e[t]=o)}if(Object.keys(e).length>0){u.logger.info(`Found ${Object.keys(e).length} verif users to upgrade`);try{const t=await o({users:e});if(t)for(const n of t)n in e&&await this._baseApis.setDeviceVerified(n,e[n].crossSigningInfo.getId())}catch(e){u.logger.log("shouldUpgradeDeviceVerifications threw an error: not upgrading",e)}}u.logger.info("Finished device verification upgrade")}u.logger.info("Finished cross-signing key change post-processing")},B.prototype._checkForDeviceVerificationUpgrade=async function(e,t){const n=this._crossSigningInfo.checkUserTrust(t);if(t.firstUse&&!n.verified){const n=this._deviceList.getRawStoredDevicesForUser(e),o=await this._checkForValidDeviceSignature(e,t.keys.master,n);if(o.length)return{devices:o.map((e=>p.DeviceInfo.fromStorage(n[e],e))),crossSigningInfo:t}}},B.prototype._checkForValidDeviceSignature=async function(e,t,n){const o=[];if(n&&t.signatures&&t.signatures[e])for(const r of Object.keys(t.signatures[e])){const[,i]=r.split(":",2);if(i in n&&n[i].verified===I.VERIFIED)try{await d.verifySignature(this._olmDevice,t,e,i,n[i].keys[r]),o.push(i)}catch(e){}}return o},B.prototype.getCrossSigningId=function(e){return this._crossSigningInfo.getId(e)},B.prototype.getStoredCrossSigningForUser=function(e){return this._deviceList.getStoredCrossSigningForUser(e)},B.prototype.checkUserTrust=function(e){const t=this._deviceList.getStoredCrossSigningForUser(e);return t?this._crossSigningInfo.checkUserTrust(t):new g.UserTrustLevel(!1,!1,!1)},B.prototype.checkDeviceTrust=function(e,t){const n=this._deviceList.getStoredDevice(e,t);return this._checkDeviceInfoTrust(e,n)},B.prototype._checkDeviceInfoTrust=function(e,t){const n=!(!t||!t.isVerified()),o=this._deviceList.getStoredCrossSigningForUser(e);if(t&&o){const r=this._trustCrossSignedDevices||e===this._userId;return this._crossSigningInfo.checkDeviceTrust(o,t,n,r)}return new g.DeviceTrustLevel(!1,!1,n,!1)},B.prototype._onDeviceListUserCrossSigningUpdated=async function(e){if(e===this._userId){const t=this._deviceList.getStoredCrossSigningForUser(e),n=t?t.getId():null,o=this._crossSigningInfo.getId(),r=o!==n;o&&n&&!r?await this.checkOwnCrossSigningTrust():(this._storeTrustedSelfKeys(null),this.emit("crossSigning.keysChanged",{}),this.emit("userTrustStatusChanged",this._userId,this.checkUserTrust(e)))}else{await this._checkDeviceVerifications(e);const t=this._deviceList.getStoredCrossSigningForUser(e);t&&(t.updateCrossSigningVerifiedBefore(this.checkUserTrust(e).isCrossSigningVerified()),this._deviceList.setRawStoredCrossSigningForUser(e,t.toStorage())),this.emit("userTrustStatusChanged",e,this.checkUserTrust(e))}},B.prototype.checkOwnCrossSigningTrust=async function({allowPrivateKeyRequests:e=!1}={}){const t=this._userId;await this.downloadKeys([this._userId]);const n=await this._crossSigningInfo.getCrossSigningKeysFromCache(),o=this._deviceList.getStoredCrossSigningForUser(t);if(!o)return void u.logger.error("Got cross-signing update event for user "+t+" but no new cross-signing information found!");const r=o.getId(),i=this._crossSigningInfo.getId()!==r,a=o.getId()&&!n.has("master");if(i&&u.logger.info("Got new master public key",r),e&&(i||a)){u.logger.info("Attempting to retrieve cross-signing master private key");let e=null;try{e=(await this._crossSigningInfo.getCrossSigningKey("master",r))[1],u.logger.info("Got cross-signing master private key")}finally{e&&e.free()}}const s=this._crossSigningInfo.getId("self_signing"),c=this._crossSigningInfo.getId("user_signing");this._storeTrustedSelfKeys(o.keys);const l=s!==o.getId("self_signing"),d=c!==o.getId("user_signing"),h=o.getId("self_signing")&&!n.has("self_signing"),p=o.getId("user_signing")&&!n.has("user_signing"),f={};if(l&&u.logger.info("Got new self-signing key",o.getId("self_signing")),e&&(l||h)){u.logger.info("Attempting to retrieve cross-signing self-signing private key");let e=null;try{e=(await this._crossSigningInfo.getCrossSigningKey("self_signing",o.getId("self_signing")))[1],u.logger.info("Got cross-signing self-signing private key")}finally{e&&e.free()}const t=this._deviceList.getStoredDevice(this._userId,this._deviceId),n=await this._crossSigningInfo.signDevice(this._userId,t);f[this._deviceId]=n}if(d&&u.logger.info("Got new user-signing key",o.getId("user_signing")),e&&(d||p)){u.logger.info("Attempting to retrieve cross-signing user-signing private key");let e=null;try{e=(await this._crossSigningInfo.getCrossSigningKey("user_signing",o.getId("user_signing")))[1],u.logger.info("Got cross-signing user-signing private key")}finally{e&&e.free()}}if(i){const e=this._crossSigningInfo.keys.master;await this._signObject(e);const t=e.signatures[this._userId]["ed25519:"+this._deviceId];f[this._crossSigningInfo.getId()]=Object.assign({},e,{signatures:{[this._userId]:{["ed25519:"+this._deviceId]:t}}})}const g=Object.keys(f);if(g.length){const e=({shouldEmit:t})=>(u.logger.info(`Starting background key sig upload for ${g}`),this._baseApis.uploadKeySignatures({[this._userId]:f}).then((n=>{const{failures:o}=n||{};if(u.logger.info(`Finished background key sig upload for ${g}`),Object.keys(o||[]).length>0)throw t&&this._baseApis.emit("crypto.keySignatureUploadFailure",o,"checkOwnCrossSigningTrust",e),new C.KeySignatureUploadError("Key upload failed",{failures:o})})).catch((e=>{u.logger.error(`Error during background key sig upload for ${g}`,e)})));e({shouldEmit:!0})}this.emit("userTrustStatusChanged",t,this.checkUserTrust(t)),i&&(this._baseApis.emit("crossSigning.keysChanged",{}),await this._afterCrossSigningLocalKeyChange()),await this.checkKeyBackup()},B.prototype._storeTrustedSelfKeys=async function(e){e?this._crossSigningInfo.setKeys(e):this._crossSigningInfo.clearKeys(),await this._cryptoStore.doTxn("readwrite",[y.IndexedDBCryptoStore.STORE_ACCOUNT],(e=>{this._cryptoStore.storeCrossSigningKeys(e,this._crossSigningInfo.keys)}))},B.prototype._checkDeviceVerifications=async function(e){const t=this._baseApis._cryptoCallbacks.shouldUpgradeDeviceVerifications;if(t){if(u.logger.info(`Starting device verification upgrade for ${e}`),this._crossSigningInfo.keys.user_signing){const n=this._deviceList.getStoredCrossSigningForUser(e);if(n){const o=await this._checkForDeviceVerificationUpgrade(e,n);o&&(await t({users:{[e]:o}})).includes(e)&&await this._baseApis.setDeviceVerified(e,n.getId())}}u.logger.info(`Finished device verification upgrade for ${e}`)}},B.prototype._checkAndStartKeyBackup=async function(){if(u.logger.log("Checking key backup status..."),this._baseApis.isGuest())return u.logger.log("Skipping key backup check since user is guest"),this._checkedForBackup=!0,null;let e;try{e=await this._baseApis.getKeyBackupVersion()}catch(e){return u.logger.log("Error checking for active key backup",e),404===e.httpStatus&&(this._checkedForBackup=!0),null}this._checkedForBackup=!0;const t=await this.isKeyBackupTrusted(e);return t.usable&&!this.backupInfo?(u.logger.log("Found usable key backup v"+e.version+": enabling key backups"),this._baseApis.enableKeyBackup(e)):!t.usable&&this.backupInfo?(u.logger.log("No usable key backup: disabling key backup"),this._baseApis.disableKeyBackup()):t.usable||this.backupInfo?t.usable&&this.backupInfo&&(e.version!==this.backupInfo.version?(u.logger.log("On backup version "+this.backupInfo.version+" but found version "+e.version+": switching."),this._baseApis.disableKeyBackup(),this._baseApis.enableKeyBackup(e),await this.scheduleAllGroupSessionsForBackup()):u.logger.log("Backup version "+e.version+" still current")):u.logger.log("No usable key backup: not enabling key backup"),{backupInfo:e,trustInfo:t}},B.prototype.setTrustedBackupPubKey=async function(e){this._sessionStore.setLocalTrustedBackupPubKey(e),await this.checkKeyBackup()},B.prototype.checkKeyBackup=async function(){return this._checkedForBackup=!1,this._checkAndStartKeyBackup()},B.prototype.isKeyBackupTrusted=async function(e){const t={usable:!1,trusted_locally:!1,sigs:[]};if(!(e&&e.algorithm&&e.auth_data&&e.auth_data.public_key&&e.auth_data.signatures))return u.logger.info("Key backup is absent or missing required data"),t;const n=this._sessionStore.getLocalTrustedBackupPubKey();e.auth_data.public_key===n&&(u.logger.info("Backup public key "+n+" is trusted locally"),t.trusted_locally=!0);const o=e.auth_data.signatures[this._userId]||[];for(const n of Object.keys(o)){const o=n.split(":");if("ed25519"!==o[0]){u.logger.log("Ignoring unknown signature type: "+o[0]);continue}const r={deviceId:o[1]},i=this._crossSigningInfo.getId();if(i===r.deviceId){r.crossSigningId=!0;try{await d.verifySignature(this._olmDevice,e.auth_data,this._userId,r.deviceId,i),r.valid=!0}catch(e){u.logger.warning("Bad signature from cross signing key "+i,e),r.valid=!1}t.sigs.push(r);continue}const a=this._deviceList.getStoredDevice(this._userId,r.deviceId);if(a){r.device=a,r.deviceTrust=await this.checkDeviceTrust(this._userId,r.deviceId);try{await d.verifySignature(this._olmDevice,e.auth_data,this._userId,a.deviceId,a.getFingerprint()),r.valid=!0}catch(t){u.logger.info("Bad signature from key ID "+n+" userID "+this._userId+" device ID "+a.deviceId+" fingerprint: "+a.getFingerprint(),e.auth_data,t),r.valid=!1}}else r.valid=null,u.logger.info("Ignoring signature from unknown key "+n);t.sigs.push(r)}return t.usable=t.sigs.some((e=>e.valid&&(e.device&&e.deviceTrust.isVerified()||e.crossSigningId))),t.usable|=t.trusted_locally,t},B.prototype.enableLazyLoading=function(){this._lazyLoadMembers=!0},B.prototype.registerEventHandlers=function(e){const t=this;e.on("RoomMember.membership",(function(e,n,o){try{t._onRoomMembership(e,n,o)}catch(e){u.logger.error("Error handling membership change:",e)}})),e.on("toDeviceEvent",t._onToDeviceEvent.bind(t));const n=t._onTimelineEvent.bind(t);e.on("Room.timeline",n),e.on("Event.decrypted",n)},B.prototype.start=function(){this._outgoingRoomKeyRequestManager.start()},B.prototype.stop=function(){this._outgoingRoomKeyRequestManager.stop(),this._deviceList.stop(),this._dehydrationManager.stop()},B.getOlmVersion=function(){return l.OlmDevice.getOlmVersion()},B.prototype.getDeviceEd25519Key=function(){return this._olmDevice.deviceEd25519Key},B.prototype.getDeviceCurve25519Key=function(){return this._olmDevice.deviceCurve25519Key},B.prototype.setGlobalBlacklistUnverifiedDevices=function(e){this._globalBlacklistUnverifiedDevices=e},B.prototype.getGlobalBlacklistUnverifiedDevices=function(){return this._globalBlacklistUnverifiedDevices},B.prototype.setGlobalErrorOnUnknownDevices=function(e){this._globalErrorOnUnknownDevices=e},B.prototype.getGlobalErrorOnUnknownDevices=function(){return this._globalErrorOnUnknownDevices},B.prototype.uploadDeviceKeys=function(){const e=this,t=e._userId,n=e._deviceId,o={algorithms:e._supportedAlgorithms,device_id:n,keys:e._deviceKeys,user_id:t};return e._signObject(o).then((()=>e._baseApis.uploadKeysRequest({device_keys:o})))},B.prototype.updateOneTimeKeyCount=function(e){if(!isFinite(e))throw new TypeError("Parameter for updateOneTimeKeyCount has to be a number");this._oneTimeKeyCount=e},B.prototype.setNeedsNewFallback=function(e){this._needsNewFallback=!!e},B.prototype.getNeedsNewFallback=function(){return this._needsNewFallback},B.prototype.downloadKeys=function(e,t){return this._deviceList.downloadKeys(e,t)},B.prototype.getStoredDevicesForUser=function(e){return this._deviceList.getStoredDevicesForUser(e)},B.prototype.getStoredDevice=function(e,t){return this._deviceList.getStoredDevice(e,t)},B.prototype.saveDeviceList=function(e){return this._deviceList.saveIfDirty(e)},B.prototype.setDeviceVerification=async function(e,t,n,o,r){void 0===n&&(n=null),void 0===o&&(o=null),void 0===r&&(r=null);const i=this._deviceList.getStoredCrossSigningForUser(e);if(i&&i.getId()===t){if(null!==o||null!==r)throw new Error("Cannot set blocked or known for a cross-signing key");if(!n)throw new Error("Cannot set a cross-signing key as unverified");if(this._crossSigningInfo.getId()||e!==this._crossSigningInfo.userId||(this._storeTrustedSelfKeys(i.keys),this.emit("userTrustStatusChanged",this._userId,this.checkUserTrust(e))),e!==this._userId){u.logger.info("Master key "+i.getId()+" for "+e+" marked verified. Signing...");const n=await this._crossSigningInfo.signUser(i);if(n){const o=async({shouldEmit:r})=>{u.logger.info("Uploading signature for "+e+"...");const i=await this._baseApis.uploadKeySignatures({[e]:{[t]:n}}),{failures:a}=i||{};if(Object.keys(a||[]).length>0)throw r&&this._baseApis.emit("crypto.keySignatureUploadFailure",a,"setDeviceVerification",o),new C.KeySignatureUploadError("Key upload failed",{failures:a})};await o({shouldEmit:!0})}return n}return i}const a=this._deviceList.getRawStoredDevicesForUser(e);if(!a||!a[t])throw new Error("Unknown device "+e+":"+t);const s=a[t];let c=s.verified;n?c=I.VERIFIED:null!==n&&c==I.VERIFIED&&(c=I.UNVERIFIED),o?c=I.BLOCKED:null!==o&&c==I.BLOCKED&&(c=I.UNVERIFIED);let l=s.known;if(null!==r&&(l=r),s.verified===c&&s.known===l||(s.verified=c,s.known=l,this._deviceList.storeDevicesForUser(e,a),this._deviceList.saveIfDirty()),n&&e===this._userId){let n;if(u.logger.info("Own device "+t+" marked verified: signing"),this.checkDeviceTrust(e,t).isCrossSigningVerified()?u.logger.log(`Own device ${t} already cross-signing verified`):n=await this._crossSigningInfo.signDevice(e,p.DeviceInfo.fromStorage(s,t)),n){const o=async({shouldEmit:r})=>{u.logger.info("Uploading signature for "+t);const i=await this._baseApis.uploadKeySignatures({[e]:{[t]:n}}),{failures:a}=i||{};if(Object.keys(a||[]).length>0)throw r&&this._baseApis.emit("crypto.keySignatureUploadFailure",a,"setDeviceVerification",o),new C.KeySignatureUploadError("Key upload failed",{failures:a})};await o({shouldEmit:!0})}}const d=p.DeviceInfo.fromStorage(s,t);return this.emit("deviceVerificationChanged",e,t,d),d},B.prototype.findVerificationRequestDMInProgress=function(e){return this._inRoomVerificationRequests.findRequestInProgress(e)},B.prototype.getVerificationRequestsToDeviceInProgress=function(e){return this._toDeviceVerificationRequests.getRequestsInProgress(e)},B.prototype.requestVerificationDM=function(e,t){const n=this._inRoomVerificationRequests.findRequestInProgress(t);if(n)return Promise.resolve(n);const o=new D.InRoomChannel(this._baseApis,t,e);return this._requestVerificationWithChannel(e,o,this._inRoomVerificationRequests)},B.prototype.requestVerification=function(e,t){t||(t=Object.keys(this._deviceList.getRawStoredDevicesForUser(e)));const n=this._toDeviceVerificationRequests.findRequestInProgress(e,t);if(n)return Promise.resolve(n);const o=new S.ToDeviceChannel(this._baseApis,e,t,S.ToDeviceChannel.makeTransactionId());return this._requestVerificationWithChannel(e,o,this._toDeviceVerificationRequests)},B.prototype._requestVerificationWithChannel=async function(e,t,n){let o=new k.VerificationRequest(t,this._verificationMethods,this._baseApis);t.transactionId&&n.setRequestByChannel(t,o),await o.sendRequest();const r=n.getRequestByChannel(t);return r?o=r:(u.logger.log(`Crypto: adding new request to requestsByTxnId with id ${t.transactionId} ${t.roomId}`),n.setRequestByChannel(t,o)),o},B.prototype.beginKeyVerification=function(e,t,n,o=null){let r;if(o){if(r=this._toDeviceVerificationRequests.getRequestBySenderAndTxnId(t,o),!r)throw new Error(`No request found for user ${t} with transactionId ${o}`)}else{o=S.ToDeviceChannel.makeTransactionId();const e=new S.ToDeviceChannel(this._baseApis,t,[n],o,n);r=new k.VerificationRequest(e,this._verificationMethods,this._baseApis),this._toDeviceVerificationRequests.setRequestBySenderAndTxnId(t,o,r)}return r.beginKeyVerification(e,{userId:t,deviceId:n})},B.prototype.legacyDeviceVerification=async function(e,t,n){const o=S.ToDeviceChannel.makeTransactionId(),r=new S.ToDeviceChannel(this._baseApis,e,[t],o,t),i=new k.VerificationRequest(r,this._verificationMethods,this._baseApis);this._toDeviceVerificationRequests.setRequestBySenderAndTxnId(e,o,i);const a=i.beginKeyVerification(n,{userId:e,deviceId:t});return await Promise.race([a.verify(),i.waitFor((e=>e.started))]),i},B.prototype.getOlmSessionsForUser=async function(e){const t=this.getStoredDevicesForUser(e)||[],n={};for(let e=0;e0)return null;if(e.isKeySourceUntrusted())return null;const o=this._deviceList.getDeviceByIdentityKey(n,t);if(null===o)return null;const r=e.getClaimedEd25519Key();return r?r!==o.getFingerprint()?(u.logger.warn("Event "+e.getId()+" claims ed25519 key "+r+" but sender device has key "+o.getFingerprint()),null):o:(u.logger.warn("Event "+e.getId()+" claims no ed25519 key: cannot verify sending device"),null)},B.prototype.getEventEncryptionInfo=function(e){const t={};if(t.senderKey=e.getSenderKey(),t.algorithm=e.getWireContent().algorithm,!t.senderKey||!t.algorithm)return t.encrypted=!1,t;t.encrypted=!0,e.getForwardingCurve25519KeyChain().length>0||e.isKeySourceUntrusted()?t.authenticated=!1:t.authenticated=!0,t.sender=this._deviceList.getDeviceByIdentityKey(t.algorithm,t.senderKey);const n=e.getClaimedEd25519Key();return n||(u.logger.warn("Event "+e.getId()+" claims no ed25519 key: cannot verify sending device"),t.mismatchedSender=!0),t.sender&&n!==t.sender.getFingerprint()&&(u.logger.warn("Event "+e.getId()+" claims ed25519 key "+n+"but sender device has key "+t.sender.getFingerprint()),t.mismatchedSender=!0),t},B.prototype.forceDiscardSession=function(e){const t=this._roomEncryptors[e];if(void 0===t)throw new Error("Room not encrypted");if(void 0===t.forceDiscardSession)throw new Error("Room encryption algorithm doesn't support session discarding");t.forceDiscardSession()},B.prototype.setRoomEncryption=async function(e,t,n){if(!t.algorithm)return void u.logger.log("Ignoring setRoomEncryption with no algorithm");const o=this._roomList.getRoomEncryption(e);if(o&&JSON.stringify(o)!=JSON.stringify(t))return void u.logger.error("Ignoring m.room.encryption event which requests a change of config in "+e);if(this._roomEncryptors[e])return;let r=null;o||(r=this._roomList.setRoomEncryption(e,t));const i=f.ENCRYPTION_CLASSES[t.algorithm];if(!i)throw new Error("Unable to encrypt with "+t.algorithm);const a=new i({userId:this._userId,deviceId:this._deviceId,crypto:this,olmDevice:this._olmDevice,baseApis:this._baseApis,roomId:e,config:t});this._roomEncryptors[e]=a,r&&await r,this._lazyLoadMembers?u.logger.log("Enabling encryption in "+e):(u.logger.log("Enabling encryption in "+e+"; starting to track device lists for all users therein"),await this.trackRoomDevices(e),this.inhibitDeviceQuery||this._deviceList.refreshOutdatedDeviceLists())},B.prototype.trackRoomDevices=function(e){let t=this._roomDeviceTrackingState[e];return t||(t=(async()=>{if(!this._roomEncryptors[e])return;const t=this._clientStore.getRoom(e);if(!t)throw new Error(`Unable to start tracking devices in unknown room ${e}`);u.logger.log(`Starting to track devices for room ${e} ...`),(await t.getEncryptionTargetMembers()).forEach((e=>{this._deviceList.startTrackingDeviceList(e.userId)}))})(),this._roomDeviceTrackingState[e]=t.catch((t=>{throw this._roomDeviceTrackingState[e]=null,t}))),t},B.prototype.ensureOlmSessionsForUsers=function(e){const t={};for(let n=0;n{this._cryptoStore.getAllEndToEndInboundGroupSessions(t,(t=>{if(null===t)return;const n=this._olmDevice.exportInboundGroupSession(t.senderKey,t.sessionId,t.sessionData);delete n.first_known_index,n.algorithm=d.MEGOLM_ALGORITHM,e.push(n)}))})),e},B.prototype.importRoomKeys=function(e,t={}){let n=0,o=0;const r=e.length;function i(){t.progressCallback({stage:"load_keys",successes:n,failures:o,total:r})}return Promise.all(e.map((e=>e.room_id&&e.algorithm?this._getRoomDecryptor(e.room_id,e.algorithm).importRoomKey(e,t).finally((e=>{n++,t.progressCallback&&i()})):(u.logger.warn("ignoring room key entry with missing fields",e),o++,t.progressCallback&&i(),null))))},B.prototype.scheduleKeyBackupSend=async function(e=1e4){if(!this._sendingBackups){this._sendingBackups=!0;try{const t=Math.random()*e;await(0,c.sleep)(t);let n=0;for(;;){if(!this.backupKey)return;try{if(0===await this._backupPendingKeys(200))return;n=0}catch(e){if(n++,u.logger.log("Key backup request failed",e),e.data&&("M_NOT_FOUND"==e.data.errcode||"M_WRONG_ROOM_KEYS_VERSION"==e.data.errcode))throw await this.checkKeyBackup(),this.emit("crypto.keyBackupFailed",e.data.errcode),e}n&&await(0,c.sleep)(1e3*Math.pow(2,Math.min(n-1,4)))}}finally{this._sendingBackups=!1}}},B.prototype._backupPendingKeys=async function(e){const t=await this._cryptoStore.getSessionsNeedingBackup(e);if(!t.length)return 0;let n=await this._cryptoStore.countSessionsNeedingBackup();this.emit("crypto.keyBackupSessionsRemaining",n);const o={};for(const e of t){const t=e.sessionData.room_id;void 0===o[t]&&(o[t]={sessions:{}});const n=await this._olmDevice.exportInboundGroupSession(e.senderKey,e.sessionId,e.sessionData);n.algorithm=d.MEGOLM_ALGORITHM,delete n.session_id,delete n.room_id;const r=n.first_known_index;delete n.first_known_index;const i=this.backupKey.encrypt(JSON.stringify(n)),a=(n.forwarding_curve25519_key_chain||[]).length,s=this._deviceList.getUserByIdentityKey(d.MEGOLM_ALGORITHM,e.senderKey),u=this._deviceList.getDeviceByIdentityKey(d.MEGOLM_ALGORITHM,e.senderKey),c=this._checkDeviceInfoTrust(s,u).isVerified();o[t].sessions[e.sessionId]={first_message_index:r,forwarded_count:a,is_verified:c,session_data:i}}return await this._baseApis.sendKeyBackup(void 0,void 0,this.backupInfo.version,{rooms:o}),await this._cryptoStore.unmarkSessionsNeedingBackup(t),n=await this._cryptoStore.countSessionsNeedingBackup(),this.emit("crypto.keyBackupSessionsRemaining",n),t.length},B.prototype.backupGroupSession=async function(e,t,n,o,r,i,a){await this._cryptoStore.markSessionsNeedingBackup([{senderKey:t,sessionId:o}]),this.backupInfo&&this.scheduleKeyBackupSend()},B.prototype.scheduleAllGroupSessionsForBackup=async function(){await this.flagAllGroupSessionsForBackup(),this.scheduleKeyBackupSend(0)},B.prototype.flagAllGroupSessionsForBackup=async function(){await this._cryptoStore.doTxn("readwrite",[y.IndexedDBCryptoStore.STORE_INBOUND_GROUP_SESSIONS,y.IndexedDBCryptoStore.STORE_BACKUP],(e=>{this._cryptoStore.getAllEndToEndInboundGroupSessions(e,(t=>{null!==t&&this._cryptoStore.markSessionsNeedingBackup([t],e)}))}));const e=await this._cryptoStore.countSessionsNeedingBackup();return this.emit("crypto.keyBackupSessionsRemaining",e),e},B.prototype.countSessionsNeedingBackup=function(){return this._cryptoStore.countSessionsNeedingBackup()},B.prototype.prepareToEncrypt=function(e){const t=e.roomId,n=this._roomEncryptors[t];n&&n.prepareToEncrypt(e)},B.prototype.encryptEvent=async function(e,t){if(!t)throw new Error("Cannot send encrypted messages in unknown rooms");const n=e.getRoomId(),o=this._roomEncryptors[n];if(!o)throw new Error("Room was previously configured to use encryption, but is no longer. Perhaps the homeserver is hiding the configuration event.");this._roomDeviceTrackingState[n]||this.trackRoomDevices(n),await this._roomDeviceTrackingState[n];let r=e.getContent();const i=r["m.relates_to"];i&&(r=Object.assign({},r),delete r["m.relates_to"]);const a=await o.encryptMessage(t,e.getType(),r);i&&(a["m.relates_to"]=i),e.makeEncrypted("m.room.encrypted",a,this._olmDevice.deviceCurve25519Key,this._olmDevice.deviceEd25519Key)},B.prototype.decryptEvent=async function(e){if(e.isRedacted()){const t=new R.MatrixEvent(e.getUnsigned().redacted_because),n=await this.decryptEvent(t);return{clearEvent:{room_id:e.getRoomId(),type:"m.room.message",content:{},unsigned:{redacted_because:n.clearEvent}}}}{const t=e.getWireContent(),n=this._getRoomDecryptor(e.getRoomId(),t.algorithm);return await n.decryptEvent(e)}},B.prototype.handleDeviceListChanges=async function(e,t){e.oldSyncToken&&await this._evalDeviceListChanges(t)},B.prototype.requestRoomKey=function(e,t,n=!1){return this._outgoingRoomKeyRequestManager.queueRoomKeyRequest(e,t,n).then((()=>{this._sendKeyRequestsImmediately&&this._outgoingRoomKeyRequestManager.sendQueuedRequests()})).catch((e=>{u.logger.error("Error requesting key for event",e)}))},B.prototype.cancelRoomKeyRequest=function(e){this._outgoingRoomKeyRequestManager.cancelRoomKeyRequest(e).catch((e=>{u.logger.warn("Error clearing pending room key requests",e)}))},B.prototype.cancelAndResendAllOutgoingKeyRequests=function(){return this._outgoingRoomKeyRequestManager.cancelAndResendAllOutgoingRequests()},B.prototype.onCryptoEvent=async function(e){const t=e.getRoomId(),n=e.getContent();try{await this.setRoomEncryption(t,n,!0)}catch(e){u.logger.error("Error configuring encryption in room "+t+":",e)}},B.prototype.onSyncWillProcess=async function(e){e.oldSyncToken||(u.logger.log("Initial sync performed - resetting device tracking state"),this._deviceList.stopTrackingAllDeviceLists(),this._deviceList.startTrackingDeviceList(this._userId),this._roomDeviceTrackingState={}),this._sendKeyRequestsImmediately=!1},B.prototype.onSyncCompleted=async function(e){const t=e.nextSyncToken;this._deviceList.setSyncToken(e.nextSyncToken),this._deviceList.saveIfDirty(),this._deviceList.lastKnownSyncToken=t,this._deviceList.startTrackingDeviceList(this._userId),this._deviceList.refreshOutdatedDeviceLists(),e.catchingUp||(function(e){if(e._oneTimeKeyCheckInProgress)return;const t=Date.now();if(null!==e._lastOneTimeKeyCheck&&t-e._lastOneTimeKeyCheck<6e4)return;e._lastOneTimeKeyCheck=t;const n=e._olmDevice.maxNumberOfOneTimeKeys(),o=Math.floor(n/2);e._oneTimeKeyCheckInProgress=!0,Promise.resolve().then((()=>void 0!==e._oneTimeKeyCount?Promise.resolve(e._oneTimeKeyCount):e._baseApis.uploadKeysRequest({}).then((e=>e.one_time_key_counts.signed_curve25519||0)))).then((t=>async function(t){for(;o>t||e.getNeedsNewFallback();){if(o>t){u.logger.info("generating oneTimeKeys");const n=Math.min(o-t,5);await e._olmDevice.generateOneTimeKeys(n)}e.getNeedsNewFallback()&&(u.logger.info("generating fallback key"),await e._olmDevice.generateFallbackKey()),u.logger.info("calling _uploadOneTimeKeys");const n=await L(e);if(!n.one_time_key_counts||!n.one_time_key_counts.signed_curve25519)throw new Error("response for uploading keys does not contain one_time_key_counts.signed_curve25519");t=n.one_time_key_counts.signed_curve25519}}(t))).catch((e=>{u.logger.error("Error uploading one-time keys",e.stack||e)})).finally((()=>{e._oneTimeKeyCount=void 0,e._oneTimeKeyCheckInProgress=!1}))}(this),this._processReceivedRoomKeyRequests(),this._outgoingRoomKeyRequestManager.sendQueuedRequests(),this._sendKeyRequestsImmediately=!0)},B.prototype._evalDeviceListChanges=async function(e){if(e.changed&&Array.isArray(e.changed)&&e.changed.forEach((e=>{this._deviceList.invalidateUserDeviceList(e)})),e.left&&Array.isArray(e.left)&&e.left.length){const t=new Set(await this._getTrackedE2eUsers());e.left.forEach((e=>{t.has(e)||this._deviceList.stopTrackingDeviceList(e)}))}},B.prototype._getTrackedE2eUsers=async function(){const e=[];for(const t of this._getTrackedE2eRooms()){const n=await t.getEncryptionTargetMembers();for(const t of n)e.push(t.userId)}return e},B.prototype._getTrackedE2eRooms=function(){return this._clientStore.getRooms().filter((e=>{if(!this._roomEncryptors[e.roomId])return!1;if(!this._roomDeviceTrackingState[e.roomId])return!1;const t=e.getMyMembership();return"join"===t||"invite"===t}))},B.prototype._onToDeviceEvent=function(e){try{u.logger.log(`received to_device ${e.getType()} from: ${e.getSender()} id: ${e.getId()}`),"m.room_key"==e.getType()||"m.forwarded_room_key"==e.getType()?this._onRoomKeyEvent(e):"m.room_key_request"==e.getType()?this._onRoomKeyRequestEvent(e):"m.secret.request"===e.getType()?this._secretStorage._onRequestReceived(e):"m.secret.send"===e.getType()?this._secretStorage._onSecretReceived(e):"org.matrix.room_key.withheld"===e.getType()?this._onRoomKeyWithheldEvent(e):e.getContent().transaction_id?this._onKeyVerificationMessage(e):"m.bad.encrypted"===e.getContent().msgtype?this._onToDeviceBadEncrypted(e):(e.isBeingDecrypted()||e.shouldAttemptDecryption())&&(e.isBeingDecrypted()||e.attemptDecryption(this),e.once("Event.decrypted",(e=>{this._onToDeviceEvent(e)})))}catch(e){u.logger.error("Error handling toDeviceEvent:",e)}},B.prototype._onRoomKeyEvent=function(e){const t=e.getContent();t.room_id&&t.algorithm?(this._checkedForBackup||this._checkAndStartKeyBackup(),this._getRoomDecryptor(t.room_id,t.algorithm).onRoomKeyEvent(e)):u.logger.error("key event is missing fields")},B.prototype._onRoomKeyWithheldEvent=function(e){const t=e.getContent();if(!(("m.no_olm"===t.code||t.room_id&&t.session_id)&&t.algorithm&&t.sender_key))return void u.logger.error("key withheld event is missing fields");u.logger.info(`Got room key withheld event from ${e.getSender()} (${t.sender_key}) for ${t.algorithm}/${t.room_id}/${t.session_id} with reason ${t.code} (${t.reason})`);const n=this._getRoomDecryptor(t.room_id,t.algorithm);if(n.onRoomKeyWithheldEvent&&n.onRoomKeyWithheldEvent(e),!t.room_id){const e=this._getRoomDecryptors(t.algorithm);for(const n of e)n.retryDecryptionFromSender(t.sender_key)}},B.prototype._onKeyVerificationMessage=function(e){S.ToDeviceChannel.validateEvent(e,this._baseApis)&&this._handleVerificationEvent(e,this._toDeviceVerificationRequests,(e=>{if(!S.ToDeviceChannel.canCreateRequest(S.ToDeviceChannel.getEventType(e)))return;const t=e.getContent(),n=t&&t.from_device;if(!n)return;const o=e.getSender(),r=new S.ToDeviceChannel(this._baseApis,o,[n]);return new k.VerificationRequest(r,this._verificationMethods,this._baseApis)}))},B.prototype._onTimelineEvent=function(e,t,n,o,{liveEvent:r}={}){D.InRoomChannel.validateEvent(e,this._baseApis)&&this._handleVerificationEvent(e,this._inRoomVerificationRequests,(e=>{const t=new D.InRoomChannel(this._baseApis,e.getRoomId());return new k.VerificationRequest(t,this._verificationMethods,this._baseApis)}),r)},B.prototype._handleVerificationEvent=async function(e,t,n,o=!0){let r=t.getRequest(e),i=!1;if(!r){if(r=n(e),!r)return void u.logger.log(`Crypto: could not find VerificationRequest for ${e.getType()}, and could not create one, so ignoring.`);i=!0,t.setRequest(e,r)}e.setVerificationRequest(r);try{await r.channel.handleEvent(e,r,o)}catch(e){u.logger.error("error while handling verification event: "+e.message)}i&&!r.initiatedByMe&&!r.invalid&&!r.observeOnly&&this._baseApis.emit("crypto.verification.request",r)},B.prototype._onToDeviceBadEncrypted=async function(e){const t=e.getWireContent(),n=e.getSender(),o=t.algorithm,r=t.sender_key,i=()=>{const e=this._getRoomDecryptors(d.MEGOLM_ALGORITHM);for(const t of e)t.retryDecryptionFromSender(r)};if(void 0===n||void 0===r||void 0===r)return;this._lastNewSessionForced[n]=this._lastNewSessionForced[n]||{};const a=this._lastNewSessionForced[n][r]||0;if(a+36e5>Date.now())return u.logger.debug("New session already forced with device "+n+":"+r+" at "+a+": not forcing another"),await this._olmDevice.recordSessionProblem(r,"wedged",!0),void i();let s=this._deviceList.getDeviceByIdentityKey(o,r);if(!s&&(await this.downloadKeys([n],!1),s=this._deviceList.getDeviceByIdentityKey(o,r),!s))return u.logger.info("Couldn't find device for identity key "+r+": not re-establishing session"),await this._olmDevice.recordSessionProblem(r,"wedged",!1),void i();const c={};c[n]=[s],await d.ensureOlmSessionsForDevices(this._olmDevice,this._baseApis,c,!0),this._lastNewSessionForced[n][r]=Date.now();const l={algorithm:d.OLM_ALGORITHM,sender_key:this._olmDevice.deviceCurve25519Key,ciphertext:{}};await d.encryptMessageForDevice(l.ciphertext,this._userId,this._deviceId,this._olmDevice,n,s,{type:"m.dummy"}),await this._olmDevice.recordSessionProblem(r,"wedged",!0),i(),await this._baseApis.sendToDevice("m.room.encrypted",{[n]:{[s.deviceId]:l}});const h=await this._outgoingRoomKeyRequestManager.getOutgoingSentRoomKeyRequest(n,s.deviceId);for(const e of h)this.requestRoomKey(e.requestBody,e.recipients,!0)},B.prototype._onRoomMembership=function(e,t,n){const o=t.roomId,r=this._roomEncryptors[o];r&&(this._roomDeviceTrackingState[o]&&("join"==t.membership?(u.logger.log("Join event for "+t.userId+" in "+o),this._deviceList.startTrackingDeviceList(t.userId)):"invite"==t.membership&&this._clientStore.getRoom(o).shouldEncryptForInvitedMembers()&&(u.logger.log("Invite event for "+t.userId+" in "+o),this._deviceList.startTrackingDeviceList(t.userId))),r.onRoomMembership(e,t,n))},B.prototype._onRoomKeyRequestEvent=function(e){const t=e.getContent();if("request"===t.action){const t=new P(e);this._receivedRoomKeyRequests.push(t)}else if("request_cancellation"===t.action){const t=new U(e);this._receivedRoomKeyRequestCancellations.push(t)}},B.prototype._processReceivedRoomKeyRequests=async function(){if(!this._processingRoomKeyRequests){this._processingRoomKeyRequests=!0;try{const e=this._receivedRoomKeyRequests;this._receivedRoomKeyRequests=[];const t=this._receivedRoomKeyRequestCancellations;this._receivedRoomKeyRequestCancellations=[],await Promise.all(e.map((e=>this._processReceivedRoomKeyRequest(e)))),await Promise.all(t.map((e=>this._processReceivedRoomKeyRequestCancellation(e))))}catch(e){u.logger.error(`Error processing room key requsts: ${e}`)}finally{this._processingRoomKeyRequests=!1}}},B.prototype._processReceivedRoomKeyRequest=async function(e){const t=e.userId,n=e.deviceId,o=e.requestBody,r=o.room_id,i=o.algorithm;if(u.logger.log(`m.room_key_request from ${t}:${n} for ${r} / ${o.session_id} (id ${e.requestId})`),t!==this._userId){if(!this._roomEncryptors[r])return void u.logger.debug(`room key request for unencrypted room ${r}`);const e=this._roomEncryptors[r],i=this._deviceList.getStoredDevice(t,n);if(!i)return void u.logger.debug(`Ignoring keyshare for unknown device ${t}:${n}`);try{await e.reshareKeyWithDevice(o.sender_key,o.session_id,t,i)}catch(e){u.logger.warn("Failed to re-share keys for session "+o.session_id+" with device "+t+":"+i.deviceId,e)}return}if(n===this._deviceId)return void u.logger.log("Ignoring room key request from ourselves");if(!this._roomDecryptors[r])return void u.logger.log(`room key request for unencrypted room ${r}`);const a=this._roomDecryptors[r][i];if(a)if(await a.hasKeysForKeyRequest(e)){if(e.share=()=>{a.shareKeysWithDevice(e)},this.checkDeviceTrust(t,n).isVerified())return u.logger.log("device is already verified: sharing keys"),void e.share();this.emit("crypto.roomKeyRequest",e)}else u.logger.log(`room key request for unknown session ${r} / `+o.session_id);else u.logger.log(`room key request for unknown alg ${i} in room ${r}`)},B.prototype._processReceivedRoomKeyRequestCancellation=async function(e){u.logger.log(`m.room_key_request cancellation for ${e.userId}:${e.deviceId} (id ${e.requestId})`),this.emit("crypto.roomKeyRequestCancellation",e)},B.prototype._getRoomDecryptor=function(e,t){let n,o;if((e=e||null)&&(n=this._roomDecryptors[e],n||(this._roomDecryptors[e]=n={}),o=n[t],o))return o;const r=f.DECRYPTION_CLASSES[t];if(!r)throw new f.DecryptionError("UNKNOWN_ENCRYPTION_ALGORITHM",'Unknown encryption algorithm "'+t+'".');return o=new r({userId:this._userId,crypto:this,olmDevice:this._olmDevice,baseApis:this._baseApis,roomId:e}),n&&(n[t]=o),o},B.prototype._getRoomDecryptors=function(e){const t=[];for(const n of Object.values(this._roomDecryptors))e in n&&t.push(n[e]);return t},B.prototype._signObject=async function(e){const t=e.signatures||{},n=e.unsigned;delete e.signatures,delete e.unsigned,t[this._userId]=t[this._userId]||{},t[this._userId]["ed25519:"+this._deviceId]=await this._olmDevice.sign(i.default.stringify(e)),e.signatures=t,void 0!==n&&(e.unsigned=n)};class P{constructor(e){const t=e.getContent();this.userId=e.getSender(),this.deviceId=t.requesting_device_id,this.requestId=t.request_id,this.requestBody=t.body||{},this.share=()=>{throw new Error("don't know how to share keys for this request yet")}}}class U{constructor(e){const t=e.getContent();this.userId=e.getSender(),this.deviceId=t.requesting_device_id,this.requestId=t.request_id}}},91597:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.keyFromAuthData=async function(e,t){if(!n.g.Olm)throw new Error("Olm is not available");if(!e.private_key_salt||!e.private_key_iterations)throw new Error("Salt and/or iterations not found: this backup cannot be restored with a passphrase");return await i(t,e.private_key_salt,e.private_key_iterations,e.private_key_bits||256)},t.keyFromPassphrase=async function(e){if(!n.g.Olm)throw new Error("Olm is not available");const t=(0,o.randomString)(32);return{key:await i(e,t,r,256),salt:t,iterations:r}},t.deriveKey=i;var o=n(98401);const r=5e5;async function i(e,t,o,r=256){const i=n.g.crypto.subtle,a=n.g.TextEncoder;if(!i||!a)throw new Error("Password-based backup is not avaiable on this platform");const s=await i.importKey("raw",(new a).encode(e),{name:"PBKDF2"},!1,["deriveBits"]),u=await i.deriveBits({name:"PBKDF2",salt:(new a).encode(t),iterations:o,hash:"SHA-512"},s,r);return new Uint8Array(u)}},32772:(e,t,n)=>{"use strict";var o=n(95318),r=n(20862);Object.defineProperty(t,"__esModule",{value:!0}),t.encryptMessageForDevice=async function(e,t,n,o,r,s,u){const c=s.getIdentityKey(),l=await o.getSessionIdForDevice(c);if(null===l)return;i.logger.log("Using sessionid "+l+" for device "+r+":"+s.deviceId);const d={sender:t,sender_device:n,keys:{ed25519:o.deviceEd25519Key},recipient:r,recipient_keys:{ed25519:s.getFingerprint()}};a.extend(d,u),e[c]=await o.encryptMessage(c,l,JSON.stringify(d))},t.getExistingOlmSessions=async function(e,t,n){const o={},r={},i=[];for(const[t,a]of Object.entries(n))for(const n of a){const a=n.deviceId,s=n.getIdentityKey();i.push((async()=>{const i=await e.getSessionIdForDevice(s,!0);null===i?(o[t]=o[t]||[],o[t].push(n)):(r[t]=r[t]||{},r[t][a]={device:n,sessionId:i})})())}return await Promise.all(i),[o,r]},t.ensureOlmSessionsForDevices=async function(e,t,n,o,r,a,s){"number"==typeof o&&(s=a,a=r,r=o,o=!1),s||(s=i.logger);const c=[],l={},d={};for(const[,t]of Object.entries(n))for(const n of t){const t=n.getIdentityKey();t!==e.deviceCurve25519Key&&(e._sessionsInProgress[t]||(e._sessionsInProgress[t]=new Promise((n=>{d[t]=(...o)=>{delete e._sessionsInProgress[t],n(...o)}}))))}for(const[t,r]of Object.entries(n)){l[t]={};for(const n of r){const r=n.deviceId,i=n.getIdentityKey();if(i===e.deviceCurve25519Key){s.info("Attempted to start session with ourself! Ignoring"),l[t][r]={device:n,sessionId:null};continue}const a=`for ${i} (${t}:${r})`,u=await e.getSessionIdForDevice(i,d[i],s);null!==u&&d[i]&&d[i](),(null===u||o)&&(o?s.info(`Forcing new Olm session ${a}`):s.info(`Making new Olm session ${a}`),c.push([t,r])),l[t][r]={device:n,sessionId:u}}}if(0===c.length)return l;let h,p=`one-time keys for ${c.length} devices`;try{s.debug(`Claiming ${p}`),h=await t.claimOneTimeKeys(c,"signed_curve25519",r),s.debug(`Claimed ${p}`)}catch(e){for(const e of Object.values(d))e();throw s.log(`Failed to claim ${p}`,e,c),e}a&&"failures"in h&&a.push(...Object.keys(h.failures));const f=h.one_time_keys||{},g=[];for(const[t,r]of Object.entries(n)){const n=f[t]||{};for(let i=0;i{d[h]&&d[h](e),l[t][c].sessionId=e}),(e=>{throw d[h]&&d[h](),e}))):(s.warn(`No one-time keys (alg=signed_curve25519) for device ${t}:${c}`),d[h]&&d[h]())}}return p=`Olm sessions for ${g.length} devices`,s.debug(`Starting ${p}`),await Promise.all(g),s.debug(`Started ${p}`),l},t.verifySignature=c,t.pkSign=function(e,t,o,r){let i=!1;if(t instanceof Uint8Array){const e=new n.g.Olm.PkSigning;r=e.init_with_seed(t),t=e,i=!0}const a=e.signatures||{};delete e.signatures;const u=e.unsigned;e.unsigned&&delete e.unsigned;try{const n=a[o]||{};return a[o]=n,n["ed25519:"+r]=t.sign(s.default.stringify(e))}finally{e.signatures=a,u&&(e.unsigned=u),i&&t.free()}},t.pkVerify=function(e,t,o){const r="ed25519:"+t;if(!(e.signatures&&e.signatures[o]&&e.signatures[o][r]))throw new Error("No signature");const i=e.signatures[o][r],a=new n.g.Olm.Utility,u=e.signatures;delete e.signatures;const c=e.unsigned;e.unsigned&&delete e.unsigned;try{a.ed25519_verify(t,s.default.stringify(e),i)}finally{e.signatures=u,c&&(e.unsigned=c),a.free()}},t.encodeBase64=l,t.encodeUnpaddedBase64=function(e){return l(e).replace(/=+$/g,"")},t.decodeBase64=function(e){return Buffer.from(e,"base64")},t.MEGOLM_BACKUP_ALGORITHM=t.MEGOLM_ALGORITHM=t.OLM_ALGORITHM=void 0;var i=n(7434),a=r(n(3102)),s=o(n(69141));async function u(e,t,n,o){const r=o.deviceId;try{await c(e,t,n,r,o.getFingerprint())}catch(e){return i.logger.error("Unable to verify signature on one-time key for device "+n+":"+r+":",e),null}let a;try{a=await e.createOutboundSession(o.getIdentityKey(),t.key)}catch(e){return i.logger.error("Error starting olm session with device "+n+":"+r+": "+e),null}return i.logger.log("Started new olm sessionid "+a+" for device "+n+":"+r),a}async function c(e,t,n,o,r){const i="ed25519:"+o,a=((t.signatures||{})[n]||{})[i];if(!a)throw Error("No signature");const u=Object.assign({},t);delete u.unsigned,delete u.signatures;const c=s.default.stringify(u);e.verifySignature(r,c,a)}function l(e){return Buffer.from(e).toString("base64")}t.OLM_ALGORITHM="m.olm.v1.curve25519-aes-sha2",t.MEGOLM_ALGORITHM="m.megolm.v1.aes-sha2",t.MEGOLM_BACKUP_ALGORITHM="m.megolm_backup.v1.curve25519-aes-sha2"},34077:(e,t,n)=>{"use strict";var o=n(95318);Object.defineProperty(t,"__esModule",{value:!0}),t.encodeRecoveryKey=function(e){const t=new Buffer(i.length+e.length+1);t.set(i,0),t.set(e,i.length);let n=0;for(let e=0;e{"use strict";var o=n(20862);Object.defineProperty(t,"__esModule",{value:!0}),t.upgradeDatabase=function(e,t){r.logger.log(`Upgrading IndexedDBCryptoStore from version ${t} to 10`),t<1&&function(e){const t=e.createObjectStore("outgoingRoomKeyRequests",{keyPath:"requestId"});t.createIndex("session",["requestBody.room_id","requestBody.session_id"]),t.createIndex("state","state")}(e),t<2&&e.createObjectStore("account"),t<3&&e.createObjectStore("sessions",{keyPath:["deviceKey","sessionId"]}).createIndex("deviceKey","deviceKey"),t<4&&e.createObjectStore("inbound_group_sessions",{keyPath:["senderCurve25519Key","sessionId"]}),t<5&&e.createObjectStore("device_data"),t<6&&e.createObjectStore("rooms"),t<7&&e.createObjectStore("sessions_needing_backup",{keyPath:["senderCurve25519Key","sessionId"]}),t<8&&e.createObjectStore("inbound_group_sessions_withheld",{keyPath:["senderCurve25519Key","sessionId"]}),t<9&&(e.createObjectStore("session_problems",{keyPath:["deviceKey","time"]}).createIndex("deviceKey","deviceKey"),e.createObjectStore("notified_error_devices",{keyPath:["userId","deviceId"]})),t<10&&e.createObjectStore("shared_history_inbound_group_sessions",{keyPath:["roomId"]})},t.Backend=t.VERSION=void 0;var r=n(7434),i=o(n(3102));function a(e,t){e._mx_abortexception=t;try{e.abort()}catch(t){}}function s(e){return new Promise(((t,n)=>{e.oncomplete=()=>{void 0!==e._mx_abortexception&&n(e._mx_abortexception),t()},e.onerror=t=>{void 0!==e._mx_abortexception?n(e._mx_abortexception):(r.logger.log("Error performing indexeddb txn",t),n(t.target.error))},e.onabort=t=>{void 0!==e._mx_abortexception?n(e._mx_abortexception):(r.logger.log("Error performing indexeddb txn",t),n(t.target.error))}}))}t.VERSION=10,t.Backend=class{constructor(e){this._db=e,this._nextTxnId=0,e.onversionchange=t=>{r.logger.log(`versionchange for indexeddb ${this._dbName}: closing`),e.close()}}getOrAddOutgoingRoomKeyRequest(e){const t=e.requestBody;return new Promise(((n,o)=>{const i=this._db.transaction("outgoingRoomKeyRequests","readwrite");i.onerror=o,this._getOutgoingRoomKeyRequest(i,t,(o=>{if(o)return r.logger.log(`already have key request outstanding for ${t.room_id} / ${t.session_id}: not sending another`),void n(o);r.logger.log(`enqueueing key request for ${t.room_id} / `+t.session_id),i.oncomplete=()=>{n(e)},i.objectStore("outgoingRoomKeyRequests").add(e)}))}))}getOutgoingRoomKeyRequest(e){return new Promise(((t,n)=>{const o=this._db.transaction("outgoingRoomKeyRequests","readonly");o.onerror=n,this._getOutgoingRoomKeyRequest(o,e,(e=>{t(e)}))}))}_getOutgoingRoomKeyRequest(e,t,n){e.objectStore("outgoingRoomKeyRequests").index("session").openCursor([t.room_id,t.session_id]).onsuccess=e=>{const o=e.target.result;if(!o)return void n(null);const r=o.value;i.deepCompare(r.requestBody,t)?n(r):o.continue()}}getOutgoingRoomKeyRequestByState(e){if(0===e.length)return Promise.resolve(null);let t,n=0;const o=this._db.transaction("outgoingRoomKeyRequests","readonly"),r=o.objectStore("outgoingRoomKeyRequests"),i=e[n];return r.index("state").openCursor(i).onsuccess=function o(r){const i=r.target.result;if(i)return void(t=i.value);if(n++,n>=e.length)return;const a=e[n];r.target.source.openCursor(a).onsuccess=o},s(o).then((()=>t))}getAllOutgoingRoomKeyRequestsByState(e){return new Promise(((t,n)=>{const o=this._db.transaction("outgoingRoomKeyRequests","readonly").objectStore("outgoingRoomKeyRequests").index("state").getAll(e);o.onsuccess=e=>t(e.target.result),o.onerror=e=>n(e.target.error)}))}getOutgoingRoomKeyRequestsByTarget(e,t,n){let o=0;const r=[],i=this._db.transaction("outgoingRoomKeyRequests","readonly"),a=i.objectStore("outgoingRoomKeyRequests"),u=n[o];return a.index("state").openCursor(u).onsuccess=function i(a){const s=a.target.result;if(s){const n=s.value;n.recipients.includes({userId:e,deviceId:t})&&r.push(n),s.continue()}else{if(o++,o>=n.length)return;const e=n[o];a.target.source.openCursor(e).onsuccess=i}},s(i).then((()=>r))}updateOutgoingRoomKeyRequest(e,t,n){let o=null;const i=this._db.transaction("outgoingRoomKeyRequests","readwrite");return i.objectStore("outgoingRoomKeyRequests").openCursor(e).onsuccess=function(e){const i=e.target.result;if(!i)return;const a=i.value;a.state==t?(Object.assign(a,n),i.update(a),o=a):r.logger.warn(`Cannot update room key request from ${t} as it was already updated to ${a.state}`)},s(i).then((()=>o))}deleteOutgoingRoomKeyRequest(e,t){const n=this._db.transaction("outgoingRoomKeyRequests","readwrite");return n.objectStore("outgoingRoomKeyRequests").openCursor(e).onsuccess=e=>{const n=e.target.result;if(!n)return;const o=n.value;o.state==t?n.delete():r.logger.warn(`Cannot delete room key request in state ${o.state} (expected ${t})`)},s(n)}getAccount(e,t){const n=e.objectStore("account").get("-");n.onsuccess=function(){try{t(n.result||null)}catch(t){a(e,t)}}}storeAccount(e,t){e.objectStore("account").put(t,"-")}getCrossSigningKeys(e,t){const n=e.objectStore("account").get("crossSigningKeys");n.onsuccess=function(){try{t(n.result||null)}catch(t){a(e,t)}}}getSecretStorePrivateKey(e,t,n){const o=e.objectStore("account").get(`ssss_cache:${n}`);o.onsuccess=function(){try{t(o.result||null)}catch(t){a(e,t)}}}storeCrossSigningKeys(e,t){e.objectStore("account").put(t,"crossSigningKeys")}storeSecretStorePrivateKey(e,t,n){e.objectStore("account").put(n,`ssss_cache:${t}`)}countEndToEndSessions(e,t){const n=e.objectStore("sessions").count();n.onsuccess=function(){try{t(n.result)}catch(t){a(e,t)}}}getEndToEndSessions(e,t,n){const o=t.objectStore("sessions").index("deviceKey").openCursor(e),r={};o.onsuccess=function(){const e=o.result;if(e)r[e.value.sessionId]={session:e.value.session,lastReceivedMessageTs:e.value.lastReceivedMessageTs},e.continue();else try{n(r)}catch(e){a(t,e)}}}getEndToEndSession(e,t,n,o){const r=n.objectStore("sessions").get([e,t]);r.onsuccess=function(){try{r.result?o({session:r.result.session,lastReceivedMessageTs:r.result.lastReceivedMessageTs}):o(null)}catch(e){a(n,e)}}}getAllEndToEndSessions(e,t){const n=e.objectStore("sessions").openCursor();n.onsuccess=function(){try{const e=n.result;e?(t(e.value),e.continue()):t(null)}catch(t){a(e,t)}}}storeEndToEndSession(e,t,n,o){o.objectStore("sessions").put({deviceKey:e,sessionId:t,session:n.session,lastReceivedMessageTs:n.lastReceivedMessageTs})}async storeEndToEndSessionProblem(e,t,n){const o=this._db.transaction("session_problems","readwrite");return o.objectStore("session_problems").put({deviceKey:e,type:t,fixed:n,time:Date.now()}),s(o)}async getEndToEndSessionProblem(e,t){let n;const o=this._db.transaction("session_problems","readwrite"),r=o.objectStore("session_problems").index("deviceKey").getAll(e);return r.onsuccess=e=>{const o=r.result;if(!o.length)return void(n=null);o.sort(((e,t)=>e.time-t.time));const i=o[o.length-1];for(const e of o)if(e.time>t)return void(n=Object.assign({},e,{fixed:i.fixed}));n=i.fixed?null:i},await s(o),n}async filterOutNotifiedErrorDevices(e){const t=this._db.transaction("notified_error_devices","readwrite").objectStore("notified_error_devices"),n=[];return await Promise.all(e.map((e=>new Promise((o=>{const{userId:r,deviceInfo:i}=e,a=t.get([r,i.deviceId]);a.onsuccess=function(){a.result||(t.put({userId:r,deviceId:i.deviceId}),n.push(e)),o()}}))))),n}getEndToEndInboundGroupSession(e,t,n,o){let r=!1,i=!1;const s=n.objectStore("inbound_group_sessions").get([e,t]);s.onsuccess=function(){try{r=s.result?s.result.session:null,!1!==i&&o(r,i)}catch(e){a(n,e)}};const u=n.objectStore("inbound_group_sessions_withheld").get([e,t]);u.onsuccess=function(){try{i=u.result?u.result.session:null,!1!==r&&o(r,i)}catch(e){a(n,e)}}}getAllEndToEndInboundGroupSessions(e,t){const n=e.objectStore("inbound_group_sessions").openCursor();n.onsuccess=function(){const o=n.result;if(o){try{t({senderKey:o.value.senderCurve25519Key,sessionId:o.value.sessionId,sessionData:o.value.session})}catch(t){a(e,t)}o.continue()}else try{t(null)}catch(t){a(e,t)}}}addEndToEndInboundGroupSession(e,t,n,o){const i=o.objectStore("inbound_group_sessions").add({senderCurve25519Key:e,sessionId:t,session:n});i.onerror=n=>{"ConstraintError"===i.error.name?(n.stopPropagation(),n.preventDefault(),r.logger.log("Ignoring duplicate inbound group session: "+e+" / "+t)):a(o,new Error("Failed to add inbound group session: "+i.error))}}storeEndToEndInboundGroupSession(e,t,n,o){o.objectStore("inbound_group_sessions").put({senderCurve25519Key:e,sessionId:t,session:n})}storeEndToEndInboundGroupSessionWithheld(e,t,n,o){o.objectStore("inbound_group_sessions_withheld").put({senderCurve25519Key:e,sessionId:t,session:n})}getEndToEndDeviceData(e,t){const n=e.objectStore("device_data").get("-");n.onsuccess=function(){try{t(n.result||null)}catch(t){a(e,t)}}}storeEndToEndDeviceData(e,t){t.objectStore("device_data").put(e,"-")}storeEndToEndRoom(e,t,n){n.objectStore("rooms").put(t,e)}getEndToEndRooms(e,t){const n={},o=e.objectStore("rooms").openCursor();o.onsuccess=function(){const r=o.result;if(r)n[r.key]=r.value,r.continue();else try{t(n)}catch(t){a(e,t)}}}getSessionsNeedingBackup(e){return new Promise(((t,n)=>{const o=[],r=this._db.transaction(["sessions_needing_backup","inbound_group_sessions"],"readonly");r.onerror=n,r.oncomplete=function(){t(o)};const i=r.objectStore("sessions_needing_backup"),a=r.objectStore("inbound_group_sessions"),s=i.openCursor();s.onsuccess=function(){const t=s.result;if(t){const n=a.get(t.key);n.onsuccess=function(){o.push({senderKey:n.result.senderCurve25519Key,sessionId:n.result.sessionId,sessionData:n.result.session})},(!e||o.length{const o=t.count();o.onerror=n,o.onsuccess=()=>e(o.result)}))}unmarkSessionsNeedingBackup(e,t){t||(t=this._db.transaction("sessions_needing_backup","readwrite"));const n=t.objectStore("sessions_needing_backup");return Promise.all(e.map((e=>new Promise(((t,o)=>{const r=n.delete([e.senderKey,e.sessionId]);r.onsuccess=t,r.onerror=o})))))}markSessionsNeedingBackup(e,t){t||(t=this._db.transaction("sessions_needing_backup","readwrite"));const n=t.objectStore("sessions_needing_backup");return Promise.all(e.map((e=>new Promise(((t,o)=>{const r=n.put({senderCurve25519Key:e.senderKey,sessionId:e.sessionId});r.onsuccess=t,r.onerror=o})))))}addSharedHistoryInboundGroupSession(e,t,n,o){o||(o=this._db.transaction("shared_history_inbound_group_sessions","readwrite"));const r=o.objectStore("shared_history_inbound_group_sessions"),i=r.get([e]);i.onsuccess=()=>{const{sessions:o}=i.result||{sessions:[]};o.push([t,n]),r.put({roomId:e,sessions:o})}}getSharedHistoryInboundGroupSessions(e,t){t||(t=this._db.transaction("shared_history_inbound_group_sessions","readonly"));const n=t.objectStore("shared_history_inbound_group_sessions").get([e]);return new Promise(((e,t)=>{n.onsuccess=()=>{const{sessions:t}=n.result||{sessions:[]};e(t)},n.onerror=t}))}doTxn(e,t,n,o=r.logger){const i=this._db.transaction(t,e),a=s(i),u=n(i);return a.then((()=>u))}}},57585:(e,t,n)=>{"use strict";var o=n(20862);Object.defineProperty(t,"__esModule",{value:!0}),t.IndexedDBCryptoStore=void 0;var r=n(7434),i=n(84250),a=n(11045),s=o(n(35251)),u=n(19489),c=o(n(33415));class l{constructor(e,t){this._indexedDB=e,this._dbName=t,this._backendPromise=null,this._backend=null}static exists(e,t){return c.exists(e,t)}startup(){return this._backendPromise||(this._backendPromise=new Promise(((e,t)=>{if(!this._indexedDB)return void t(new Error("no indexeddb support available"));r.logger.log(`connecting to indexeddb ${this._dbName}`);const n=this._indexedDB.open(this._dbName,s.VERSION);n.onupgradeneeded=e=>{const t=e.target.result,n=e.oldVersion;s.upgradeDatabase(t,n)},n.onblocked=()=>{r.logger.log("can't yet open IndexedDBCryptoStore because it is open elsewhere")},n.onerror=e=>{r.logger.log("Error connecting to indexeddb",e),t(e.target.error)},n.onsuccess=t=>{const n=t.target.result;r.logger.log(`connected to indexeddb ${this._dbName}`),e(new s.Backend(n))}})).then((e=>e.doTxn("readonly",[l.STORE_INBOUND_GROUP_SESSIONS,l.STORE_INBOUND_GROUP_SESSIONS_WITHHELD],(t=>{e.getEndToEndInboundGroupSession("","",t,(()=>{}))})).then((()=>e)))).catch((e=>{if("VersionError"===e.name)throw r.logger.warn("Crypto DB is too new for us to use!",e),new u.InvalidCryptoStoreError(u.InvalidCryptoStoreError.TOO_NEW);r.logger.warn(`unable to connect to indexeddb ${this._dbName}: falling back to localStorage store: ${e}`);try{return new i.LocalStorageCryptoStore(n.g.localStorage)}catch(e){return r.logger.warn(`unable to open localStorage: falling back to in-memory store: ${e}`),new a.MemoryCryptoStore}})).then((e=>{this._backend=e}))),this._backendPromise}deleteAllData(){return new Promise(((e,t)=>{if(!this._indexedDB)return void t(new Error("no indexeddb support available"));r.logger.log(`Removing indexeddb instance: ${this._dbName}`);const n=this._indexedDB.deleteDatabase(this._dbName);n.onblocked=()=>{r.logger.log("can't yet delete IndexedDBCryptoStore because it is open elsewhere")},n.onerror=e=>{r.logger.log("Error deleting data from indexeddb",e),t(e.target.error)},n.onsuccess=()=>{r.logger.log(`Removed indexeddb instance: ${this._dbName}`),e()}})).catch((e=>{r.logger.warn(`unable to delete IndexedDBCryptoStore: ${e}`)}))}getOrAddOutgoingRoomKeyRequest(e){return this._backend.getOrAddOutgoingRoomKeyRequest(e)}getOutgoingRoomKeyRequest(e){return this._backend.getOutgoingRoomKeyRequest(e)}getOutgoingRoomKeyRequestByState(e){return this._backend.getOutgoingRoomKeyRequestByState(e)}getAllOutgoingRoomKeyRequestsByState(e){return this._backend.getAllOutgoingRoomKeyRequestsByState(e)}getOutgoingRoomKeyRequestsByTarget(e,t,n){return this._backend.getOutgoingRoomKeyRequestsByTarget(e,t,n)}updateOutgoingRoomKeyRequest(e,t,n){return this._backend.updateOutgoingRoomKeyRequest(e,t,n)}deleteOutgoingRoomKeyRequest(e,t){return this._backend.deleteOutgoingRoomKeyRequest(e,t)}getAccount(e,t){this._backend.getAccount(e,t)}storeAccount(e,t){this._backend.storeAccount(e,t)}getCrossSigningKeys(e,t){this._backend.getCrossSigningKeys(e,t)}getSecretStorePrivateKey(e,t,n){this._backend.getSecretStorePrivateKey(e,t,n)}storeCrossSigningKeys(e,t){this._backend.storeCrossSigningKeys(e,t)}storeSecretStorePrivateKey(e,t,n){this._backend.storeSecretStorePrivateKey(e,t,n)}countEndToEndSessions(e,t){this._backend.countEndToEndSessions(e,t)}getEndToEndSession(e,t,n,o){this._backend.getEndToEndSession(e,t,n,o)}getEndToEndSessions(e,t,n){this._backend.getEndToEndSessions(e,t,n)}getAllEndToEndSessions(e,t){this._backend.getAllEndToEndSessions(e,t)}storeEndToEndSession(e,t,n,o){this._backend.storeEndToEndSession(e,t,n,o)}storeEndToEndSessionProblem(e,t,n){return this._backend.storeEndToEndSessionProblem(e,t,n)}getEndToEndSessionProblem(e,t){return this._backend.getEndToEndSessionProblem(e,t)}filterOutNotifiedErrorDevices(e){return this._backend.filterOutNotifiedErrorDevices(e)}getEndToEndInboundGroupSession(e,t,n,o){this._backend.getEndToEndInboundGroupSession(e,t,n,o)}getAllEndToEndInboundGroupSessions(e,t){this._backend.getAllEndToEndInboundGroupSessions(e,t)}addEndToEndInboundGroupSession(e,t,n,o){this._backend.addEndToEndInboundGroupSession(e,t,n,o)}storeEndToEndInboundGroupSession(e,t,n,o){this._backend.storeEndToEndInboundGroupSession(e,t,n,o)}storeEndToEndInboundGroupSessionWithheld(e,t,n,o){this._backend.storeEndToEndInboundGroupSessionWithheld(e,t,n,o)}storeEndToEndDeviceData(e,t){this._backend.storeEndToEndDeviceData(e,t)}getEndToEndDeviceData(e,t){this._backend.getEndToEndDeviceData(e,t)}storeEndToEndRoom(e,t,n){this._backend.storeEndToEndRoom(e,t,n)}getEndToEndRooms(e,t){this._backend.getEndToEndRooms(e,t)}getSessionsNeedingBackup(e){return this._backend.getSessionsNeedingBackup(e)}countSessionsNeedingBackup(e){return this._backend.countSessionsNeedingBackup(e)}unmarkSessionsNeedingBackup(e,t){return this._backend.unmarkSessionsNeedingBackup(e,t)}markSessionsNeedingBackup(e,t){return this._backend.markSessionsNeedingBackup(e,t)}addSharedHistoryInboundGroupSession(e,t,n,o){this._backend.addSharedHistoryInboundGroupSession(e,t,n,o)}getSharedHistoryInboundGroupSessions(e,t){return this._backend.getSharedHistoryInboundGroupSessions(e,t)}doTxn(e,t,n,o){return this._backend.doTxn(e,t,n,o)}}t.IndexedDBCryptoStore=l,l.STORE_ACCOUNT="account",l.STORE_SESSIONS="sessions",l.STORE_INBOUND_GROUP_SESSIONS="inbound_group_sessions",l.STORE_INBOUND_GROUP_SESSIONS_WITHHELD="inbound_group_sessions_withheld",l.STORE_SHARED_HISTORY_INBOUND_GROUP_SESSIONS="shared_history_inbound_group_sessions",l.STORE_DEVICE_DATA="device_data",l.STORE_ROOMS="rooms",l.STORE_BACKUP="sessions_needing_backup"},84250:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.LocalStorageCryptoStore=void 0;var o=n(7434),r=n(11045);const i="crypto.account",a="crypto.cross_signing_keys",s="crypto.notified_error_devices",u="crypto.device_data",c="crypto.inboundgroupsessions/",l="crypto.sessionsneedingbackup";function d(e){return"crypto.sessions/"+e}function h(e){return"crypto.session.problems/"+e}function p(e,t){return c+e+"/"+t}function f(e,t){return"crypto.inboundgroupsessions.withheld/"+e+"/"+t}function g(e){return"crypto.rooms/"+e}class m extends r.MemoryCryptoStore{constructor(e){super(),this.store=e}static exists(e){const t=e.length;for(let n=0;ne.time-t.time)),F(this.store,o,r)}async getEndToEndSessionProblem(e,t){const n=h(e),o=_(this.store,n)||[];if(!o.length)return null;const r=o[o.length-1];for(const e of o)if(e.time>t)return Object.assign({},e,{fixed:r.fixed});return r.fixed?null:r}async filterOutNotifiedErrorDevices(e){const t=_(this.store,s)||{},n=[];for(const o of e){const{userId:e,deviceInfo:r}=o;e in t?r.deviceId in t[e]||(n.push(o),t[e][r.deviceId]=!0):(n.push(o),t[e]={[r.deviceId]:!0})}return F(this.store,s,t),n}getEndToEndInboundGroupSession(e,t,n,o){o(_(this.store,p(e,t)),_(this.store,f(e,t)))}getAllEndToEndInboundGroupSessions(e,t){for(let e=0;e{n.push({senderKey:t,sessionId:r,sessionData:e})})),e&&o.length>=e)break}return Promise.resolve(n)}countSessionsNeedingBackup(){const e=_(this.store,l)||{};return Promise.resolve(Object.keys(e).length)}unmarkSessionsNeedingBackup(e){const t=_(this.store,l)||{};for(const n of e)delete t[n.senderKey+"/"+n.sessionId];return F(this.store,l,t),Promise.resolve()}markSessionsNeedingBackup(e){const t=_(this.store,l)||{};for(const n of e)t[n.senderKey+"/"+n.sessionId]=!0;return F(this.store,l,t),Promise.resolve()}deleteAllData(){return this.store.removeItem(i),Promise.resolve()}getAccount(e,t){t(_(this.store,i))}storeAccount(e,t){F(this.store,i,t)}getCrossSigningKeys(e,t){t(_(this.store,a))}getSecretStorePrivateKey(e,t,n){t(_(this.store,`crypto.ssss_cache.${n}`))}storeCrossSigningKeys(e,t){F(this.store,a,t)}storeSecretStorePrivateKey(e,t,n){F(this.store,`crypto.ssss_cache.${t}`,n)}doTxn(e,t,n){return Promise.resolve(n(null))}}function _(e,t){try{return JSON.parse(e.getItem(t))}catch(e){o.logger.log("Error: Failed to get key %s: %s",t,e.stack||e),o.logger.log(e.stack)}return null}function F(e,t,n){e.setItem(t,JSON.stringify(n))}t.LocalStorageCryptoStore=m},11045:(e,t,n)=>{"use strict";var o=n(20862),r=n(95318);Object.defineProperty(t,"__esModule",{value:!0}),t.MemoryCryptoStore=void 0;var i=r(n(59713)),a=n(7434),s=o(n(3102));function u(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function c(e){for(var t=1;t{const n=this._getOutgoingRoomKeyRequest(t);return n?(a.logger.log(`already have key request outstanding for ${t.room_id} / ${t.session_id}: not sending another`),n):(a.logger.log(`enqueueing key request for ${t.room_id} / `+t.session_id),this._outgoingRoomKeyRequests.push(e),e)}))}getOutgoingRoomKeyRequest(e){return Promise.resolve(this._getOutgoingRoomKeyRequest(e))}_getOutgoingRoomKeyRequest(e){for(const t of this._outgoingRoomKeyRequests)if(s.deepCompare(t.requestBody,e))return t;return null}getOutgoingRoomKeyRequestByState(e){for(const t of this._outgoingRoomKeyRequests)for(const n of e)if(t.state===n)return Promise.resolve(t);return Promise.resolve(null)}getAllOutgoingRoomKeyRequestsByState(e){return Promise.resolve(this._outgoingRoomKeyRequests.filter((t=>t.state==e)))}getOutgoingRoomKeyRequestsByTarget(e,t,n){const o=[];for(const r of this._outgoingRoomKeyRequests)for(const i of n)r.state===i&&r.recipients.includes({userId:e,deviceId:t})&&o.push(r);return Promise.resolve(o)}updateOutgoingRoomKeyRequest(e,t,n){for(const o of this._outgoingRoomKeyRequests)if(o.requestId===e)return o.state!=t?(a.logger.warn(`Cannot update room key request from ${t} as it was already updated to ${o.state}`),Promise.resolve(null)):(Object.assign(o,n),Promise.resolve(o));return Promise.resolve(null)}deleteOutgoingRoomKeyRequest(e,t){for(let n=0;n{Object.entries(n).forEach((([n,o])=>{t(c(c({},o),{},{deviceKey:e,sessionId:n}))}))}))}storeEndToEndSession(e,t,n,o){let r=this._sessions[e];void 0===r&&(r={},this._sessions[e]=r),r[t]=n}async storeEndToEndSessionProblem(e,t,n){const o=this._sessionProblems[e]=this._sessionProblems[e]||[];o.push({type:t,fixed:n,time:Date.now()}),o.sort(((e,t)=>e.time-t.time))}async getEndToEndSessionProblem(e,t){const n=this._sessionProblems[e]||[];if(!n.length)return null;const o=n[n.length-1];for(const e of n)if(e.time>t)return Object.assign({},e,{fixed:o.fixed});return o.fixed?null:o}async filterOutNotifiedErrorDevices(e){const t=this._notifiedErrorDevices,n=[];for(const o of e){const{userId:e,deviceInfo:r}=o;e in t?r.deviceId in t[e]||(n.push(o),t[e][r.deviceId]=!0):(n.push(o),t[e]={[r.deviceId]:!0})}return n}getEndToEndInboundGroupSession(e,t,n,o){const r=e+"/"+t;o(this._inboundGroupSessions[r]||null,this._inboundGroupSessionsWithheld[r]||null)}getAllEndToEndInboundGroupSessions(e,t){for(const e of Object.keys(this._inboundGroupSessions))t({senderKey:e.substr(0,43),sessionId:e.substr(44),sessionData:this._inboundGroupSessions[e]});t(null)}addEndToEndInboundGroupSession(e,t,n,o){const r=e+"/"+t;void 0===this._inboundGroupSessions[r]&&(this._inboundGroupSessions[r]=n)}storeEndToEndInboundGroupSession(e,t,n,o){this._inboundGroupSessions[e+"/"+t]=n}storeEndToEndInboundGroupSessionWithheld(e,t,n,o){const r=e+"/"+t;this._inboundGroupSessionsWithheld[r]=n}getEndToEndDeviceData(e,t){t(this._deviceData)}storeEndToEndDeviceData(e,t){this._deviceData=e}storeEndToEndRoom(e,t,n){this._rooms[e]=t}getEndToEndRooms(e,t){t(this._rooms)}getSessionsNeedingBackup(e){const t=[];for(const n in this._sessionsNeedingBackup)if(this._inboundGroupSessions[n]&&(t.push({senderKey:n.substr(0,43),sessionId:n.substr(44),sessionData:this._inboundGroupSessions[n]}),e&&n.length>=e))break;return Promise.resolve(t)}countSessionsNeedingBackup(){return Promise.resolve(Object.keys(this._sessionsNeedingBackup).length)}unmarkSessionsNeedingBackup(e){for(const t of e){const e=t.senderKey+"/"+t.sessionId;delete this._sessionsNeedingBackup[e]}return Promise.resolve()}markSessionsNeedingBackup(e){for(const t of e){const e=t.senderKey+"/"+t.sessionId;this._sessionsNeedingBackup[e]=!0}return Promise.resolve()}addSharedHistoryInboundGroupSession(e,t,n){const o=this._sharedHistoryInboundGroupSessions[e]||[];o.push([t,n]),this._sharedHistoryInboundGroupSessions[e]=o}getSharedHistoryInboundGroupSessions(e){return Promise.resolve(this._sharedHistoryInboundGroupSessions[e]||[])}doTxn(e,t,n){return Promise.resolve(n(null))}}},41631:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.VerificationBase=t.SwitchStartEventError=void 0;var o=n(24369),r=n(17187),i=n(7434),a=n(23272),s=n(16702),u=n(3075);const c=new Error("Verification timed out");class l extends Error{constructor(e){super(),this.startEvent=e}}t.SwitchStartEventError=l;class d extends r.EventEmitter{constructor(e,t,n,o,r,i){super(),this._channel=e,this._baseApis=t,this.userId=n,this.deviceId=o,this.startEvent=r,this.request=i,this.cancelled=!1,this._done=!1,this._promise=null,this._transactionTimeoutTimer=null}get initiatedByMe(){if(!this.startEvent)return!0;const e=this.startEvent.getSender(),t=this.startEvent.getContent();return e===this._baseApis.getUserId()&&t.from_device===this._baseApis.getDeviceId()}_resetTimer(){i.logger.info("Refreshing/starting the verification transaction timeout timer"),null!==this._transactionTimeoutTimer&&clearTimeout(this._transactionTimeoutTimer),this._transactionTimeoutTimer=setTimeout((()=>{this._done||this.cancelled||(i.logger.info("Triggering verification timeout"),this.cancel(c))}),6e5)}_endTimer(){null!==this._transactionTimeoutTimer&&(clearTimeout(this._transactionTimeoutTimer),this._transactionTimeoutTimer=null)}_send(e,t){return this._channel.send(e,t)}_waitForEvent(e){if(this._done)return Promise.reject(new Error("Verification is already done"));const t=this.request.getEventFromOtherParty(e);return t?Promise.resolve(t):(this._expectedEvent=e,new Promise(((e,t)=>{this._resolveEvent=e,this._rejectEvent=t})))}canSwitchStartEvent(){return!1}switchStartEvent(e){if(this.canSwitchStartEvent(e))if(i.logger.log("Verification Base: switching verification start event",{restartingFlow:!!this._rejectEvent}),this._rejectEvent){const t=this._rejectEvent;this._rejectEvent=void 0,t(new l(e))}else this.startEvent=e}handleEvent(e){if(!this._done)if(e.getType()===this._expectedEvent)"m.key.verification.done"!==this._expectedEvent&&(this._expectedEvent=void 0,this._rejectEvent=void 0,this._resetTimer(),this._resolveEvent(e));else if("m.key.verification.cancel"===e.getType()){const t=this._reject;if(this._reject=void 0,t){const n=e.getContent(),{reason:o,code:r}=n;t(new Error(`Other side cancelled verification because ${o} (${r})`))}}else if(this._expectedEvent){const t=new Error("Unexpected message: expecting "+this._expectedEvent+" but got "+e.getType());if(this._expectedEvent=void 0,this._rejectEvent){const e=this._rejectEvent;this._rejectEvent=void 0,e(t)}this.cancel(t)}}done(){if(this._endTimer(),!this._done)return this.request.onVerifierFinished(),this._resolve(),(0,u.requestKeysDuringVerification)(this._baseApis,this.userId,this.deviceId)}cancel(e){if(this._endTimer(),!this._done){if(this.cancelled=!0,this.request.onVerifierCancelled(),this.userId&&this.deviceId)if(e===c){const e=(0,s.newTimeoutError)();this._send(e.getType(),e.getContent())}else if(e instanceof o.MatrixEvent){if(e.getSender()!==this.userId){const t=e.getContent();"m.key.verification.cancel"===e.getType()?(t.code=t.code||"m.unknown",t.reason=t.reason||t.body||"Unknown reason",this._send("m.key.verification.cancel",t)):this._send("m.key.verification.cancel",{code:"m.unknown",reason:t.body||"Unknown reason"})}}else this._send("m.key.verification.cancel",{code:"m.unknown",reason:e.toString()});null!==this._promise?this._reject&&this._reject(e):this._promise=Promise.reject(e),this.emit("cancel",e)}}verify(){return this._promise||(this._promise=new Promise(((e,t)=>{this._resolve=(...t)=>{this._done=!0,this._endTimer(),e(...t)},this._reject=(...e)=>{this._done=!0,this._endTimer(),t(...e)}})),this._doVerification&&!this._started&&(this._started=!0,this._resetTimer(),Promise.resolve(this._doVerification()).then(this.done.bind(this),this.cancel.bind(this)))),this._promise}async _verifyKeys(e,t,n){const o=[];for(const[r,s]of Object.entries(t)){const t=r.split(":",2)[1],u=this._baseApis.getStoredDevice(e,t);if(u)await n(r,u,s),o.push(t);else{const u=this._baseApis._crypto._deviceList.getStoredCrossSigningForUser(e);u&&u.getId()===t?(await n(r,a.DeviceInfo.fromStorage({keys:{[r]:t}},t),s),o.push(t)):i.logger.warn(`verification: Could not find device ${t} to verify`)}}if(!o.length)throw new Error("No devices could be verified");i.logger.info("Verification completed! Marking devices verified: ",o);for(const t of o)await this._baseApis.setDeviceVerified(e,t)}}t.VerificationBase=d},16702:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.newVerificationError=r,t.errorFactory=i,t.errorFromEvent=function(e){const t=e.getContent();if(t){const{code:e,reason:n}=t;return{code:e,reason:n}}return{code:"Unknown error",reason:"m.unknown"}},t.newInvalidMessageError=t.newUserMismatchError=t.newKeyMismatchError=t.newUnexpectedMessageError=t.newUnknownMethodError=t.newUnknownTransactionError=t.newTimeoutError=t.newUserCancelledError=void 0;var o=n(24369);function r(e,t,n){const r=Object.assign({},{code:e,reason:t},n);return new o.MatrixEvent({type:"m.key.verification.cancel",content:r})}function i(e,t){return function(n){return r(e,t,n)}}const a=i("m.user","Cancelled by user");t.newUserCancelledError=a;const s=i("m.timeout","Timed out");t.newTimeoutError=s;const u=i("m.unknown_transaction","Unknown transaction");t.newUnknownTransactionError=u;const c=i("m.unknown_method","Unknown method");t.newUnknownMethodError=c;const l=i("m.unexpected_message","Unexpected message");t.newUnexpectedMessageError=l;const d=i("m.key_mismatch","Key mismatch");t.newKeyMismatchError=d;const h=i("m.user_error","User mismatch");t.newUserMismatchError=h;const p=i("m.invalid_message","Invalid message");t.newInvalidMessageError=p},4028:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.IllegalMethod=void 0;var o=n(41631);class r extends o.VerificationBase{static factory(...e){return new r(...e)}static get NAME(){return"org.matrix.illegal_method"}async _doVerification(){throw new Error("Verification is not possible with this method")}}t.IllegalMethod=r},51696:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.QRCodeData=t.ReciprocateQRCode=t.SCAN_QR_CODE_METHOD=t.SHOW_QR_CODE_METHOD=void 0;var o=n(41631),r=n(16702),i=n(32772),a=n(7434);t.SHOW_QR_CODE_METHOD="m.qr_code.show.v1",t.SCAN_QR_CODE_METHOD="m.qr_code.scan.v1";class s extends o.VerificationBase{static factory(...e){return new s(...e)}static get NAME(){return"m.reciprocate.v1"}async _doVerification(){if(!this.startEvent)throw new Error("It is not currently possible to start verificationwith this method yet.");const{qrCodeData:e}=this.request;if(this.startEvent.getContent().secret!==e.encodedSharedSecret)throw(0,r.newKeyMismatchError)();await new Promise(((e,t)=>{this.reciprocateQREvent={confirm:e,cancel:()=>t((0,r.newUserCancelledError)())},this.emit("show_reciprocate_qr",this.reciprocateQREvent)}));const t={};switch(e.mode){case u:{const n=e.otherUserMasterKey;t[`ed25519:${n}`]=n;break}case c:{const n=this.request.targetDevice.deviceId;t[`ed25519:${n}`]=e.otherDeviceKey;break}case l:{const n=e.myMasterKey;t[`ed25519:${n}`]=n;break}}await this._verifyKeys(this.userId,t,((e,n,o)=>{const i=t[e];if(!i)throw(0,r.newKeyMismatchError)();if(o!==i)throw a.logger.error("key ID from key info does not match"),(0,r.newKeyMismatchError)();for(const e in n.keys){if(!e.startsWith("ed25519"))continue;const o=t[e];if(!o)throw(0,r.newKeyMismatchError)();if(n.keys[e]!==o)throw a.logger.error("master key does not match"),(0,r.newKeyMismatchError)()}}))}}t.ReciprocateQRCode=s;const u=0,c=1,l=2;class d{constructor(e,t,n,o,r,i){this._sharedSecret=t,this._mode=e,this._otherUserMasterKey=n,this._otherDeviceKey=o,this._myMasterKey=r,this._buffer=i}static async create(e,t){const n=d._generateSharedSecret(),o=d._determineMode(e,t);let r=null,i=null,a=null;if(o===u)r=t.getStoredCrossSigningForUser(e.otherUserId).getId("master");else if(o===c)i=await d._getOtherDeviceKey(e,t);else if(o===l){const e=t.getUserId();a=t.getStoredCrossSigningForUser(e).getId("master")}const s=d._generateQrData(e,t,o,n,r,i,a),h=d._generateBuffer(s);return new d(o,n,r,i,a,h)}get buffer(){return this._buffer}get mode(){return this._mode}get otherDeviceKey(){return this._otherDeviceKey}get otherUserMasterKey(){return this._otherUserMasterKey}get myMasterKey(){return this._myMasterKey}get encodedSharedSecret(){return this._sharedSecret}static _generateSharedSecret(){const e=new Uint8Array(11);return n.g.crypto.getRandomValues(e),(0,i.encodeUnpaddedBase64)(e)}static async _getOtherDeviceKey(e,t){const n=t.getUserId(),o=e.targetDevice,r=o?o.deviceId:null,i=t.getStoredDevice(n,r);if(!i)throw new Error("could not find device "+r);return i.getFingerprint()}static _determineMode(e,t){const n=t.getUserId(),o=e.otherUserId;let r=u;return n===o&&(r=t.checkUserTrust(n).isCrossSigningVerified()?c:l),r}static _generateQrData(e,t,n,o,r,i,a){const s=t.getUserId(),d={prefix:"MATRIX",version:2,mode:n,transactionId:e.channel.transactionId,firstKeyB64:"",secondKeyB64:"",secretB64:o},h=t.getStoredCrossSigningForUser(s);return n===u?(d.firstKeyB64=h.getId("master"),d.secondKeyB64=r):n===c?(d.firstKeyB64=h.getId("master"),d.secondKeyB64=i):n===l&&(d.firstKeyB64=t.getDeviceEd25519Key(),d.secondKeyB64=a),d}static _generateBuffer(e){let t=Buffer.alloc(0);const n=e=>{const n=Buffer.from([e]);t=Buffer.concat([t,n])},o=(e,n,o=!0)=>{const r=Buffer.from(e,n);o&&(e=>{const n=Buffer.alloc(2);n.writeInt16BE(e,0),t=Buffer.concat([t,n])})(r.byteLength),t=Buffer.concat([t,r])},r=e=>{const n=(0,i.decodeBase64)(e),o=Buffer.from(n);t=Buffer.concat([t,o])};return o(e.prefix,"ascii",!1),n(e.version),n(e.mode),o(e.transactionId,"utf-8"),r(e.firstKeyB64),r(e.secondKeyB64),r(e.secretB64),t}}t.QRCodeData=d},56381:(e,t,n)=>{"use strict";var o=n(95318);Object.defineProperty(t,"__esModule",{value:!0}),t.SAS=void 0;var r=n(41631),i=o(n(69141)),a=n(16702),s=n(7434);const u="m.key.verification.start",c=["m.key.verification.accept","m.key.verification.key","m.key.verification.mac"];let l;const d=(0,a.errorFactory)("m.mismatched_sas","Mismatched short authentication string"),h=(0,a.errorFactory)("m.mismatched_commitment","Mismatched commitment"),p=[["🐶","dog"],["🐱","cat"],["🦁","lion"],["🐎","horse"],["🦄","unicorn"],["🐷","pig"],["🐘","elephant"],["🐰","rabbit"],["🐼","panda"],["🐓","rooster"],["🐧","penguin"],["🐢","turtle"],["🐟","fish"],["🐙","octopus"],["🦋","butterfly"],["🌷","flower"],["🌳","tree"],["🌵","cactus"],["🍄","mushroom"],["🌏","globe"],["🌙","moon"],["☁️","cloud"],["🔥","fire"],["🍌","banana"],["🍎","apple"],["🍓","strawberry"],["🌽","corn"],["🍕","pizza"],["🎂","cake"],["❤️","heart"],["🙂","smiley"],["🤖","robot"],["🎩","hat"],["👓","glasses"],["🔧","spanner"],["🎅","santa"],["👍","thumbs up"],["☂️","umbrella"],["⌛","hourglass"],["⏰","clock"],["🎁","gift"],["💡","light bulb"],["📕","book"],["✏️","pencil"],["📎","paperclip"],["✂️","scissors"],["🔒","lock"],["🔑","key"],["🔨","hammer"],["☎️","telephone"],["🏁","flag"],["🚂","train"],["🚲","bicycle"],["✈️","aeroplane"],["🚀","rocket"],["🏆","trophy"],["⚽","ball"],["🎸","guitar"],["🎺","trumpet"],["🔔","bell"],["⚓️","anchor"],["🎧","headphones"],["📁","folder"],["📌","pin"]],f={decimal:function(e){return[1e3+(e[0]<<5|e[1]>>3),1e3+((7&e[1])<<10|e[2]<<2|e[3]>>6),1e3+((63&e[3])<<7|e[4]>>1)]},emoji:function(e){return[e[0]>>2,(3&e[0])<<4|e[1]>>4,(15&e[1])<<2|e[2]>>6,63&e[2],e[3]>>2,(3&e[3])<<4|e[4]>>4,(15&e[4])<<2|e[5]>>6].map((e=>p[e]))}};function g(e,t){const n={};for(const o of t)o in f&&(n[o]=f[o](e));return n}const m={"hkdf-hmac-sha256":"calculate_mac","hmac-sha256":"calculate_mac_long_kdf"};function _(e,t){return function(...n){const o=e[m[t]].apply(e,n);return s.logger.log("SAS calculateMAC:",t,n,o),o}}const F={"curve25519-hkdf-sha256":function(e,t,n){const o=`${e._baseApis.getUserId()}|${e._baseApis.deviceId}|${e.ourSASPubKey}|`,r=`${e.userId}|${e.deviceId}|${e.theirSASPubKey}|`,i="MATRIX_KEY_VERIFICATION_SAS|"+(e.initiatedByMe?o+r:r+o)+e._channel.transactionId;return t.generate_bytes(i,n)},curve25519:function(e,t,n){const o=`${e._baseApis.getUserId()}${e._baseApis.deviceId}`,r=`${e.userId}${e.deviceId}`,i="MATRIX_KEY_VERIFICATION_SAS"+(e.initiatedByMe?o+r:r+o)+e._channel.transactionId;return t.generate_bytes(i,n)}},y=["curve25519-hkdf-sha256","curve25519"],b=["sha256"],v=["hkdf-hmac-sha256","hmac-sha256"],w=Object.keys(f),E=new Set(y),k=new Set(b),D=new Set(v),S=new Set(w);function x(e,t){return e instanceof Array?e.filter((e=>t.has(e))):[]}class C extends r.VerificationBase{static get NAME(){return"m.sas.v1"}get events(){return c}async _doVerification(){await n.g.Olm.init(),l=l||new n.g.Olm.Utility,await this._baseApis.downloadKeys([this.userId]);let e=!1;do{try{return this.initiatedByMe?await this._doSendVerification():await this._doRespondVerification()}catch(t){if(!(t instanceof r.SwitchStartEventError))throw t;this.startEvent=t.startEvent,e=!0}}while(e)}canSwitchStartEvent(e){if(e.getType()!==u)return!1;const t=e.getContent();return t&&t.method===C.NAME&&this._waitingForAccept}async _sendStart(){const e=this._channel.completeContent(u,{method:C.NAME,from_device:this._baseApis.deviceId,key_agreement_protocols:y,hashes:b,message_authentication_codes:v,short_authentication_string:w});return await this._channel.sendCompleted(u,e),e}async _doSendVerification(){let e,t;if(this._waitingForAccept=!0,e=this.startEvent?this._channel.completedContentFromEvent(this.startEvent):await this._sendStart(),!this.initiatedByMe)throw new r.SwitchStartEventError(this.startEvent);try{t=await this._waitForEvent("m.key.verification.accept")}finally{this._waitingForAccept=!1}let o=t.getContent();const s=x(o.short_authentication_string,S);if(!(E.has(o.key_agreement_protocol)&&k.has(o.hash)&&D.has(o.message_authentication_code)&&s.length))throw(0,a.newUnknownMethodError)();if("string"!=typeof o.commitment)throw(0,a.newInvalidMessageError)();const u=o.key_agreement_protocol,c=o.message_authentication_code,p=o.commitment,f=new n.g.Olm.SAS;try{this.ourSASPubKey=f.get_pubkey(),await this._send("m.key.verification.key",{key:this.ourSASPubKey}),t=await this._waitForEvent("m.key.verification.key"),o=t.getContent();const n=o.key+i.default.stringify(e);if(l.sha256(n)!==p)throw h();this.theirSASPubKey=o.key,f.set_their_key(o.key);const r=F[u](this,f,6),m=new Promise(((e,t)=>{this.sasEvent={sas:g(r,s),confirm:async()=>{try{await this._sendMAC(f,c),e()}catch(e){t(e)}},cancel:()=>t((0,a.newUserCancelledError)()),mismatch:()=>t(d())},this.emit("show_sas",this.sasEvent)}));[t]=await Promise.all([this._waitForEvent("m.key.verification.mac").then((e=>(this._expectedEvent="m.key.verification.done",e))),m]),o=t.getContent(),await this._checkMAC(f,o,c)}finally{f.free()}}async _doRespondVerification(){let e=this._channel.completedContentFromEvent(this.startEvent);const t=x(y,new Set(e.key_agreement_protocols))[0],o=x(b,new Set(e.hashes))[0],r=x(v,new Set(e.message_authentication_codes))[0],s=x(e.short_authentication_string,S);if(void 0===t||void 0===o||void 0===r||!s.length)throw(0,a.newUnknownMethodError)();const u=new n.g.Olm.SAS;try{const n=u.get_pubkey()+i.default.stringify(e);await this._send("m.key.verification.accept",{key_agreement_protocol:t,hash:o,message_authentication_code:r,short_authentication_string:s,commitment:l.sha256(n)});let c=await this._waitForEvent("m.key.verification.key");e=c.getContent(),this.theirSASPubKey=e.key,u.set_their_key(e.key),this.ourSASPubKey=u.get_pubkey(),await this._send("m.key.verification.key",{key:this.ourSASPubKey});const h=F[t](this,u,6),p=new Promise(((e,t)=>{this.sasEvent={sas:g(h,s),confirm:async()=>{try{await this._sendMAC(u,r),e()}catch(e){t(e)}},cancel:()=>t((0,a.newUserCancelledError)()),mismatch:()=>t(d())},this.emit("show_sas",this.sasEvent)}));[c]=await Promise.all([this._waitForEvent("m.key.verification.mac").then((e=>(this._expectedEvent="m.key.verification.done",e))),p]),e=c.getContent(),await this._checkMAC(u,e,r)}finally{u.free()}}_sendMAC(e,t){const n={},o=[],r="MATRIX_KEY_VERIFICATION_MAC"+this._baseApis.getUserId()+this._baseApis.deviceId+this.userId+this.deviceId+this._channel.transactionId,i=`ed25519:${this._baseApis.deviceId}`;n[i]=_(e,t)(this._baseApis.getDeviceEd25519Key(),r+i),o.push(i);const a=this._baseApis.getCrossSigningId();if(a){const i=`ed25519:${a}`;n[i]=_(e,t)(a,r+i),o.push(i)}const s=_(e,t)(o.sort().join(","),r+"KEY_IDS");return this._send("m.key.verification.mac",{mac:n,keys:s})}async _checkMAC(e,t,n){const o="MATRIX_KEY_VERIFICATION_MAC"+this.userId+this.deviceId+this._baseApis.getUserId()+this._baseApis.deviceId+this._channel.transactionId;if(t.keys!==_(e,n)(Object.keys(t.mac).sort().join(","),o+"KEY_IDS"))throw(0,a.newKeyMismatchError)();await this._verifyKeys(this.userId,t.mac,((t,r,i)=>{if(i!==_(e,n)(r.keys[t],o+t))throw(0,a.newKeyMismatchError)()}))}}t.SAS=C},22842:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.InRoomRequests=t.InRoomChannel=void 0;var o=n(85279),r=n(7434);const i="m.room.message",a="m.reference",s="m.relates_to";class u{constructor(e,t,n=null){this._client=e,this._roomId=t,this.userId=n,this._requestEventId=null}get receiveStartFromOtherDevices(){return!0}get roomId(){return this._roomId}get transactionId(){return this._requestEventId}static getOtherPartyUserId(e,t){if(u.getEventType(e)!==o.REQUEST_TYPE)return;const n=t.getUserId(),r=e.getSender(),i=e.getContent().to;return r===n?i:i===n?r:void 0}getTimestamp(e){return e.getTs()}static canCreateRequest(e){return e===o.REQUEST_TYPE}static getTransactionId(e){if(u.getEventType(e)===o.REQUEST_TYPE)return e.getId();{const t=e.getRelation();if(t&&t.rel_type===a)return t.event_id}}static validateEvent(e,t){const n=u.getTransactionId(e);if("string"!=typeof n||0===n.length)return!1;const i=u.getEventType(e),a=e.getContent();if(i===o.REQUEST_TYPE){if(!a||"string"!=typeof a.to||!a.to.length)return r.logger.log("InRoomChannel: validateEvent: no valid to "+(a&&a.to)),!1;if(!u.getOtherPartyUserId(e,t))return r.logger.log(`InRoomChannel: validateEvent: not directed to or sent by me: ${e.getSender()}, ${a&&a.to}`),!1}return o.VerificationRequest.validateEvent(i,e,t)}static getEventType(e){const t=e.getType();if(t===i){const t=e.getContent();if(t){const{msgtype:e}=t;if(e===o.REQUEST_TYPE)return o.REQUEST_TYPE}}return t&&t!==o.REQUEST_TYPE?t:""}async handleEvent(e,t,n){if(t.hasEventId(e.getId()))return;const o=u.getEventType(e);if(e.getRoomId()!==this._roomId)return;if(null===this.userId){const t=u.getOtherPartyUserId(e,this._client);t&&(this.userId=t)}const i=this._client.getUserId(),a=e.getSender();if(null!==this.userId&&a!==i&&a!==this.userId)return void r.logger.log(`InRoomChannel: ignoring verification event from non-participating sender ${a}`);null===this._requestEventId&&(this._requestEventId=u.getTransactionId(e));const s=!!e.getUnsigned().transaction_id,c=e.getSender()===this._client.getUserId();return await t.handleEvent(o,e,n,s,c)}completedContentFromEvent(e){const t=Object.assign({},e.getContent());return t[s]=e.getRelation(),t}completeContent(e,t){return t=Object.assign({},t),e!==o.REQUEST_TYPE&&e!==o.READY_TYPE&&e!==o.START_TYPE||(t.from_device=this._client.getDeviceId()),e===o.REQUEST_TYPE?t={body:this._client.getUserId()+" is requesting to verify your key, but your client does not support in-chat key verification. You will need to use legacy key verification to verify keys.",msgtype:o.REQUEST_TYPE,to:this.userId,from_device:t.from_device,methods:t.methods}:t[s]={rel_type:a,event_id:this.transactionId},t}send(e,t){const n=this.completeContent(e,t);return this.sendCompleted(e,n)}async sendCompleted(e,t){let n=e;e===o.REQUEST_TYPE&&(n=i);const r=await this._client.sendEvent(this._roomId,n,t);e===o.REQUEST_TYPE&&(this._requestEventId=r.event_id)}}t.InRoomChannel=u,t.InRoomRequests=class{constructor(){this._requestsByRoomId=new Map}getRequest(e){const t=e.getRoomId(),n=u.getTransactionId(e);return this._getRequestByTxnId(t,n)}getRequestByChannel(e){return this._getRequestByTxnId(e.roomId,e.transactionId)}_getRequestByTxnId(e,t){const n=this._requestsByRoomId.get(e);if(n)return n.get(t)}setRequest(e,t){this._setRequest(e.getRoomId(),u.getTransactionId(e),t)}setRequestByChannel(e,t){this._setRequest(e.roomId,e.transactionId,t)}_setRequest(e,t,n){let o=this._requestsByRoomId.get(e);o||(o=new Map,this._requestsByRoomId.set(e,o)),o.set(t,n)}removeRequest(e){const t=e.getRoomId(),n=this._requestsByRoomId.get(t);n&&(n.delete(u.getTransactionId(e)),0===n.size&&this._requestsByRoomId.delete(t))}findRequestInProgress(e){const t=this._requestsByRoomId.get(e);if(t)for(const e of t.values())if(e.pending)return e}}},89588:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.ToDeviceRequests=t.ToDeviceChannel=void 0;var o=n(98401),r=n(7434),i=n(85279),a=n(16702),s=n(24369);class u{constructor(e,t,n,o=null,r=null){this._client=e,this.userId=t,this._devices=n,this.transactionId=o,this._deviceId=r}isToDevices(e){if(e.length===this._devices.length){for(const t of e)if(!this._devices.find((e=>e.deviceId===t.deviceId)))return!1;return!0}return!1}get deviceId(){return this._deviceId}static getEventType(e){return e.getType()}static getTransactionId(e){const t=e.getContent();return t&&t.transaction_id}static canCreateRequest(e){return e===i.REQUEST_TYPE||e===i.START_TYPE}static validateEvent(e,t){if(e.isCancelled())return r.logger.warn("Ignoring flagged verification request from "+e.getSender()),!1;const n=e.getContent();if(!n)return r.logger.warn("ToDeviceChannel.validateEvent: invalid: no content"),!1;if(!n.transaction_id)return r.logger.warn("ToDeviceChannel.validateEvent: invalid: no transaction_id"),!1;const o=e.getType();if(o===i.REQUEST_TYPE){if(!Number.isFinite(n.timestamp))return r.logger.warn("ToDeviceChannel.validateEvent: invalid: no timestamp"),!1;if(e.getSender()===t.getUserId()&&n.from_device==t.getDeviceId())return r.logger.warn("ToDeviceChannel.validateEvent: invalid: from own device"),!1}return i.VerificationRequest.validateEvent(o,e,t)}getTimestamp(e){const t=e.getContent();return t&&t.timestamp}async handleEvent(e,t,n){const o=e.getType(),r=e.getContent();if(o===i.REQUEST_TYPE||o===i.READY_TYPE||o===i.START_TYPE){this.transactionId||(this.transactionId=r.transaction_id);const e=r.from_device;if(!this._deviceId&&this._devices.includes(e)&&(this._deviceId=e),!this._deviceId||this._deviceId!==e){const t=this.completeContent((0,a.errorFromEvent)((0,a.newUnexpectedMessageError)()));return this._sendToDevices(i.CANCEL_TYPE,t,[e])}}const s=t.phase===i.PHASE_STARTED||t.phase===i.PHASE_READY;await t.handleEvent(e.getType(),e,n,!1,!1);const u=t.phase===i.PHASE_STARTED||t.phase===i.PHASE_READY;if((o===i.START_TYPE||o===i.READY_TYPE)&&!s&&u&&this._deviceId){const e=this._devices.filter((e=>e!==this._deviceId&&e!==this._client.getDeviceId()));if(e.length){const t=this.completeContent({code:"m.accepted",reason:"Verification request accepted by another device"});await this._sendToDevices(i.CANCEL_TYPE,t,e)}}}completedContentFromEvent(e){return e.getContent()}completeContent(e,t){return t=Object.assign({},t),this.transactionId&&(t.transaction_id=this.transactionId),e!==i.REQUEST_TYPE&&e!==i.READY_TYPE&&e!==i.START_TYPE||(t.from_device=this._client.getDeviceId()),e===i.REQUEST_TYPE&&(t.timestamp=Date.now()),t}send(e,t={}){e!==i.REQUEST_TYPE&&e!==i.START_TYPE||this.transactionId||(this.transactionId=u.makeTransactionId());const n=this.completeContent(e,t);return this.sendCompleted(e,n)}async sendCompleted(e,t){let n;n=e===i.REQUEST_TYPE?await this._sendToDevices(e,t,this._devices):await this._sendToDevices(e,t,[this._deviceId]);const o=new s.MatrixEvent({sender:this._client.getUserId(),content:t,type:e});return await this._request.handleEvent(e,o,!0,!0,!0),n}_sendToDevices(e,t,n){if(n.length){const o={};for(const e of n)o[e]=t;return this._client.sendToDevice(e,{[this.userId]:o})}return Promise.resolve()}static makeTransactionId(){return(0,o.randomString)(32)}}t.ToDeviceChannel=u,t.ToDeviceRequests=class{constructor(){this._requestsByUserId=new Map}getRequest(e){return this.getRequestBySenderAndTxnId(e.getSender(),u.getTransactionId(e))}getRequestByChannel(e){return this.getRequestBySenderAndTxnId(e.userId,e.transactionId)}getRequestBySenderAndTxnId(e,t){const n=this._requestsByUserId.get(e);if(n)return n.get(t)}setRequest(e,t){this.setRequestBySenderAndTxnId(e.getSender(),u.getTransactionId(e),t)}setRequestByChannel(e,t){this.setRequestBySenderAndTxnId(e.userId,e.transactionId,t)}setRequestBySenderAndTxnId(e,t,n){let o=this._requestsByUserId.get(e);o||(o=new Map,this._requestsByUserId.set(e,o)),o.set(t,n)}removeRequest(e){const t=e.getSender(),n=this._requestsByUserId.get(t);n&&(n.delete(u.getTransactionId(e)),0===n.size&&this._requestsByUserId.delete(t))}findRequestInProgress(e,t){const n=this._requestsByUserId.get(e);if(n)for(const e of n.values())if(e.pending&&e.channel.isToDevices(t))return e}getRequestsInProgress(e){const t=this._requestsByUserId.get(e);return t?Array.from(t.values()).filter((e=>e.pending)):[]}}},85279:(e,t,n)=>{"use strict";var o=n(95318);Object.defineProperty(t,"__esModule",{value:!0}),t.VerificationRequest=t.PHASE_DONE=t.PHASE_CANCELLED=t.PHASE_STARTED=t.PHASE_READY=t.PHASE_REQUESTED=t.PHASE_UNSENT=t.READY_TYPE=t.DONE_TYPE=t.CANCEL_TYPE=t.START_TYPE=t.REQUEST_TYPE=t.EVENT_PREFIX=void 0;var r=o(n(59713)),i=n(7434),a=n(17187),s=n(16702),u=n(51696);const c="m.key.verification.";t.EVENT_PREFIX=c;const l=c+"request";t.REQUEST_TYPE=l;const d=c+"start";t.START_TYPE=d;const h=c+"cancel";t.CANCEL_TYPE=h;const p=c+"done";t.DONE_TYPE=p;const f=c+"ready";t.READY_TYPE=f,t.PHASE_UNSENT=1,t.PHASE_REQUESTED=2,t.PHASE_READY=3,t.PHASE_STARTED=4,t.PHASE_CANCELLED=5,t.PHASE_DONE=6;class g extends a.EventEmitter{constructor(e,t,n){super(),(0,r.default)(this,"_cancelOnTimeout",(()=>{try{this.initiatedByMe?this.cancel({reason:"Other party didn't accept in time",code:"m.timeout"}):this.cancel({reason:"User didn't accept in time",code:"m.timeout"})}catch(e){i.logger.error("Error while cancelling verification request",e)}})),this.channel=e,this.channel._request=this,this._verificationMethods=t,this._client=n,this._commonMethods=[],this._setPhase(1,!1),this._eventsByUs=new Map,this._eventsByThem=new Map,this._observeOnly=!1,this._timeoutTimer=null,this._accepting=!1,this._declining=!1,this._verifierHasFinished=!1,this._cancelled=!1,this._chosenMethod=null,this._qrCodeData=null,this._requestReceivedAt=null}static validateEvent(e,t,n){const o=t.getContent();return!(!e||!e.startsWith(c))&&(o?e!==l&&e!==f||Array.isArray(o.methods)?e!==l&&e!==f&&e!==d||"string"==typeof o.from_device&&0!==o.from_device.length||(i.logger.log("VerificationRequest: validateEvent: fail because from_device"),!1):(i.logger.log("VerificationRequest: validateEvent: fail because methods"),!1):(i.logger.log("VerificationRequest: validateEvent: no content"),!1))}get invalid(){return 1===this.phase}get requested(){return 2===this.phase}get cancelled(){return 5===this.phase}get ready(){return 3===this.phase}get started(){return 4===this.phase}get done(){return 6===this.phase}get methods(){return this._commonMethods}get chosenMethod(){return this._chosenMethod}calculateEventTimeout(e){let t=this.channel.getTimestamp(e)+6e5;if(this._requestReceivedAt&&!this.initiatedByMe&&this.phase<=2){const e=this._requestReceivedAt+12e4;t=Math.min(t,e)}return Math.max(0,t-Date.now())}get timeout(){const e=this._getEventByEither(l);return e?this.calculateEventTimeout(e):0}get requestEvent(){return this._getEventByEither(l)}get phase(){return this._phase}get verifier(){return this._verifier}get canAccept(){return this.phase<3&&!this._accepting&&!this._declining}get accepting(){return this._accepting}get declining(){return this._declining}get pending(){return!this.observeOnly&&6!==this._phase&&5!==this._phase}get qrCodeData(){return this._qrCodeData}otherPartySupportsMethod(e,t=!1){if(!t&&!this.ready&&!this.started)return!1;const n=this._eventsByThem.get(l)||this._eventsByThem.get(f);if(!n){if(this.started&&this.initiatedByMe){const t=this._eventsByUs.get(d),n=t&&t.getContent();return e==(n&&n.method)}return!1}const o=n.getContent();if(!o)return!1;const{methods:r}=o;return!!Array.isArray(r)&&r.includes(e)}get initiatedByMe(){const e=this._eventsByUs.size+this._eventsByThem.size===0;if(1===this._phase&&e)return!0;const t=this._eventsByUs.has(l),n=this._eventsByThem.has(l);if(t&&!n)return!0;if(!t&&n)return!1;const o=this._eventsByUs.has(d),r=this._eventsByThem.has(d);return!(!o||r)}get requestingUserId(){return this.initiatedByMe?this._client.getUserId():this.otherUserId}get receivingUserId(){return this.initiatedByMe?this.otherUserId:this._client.getUserId()}get otherUserId(){return this.channel.userId}get isSelfVerification(){return this._client.getUserId()===this.otherUserId}get cancellingUserId(){const e=this._eventsByUs.get(h),t=this._eventsByThem.get(h);return e&&(!t||e.getId(){const o=()=>{let r=!1;return e(this)?(t(this),r=!0):this.cancelled&&(n(new Error("cancelled")),r=!0),r&&this.off("change",o),r};o()||this.on("change",o)}))}_setPhase(e,t=!0){this._phase=e,t&&this.emit("change")}_getEventByEither(e){return this._eventsByThem.get(e)||this._eventsByUs.get(e)}_getEventBy(e,t){return t?this._eventsByThem.get(e):this._eventsByUs.get(e)}_calculatePhaseTransitions(){const e=[{phase:1}],t=()=>e[e.length-1].phase,n=this._eventsByThem.has(l),o=this._getEventBy(l,n);o&&e.push({phase:2,event:o});const r=o&&this._getEventBy(f,!n);let i;if(r&&2===t()&&e.push({phase:3,event:r}),r||!o){const e=this._eventsByThem.get(d),t=this._eventsByUs.get(d);i=e&&t?e.getSender()this._verificationMethods.has(e)))}if(this.observeOnly||2!==t&&4!==t&&3!==t||this.channel.receiveStartFromOtherDevices&&this._wasSentByOwnUser(n)&&!this._wasSentByOwnDevice(n)&&(this._observeOnly=!0),4===t){const{method:e}=n.getContent();this._verifier||this.observeOnly||(this._verifier=this._createVerifier(e,n),this._verifier?this._chosenMethod=e:this.cancel({code:"m.unknown_method",reason:`Unknown method: ${e}`}))}}_applyPhaseTransitions(){const e=this._calculatePhaseTransitions(),t=e.findIndex((e=>e.phase===this.phase)),n=e.slice(t+1);for(const e of n)this._transitionToPhase(e);return n}_isWinningStartRace(e){if(e.getType()!==d)return!1;const t=this._verifier.startEvent;let n,o;if(this.isSelfVerification)if(t){const e=t.getContent();n=e&&e.from_device}else n=this._client.getDeviceId();else n=t?t.getSender():this._client.getUserId();if(this.isSelfVerification){const t=e.getContent();o=t&&t.from_device}else o=e.getSender();return o3===e.phase))&&this.otherPartySupportsMethod(u.SCAN_QR_CODE_METHOD,!0)&&(this._qrCodeData=await u.QRCodeData.create(this,this._client));const e=c[c.length-1],{phase:t}=e;this._setupTimeout(t),this._setPhase(t)}else this._observeOnly!==a&&this.emit("change")}finally{i.logger.log(`Verification request ${this.channel.transactionId}: ${e} event with id:${t.getId()}, content:${JSON.stringify(t.getContent())} deviceId:${this.channel.deviceId}, sender:${t.getSender()}, isSentByUs:${r}, isLiveEvent:${n}, isRemoteEcho:${o}, phase:${s}=>${this.phase}, observeOnly:${a}=>${this._observeOnly}`)}}_setupTimeout(e){!this._timeoutTimer&&!this.observeOnly&&2===e&&(this._timeoutTimer=setTimeout(this._cancelOnTimeout,this.timeout)),this._timeoutTimer&&(4===e||3===e||6===e||5===e)&&(clearTimeout(this._timeoutTimer),this._timeoutTimer=null)}async _cancelOnError(e,t){if(e===d){const e=t.getContent().method;if(!this._verificationMethods.has(e))return await this.cancel((0,s.errorFromEvent)((0,s.newUnknownMethodError)())),!0}const n=e===l&&1!==this.phase,o=e===f&&2!==this.phase;if(1!==this.phase&&(n||o)){i.logger.warn(`Cancelling, unexpected ${e} verification event from ${t.getSender()}`);const n=`Unexpected ${e} event in phase ${this.phase}`;return await this.cancel((0,s.errorFromEvent)((0,s.newUnexpectedMessageError)({reason:n}))),!0}return!1}_adjustObserveOnly(e,t){t||(this._observeOnly=!0),this.calculateEventTimeout(e)<3e3&&(this._observeOnly=!0)}_addEvent(e,t,n){if(n?this._eventsByUs.set(e,t):this._eventsByThem.set(e,t),e===l){for(const[e,t]of this._eventsByThem.entries())t.getSender()!==this.otherUserId&&this._eventsByThem.delete(e);this._requestReceivedAt=Date.now()}}_createVerifier(e,t=null,n=null){n||(n=this.targetDevice);const{userId:o,deviceId:r}=n,a=this._verificationMethods.get(e);if(a)return new a(this.channel,this._client,o,r,t,this);i.logger.warn("could not find verifier constructor for method",e)}_wasSentByOwnUser(e){return e.getSender()===this._client.getUserId()}_wasSentByOwnDevice(e){if(!this._wasSentByOwnUser(e))return!1;const t=e.getContent();return!(!t||t.from_device!==this._client.getDeviceId())}onVerifierCancelled(){this._cancelled=!0;const e=this._applyPhaseTransitions();e.length&&this._setPhase(e[e.length-1].phase)}onVerifierFinished(){this.channel.send("m.key.verification.done",{}),this._verifierHasFinished=!0;const e=this._applyPhaseTransitions();e.length&&this._setPhase(e[e.length-1].phase)}getEventFromOtherParty(e){return this._eventsByThem.get(e)}}t.VerificationRequest=g},19489:(e,t)=>{"use strict";function n(e,t){const n=`Store is invalid because ${e}, please stop the client, delete all data and start the client again`,o=Reflect.construct(Error,[n]);return Reflect.setPrototypeOf(o,Reflect.getPrototypeOf(this)),o.reason=e,o.value=t,o}function o(e){const t=`Crypto store is invalid because ${e}, please stop the client, delete all data and start the client again`,n=Reflect.construct(Error,[t]);return Reflect.setPrototypeOf(n,Reflect.getPrototypeOf(this)),n.reason=e,n.name="InvalidCryptoStoreError",n}Object.defineProperty(t,"__esModule",{value:!0}),t.InvalidStoreError=n,t.InvalidCryptoStoreError=o,t.KeySignatureUploadError=void 0,n.TOGGLED_LAZY_LOADING="TOGGLED_LAZY_LOADING",n.prototype=Object.create(Error.prototype,{constructor:{value:Error,enumerable:!1,writable:!0,configurable:!0}}),Reflect.setPrototypeOf(n,Error),o.TOO_NEW="TOO_NEW",o.prototype=Object.create(Error.prototype,{constructor:{value:Error,enumerable:!1,writable:!0,configurable:!0}}),Reflect.setPrototypeOf(o,Error);class r extends Error{constructor(e,t){super(e),this.value=t}}t.KeySignatureUploadError=r},33564:(e,t)=>{"use strict";function n(e){this.filter_json=e,this.types=e.types||null,this.not_types=e.not_types||[],this.rooms=e.rooms||null,this.not_rooms=e.not_rooms||[],this.senders=e.senders||null,this.not_senders=e.not_senders||[],this.contains_url=e.contains_url||null}Object.defineProperty(t,"__esModule",{value:!0}),t.FilterComponent=n,n.prototype.check=function(e){return this._checkFields(e.getRoomId(),e.getSender(),e.getType(),!!e.getContent()&&void 0!==e.getContent().url)},n.prototype._checkFields=function(e,t,n,o){const r={rooms:function(t){return e===t},senders:function(e){return t===e},types:function(e){return function(e,t){if(t.endsWith("*")){const n=t.slice(0,-1);return e.substr(0,n.length)===n}return e===t}(n,e)}},i=this;for(let e=0;e0)return!1;const o=i[t];if(o&&o.length>0&&!o.some(n))return!1}const a=this.filter_json.contains_url;return void 0===a||a===o},n.prototype.filter=function(e){return e.filter(this.check,this)},n.prototype.limit=function(){return void 0!==this.filter_json.limit?this.filter_json.limit:10}},27906:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.Filter=i;var o=n(33564);function r(e,t,n){const o=t.split(".");let r=e;for(let e=0;e{"use strict";var o=n(20862),r=n(95318);Object.defineProperty(t,"__esModule",{value:!0}),t.MatrixHttpApi=h,t.retryNetworkOperation=async function(e,t){let n=0,o=null;for(;n0){const e=1e3*Math.pow(2,n);u.logger.log(`network operation failed ${n} times, retrying in ${e}ms...`),await new Promise((t=>setTimeout(t,e)))}return await t()}catch(e){if(!(e instanceof g))throw e;n+=1,o=e}throw o},t.AbortError=t.ConnectionError=t.MatrixError=t.PREFIX_MEDIA_R0=t.PREFIX_IDENTITY_V2=t.PREFIX_IDENTITY_V1=t.PREFIX_UNSTABLE=t.PREFIX_R0=void 0;var i=r(n(59713)),a=n(37811),s=o(n(3102)),u=n(7434),c=o(n(82731));function l(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function d(e){for(var t=1;t0&&(_+="?"+F.join("&")),u.open("POST",_),this.useAuthorizationHeader&&u.setRequestHeader("Authorization","Bearer "+this.opts.accessToken),u.setRequestHeader("Content-Type",r),u.send(a),f=e.promise,f.abort=u.abort.bind(u)}else{const e={};o&&i&&(e.filename=i),f=this.authedRequest(t.callback,"POST","/upload",e,a,{prefix:"/_matrix/media/r0",headers:{"Content-Type":r},json:!1,bodyParser:g})}const _=this,F=f.finally((function(){for(let e=0;e<_.uploads.length;++e)if(_.uploads[e]===h)return void _.uploads.splice(e,1)}));return F.abort=f.abort,h.promise=F,this.uploads.push(h),F},cancelUpload:function(e){return!!e.abort&&(e.abort(),!0)},getCurrentUploads:function(){return this.uploads},idServerRequest:function(e,t,n,o,r,i){if(!this.opts.idBaseUrl)throw new Error("No Identity Server base URL set");const a=this.opts.idBaseUrl+r+n;if(void 0!==e&&!s.isFunction(e))throw Error("Expected callback to be a function but got "+typeof e);const u={uri:a,method:t,withCredentials:!1,json:!0,_matrix_opts:this.opts,headers:{}};"GET"===t?u.qs=o:"object"==typeof o&&(u.json=o),i&&(u.headers.Authorization=`Bearer ${i}`);const c=s.defer();return this.opts.request(u,p(c,e,this.opts.onlyData)),c.promise},authedRequest:function(e,t,n,o,r,i){o||(o={}),this.useAuthorizationHeader?(isFinite(i)&&(i={localTimeoutMs:i}),i||(i={}),i.headers||(i.headers={}),i.headers.Authorization||(i.headers.Authorization="Bearer "+this.opts.accessToken),o.access_token&&delete o.access_token):o.access_token||(o.access_token=this.opts.accessToken);const a=this.request(e,t,n,o,r,i),s=this;return a.catch((function(e){"M_UNKNOWN_TOKEN"==e.errcode?s.event_emitter.emit("Session.logged_out",e):"M_CONSENT_NOT_GIVEN"==e.errcode&&s.event_emitter.emit("no_consent",e.message,e.data.consent_uri)})),a},request:function(e,t,n,o,r,i){const a=void 0!==(i=i||{}).prefix?i.prefix:this.opts.prefix,s=this.opts.baseUrl+a+n;return this.requestOtherUrl(e,t,s,o,r,i)},requestOtherUrl:function(e,t,n,o,r,i){return null==i?i={}:isFinite(i)&&(i={localTimeoutMs:i}),this._request(e,t,n,o,r,i)},getUrl:function(e,t,n){let o="";return t&&(o="?"+s.encodeParams(t)),this.opts.baseUrl+n+e+o},_request:function(e,t,n,o,r,i){if(void 0!==e&&!s.isFunction(e))throw Error("Expected callback to be a function but got "+typeof e);i=i||{};const a=this;this.opts.extraParams&&(o=d(d({},o),this.opts.extraParams));const u=s.extend({},i.headers||{}),l=void 0===i.json||i.json;let h=i.bodyParser;l&&(r&&(r=JSON.stringify(r),u["content-type"]="application/json"),u.accept||(u.accept="application/json"),void 0===h&&(h=function(e){return JSON.parse(e)}));const g=s.defer();let m,_,F=!1;const y=i.localTimeoutMs||this.opts.localTimeoutMs,b=()=>{y&&(m&&c.clearTimeout(m),m=c.setTimeout((function(){F=!0,_&&_.abort&&_.abort(),g.reject(new f({error:"Locally timed out waiting for a response",errcode:"ORG.MATRIX.JSSDK_TIMEOUT",timeout:y}))}),y))};b();const v=g.promise;try{_=this.opts.request({uri:n,method:t,withCredentials:!1,qs:o,qsStringifyOptions:i.qsStringifyOptions,useQuerystring:!0,body:r,json:!1,timeout:y,headers:u||{},_matrix_opts:this.opts},(function(t,n,o){y&&(c.clearTimeout(m),F)||p(g,e,a.opts.onlyData,h)(t,n,o)})),_&&("onprogress"in _&&(_.onprogress=e=>{b()}),_.abort&&(v.abort=_.abort.bind(_)))}catch(t){g.reject(t),e&&e(t)}return v}};const p=function(e,t,n,o){return t=t||function(){},function(r,i,s){if(r&&("AbortError"===r.name||"aborted"===r||r instanceof f||(r=new g("request failed",r))),!r)try{(i.status||i.statusCode)>=400?r=function(e,t){const n=e.status||e.statusCode,o=function(e){let t;if(e.getResponseHeader?t=e.getResponseHeader("Content-Type"):e.headers&&(t=e.headers["content-type"]||null),!t)return null;try{return(0,a.parse)(t)}catch(e){throw new Error(`Error parsing Content-Type '${t}': ${e}`)}}(e);let r;if(o)if("application/json"===o.type){const e="object"==typeof t?t:JSON.parse(t);r=new f(e)}else"text/plain"===o.type&&(r=new Error(`Server returned ${n} error: ${t}`));return r||(r=new Error(`Server returned ${n} error`)),r.httpStatus=n,r}(i,s):o&&(s=o(s))}catch(e){r=new Error(`Error parsing server response: ${e}`)}if(r)e.reject(r),t(r);else{const o={code:i.status||i.statusCode,headers:i.headers,data:s};e.resolve(n?s:o),t(null,n?s:o)}}};class f extends Error{constructor(e){super(`MatrixError: ${(e=e||{}).errcode}`),this.errcode=e.errcode,this.name=e.errcode||"Unknown error code",this.message=e.error||"Unknown message",this.data=e}}t.MatrixError=f;class g extends Error{constructor(e,t){super(e+(t?`: ${t.message}`:"")),this._cause=t}get name(){return"ConnectionError"}get cause(){return this._cause}}t.ConnectionError=g;class m extends Error{constructor(){super("Operation aborted")}get name(){return"AbortError"}}t.AbortError=m},33415:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.exists=function(e,t){return new Promise(((n,o)=>{let r=!0;const i=e.open(t);i.onupgradeneeded=()=>{r=!1},i.onblocked=()=>o(),i.onsuccess=()=>{i.result.close(),r||e.deleteDatabase(t),n(r)},i.onerror=e=>o(e.target.error)}))}},28670:(e,t,n)=>{"use strict";var o=n(20862),r=n(95318);Object.defineProperty(t,"__esModule",{value:!0}),t.InteractiveAuth=l;var i=r(n(8575)),a=o(n(3102)),s=n(7434);const u="m.login.email.identity",c="m.login.msisdn";function l(e){this._matrixClient=e.matrixClient,this._data=e.authData||{},this._requestCallback=e.doRequest,this._busyChangedCallback=e.busyChanged,this._stateUpdatedCallback=e.stateUpdated||e.startAuthStage,this._resolveFunc=null,this._rejectFunc=null,this._inputs=e.inputs||{},this._requestEmailTokenCallback=e.requestEmailToken,e.sessionId&&(this._data.session=e.sessionId),this._clientSecret=e.clientSecret||this._matrixClient.generateClientSecret(),this._emailSid=e.emailSid,void 0===this._emailSid&&(this._emailSid=null),this._requestingEmailToken=!1,this._chosenFlow=null,this._currentStage=null,this._submitPromise=null}l.prototype={attemptAuth:function(){return new Promise(((e,t)=>{if(this._resolveFunc=e,this._rejectFunc=t,this._data&&this._data.flows)this._startNextAuthStage();else{this._busyChangedCallback&&this._busyChangedCallback(!0);let e=null;this._data.session&&(e={session:this._data.session}),this._doRequest(e).finally((()=>{this._busyChangedCallback&&this._busyChangedCallback(!1)}))}}))},poll:async function(){if(!this._data.session)return;if(!this._resolveFunc)return;if(this._submitPromise)return;let e={};if(this._currentStage==u&&this._emailSid){const t={sid:this._emailSid,client_secret:this._clientSecret};if(await this._matrixClient.doesServerRequireIdServerParam()){const e=i.default.parse(this._matrixClient.getIdentityServerUrl());t.id_server=e.host}e={type:u,threepid_creds:t,threepidCreds:t}}this.submitAuthDict(e,!0)},getSessionId:function(){return this._data?this._data.session:void 0},getClientSecret:function(){return this._clientSecret},getStageParams:function(e){let t={};return this._data&&this._data.params&&(t=this._data.params),t[e]},getChosenFlow(){return this._chosenFlow},submitAuthDict:async function(e,t){if(!this._resolveFunc)throw new Error("submitAuthDict() called before attemptAuth()");for(!t&&this._busyChangedCallback&&this._busyChangedCallback(!0);this._submitPromise;)try{await this._submitPromise}catch(e){}let n;this._data.session?(n={session:this._data.session},a.extend(n,e)):n=e;try{this._submitPromise=this._doRequest(n,t),await this._submitPromise}finally{this._submitPromise=null,!t&&this._busyChangedCallback&&this._busyChangedCallback(!1)}},getEmailSid:function(){return this._emailSid},setEmailSid:function(e){this._emailSid=e},_doRequest:async function(e,t){try{const n=await this._requestCallback(e,t);this._resolveFunc(n),this._resolveFunc=null,this._rejectFunc=null}catch(e){const n=e.data?e.data.flows:null,o=this._data.flows||Boolean(n);401===e.httpStatus&&e.data&&o||(t?s.logger.log("Background poll request failed doing UI auth: ignoring",e):this._rejectFunc(e)),e.data.flows||e.data.completed||e.data.session||(e.data.flows=this._data.flows,e.data.completed=this._data.completed,e.data.session=this._data.session),this._data=e.data;try{this._startNextAuthStage()}catch(e){this._rejectFunc(e),this._resolveFunc=null,this._rejectFunc=null}if(!this._emailSid&&!this._requestingEmailToken&&this._chosenFlow.stages.includes("m.login.email.identity")){this._requestingEmailToken=!0;try{const e=await this._requestEmailTokenCallback(this._inputs.emailAddress,this._clientSecret,1,this._data.session);this._emailSid=e.sid}catch(e){this._rejectFunc(e),this._resolveFunc=null,this._rejectFunc=null}finally{this._requestingEmailToken=!1}}}},_startNextAuthStage:function(){const e=this._chooseStage();if(!e)throw new Error("No incomplete flows from the server");if(this._currentStage=e,"m.login.dummy"===e)return void this.submitAuthDict({type:"m.login.dummy"});if(this._data&&this._data.errcode||this._data.error)return void this._stateUpdatedCallback(e,{errcode:this._data.errcode||"",error:this._data.error||""});const t={};e==u&&(t.emailSid=this._emailSid),this._stateUpdatedCallback(e,t)},_chooseStage:function(){null===this._chosenFlow&&(this._chosenFlow=this._chooseFlow()),s.logger.log("Active flow => %s",JSON.stringify(this._chosenFlow));const e=this._firstUncompletedStage(this._chosenFlow);return s.logger.log("Next stage: %s",e),e},_chooseFlow:function(){const e=this._data.flows||[],t=Boolean(this._inputs.emailAddress)||Boolean(this._emailSid),n=Boolean(this._inputs.phoneCountry)&&Boolean(this._inputs.phoneNumber);for(const o of e){let e=!1,r=!1;for(const t of o.stages)t===u?e=!0:t==c&&(r=!0);if(e==t&&r==n)return o}const o=new Error("No appropriate authentication flow found");throw o.name="NoAuthFlowFoundError",o.required_stages=[],t&&o.required_stages.push(u),n&&o.required_stages.push(c),o.available_flows=e,o},_firstUncompletedStage:function(e){const t=(this._data||{}).completed||[];for(let n=0;n{"use strict";var o=n(95318);Object.defineProperty(t,"__esModule",{value:!0}),t.logger=void 0;var r=o(n(2043));r.default.methodFactory=function(e,t,n){return function(...t){return this.prefix&&t.unshift(this.prefix),"error"===e||"warn"===e||"trace"===e||"info"===e?console[e](...t):console.log(...t)}};const i=r.default.getLogger("matrix");t.logger=i,i.setLevel(r.default.levels.DEBUG),function e(t){t.withPrefix=function(t){return function(t){const n=r.default.getLogger(`matrix-${t}`);return n.prefix!==t&&(e(n),n.prefix=t,n.setLevel(r.default.levels.DEBUG)),n}((this.prefix||"")+t)}}(i)},48070:(e,t,n)=>{"use strict";var o=n(20862);Object.defineProperty(t,"__esModule",{value:!0});var r={request:!0,getRequest:!0,wrapRequest:!0,setCryptoStoreFactory:!0,createClient:!0,ContentHelpers:!0,createNewMatrixCall:!0,setMatrixCallAudioInput:!0,setMatrixCallVideoInput:!0};t.request=function(e){R=e},t.getRequest=function(){return R},t.wrapRequest=function(e){const t=R;R=function(n,o){return e(t,n,o)}},t.setCryptoStoreFactory=function(e){I=e},t.createClient=function(e){return"string"==typeof e&&(e={baseUrl:e}),e.request=e.request||R,e.store=e.store||new a.MemoryStore({localStorage:n.g.localStorage}),e.scheduler=e.scheduler||new s.MatrixScheduler,e.cryptoStore=e.cryptoStore||I(),new u.MatrixClient(e)},Object.defineProperty(t,"createNewMatrixCall",{enumerable:!0,get:function(){return T.createNewMatrixCall}}),Object.defineProperty(t,"setMatrixCallAudioInput",{enumerable:!0,get:function(){return T.setAudioInput}}),Object.defineProperty(t,"setMatrixCallVideoInput",{enumerable:!0,get:function(){return T.setVideoInput}}),t.ContentHelpers=void 0;var i=n(11045);Object.keys(i).forEach((function(e){"default"!==e&&"__esModule"!==e&&(Object.prototype.hasOwnProperty.call(r,e)||e in t&&t[e]===i[e]||Object.defineProperty(t,e,{enumerable:!0,get:function(){return i[e]}}))}));var a=n(11703);Object.keys(a).forEach((function(e){"default"!==e&&"__esModule"!==e&&(Object.prototype.hasOwnProperty.call(r,e)||e in t&&t[e]===a[e]||Object.defineProperty(t,e,{enumerable:!0,get:function(){return a[e]}}))}));var s=n(39443);Object.keys(s).forEach((function(e){"default"!==e&&"__esModule"!==e&&(Object.prototype.hasOwnProperty.call(r,e)||e in t&&t[e]===s[e]||Object.defineProperty(t,e,{enumerable:!0,get:function(){return s[e]}}))}));var u=n(62168);Object.keys(u).forEach((function(e){"default"!==e&&"__esModule"!==e&&(Object.prototype.hasOwnProperty.call(r,e)||e in t&&t[e]===u[e]||Object.defineProperty(t,e,{enumerable:!0,get:function(){return u[e]}}))}));var c=n(17715);Object.keys(c).forEach((function(e){"default"!==e&&"__esModule"!==e&&(Object.prototype.hasOwnProperty.call(r,e)||e in t&&t[e]===c[e]||Object.defineProperty(t,e,{enumerable:!0,get:function(){return c[e]}}))}));var l=n(79118);Object.keys(l).forEach((function(e){"default"!==e&&"__esModule"!==e&&(Object.prototype.hasOwnProperty.call(r,e)||e in t&&t[e]===l[e]||Object.defineProperty(t,e,{enumerable:!0,get:function(){return l[e]}}))}));var d=n(22741);Object.keys(d).forEach((function(e){"default"!==e&&"__esModule"!==e&&(Object.prototype.hasOwnProperty.call(r,e)||e in t&&t[e]===d[e]||Object.defineProperty(t,e,{enumerable:!0,get:function(){return d[e]}}))}));var h=n(19489);Object.keys(h).forEach((function(e){"default"!==e&&"__esModule"!==e&&(Object.prototype.hasOwnProperty.call(r,e)||e in t&&t[e]===h[e]||Object.defineProperty(t,e,{enumerable:!0,get:function(){return h[e]}}))}));var p=n(24369);Object.keys(p).forEach((function(e){"default"!==e&&"__esModule"!==e&&(Object.prototype.hasOwnProperty.call(r,e)||e in t&&t[e]===p[e]||Object.defineProperty(t,e,{enumerable:!0,get:function(){return p[e]}}))}));var f=n(27366);Object.keys(f).forEach((function(e){"default"!==e&&"__esModule"!==e&&(Object.prototype.hasOwnProperty.call(r,e)||e in t&&t[e]===f[e]||Object.defineProperty(t,e,{enumerable:!0,get:function(){return f[e]}}))}));var g=n(70142);Object.keys(g).forEach((function(e){"default"!==e&&"__esModule"!==e&&(Object.prototype.hasOwnProperty.call(r,e)||e in t&&t[e]===g[e]||Object.defineProperty(t,e,{enumerable:!0,get:function(){return g[e]}}))}));var m=n(88910);Object.keys(m).forEach((function(e){"default"!==e&&"__esModule"!==e&&(Object.prototype.hasOwnProperty.call(r,e)||e in t&&t[e]===m[e]||Object.defineProperty(t,e,{enumerable:!0,get:function(){return m[e]}}))}));var _=n(33705);Object.keys(_).forEach((function(e){"default"!==e&&"__esModule"!==e&&(Object.prototype.hasOwnProperty.call(r,e)||e in t&&t[e]===_[e]||Object.defineProperty(t,e,{enumerable:!0,get:function(){return _[e]}}))}));var F=n(32848);Object.keys(F).forEach((function(e){"default"!==e&&"__esModule"!==e&&(Object.prototype.hasOwnProperty.call(r,e)||e in t&&t[e]===F[e]||Object.defineProperty(t,e,{enumerable:!0,get:function(){return F[e]}}))}));var y=n(26860);Object.keys(y).forEach((function(e){"default"!==e&&"__esModule"!==e&&(Object.prototype.hasOwnProperty.call(r,e)||e in t&&t[e]===y[e]||Object.defineProperty(t,e,{enumerable:!0,get:function(){return y[e]}}))}));var b=n(83998);Object.keys(b).forEach((function(e){"default"!==e&&"__esModule"!==e&&(Object.prototype.hasOwnProperty.call(r,e)||e in t&&t[e]===b[e]||Object.defineProperty(t,e,{enumerable:!0,get:function(){return b[e]}}))}));var v=n(27906);Object.keys(v).forEach((function(e){"default"!==e&&"__esModule"!==e&&(Object.prototype.hasOwnProperty.call(r,e)||e in t&&t[e]===v[e]||Object.defineProperty(t,e,{enumerable:!0,get:function(){return v[e]}}))}));var w=n(34969);Object.keys(w).forEach((function(e){"default"!==e&&"__esModule"!==e&&(Object.prototype.hasOwnProperty.call(r,e)||e in t&&t[e]===w[e]||Object.defineProperty(t,e,{enumerable:!0,get:function(){return w[e]}}))}));var E=n(28670);Object.keys(E).forEach((function(e){"default"!==e&&"__esModule"!==e&&(Object.prototype.hasOwnProperty.call(r,e)||e in t&&t[e]===E[e]||Object.defineProperty(t,e,{enumerable:!0,get:function(){return E[e]}}))}));var k=n(91415);Object.keys(k).forEach((function(e){"default"!==e&&"__esModule"!==e&&(Object.prototype.hasOwnProperty.call(r,e)||e in t&&t[e]===k[e]||Object.defineProperty(t,e,{enumerable:!0,get:function(){return k[e]}}))}));var D=n(99789);Object.keys(D).forEach((function(e){"default"!==e&&"__esModule"!==e&&(Object.prototype.hasOwnProperty.call(r,e)||e in t&&t[e]===D[e]||Object.defineProperty(t,e,{enumerable:!0,get:function(){return D[e]}}))}));var S=n(55837);Object.keys(S).forEach((function(e){"default"!==e&&"__esModule"!==e&&(Object.prototype.hasOwnProperty.call(r,e)||e in t&&t[e]===S[e]||Object.defineProperty(t,e,{enumerable:!0,get:function(){return S[e]}}))}));var x=n(57585);Object.keys(x).forEach((function(e){"default"!==e&&"__esModule"!==e&&(Object.prototype.hasOwnProperty.call(r,e)||e in t&&t[e]===x[e]||Object.defineProperty(t,e,{enumerable:!0,get:function(){return x[e]}}))}));var C=n(73667);Object.keys(C).forEach((function(e){"default"!==e&&"__esModule"!==e&&(Object.prototype.hasOwnProperty.call(r,e)||e in t&&t[e]===C[e]||Object.defineProperty(t,e,{enumerable:!0,get:function(){return C[e]}}))}));var A=o(n(44656));t.ContentHelpers=A;var T=n(59679);let R,I=()=>new i.MemoryCryptoStore},43558:(e,t)=>{"use strict";function n(e){this._timeline=[e],this._ourEventIndex=0,this._paginateTokens={b:null,f:null},this._paginateRequests={b:null,f:null}}Object.defineProperty(t,"__esModule",{value:!0}),t.EventContext=n,n.prototype.getEvent=function(){return this._timeline[this._ourEventIndex]},n.prototype.getTimeline=function(){return this._timeline},n.prototype.getOurEventIndex=function(){return this._ourEventIndex},n.prototype.getPaginateToken=function(e){return this._paginateTokens[e?"b":"f"]},n.prototype.setPaginateToken=function(e,t){this._paginateTokens[t?"b":"f"]=e},n.prototype.addEvents=function(e,t){t?(this._timeline=e.concat(this._timeline),this._ourEventIndex+=e.length):this._timeline=this._timeline.concat(e)}},33705:(e,t,n)=>{"use strict";var o=n(20862);Object.defineProperty(t,"__esModule",{value:!0}),t.EventTimelineSet=d;var r=n(17187),i=n(88910),a=n(24369),s=o(n(3102)),u=n(7434),c=n(49690);let l;function d(e,t){this.room=e,this._timelineSupport=Boolean(t.timelineSupport),this._liveTimeline=new i.EventTimeline(this),this._unstableClientRelationAggregation=!!t.unstableClientRelationAggregation,this._timelines=[this._liveTimeline],this._eventIdToTimeline={},this._filter=t.filter||null,this._unstableClientRelationAggregation&&(this._relations={})}l=u.logger.log.bind(u.logger),s.inherits(d,r.EventEmitter),d.prototype.getTimelines=function(){return this._timelines},d.prototype.getFilter=function(){return this._filter},d.prototype.setFilter=function(e){this._filter=e},d.prototype.getPendingEvents=function(){return this.room?this._filter?this._filter.filterRoomTimeline(this.room.getPendingEvents()):this.room.getPendingEvents():[]},d.prototype.getLiveTimeline=function(){return this._liveTimeline},d.prototype.eventIdToTimeline=function(e){return this._eventIdToTimeline[e]},d.prototype.replaceEventId=function(e,t){const n=this._eventIdToTimeline[e];n&&(delete this._eventIdToTimeline[e],this._eventIdToTimeline[t]=n)},d.prototype.resetLiveTimeline=function(e,t){const n=!this._timelineSupport||!t,o=this._liveTimeline,r=n?o.forkLive(i.EventTimeline.FORWARDS):o.fork(i.EventTimeline.FORWARDS);n?(this._timelines=[r],this._eventIdToTimeline={}):this._timelines.push(r),t&&o.setPaginationToken(t,i.EventTimeline.FORWARDS),r.setPaginationToken(e,i.EventTimeline.BACKWARDS),this._liveTimeline=r,this.emit("Room.timelineReset",this.room,this,n)},d.prototype.getTimelineForEvent=function(e){const t=this._eventIdToTimeline[e];return void 0===t?null:t},d.prototype.findEventById=function(e){const t=this.getTimelineForEvent(e);if(t)return t.getEvents().find((function(t){return t.getId()==e}))},d.prototype.addTimeline=function(){if(!this._timelineSupport)throw new Error("timeline support is disabled. Set the 'timelineSupport' parameter to true when creating MatrixClient to enable it.");const e=new i.EventTimeline(this);return this._timelines.push(e),e},d.prototype.addEventsToTimeline=function(e,t,n,o){if(!n)throw new Error("'timeline' not specified for EventTimelineSet.addEventsToTimeline");if(!t&&n==this._liveTimeline)throw new Error("EventTimelineSet.addEventsToTimeline cannot be used for adding events to the live timeline - use Room.addLiveEvents instead");if(this._filter&&!(e=this._filter.filterRoomTimeline(e)).length)return;const r=t?i.EventTimeline.BACKWARDS:i.EventTimeline.FORWARDS,a=t?i.EventTimeline.FORWARDS:i.EventTimeline.BACKWARDS;let s=!1,c=!1;for(let o=0;o{this.aggregateRelations(e)}));const t=e.getRelation();if(!t)return;const n=t.event_id,o=t.rel_type,r=e.getType();let i=this._relations[n];i||(i=this._relations[n]={});let s=i[o];s||(s=i[o]={});let u,l=s[r];l||(l=s[r]=new c.Relations(o,r,this.room),u=this.findEventById(n)||this.room.getPendingEvent(n),u&&l.setTargetEvent(u)),l.addEvent(e)}},88910:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.EventTimeline=r;var o=n(26860);function r(e){this._eventTimelineSet=e,this._roomId=e.room?e.room.roomId:null,this._events=[],this._baseIndex=0,this._startState=new o.RoomState(this._roomId),this._startState.paginationToken=null,this._endState=new o.RoomState(this._roomId),this._endState.paginationToken=null,this._prevTimeline=null,this._nextTimeline=null,this._paginationRequests={b:null,f:null},this._name=this._roomId+":"+(new Date).toISOString()}r.BACKWARDS="b",r.FORWARDS="f",r.prototype.initialiseState=function(e){if(this._events.length>0)throw new Error("Cannot initialise state after events are added");for(const t of e)Object.freeze(t);this._startState.setStateEvents(e),this._endState.setStateEvents(e)},r.prototype.forkLive=function(e){const t=this.getState(e),n=new r(this._eventTimelineSet);return n._startState=t.clone(),n._endState=t,this._endState=t.clone(),n},r.prototype.fork=function(e){const t=this.getState(e),n=new r(this._eventTimelineSet);return n._startState=t.clone(),n._endState=t.clone(),n},r.prototype.getRoomId=function(){return this._roomId},r.prototype.getFilter=function(){return this._eventTimelineSet.getFilter()},r.prototype.getTimelineSet=function(){return this._eventTimelineSet},r.prototype.getBaseIndex=function(){return this._baseIndex},r.prototype.getEvents=function(){return this._events},r.prototype.getState=function(e){if(e==r.BACKWARDS)return this._startState;if(e==r.FORWARDS)return this._endState;throw new Error("Invalid direction '"+e+"'")},r.prototype.getPaginationToken=function(e){return this.getState(e).paginationToken},r.prototype.setPaginationToken=function(e,t){this.getState(t).paginationToken=e},r.prototype.getNeighbouringTimeline=function(e){if(e==r.BACKWARDS)return this._prevTimeline;if(e==r.FORWARDS)return this._nextTimeline;throw new Error("Invalid direction '"+e+"'")},r.prototype.setNeighbouringTimeline=function(e,t){if(this.getNeighbouringTimeline(t))throw new Error("timeline already has a neighbouring timeline - cannot reset neighbour (direction: "+t+")");if(t==r.BACKWARDS)this._prevTimeline=e;else{if(t!=r.FORWARDS)throw new Error("Invalid direction '"+t+"'");this._nextTimeline=e}this.setPaginationToken(null,t)},r.prototype.addEvent=function(e,t){const n=t?this._startState:this._endState,o=this.getTimelineSet();let i;o.room&&o.room.getUnfilteredTimelineSet()===o&&(r.setEventMetadata(e,n,t),e.isState()&&(n.setStateEvents([e]),e.sender&&("m.room.member"!==e.getType()||t)||r.setEventMetadata(e,n,t))),i=t?0:this._events.length,this._events.splice(i,0,e),t&&this._baseIndex++},r.setEventMetadata=function(e,t,n){e.sender=t.getSentinelMember(e.getSender()),"m.room.member"===e.getType()&&(e.target=t.getSentinelMember(e.getStateKey())),e.isState()&&n&&(e.forwardLooking=!1)},r.prototype.removeEvent=function(e){for(let t=this._events.length-1;t>=0;t--){const n=this._events[t];if(n.getId()==e)return this._events.splice(t,1),t{"use strict";var o=n(20862);Object.defineProperty(t,"__esModule",{value:!0}),t.MatrixEvent=t.EventStatus=void 0;var r=n(17187),i=o(n(3102)),a=n(7434);t.EventStatus={NOT_SENT:"not_sent",ENCRYPTING:"encrypting",SENDING:"sending",QUEUED:"queued",SENT:"sent",CANCELLED:"cancelled"};const s={};function u(e){return s[e]||(s[e]=e),s[e]}const c=function(e){["state_key","type","sender","room_id","membership"].forEach((t=>{e[t]&&(e[t]=u(e[t]))})),["membership","avatar_url","displayname"].forEach((t=>{e.content&&e.content[t]&&(e.content[t]=u(e.content[t]))})),["rel_type"].forEach((t=>{e.content&&e.content["m.relates_to"]&&e.content["m.relates_to"][t]&&(e.content["m.relates_to"][t]=u(e.content["m.relates_to"][t]))})),this.event=e||{},this.sender=null,this.target=null,this.status=null,this.error=null,this.forwardLooking=!0,this._pushActions=null,this._replacingEvent=null,this._localRedactionEvent=null,this._isCancelled=!1,this._clearEvent={},this._senderCurve25519Key=null,this._claimedEd25519Key=null,this._forwardingCurve25519KeyChain=[],this._untrusted=null,this._decryptionPromise=null,this._retryDecryption=!1,this.verificationRequest=null,this._txnId=e.txn_id||null,this._localTimestamp=Date.now()-this.getAge()};t.MatrixEvent=c,i.inherits(c,r.EventEmitter),i.extend(c.prototype,{getId:function(){return this.event.event_id},getSender:function(){return this.event.sender||this.event.user_id},getType:function(){return this._clearEvent.type||this.event.type},getWireType:function(){return this.event.type},getRoomId:function(){return this.event.room_id},getTs:function(){return this.event.origin_server_ts},getDate:function(){return this.event.origin_server_ts?new Date(this.event.origin_server_ts):null},getOriginalContent:function(){return this._localRedactionEvent?{}:this._clearEvent.content||this.event.content||{}},getContent:function(){return this._localRedactionEvent?{}:this._replacingEvent?this._replacingEvent.getContent()["m.new_content"]||{}:this.getOriginalContent()},getWireContent:function(){return this.event.content||{}},getPrevContent:function(){return this.getUnsigned().prev_content||this.event.prev_content||{}},getDirectionalContent:function(){return this.forwardLooking?this.getContent():this.getPrevContent()},getAge:function(){return this.getUnsigned().age||this.event.age},getLocalAge:function(){return Date.now()-this._localTimestamp},getStateKey:function(){return this.event.state_key},isState:function(){return void 0!==this.event.state_key},makeEncrypted:function(e,t,n,o){this._clearEvent={type:this.event.type,content:this.event.content},this.event.type=e,this.event.content=t,this._senderCurve25519Key=n,this._claimedEd25519Key=o},isBeingDecrypted:function(){return null!=this._decryptionPromise},isDecryptionFailure:function(){return this._clearEvent&&this._clearEvent.content&&"m.bad.encrypted"===this._clearEvent.content.msgtype},shouldAttemptDecryption:function(){return this.isEncrypted()&&!this.isBeingDecrypted()&&null===this.getClearContent()},attemptDecryption:async function(e,t={}){if("boolean"==typeof t&&(t={isRetry:t}),!this.isEncrypted())throw new Error("Attempt to decrypt event which isn't encrypted");if(this._clearEvent&&this._clearEvent.content&&"m.bad.encrypted"!==this._clearEvent.content.msgtype)throw new Error("Attempt to decrypt event which has already been decrypted");return this._decryptionPromise?(a.logger.log(`Event ${this.getId()} already being decrypted; queueing a retry`),this._retryDecryption=!0,this._decryptionPromise):(this._decryptionPromise=this._decryptionLoop(e,t),this._decryptionPromise)},cancelAndResendKeyRequest:function(e,t){const n=this.getWireContent();return e.requestRoomKey({algorithm:n.algorithm,room_id:this.getRoomId(),session_id:n.session_id,sender_key:n.sender_key},this.getKeyRequestRecipients(t),!0)},getKeyRequestRecipients:function(e){const t=this.getWireContent(),n=[{userId:e,deviceId:"*"}],o=this.getSender();return o!==e&&n.push({userId:o,deviceId:t.device_id}),n},_decryptionLoop:async function(e,t={}){for(await Promise.resolve();;){let n,o;this._retryDecryption=!1;try{e?(n=await e.decryptEvent(this),!0===t.isRetry&&a.logger.info(`Decrypted event on retry (id=${this.getId()})`)):n=this._badEncryptedMessage("Encryption not enabled")}catch(e){if("DecryptionError"!==e.name){const n=t.isRetry?"re":"";return a.logger.error(`Error ${n}decrypting event (id=${this.getId()}): ${e.stack||e}`),this._decryptionPromise=null,void(this._retryDecryption=!1)}if(o=e,this._retryDecryption){a.logger.log(`Got error decrypting event (id=${this.getId()}: ${e}), but retrying`);continue}a.logger.warn(`Error decrypting event (id=${this.getId()}): ${e.detailedString}`),n=this._badEncryptedMessage(e.message)}return this._decryptionPromise=null,this._retryDecryption=!1,this._setClearData(n),this.setPushActions(null),void(!1!==t.emit&&this.emit("Event.decrypted",this,o))}},_badEncryptedMessage:function(e){return{clearEvent:{type:"m.room.message",content:{msgtype:"m.bad.encrypted",body:"** Unable to decrypt: "+e+" **"}}}},_setClearData:function(e){this._clearEvent=e.clearEvent,this._senderCurve25519Key=e.senderCurve25519Key||null,this._claimedEd25519Key=e.claimedEd25519Key||null,this._forwardingCurve25519KeyChain=e.forwardingCurve25519KeyChain||[],this._untrusted=e.untrusted||!1},getClearContent:function(){const e=this._clearEvent;return e&&e.content?e.content:null},isEncrypted:function(){return!this.isState()&&"m.room.encrypted"===this.event.type},getSenderKey:function(){return this._senderCurve25519Key},getKeysClaimed:function(){return{ed25519:this._claimedEd25519Key}},getClaimedEd25519Key:function(){return this._claimedEd25519Key},getForwardingCurve25519KeyChain:function(){return this._forwardingCurve25519KeyChain},isKeySourceUntrusted:function(){return this._untrusted},getUnsigned:function(){return this.event.unsigned||{}},unmarkLocallyRedacted:function(){const e=this._localRedactionEvent;return this._localRedactionEvent=null,this.event.unsigned&&(this.event.unsigned.redacted_because=null),!!e},markLocallyRedacted:function(e){this._localRedactionEvent||(this.emit("Event.beforeRedaction",this,e),this._localRedactionEvent=e,this.event.unsigned||(this.event.unsigned={}),this.event.unsigned.redacted_because=e.event)},makeRedacted:function(e){if(!e.event)throw new Error("invalid redaction_event in makeRedacted");let t;for(t in this._localRedactionEvent=null,this.emit("Event.beforeRedaction",this,e),this._replacingEvent=null,this.event.unsigned||(this.event.unsigned={}),this.event.unsigned.redacted_because=e.event,this.event)this.event.hasOwnProperty(t)&&(l[t]||delete this.event[t]);const n=d[this.getType()]||{},o=this.getContent();for(t in o)o.hasOwnProperty(t)&&(n[t]||delete o[t])},isRedacted:function(){return Boolean(this.getUnsigned().redacted_because)},isRedaction:function(){return"m.room.redaction"===this.getType()},getRedactionEvent:function(){return this.isRedacted()?this._clearEvent.unsigned?this._clearEvent.unsigned.redacted_because:this.event.unsigned.redacted_because?this.event.unsigned.redacted_because:{}:null},getPushActions:function(){return this._pushActions},setPushActions:function(e){this._pushActions=e},handleRemoteEcho:function(e){const t=this.getUnsigned(),n=this.getId();this.event=e,t.redacted_because&&(this.event.unsigned||(this.event.unsigned={}),this.event.unsigned.redacted_because=t.redacted_because),this.setStatus(null),this.getId()!==n&&this.emit("Event.localEventIdReplaced",this)},isSending(){return!!this.status},setStatus(e){this.status=e,this.emit("Event.status",this,e)},replaceLocalEventId(e){this.event.event_id=e,this.emit("Event.localEventIdReplaced",this)},isRelation(e){const t=this.getWireContent(),n=t&&t["m.relates_to"];return n&&n.rel_type&&n.event_id&&(e&&n.rel_type===e||!e)},getRelation(){return this.isRelation()?this.getWireContent()["m.relates_to"]:null},makeReplaced(e){this.isRedacted()&&e||this._replacingEvent!==e&&(this._replacingEvent=e,this.emit("Event.replaced",this))},getAssociatedStatus(){return this._replacingEvent?this._replacingEvent.status:this._localRedactionEvent?this._localRedactionEvent.status:this.status},getServerAggregatedRelation(e){const t=this.getUnsigned()["m.relations"];if(t)return t[e]},replacingEventId(){const e=this.getServerAggregatedRelation("m.replace");return e?e.event_id:this._replacingEvent?this._replacingEvent.getId():void 0},replacingEvent(){return this._replacingEvent},replacingEventDate(){const e=this.getServerAggregatedRelation("m.replace");if(e){const t=e.origin_server_ts;if(Number.isFinite(t))return new Date(t)}else if(this._replacingEvent)return this._replacingEvent.getDate()},localRedactionEvent(){return this._localRedactionEvent},getAssociatedId(){const e=this.getRelation();return e?e.event_id:this.isRedaction()?this.event.redacts:void 0},hasAssocation(){return!!this.getAssociatedId()},updateAssociatedId(e){const t=this.getRelation();t?t.event_id=e:this.isRedaction()&&(this.event.redacts=e)},flagCancelled(e=!0){this._isCancelled=e},isCancelled(){return this._isCancelled},toJSON(){const e={type:this.getType(),sender:this.getSender(),content:this.getContent(),event_id:this.getId(),origin_server_ts:this.getTs(),unsigned:this.getUnsigned(),room_id:this.getRoomId()};return this.isRedaction()&&(e.redacts=this.event.redacts),this.isEncrypted()?{decrypted:e,encrypted:this.event}:e},setVerificationRequest:function(e){this.verificationRequest=e},setTxnId(e){this._txnId=e},getTxnId(){return this._txnId}});const l=["event_id","type","room_id","user_id","sender","state_key","prev_state","content","unsigned","origin_server_ts"].reduce((function(e,t){return e[t]=1,e}),{}),d={"m.room.member":{membership:1},"m.room.create":{creator:1},"m.room.join_rules":{join_rule:1},"m.room.power_levels":{ban:1,events:1,events_default:1,kick:1,redact:1,state_default:1,users:1,users_default:1},"m.room.aliases":{aliases:1}}},70142:(e,t,n)=>{"use strict";var o=n(20862);Object.defineProperty(t,"__esModule",{value:!0}),t.Group=a;var r=o(n(3102)),i=n(17187);function a(e){this.groupId=e,this.name=null,this.avatarUrl=null,this.myMembership=null,this.inviter=null}r.inherits(a,i.EventEmitter),a.prototype.setProfile=function(e,t){this.name===e&&this.avatarUrl===t||(this.name=e||this.groupId,this.avatarUrl=t,this.emit("Group.profile",this))},a.prototype.setMyMembership=function(e){this.myMembership!==e&&(this.myMembership=e,this.emit("Group.myMembership",this))},a.prototype.setInviter=function(e){this.inviter=e}},49690:(e,t,n)=>{"use strict";var o=n(95318);Object.defineProperty(t,"__esModule",{value:!0}),t.Relations=void 0;var r=o(n(59713)),i=n(17187),a=n(24369),s=n(7434);class u extends i.EventEmitter{constructor(e,t,n){super(),(0,r.default)(this,"_onEventStatus",((e,t)=>{e.isSending()?t===a.EventStatus.CANCELLED&&(e.removeListener("Event.status",this._onEventStatus),this._removeEvent(e)):e.removeListener("Event.status",this._onEventStatus)})),(0,r.default)(this,"_onBeforeRedaction",(async e=>{if(this._relations.has(e)){if(this._relations.delete(e),"m.annotation"===this.relationType)this._removeAnnotationFromAggregation(e);else if("m.replace"===this.relationType&&this._targetEvent){const e=await this.getLastReplacement();this._targetEvent.makeReplaced(e)}e.removeListener("Event.beforeRedaction",this._onBeforeRedaction),this.emit("Relations.redaction",e)}})),this.relationType=e,this.eventType=t,this._relationEventIds=new Set,this._relations=new Set,this._annotationsByKey={},this._annotationsBySender={},this._sortedAnnotationsByKey=[],this._targetEvent=null,this._room=n,this._creationEmitted=!1}async addEvent(e){if(this._relationEventIds.has(e.getId()))return;const t=e.getRelation();if(!t)return void s.logger.error("Event must have relation info");const n=t.rel_type,o=e.getType();if(this.relationType===n&&this.eventType===o){if(e.isSending()&&e.on("Event.status",this._onEventStatus),this._relations.add(e),this._relationEventIds.add(e.getId()),"m.annotation"===this.relationType)this._addAnnotationToAggregation(e);else if("m.replace"===this.relationType&&this._targetEvent){const e=await this.getLastReplacement();this._targetEvent.makeReplaced(e)}e.on("Event.beforeRedaction",this._onBeforeRedaction),this.emit("Relations.add",e),this._maybeEmitCreated()}else s.logger.error("Event relation info doesn't match this container")}async _removeEvent(e){if(!this._relations.has(e))return;const t=e.getRelation();if(!t)return void s.logger.error("Event must have relation info");const n=t.rel_type,o=e.getType();if(this.relationType===n&&this.eventType===o){if(this._relations.delete(e),"m.annotation"===this.relationType)this._removeAnnotationFromAggregation(e);else if("m.replace"===this.relationType&&this._targetEvent){const e=await this.getLastReplacement();this._targetEvent.makeReplaced(e)}this.emit("Relations.remove",e)}else s.logger.error("Event relation info doesn't match this container")}getRelations(){return[...this._relations]}_addAnnotationToAggregation(e){const{key:t}=e.getRelation();if(!t)return;let n=this._annotationsByKey[t];n||(n=this._annotationsByKey[t]=new Set,this._sortedAnnotationsByKey.push([t,n])),n.add(e),this._sortedAnnotationsByKey.sort(((e,t)=>{const n=e[1];return t[1].size-n.size}));const o=e.getSender();let r=this._annotationsBySender[o];r||(r=this._annotationsBySender[o]=new Set),r.add(e)}_removeAnnotationFromAggregation(e){const{key:t}=e.getRelation();if(!t)return;const n=this._annotationsByKey[t];n&&(n.delete(e),this._sortedAnnotationsByKey.sort(((e,t)=>{const n=e[1];return t[1].size-n.size})));const o=e.getSender(),r=this._annotationsBySender[o];r&&r.delete(e)}getSortedAnnotationsByKey(){return"m.annotation"!==this.relationType?null:this._sortedAnnotationsByKey}getAnnotationsBySender(){return"m.annotation"!==this.relationType?null:this._annotationsBySender}async getLastReplacement(){if("m.replace"!==this.relationType)return null;if(!this._targetEvent)return null;const e=this._targetEvent.getServerAggregatedRelation("m.replace"),t=e&&e.origin_server_ts,n=this.getRelations().reduce(((e,n)=>n.getSender()!==this._targetEvent.getSender()||t&&t>n.getTs()||e&&e.getTs()>n.getTs()?e:n),null);return null!=n&&n.shouldAttemptDecryption()?await n.attemptDecryption(this._room._client._crypto):null!=n&&n.isBeingDecrypted()&&await n._decryptionPromise,n}async setTargetEvent(e){if(!this._targetEvent){if(this._targetEvent=e,"m.replace"===this.relationType){const e=await this.getLastReplacement();e&&this._targetEvent.makeReplaced(e)}this._maybeEmitCreated()}}_maybeEmitCreated(){this._creationEmitted||this._targetEvent&&this._relations.size&&(this._creationEmitted=!0,this._targetEvent.emit("Event.relationsCreated",this.relationType,this.eventType))}}t.Relations=u},32848:(e,t,n)=>{"use strict";var o=n(20862);Object.defineProperty(t,"__esModule",{value:!0}),t.RoomMember=s;var r=n(17187),i=n(73667),a=o(n(3102));function s(e,t){this.roomId=e,this.userId=t,this.typing=!1,this.name=t,this.rawDisplayName=t,this.powerLevel=0,this.powerLevelNorm=0,this.user=null,this.membership=null,this.events={member:null},this._isOutOfBand=!1,this._updateModifiedTime()}a.inherits(s,r.EventEmitter),s.prototype.markOutOfBand=function(){this._isOutOfBand=!0},s.prototype.isOutOfBand=function(){return this._isOutOfBand},s.prototype.setMembershipEvent=function(e,t){if("m.room.member"!==e.getType())return;this._isOutOfBand=!1,this.events.member=e;const n=this.membership;this.membership=e.getDirectionalContent().membership;const o=this.name;this.name=function(e,t,n){if(!t||t===e)return e;if(!a.removeHiddenChars(t))return e;if(!n)return t;let o=u.test(t);return o||(o=c.test(t)),o||(o=n.getUserIdsWithDisplayName(t).some((t=>t!==e))),o?t+" ("+e+")":t}(this.userId,e.getDirectionalContent().displayname,t),this.rawDisplayName=e.getDirectionalContent().displayname||this.userId,n!==this.membership&&(this._updateModifiedTime(),this.emit("RoomMember.membership",e,this,n)),o!==this.name&&(this._updateModifiedTime(),this.emit("RoomMember.name",e,this,o))},s.prototype.setPowerLevelEvent=function(e){if("m.room.power_levels"!==e.getType())return;const t=e.getDirectionalContent();let n=t.users_default||0;const o=t.users||{};Object.values(o).forEach((function(e){n=Math.max(n,e)}));const r=this.powerLevel,i=this.powerLevelNorm;void 0!==o[this.userId]?this.powerLevel=o[this.userId]:void 0!==t.users_default?this.powerLevel=t.users_default:this.powerLevel=0,this.powerLevelNorm=0,n>0&&(this.powerLevelNorm=100*this.powerLevel/n),r===this.powerLevel&&i===this.powerLevelNorm||(this._updateModifiedTime(),this.emit("RoomMember.powerLevel",e,this))},s.prototype.setTypingEvent=function(e){if("m.typing"!==e.getType())return;const t=this.typing;this.typing=!1;const n=e.getContent().user_ids;Array.isArray(n)&&(-1!==n.indexOf(this.userId)&&(this.typing=!0),t!==this.typing&&(this._updateModifiedTime(),this.emit("RoomMember.typing",e,this)))},s.prototype._updateModifiedTime=function(){this._modified=Date.now()},s.prototype.getLastModifiedTime=function(){return this._modified},s.prototype.isKicked=function(){return"leave"===this.membership&&this.events.member.getSender()!==this.events.member.getStateKey()},s.prototype.getDMInviter=function(){if(this.events.member){const e=this.events.member;let t=e.getContent(),n=e.getSender();if("join"===t.membership&&(t=e.getPrevContent(),n=e.getUnsigned().prev_sender),"invite"===t.membership&&t.is_direct)return n}},s.prototype.getAvatarUrl=function(e,t,n,o,r,a){void 0===r&&(r=!0);const s=this.getMxcAvatarUrl();if(!s&&!r)return null;return(0,i.getHttpUriForMxc)(e,s,t,n,o,a)||null},s.prototype.getMxcAvatarUrl=function(){return this.events.member?this.events.member.getDirectionalContent().avatar_url:this.user?this.user.avatarUrl:null};const u=/@.+:.+/,c=/[\u200E\u200F\u202A-\u202F]/},26860:(e,t,n)=>{"use strict";var o=n(20862);Object.defineProperty(t,"__esModule",{value:!0}),t.RoomState=c;var r=n(17187),i=n(32848),a=n(7434),s=o(n(3102)),u=n(42481);function c(e,t){this.roomId=e,this.members={},this.events=new Map,this.paginationToken=null,this._sentinels={},this._updateModifiedTime(),this._displayNameToUserIds={},this._userIdsToDisplayNames={},this._tokenToInvite={},this._joinedMemberCount=null,this._summaryJoinedMemberCount=null,this._invitedMemberCount=null,this._summaryInvitedMemberCount=null,t||(t={status:1}),this._oobMemberFlags=t}function l(e,t,n){const o=e._userIdsToDisplayNames[t];if(delete e._userIdsToDisplayNames[t],o){const n=s.removeHiddenChars(o),r=e._displayNameToUserIds[n];if(r){const o=r.filter((e=>e!==t));e._displayNameToUserIds[n]=o}}e._userIdsToDisplayNames[t]=n;const r=n&&s.removeHiddenChars(n);r&&(e._displayNameToUserIds[r]||(e._displayNameToUserIds[r]=[]),e._displayNameToUserIds[r].push(t))}s.inherits(c,r.EventEmitter),c.prototype.getJoinedMemberCount=function(){return null!==this._summaryJoinedMemberCount?this._summaryJoinedMemberCount:(null===this._joinedMemberCount&&(this._joinedMemberCount=this.getMembers().reduce(((e,t)=>"join"===t.membership?e+1:e),0)),this._joinedMemberCount)},c.prototype.setJoinedMemberCount=function(e){this._summaryJoinedMemberCount=e},c.prototype.getInvitedMemberCount=function(){return null!==this._summaryInvitedMemberCount?this._summaryInvitedMemberCount:(null===this._invitedMemberCount&&(this._invitedMemberCount=this.getMembers().reduce(((e,t)=>"invite"===t.membership?e+1:e),0)),this._invitedMemberCount)},c.prototype.setInvitedMemberCount=function(e){this._summaryInvitedMemberCount=e},c.prototype.getMembers=function(){return Object.values(this.members)},c.prototype.getMembersExcept=function(e){return Object.values(this.members).filter((t=>!e.includes(t.userId)))},c.prototype.getMember=function(e){return this.members[e]||null},c.prototype.getSentinelMember=function(e){if(!e)return null;let t=this._sentinels[e];if(void 0===t){t=new i.RoomMember(this.roomId,e);const n=this.members[e];n&&t.setMembershipEvent(n.events.member,this),this._sentinels[e]=t}return t},c.prototype.getStateEvents=function(e,t){if(!this.events.has(e))return void 0===t?[]:null;if(void 0===t)return Array.from(this.events.get(e).values());return this.events.get(e).get(t)||null},c.prototype.clone=function(){const e=new c(this.roomId,this._oobMemberFlags),t=this._oobMemberFlags.status;return this._oobMemberFlags.status=1,Array.from(this.events.values()).forEach((t=>{e.setStateEvents(Array.from(t.values()))})),this._oobMemberFlags.status=t,null!==this._summaryInvitedMemberCount&&e.setInvitedMemberCount(this.getInvitedMemberCount()),null!==this._summaryJoinedMemberCount&&e.setJoinedMemberCount(this.getJoinedMemberCount()),3==this._oobMemberFlags.status&&this.getMembers().forEach((t=>{t.isOutOfBand()&&e.getMember(t.userId).markOutOfBand()})),e},c.prototype.setUnknownStateEvents=function(e){const t=e.filter((e=>!this.events.has(e.getType())||!this.events.get(e.getType()).has(e.getStateKey())));this.setStateEvents(t)},c.prototype.setStateEvents=function(e){const t=this;this._updateModifiedTime(),e.forEach((function(e){if(e.getRoomId()!==t.roomId)return;if(!e.isState())return;const n=t._getStateEventMatching(e);t._setStateEvent(e),"m.room.member"===e.getType()&&(l(t,e.getStateKey(),e.getContent().displayname),function(e,t){if(!t.getContent().third_party_invite)return;const n=(t.getContent().third_party_invite.signed||{}).token;n&&e.getStateEvents("m.room.third_party_invite",n)&&(e._tokenToInvite[n]=t)}(t,e)),t.emit("RoomState.events",e,t,n)})),e.forEach((function(e){if(e.getRoomId()===t.roomId&&e.isState())if("m.room.member"===e.getType()){const n=e.getStateKey();"leave"!==e.getContent().membership&&"ban"!==e.getContent().membership||(e.getContent().avatar_url=e.getContent().avatar_url||e.getPrevContent().avatar_url,e.getContent().displayname=e.getContent().displayname||e.getPrevContent().displayname);const o=t._getOrCreateMember(n,e);o.setMembershipEvent(e,t),t._updateMember(o),t.emit("RoomState.members",e,t,o)}else"m.room.power_levels"===e.getType()&&(Object.values(t.members).forEach((function(n){const o=n.getLastModifiedTime();n.setPowerLevelEvent(e),o!==n.getLastModifiedTime()&&t.emit("RoomState.members",e,t,n)})),t._sentinels={})}))},c.prototype._getOrCreateMember=function(e,t){let n=this.members[e];return n||(n=new i.RoomMember(this.roomId,e),this.members[e]=n,this.emit("RoomState.newMember",t,this,n)),n},c.prototype._setStateEvent=function(e){this.events.has(e.getType())||this.events.set(e.getType(),new Map),this.events.get(e.getType()).set(e.getStateKey(),e)},c.prototype._getStateEventMatching=function(e){return this.events.has(e.getType())?this.events.get(e.getType()).get(e.getStateKey()):null},c.prototype._updateMember=function(e){const t=this.getStateEvents("m.room.power_levels","");t&&e.setPowerLevelEvent(t),delete this._sentinels[e.userId],this.members[e.userId]=e,this._joinedMemberCount=null,this._invitedMemberCount=null},c.prototype.needsOutOfBandMembers=function(){return 1===this._oobMemberFlags.status},c.prototype.markOutOfBandMembersStarted=function(){1===this._oobMemberFlags.status&&(this._oobMemberFlags.status=2)},c.prototype.markOutOfBandMembersFailed=function(){2===this._oobMemberFlags.status&&(this._oobMemberFlags.status=1)},c.prototype.clearOutOfBandMembers=function(){let e=0;Object.keys(this.members).forEach((t=>{this.members[t].isOutOfBand()&&(++e,delete this.members[t])})),a.logger.log(`LL: RoomState removed ${e} members...`),this._oobMemberFlags.status=1},c.prototype.setOutOfBandMembers=function(e){a.logger.log(`LL: RoomState about to set ${e.length} OOB members ...`),2===this._oobMemberFlags.status&&(a.logger.log("LL: RoomState put in OOB_STATUS_FINISHED state ..."),this._oobMemberFlags.status=3,e.forEach((e=>this._setOutOfBandMember(e))))},c.prototype._setOutOfBandMember=function(e){if("m.room.member"!==e.getType())return;const t=e.getStateKey(),n=this.getMember(t);if(n&&!n.isOutOfBand())return;const o=this._getOrCreateMember(t,e);o.setMembershipEvent(e,this),o.markOutOfBand(),l(this,o.userId,o.name),this._setStateEvent(e),this._updateMember(o),this.emit("RoomState.members",e,this,o)},c.prototype.setTypingEvent=function(e){Object.values(this.members).forEach((function(t){t.setTypingEvent(e)}))},c.prototype.getInviteForThreePidToken=function(e){return this._tokenToInvite[e]||null},c.prototype._updateModifiedTime=function(){this._modified=Date.now()},c.prototype.getLastModifiedTime=function(){return this._modified},c.prototype.getUserIdsWithDisplayName=function(e){return this._displayNameToUserIds[s.removeHiddenChars(e)]||[]},c.prototype.maySendRedactionForEvent=function(e,t){const n=this.getMember(t);if(!n||"leave"===n.membership)return!1;if(e.status||e.isRedacted())return!1;const o=this.maySendEvent("m.room.redaction",t);return e.getSender()===t?o:this._hasSufficientPowerLevelFor("redact",n.powerLevel)},c.prototype._hasSufficientPowerLevelFor=function(e,t){const n=this.getStateEvents("m.room.power_levels","");let o={};n&&(o=n.getContent());let r=50;return s.isNumber(o[e])&&(r=o[e]),t>=r},c.prototype.maySendMessage=function(e){return this._maySendEventOfType("m.room.message",e,!1)},c.prototype.maySendEvent=function(e,t){return this._maySendEventOfType(e,t,!1)},c.prototype.mayClientSendStateEvent=function(e,t){return!t.isGuest()&&this.maySendStateEvent(e,t.credentials.userId)},c.prototype.maySendStateEvent=function(e,t){return this._maySendEventOfType(e,t,!0)},c.prototype._maySendEventOfType=function(e,t,n){const o=this.getStateEvents("m.room.power_levels","");let r,i={},a=0,s=0,u=0;if(o){r=o.getContent(),i=r.events||{},a=Number.isFinite(r.state_default)?r.state_default:50;const e=r.users&&r.users[t];Number.isFinite(e)?u=e:Number.isFinite(r.users_default)&&(u=r.users_default),Number.isFinite(r.events_default)&&(s=r.events_default)}let c=n?a:s;return Number.isFinite(i[e])&&(c=i[e]),u>=c},c.prototype.mayTriggerNotifOfType=function(e,t){const n=this.getMember(t);if(!n)return!1;const o=this.getStateEvents("m.room.power_levels","");let r=50;return o&&o.getContent()&&o.getContent().notifications&&s.isNumber(o.getContent().notifications[e])&&(r=o.getContent().notifications[e]),n.powerLevel>=r},c.prototype.getJoinRule=function(){const e=this.getStateEvents(u.EventType.RoomJoinRules,"");return(e?e.getContent():{}).join_rule||"invite"}},65205:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.RoomSummary=function(e,t){this.roomId=e,this.info=t}},27366:(e,t,n)=>{"use strict";var o=n(20862),r=n(95318);Object.defineProperty(t,"__esModule",{value:!0}),t.Room=v;var i=r(n(59713)),a=n(17187),s=n(33705),u=n(88910),c=n(73667),l=o(n(3102)),d=n(24369),h=n(32848),p=n(65205),f=n(7434),g=n(20771),m=n(42481);function _(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function F(e){for(var t=1;t{const t=new d.MatrixEvent(e);"m.room.encrypted"===t.getType()&&await t.attemptDecryption(this._client._crypto),t.setStatus(d.EventStatus.NOT_SENT),this.addPendingEvent(t,t.getTxnId())}))}this._blacklistUnverifiedDevices=null,this._selfMembership=null,this._summaryHeroes=null,this._opts.lazyLoadMembers?this._membersPromise=null:this._membersPromise=Promise.resolve(),this.getTypeWarning=!1,this.getVersionWarning=!1}function w(e){return`mx_pending_events_${e}`}l.inherits(v,a.EventEmitter),v.prototype.decryptCriticalEvents=function(){const e=this.getEventReadUpTo(this._client.getUserId(),!0),t=this.getLiveTimeline().getEvents(),n=t.findIndex((t=>t.event.event_id===e)),o=t.slice(n).filter((e=>e.shouldAttemptDecryption())).reverse().map((e=>e.attemptDecryption(this._client._crypto,{isRetry:!0})));return Promise.allSettled(o)},v.prototype.decryptAllEvents=function(){const e=this.getUnfilteredTimelineSet().getLiveTimeline().getEvents().filter((e=>e.shouldAttemptDecryption())).reverse().map((e=>e.attemptDecryption(this._client._crypto,{isRetry:!0})));return Promise.allSettled(e)},v.prototype.getVersion=function(){const e=this.currentState.getStateEvents("m.room.create","");if(!e)return this.getVersionWarning||(f.logger.warn("[getVersion] Room "+this.roomId+" does not have an m.room.create event"),this.getVersionWarning=!0),"1";const t=e.getContent().room_version;return void 0===t?"1":t},v.prototype.shouldUpgradeToVersion=function(){return y.includes(this.getVersion())?null:"6"},v.prototype.getRecommendedVersion=async function(){let e=(await this._client.getCapabilities())["m.room_versions"];if(!e){e={default:"6",available:{}};for(const t of y)e.available[t]="stable"}let t=this._checkVersionAgainstCapability(e);if(t.urgent&&t.needsUpgrade){if(f.logger.warn("Refreshing room version capability because the server looks to be supporting a newer room version we don't know about."),e=(await this._client.getCapabilities(!0))["m.room_versions"],!e)return f.logger.warn("No room version capability - assuming upgrade required."),t;t=this._checkVersionAgainstCapability(e)}return t},v.prototype._checkVersionAgainstCapability=function(e){const t=this.getVersion();f.logger.log(`[${this.roomId}] Current version: ${t}`),f.logger.log(`[${this.roomId}] Version capability: `,e);const n={version:t,needsUpgrade:!1,urgent:!1};return t===e.default||Object.keys(e.available).filter((t=>"stable"===e.available[t])).includes(t)||(n.version=e.default,n.needsUpgrade=!0,n.urgent=!!this.getVersion().match(/^[0-9]+[0-9.]*$/g),n.urgent?f.logger.warn(`URGENT upgrade required on ${this.roomId}`):f.logger.warn(`Non-urgent upgrade required on ${this.roomId}`)),n},v.prototype.userMayUpgradeRoom=function(e){return this.currentState.maySendStateEvent("m.room.tombstone",e)},v.prototype.getPendingEvents=function(){if("detached"!==this._opts.pendingEventOrdering)throw new Error("Cannot call getPendingEvents with pendingEventOrdering == "+this._opts.pendingEventOrdering);return this._pendingEventList},v.prototype.removePendingEvent=function(e){if("detached"!==this._opts.pendingEventOrdering)throw new Error("Cannot call removePendingEvent with pendingEventOrdering == "+this._opts.pendingEventOrdering);const t=l.removeElement(this._pendingEventList,(function(t){return t.getId()==e}),!1);return this._savePendingEvents(),t},v.prototype.hasPendingEvent=function(e){return"detached"===this._opts.pendingEventOrdering&&this._pendingEventList.some((t=>t.getId()===e))},v.prototype.getPendingEvent=function(e){return"detached"!==this._opts.pendingEventOrdering?null:this._pendingEventList.find((t=>t.getId()===e))},v.prototype.getLiveTimeline=function(){return this.getUnfilteredTimelineSet().getLiveTimeline()},v.prototype.getLastActiveTimestamp=function(){const e=this.getLiveTimeline().getEvents();return e.length?e[e.length-1].getTs():Number.MIN_SAFE_INTEGER},v.prototype.getMyMembership=function(){return this._selfMembership},v.prototype.getDMInviter=function(){if(this.myUserId){const e=this.getMember(this.myUserId);if(e)return e.getDMInviter()}if("invite"===this._selfMembership&&2==this.getInvitedAndJoinedMemberCount()&&this._summaryHeroes.length)return this._summaryHeroes[0]},v.prototype.guessDMUserId=function(){const e=this.getMember(this.myUserId);if(e){const t=e.getDMInviter();if(t)return t}if(Array.isArray(this._summaryHeroes)&&this._summaryHeroes.length)return this._summaryHeroes[0];const t=this.currentState.getMembers().find((e=>e.userId!==this.myUserId));return t?t.userId:this.myUserId},v.prototype.getAvatarFallbackMember=function(){if(this.getInvitedAndJoinedMemberCount()>2)return;const e=Array.isArray(this._summaryHeroes)&&this._summaryHeroes.length;if(e){const e=this._summaryHeroes.map((e=>this.getMember(e))).find((e=>!!e));if(e)return e}const t=this.currentState.getMembers();if(t.length<=2){const e=t.find((e=>e.userId!==this.myUserId));if(e)return e}if(e){const e=this._summaryHeroes.map((e=>this._client.getUser(e))).find((e=>!!e));if(e){const t=new h.RoomMember(this.roomId,e.userId);return t.user=e,t}}},v.prototype.updateMyMembership=function(e){const t=this._selfMembership;this._selfMembership=e,t!==e&&("leave"===e&&this._cleanupAfterLeaving(),this.emit("Room.myMembership",this,e,t))},v.prototype._loadMembersFromServer=async function(){const e=this._client.store.getSyncToken(),t=l.encodeParams({not_membership:"leave",at:e}),n=l.encodeUri("/rooms/$roomId/members?"+t,{$roomId:this.roomId}),o=this._client._http;return(await o.authedRequest(void 0,"GET",n)).chunk},v.prototype._loadMembers=async function(){let e=!1,t=await this._client.store.getOutOfBandMembers(this.roomId);return null===t&&(e=!0,t=await this._loadMembersFromServer(),f.logger.log(`LL: got ${t.length} members from server for room ${this.roomId}`)),{memberEvents:t.map(this._client.getEventMapper()),fromServer:e}},v.prototype.loadMembersIfNeeded=function(){if(this._membersPromise)return this._membersPromise;this.currentState.markOutOfBandMembersStarted();const e=this._loadMembers().then((e=>(this.currentState.setOutOfBandMembers(e.memberEvents),this._client.isCryptoEnabled()&&this._client.isRoomEncrypted(this.roomId)&&this._client._crypto.trackRoomDevices(this.roomId),e.fromServer))).catch((e=>{throw this._membersPromise=null,this.currentState.markOutOfBandMembersFailed(),e}));return e.then((e=>{if(e){const e=this.currentState.getMembers().filter((e=>e.isOutOfBand())).map((e=>e.events.member.event));return f.logger.log(`LL: telling store to write ${e.length} members for room ${this.roomId}`),this._client.store.setOutOfBandMembers(this.roomId,e).catch((e=>{f.logger.log("LL: storing OOB room members failed, oh well",e)}))}})).catch((e=>{f.logger.error(e)})),this._membersPromise=e,this._membersPromise},v.prototype.clearLoadedMembersIfNeeded=async function(){this._opts.lazyLoadMembers&&this._membersPromise&&(await this.loadMembersIfNeeded(),await this._client.store.clearOutOfBandMembers(this.roomId),this.currentState.clearOutOfBandMembers(),this._membersPromise=null)},v.prototype._cleanupAfterLeaving=function(){this.clearLoadedMembersIfNeeded().catch((e=>{f.logger.error(`error after clearing loaded members from room ${this.roomId} after leaving`),f.logger.log(e)}))},v.prototype.resetLiveTimeline=function(e,t){for(let n=0;ne.isUnverified())))return!0;return!1},v.prototype.getTimelineSets=function(){return this._timelineSets},v.prototype.getUnfilteredTimelineSet=function(){return this._timelineSets[0]},v.prototype.getTimelineForEvent=function(e){return this.getUnfilteredTimelineSet().getTimelineForEvent(e)},v.prototype.addTimeline=function(){return this.getUnfilteredTimelineSet().addTimeline()},v.prototype.findEventById=function(e){return this.getUnfilteredTimelineSet().findEventById(e)},v.prototype.getUnreadNotificationCount=function(e){return e=e||"total",this._notificationCounts[e]},v.prototype.setUnreadNotificationCount=function(e,t){this._notificationCounts[e]=t},v.prototype.setSummary=function(e){const t=e["m.heroes"],n=e["m.joined_member_count"],o=e["m.invited_member_count"];Number.isInteger(n)&&this.currentState.setJoinedMemberCount(n),Number.isInteger(o)&&this.currentState.setInvitedMemberCount(o),Array.isArray(t)&&(this._summaryHeroes=t.filter((e=>e!==this.myUserId)))},v.prototype.setBlacklistUnverifiedDevices=function(e){this._blacklistUnverifiedDevices=e},v.prototype.getBlacklistUnverifiedDevices=function(){return this._blacklistUnverifiedDevices},v.prototype.getAvatarUrl=function(e,t,n,o,r){const i=this.currentState.getStateEvents(m.EventType.RoomAvatar,"");if(void 0===r&&(r=!0),!i&&!r)return null;const a=i?i.getContent().url:null;return a?(0,c.getHttpUriForMxc)(e,a,t,n,o):null},v.prototype.getMxcAvatarUrl=function(){const e=this.currentState.getStateEvents(m.EventType.RoomAvatar,"");return e?e.getContent().url:null},v.prototype.getAliases=function(){const e=[],t=this.currentState.getStateEvents("m.room.aliases");if(t)for(let n=0;n"string"==typeof e&&"#"===e[0]&&!!e.endsWith(`:${o.getStateKey()}`)));Array.prototype.push.apply(e,t)}}return e},v.prototype.getCanonicalAlias=function(){const e=this.currentState.getStateEvents("m.room.canonical_alias","");return e&&e.getContent().alias||null},v.prototype.getAltAliases=function(){const e=this.currentState.getStateEvents("m.room.canonical_alias","");return e&&e.getContent().alt_aliases||[]},v.prototype.addEventsToTimeline=function(e,t,n,o){n.getTimelineSet().addEventsToTimeline(e,t,n,o)},v.prototype.getMember=function(e){return this.currentState.getMember(e)},v.prototype.getMembers=function(){return this.currentState.getMembers()},v.prototype.getJoinedMembers=function(){return this.getMembersWithMembership("join")},v.prototype.getJoinedMemberCount=function(){return this.currentState.getJoinedMemberCount()},v.prototype.getInvitedMemberCount=function(){return this.currentState.getInvitedMemberCount()},v.prototype.getInvitedAndJoinedMemberCount=function(){return this.getInvitedMemberCount()+this.getJoinedMemberCount()},v.prototype.getMembersWithMembership=function(e){return this.currentState.getMembers().filter((function(t){return t.membership===e}))},v.prototype.getEncryptionTargetMembers=async function(){await this.loadMembersIfNeeded();let e=this.getMembersWithMembership("join");return this.shouldEncryptForInvitedMembers()&&(e=e.concat(this.getMembersWithMembership("invite"))),e},v.prototype.shouldEncryptForInvitedMembers=function(){const e=this.currentState.getStateEvents("m.room.history_visibility","");return e&&e.getContent()&&"joined"!==e.getContent().history_visibility},v.prototype.getDefaultRoomName=function(e){return k(this,e,!0)},v.prototype.hasMembershipState=function(e,t){const n=this.getMember(e);return!!n&&n.membership===t},v.prototype.getOrCreateFilteredTimelineSet=function(e){if(this._filteredTimelineSets[e.filterId])return this._filteredTimelineSets[e.filterId];const t=Object.assign({filter:e},this._opts),n=new s.EventTimelineSet(this,t);this.reEmitter.reEmit(n,["Room.timeline","Room.timelineReset"]),this._filteredTimelineSets[e.filterId]=n,this._timelineSets.push(n);const o=this.getLiveTimeline();o.getEvents().forEach((function(e){n.addLiveEvent(e)}));let r=o;for(;r.getNeighbouringTimeline(u.EventTimeline.BACKWARDS);)r=r.getNeighbouringTimeline(u.EventTimeline.BACKWARDS);return n.getLiveTimeline().setPaginationToken(r.getPaginationToken(u.EventTimeline.BACKWARDS),u.EventTimeline.BACKWARDS),n},v.prototype.removeFilteredTimelineSet=function(e){const t=this._filteredTimelineSets[e.filterId];delete this._filteredTimelineSets[e.filterId];const n=this._timelineSets.indexOf(t);n>-1&&this._timelineSets.splice(n,1)},v.prototype._addLiveEvent=function(e,t,n){if(e.isRedaction()){const t=e.event.redacts,n=this.getUnfilteredTimelineSet().findEventById(t);n&&(n.makeRedacted(e),n.getStateKey()&&this.currentState.getStateEvents(n.getType(),n.getStateKey()).getId()===n.getId()&&this.currentState.setStateEvents([n]),this.emit("Room.redaction",e,this))}if(e.getUnsigned().transaction_id){const t=this._txnToEvent[e.getUnsigned().transaction_id];if(t)return void this._handleRemoteEcho(e,t)}for(let o=0;oe.status===d.EventStatus.NOT_SENT))&&(f.logger.warn("Setting event as NOT_SENT due to messages in the same state"),e.setStatus(d.EventStatus.NOT_SENT)),this._pendingEventList.push(e),this._savePendingEvents(),e.isRelation()&&this._aggregateNonLiveRelation(e),e.isRedaction()){const t=e.event.redacts;let n=this._pendingEventList&&this._pendingEventList.find((e=>e.getId()===t));n||(n=this.getUnfilteredTimelineSet().findEventById(t)),n&&(n.markLocallyRedacted(e),this.emit("Room.redaction",e,this))}}else for(let t=0;tF(F({},e.event),{},{txn_id:e.getTxnId()}))).filter((e=>{const t="m.room.encrypted"===e.type,n=this._client.isRoomEncrypted(this.roomId);return t||!n})),{store:t}=this._client._sessionStore;this._pendingEventList.length>0?t.setItem(w(this.roomId),JSON.stringify(e)):t.removeItem(w(this.roomId))}},v.prototype._aggregateNonLiveRelation=function(e){for(let t=0;t ${o} old status ${r}`),delete this._txnToEvent[e.getUnsigned().transaction_id],this._pendingEventList&&this.removePendingEvent(n),t.handleRemoteEcho(e.event);for(let e=0;e{const n=e.getMember(t);return n?n.name:t}));else{let n=e.currentState.getMembers().filter((e=>e.userId!==t&&("invite"===e.membership||"join"===e.membership)));n.sort(((e,t)=>e.userId.localeCompare(t.userId))),n=n.slice(0,5),i=n.map((e=>e.name))}if(r)return D(i,r);if("join"==e.getMyMembership()){const t=e.currentState.getStateEvents("m.room.third_party_invite");if(t&&t.length)return`Inviting ${D(t.map((e=>e.getContent().display_name)))}`}let a=i;return a.length||(a=e.currentState.getMembers().filter((e=>e.userId!==t&&"invite"!==e.membership&&"join"!==e.membership)).map((e=>e.name))),a.length?`Empty room (was ${D(a)})`:"Empty room"}function D(e,t=e.length+1){const n=t-1;return e.length?1===e.length&&n<=1?e[0]:2===e.length&&n<=2?`${e[0]} and ${e[1]}`:n>1?`${e[0]} and ${n} others`:`${e[0]} and 1 other`:"Empty room"}E[d.EventStatus.ENCRYPTING]=[d.EventStatus.SENDING,d.EventStatus.NOT_SENT],E[d.EventStatus.SENDING]=[d.EventStatus.ENCRYPTING,d.EventStatus.QUEUED,d.EventStatus.NOT_SENT,d.EventStatus.SENT],E[d.EventStatus.QUEUED]=[d.EventStatus.SENDING,d.EventStatus.CANCELLED],E[d.EventStatus.SENT]=[],E[d.EventStatus.NOT_SENT]=[d.EventStatus.SENDING,d.EventStatus.QUEUED,d.EventStatus.CANCELLED],E[d.EventStatus.CANCELLED]=[],v.prototype.updatePendingEvent=function(e,t,n){if(f.logger.log(`setting pendingEvent status to ${t} in ${e.getRoomId()} event ID ${e.getId()} -> ${n}`),t==d.EventStatus.SENT&&!n)throw new Error("updatePendingEvent called with status=SENT, but no new event id");if(t==d.EventStatus.SENT&&this.getUnfilteredTimelineSet().eventIdToTimeline(n))return;const o=e.status,r=e.getId();if(!o)throw new Error("updatePendingEventStatus called on an event which is not a local echo.");const i=E[o];if(!i||i.indexOf(t)<0)throw new Error("Invalid EventStatus transition "+o+"->"+t);if(e.setStatus(t),t==d.EventStatus.SENT){e.replaceLocalEventId(n);for(let e=0;ee.getId()===r));if(-1!==e){const[t]=this._pendingEventList.splice(e,1);t.isRedaction()&&this._revertRedactionLocalEcho(t)}}this.removeEvent(r)}this._savePendingEvents(),this.emit("Room.localEchoUpdated",e,this,r,o)},v.prototype._revertRedactionLocalEcho=function(e){const t=e.event.redacts;if(!t)return;const n=this.getUnfilteredTimelineSet().findEventById(t);n&&(n.unmarkLocallyRedacted(),this.emit("Room.redactionCancelled",e,this),n.isRelation()&&this._aggregateNonLiveRelation(n))},v.prototype.addLiveEvents=function(e,t,n){let o;if(t&&-1===["replace","ignore"].indexOf(t))throw new Error("duplicateStrategy MUST be either 'replace' or 'ignore'");for(o=0;o=0;--e){const o=this.timeline[e];if(o.getId()===t)return!1;if(o.getId()===n)return!0}return!1},v.prototype.getReceiptsForEvent=function(e){return this._receiptCacheByEventId[e.getId()]||[]},v.prototype.addReceipt=function(e,t){void 0===t&&(t=!1),t||this._addReceiptsToStructure(e,this._realReceipts),this._addReceiptsToStructure(e,this._receipts),this._receiptCacheByEventId=this._buildReceiptCache(this._receipts),this.emit("Room.receipt",e,this)},v.prototype._addReceiptsToStructure=function(e,t){const n=this;Object.keys(e.getContent()).forEach((function(o){Object.keys(e.getContent()[o]).forEach((function(r){Object.keys(e.getContent()[o][r]).forEach((function(i){const a=e.getContent()[o][r][i];t[r]||(t[r]={});const s=t[r][i];if(s){const e=n.getUnfilteredTimelineSet().compareEventOrdering(s.eventId,o);if(null!==e&&e>=0)return}else t[r][i]={};t[r][i]={eventId:o,data:a}}))}))}))},v.prototype._buildReceiptCache=function(e){const t={};return Object.keys(e).forEach((function(n){Object.keys(e[n]).forEach((function(o){const r=e[n][o];t[r.eventId]||(t[r.eventId]=[]),t[r.eventId].push({userId:o,type:n,data:r.data})}))})),t},v.prototype._addLocalEchoReceipt=function(e,t,n){this.addReceipt(b(e,t,n),!0)},v.prototype.addTags=function(e){this.tags=e.getContent().tags||{},this.emit("Room.tags",e,this)},v.prototype.addAccountData=function(e){for(let t=0;tr.powerLevel&&(t=!1),t},v.prototype.getJoinRule=function(){return this.currentState.getJoinRule()},v.prototype.getType=function(){const e=this.currentState.getStateEvents("m.room.create","");if(e)return e.getContent()[m.RoomCreateTypeField];this.getTypeWarning||(f.logger.warn("[getType] Room "+this.roomId+" does not have an m.room.create event"),this.getTypeWarning=!0)},v.prototype.isSpaceRoom=function(){return this.getType()===m.RoomType.Space}},41398:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.SearchResult=r;var o=n(43558);function r(e,t){this.rank=e,this.context=t}r.fromJson=function(e,t){const n=e.context||{},i=n.events_before||[],a=n.events_after||[],s=new o.EventContext(t(e.result));return s.setPaginateToken(n.start,!0),s.addEvents(i.map(t),!0),s.addEvents(a.map(t),!1),s.setPaginateToken(n.end,!1),new r(e.rank,s)}},83998:(e,t,n)=>{"use strict";var o=n(20862);Object.defineProperty(t,"__esModule",{value:!0}),t.User=a;var r=o(n(3102)),i=n(17187);function a(e){this.userId=e,this.presence="offline",this.presenceStatusMsg=null,this._unstable_statusMessage="",this.displayName=e,this.rawDisplayName=e,this.avatarUrl=null,this.lastActiveAgo=0,this.lastPresenceTs=0,this.currentlyActive=!1,this.events={presence:null,profile:null},this._updateModifiedTime()}r.inherits(a,i.EventEmitter),a.prototype.setPresenceEvent=function(e){if("m.presence"!==e.getType())return;const t=null===this.events.presence;this.events.presence=e;const n=[];(e.getContent().presence!==this.presence||t)&&n.push("User.presence"),e.getContent().avatar_url&&e.getContent().avatar_url!==this.avatarUrl&&n.push("User.avatarUrl"),e.getContent().displayname&&e.getContent().displayname!==this.displayName&&n.push("User.displayName"),void 0!==e.getContent().currently_active&&e.getContent().currently_active!==this.currentlyActive&&n.push("User.currentlyActive"),this.presence=e.getContent().presence,n.push("User.lastPresenceTs"),e.getContent().status_msg&&(this.presenceStatusMsg=e.getContent().status_msg),e.getContent().displayname&&(this.displayName=e.getContent().displayname),e.getContent().avatar_url&&(this.avatarUrl=e.getContent().avatar_url),this.lastActiveAgo=e.getContent().last_active_ago,this.lastPresenceTs=Date.now(),this.currentlyActive=e.getContent().currently_active,this._updateModifiedTime();for(let t=0;t{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.PushProcessor=s;var o=n(3102),r=n(7434);const i=["override","content","room","sender","underride"],a=[{rule_id:".m.rule.tombstone",default:!0,enabled:!0,conditions:[{kind:"event_match",key:"type",pattern:"m.room.tombstone"},{kind:"event_match",key:"state_key",pattern:""}],actions:["notify",{set_tweak:"highlight",value:!0}]},{rule_id:".m.rule.reaction",default:!0,enabled:!0,conditions:[{kind:"event_match",key:"type",pattern:"m.reaction"}],actions:["dont_notify"]}];function s(e){const t={},n=(e,t)=>{for(let n=0;n]*)([0-9]*)$/);if(!i)return!1;const a=i[1],s=parseInt(i[2]);if(isNaN(s))return!1;switch(a){case"":case"==":return r==s;case"<":return r":return r>s;case"<=":return r<=s;case">=":return r>=s;default:return!1}},l=function(t,n){let r=n.getContent();if(n.isEncrypted()&&n.getClearContent()&&(r=n.getClearContent()),!r||!r.body||"string"!=typeof r.body)return!1;const i=e.getRoom(n.getRoomId());if(!(i&&i.currentState&&i.currentState.members&&i.currentState.getMember(e.credentials.userId)))return!1;const a=i.currentState.getMember(e.credentials.userId).name,s=new RegExp("(^|\\W)"+(0,o.escapeRegExp)(a)+"(\\W|$)","i");return r.body.search(s)>-1},d=function(e,t){if(!e.key)return!1;const n=p(e.key,t);if("string"!=typeof n)return!1;if(e.value)return e.value===n;if("string"!=typeof e.pattern)return!1;let o;return o="content.body"==e.key?h("(^|\\W)",e.pattern,"(\\W|$)"):h("^",e.pattern,"$"),!!n.match(o)},h=function(e,n,r){return t[n]||(t[n]=new RegExp(e+(0,o.globToRegexp)(n)+r,"i")),t[n]},p=function(e,t){const n=e.split(".");let r;const i=n[0];for("content"===i?(r=t.getContent(),n.shift()):"type"===i?(r=t.getType(),n.shift()):r=t.event;n.length>0;){const e=n.shift();if((0,o.isNullOrUndefined)(r[e]))return null;r=r[e]}return r};this.ruleMatchesEvent=function(e,t){let n=!0;for(let o=0;ot.rule_id===e.rule_id));if(t)t.default=e.default,t.conditions=e.conditions,t.actions=e.actions;else{const t=e.rule_id;r.logger.warn(`Adding default global override for ${t}`),n.push(e)}}return t}},98401:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.randomString=function(e){return r(e,o+n+"0123456789")},t.randomLowercaseString=function(e){return r(e,n)},t.randomUppercaseString=function(e){return r(e,o)};const n="abcdefghijklmnopqrstuvwxyz",o="ABCDEFGHIJKLMNOPQRSTUVWXYZ";function r(e,t){let n="";for(let o=0;o{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.setNow=function(e){s=e||Date.now},t.setTimeout=function(e,t){(t=t||0)<0&&(t=0);const n=Array.prototype.slice.call(arguments,2),o=s()+t,r=i++,c={runAt:o,func:e,params:n,key:r},d=l(a,(function(e){return e.runAt-o}));return a.splice(d,0,c),u(),r},t.clearTimeout=function(e){if(0===a.length)return;let t;for(t=0;tt)break;e=a.shift(),e.key,r.push(e)}u();for(let t=0;t>1;t(e[r])>0?o=r:n=r+1}return n}},39443:(e,t,n)=>{"use strict";var o=n(20862);Object.defineProperty(t,"__esModule",{value:!0}),t.MatrixScheduler=i;var r=o(n(3102));function i(e,t){this.retryAlgorithm=e||i.RETRY_BACKOFF_RATELIMIT,this.queueAlgorithm=t||i.QUEUE_MESSAGES,this._queues={},this._activeQueues=[],this._procFn=null}function a(e){e._procFn&&Object.keys(e._queues).filter((function(t){return-1===e._activeQueues.indexOf(t)&&e._queues[t].length>0})).forEach((function(t){e._activeQueues.push(t),c(),s(e,t)}))}function s(e,t){const n=function(e,t){const n=e._queues[t];return Array.isArray(n)?n[0]:null}(e,t);if(!n){const n=e._activeQueues.indexOf(t);return n>=0&&e._activeQueues.splice(n,1),void c()}c(e._queues[t].length),Promise.resolve().then((()=>e._procFn(n.event))).then((function(o){u(e,t),c(n.event.getId()),n.defer.resolve(o),s(e,t)}),(function(o){n.attempts+=1;const r=e.retryAlgorithm(n.event,n.attempts,o);c(n.attempts,n.event.getId()),-1===r?(c(n.event.getId()),u(e,t),n.defer.reject(o),s(e,t)):setTimeout((function(){s(e,t)}),r)}))}function u(e,t){const n=e._queues[t];return Array.isArray(n)?n.shift():null}function c(){}n(7434),i.prototype.getQueueForEvent=function(e){const t=this.queueAlgorithm(e);return t&&this._queues[t]?this._queues[t].map((function(e){return e.event})):null},i.prototype.removeEventFromQueue=function(e){const t=this.queueAlgorithm(e);if(!t||!this._queues[t])return!1;let n=!1;return r.removeElement(this._queues[t],(function(t){if(t.event.getId()===e.getId())return n=!0,!0})),n},i.prototype.setProcessFunction=function(e){this._procFn=e,a(this)},i.prototype.queueEvent=function(e){const t=this.queueAlgorithm(e);if(!t)return null;this._queues[t]||(this._queues[t]=[]);const n=r.defer();return this._queues[t].push({event:e,defer:n,attempts:0}),e.getId(),a(this),n.promise},i.RETRY_BACKOFF_RATELIMIT=function(e,t,n){if(400===n.httpStatus||403===n.httpStatus||401===n.httpStatus)return-1;if("rejected"===n.cors)return-1;if("M_TOO_LARGE"===n.name)return-1;if("M_LIMIT_EXCEEDED"===n.name){const e=n.data.retry_after_ms;if(e>0)return e}return t>4?-1:1e3*Math.pow(2,t)},i.QUEUE_MESSAGES=function(e){return"m.room.message"===e.getType()||e.hasAssocation()?"message":null}},91415:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.SERVICE_TYPES=void 0;const n=Object.freeze({IS:"SERVICE_TYPE_IS",IM:"SERVICE_TYPE_IM"});t.SERVICE_TYPES=n},53861:(e,t,n)=>{"use strict";var o=n(20862);Object.defineProperty(t,"__esModule",{value:!0}),t.LocalIndexedDBStoreBackend=h;var r=n(22741),i=o(n(3102)),a=o(n(33415)),s=n(7434);function u(e,t,n){const o=e.openCursor(t);return new Promise(((e,t)=>{const r=[];o.onerror=e=>{t(new Error("Query failed: "+e.target.errorCode))},o.onsuccess=t=>{const o=t.target.result;o?(r.push(n(o)),o.continue()):e(r)}}))}function c(e){return new Promise(((t,n)=>{e.oncomplete=function(e){t(e)},e.onerror=function(e){n(e.target.error)}}))}function l(e){return new Promise(((t,n)=>{e.onsuccess=function(e){t(e)},e.onerror=function(e){n(e.target.error)}}))}function d(e){return l(e).then((e=>e.target.result))}function h(e,t){this.indexedDB=e,this._dbName="matrix-js-sdk:"+(t||"default"),this.db=null,this._disconnected=!0,this._syncAccumulator=new r.SyncAccumulator,this._isNewlyCreated=!1}h.exists=function(e,t){return t="matrix-js-sdk:"+(t||"default"),a.exists(e,t)},h.prototype={connect:function(){if(!this._disconnected)return s.logger.log("LocalIndexedDBStoreBackend.connect: already connected or connecting"),Promise.resolve();this._disconnected=!1,s.logger.log("LocalIndexedDBStoreBackend.connect: connecting...");const e=this.indexedDB.open(this._dbName,3);return e.onupgradeneeded=e=>{const t=e.target.result,n=e.oldVersion;s.logger.log(`LocalIndexedDBStoreBackend.connect: upgrading from ${n}`),n<1&&(this._isNewlyCreated=!0,function(e){e.createObjectStore("users",{keyPath:["userId"]}),e.createObjectStore("accountData",{keyPath:["type"]}),e.createObjectStore("sync",{keyPath:["clobber"]})}(t)),n<2&&function(e){e.createObjectStore("oob_membership_events",{keyPath:["room_id","state_key"]}).createIndex("room","room_id")}(t),n<3&&function(e){e.createObjectStore("client_options",{keyPath:["clobber"]})}(t)},e.onblocked=()=>{s.logger.log("can't yet open LocalIndexedDBStoreBackend because it is open elsewhere")},s.logger.log("LocalIndexedDBStoreBackend.connect: awaiting connection..."),l(e).then((e=>(s.logger.log("LocalIndexedDBStoreBackend.connect: connected"),this.db=e.target.result,this.db.onversionchange=()=>{this.db.close()},this._init())))},isNewlyCreated:function(){return Promise.resolve(this._isNewlyCreated)},_init:function(){return Promise.all([this._loadAccountData(),this._loadSyncData()]).then((([e,t])=>{s.logger.log("LocalIndexedDBStoreBackend: loaded initial data"),this._syncAccumulator.accumulate({next_batch:t.nextBatch,rooms:t.roomsData,groups:t.groupsData,account_data:{events:e}},!0)}))},getOutOfBandMembers:function(e){return new Promise(((t,n)=>{const o=this.db.transaction(["oob_membership_events"],"readonly").objectStore("oob_membership_events").index("room"),r=IDBKeyRange.only(e),i=o.openCursor(r),a=[];let s=!1;i.onsuccess=e=>{const n=e.target.result;if(!n)return a.length||s?t(a):t(null);const o=n.value;o.oob_written?s=!0:a.push(o),n.continue()},i.onerror=e=>{n(e)}})).then((t=>(s.logger.log(`LL: got ${t&&t.length} membershipEvents from storage for room ${e} ...`),t)))},setOutOfBandMembers:async function(e,t){s.logger.log(`LL: backend about to store ${t.length} members for ${e}`);const n=this.db.transaction(["oob_membership_events"],"readwrite"),o=n.objectStore("oob_membership_events");t.forEach((e=>{o.put(e)}));const r={room_id:e,oob_written:!0,state_key:0};o.put(r),await c(n),s.logger.log(`LL: backend done storing for ${e}!`)},clearOutOfBandMembers:async function(e){const t=this.db.transaction(["oob_membership_events"],"readonly").objectStore("oob_membership_events").index("room"),n=IDBKeyRange.only(e),o=d(t.openKeyCursor(n,"next")).then((e=>e&&e.primaryKey[1])),r=d(t.openKeyCursor(n,"prev")).then((e=>e&&e.primaryKey[1])),[i,a]=await Promise.all([o,r]),u=this.db.transaction(["oob_membership_events"],"readwrite").objectStore("oob_membership_events"),c=IDBKeyRange.bound([e,i],[e,a]);var l;s.logger.log(`LL: Deleting all users + marker in storage for room ${e}, with key range:`,[e,i],[e,a]),await(l=u.delete(c),new Promise(((e,t)=>{l.onsuccess=()=>e(l),l.onerror=e=>t(e)})))},clearDatabase:function(){return new Promise(((e,t)=>{s.logger.log(`Removing indexeddb instance: ${this._dbName}`);const n=this.indexedDB.deleteDatabase(this._dbName);n.onblocked=()=>{s.logger.log(`can't yet delete indexeddb ${this._dbName} because it is open elsewhere`)},n.onerror=t=>{s.logger.warn(`unable to delete js-sdk store indexeddb: ${t.target.error}`),e()},n.onsuccess=()=>{s.logger.log(`Removed indexeddb instance: ${this._dbName}`),e()}}))},getSavedSync:function(e){void 0===e&&(e=!0);const t=this._syncAccumulator.getJSON();return t.nextBatch?e?Promise.resolve(i.deepCopy(t)):Promise.resolve(t):Promise.resolve(null)},getNextBatchToken:function(){return Promise.resolve(this._syncAccumulator.getNextBatchToken())},setSyncData:function(e){return Promise.resolve().then((()=>{this._syncAccumulator.accumulate(e)}))},syncToDatabase:function(e){const t=this._syncAccumulator.getJSON(!0);return Promise.all([this._persistUserPresenceEvents(e),this._persistAccountData(t.accountData),this._persistSyncData(t.nextBatch,t.roomsData,t.groupsData)])},_persistSyncData:function(e,t,n){return s.logger.log("Persisting sync data up to",e),i.promiseTry((()=>{const o=this.db.transaction(["sync"],"readwrite");return o.objectStore("sync").put({clobber:"-",nextBatch:e,roomsData:t,groupsData:n}),c(o)}))},_persistAccountData:function(e){return i.promiseTry((()=>{const t=this.db.transaction(["accountData"],"readwrite"),n=t.objectStore("accountData");for(let t=0;t{const t=this.db.transaction(["users"],"readwrite"),n=t.objectStore("users");for(const t of e)n.put({userId:t[0],event:t[1]});return c(t)}))},getUserPresenceEvents:function(){return i.promiseTry((()=>u(this.db.transaction(["users"],"readonly").objectStore("users"),void 0,(e=>[e.value.userId,e.value.event]))))},_loadAccountData:function(){return s.logger.log("LocalIndexedDBStoreBackend: loading account data..."),i.promiseTry((()=>u(this.db.transaction(["accountData"],"readonly").objectStore("accountData"),void 0,(e=>e.value)).then((e=>(s.logger.log("LocalIndexedDBStoreBackend: loaded account data"),e)))))},_loadSyncData:function(){return s.logger.log("LocalIndexedDBStoreBackend: loading sync data..."),i.promiseTry((()=>u(this.db.transaction(["sync"],"readonly").objectStore("sync"),void 0,(e=>e.value)).then((e=>(s.logger.log("LocalIndexedDBStoreBackend: loaded sync data"),e.length>1&&s.logger.warn("loadSyncData: More than 1 sync row found."),e.length>0?e[0]:{})))))},getClientOptions:function(){return Promise.resolve().then((()=>u(this.db.transaction(["client_options"],"readonly").objectStore("client_options"),void 0,(e=>{if(e.value&&e.value&&e.value.options)return e.value.options})).then((e=>e[0]))))},storeClientOptions:async function(e){const t=this.db.transaction(["client_options"],"readwrite");t.objectStore("client_options").put({clobber:"-",options:e}),await c(t)}}},64215:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.RemoteIndexedDBStoreBackend=i;var o=n(7434),r=n(3102);function i(e,t,n){this._workerScript=e,this._dbName=t,this._workerApi=n,this._worker=null,this._nextSeq=0,this._inFlight={},this._startPromise=null}i.prototype={connect:function(){return this._ensureStarted().then((()=>this._doCmd("connect")))},clearDatabase:function(){return this._ensureStarted().then((()=>this._doCmd("clearDatabase")))},isNewlyCreated:function(){return this._doCmd("isNewlyCreated")},getSavedSync:function(){return this._doCmd("getSavedSync")},getNextBatchToken:function(){return this._doCmd("getNextBatchToken")},setSyncData:function(e){return this._doCmd("setSyncData",[e])},syncToDatabase:function(e){return this._doCmd("syncToDatabase",[e])},getOutOfBandMembers:function(e){return this._doCmd("getOutOfBandMembers",[e])},setOutOfBandMembers:function(e,t){return this._doCmd("setOutOfBandMembers",[e,t])},clearOutOfBandMembers:function(e){return this._doCmd("clearOutOfBandMembers",[e])},getClientOptions:function(){return this._doCmd("getClientOptions")},storeClientOptions:function(e){return this._doCmd("storeClientOptions",[e])},getUserPresenceEvents:function(){return this._doCmd("getUserPresenceEvents")},_ensureStarted:function(){return null===this._startPromise&&(this._worker=new this._workerApi(this._workerScript),this._worker.onmessage=this._onWorkerMessage.bind(this),this._startPromise=this._doCmd("_setupWorker",[this._dbName]).then((()=>{o.logger.log("IndexedDB worker is ready")}))),this._startPromise},_doCmd:function(e,t){return Promise.resolve().then((()=>{const n=this._nextSeq++,o=(0,r.defer)();return this._inFlight[n]=o,this._worker.postMessage({command:e,seq:n,args:t}),o.promise}))},_onWorkerMessage:function(e){const t=e.data;if("cmd_success"==t.command||"cmd_fail"==t.command){if(void 0===t.seq)return void o.logger.error("Got reply from worker with no seq");const e=this._inFlight[t.seq];if(void 0===e)return void o.logger.error("Got reply for unknown seq "+t.seq);if(delete this._inFlight[t.seq],"cmd_success"==t.command)e.resolve(t.result);else{const n=new Error(t.error.message);n.name=t.error.name,e.reject(n)}}else o.logger.warn("Unrecognised message from worker: "+t)}}},99789:(e,t,n)=>{"use strict";var o=n(20862);Object.defineProperty(t,"__esModule",{value:!0}),t.IndexedDBStore=h;var r=n(11703),i=o(n(3102)),a=n(17187),s=n(53861),u=n(64215),c=n(83998),l=n(24369),d=n(7434);function h(e){if(r.MemoryStore.call(this,e),!e.indexedDB)throw new Error("Missing required option: indexedDB");if(e.workerScript){let t=e.workerApi;t||(t=n.g.Worker),this.backend=new u.RemoteIndexedDBStoreBackend(e.workerScript,e.dbName,t)}else this.backend=new s.LocalIndexedDBStoreBackend(e.indexedDB,e.dbName);this.startedUp=!1,this._syncTs=0,this._userModifiedMap={}}function p(e,t){return async function(...n){try{return await e.call(this,...n)}catch(e){d.logger.error("IndexedDBStore failure, degrading to MemoryStore",e),this.emit("degraded",e);try{d.logger.log("IndexedDBStore trying to delete degraded data"),await this.backend.clearDatabase(),d.logger.log("IndexedDBStore delete after degrading succeeeded")}catch(e){d.logger.warn("IndexedDBStore delete after degrading failed",e)}if(Object.setPrototypeOf(this,r.MemoryStore.prototype),t)return await r.MemoryStore.prototype[t].call(this,...n)}}}i.inherits(h,r.MemoryStore),i.extend(h.prototype,a.EventEmitter.prototype),h.exists=function(e,t){return s.LocalIndexedDBStoreBackend.exists(e,t)},h.prototype.startup=function(){return this.startedUp?(d.logger.log("IndexedDBStore.startup: already started"),Promise.resolve()):(d.logger.log("IndexedDBStore.startup: connecting to backend"),this.backend.connect().then((()=>(d.logger.log("IndexedDBStore.startup: loading presence events"),this.backend.getUserPresenceEvents()))).then((e=>{d.logger.log("IndexedDBStore.startup: processing presence events"),e.forEach((([e,t])=>{const n=new c.User(e);t&&n.setPresenceEvent(new l.MatrixEvent(t)),this._userModifiedMap[n.userId]=n.getLastModifiedTime(),this.storeUser(n)}))})))},h.prototype.getSavedSync=p((function(){return this.backend.getSavedSync()}),"getSavedSync"),h.prototype.isNewlyCreated=p((function(){return this.backend.isNewlyCreated()}),"isNewlyCreated"),h.prototype.getSavedSyncToken=p((function(){return this.backend.getNextBatchToken()}),"getSavedSyncToken"),h.prototype.deleteAllData=p((function(){return r.MemoryStore.prototype.deleteAllData.call(this),this.backend.clearDatabase().then((()=>{d.logger.log("Deleted indexeddb data.")}),(e=>{throw d.logger.error(`Failed to delete indexeddb data: ${e}`),e}))})),h.prototype.wantsSave=function(){return Date.now()-this._syncTs>3e5},h.prototype.save=function(e){return e||this.wantsSave()?this._reallySave():Promise.resolve()},h.prototype._reallySave=p((function(){this._syncTs=Date.now();const e=[];for(const t of this.getUsers())this._userModifiedMap[t.userId]!==t.getLastModifiedTime()&&t.events.presence&&(e.push([t.userId,t.events.presence.event]),this._userModifiedMap[t.userId]=t.getLastModifiedTime());return this.backend.syncToDatabase(e)})),h.prototype.setSyncData=p((function(e){return this.backend.setSyncData(e)}),"setSyncData"),h.prototype.getOutOfBandMembers=p((function(e){return this.backend.getOutOfBandMembers(e)}),"getOutOfBandMembers"),h.prototype.setOutOfBandMembers=p((function(e,t){return r.MemoryStore.prototype.setOutOfBandMembers.call(this,e,t),this.backend.setOutOfBandMembers(e,t)}),"setOutOfBandMembers"),h.prototype.clearOutOfBandMembers=p((function(e){return r.MemoryStore.prototype.clearOutOfBandMembers.call(this),this.backend.clearOutOfBandMembers(e)}),"clearOutOfBandMembers"),h.prototype.getClientOptions=p((function(){return this.backend.getClientOptions()}),"getClientOptions"),h.prototype.storeClientOptions=p((function(e){return r.MemoryStore.prototype.storeClientOptions.call(this,e),this.backend.storeClientOptions(e)}),"storeClientOptions")},11703:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.MemoryStore=i;var o=n(83998);function r(e){return"string"==typeof e&&!!e&&"undefined"!==e&&"null"!==e||"number"==typeof e}function i(e){e=e||{},this.rooms={},this.groups={},this.users={},this.syncToken=null,this.filters={},this.accountData={},this.localStorage=e.localStorage,this._oobMembers={},this._clientOptions={}}i.prototype={getSyncToken:function(){return this.syncToken},isNewlyCreated:function(){return Promise.resolve(!0)},setSyncToken:function(e){this.syncToken=e},storeGroup:function(e){this.groups[e.groupId]=e},getGroup:function(e){return this.groups[e]||null},getGroups:function(){return Object.values(this.groups)},storeRoom:function(e){this.rooms[e.roomId]=e,e.currentState.on("RoomState.members",this._onRoomMember.bind(this));const t=this;e.currentState.getMembers().forEach((function(n){t._onRoomMember(null,e.currentState,n)}))},_onRoomMember:function(e,t,n){if("invite"===n.membership)return;const r=this.users[n.userId]||new o.User(n.userId);n.name&&(r.setDisplayName(n.name),n.events.member&&r.setRawDisplayName(n.events.member.getDirectionalContent().displayname)),n.events.member&&n.events.member.getContent().avatar_url&&r.setAvatarUrl(n.events.member.getContent().avatar_url),this.users[r.userId]=r},getRoom:function(e){return this.rooms[e]||null},getRooms:function(){return Object.values(this.rooms)},removeRoom:function(e){this.rooms[e]&&this.rooms[e].removeListener("RoomState.members",this._onRoomMember),delete this.rooms[e]},getRoomSummaries:function(){return Object.values(this.rooms).map((function(e){return e.summary}))},storeUser:function(e){this.users[e.userId]=e},getUser:function(e){return this.users[e]||null},getUsers:function(){return Object.values(this.users)},scrollback:function(e,t){return[]},storeEvents:function(e,t,n,o){},storeFilter:function(e){e&&(this.filters[e.userId]||(this.filters[e.userId]={}),this.filters[e.userId][e.filterId]=e)},getFilter:function(e,t){return this.filters[e]&&this.filters[e][t]?this.filters[e][t]:null},getFilterIdByName:function(e){if(!this.localStorage)return null;const t="mxjssdk_memory_filter_"+e;try{const e=this.localStorage.getItem(t);if(r(e))return e}catch(e){}return null},setFilterIdByName:function(e,t){if(!this.localStorage)return;const n="mxjssdk_memory_filter_"+e;try{r(t)?this.localStorage.setItem(n,t):this.localStorage.removeItem(n)}catch(e){}},storeAccountDataEvents:function(e){const t=this;e.forEach((function(e){t.accountData[e.getType()]=e}))},getAccountData:function(e){return this.accountData[e]},setSyncData:function(e){return Promise.resolve()},wantsSave:function(){return!1},save:function(e){},startup:function(){return Promise.resolve()},getSavedSync:function(){return Promise.resolve(null)},getSavedSyncToken:function(){return Promise.resolve(null)},deleteAllData:function(){return this.rooms={},this.users={},this.syncToken=null,this.filters={},this.accountData={},Promise.resolve()},getOutOfBandMembers:function(e){return Promise.resolve(this._oobMembers[e]||null)},setOutOfBandMembers:function(e,t){return this._oobMembers[e]=t,Promise.resolve()},clearOutOfBandMembers:function(){return this._oobMembers={},Promise.resolve()},getClientOptions:function(){return Promise.resolve(this._clientOptions)},storeClientOptions:function(e){return this._clientOptions=Object.assign({},e),Promise.resolve()}}},55837:(e,t,n)=>{"use strict";var o=n(20862);Object.defineProperty(t,"__esModule",{value:!0}),t.WebStorageSessionStore=a;var r=o(n(3102));n(7434);const i="session.e2e.";function a(e){if(this.store=e,!(r.isFunction(e.getItem)&&r.isFunction(e.setItem)&&r.isFunction(e.removeItem)&&r.isFunction(e.key)&&"number"==typeof e.length))throw new Error("Supplied webStore does not meet the WebStorage API interface")}a.prototype={removeEndToEndAccount:function(){this.store.removeItem(s)},getEndToEndAccount:function(){return this.store.getItem(s)},getAllEndToEndDevices:function(){const e=d(""),t={};for(let n=0;n{"use strict";function n(){this.fromToken=null}Object.defineProperty(t,"__esModule",{value:!0}),t.StubStore=n,n.prototype={isNewlyCreated:function(){return Promise.resolve(!0)},getSyncToken:function(){return this.fromToken},setSyncToken:function(e){this.fromToken=e},storeGroup:function(e){},getGroup:function(e){return null},getGroups:function(){return[]},storeRoom:function(e){},getRoom:function(e){return null},getRooms:function(){return[]},removeRoom:function(e){},getRoomSummaries:function(){return[]},storeUser:function(e){},getUser:function(e){return null},getUsers:function(){return[]},scrollback:function(e,t){return[]},storeEvents:function(e,t,n,o){},storeFilter:function(e){},getFilter:function(e,t){return null},getFilterIdByName:function(e){return null},setFilterIdByName:function(e,t){},storeAccountDataEvents:function(e){},getAccountData:function(e){},setSyncData:function(e){return Promise.resolve()},wantsSave:function(){return!1},save:function(){},startup:function(){return Promise.resolve()},getSavedSync:function(){return Promise.resolve(null)},getSavedSyncToken:function(){return Promise.resolve(null)},deleteAllData:function(){return Promise.resolve()},getOutOfBandMembers:function(){return Promise.resolve(null)},setOutOfBandMembers:function(){return Promise.resolve()},clearOutOfBandMembers:function(){return Promise.resolve()},getClientOptions:function(){return Promise.resolve()},storeClientOptions:function(){return Promise.resolve()}}},22741:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.SyncAccumulator=void 0;var o=n(7434),r=n(3102);function i(e,t){null!==t.state_key&&void 0!==t.state_key&&t.type&&(e[t.type]||(e[t.type]=Object.create(null)),e[t.type][t.state_key]=t)}t.SyncAccumulator=class{constructor(e){(e=e||{}).maxTimelineEntries=e.maxTimelineEntries||50,this.opts=e,this.accountData={},this.inviteRooms={},this.joinRooms={},this.nextBatch=null,this.groups={invite:{},join:{},leave:{}}}accumulate(e,t){this._accumulateRooms(e,t),this._accumulateGroups(e),this._accumulateAccountData(e),this.nextBatch=e.next_batch}_accumulateAccountData(e){e.account_data&&e.account_data.events&&e.account_data.events.forEach((e=>{this.accountData[e.type]=e}))}_accumulateRooms(e,t){e.rooms&&(e.rooms.invite&&Object.keys(e.rooms.invite).forEach((n=>{this._accumulateRoom(n,"invite",e.rooms.invite[n],t)})),e.rooms.join&&Object.keys(e.rooms.join).forEach((n=>{this._accumulateRoom(n,"join",e.rooms.join[n],t)})),e.rooms.leave&&Object.keys(e.rooms.leave).forEach((n=>{this._accumulateRoom(n,"leave",e.rooms.leave[n],t)})))}_accumulateRoom(e,t,n,r){switch(t){case"invite":this._accumulateInviteState(e,n);break;case"join":this.inviteRooms[e]&&delete this.inviteRooms[e],this._accumulateJoinState(e,n,r);break;case"leave":this.inviteRooms[e]?delete this.inviteRooms[e]:delete this.joinRooms[e];break;default:o.logger.error("Unknown cateogory: ",t)}}_accumulateInviteState(e,t){if(!t.invite_state||!t.invite_state.events)return;if(!this.inviteRooms[e])return void(this.inviteRooms[e]={invite_state:t.invite_state});const n=this.inviteRooms[e];t.invite_state.events.forEach((e=>{let t=!1;for(let o=0;o{o._accountData[e.type]=e})),t.unread_notifications&&(o._unreadNotifications=t.unread_notifications),t.summary){const e="m.heroes",n="m.invited_member_count",r="m.joined_member_count",i=o._summary,a=t.summary;i[e]=a[e]||i[e],i[r]=a[r]||i[r],i[n]=a[n]||i[n]}if(t.ephemeral&&t.ephemeral.events&&t.ephemeral.events.forEach((e=>{"m.receipt"===e.type&&e.content&&Object.keys(e.content).forEach((t=>{e.content[t]["m.read"]&&Object.keys(e.content[t]["m.read"]).forEach((n=>{o._readReceipts[n]={data:e.content[t]["m.read"][n],eventId:t}}))}))})),t.timeline&&t.timeline.limited&&(o._timeline=[]),t.state&&t.state.events&&t.state.events.forEach((e=>{i(o._currentState,e)})),t.timeline&&t.timeline.events&&t.timeline.events.forEach(((e,r)=>{let a;if(i(o._currentState,e),n)a=e;else{a=Object.assign({},e),void 0!==a.unsigned&&(a.unsigned=Object.assign({},a.unsigned));const t=e.unsigned?e.unsigned.age:e.age;void 0!==t&&(a._localTs=Date.now()-t)}o._timeline.push({event:a,token:0===r?t.timeline.prev_batch:null})})),o._timeline.length>this.opts.maxTimelineEntries)for(let e=o._timeline.length-this.opts.maxTimelineEntries;e{this._accumulateGroup(t,"invite",e.groups.invite[t])})),e.groups.join&&Object.keys(e.groups.join).forEach((t=>{this._accumulateGroup(t,"join",e.groups.join[t])})),e.groups.leave&&Object.keys(e.groups.leave).forEach((t=>{this._accumulateGroup(t,"leave",e.groups.leave[t])})))}_accumulateGroup(e,t,n){for(const t of["invite","join","leave"])delete this.groups[t][e];this.groups[t][e]=n}getJSON(e){const t={join:{},invite:{},leave:{}};Object.keys(this.inviteRooms).forEach((e=>{t.invite[e]=this.inviteRooms[e]})),Object.keys(this.joinRooms).forEach((n=>{const o=this.joinRooms[n],a={ephemeral:{events:[]},account_data:{events:[]},state:{events:[]},timeline:{events:[],prev_batch:null},unread_notifications:o._unreadNotifications,summary:o._summary};Object.keys(o._accountData).forEach((e=>{a.account_data.events.push(o._accountData[e])}));const s={type:"m.receipt",room_id:n,content:{}};Object.keys(o._readReceipts).forEach((e=>{const t=o._readReceipts[e];s.content[t.eventId]||(s.content[t.eventId]={"m.read":{}}),s.content[t.eventId]["m.read"][e]=t.data})),Object.keys(s.content).length>0&&a.ephemeral.events.push(s),o._timeline.forEach((t=>{if(!a.timeline.prev_batch){if(!t.token)return;a.timeline.prev_batch=t.token}let n;!e&&t.event._localTs?(n=Object.assign({},t.event),void 0!==n.unsigned&&(n.unsigned=Object.assign({},n.unsigned)),delete n._localTs,n.unsigned=n.unsigned||{},n.unsigned.age=Date.now()-t.event._localTs):n=t.event,a.timeline.events.push(n)}));const u=Object.create(null);for(let e=a.timeline.events.length-1;e>=0;e--){const t=a.timeline.events[e];if(null===t.state_key||void 0===t.state_key)continue;const n=(0,r.deepCopy)(t);n.unsigned&&(n.unsigned.prev_content&&(n.content=n.unsigned.prev_content),n.unsigned.prev_sender&&(n.sender=n.unsigned.prev_sender)),i(u,n)}Object.keys(o._currentState).forEach((e=>{Object.keys(o._currentState[e]).forEach((t=>{let n=o._currentState[e][t];u[e]&&u[e][t]&&(n=u[e][t]),a.state.events.push(n)}))})),t.join[n]=a}));const n=[];return Object.keys(this.accountData).forEach((e=>{n.push(this.accountData[e])})),{nextBatch:this.nextBatch,roomsData:t,groupsData:this.groups,accountData:n}}getNextBatchToken(){return this.nextBatch}}},64551:(e,t,n)=>{"use strict";var o=n(20862);Object.defineProperty(t,"__esModule",{value:!0}),t.SyncApi=g;var r=n(83998),i=n(27366),a=n(70142),s=o(n(3102)),u=n(27906),c=n(88910),l=n(31707),d=n(7434),h=n(19489);function p(e,t){return"FILTER_SYNC_"+e+(t?"_"+t:"")}function f(...e){d.logger.log(...e)}function g(e,t){this.client=e,(t=t||{}).initialSyncLimit=void 0===t.initialSyncLimit?8:t.initialSyncLimit,t.resolveInvitesToProfiles=t.resolveInvitesToProfiles||!1,t.pollTimeout=t.pollTimeout||3e4,t.pendingEventOrdering=t.pendingEventOrdering||"chronological",t.canResetEntireTimeline||(t.canResetEntireTimeline=function(e){return!1}),this.opts=t,this._peekRoom=null,this._currentSyncRequest=null,this._syncState=null,this._syncStateData=null,this._catchingUp=!1,this._running=!1,this._keepAliveTimer=null,this._connectionReturnedDefer=null,this._notifEvents=[],this._failedSyncCount=0,this._storeIsInvalid=!1,e.getNotifTimelineSet()&&e.reEmitter.reEmit(e.getNotifTimelineSet(),["Room.timeline","Room.timelineReset"])}function m(e,t){const n=new r.User(t);return e.reEmitter.reEmit(n,["User.avatarUrl","User.displayName","User.presence","User.currentlyActive","User.lastPresenceTs"]),n}g.prototype.createRoom=function(e){const t=this.client,{timelineSupport:n,unstableClientRelationAggregation:o}=t,r=new i.Room(e,t,t.getUserId(),{lazyLoadMembers:this.opts.lazyLoadMembers,pendingEventOrdering:this.opts.pendingEventOrdering,timelineSupport:n,unstableClientRelationAggregation:o});return t.reEmitter.reEmit(r,["Room.name","Room.timeline","Room.redaction","Room.redactionCancelled","Room.receipt","Room.tags","Room.timelineReset","Room.localEchoUpdated","Room.accountData","Room.myMembership","Room.replaceEvent"]),this._registerStateListeners(r),r},g.prototype.createGroup=function(e){const t=this.client,n=new a.Group(e);return t.reEmitter.reEmit(n,["Group.profile","Group.myMembership"]),t.store.storeGroup(n),n},g.prototype._registerStateListeners=function(e){const t=this.client;t.reEmitter.reEmit(e.currentState,["RoomState.events","RoomState.members","RoomState.newMember"]),e.currentState.on("RoomState.newMember",(function(e,n,o){o.user=t.getUser(o.userId),t.reEmitter.reEmit(o,["RoomMember.name","RoomMember.typing","RoomMember.powerLevel","RoomMember.membership"])}))},g.prototype._deregisterStateListeners=function(e){e.currentState.removeAllListeners("RoomState.events"),e.currentState.removeAllListeners("RoomState.members"),e.currentState.removeAllListeners("RoomState.newMember")},g.prototype.syncLeftRooms=function(){const e=this.client,t=this,n=new u.Filter(this.client.credentials.userId);n.setTimelineLimit(1),n.setIncludeLeaveRooms(!0);const o=this.opts.pollTimeout+8e4,r={timeout:0};return e.getOrCreateFilter(p(e.credentials.userId,"LEFT_ROOMS"),n).then((function(t){return r.filter=t,e._http.authedRequest(void 0,"GET","/sync",r,void 0,o)})).then((function(n){let o=[];n.rooms&&n.rooms.leave&&(o=t._mapSyncResponseToRoomArray(n.rooms.leave));const r=[];return o.forEach((function(n){const o=n.room;if(r.push(o),!n.isBrandNewRoom)return;n.timeline=n.timeline||{};const i=t._mapSyncEventsFormat(n.timeline,o),a=t._mapSyncEventsFormat(n.state,o);o.getLiveTimeline().setPaginationToken(n.timeline.prev_batch,c.EventTimeline.BACKWARDS),t._processRoomEvents(o,a,i),o.recalculate(),e.store.storeRoom(o),e.emit("Room",o),t._processEventsForNotifs(o,i)})),r}))},g.prototype.peek=function(e){if(this._peekRoom&&this._peekRoom.roomId===e)return Promise.resolve(this._peekRoom);const t=this.client;return this._peekRoom=this.createRoom(e),this.client.roomInitialSync(e,20).then((e=>{e.messages=e.messages||{},e.messages.chunk=e.messages.chunk||[],e.state=e.state||[];const n=s.deepCopy(e.state).map(t.getEventMapper()),o=e.state.map(t.getEventMapper()),r=e.messages.chunk.map(t.getEventMapper());return e.presence&&Array.isArray(e.presence)&&e.presence.map(t.getEventMapper()).forEach((function(e){let n=t.store.getUser(e.getContent().user_id);n?n.setPresenceEvent(e):(n=m(t,e.getContent().user_id),n.setPresenceEvent(e),t.store.storeUser(n)),t.emit("event",e)})),e.messages.start&&(this._peekRoom.oldState.paginationToken=e.messages.start),this._peekRoom.oldState.setStateEvents(n),this._peekRoom.currentState.setStateEvents(o),this._resolveInvites(this._peekRoom),this._peekRoom.recalculate(),this._peekRoom.addEventsToTimeline(r.reverse(),!0,this._peekRoom.getLiveTimeline(),e.messages.start),t.store.storeRoom(this._peekRoom),t.emit("Room",this._peekRoom),this._peekPoll(this._peekRoom),this._peekRoom}))},g.prototype.stopPeeking=function(){this._peekRoom=null},g.prototype._peekPoll=function(e,t){if(this._peekRoom!==e)return void f("Stopped peeking in room %s",e.roomId);const n=this;this.client._http.authedRequest(void 0,"GET","/events",{room_id:e.roomId,timeout:3e4,from:t},void 0,5e4).then((function(t){if(n._peekRoom!==e)return void f("Stopped peeking in room %s",e.roomId);t.chunk.filter((function(e){return"m.presence"===e.type})).map(n.client.getEventMapper()).forEach((function(e){let t=n.client.store.getUser(e.getContent().user_id);t?t.setPresenceEvent(e):(t=m(n.client,e.getContent().user_id),t.setPresenceEvent(e),n.client.store.storeUser(t)),n.client.emit("event",e)}));const o=t.chunk.filter((function(t){return t.room_id===e.roomId&&t.event_id})).map(n.client.getEventMapper());e.addLiveEvents(o),n._peekPoll(e,t.end)}),(function(o){d.logger.error("[%s] Peek poll failed: %s",e.roomId,o),setTimeout((function(){n._peekPoll(e,t)}),3e4)}))},g.prototype.getSyncState=function(){return this._syncState},g.prototype.getSyncStateData=function(){return this._syncStateData},g.prototype.recoverFromSyncStartupError=async function(e,t){await e;const n=this._startKeepAlives();this._updateSyncState("ERROR",{error:t}),await n},g.prototype._wasLazyLoadingToggled=async function(e){e=!!e;let t=!1;if(!await this.client.store.isNewlyCreated()){const n=await this.client.store.getClientOptions();return n&&(t=!!n.lazyLoadMembers),t!==e}return!1},g.prototype._shouldAbortSync=function(e){return"M_UNKNOWN_TOKEN"===e.errcode&&(d.logger.warn("Token no longer valid - assuming logout"),this.stop(),!0)},g.prototype.sync=function(){const e=this.client,t=this;this._running=!0,n.g.window&&n.g.window.addEventListener&&(this._onOnlineBound=this._onOnline.bind(this),n.g.window.addEventListener("online",this._onOnlineBound,!1));let o=Promise.resolve(),r=null;function i(){const n=new u.Filter(e.credentials.userId);return n.setTimelineLimit(t.opts.initialSyncLimit),n}const a=async()=>{if(f("Checking lazy load status..."),this.opts.lazyLoadMembers&&e.isGuest()&&(this.opts.lazyLoadMembers=!1),this.opts.lazyLoadMembers&&(f("Checking server lazy load support..."),await e.doesServerSupportLazyLoading()?(f("Enabling lazy load on sync filter..."),this.opts.filter||(this.opts.filter=i()),this.opts.filter.setLazyLoadMembers(!0)):(f("LL: lazy loading requested but not supported by server, so disabling"),this.opts.lazyLoadMembers=!1)),f("Checking whether lazy loading has changed in store..."),await this._wasLazyLoadingToggled(this.opts.lazyLoadMembers)){this._storeIsInvalid=!0;const e=h.InvalidStoreError.TOGGLED_LAZY_LOADING,t=new h.InvalidStoreError(e,!!this.opts.lazyLoadMembers);return this._updateSyncState("ERROR",{error:t}),void d.logger.warn("InvalidStoreError: store is not usable: stopping sync.")}this.opts.lazyLoadMembers&&this.opts.crypto&&this.opts.crypto.enableLazyLoading();try{f("Storing client options..."),await this.client._storeClientOptions(),f("Stored client options")}catch(e){throw d.logger.error("Storing client options failed",e),e}s()};async function s(){let n,a;f("Getting filter..."),n=t.opts.filter?t.opts.filter:i();try{a=await e.getOrCreateFilter(p(e.credentials.userId),n)}catch(e){if(d.logger.error("Getting filter failed",e),t._shouldAbortSync(e))return;return f("Waiting for saved sync before retrying filter..."),await t.recoverFromSyncStartupError(o,e),void s()}e.resetNotifTimelineSet(),null===t._currentSyncRequest&&(f("Sending first sync request..."),t._currentSyncRequest=t._doSyncRequest({filterId:a},r)),f("Waiting for saved sync before starting sync processing..."),await o,t._sync({filterId:a})}e.isGuest()?t._sync({}):(f("Getting saved sync token..."),o=e.store.getSavedSyncToken().then((t=>(f("Got saved sync token"),r=t,f("Getting saved sync..."),e.store.getSavedSync()))).then((e=>{if(f(`Got reply from saved sync, exists? ${!!e}`),e)return t._syncFromCache(e)})).catch((e=>{d.logger.error("Getting saved sync failed",e)})),async function n(){try{f("Getting push rules...");const t=await e.getPushRules();f("Got push rules"),e.pushRules=t}catch(e){if(d.logger.error("Getting push rules failed",e),t._shouldAbortSync(e))return;return f("Waiting for saved sync before retrying push rules..."),await t.recoverFromSyncStartupError(o,e),void n()}a()}())},g.prototype.stop=function(){f("SyncApi.stop"),n.g.window&&(n.g.window.removeEventListener("online",this._onOnlineBound,!1),this._onOnlineBound=void 0),this._running=!1,this._currentSyncRequest&&this._currentSyncRequest.abort(),this._keepAliveTimer&&(clearTimeout(this._keepAliveTimer),this._keepAliveTimer=null)},g.prototype.retryImmediately=function(){return!!this._connectionReturnedDefer&&(this._startKeepAlives(0),!0)},g.prototype._syncFromCache=async function(e){f("sync(): not doing HTTP hit, instead returning stored /sync data");const t=e.nextBatch;this.client.store.setSyncToken(t);const n={oldSyncToken:null,nextSyncToken:t,catchingUp:!1,fromCache:!0},o={next_batch:t,rooms:e.roomsData,groups:e.groupsData,account_data:{events:e.accountData}};try{await this._processSyncResponse(n,o)}catch(e){d.logger.error("Error processing cached sync",e.stack||e)}this._storeIsInvalid||this._updateSyncState("PREPARED",n)},g.prototype._sync=async function(e){const t=this.client;if(!this._running)return f("Sync no longer running: exiting."),this._connectionReturnedDefer&&(this._connectionReturnedDefer.reject(),this._connectionReturnedDefer=null),void this._updateSyncState("STOPPED");const n=t.store.getSyncToken();let o;try{null===this._currentSyncRequest&&(this._currentSyncRequest=this._doSyncRequest(e,n)),o=await this._currentSyncRequest}catch(t){return void this._onSyncError(t,e)}finally{this._currentSyncRequest=null}t.store.setSyncToken(o.next_batch),this._failedSyncCount=0,await t.store.setSyncData(o);const r={oldSyncToken:n,nextSyncToken:o.next_batch,catchingUp:this._catchingUp};this.opts.crypto&&await this.opts.crypto.onSyncWillProcess(r);try{await this._processSyncResponse(r,o)}catch(e){d.logger.error("Caught /sync error",e.stack||e),this.client.emit("sync.unexpectedError",e)}r.catchingUp=this._catchingUp,e.hasSyncedBefore||(this._updateSyncState("PREPARED",r),e.hasSyncedBefore=!0),this.opts.crypto&&await this.opts.crypto.onSyncCompleted(r),this._updateSyncState("SYNCING",r),t.store.wantsSave()&&(this.opts.crypto&&await this.opts.crypto.saveDeviceList(0),t.store.save()),this._sync(e)},g.prototype._doSyncRequest=function(e,t){const n=this._getSyncParams(e,t);return this.client._http.authedRequest(void 0,"GET","/sync",n,void 0,n.timeout+8e4)},g.prototype._getSyncParams=function(e,t){let n=this.opts.pollTimeout;("SYNCING"!==this.getSyncState()||this._catchingUp)&&(this._catchingUp=!0,n=0);let o=e.filterId;this.client.isGuest()&&!o&&(o=this._getGuestFilter());const r={filter:o,timeout:n};return this.opts.disablePresence&&(r.set_presence="offline"),t?r.since=t:r._cacheBuster=Date.now(),"ERROR"!=this.getSyncState()&&"RECONNECTING"!=this.getSyncState()||(r.timeout=0),r},g.prototype._onSyncError=function(e,t){if(!this._running)return f("Sync no longer running: exiting"),this._connectionReturnedDefer&&(this._connectionReturnedDefer.reject(),this._connectionReturnedDefer=null),void this._updateSyncState("STOPPED");d.logger.error("/sync error %s",e),d.logger.error(e),this._shouldAbortSync(e)||(this._failedSyncCount++,d.logger.log("Number of consecutive failed sync requests:",this._failedSyncCount),f("Starting keep-alive"),this._startKeepAlives().then((e=>{e&&"ERROR"===this.getSyncState()&&this._updateSyncState("CATCHUP",{oldSyncToken:null,nextSyncToken:null,catchingUp:!0}),this._sync(t)})),this._currentSyncRequest=null,this._updateSyncState(this._failedSyncCount>=3?"ERROR":"RECONNECTING",{error:e}))},g.prototype._processSyncResponse=async function(e,t){const n=this.client,o=this;if(t.presence&&Array.isArray(t.presence.events)&&t.presence.events.map(n.getEventMapper()).forEach((function(e){let t=n.store.getUser(e.getSender());t?t.setPresenceEvent(e):(t=m(n,e.getSender()),t.setPresenceEvent(e),n.store.storeUser(t)),n.emit("event",e)})),t.account_data&&Array.isArray(t.account_data.events)){const e=t.account_data.events.map(n.getEventMapper()),o=e.reduce(((e,t)=>(e[t.getId()]=n.store.getAccountData(t.getType()),e)),{});n.store.storeAccountDataEvents(e),e.forEach((function(e){if("m.push_rules"===e.getType()){const t=e.getContent();n.pushRules=l.PushProcessor.rewriteDefaultRules(t)}const t=o[e.getId()];return n.emit("accountData",e,t),e}))}if(t.to_device&&Array.isArray(t.to_device.events)&&t.to_device.events.length>0){const e=[];t.to_device.events.map(n.getEventMapper()).map((t=>{if("m.key.verification.cancel"===t.getType()){const n=t.getContent().transaction_id;n&&e.push(n)}return t})).forEach((function(t){const o=t.getContent();if("m.room.message"!=t.getType()||"m.bad.encrypted"!=o.msgtype){if("m.key.verification.start"===t.getType()||"m.key.verification.request"===t.getType()){const n=o.transaction_id;e.includes(n)&&t.flagCancelled()}n.emit("toDeviceEvent",t)}else d.logger.log("Ignoring undecryptable to-device event from "+t.getSender())}))}else this._catchingUp=!1;t.groups&&(t.groups.invite&&this._processGroupSyncEntry(t.groups.invite,"invite"),t.groups.join&&this._processGroupSyncEntry(t.groups.join,"join"),t.groups.leave&&this._processGroupSyncEntry(t.groups.leave,"leave"));let r=[],i=[],a=[];if(t.rooms&&(t.rooms.invite&&(r=this._mapSyncResponseToRoomArray(t.rooms.invite)),t.rooms.join&&(i=this._mapSyncResponseToRoomArray(t.rooms.join)),t.rooms.leave&&(a=this._mapSyncResponseToRoomArray(t.rooms.leave))),this._notifEvents=[],r.forEach((function(e){const t=e.room,r=o._mapSyncEventsFormat(e.invite_state,t);o._processRoomEvents(t,r),e.isBrandNewRoom&&(t.recalculate(),n.store.storeRoom(t),n.emit("Room",t)),r.forEach((function(e){n.emit("event",e)})),t.updateMyMembership("invite")})),await s.promiseMapSeries(i,(async function(t){const r=t.room,i=o._mapSyncEventsFormat(t.state,r),a=o._mapSyncEventsFormat(t.timeline,r,!1),u=o._mapSyncEventsFormat(t.ephemeral),l=o._mapSyncEventsFormat(t.account_data),d=n.isRoomEncrypted(r.roomId);if(t.unread_notifications&&(r.setUnreadNotificationCount("total",t.unread_notifications.notification_count),(!d||d&&r.getUnreadNotificationCount("highlight")<=0)&&r.setUnreadNotificationCount("highlight",t.unread_notifications.highlight_count)),t.timeline=t.timeline||{},t.isBrandNewRoom)r.getLiveTimeline().setPaginationToken(t.timeline.prev_batch,c.EventTimeline.BACKWARDS);else if(t.timeline.limited){let i=!0;for(let e=a.length-1;e>=0;e--){const t=a[e].getId();if(r.getTimelineForEvent(t)){f("Already have event "+t+" in limited sync - not resetting"),i=!1,a.splice(0,e);break}}i&&(o._deregisterStateListeners(r),r.resetLiveTimeline(t.timeline.prev_batch,o.opts.canResetEntireTimeline(r.roomId)?null:e.oldSyncToken),n.resetNotifTimelineSet(),o._registerStateListeners(r))}async function h(e){if(n.emit("event",e),e.isState()&&"m.room.encryption"==e.getType()&&o.opts.crypto&&await o.opts.crypto.onCryptoEvent(e),e.isState()&&"im.vector.user_status"===e.getType()){let t=n.store.getUser(e.getStateKey());t?t._unstable_updateStatusMessage(e):(t=m(n,e.getStateKey()),t._unstable_updateStatusMessage(e),n.store.storeUser(t))}}o._processRoomEvents(r,i,a,e.fromCache),t.summary&&r.setSummary(t.summary),r.addEphemeralEvents(u),r.addAccountData(l),r.recalculate(),t.isBrandNewRoom&&(n.store.storeRoom(r),n.emit("Room",r)),o._processEventsForNotifs(r,a),await s.promiseMapSeries(i,h),await s.promiseMapSeries(a,h),u.forEach((function(e){n.emit("event",e)})),l.forEach((function(e){n.emit("event",e)})),r.updateMyMembership("join"),r.decryptCriticalEvents()})),a.forEach((function(e){const t=e.room,r=o._mapSyncEventsFormat(e.state,t),i=o._mapSyncEventsFormat(e.timeline,t),a=o._mapSyncEventsFormat(e.account_data);o._processRoomEvents(t,r,i),t.addAccountData(a),t.recalculate(),e.isBrandNewRoom&&(n.store.storeRoom(t),n.emit("Room",t)),o._processEventsForNotifs(t,i),r.forEach((function(e){n.emit("event",e)})),i.forEach((function(e){n.emit("event",e)})),a.forEach((function(e){n.emit("event",e)})),t.updateMyMembership("leave")})),e.oldSyncToken&&this._notifEvents.length&&(this._notifEvents.sort((function(e,t){return e.getTs()-t.getTs()})),this._notifEvents.forEach((function(e){n.getNotifTimelineSet().addLiveEvent(e)}))),t.device_lists&&this.opts.crypto&&await this.opts.crypto.handleDeviceListChanges(e,t.device_lists),this.opts.crypto&&t.device_one_time_keys_count){const e=t.device_one_time_keys_count.signed_curve25519||0;this.opts.crypto.updateOneTimeKeyCount(e)}if(this.opts.crypto&&t["org.matrix.msc2732.device_unused_fallback_key_types"]){const e=t["org.matrix.msc2732.device_unused_fallback_key_types"];this.opts.crypto.setNeedsNewFallback(e instanceof Array&&!e.includes("signed_curve25519"))}},g.prototype._startKeepAlives=function(e){void 0===e&&(e=2e3+Math.floor(5e3*Math.random())),null!==this._keepAliveTimer&&clearTimeout(this._keepAliveTimer);const t=this;return e>0?t._keepAliveTimer=setTimeout(t._pokeKeepAlive.bind(t),e):t._pokeKeepAlive(),this._connectionReturnedDefer||(this._connectionReturnedDefer=s.defer()),this._connectionReturnedDefer.promise},g.prototype._pokeKeepAlive=function(e){void 0===e&&(e=!1);const t=this;function n(){clearTimeout(t._keepAliveTimer),t._connectionReturnedDefer&&(t._connectionReturnedDefer.resolve(e),t._connectionReturnedDefer=null)}this.client._http.request(void 0,"GET","/_matrix/client/versions",void 0,void 0,{prefix:"",localTimeoutMs:15e3}).then((function(){n()}),(function(o){400==o.httpStatus||404==o.httpStatus?t._keepAliveTimer=setTimeout(n,2e3):(e=!0,t._keepAliveTimer=setTimeout(t._pokeKeepAlive.bind(t,e),5e3+Math.floor(5e3*Math.random())),t._updateSyncState("ERROR",{error:o}))}))},g.prototype._processGroupSyncEntry=function(e,t){for(const n of Object.keys(e)){const o=e[n];let r=this.client.store.getGroup(n);const i=null===r;null===r&&(r=this.createGroup(n)),o.profile&&r.setProfile(o.profile.name,o.profile.avatar_url),o.inviter&&r.setInviter({userId:o.inviter}),r.setMyMembership(t),i&&this.client.emit("Group",r)}},g.prototype._mapSyncResponseToRoomArray=function(e){const t=this.client,n=this;return Object.keys(e).map((function(o){const r=e[o];let i=t.store.getRoom(o),a=!1;return i||(i=n.createRoom(o),a=!0),r.room=i,r.isBrandNewRoom=a,r}))},g.prototype._mapSyncEventsFormat=function(e,t,n=!0){if(!e||!Array.isArray(e.events))return[];const o=this.client.getEventMapper({decrypt:n});return e.events.map((function(e){return t&&(e.room_id=t.roomId),o(e)}))},g.prototype._resolveInvites=function(e){if(!e||!this.opts.resolveInvitesToProfiles)return;const t=this.client;e.getMembersWithMembership("invite").forEach((function(n){if(n._requestedProfileInfo)return;n._requestedProfileInfo=!0;const o=t.getUser(n.userId);let r;r=o?Promise.resolve({avatar_url:o.avatarUrl,displayname:o.displayName}):t.getProfileInfo(n.userId),r.then((function(t){const o=n.events.member;"invite"===o.getContent().membership&&(o.getContent().avatar_url=t.avatar_url,o.getContent().displayname=t.displayname,n.setMembershipEvent(o,e.currentState))}),(function(e){}))}))},g.prototype._processRoomEvents=function(e,t,n,o){const r=e.getLiveTimeline(),i=0==r.getEvents().length;if(i){for(const e of t)this.client.getPushActionsForEvent(e);r.initialiseState(t)}this._resolveInvites(e),e.recalculate(),i||(e.oldState.setStateEvents(t||[]),e.currentState.setStateEvents(t||[])),e.addLiveEvents(n||[],null,o)},g.prototype._processEventsForNotifs=function(e,t){if(this.client.getNotifTimelineSet())for(let e=0;e{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.TimelineWindow=r,t.TimelineIndex=i;var o=n(88910);n(7434);function r(e,t,n){n=n||{},this._client=e,this._timelineSet=t,this._start=null,this._end=null,this._eventCount=0,this._windowLimit=n.windowLimit||1e3}function i(e,t){this.timeline=e,this.index=t}r.prototype.load=function(e,t){const n=this;t=t||20;const o=function(o){let r;const a=o.getEvents();if(e){for(let t=0;t0&&this.unpaginate(t,e!=o.EventTimeline.BACKWARDS),!0}return!1},r.prototype.canPaginate=function(e){const t=this.getTimelineIndex(e);if(!t)return!1;if(e==o.EventTimeline.BACKWARDS){if(t.index>t.minIndex())return!0}else if(t.indexthis._eventCount||e<0)throw new Error("Attemting to unpaginate "+e+" events, but only have "+this._eventCount+" in the timeline");for(;e>0;){const o=t?n.advance(e):n.retreat(e);if(o<=0)throw new Error("Unable to unpaginate any further, but still have "+this._eventCount+" events");e-=o,this._eventCount-=o,this._eventCount}},r.prototype.getEvents=function(){if(!this._start)return[];const e=[];let t=this._start.timeline;for(;;){const n=t.getEvents();let r=0,i=n.length;t===this._start.timeline&&(r=this._start.index+t.getBaseIndex()),t===this._end.timeline&&(i=this._end.index+t.getBaseIndex());for(let t=r;t0)return this.index+=t,t;const n=this.timeline.getNeighbouringTimeline(e<0?o.EventTimeline.BACKWARDS:o.EventTimeline.FORWARDS);return n?(this.timeline=n,this.index=e<0?this.maxIndex():this.minIndex(),this.advance(e)):0},i.prototype.retreat=function(e){return-1*this.advance(-1*e)}},3102:(e,t,n)=>{"use strict";var o=n(95318);Object.defineProperty(t,"__esModule",{value:!0}),t.encodeParams=function(e){let t="";for(const n in e)e.hasOwnProperty(n)&&(t+="&"+encodeURIComponent(n)+"="+encodeURIComponent(e[n]));return t.substring(1)},t.encodeUri=function(e,t){for(const n in t)t.hasOwnProperty(n)&&(e=e.replace(n,encodeURIComponent(t[n])));return e},t.removeElement=function(e,t,n){let o,r;if(n){for(o=e.length-1;o>=0;o--)if(t(e[o],o,e))return r=e[o],e.splice(o,1),r}else for(o=0;o?@[\]^_`{|}~\u2000-\u206f\u2e00-\u2e7f]/g,"").toLowerCase()},t.escapeRegExp=s,t.globToRegexp=function(e,t){t="boolean"!=typeof t||t;let n=s(e);return n=n.replace(/\\\*/g,".*"),n=n.replace(/\?/g,"."),t&&(n=n.replace(/\\\[(!|)(.*)\\]/g,(function(e,t,n,o,r){return"["+(t?"^":"")+n.replace(/\\-/,"-")+"]"}))),n},t.ensureNoTrailingSlash=function(e){return e&&e.endsWith("/")?e.substr(0,e.length-1):e},t.sleep=function(e,t){return new Promise((n=>{setTimeout(n,e,t)}))},t.isNullOrUndefined=function(e){return null==e},t.defer=function(){let e,t;const n=new Promise(((n,o)=>{e=n,t=o}));return{resolve:e,reject:t,promise:n}},t.promiseMapSeries=async function(e,t){for(const n of await e)await t(await n)},t.promiseTry=function(e){return new Promise((t=>t(e())))},t.chunkPromises=async function(e,t){const n=[];for(let o=0;oe()))));return n},t.setCrypto=function(e){u=e},t.getCrypto=function(){return u};var r=o(n(85067));function i(e){return"string"==typeof e?(0,r.default)(e.normalize("NFD").replace(a,"")):""}const a=/[\u2000-\u200F\u202A-\u202F\u0300-\u036f\uFEFF\s]/g;function s(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}let u},59679:(e,t,n)=>{"use strict";var o=n(20862),r=n(95318);Object.defineProperty(t,"__esModule",{value:!0}),t.getDesktopCapturerSources=function(){return window.electron.getDesktopCapturerSources({thumbnailSize:{height:176,width:312},types:["screen","window"]})},t.setAudioInput=function(e){D=e},t.setVideoInput=function(e){S=e},t.createNewMatrixCall=function(e,t,n){if("undefined"==typeof window||"undefined"==typeof document)return null;try{if(!Boolean(window.RTCPeerConnection||window.RTCSessionDescription||window.RTCIceCandidate||navigator.mediaDevices))return a.logger.error("WebRTC is not supported in this browser / environment"),null}catch(e){return a.logger.error("Exception thrown when trying to access WebRTC",e),null}const o=!!n&&n.forceTURN,r={client:e,roomId:t,turnServers:e.getTurnServers(),forceTURN:e._forceTURN||o},i=new w(r);return e.reEmitter.reEmit(i,Object.values(_)),i},t.MatrixCall=t.CallError=t.CallErrorCode=t.CallEvent=t.CallParty=t.CallDirection=t.CallType=t.CallState=void 0;var i=r(n(59713)),a=n(7434),s=n(17187),u=o(n(3102)),c=n(42481),l=n(98401),d=n(15964),h=n(49704);let p,f,g,m,_,F;var y;t.CallState=p,function(e){e.Fledgling="fledgling",e.InviteSent="invite_sent",e.WaitLocalMedia="wait_local_media",e.CreateOffer="create_offer",e.CreateAnswer="create_answer",e.Connecting="connecting",e.Connected="connected",e.Ringing="ringing",e.Ended="ended"}(p||(t.CallState=p={})),t.CallType=f,function(e){e.Voice="voice",e.Video="video"}(f||(t.CallType=f={})),t.CallDirection=g,function(e){e.Inbound="inbound",e.Outbound="outbound"}(g||(t.CallDirection=g={})),t.CallParty=m,function(e){e.Local="local",e.Remote="remote"}(m||(t.CallParty=m={})),t.CallEvent=_,function(e){e.Hangup="hangup",e.State="state",e.Error="error",e.Replaced="replaced",e.LocalHoldUnhold="local_hold_unhold",e.RemoteHoldUnhold="remote_hold_unhold",e.HoldUnhold="hold_unhold",e.FeedsChanged="feeds_changed",e.AssertedIdentityChanged="asserted_identity_changed"}(_||(t.CallEvent=_={})),t.CallErrorCode=F,function(e){e.UserHangup="user_hangup",e.LocalOfferFailed="local_offer_failed",e.NoUserMedia="no_user_media",e.UnknownDevices="unknown_devices",e.SendInvite="send_invite",e.CreateAnswer="create_answer",e.SendAnswer="send_answer",e.SetRemoteDescription="set_remote_description",e.SetLocalDescription="set_local_description",e.AnsweredElsewhere="answered_elsewhere",e.IceFailed="ice_failed",e.InviteTimeout="invite_timeout",e.Replaced="replaced",e.SignallingFailed="signalling_timeout",e.UserBusy="user_busy"}(F||(t.CallErrorCode=F={})),function(e){e.Audio="audio",e.Video="video"}(y||(y={}));class b extends Error{constructor(e,t,n){super(t+": "+n),(0,i.default)(this,"code",void 0),this.code=e}}function v(){return Date.now().toString()+(0,l.randomString)(16)}t.CallError=b;class w extends s.EventEmitter{constructor(e){super(),(0,i.default)(this,"roomId",void 0),(0,i.default)(this,"type",void 0),(0,i.default)(this,"callId",void 0),(0,i.default)(this,"state",void 0),(0,i.default)(this,"hangupParty",void 0),(0,i.default)(this,"hangupReason",void 0),(0,i.default)(this,"direction",void 0),(0,i.default)(this,"ourPartyId",void 0),(0,i.default)(this,"client",void 0),(0,i.default)(this,"forceTURN",void 0),(0,i.default)(this,"turnServers",void 0),(0,i.default)(this,"candidateSendQueue",void 0),(0,i.default)(this,"candidateSendTries",void 0),(0,i.default)(this,"sentEndOfCandidates",void 0),(0,i.default)(this,"peerConn",void 0),(0,i.default)(this,"feeds",void 0),(0,i.default)(this,"screenSharingStream",void 0),(0,i.default)(this,"localAVStream",void 0),(0,i.default)(this,"inviteOrAnswerSent",void 0),(0,i.default)(this,"waitForLocalAVStream",void 0),(0,i.default)(this,"config",void 0),(0,i.default)(this,"successor",void 0),(0,i.default)(this,"opponentMember",void 0),(0,i.default)(this,"opponentVersion",void 0),(0,i.default)(this,"opponentPartyId",void 0),(0,i.default)(this,"opponentCaps",void 0),(0,i.default)(this,"inviteTimeout",void 0),(0,i.default)(this,"remoteOnHold",void 0),(0,i.default)(this,"unholdingRemote",void 0),(0,i.default)(this,"micMuted",void 0),(0,i.default)(this,"vidMuted",void 0),(0,i.default)(this,"callStatsAtEnd",void 0),(0,i.default)(this,"makingOffer",void 0),(0,i.default)(this,"ignoreOffer",void 0),(0,i.default)(this,"remoteCandidateBuffer",new Map),(0,i.default)(this,"remoteAssertedIdentity",void 0),(0,i.default)(this,"gotUserMediaForInvite",(async e=>{if(this.successor)this.successor.gotUserMediaForAnswer(e);else if(this.callHasEnded())this.stopAllMedia();else{this.localAVStream=e,a.logger.info("Got local AV stream with id "+this.localAVStream.id),this.setState(p.CreateOffer),a.logger.debug("gotUserMediaForInvite -> "+this.type),this.screenSharingStream?(a.logger.debug("Setting screen sharing stream to the local video element"),this.pushNewFeed(this.screenSharingStream,this.client.getUserId(),d.SDPStreamMetadataPurpose.Screenshare)):this.pushNewFeed(e,this.client.getUserId(),d.SDPStreamMetadataPurpose.Usermedia),E(e.getAudioTracks(),!0);for(const t of e.getAudioTracks())a.logger.info("Adding audio track with id "+t.id),this.peerConn.addTrack(t,e);for(const t of(this.screenSharingStream||e).getVideoTracks())a.logger.info("Adding video track with id "+t.id),this.peerConn.addTrack(t,e)}})),(0,i.default)(this,"gotUserMediaForAnswer",(async e=>{if(this.callHasEnded())return;this.pushNewFeed(e,this.client.getUserId(),d.SDPStreamMetadataPurpose.Usermedia),this.localAVStream=e,a.logger.info("Got local AV stream with id "+this.localAVStream.id),E(e.getAudioTracks(),!0);for(const t of e.getTracks())this.peerConn.addTrack(t,e);let t;this.setState(p.CreateAnswer);try{t=await this.peerConn.createAnswer()}catch(e){return a.logger.debug("Failed to create answer: ",e),void this.terminate(m.Local,F.CreateAnswer,!0)}try{await this.peerConn.setLocalDescription(t),this.setState(p.Connecting),await new Promise((e=>{setTimeout(e,200)})),this.sendAnswer()}catch(e){return a.logger.debug("Error setting local description!",e),void this.terminate(m.Local,F.SetLocalDescription,!0)}})),(0,i.default)(this,"gotLocalIceCandidate",(e=>{if(e.candidate){if(a.logger.debug("Call "+this.callId+" got local ICE "+e.candidate.sdpMid+" candidate: "+e.candidate.candidate),this.callHasEnded())return;""===e.candidate.candidate&&this.sentEndOfCandidates||(this.queueCandidate(e.candidate),""===e.candidate.candidate&&(this.sentEndOfCandidates=!0))}})),(0,i.default)(this,"onIceGatheringStateChange",(e=>{if(a.logger.debug("ice gathering state changed to "+this.peerConn.iceGatheringState),"complete"===this.peerConn.iceGatheringState&&!this.sentEndOfCandidates){const e={candidate:""};this.queueCandidate(e),this.sentEndOfCandidates=!0}})),(0,i.default)(this,"gotLocalOffer",(async e=>{if(a.logger.debug("Created offer: ",e),this.callHasEnded())return void a.logger.debug("Ignoring newly created offer on call ID "+this.callId+" because the call has ended");try{await this.peerConn.setLocalDescription(e)}catch(e){return a.logger.debug("Error setting local description!",e),void this.terminate(m.Local,F.SetLocalDescription,!0)}if("gathering"===this.peerConn.iceGatheringState&&await new Promise((e=>{setTimeout(e,200)})),this.callHasEnded())return;const t=this.state===p.CreateOffer?c.EventType.CallInvite:c.EventType.CallNegotiate,n={lifetime:6e4};this.state===p.CreateOffer?n.offer=this.peerConn.localDescription:n.description=this.peerConn.localDescription,this.client._supportsCallTransfer&&(n.capabilities={"m.call.transferee":!0}),a.logger.info(`Discarding ${this.candidateSendQueue.length} candidates that will be sent in offer`),this.candidateSendQueue=[];try{await this.sendVoipEvent(t,n)}catch(e){a.logger.error("Failed to send invite",e),e.event&&this.client.cancelPendingEvent(e.event);let t=F.SignallingFailed,n="Signalling failed";return this.state===p.CreateOffer&&(t=F.SendInvite,n="Failed to send invite"),"UnknownDeviceError"==e.name&&(t=F.UnknownDevices,n="Unknown devices present in the room"),this.emit(_.Error,new b(t,n,e)),void this.terminate(m.Local,t,!1)}this.sendCandidateQueue(),this.state===p.CreateOffer&&(this.inviteOrAnswerSent=!0,this.setState(p.InviteSent),this.inviteTimeout=setTimeout((()=>{this.inviteTimeout=null,this.state===p.InviteSent&&this.hangup(F.InviteTimeout,!1)}),6e4))})),(0,i.default)(this,"getLocalOfferFailed",(e=>{a.logger.error("Failed to get local offer",e),this.emit(_.Error,new b(F.LocalOfferFailed,"Failed to get local offer!",e)),this.terminate(m.Local,F.LocalOfferFailed,!1)})),(0,i.default)(this,"getUserMediaFailed",(e=>{this.successor?this.successor.getUserMediaFailed(e):(a.logger.warn("Failed to get user media - ending call",e),this.emit(_.Error,new b(F.NoUserMedia,"Couldn't start capturing media! Is your microphone set up and does this app have permission?",e)),this.terminate(m.Local,F.NoUserMedia,!1))})),(0,i.default)(this,"onIceConnectionStateChanged",(()=>{this.callHasEnded()||(a.logger.debug("Call ID "+this.callId+": ICE connection state changed to: "+this.peerConn.iceConnectionState),"connected"==this.peerConn.iceConnectionState?this.setState(p.Connected):"failed"==this.peerConn.iceConnectionState&&this.hangup(F.IceFailed,!1))})),(0,i.default)(this,"onSignallingStateChanged",(()=>{a.logger.debug("call "+this.callId+": Signalling state changed to: "+this.peerConn.signalingState)})),(0,i.default)(this,"onTrack",(e=>{var t;if(0===e.streams.length)return void a.logger.warn(`Streamless ${e.track.kind} found: ignoring.`);const n=null===(t=this.feeds.find((e=>!e.isLocal())))||void 0===t?void 0:t.stream;if(n&&e.streams[0].id!==n.id)return void a.logger.warn(`Ignoring new stream ID ${e.streams[0].id}: we already have stream ID ${n.id}`);n||a.logger.info("Got remote stream with id "+e.streams[0].id);const o=e.streams[0];a.logger.debug(`Track id ${e.track.id} of kind ${e.track.kind} added`),this.pushNewFeed(o,this.getOpponentMember().userId,d.SDPStreamMetadataPurpose.Usermedia),a.logger.info("playing remote. stream active? "+o.active)})),(0,i.default)(this,"onNegotiationNeeded",(async()=>{if(a.logger.info("Negotation is needed!"),this.state===p.CreateOffer||0!==this.opponentVersion){this.makingOffer=!0;try{const e=await this.peerConn.createOffer();await this.gotLocalOffer(e)}catch(e){return void this.getLocalOfferFailed(e)}finally{this.makingOffer=!1}}else a.logger.info("Opponent does not support renegotiation: ignoring negotiationneeded event")})),(0,i.default)(this,"onHangupReceived",(e=>{a.logger.debug("Hangup received for call ID "+this.callId),this.partyIdMatches(e)||this.state===p.Ringing?this.terminate(m.Remote,e.reason||F.UserHangup,!0):a.logger.info(`Ignoring message from party ID ${e.party_id}: our partner is ${this.opponentPartyId}`)})),(0,i.default)(this,"onRejectReceived",(e=>{a.logger.debug("Reject received for call ID "+this.callId),[p.InviteSent,p.Ringing].includes(this.state)||this.state===p.Fledgling&&this.direction===g.Inbound?this.terminate(m.Remote,e.reason||F.UserHangup,!0):a.logger.debug(`Call is in state: ${this.state}: ignoring reject`)})),(0,i.default)(this,"onAnsweredElsewhere",(e=>{a.logger.debug("Call ID "+this.callId+" answered elsewhere"),this.terminate(m.Remote,F.AnsweredElsewhere,!0)})),this.roomId=e.roomId,this.client=e.client,this.type=null,this.forceTURN=e.forceTURN,this.ourPartyId=this.client.deviceId,this.turnServers=e.turnServers||[],0===this.turnServers.length&&this.client.isFallbackICEServerAllowed()&&this.turnServers.push({urls:["stun:turn.matrix.org"]});for(const e of this.turnServers)u.checkObjectHasKeys(e,["urls"]);this.callId=v(),this.state=p.Fledgling,this.candidateSendQueue=[],this.candidateSendTries=0,this.sentEndOfCandidates=!1,this.inviteOrAnswerSent=!1,this.makingOffer=!1,this.remoteOnHold=!1,this.unholdingRemote=!1,this.micMuted=!1,this.vidMuted=!1,this.feeds=[]}async placeVoiceCall(){a.logger.debug("placeVoiceCall"),this.checkForErrorListener();const e=k(y.Audio);this.type=f.Voice,await this.placeCallWithConstraints(e)}async placeVideoCall(){a.logger.debug("placeVideoCall"),this.checkForErrorListener();const e=k(y.Video);this.type=f.Video,await this.placeCallWithConstraints(e)}async placeScreenSharingCall(e){a.logger.debug("placeScreenSharingCall"),this.checkForErrorListener();try{var t;const n=await async function(e){var t;if(null!==(t=window.electron)&&void 0!==t&&t.getDesktopCapturerSources&&e){a.logger.debug("Electron getDesktopCapturerSources() is available...");const t=await e();return t?{audio:!1,video:{mandatory:{chromeMediaSource:"desktop",chromeMediaSourceId:t.id}}}:null}return a.logger.debug("Electron desktopCapturer is not available..."),{audio:!1,video:!0}}(e);if(!n)return void this.terminate(m.Local,F.NoUserMedia,!1);null!==(t=window.electron)&&void 0!==t&&t.getDesktopCapturerSources?(a.logger.debug("Getting screen stream using getUserMedia()..."),this.screenSharingStream=await navigator.mediaDevices.getUserMedia(n)):(a.logger.debug("Getting screen stream using getDisplayMedia()..."),this.screenSharingStream=await navigator.mediaDevices.getDisplayMedia(n)),a.logger.debug("Got screen stream, requesting audio stream...");const o=k(y.Audio);this.placeCallWithConstraints(o)}catch(e){this.emit(_.Error,new b(F.NoUserMedia,"Failed to get screen-sharing stream: ",e)),this.terminate(m.Local,F.NoUserMedia,!1)}this.type=f.Video}getOpponentMember(){return this.opponentMember}opponentCanBeTransferred(){return Boolean(this.opponentCaps&&this.opponentCaps["m.call.transferee"])}getRemoteAssertedIdentity(){return this.remoteAssertedIdentity}getFeeds(){return this.feeds}getLocalFeeds(){return this.feeds.filter((e=>e.isLocal()))}getRemoteFeeds(){return this.feeds.filter((e=>!e.isLocal()))}noIncomingFeeds(){return!this.feeds.some((e=>!e.isLocal()))}pushNewFeed(e,t,n){const o=this.feeds.find((t=>t.stream.id===e.id));o?o.setNewStream(e):(this.feeds.push(new h.CallFeed(e,t,n,this.client,this.roomId)),this.emit(_.FeedsChanged,this.feeds))}deleteAllFeeds(){this.feeds=[],this.emit(_.FeedsChanged,this.feeds)}async getCurrentCallStats(){return this.callHasEnded()?this.callStatsAtEnd:this.collectCallStats()}async collectCallStats(){if(!this.peerConn)return;const e=await this.peerConn.getStats(),t=[];for(const n of e)t.push(n[1]);return t}async initWithInvite(e){var t;const n=e.getContent();this.direction=g.Inbound,await this.client._checkTurnServers()||a.logger.warn("Failed to get TURN credentials! Proceeding with call anyway..."),this.peerConn=this.createPeerConnection(),this.chooseOpponent(e);try{await this.peerConn.setRemoteDescription(n.offer),await this.addBufferedIceCandidates()}catch(e){return a.logger.debug("Failed to set remote description",e),void this.terminate(m.Local,F.SetRemoteDescription,!1)}const o=null===(t=this.feeds.find((e=>!e.isLocal())))||void 0===t?void 0:t.stream;if(!o||0===o.getTracks().length)return a.logger.error("No remote stream or no tracks after setting remote description!"),void this.terminate(m.Local,F.SetRemoteDescription,!1);this.type=o.getTracks().some((e=>"video"===e.kind))?f.Video:f.Voice,this.setState(p.Ringing),e.getLocalAge()&&setTimeout((()=>{this.state==p.Ringing&&(a.logger.debug("Call invite has expired. Hanging up."),this.hangupParty=m.Remote,this.setState(p.Ended),this.stopAllMedia(),"closed"!=this.peerConn.signalingState&&this.peerConn.close(),this.emit(_.Hangup))}),n.lifetime-e.getLocalAge())}initWithHangup(e){this.setState(p.Ended)}async answer(){if(!this.inviteOrAnswerSent)if(a.logger.debug(`Answering call ${this.callId} of type ${this.type}`),this.localAVStream||this.waitForLocalAVStream)this.localAVStream?this.gotUserMediaForAnswer(this.localAVStream):this.waitForLocalAVStream&&this.setState(p.WaitLocalMedia);else{const e=k(this.type==f.Video?y.Video:y.Audio);a.logger.log("Getting user media with constraints",e),this.setState(p.WaitLocalMedia),this.waitForLocalAVStream=!0;try{const t=await navigator.mediaDevices.getUserMedia(e);this.waitForLocalAVStream=!1,this.gotUserMediaForAnswer(t)}catch(e){return void this.getUserMediaFailed(e)}}}replacedBy(e){a.logger.debug(this.callId+" being replaced by "+e.callId),this.state===p.WaitLocalMedia?(a.logger.debug("Telling new call to wait for local media"),e.waitForLocalAVStream=!0):(this.state===p.CreateOffer||this.state===p.InviteSent)&&(a.logger.debug("Handing local stream to new call"),e.gotUserMediaForAnswer(this.localAVStream),delete this.localAVStream),this.successor=e,this.emit(_.Replaced,e),this.hangup(F.Replaced,!0)}hangup(e,t){if(this.callHasEnded())return;if(a.logger.debug("Ending call "+this.callId),this.terminate(m.Local,e,!t),this.state===p.WaitLocalMedia)return;const n={};e!==F.UserHangup&&(n.reason=e),this.sendVoipEvent(c.EventType.CallHangup,n)}reject(){if(this.state!==p.Ringing)throw Error("Call must be in 'ringing' state to reject!");if(this.opponentVersion<1)return a.logger.info(`Opponent version is less than 1 (${this.opponentVersion}): sending hangup instead of reject`),void this.hangup(F.UserHangup,!0);a.logger.debug("Rejecting call: "+this.callId),this.terminate(m.Local,F.UserHangup,!0),this.sendVoipEvent(c.EventType.CallReject,{})}setLocalVideoMuted(e){this.vidMuted=e,this.updateMuteStatus()}isLocalVideoMuted(){return this.vidMuted}setMicrophoneMuted(e){this.micMuted=e,this.updateMuteStatus()}isMicrophoneMuted(){return this.micMuted}isRemoteOnHold(){return this.remoteOnHold}setRemoteOnHold(e){if(this.isRemoteOnHold()!==e){this.remoteOnHold=e,e||(this.unholdingRemote=!0);for(const t of this.peerConn.getTransceivers())t.direction=e?"inactive":"sendrecv";this.updateMuteStatus(),this.emit(_.RemoteHoldUnhold,this.remoteOnHold)}}isLocalOnHold(){if(this.state!==p.Connected)return!1;if(this.unholdingRemote)return!1;let e=!0;for(const t of this.peerConn.getTransceivers())["inactive","recvonly"].includes(t.currentDirection)||(e=!1);return e}sendDtmfDigit(e){for(const t of this.peerConn.getSenders())if("audio"===t.track.kind&&t.dtmf)return void t.dtmf.insertDTMF(e);throw new Error("Unable to find a track to send DTMF on")}updateMuteStatus(){if(!this.localAVStream)return;const e=this.micMuted||this.remoteOnHold;E(this.localAVStream.getAudioTracks(),!e);const t=this.vidMuted||this.remoteOnHold;E(this.localAVStream.getVideoTracks(),!t)}async sendAnswer(){const e={answer:{sdp:this.peerConn.localDescription.sdp,type:this.peerConn.localDescription.type}};this.client._supportsCallTransfer&&(e.capabilities={"m.call.transferee":!0}),a.logger.info(`Discarding ${this.candidateSendQueue.length} candidates that will be sent in answer`),this.candidateSendQueue=[];try{await this.sendVoipEvent(c.EventType.CallAnswer,e),this.inviteOrAnswerSent=!0}catch(e){this.setState(p.Ringing),this.client.cancelPendingEvent(e.event);let t=F.SendAnswer,n="Failed to send answer";throw"UnknownDeviceError"==e.name&&(t=F.UnknownDevices,n="Unknown devices present in the room"),this.emit(_.Error,new b(t,n,e)),e}this.sendCandidateQueue()}async onRemoteIceCandidatesReceived(e){if(this.callHasEnded())return;const t=e.getContent().candidates;if(!t)return void a.logger.info("Ignoring candidates event with no candidates!");const n=0===e.getContent().version?null:e.getContent().party_id||null;if(void 0===this.opponentPartyId){a.logger.info(`Bufferring ${t.length} candidates until we pick an opponent`);const e=this.remoteCandidateBuffer.get(n)||[];return e.push(...t),void this.remoteCandidateBuffer.set(n,e)}this.partyIdMatches(e.getContent())?await this.addIceCandidates(t):a.logger.info(`Ignoring candidates from party ID ${e.getContent().party_id}: we have chosen party ID ${this.opponentPartyId}`)}async onAnswerReceived(e){if(a.logger.debug(`Got answer for call ID ${this.callId} from party ID ${e.getContent().party_id}`),this.callHasEnded())a.logger.debug(`Ignoring answer because call ID ${this.callId} has ended`);else if(void 0===this.opponentPartyId){this.chooseOpponent(e),await this.addBufferedIceCandidates(),this.setState(p.Connecting);try{await this.peerConn.setRemoteDescription(e.getContent().answer)}catch(e){return a.logger.debug("Failed to set remote description",e),void this.terminate(m.Local,F.SetRemoteDescription,!1)}if(null!==this.opponentPartyId)try{await this.sendVoipEvent(c.EventType.CallSelectAnswer,{selected_party_id:this.opponentPartyId})}catch(e){a.logger.warn("Failed to send select_answer event",e)}}else a.logger.info(`Ignoring answer from party ID ${e.getContent().party_id}: we already have an answer/reject from ${this.opponentPartyId}`)}async onSelectAnswerReceived(e){if(this.direction!==g.Inbound)return void a.logger.warn("Got select_answer for an outbound call: ignoring");const t=e.getContent().selected_party_id;null!=t?t!==this.ourPartyId&&(a.logger.info(`Got select_answer for party ID ${t}: we are party ID ${this.ourPartyId}.`),this.terminate(m.Remote,F.AnsweredElsewhere,!0)):a.logger.warn("Got nonsensical select_answer with null/undefined selected_party_id: ignoring")}async onNegotiateReceived(e){const t=e.getContent().description;if(!t||!t.sdp||!t.type)return void a.logger.info("Ignoring invalid m.call.negotiate event");const n=this.direction===g.Inbound,o="offer"===t.type&&(this.makingOffer||"stable"!=this.peerConn.signalingState);if(this.ignoreOffer=!n&&o,this.ignoreOffer)return void a.logger.info("Ignoring colliding negotiate event because we're impolite");const r=this.isLocalOnHold();"answer"===t.type&&(this.unholdingRemote=!1);try{if(await this.peerConn.setRemoteDescription(t),"offer"===t.type){for(const e of this.peerConn.getTransceivers())e.direction=this.isRemoteOnHold()?"inactive":"sendrecv";const e=await this.peerConn.createAnswer();await this.peerConn.setLocalDescription(e);for(const e of this.peerConn.getTransceivers())e.direction=e.currentDirection;this.sendVoipEvent(c.EventType.CallNegotiate,{description:this.peerConn.localDescription})}}catch(e){a.logger.warn("Failed to complete negotiation",e)}const i=this.isLocalOnHold();r!==i&&(this.emit(_.LocalHoldUnhold,i),this.emit(_.HoldUnhold,i))}async onAssertedIdentityReceived(e){e.getContent().asserted_identity&&(this.remoteAssertedIdentity={id:e.getContent().asserted_identity.id,displayName:e.getContent().asserted_identity.display_name},this.emit(_.AssertedIdentityChanged))}callHasEnded(){return this.state===p.Ended}setState(e){const t=this.state;this.state=e,this.emit(_.State,e,t)}sendVoipEvent(e,t){return this.client.sendEvent(this.roomId,e,Object.assign({},t,{version:1,call_id:this.callId,party_id:this.ourPartyId}))}queueCandidate(e){if(this.candidateSendQueue.push(e),this.state===p.Ringing||!this.inviteOrAnswerSent)return;const t=this.direction===g.Inbound?500:2e3;0===this.candidateSendTries&&setTimeout((()=>{this.sendCandidateQueue()}),t)}async transfer(e){const t=await this.client.getProfileInfo(e),n=v(),o={replacement_id:v(),target_user:{id:e,display_name:t.display_name,avatar_url:t.avatar_url},create_call:n};await this.sendVoipEvent(c.EventType.CallReplaces,o),await this.terminate(m.Local,F.Replaced,!0)}async transferToCall(e){const t=await this.client.getProfileInfo(e.getOpponentMember().userId),n=await this.client.getProfileInfo(this.getOpponentMember().userId),o=v(),r={replacement_id:v(),target_user:{id:this.getOpponentMember().userId,display_name:n.display_name,avatar_url:n.avatar_url},await_call:o};await e.sendVoipEvent(c.EventType.CallReplaces,r);const i={replacement_id:v(),target_user:{id:e.getOpponentMember().userId,display_name:t.display_name,avatar_url:t.avatar_url},create_call:o};await this.sendVoipEvent(c.EventType.CallReplaces,i),await this.terminate(m.Local,F.Replaced,!0),await e.terminate(m.Local,F.Replaced,!0)}async terminate(e,t,n){this.callHasEnded()||(this.callStatsAtEnd=await this.collectCallStats(),this.inviteTimeout&&(clearTimeout(this.inviteTimeout),this.inviteTimeout=null),t!==F.Replaced&&this.stopAllMedia(),this.deleteAllFeeds(),this.hangupParty=e,this.hangupReason=t,this.setState(p.Ended),this.peerConn&&"closed"!==this.peerConn.signalingState&&this.peerConn.close(),n&&this.emit(_.Hangup,this))}stopAllMedia(){a.logger.debug(`stopAllMedia (stream=${this.localAVStream})`);for(const e of this.feeds)for(const t of e.stream.getTracks())t.stop()}checkForErrorListener(){if(0===this.listeners("error").length)throw new Error("You MUST attach an error listener using call.on('error', function() {})")}async sendCandidateQueue(){if(0===this.candidateSendQueue.length)return;const e=this.candidateSendQueue;this.candidateSendQueue=[],++this.candidateSendTries;const t={candidates:e};a.logger.debug("Attempting to send "+e.length+" candidates");try{await this.sendVoipEvent(c.EventType.CallCandidates,t)}catch(t){if(t.event&&this.client.cancelPendingEvent(t.event),this.candidateSendQueue.push(...e),this.candidateSendTries>5){a.logger.debug("Failed to send candidates on attempt "+this.candidateSendTries+". Giving up on this call.",t);const e=F.SignallingFailed,n="Signalling failed";return this.emit(_.Error,new b(e,n,t)),void this.hangup(e,!1)}const n=500*Math.pow(2,this.candidateSendTries);++this.candidateSendTries,a.logger.debug("Failed to send candidates. Retrying in "+n+"ms",t),setTimeout((()=>{this.sendCandidateQueue()}),n)}}async placeCallWithConstraints(e){a.logger.log("Getting user media with constraints",e),this.client._callEventHandler.calls.set(this.callId,this),this.setState(p.WaitLocalMedia),this.direction=g.Outbound,this.config=e,await this.client._checkTurnServers()||a.logger.warn("Failed to get TURN credentials! Proceeding with call anyway..."),this.peerConn=this.createPeerConnection();try{const t=await navigator.mediaDevices.getUserMedia(e);this.gotUserMediaForInvite(t)}catch(e){return void this.getUserMediaFailed(e)}}createPeerConnection(){const e=new window.RTCPeerConnection({iceTransportPolicy:this.forceTURN?"relay":void 0,iceServers:this.turnServers,iceCandidatePoolSize:this.client._iceCandidatePoolSize});return e.addEventListener("iceconnectionstatechange",this.onIceConnectionStateChanged),e.addEventListener("signalingstatechange",this.onSignallingStateChanged),e.addEventListener("icecandidate",this.gotLocalIceCandidate),e.addEventListener("icegatheringstatechange",this.onIceGatheringStateChange),e.addEventListener("track",this.onTrack),e.addEventListener("negotiationneeded",this.onNegotiationNeeded),e}partyIdMatches(e){return(0===e.version?null:e.party_id||null)===this.opponentPartyId}chooseOpponent(e){const t=e.getContent();a.logger.debug(`Choosing party ID ${t.party_id} for call ID ${this.callId}`),this.opponentVersion=t.version,0===this.opponentVersion?this.opponentPartyId=null:this.opponentPartyId=t.party_id||null,this.opponentCaps=t.capabilities||{},this.opponentMember=e.sender}async addBufferedIceCandidates(){const e=this.remoteCandidateBuffer.get(this.opponentPartyId);e&&(a.logger.info(`Adding ${e.length} buffered candidates for opponent ${this.opponentPartyId}`),await this.addIceCandidates(e)),this.remoteCandidateBuffer=null}async addIceCandidates(e){for(const t of e)if(null!==t.sdpMid&&void 0!==t.sdpMid||null!==t.sdpMLineIndex&&void 0!==t.sdpMLineIndex){a.logger.debug("Call "+this.callId+" got remote ICE "+t.sdpMid+" candidate: "+t.candidate);try{await this.peerConn.addIceCandidate(t)}catch(e){this.ignoreOffer||a.logger.info("Failed to add remote ICE candidate",e)}}else a.logger.debug("Ignoring remote ICE candidate with no sdpMid or sdpMLineIndex")}}function E(e,t){for(let n=0;n{"use strict";var o=n(95318);Object.defineProperty(t,"__esModule",{value:!0}),t.CallEventHandler=void 0;var r=o(n(59713)),i=n(7434),a=n(59679),s=n(42481);t.CallEventHandler=class{constructor(e){(0,r.default)(this,"client",void 0),(0,r.default)(this,"calls",void 0),(0,r.default)(this,"callEventBuffer",void 0),(0,r.default)(this,"candidateEventsByCall",void 0),(0,r.default)(this,"evaluateEventBuffer",(async()=>{if("SYNCING"===this.client.getSyncState()){await Promise.all(this.callEventBuffer.map((e=>{this.client.decryptEventIfNeeded(e)})));const e=new Set;for(const t of this.callEventBuffer)t.getType()!==s.EventType.CallAnswer&&t.getType()!==s.EventType.CallHangup||e.add(t.getContent().call_id);for(const t of this.callEventBuffer)if(t.getType()!==s.EventType.CallInvite||!e.has(t.getContent().call_id))try{this.handleCallEvent(t)}catch(e){i.logger.error("Caught exception handling call event",e)}this.callEventBuffer=[]}})),(0,r.default)(this,"onEvent",(e=>{this.client.decryptEventIfNeeded(e),(this.eventIsACall(e)||e.isBeingDecrypted())&&this.callEventBuffer.push(e),(e.isBeingDecrypted()||e.isDecryptionFailure())&&e.once("Event.decrypted",(()=>{if(this.eventIsACall(e))if(this.callEventBuffer.includes(e))this.evaluateEventBuffer();else try{this.handleCallEvent(e)}catch(e){i.logger.error("Caught exception handling call event",e)}}))})),this.client=e,this.calls=new Map,this.callEventBuffer=[],this.candidateEventsByCall=new Map}start(){this.client.on("sync",this.evaluateEventBuffer),this.client.on("event",this.onEvent)}stop(){this.client.removeListener("sync",this.evaluateEventBuffer),this.client.removeListener("event",this.onEvent)}eventIsACall(e){const t=e.getType();return t.startsWith("m.call.")||t.startsWith("org.matrix.call.")}handleCallEvent(e){const t=e.getContent();let n=t.call_id?this.calls.get(t.call_id):void 0;if(e.getType()===s.EventType.CallInvite){if(e.getSender()===this.client.credentials.userId)return;if(e.getLocalAge()>t.lifetime-3e3)return;if(n&&n.state===a.CallState.Ended)return;n&&i.logger.log(`WARN: Already have a MatrixCall with id ${t.call_id} but got an invite. Clobbering.`);const o=this.client.getTurnServersExpiry()-Date.now();if(i.logger.info("Current turn creds expire in "+o+" ms"),n=(0,a.createNewMatrixCall)(this.client,e.getRoomId(),{forceTURN:this.client._forceTURN}),!n)return void i.logger.log("Incoming call ID "+t.call_id+" but this client doesn't support WebRTC");if(n.callId=t.call_id,n.initWithInvite(e),this.calls.set(n.callId,n),this.candidateEventsByCall.get(n.callId))for(const e of this.candidateEventsByCall.get(n.callId))n.onRemoteIceCandidatesReceived(e);let r;for(const e of this.calls.values()){const t=[a.CallState.WaitLocalMedia,a.CallState.CreateOffer,a.CallState.InviteSent].includes(e.state);if(n.roomId===e.roomId&&e.direction===a.CallDirection.Outbound&&t){r=e;break}}r?r.state===a.CallState.WaitLocalMedia||r.state===a.CallState.CreateOffer||r.callId>n.callId?(i.logger.log("Glare detected: answering incoming call "+n.callId+" and canceling outgoing call "+r.callId),r.replacedBy(n),n.answer()):(i.logger.log("Glare detected: rejecting incoming call "+n.callId+" and keeping outgoing call "+r.callId),n.hangup(a.CallErrorCode.Replaced,!0)):this.client.emit("Call.incoming",n)}else if(e.getType()===s.EventType.CallAnswer){if(!n)return;e.getSender()===this.client.credentials.userId?n.state===a.CallState.Ringing&&n.onAnsweredElsewhere(t):n.onAnswerReceived(e)}else if(e.getType()===s.EventType.CallCandidates){if(e.getSender()===this.client.credentials.userId)return;n?n.onRemoteIceCandidatesReceived(e):(this.candidateEventsByCall.has(t.call_id)||this.candidateEventsByCall.set(t.call_id,[]),this.candidateEventsByCall.get(t.call_id).push(e))}else if([s.EventType.CallHangup,s.EventType.CallReject].includes(e.getType()))n?n.state!==a.CallState.Ended&&(e.getType()===s.EventType.CallHangup?n.onHangupReceived(t):n.onRejectReceived(t),this.calls.delete(t.call_id)):(n=(0,a.createNewMatrixCall)(this.client,e.getRoomId()),n&&(n.callId=t.call_id,n.initWithHangup(e),this.calls.set(t.call_id,n)));else if(e.getType()===s.EventType.CallSelectAnswer){if(!n)return;if(e.getContent().party_id===n.ourPartyId)return;n.onSelectAnswerReceived(e)}else if(e.getType()===s.EventType.CallNegotiate){if(!n)return;if(e.getContent().party_id===n.ourPartyId)return;n.onNegotiateReceived(e)}else if(e.getType()===s.EventType.CallAssertedIdentity||e.getType()===s.EventType.CallAssertedIdentityPrefix){if(!n)return;if(e.getContent().party_id===n.ourPartyId)return;n.onAssertedIdentityReceived(e)}}}},15964:(e,t)=>{"use strict";let n;Object.defineProperty(t,"__esModule",{value:!0}),t.SDPStreamMetadataPurpose=void 0,t.SDPStreamMetadataPurpose=n,function(e){e.Usermedia="m.usermedia",e.Screenshare="m.screenshare"}(n||(t.SDPStreamMetadataPurpose=n={}))},49704:(e,t,n)=>{"use strict";var o=n(95318);Object.defineProperty(t,"__esModule",{value:!0}),t.CallFeed=t.CallFeedEvent=void 0;var r=o(n(17187));let i;t.CallFeedEvent=i,function(e){e.NewStream="new_stream"}(i||(t.CallFeedEvent=i={}));class a extends r.default{constructor(e,t,n,o,r){super(),this.stream=e,this.userId=t,this.purpose=n,this.client=o,this.roomId=r}getMember(){return this.client.getRoom(this.roomId).getMember(this.userId)}isLocal(){return this.userId===this.client.getUserId()}isAudioMuted(){return 0===this.stream.getAudioTracks().length}isVideoMuted(){return 0===this.stream.getVideoTracks().length}setNewStream(e){this.stream=e,this.emit(i.NewStream,this.stream)}}t.CallFeed=a},62318:(e,t,n)=>{"use strict";var o=n(35717),r=n(3349),i=n(89509).Buffer,a=new Array(16);function s(){r.call(this,64),this._a=1732584193,this._b=4023233417,this._c=2562383102,this._d=271733878}function u(e,t){return e<>>32-t}function c(e,t,n,o,r,i,a){return u(e+(t&n|~t&o)+r+i|0,a)+t|0}function l(e,t,n,o,r,i,a){return u(e+(t&o|n&~o)+r+i|0,a)+t|0}function d(e,t,n,o,r,i,a){return u(e+(t^n^o)+r+i|0,a)+t|0}function h(e,t,n,o,r,i,a){return u(e+(n^(t|~o))+r+i|0,a)+t|0}o(s,r),s.prototype._update=function(){for(var e=a,t=0;t<16;++t)e[t]=this._block.readInt32LE(4*t);var n=this._a,o=this._b,r=this._c,i=this._d;n=c(n,o,r,i,e[0],3614090360,7),i=c(i,n,o,r,e[1],3905402710,12),r=c(r,i,n,o,e[2],606105819,17),o=c(o,r,i,n,e[3],3250441966,22),n=c(n,o,r,i,e[4],4118548399,7),i=c(i,n,o,r,e[5],1200080426,12),r=c(r,i,n,o,e[6],2821735955,17),o=c(o,r,i,n,e[7],4249261313,22),n=c(n,o,r,i,e[8],1770035416,7),i=c(i,n,o,r,e[9],2336552879,12),r=c(r,i,n,o,e[10],4294925233,17),o=c(o,r,i,n,e[11],2304563134,22),n=c(n,o,r,i,e[12],1804603682,7),i=c(i,n,o,r,e[13],4254626195,12),r=c(r,i,n,o,e[14],2792965006,17),n=l(n,o=c(o,r,i,n,e[15],1236535329,22),r,i,e[1],4129170786,5),i=l(i,n,o,r,e[6],3225465664,9),r=l(r,i,n,o,e[11],643717713,14),o=l(o,r,i,n,e[0],3921069994,20),n=l(n,o,r,i,e[5],3593408605,5),i=l(i,n,o,r,e[10],38016083,9),r=l(r,i,n,o,e[15],3634488961,14),o=l(o,r,i,n,e[4],3889429448,20),n=l(n,o,r,i,e[9],568446438,5),i=l(i,n,o,r,e[14],3275163606,9),r=l(r,i,n,o,e[3],4107603335,14),o=l(o,r,i,n,e[8],1163531501,20),n=l(n,o,r,i,e[13],2850285829,5),i=l(i,n,o,r,e[2],4243563512,9),r=l(r,i,n,o,e[7],1735328473,14),n=d(n,o=l(o,r,i,n,e[12],2368359562,20),r,i,e[5],4294588738,4),i=d(i,n,o,r,e[8],2272392833,11),r=d(r,i,n,o,e[11],1839030562,16),o=d(o,r,i,n,e[14],4259657740,23),n=d(n,o,r,i,e[1],2763975236,4),i=d(i,n,o,r,e[4],1272893353,11),r=d(r,i,n,o,e[7],4139469664,16),o=d(o,r,i,n,e[10],3200236656,23),n=d(n,o,r,i,e[13],681279174,4),i=d(i,n,o,r,e[0],3936430074,11),r=d(r,i,n,o,e[3],3572445317,16),o=d(o,r,i,n,e[6],76029189,23),n=d(n,o,r,i,e[9],3654602809,4),i=d(i,n,o,r,e[12],3873151461,11),r=d(r,i,n,o,e[15],530742520,16),n=h(n,o=d(o,r,i,n,e[2],3299628645,23),r,i,e[0],4096336452,6),i=h(i,n,o,r,e[7],1126891415,10),r=h(r,i,n,o,e[14],2878612391,15),o=h(o,r,i,n,e[5],4237533241,21),n=h(n,o,r,i,e[12],1700485571,6),i=h(i,n,o,r,e[3],2399980690,10),r=h(r,i,n,o,e[10],4293915773,15),o=h(o,r,i,n,e[1],2240044497,21),n=h(n,o,r,i,e[8],1873313359,6),i=h(i,n,o,r,e[15],4264355552,10),r=h(r,i,n,o,e[6],2734768916,15),o=h(o,r,i,n,e[13],1309151649,21),n=h(n,o,r,i,e[4],4149444226,6),i=h(i,n,o,r,e[11],3174756917,10),r=h(r,i,n,o,e[2],718787259,15),o=h(o,r,i,n,e[9],3951481745,21),this._a=this._a+n|0,this._b=this._b+o|0,this._c=this._c+r|0,this._d=this._d+i|0},s.prototype._digest=function(){this._block[this._blockOffset++]=128,this._blockOffset>56&&(this._block.fill(0,this._blockOffset,64),this._update(),this._blockOffset=0),this._block.fill(0,this._blockOffset,56),this._block.writeUInt32LE(this._length[0],56),this._block.writeUInt32LE(this._length[1],60),this._update();var e=i.allocUnsafe(16);return e.writeInt32LE(this._a,0),e.writeInt32LE(this._b,4),e.writeInt32LE(this._c,8),e.writeInt32LE(this._d,12),e},e.exports=s},86630:(e,t,n)=>{"use strict";var o=n(62854);e.exports=function(e,t){return n=function(e){var t={};if(!e||!e.type)throw new Error("mdast-util-definitions expected node");return o(e,"definition",(function(e){var n=i(e.identifier);r.call(t,n)||(t[n]=e)})),t}(e),function(e){var t=e&&i(e);return t&&r.call(n,t)?n[t]:null};var n};var r={}.hasOwnProperty;function i(e){return e.toUpperCase()}},52962:(e,t,n)=>{"use strict";e.exports=function(e,t,n,o){var r,i;return"string"==typeof t||t&&"function"==typeof t.exec?i=[[t,n]]:(i=t,o=n),s(e,r=o||{},function e(t){var n=t[0];return function(o,i){var u,c,l,d,h=n[0],p=n[1],f=[],g=0,m=i.children.indexOf(o);for(h.lastIndex=0,c=h.exec(o.value);c&&(u=c.index,!1!==(d=p.apply(null,[].concat(c,{index:c.index,input:c.input})))&&(g!==u&&f.push({type:"text",value:o.value.slice(g,u)}),"string"==typeof d&&d.length>0&&(d={type:"text",value:d}),d&&(f=[].concat(f,d)),g=u+c[0].length),h.global);)c=h.exec(o.value);if(void 0===u?(f=[o],m--):(g1)for(l=e(t.slice(1)),u=-1;++u{"use strict";e.exports=e=>{if("string"!=typeof e)throw new TypeError("Expected a string");return e.replace(/[|\\{}()[\]^$+*?.]/g,"\\$&").replace(/-/g,"\\x2d")}},52524:(e,t,n)=>{"use strict";e.exports=function(e,t,n){return"string"!=typeof t&&(n=t,t=void 0),function(e){var t=e||{},n=function(e,t){for(var n=-1;++n-1&&(w.call(this,e),E.call(this,e))},link:y((function(){var e=this.stack[this.stack.length-1];f("inReference")?(e.type+="Reference",e.referenceType=f("referenceType")||"shortcut",delete e.url,delete e.title):(delete e.identifier,delete e.label,delete e.referenceType),l("referenceType")})),listItem:y(),listOrdered:y(),listUnordered:y(),paragraph:y(),referenceString:function(e){var t=this.resume();this.stack[this.stack.length-1].label=t,this.stack[this.stack.length-1].identifier=a(this.sliceSerialize(e)).toLowerCase(),l("referenceType","full")},resourceDestinationString:function(){var e=this.resume();this.stack[this.stack.length-1].url=e},resourceTitleString:function(){var e=this.resume();this.stack[this.stack.length-1].title=e},resource:function(){l("inReference")},setextHeading:y((function(){l("setextHeadingSlurpLineEnding")})),setextHeadingLineSequence:function(e){this.stack[this.stack.length-1].depth=61===this.sliceSerialize(e).charCodeAt(0)?1:2},setextHeadingText:function(){l("setextHeadingSlurpLineEnding",!0)},strong:y(),thematicBreak:y()}},t.mdastExtensions||[]),u={};return function(e){for(var t,o={type:"root",children:[]},a=[],s=[],u=-1,d={stack:[o],tokenStack:a,config:n,enter:F,exit:b,buffer:_,resume:v,setData:l,getData:f};++u{"use strict";e.exports=n(52524)},57824:(e,t,n)=>{var o=n(30932),r=n(52962),i=n(36996),a=n(10395);function s(e){this.config.enter.autolinkProtocol.call(this,e)}function u(e,t,n,r,i){var a,s,u="";return!!l(i)&&(/^w/i.test(t)&&(n=t+n,t="",u="http://"),!!function(e){var t=e.split(".");return!(t.length<2||t[t.length-1]&&(/_/.test(t[t.length-1])||!/[a-zA-Z\d]/.test(t[t.length-1]))||t[t.length-2]&&(/_/.test(t[t.length-2])||!/[a-zA-Z\d]/.test(t[t.length-2])))}(n)&&!!(a=function(e){var t,n,r,i=/[!"&'),.:;<>?\]}]+$/.exec(e);if(i)for(e=e.slice(0,i.index),t=(i=i[0]).indexOf(")"),n=o(e,"("),r=o(e,")");-1!==t&&n>r;)e+=i.slice(0,t+1),t=(i=i.slice(t+1)).indexOf(")"),r++;return[e,i]}(n+r))[0]&&(s={type:"link",title:null,url:u+t+a[0],children:[{type:"text",value:t+a[0]}]},a[1]&&(s=[s,{type:"text",value:a[1]}]),s))}function c(e,t,n,o){return!(!l(o,!0)||/[_-]$/.test(n))&&{type:"link",title:null,url:"mailto:"+t+"@"+n,children:[{type:"text",value:t+"@"+n}]}}function l(e,t){var n=e.input.charCodeAt(e.index-1);return(n!=n||a(n)||i(n))&&(!t||47!==n)}t.transforms=[function(e){r(e,[[/(https?:\/\/|www(?=\.))([-.\w]+)([^ \t\r\n]*)/i,u],[/([-.\w+]+)@([-\w]+(?:\.[-\w]+)+)/,c]],{ignore:["link","linkReference"]})}],t.enter={literalAutolink:function(e){this.enter({type:"link",title:null,url:"",children:[]},e)},literalAutolinkEmail:s,literalAutolinkHttp:s,literalAutolinkWww:s},t.exit={literalAutolink:function(e){this.exit(e)},literalAutolinkEmail:function(e){this.config.exit.autolinkEmail.call(this,e)},literalAutolinkHttp:function(e){this.config.exit.autolinkProtocol.call(this,e)},literalAutolinkWww:function(e){this.config.exit.data.call(this,e),this.stack[this.stack.length-1].url="http://"+this.sliceSerialize(e)}}},45574:(e,t)=>{var n="phrasing",o=["autolink","link","image","label"];t.unsafe=[{character:"@",before:"[+\\-.\\w]",after:"[\\-.\\w]",inConstruct:n,notInConstruct:o},{character:".",before:"[Ww]",after:"[\\-.\\w]",inConstruct:n,notInConstruct:o},{character:":",before:"[ps]",after:"\\/",inConstruct:n,notInConstruct:o}]},89828:(e,t)=>{t.canContainEols=["delete"],t.enter={strikethrough:function(e){this.enter({type:"delete",children:[]},e)}},t.exit={strikethrough:function(e){this.exit(e)}}},9888:(e,t,n)=>{var o=n(25362);function r(e,t,n){var r=n.enter("emphasis"),i=o(e,n,{before:"~",after:"~"});return r(),"~~"+i+"~~"}t.unsafe=[{character:"~",inConstruct:"phrasing"}],t.handlers={delete:r},r.peek=function(){return"~"}},4865:(e,t)=>{function n(e){this.exit(e)}function o(e){this.enter({type:"tableCell",children:[]},e)}function r(e,t){return"|"===t?t:e}t.enter={table:function(e){this.enter({type:"table",align:e._align,children:[]},e),this.setData("inTable",!0)},tableData:o,tableHeader:o,tableRow:function(e){this.enter({type:"tableRow",children:[]},e)}},t.exit={codeText:function(e){var t=this.resume();this.getData("inTable")&&(t=t.replace(/\\([\\|])/g,r)),this.stack[this.stack.length-1].value=t,this.exit(e)},table:function(e){this.exit(e),this.setData("inTable")},tableData:n,tableHeader:n,tableRow:n}},63046:(e,t,n)=>{var o=n(25362),r=n(11595),i=n(78234);e.exports=function(e){var t=e||{},n=t.tableCellPadding,a=t.tablePipeAlign,s=t.stringLength,u=n?" ":"|";return{unsafe:[{character:"\r",inConstruct:"tableCell"},{character:"\n",inConstruct:"tableCell"},{atBreak:!0,character:"|",after:"[\t :-]"},{character:"|",inConstruct:"tableCell"},{atBreak:!0,character:":",after:"-"},{atBreak:!0,character:"-",after:"[:|-]"}],handlers:{table:function(e,t,n){return l(function(e,t){for(var n=e.children,o=-1,r=n.length,i=[],a=t.enter("table");++o{function n(e){this.stack[this.stack.length-2].checked="taskListCheckValueChecked"===e.type}t.exit={taskListCheckValueChecked:n,taskListCheckValueUnchecked:n,paragraph:function(e){var t,n=this.stack[this.stack.length-2],o=this.stack[this.stack.length-1],r=n.children,i=o.children[0],a=-1;if(n&&"listItem"===n.type&&"boolean"==typeof n.checked&&i&&"text"===i.type){for(;++a{var o=n(48618);t.unsafe=[{atBreak:!0,character:"-",after:"[:|-]"}],t.handlers={listItem:function(e,t,n){var r=o(e,t,n),i=e.children[0];return"boolean"==typeof e.checked&&i&&"paragraph"===i.type&&(r=r.replace(/^(?:[*+-]|\d+\.)([\r\n]| {1,3})/,(function(t){return t+"["+(e.checked?"x":" ")+"] "}))),r}}},10438:(e,t,n)=>{var o=n(57824),r=n(89828),i=n(4865),a=n(29511),s={}.hasOwnProperty;function u(e,t){var n,o,r;for(n in t)o=s.call(e,n)?e[n]:e[n]={},r=t[n],"canContainEols"===n||"transforms"===n?e[n]=[].concat(o,r):Object.assign(o,r)}e.exports=function(e){for(var t={transforms:[],canContainEols:[]},n=e.length,o=-1;++o{var o=n(45574),r=n(9888),i=n(63046),a=n(94625),s=n(2564);e.exports=function(e){var t=s({handlers:{},join:[],unsafe:[],options:{}},{extensions:[o,r,i(e),a]});return Object.assign(t.options,{handlers:t.handlers,join:t.join,unsafe:t.unsafe})}},55288:(e,t,n)=>{"use strict";e.exports=n(31601)},95426:(e,t,n)=>{"use strict";e.exports=function(e,t){for(var n,r,i=t.children||[],a=i.length,s=[],u=-1;++u{"use strict";e.exports=function(e){for(var t,n,a,s,u=e.footnoteById,c=e.footnoteOrder,l=c.length,d=-1,h=[];++d{"use strict";e.exports=function(e,t){return e(t,"blockquote",o(r(e,t),!0))};var o=n(96115),r=n(95426)},13562:(e,t,n)=>{"use strict";e.exports=function(e,t){return[e(t,"br"),o("text","\n")]};var o=n(50914)},37891:(e,t,n)=>{"use strict";e.exports=function(e,t){var n,r=t.value?t.value+"\n":"",i=t.lang&&t.lang.match(/^[^ \t]+(?=[ \t]|$)/),a={};return i&&(a.className=["language-"+i]),n=e(t,"code",a,[o("text",r)]),t.meta&&(n.data={meta:t.meta}),e(t.position,"pre",[n])};var o=n(50914)},59381:(e,t,n)=>{"use strict";e.exports=function(e,t){return e(t,"del",o(e,t))};var o=n(95426)},80790:(e,t,n)=>{"use strict";e.exports=function(e,t){return e(t,"em",o(e,t))};var o=n(95426)},58235:(e,t,n)=>{"use strict";e.exports=function(e,t){var n=e.footnoteOrder,r=String(t.identifier);return-1===n.indexOf(r)&&n.push(r),e(t.position,"sup",{id:"fnref-"+r},[e(t,"a",{href:"#fn-"+r,className:["footnote-ref"]},[o("text",t.label||r)])])};var o=n(50914)},85758:(e,t,n)=>{"use strict";e.exports=function(e,t){for(var n=e.footnoteById,r=e.footnoteOrder,i=1;i in n;)i++;return i=String(i),r.push(i),n[i]={type:"footnoteDefinition",identifier:i,children:[{type:"paragraph",children:t.children}],position:t.position},o(e,{type:"footnoteReference",identifier:i,position:t.position})};var o=n(58235)},34890:(e,t,n)=>{"use strict";e.exports=function(e,t){return e(t,"h"+t.depth,o(e,t))};var o=n(95426)},92202:(e,t,n)=>{"use strict";e.exports=function(e,t){return e.dangerous?e.augment(t,o("raw",t.value)):null};var o=n(50914)},71454:(e,t,n)=>{"use strict";e.exports=function(e,t){var n,i=e.definition(t.identifier);return i?(n={src:o(i.url||""),alt:t.alt},null!==i.title&&void 0!==i.title&&(n.title=i.title),e(t,"img",n)):r(e,t)};var o=n(70729),r=n(713)},5037:(e,t,n)=>{"use strict";var o=n(70729);e.exports=function(e,t){var n={src:o(t.url),alt:t.alt};return null!==t.title&&void 0!==t.title&&(n.title=t.title),e(t,"img",n)}},44617:(e,t,n)=>{"use strict";function o(){return null}e.exports={blockquote:n(34590),break:n(13562),code:n(37891),delete:n(59381),emphasis:n(80790),footnoteReference:n(58235),footnote:n(85758),heading:n(34890),html:n(92202),imageReference:n(71454),image:n(5037),inlineCode:n(28409),linkReference:n(79266),link:n(20404),listItem:n(94463),list:n(47888),paragraph:n(68346),root:n(68100),strong:n(4970),table:n(72605),text:n(50989),thematicBreak:n(37552),toml:o,yaml:o,definition:o,footnoteDefinition:o}},28409:(e,t,n)=>{"use strict";e.exports=function(e,t){var n=t.value.replace(/\r?\n|\r/g," ");return e(t,"code",[o("text",n)])};var o=n(50914)},79266:(e,t,n)=>{"use strict";e.exports=function(e,t){var n,a=e.definition(t.identifier);return a?(n={href:o(a.url||"")},null!==a.title&&void 0!==a.title&&(n.title=a.title),e(t,"a",n,i(e,t))):r(e,t)};var o=n(70729),r=n(713),i=n(95426)},20404:(e,t,n)=>{"use strict";var o=n(70729),r=n(95426);e.exports=function(e,t){var n={href:o(t.url)};return null!==t.title&&void 0!==t.title&&(n.title=t.title),e(t,"a",n,r(e,t))}},94463:(e,t,n)=>{"use strict";e.exports=function(e,t,n){var a,s,u,c=r(e,t),l=c[0],d=n?function(e){for(var t=e.spread,n=e.children,o=n.length,r=-1;!t&&++r0&&l.children.unshift(o("text"," ")),l.children.unshift(e(null,"input",{type:"checkbox",checked:t.checked,disabled:!0})),h.className=["task-list-item"]),a=c.length,s=-1;++s1:t}},47888:(e,t,n)=>{"use strict";e.exports=function(e,t){var n,i,a={},s=t.ordered?"ol":"ul",u=-1;for("number"==typeof t.start&&1!==t.start&&(a.start=t.start),i=(n=r(e,t)).length;++u{"use strict";e.exports=function(e,t){return e(t,"p",o(e,t))};var o=n(95426)},68100:(e,t,n)=>{"use strict";e.exports=function(e,t){return e.augment(t,o("root",r(i(e,t))))};var o=n(50914),r=n(96115),i=n(95426)},4970:(e,t,n)=>{"use strict";e.exports=function(e,t){return e(t,"strong",o(e,t))};var o=n(95426)},72605:(e,t,n)=>{"use strict";e.exports=function(e,t){for(var n,a,s,u,c,l=t.children,d=l.length,h=t.align||[],p=h.length,f=[];d--;){for(a=l[d].children,u=0===d?"th":"td",n=p||a.length,s=[];n--;)c=a[n],s[n]=e(c,u,{align:h[n]},c?i(e,c):[]);f[d]=e(l[d],"tr",r(s,!0))}return e(t,"table",r([e(f[0].position,"thead",r([f[0]],!0))].concat(f[1]?e({start:o.start(f[1]),end:o.end(f[f.length-1])},"tbody",r(f.slice(1),!0)):[]),!0))};var o=n(77361),r=n(96115),i=n(95426)},50989:(e,t,n)=>{"use strict";e.exports=function(e,t){return e.augment(t,o("text",String(t.value).replace(/[ \t]*(\r?\n|\r)[ \t]*/g,"$1")))};var o=n(50914)},37552:e=>{"use strict";e.exports=function(e,t){return e(t,"hr")}},31601:(e,t,n)=>{"use strict";e.exports=function(e,t){var n=function(e,t){var n=t||{};void 0===n.allowDangerousHTML||h||(h=!0,console.warn("mdast-util-to-hast: deprecation: `allowDangerousHTML` is nonstandard, use `allowDangerousHtml` instead"));var o=n.allowDangerousHtml||n.allowDangerousHTML,u={};return p.dangerous=o,p.definition=s(e),p.footnoteById=u,p.footnoteOrder=[],p.augment=c,p.handlers=Object.assign({},l,n.handlers),p.unknownHandler=n.unknownHandler,p.passThrough=n.passThrough,r(e,"footnoteDefinition",(function(e){var t=String(e.identifier).toUpperCase();d.call(u,t)||(u[t]=e)})),p;function c(e,t){var n,o;return e&&e.data&&((n=e.data).hName&&("element"!==t.type&&(t={type:"element",tagName:"",properties:{},children:[]}),t.tagName=n.hName),"element"===t.type&&n.hProperties&&(t.properties=Object.assign({},t.properties,n.hProperties)),t.children&&n.hChildren&&(t.children=n.hChildren)),o=e&&e.position?e:{position:e},a(o)||(t.position={start:i.start(o),end:i.end(o)}),t}function p(e,t,n,o){return null==o&&"object"==typeof n&&"length"in n&&(o=n,n={}),c(e,{type:"element",tagName:t,properties:n||{},children:o||[]})}}(e,t),p=u(n,e),f=c(n);return f&&(p.children=p.children.concat(o("text","\n"),f)),p};var o=n(50914),r=n(62854),i=n(77361),a=n(61744),s=n(86630),u=n(60719),c=n(61696),l=n(44617),d={}.hasOwnProperty,h=!1},60719:(e,t,n)=>{"use strict";e.exports=function(e,t,n){var o,r=t&&t.type;if(!r)throw new Error("Expected node, got `"+t+"`");return("function"==typeof(o=i.call(e.handlers,r)?e.handlers[r]:e.passThrough&&e.passThrough.indexOf(r)>-1?s:e.unknownHandler)?o:a)(e,t,n)};var o=n(50914),r=n(95426),i={}.hasOwnProperty;function a(e,t){return function(e){var t=e.data||{};return!(i.call(t,"hName")||i.call(t,"hProperties")||i.call(t,"hChildren"))&&"value"in e}(t)?e.augment(t,o("text",t.value)):e(t,"div",r(e,t))}function s(e,t){var n;return t.children?((n=Object.assign({},t)).children=r(e,t),n):t}},713:(e,t,n)=>{"use strict";e.exports=function(e,t){var n,i,a,s=t.referenceType,u="]";return"collapsed"===s?u+="[]":"full"===s&&(u+="["+(t.label||t.identifier)+"]"),"imageReference"===t.type?o("text","!["+t.alt+u):((i=(n=r(e,t))[0])&&"text"===i.type?i.value="["+i.value:n.unshift(o("text","[")),(a=n[n.length-1])&&"text"===a.type?a.value+=u:n.push(o("text",u)),n)};var o=n(50914),r=n(95426)},96115:(e,t,n)=>{"use strict";e.exports=function(e,t){var n=[],r=-1,i=e.length;for(t&&n.push(o("text","\n"));++r0&&n.push(o("text","\n")),n};var o=n(50914)},2564:e=>{e.exports=function e(t,n){var o,r=-1;if(n.extensions)for(;++r{e.exports=r,r.peek=function(){return"`"};var o=n(84553);function r(e,t,n){for(var r,i,a,s,u=e.value||"",c="`",l=-1;new RegExp("(^|[^`])"+c+"([^`]|$)").test(u);)c+="`";for(/[^ \r\n]/.test(u)&&(/[ \r\n`]/.test(u.charAt(0))||/[ \r\n`]/.test(u.charAt(u.length-1)))&&(u=" "+u+" ");++l{e.exports=function(e,t,n){var u,c,l,d=r(n),h=i(n);return t&&t.ordered&&(d=(t.start>-1?t.start:1)+(!1===n.options.incrementListMarker?0:t.children.indexOf(e))+"."),u=d.length+1,("tab"===h||"mixed"===h&&(t&&t.spread||e.spread))&&(u=4*Math.ceil(u/4)),l=n.enter("listItem"),c=s(a(e,n),(function(e,t,n){return t?(n?"":o(" ",u))+e:(n?d:d+o(" ",u-d.length))+e})),l(),c};var o=n(96464),r=n(89400),i=n(56636),a=n(93493),s=n(92670)},89400:e=>{e.exports=function(e){var t=e.options.bullet||"*";if("*"!==t&&"+"!==t&&"-"!==t)throw new Error("Cannot serialize items with `"+t+"` for `options.bullet`, expected `*`, `+`, or `-`");return t}},56636:e=>{e.exports=function(e){var t=e.options.listItemIndent||"tab";if(1===t||"1"===t)return"one";if("tab"!==t&&"one"!==t&&"mixed"!==t)throw new Error("Cannot serialize items with `"+t+"` for `options.listItemIndent`, expected `tab`, `one`, or `mixed`");return t}},93493:(e,t,n)=>{e.exports=function(e,t){for(var n,r=e.children||[],i=[],a=-1;++a{e.exports=function(e,t,n){for(var o,r,i,a=e.children||[],s=[],u=-1,c=n.before;++u0&&("\r"===c||"\n"===c)&&"html"===i.type&&(s[s.length-1]=s[s.length-1].replace(/(\r?\n|\r)$/," "),c=" "),s.push(t.handle(i,e,t,{before:c,after:o})),c=s[s.length-1].slice(-1);return s.join("")}},92670:e=>{e.exports=function(e,n){for(var o,r=[],i=0,a=0;o=t.exec(e);)s(e.slice(i,o.index)),r.push(o[0]),i=o.index+o[0].length,a++;return s(e.slice(i)),r.join("");function s(e){r.push(n(e,a,!e))}};var t=/\r?\n|\r/g},84553:e=>{e.exports=function(e){var t,n;return e._compiled||(t=e.before?"(?:"+e.before+")":"",n=e.after?"(?:"+e.after+")":"",e.atBreak&&(t="[\\r\\n][\\t ]*"+t),e._compiled=new RegExp((t?"("+t+")":"")+(/[|\\{}()[\]^$+*?.-]/.test(e.character)?"\\":"")+e.character+(n||""),"g")),e._compiled}},4999:e=>{"use strict";function t(e){return e&&(e.value||e.alt||e.title||"children"in e&&n(e.children)||"length"in e&&n(e))||""}function n(e){for(var n=[],o=-1;++o{"use strict";var t={};function n(e,o,r){var i,a,s,u,c,l="";for("string"!=typeof o&&(r=o,o=n.defaultChars),void 0===r&&(r=!0),c=function(e){var n,o,r=t[e];if(r)return r;for(r=t[e]=[],n=0;n<128;n++)o=String.fromCharCode(n),/^[0-9a-z]$/i.test(o)?r.push(o):r.push("%"+("0"+n.toString(16).toUpperCase()).slice(-2));for(n=0;n=55296&&s<=57343){if(s>=55296&&s<=56319&&i+1=56320&&u<=57343){l+=encodeURIComponent(e[i]+e[i+1]),i++;continue}l+="%EF%BF%BD"}else l+=encodeURIComponent(e[i]);return l}n.defaultChars=";/?:@&=+$,-_.!~*'()#",n.componentChars="-_.!~*'()",e.exports=n},57539:(e,t,n)=>{e.exports=n(62346)},62346:(e,t,n)=>{var o=n(76734),r=n(46712),i=n(89696),a=n(17238),s=n(36996),u=n(10395),c={tokenize:function(e,t,n){return function(t){return e.consume(t),o};function o(t){return 87===t||t-32==87?(e.consume(t),r):n(t)}function r(t){return 87===t||t-32==87?(e.consume(t),i):n(t)}function i(t){return 46===t?(e.consume(t),s):n(t)}function s(e){return null===e||a(e)?n(e):t(e)}},partial:!0},l={tokenize:function(e,t,n){var o,r;return a;function a(t){return 38===t?e.check(p,l,c)(t):46===t||95===t?e.check(h,l,c)(t):i(t)||u(t)||45!==t&&s(t)?l(t):(e.consume(t),a)}function c(t){return 46===t?(r=o,o=void 0,e.consume(t),a):(95===t&&(o=!0),e.consume(t),a)}function l(e){return r||o?n(e):t(e)}},partial:!0},d={tokenize:function(e,t){var n=0;return o;function o(a){return 38===a?e.check(p,t,r)(a):(40===a&&n++,41===a?e.check(h,i,r)(a):b(a)?t(a):y(a)?e.check(h,t,r)(a):(e.consume(a),o))}function r(t){return e.consume(t),o}function i(e){return--n<0?t(e):r(e)}},partial:!0},h={tokenize:function(e,t,n){return function(t){return e.consume(t),o};function o(r){return y(r)?(e.consume(r),o):b(r)?t(r):n(r)}},partial:!0},p={tokenize:function(e,t,n){return function(t){return e.consume(t),r};function r(t){return o(t)?(e.consume(t),r):59===t?(e.consume(t),i):n(t)}function i(e){return b(e)?t(e):n(e)}},partial:!0},f={tokenize:function(e,t,n){var o=this;return function(t){return 87!==t&&t-32!=87||!w(o.previous)||D(o.events)?n(t):(e.enter("literalAutolink"),e.enter("literalAutolinkWww"),e.check(c,e.attempt(l,e.attempt(d,r),n),n)(t))};function r(n){return e.exit("literalAutolinkWww"),e.exit("literalAutolink"),t(n)}},previous:w},g={tokenize:function(e,t,n){var o=this;return function(t){return 72!==t&&t-32!=72||!E(o.previous)||D(o.events)?n(t):(e.enter("literalAutolink"),e.enter("literalAutolinkHttp"),e.consume(t),r)};function r(t){return 84===t||t-32==84?(e.consume(t),a):n(t)}function a(t){return 84===t||t-32==84?(e.consume(t),c):n(t)}function c(t){return 80===t||t-32==80?(e.consume(t),h):n(t)}function h(t){return 83===t||t-32==83?(e.consume(t),p):p(t)}function p(t){return 58===t?(e.consume(t),f):n(t)}function f(t){return 47===t?(e.consume(t),g):n(t)}function g(t){return 47===t?(e.consume(t),m):n(t)}function m(t){return i(t)||u(t)||s(t)?n(t):e.attempt(l,e.attempt(d,_),n)(t)}function _(n){return e.exit("literalAutolinkHttp"),e.exit("literalAutolink"),t(n)}},previous:E},m={tokenize:function(e,t,n){var o,i=this;return function(t){return v(t)&&k(i.previous)&&!D(i.events)?(e.enter("literalAutolink"),e.enter("literalAutolinkEmail"),a(t)):n(t)};function a(t){return v(t)?(e.consume(t),a):64===t?(e.consume(t),s):n(t)}function s(t){return 46===t?e.check(h,d,u)(t):45===t||95===t?e.check(h,n,c)(t):r(t)?(e.consume(t),s):d(t)}function u(t){return e.consume(t),o=!0,s}function c(t){return e.consume(t),l}function l(t){return 46===t?e.check(h,n,u)(t):s(t)}function d(r){return o?(e.exit("literalAutolinkEmail"),e.exit("literalAutolink"),t(r)):n(r)}},previous:k},_={};t.text=_;for(var F=48;F<123;)_[F]=m,58==++F?F=65:91===F&&(F=97);function y(e){return 33===e||34===e||39===e||41===e||42===e||44===e||46===e||58===e||59===e||60===e||63===e||95===e||126===e}function b(e){return null===e||e<0||32===e||60===e}function v(e){return 43===e||45===e||46===e||95===e||r(e)}function w(e){return null===e||e<0||32===e||40===e||42===e||95===e||126===e}function E(e){return null===e||!o(e)}function k(e){return 47!==e&&E(e)}function D(e){for(var t=e.length;t--;)if(("labelLink"===e[t][1].type||"labelImage"===e[t][1].type)&&!e[t][1]._balanced)return!0}_[43]=m,_[45]=m,_[46]=m,_[95]=m,_[72]=[m,g],_[104]=[m,g],_[87]=[m,f],_[119]=[m,f]},3490:(e,t,n)=>{e.exports=function(e){var t=(e||{}).singleTilde,n={tokenize:function(e,n,r){var i=this.previous,a=this.events,s=0;return function(t){return 126!==t||126===i&&"characterEscape"!==a[a.length-1][1].type?r(t):(e.enter("strikethroughSequenceTemporary"),u(t))};function u(a){var c,l,d=o(i);return 126===a?s>1?r(a):(e.consume(a),s++,u):s<2&&!t?r(a):(c=e.exit("strikethroughSequenceTemporary"),l=o(a),c._open=!l||2===l&&d,c._close=!d||2===d&&l,n(a))}},resolveAll:function(e,t){for(var n,o,s,u,c=-1;++c{e.exports=n(23993)},23993:(e,t,n)=>{t.flow={null:{tokenize:function(e,t,n){var a,s,u=[],c=0;return function(t){return null===t||-5===t||-4===t||-3===t?n(t):(e.enter("table")._align=u,e.enter("tableHead"),e.enter("tableRow"),124===t?l(t):(c++,e.enter("temporaryTableCellContent"),p(t)))};function l(t){return e.enter("tableCellDivider"),e.consume(t),e.exit("tableCellDivider"),a=!0,d}function d(t){return null===t||-5===t||-4===t||-3===t?function(t){return null===t?n(t):(e.exit("tableRow"),e.exit("tableHead"),e.enter("lineEnding"),e.consume(t),e.exit("lineEnding"),e.check(r,n,o(e,g,"linePrefix",4)))}(t):-2===t||-1===t||32===t?(e.enter("whitespace"),e.consume(t),h):(a&&(a=void 0,c++),124===t?l(t):(e.enter("temporaryTableCellContent"),p(t)))}function h(t){return-2===t||-1===t||32===t?(e.consume(t),h):(e.exit("whitespace"),d(t))}function p(t){return null===t||t<0||32===t||124===t?(e.exit("temporaryTableCellContent"),d(t)):(e.consume(t),92===t?f:p)}function f(t){return 92===t||124===t?(e.consume(t),p):p(t)}function g(t){return null===t||t<0||32===t?n(t):(e.enter("tableDelimiterRow"),m(t))}function m(t){return null===t||-5===t||-4===t||-3===t?v(t):-2===t||-1===t||32===t?(e.enter("whitespace"),e.consume(t),_):45===t?(e.enter("tableDelimiterFiller"),e.consume(t),s=!0,u.push(null),F):58===t?(e.enter("tableDelimiterAlignment"),e.consume(t),e.exit("tableDelimiterAlignment"),u.push("left"),y):124===t?(e.enter("tableCellDivider"),e.consume(t),e.exit("tableCellDivider"),m):n(t)}function _(t){return-2===t||-1===t||32===t?(e.consume(t),_):(e.exit("whitespace"),m(t))}function F(t){return 45===t?(e.consume(t),F):(e.exit("tableDelimiterFiller"),58===t?(e.enter("tableDelimiterAlignment"),e.consume(t),e.exit("tableDelimiterAlignment"),u[u.length-1]="left"===u[u.length-1]?"center":"right",b):m(t))}function y(t){return 45===t?(e.enter("tableDelimiterFiller"),e.consume(t),s=!0,F):n(t)}function b(t){return null===t||-5===t||-4===t||-3===t?v(t):-2===t||-1===t||32===t?(e.enter("whitespace"),e.consume(t),_):124===t?(e.enter("tableCellDivider"),e.consume(t),e.exit("tableCellDivider"),m):n(t)}function v(t){return e.exit("tableDelimiterRow"),s&&c===u.length?null===t?w(t):e.check(i,w,E)(t):n(t)}function w(n){return e.exit("table"),t(n)}function E(t){return e.enter("lineEnding"),e.consume(t),e.exit("lineEnding"),o(e,k,"linePrefix",4)}function k(t){return e.enter("tableBody"),D(t)}function D(t){return e.enter("tableRow"),124===t?S(t):(e.enter("temporaryTableCellContent"),A(t))}function S(t){return e.enter("tableCellDivider"),e.consume(t),e.exit("tableCellDivider"),x}function x(t){return null===t||-5===t||-4===t||-3===t?function(t){return e.exit("tableRow"),null===t?R(t):e.check(i,R,I)(t)}(t):-2===t||-1===t||32===t?(e.enter("whitespace"),e.consume(t),C):124===t?S(t):(e.enter("temporaryTableCellContent"),A(t))}function C(t){return-2===t||-1===t||32===t?(e.consume(t),C):(e.exit("whitespace"),x(t))}function A(t){return null===t||t<0||32===t||124===t?(e.exit("temporaryTableCellContent"),x(t)):(e.consume(t),92===t?T:A)}function T(t){return 92===t||124===t?(e.consume(t),A):A(t)}function R(t){return e.exit("tableBody"),w(t)}function I(t){return e.enter("lineEnding"),e.consume(t),e.exit("lineEnding"),o(e,D,"linePrefix",4)}},resolve:function(e,t){for(var n,o,r,i,a,s,u,c,l,d,h=e.length,p=-1;++p{e.exports=n(27224)},27224:(e,t,n)=>{var o=n(88367),r=n(52928),i=n(15096),a={tokenize:function(e,t,n){var o=this;return function(t){return 91===t&&null===o.previous&&o._gfmTasklistFirstContentOfListItem?(e.enter("taskListCheck"),e.enter("taskListCheckMarker"),e.consume(t),e.exit("taskListCheckMarker"),r):n(t)};function r(t){return-2===t||32===t?(e.enter("taskListCheckValueUnchecked"),e.consume(t),e.exit("taskListCheckValueUnchecked"),i):88===t||120===t?(e.enter("taskListCheckValueChecked"),e.consume(t),e.exit("taskListCheckValueChecked"),i):n(t)}function i(o){return 93===o?(e.enter("taskListCheckMarker"),e.consume(o),e.exit("taskListCheckMarker"),e.exit("taskListCheck"),e.check({tokenize:s},t,n)):n(o)}}};function s(e,t,n){var a=this;return r(e,(function(e){return i(a.events,"whitespace")&&null!==e&&!o(e)?t(e):n(e)}),"whitespace")}t.text={91:a}},82747:(e,t,n)=>{e.exports=n(2518)},2518:(e,t,n)=>{var o=n(12952),r=n(57539),i=n(3490),a=n(81286),s=n(5675);e.exports=function(e){return o([r,i(e),a,s])}},76734:(e,t,n)=>{"use strict";var o=n(2841)(/[A-Za-z]/);e.exports=o},46712:(e,t,n)=>{"use strict";var o=n(2841)(/[\dA-Za-z]/);e.exports=o},13571:(e,t,n)=>{"use strict";var o=n(2841)(/[#-'*+\--9=?A-Z^-~]/);e.exports=o},89696:e=>{"use strict";e.exports=function(e){return e<32||127===e}},73977:(e,t,n)=>{"use strict";var o=n(2841)(/\d/);e.exports=o},56238:(e,t,n)=>{"use strict";var o=n(2841)(/[\dA-Fa-f]/);e.exports=o},83074:(e,t,n)=>{"use strict";var o=n(2841)(/[!-/:-@[-`{-~]/);e.exports=o},88367:e=>{"use strict";e.exports=function(e){return e<0||32===e}},17238:e=>{"use strict";e.exports=function(e){return e<-2}},73654:e=>{"use strict";e.exports=function(e){return-2===e||-1===e||32===e}},36996:(e,t,n)=>{"use strict";var o=n(76830),r=n(2841)(o);e.exports=r},10395:(e,t,n)=>{"use strict";var o=n(2841)(/\s/);e.exports=o},99198:e=>{"use strict";var t=Object.assign;e.exports=t},93267:e=>{"use strict";var t=String.fromCharCode;e.exports=t},46706:e=>{"use strict";var t={}.hasOwnProperty;e.exports=t},57139:e=>{"use strict";e.exports=["address","article","aside","base","basefont","blockquote","body","caption","center","col","colgroup","dd","details","dialog","dir","div","dl","dt","fieldset","figcaption","figure","footer","form","frame","frameset","h1","h2","h3","h4","h5","h6","head","header","hr","html","iframe","legend","li","link","main","menu","menuitem","nav","noframes","ol","optgroup","option","p","param","section","source","summary","table","tbody","td","tfoot","th","thead","title","tr","track","ul"]},16871:e=>{"use strict";e.exports=["pre","script","style","textarea"]},21362:e=>{"use strict";var t=[].splice;e.exports=t},76830:e=>{"use strict";e.exports=/[!-\/:-@\[-`\{-~\xA1\xA7\xAB\xB6\xB7\xBB\xBF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061E\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u09FD\u0A76\u0AF0\u0C77\u0C84\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B60\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2010-\u2027\u2030-\u2043\u2045-\u2051\u2053-\u205E\u207D\u207E\u208D\u208E\u2308-\u230B\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E4F\u2E52\u3001-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65]/},36274:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});var o=n(97082),r=n(47542),i=n(1349),a=n(45485),s=n(49653),u=n(36713),c=n(46597),l=n(20431),d=n(60026),h=n(93865),p=n(65694),f=n(596),g=n(76872),m=n(28911),_=n(31294),F=n(36215),y=n(60534),b=n(92607),v=n(46931),w=n(15874),E=n(37039),k={42:v,43:v,45:v,48:v,49:v,50:v,51:v,52:v,53:v,54:v,55:v,56:v,57:v,62:a},D={91:h},S={"-2":l,"-1":l,32:l},x={35:f,42:E,45:[w,E],60:g,61:w,95:E,96:c,126:c},C={38:u,92:s},A={"-5":b,"-4":b,"-3":b,33:F,38:u,42:r,60:[i,m],91:y,92:[p,s],93:_,95:r,96:d},T={null:[r,o.resolver]};t.contentInitial=D,t.disable={null:[]},t.document=k,t.flow=x,t.flowInitial=S,t.insideSpan=T,t.string=C,t.text=A},13745:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});var o=n(17238),r=n(52928);t.tokenize=function(e){var t,n=e.attempt(this.parser.constructs.contentInitial,(function(t){if(null!==t)return e.enter("lineEnding"),e.consume(t),e.exit("lineEnding"),r(e,n,"linePrefix");e.consume(t)}),(function(t){return e.enter("paragraph"),i(t)}));return n;function i(n){var o=e.enter("chunkText",{contentType:"text",previous:t});return t&&(t.next=o),t=o,a(n)}function a(t){return null===t?(e.exit("chunkText"),e.exit("paragraph"),void e.consume(t)):o(t)?(e.consume(t),e.exit("chunkText"),i):(e.consume(t),a)}}},14201:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});var o=n(17238),r=n(52928),i=n(66532),a={tokenize:function(e,t,n){return r(e,e.attempt(this.parser.constructs.document,t,n),"linePrefix",this.parser.constructs.disable.null.indexOf("codeIndented")>-1?void 0:4)}},s={tokenize:function(e,t,n){return r(e,e.lazy(this.parser.constructs.flow,t,n),"linePrefix",this.parser.constructs.disable.null.indexOf("codeIndented")>-1?void 0:4)}};t.tokenize=function(e){var t,n,r,u=this,c=[],l=0,d={tokenize:function(e,o){var r=0;return t={},l;function l(o){return rt;)u.containerState=c[i][1],c[i][0].exit.call(u,e);c.length=t}}},22871:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});var o=n(64590),r=n(52928),i=n(66532);t.tokenize=function(e){var t=this,n=e.attempt(i,(function(o){if(null!==o)return e.enter("lineEndingBlank"),e.consume(o),e.exit("lineEndingBlank"),t.currentConstruct=void 0,n;e.consume(o)}),e.attempt(this.parser.constructs.flowInitial,a,r(e,e.attempt(this.parser.constructs.flow,a,e.attempt(o,a)),"linePrefix")));return n;function a(o){if(null!==o)return e.enter("lineEnding"),e.consume(o),e.exit("lineEnding"),t.currentConstruct=void 0,n;e.consume(o)}}},97082:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});var o=n(99198),r=n(75923),i=u("text"),a=u("string"),s={resolveAll:c()};function u(e){return{tokenize:function(t){var n=this,o=this.parser.constructs[e],r=t.attempt(o,i,a);return i;function i(e){return u(e)?r(e):a(e)}function a(e){if(null!==e)return t.enter("data"),t.consume(e),s;t.consume(e)}function s(e){return u(e)?(t.exit("data"),r(e)):(t.consume(e),s)}function u(e){var t=o[e],r=-1;if(null===e)return!0;if(t)for(;++r{"use strict";var o=n(13745),r=n(14201),i=n(22871),a=n(97082),s=n(12952),u=n(21388),c=n(28180),l=n(36274);e.exports=function(e){var t={defined:[],constructs:s([l].concat(c((e||{}).extensions))),content:n(o),document:n(r),flow:n(i),string:n(a.string),text:n(a.text)};return t;function n(e){return function(n){return u(t,e,n)}}}},61242:(e,t,n)=>{"use strict";var o=n(84423);e.exports=function(e){for(;!o(e););return e}},30162:e=>{"use strict";var t=/[\0\t\n\r]/g;e.exports=function(){var e,n=!0,o=1,r="";return function(i,a,s){var u,c,l,d,h,p=[];for(i=r+i.toString(a),l=0,r="",n&&(65279===i.charCodeAt(0)&&l++,n=void 0);l{"use strict";var o=n(78811),r=n(56808),i=n(19444),a=n(15644),s=n(58280),u=n(75923),c={name:"attention",tokenize:function(e,t){var n,o=i(this.previous);return function(t){return e.enter("attentionSequence"),n=t,r(t)};function r(a){var s,u,c,l;return a===n?(e.consume(a),r):(s=e.exit("attentionSequence"),c=!(u=i(a))||2===u&&o,l=!o||2===o&&u,s._open=42===n?c:c&&(o||!l),s._close=42===n?l:l&&(u||!c),t(a))}},resolveAll:function(e,t){for(var n,i,c,l,d,h,p,f,g=-1;++g1&&e[g][1].end.offset-e[g][1].start.offset>1?2:1)>1?"strongSequence":"emphasisSequence",start:a(u(e[n][1].end),-h),end:u(e[n][1].end)},d={type:h>1?"strongSequence":"emphasisSequence",start:u(e[g][1].start),end:a(u(e[g][1].start),h)},c={type:h>1?"strongText":"emphasisText",start:u(e[n][1].end),end:u(e[g][1].start)},i={type:h>1?"strong":"emphasis",start:u(l.start),end:u(d.end)},e[n][1].end=u(l.start),e[g][1].start=u(d.end),p=[],e[n][1].end.offset-e[n][1].start.offset&&(p=o(p,[["enter",e[n][1],t],["exit",e[n][1],t]])),p=o(p,[["enter",i,t],["enter",l,t],["exit",l,t],["enter",c,t]]),p=o(p,s(t.parser.constructs.insideSpan.null,e.slice(n+1,g),t)),p=o(p,[["exit",c,t],["enter",d,t],["exit",d,t],["exit",i,t]]),e[g][1].end.offset-e[g][1].start.offset?(f=2,p=o(p,[["enter",e[g][1],t],["exit",e[g][1],t]])):f=0,r(e,n-1,g-n+3,p),g=n+p.length-f-2;break}for(g=-1;++g{"use strict";var o=n(76734),r=n(46712),i=n(13571),a=n(89696),s={name:"autolink",tokenize:function(e,t,n){var s=1;return function(t){return e.enter("autolink"),e.enter("autolinkMarker"),e.consume(t),e.exit("autolinkMarker"),e.enter("autolinkProtocol"),u};function u(t){return o(t)?(e.consume(t),c):i(t)?h(t):n(t)}function c(e){return 43===e||45===e||46===e||r(e)?l(e):h(e)}function l(t){return 58===t?(e.consume(t),d):(43===t||45===t||46===t||r(t))&&s++<32?(e.consume(t),l):h(t)}function d(t){return 62===t?(e.exit("autolinkProtocol"),m(t)):32===t||60===t||a(t)?n(t):(e.consume(t),d)}function h(t){return 64===t?(e.consume(t),s=0,p):i(t)?(e.consume(t),h):n(t)}function p(e){return r(e)?f(e):n(e)}function f(t){return 46===t?(e.consume(t),s=0,p):62===t?(e.exit("autolinkProtocol").type="autolinkEmail",m(t)):g(t)}function g(t){return(45===t||r(t))&&s++<63?(e.consume(t),45===t?g:f):n(t)}function m(n){return e.enter("autolinkMarker"),e.consume(n),e.exit("autolinkMarker"),e.exit("autolink"),t}}};e.exports=s},45485:(e,t,n)=>{"use strict";var o=n(73654),r=n(52928),i={name:"blockQuote",tokenize:function(e,t,n){var r=this;return function(t){return 62===t?(r.containerState.open||(e.enter("blockQuote",{_container:!0}),r.containerState.open=!0),e.enter("blockQuotePrefix"),e.enter("blockQuoteMarker"),e.consume(t),e.exit("blockQuoteMarker"),i):n(t)};function i(n){return o(n)?(e.enter("blockQuotePrefixWhitespace"),e.consume(n),e.exit("blockQuotePrefixWhitespace"),e.exit("blockQuotePrefix"),t):(e.exit("blockQuotePrefix"),t(n))}},continuation:{tokenize:function(e,t,n){return r(e,e.attempt(i,t,n),"linePrefix",this.parser.constructs.disable.null.indexOf("codeIndented")>-1?void 0:4)}},exit:function(e){e.exit("blockQuote")}};e.exports=i},49653:(e,t,n)=>{"use strict";var o=n(83074),r={name:"characterEscape",tokenize:function(e,t,n){return function(t){return e.enter("characterEscape"),e.enter("escapeMarker"),e.consume(t),e.exit("escapeMarker"),r};function r(r){return o(r)?(e.enter("characterEscapeValue"),e.consume(r),e.exit("characterEscapeValue"),e.exit("characterEscape"),t):n(r)}}};e.exports=r},36713:(e,t,n)=>{"use strict";var o=n(89435),r=n(46712),i=n(73977),a=n(56238);function s(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var u=s(o),c={name:"characterReference",tokenize:function(e,t,n){var o,s,c=this,l=0;return function(t){return e.enter("characterReference"),e.enter("characterReferenceMarker"),e.consume(t),e.exit("characterReferenceMarker"),d};function d(t){return 35===t?(e.enter("characterReferenceMarkerNumeric"),e.consume(t),e.exit("characterReferenceMarkerNumeric"),h):(e.enter("characterReferenceValue"),o=31,s=r,p(t))}function h(t){return 88===t||120===t?(e.enter("characterReferenceMarkerHexadecimal"),e.consume(t),e.exit("characterReferenceMarkerHexadecimal"),e.enter("characterReferenceValue"),o=6,s=a,p):(e.enter("characterReferenceValue"),o=7,s=i,p(t))}function p(i){var a;return 59===i&&l?(a=e.exit("characterReferenceValue"),s!==r||u.default(c.sliceSerialize(a))?(e.enter("characterReferenceMarker"),e.consume(i),e.exit("characterReferenceMarker"),e.exit("characterReference"),t):n(i)):s(i)&&l++{"use strict";var o=n(17238),r=n(88367),i=n(15096),a=n(52928),s={name:"codeFenced",tokenize:function(e,t,n){var s,u=this,c={tokenize:function(e,t,n){var r=0;return a(e,(function(t){return e.enter("codeFencedFence"),e.enter("codeFencedFenceSequence"),i(t)}),"linePrefix",this.parser.constructs.disable.null.indexOf("codeIndented")>-1?void 0:4);function i(t){return t===s?(e.consume(t),r++,i):r{"use strict";var o=n(17238),r=n(56808),i=n(15096),a=n(52928),s={name:"codeIndented",tokenize:function(e,t,n){return e.attempt(u,r,n);function r(n){return null===n?t(n):o(n)?e.attempt(u,r,t)(n):(e.enter("codeFlowValue"),i(n))}function i(t){return null===t||o(t)?(e.exit("codeFlowValue"),r(t)):(e.consume(t),i)}},resolve:function(e,t){var n={type:"codeIndented",start:e[0][1].start,end:e[e.length-1][1].end};return r(e,0,0,[["enter",n,t]]),r(e,e.length,0,[["exit",n,t]]),e}},u={tokenize:function(e,t,n){var r=this;return a(e,(function s(u){return o(u)?(e.enter("lineEnding"),e.consume(u),e.exit("lineEnding"),a(e,s,"linePrefix",5)):i(r.events,"linePrefix")<4?n(u):t(u)}),"linePrefix",5)},partial:!0};e.exports=s},60026:(e,t,n)=>{"use strict";var o=n(17238),r={name:"codeText",tokenize:function(e,t,n){var r,i,a=0;return function(t){return e.enter("codeText"),e.enter("codeTextSequence"),s(t)};function s(t){return 96===t?(e.consume(t),a++,s):(e.exit("codeTextSequence"),u(t))}function u(t){return null===t?n(t):96===t?(i=e.enter("codeTextSequence"),r=0,l(t)):32===t?(e.enter("space"),e.consume(t),e.exit("space"),u):o(t)?(e.enter("lineEnding"),e.consume(t),e.exit("lineEnding"),u):(e.enter("codeTextData"),c(t))}function c(t){return null===t||32===t||96===t||o(t)?(e.exit("codeTextData"),u(t)):(e.consume(t),c)}function l(n){return 96===n?(e.consume(n),r++,l):r===a?(e.exit("codeTextSequence"),e.exit("codeText"),t(n)):(i.type="codeTextData",c(n))}},resolve:function(e){var t,n,o=e.length-4,r=3;if(!("lineEnding"!==e[r][1].type&&"space"!==e[r][1].type||"lineEnding"!==e[o][1].type&&"space"!==e[o][1].type))for(t=r;++t{"use strict";var o=n(17238),r=n(15096),i=n(84423),a=n(52928),s={tokenize:function(e,t){var n;return function(t){return e.enter("content"),n=e.enter("chunkContent",{contentType:"content"}),r(t)};function r(t){return null===t?i(t):o(t)?e.check(u,a,i)(t):(e.consume(t),r)}function i(n){return e.exit("chunkContent"),e.exit("content"),t(n)}function a(t){return e.consume(t),e.exit("chunkContent"),n=n.next=e.enter("chunkContent",{contentType:"content",previous:n}),r}},resolve:function(e){return i(e),e},interruptible:!0,lazy:!0},u={tokenize:function(e,t,n){var i=this;return function(t){return e.enter("lineEnding"),e.consume(t),e.exit("lineEnding"),a(e,s,"linePrefix")};function s(a){return null===a||o(a)?n(a):i.parser.constructs.disable.null.indexOf("codeIndented")>-1||r(i.events,"linePrefix")<4?e.interrupt(i.parser.constructs.flow,n,t)(a):t(a)}},partial:!0};e.exports=s},93865:(e,t,n)=>{"use strict";var o=n(17238),r=n(88367),i=n(35478),a=n(38229),s=n(97154),u=n(52928),c=n(31056),l=n(59283),d={name:"definition",tokenize:function(e,t,n){var r,l=this;return function(t){return e.enter("definition"),s.call(l,e,d,n,"definitionLabel","definitionLabelMarker","definitionLabelString")(t)};function d(t){return r=i(l.sliceSerialize(l.events[l.events.length-1][1]).slice(1,-1)),58===t?(e.enter("definitionMarker"),e.consume(t),e.exit("definitionMarker"),c(e,a(e,e.attempt(h,u(e,p,"whitespace"),u(e,p,"whitespace")),n,"definitionDestination","definitionDestinationLiteral","definitionDestinationLiteralMarker","definitionDestinationRaw","definitionDestinationString"))):n(t)}function p(i){return null===i||o(i)?(e.exit("definition"),l.parser.defined.indexOf(r)<0&&l.parser.defined.push(r),t(i)):n(i)}}},h={tokenize:function(e,t,n){return function(t){return r(t)?c(e,i)(t):n(t)};function i(t){return 34===t||39===t||40===t?l(e,u(e,a,"whitespace"),n,"definitionTitle","definitionTitleMarker","definitionTitleString")(t):n(t)}function a(e){return null===e||o(e)?t(e):n(e)}},partial:!0};e.exports=d},38229:(e,t,n)=>{"use strict";var o=n(89696),r=n(88367),i=n(17238);e.exports=function(e,t,n,a,s,u,c,l,d){var h=d||1/0,p=0;return function(t){return 60===t?(e.enter(a),e.enter(s),e.enter(u),e.consume(t),e.exit(u),f):o(t)||41===t?n(t):(e.enter(a),e.enter(c),e.enter(l),e.enter("chunkString",{contentType:"string"}),_(t))};function f(n){return 62===n?(e.enter(u),e.consume(n),e.exit(u),e.exit(s),e.exit(a),t):(e.enter(l),e.enter("chunkString",{contentType:"string"}),g(n))}function g(t){return 62===t?(e.exit("chunkString"),e.exit(l),f(t)):null===t||60===t||i(t)?n(t):(e.consume(t),92===t?m:g)}function m(t){return 60===t||62===t||92===t?(e.consume(t),g):g(t)}function _(i){return 40===i?++p>h?n(i):(e.consume(i),_):41===i?p--?(e.consume(i),_):(e.exit("chunkString"),e.exit(l),e.exit(c),e.exit(a),t(i)):null===i||r(i)?p?n(i):(e.exit("chunkString"),e.exit(l),e.exit(c),e.exit(a),t(i)):o(i)?n(i):(e.consume(i),92===i?F:_)}function F(t){return 40===t||41===t||92===t?(e.consume(t),_):_(t)}}},97154:(e,t,n)=>{"use strict";var o=n(17238),r=n(73654);e.exports=function(e,t,n,i,a,s){var u,c=this,l=0;return function(t){return e.enter(i),e.enter(a),e.consume(t),e.exit(a),e.enter(s),d};function d(r){return null===r||91===r||93===r&&!u||94===r&&!l&&"_hiddenFootnoteSupport"in c.parser.constructs||l>999?n(r):93===r?(e.exit(s),e.enter(a),e.consume(r),e.exit(a),e.exit(i),t):o(r)?(e.enter("lineEnding"),e.consume(r),e.exit("lineEnding"),d):(e.enter("chunkString",{contentType:"string"}),h(r))}function h(t){return null===t||91===t||93===t||o(t)||l++>999?(e.exit("chunkString"),d(t)):(e.consume(t),u=u||!r(t),92===t?p:h)}function p(t){return 91===t||92===t||93===t?(e.consume(t),l++,h):h(t)}}},52928:(e,t,n)=>{"use strict";var o=n(73654);e.exports=function(e,t,n,r){var i=r?r-1:1/0,a=0;return function(r){return o(r)?(e.enter(n),s(r)):t(r)};function s(r){return o(r)&&a++{"use strict";var o=n(17238),r=n(52928);e.exports=function(e,t,n,i,a,s){var u;return function(t){return e.enter(i),e.enter(a),e.consume(t),e.exit(a),u=40===t?41:t,c};function c(n){return n===u?(e.enter(a),e.consume(n),e.exit(a),e.exit(i),t):(e.enter(s),l(n))}function l(t){return t===u?(e.exit(s),c(u)):null===t?n(t):o(t)?(e.enter("lineEnding"),e.consume(t),e.exit("lineEnding"),r(e,l,"linePrefix")):(e.enter("chunkString",{contentType:"string"}),d(t))}function d(t){return t===u||null===t||o(t)?(e.exit("chunkString"),l(t)):(e.consume(t),92===t?h:d)}function h(t){return t===u||92===t?(e.consume(t),d):d(t)}}},31056:(e,t,n)=>{"use strict";var o=n(17238),r=n(73654),i=n(52928);e.exports=function(e,t){var n;return function a(s){return o(s)?(e.enter("lineEnding"),e.consume(s),e.exit("lineEnding"),n=!0,a):r(s)?i(e,a,n?"linePrefix":"lineSuffix")(s):t(s)}}},65694:(e,t,n)=>{"use strict";var o=n(17238),r={name:"hardBreakEscape",tokenize:function(e,t,n){return function(t){return e.enter("hardBreakEscape"),e.enter("escapeMarker"),e.consume(t),r};function r(r){return o(r)?(e.exit("escapeMarker"),e.exit("hardBreakEscape"),t(r)):n(r)}}};e.exports=r},596:(e,t,n)=>{"use strict";var o=n(17238),r=n(88367),i=n(73654),a=n(56808),s=n(52928),u={name:"headingAtx",tokenize:function(e,t,n){var a=this,u=0;return function(t){return e.enter("atxHeading"),e.enter("atxHeadingSequence"),c(t)};function c(o){return 35===o&&u++<6?(e.consume(o),c):null===o||r(o)?(e.exit("atxHeadingSequence"),a.interrupt?t(o):l(o)):n(o)}function l(n){return 35===n?(e.enter("atxHeadingSequence"),d(n)):null===n||o(n)?(e.exit("atxHeading"),t(n)):i(n)?s(e,l,"whitespace")(n):(e.enter("atxHeadingText"),h(n))}function d(t){return 35===t?(e.consume(t),d):(e.exit("atxHeadingSequence"),l(t))}function h(t){return null===t||35===t||r(t)?(e.exit("atxHeadingText"),l(t)):(e.consume(t),h)}},resolve:function(e,t){var n,o,r=e.length-2,i=3;return"whitespace"===e[i][1].type&&(i+=2),r-2>i&&"whitespace"===e[r][1].type&&(r-=2),"atxHeadingSequence"===e[r][1].type&&(i===r-1||r-4>i&&"whitespace"===e[r-2][1].type)&&(r-=i+1===r?2:4),r>i&&(n={type:"atxHeadingText",start:e[i][1].start,end:e[r][1].end},o={type:"chunkText",start:e[i][1].start,end:e[r][1].end,contentType:"text"},a(e,i,r-i+1,[["enter",n,t],["enter",o,t],["exit",o,t],["exit",n,t]])),e}};e.exports=u},76872:(e,t,n)=>{"use strict";var o=n(76734),r=n(46712),i=n(17238),a=n(88367),s=n(73654),u=n(93267),c=n(57139),l=n(16871),d=n(66532),h={name:"htmlFlow",tokenize:function(e,t,n){var d,h,f,g,m,_=this;return function(t){return e.enter("htmlFlow"),e.enter("htmlFlowData"),e.consume(t),F};function F(r){return 33===r?(e.consume(r),y):47===r?(e.consume(r),w):63===r?(e.consume(r),d=3,_.interrupt?t:z):o(r)?(e.consume(r),f=u(r),h=!0,E):n(r)}function y(r){return 45===r?(e.consume(r),d=2,b):91===r?(e.consume(r),d=5,f="CDATA[",g=0,v):o(r)?(e.consume(r),d=4,_.interrupt?t:z):n(r)}function b(o){return 45===o?(e.consume(o),_.interrupt?t:z):n(o)}function v(o){return o===f.charCodeAt(g++)?(e.consume(o),g===f.length?_.interrupt?t:B:v):n(o)}function w(t){return o(t)?(e.consume(t),f=u(t),E):n(t)}function E(o){return null===o||47===o||62===o||a(o)?47!==o&&h&&l.indexOf(f.toLowerCase())>-1?(d=1,_.interrupt?t(o):B(o)):c.indexOf(f.toLowerCase())>-1?(d=6,47===o?(e.consume(o),k):_.interrupt?t(o):B(o)):(d=7,_.interrupt?n(o):h?S(o):D(o)):45===o||r(o)?(e.consume(o),f+=u(o),E):n(o)}function k(o){return 62===o?(e.consume(o),_.interrupt?t:B):n(o)}function D(t){return s(t)?(e.consume(t),D):M(t)}function S(t){return 47===t?(e.consume(t),M):58===t||95===t||o(t)?(e.consume(t),x):s(t)?(e.consume(t),S):M(t)}function x(t){return 45===t||46===t||58===t||95===t||r(t)?(e.consume(t),x):C(t)}function C(t){return 61===t?(e.consume(t),A):s(t)?(e.consume(t),C):S(t)}function A(t){return null===t||60===t||61===t||62===t||96===t?n(t):34===t||39===t?(e.consume(t),m=t,T):s(t)?(e.consume(t),A):(m=void 0,R(t))}function T(t){return t===m?(e.consume(t),I):null===t||i(t)?n(t):(e.consume(t),T)}function R(t){return null===t||34===t||39===t||60===t||61===t||62===t||96===t||a(t)?C(t):(e.consume(t),R)}function I(e){return 47===e||62===e||s(e)?S(e):n(e)}function M(t){return 62===t?(e.consume(t),O):n(t)}function O(t){return s(t)?(e.consume(t),O):null===t||i(t)?B(t):n(t)}function B(t){return 45===t&&2===d?(e.consume(t),P):60===t&&1===d?(e.consume(t),U):62===t&&4===d?(e.consume(t),K):63===t&&3===d?(e.consume(t),z):93===t&&5===d?(e.consume(t),q):!i(t)||6!==d&&7!==d?null===t||i(t)?N(t):(e.consume(t),B):e.check(p,K,N)(t)}function N(t){return e.exit("htmlFlowData"),L(t)}function L(t){return null===t?G(t):i(t)?(e.enter("lineEnding"),e.consume(t),e.exit("lineEnding"),L):(e.enter("htmlFlowData"),B(t))}function P(t){return 45===t?(e.consume(t),z):B(t)}function U(t){return 47===t?(e.consume(t),f="",j):B(t)}function j(t){return 62===t&&l.indexOf(f.toLowerCase())>-1?(e.consume(t),K):o(t)&&f.length<8?(e.consume(t),f+=u(t),j):B(t)}function q(t){return 93===t?(e.consume(t),z):B(t)}function z(t){return 62===t?(e.consume(t),K):B(t)}function K(t){return null===t||i(t)?(e.exit("htmlFlowData"),G(t)):(e.consume(t),K)}function G(n){return e.exit("htmlFlow"),t(n)}},resolveTo:function(e){for(var t=e.length;t--&&("enter"!==e[t][0]||"htmlFlow"!==e[t][1].type););return t>1&&"linePrefix"===e[t-2][1].type&&(e[t][1].start=e[t-2][1].start,e[t+1][1].start=e[t-2][1].start,e.splice(t-2,2)),e},concrete:!0},p={tokenize:function(e,t,n){return function(o){return e.exit("htmlFlowData"),e.enter("lineEndingBlank"),e.consume(o),e.exit("lineEndingBlank"),e.attempt(d,t,n)}},partial:!0};e.exports=h},28911:(e,t,n)=>{"use strict";var o=n(76734),r=n(46712),i=n(17238),a=n(88367),s=n(73654),u=n(52928),c={name:"htmlText",tokenize:function(e,t,n){var c,l,d,h,p=this;return function(t){return e.enter("htmlText"),e.enter("htmlTextData"),e.consume(t),f};function f(t){return 33===t?(e.consume(t),g):47===t?(e.consume(t),C):63===t?(e.consume(t),S):o(t)?(e.consume(t),R):n(t)}function g(t){return 45===t?(e.consume(t),m):91===t?(e.consume(t),l="CDATA[",d=0,v):o(t)?(e.consume(t),D):n(t)}function m(t){return 45===t?(e.consume(t),_):n(t)}function _(t){return null===t||62===t?n(t):45===t?(e.consume(t),F):y(t)}function F(e){return null===e||62===e?n(e):y(e)}function y(t){return null===t?n(t):45===t?(e.consume(t),b):i(t)?(h=y,U(t)):(e.consume(t),y)}function b(t){return 45===t?(e.consume(t),q):y(t)}function v(t){return t===l.charCodeAt(d++)?(e.consume(t),d===l.length?w:v):n(t)}function w(t){return null===t?n(t):93===t?(e.consume(t),E):i(t)?(h=w,U(t)):(e.consume(t),w)}function E(t){return 93===t?(e.consume(t),k):w(t)}function k(t){return 62===t?q(t):93===t?(e.consume(t),k):w(t)}function D(t){return null===t||62===t?q(t):i(t)?(h=D,U(t)):(e.consume(t),D)}function S(t){return null===t?n(t):63===t?(e.consume(t),x):i(t)?(h=S,U(t)):(e.consume(t),S)}function x(e){return 62===e?q(e):S(e)}function C(t){return o(t)?(e.consume(t),A):n(t)}function A(t){return 45===t||r(t)?(e.consume(t),A):T(t)}function T(t){return i(t)?(h=T,U(t)):s(t)?(e.consume(t),T):q(t)}function R(t){return 45===t||r(t)?(e.consume(t),R):47===t||62===t||a(t)?I(t):n(t)}function I(t){return 47===t?(e.consume(t),q):58===t||95===t||o(t)?(e.consume(t),M):i(t)?(h=I,U(t)):s(t)?(e.consume(t),I):q(t)}function M(t){return 45===t||46===t||58===t||95===t||r(t)?(e.consume(t),M):O(t)}function O(t){return 61===t?(e.consume(t),B):i(t)?(h=O,U(t)):s(t)?(e.consume(t),O):I(t)}function B(t){return null===t||60===t||61===t||62===t||96===t?n(t):34===t||39===t?(e.consume(t),c=t,N):i(t)?(h=B,U(t)):s(t)?(e.consume(t),B):(e.consume(t),c=void 0,P)}function N(t){return t===c?(e.consume(t),L):null===t?n(t):i(t)?(h=N,U(t)):(e.consume(t),N)}function L(e){return 62===e||47===e||a(e)?I(e):n(e)}function P(t){return null===t||34===t||39===t||60===t||61===t||96===t?n(t):62===t||a(t)?I(t):(e.consume(t),P)}function U(t){return e.exit("htmlTextData"),e.enter("lineEnding"),e.consume(t),e.exit("lineEnding"),u(e,j,"linePrefix",p.parser.constructs.disable.null.indexOf("codeIndented")>-1?void 0:4)}function j(t){return e.enter("htmlTextData"),h(t)}function q(o){return 62===o?(e.consume(o),e.exit("htmlTextData"),e.exit("htmlText"),t):n(o)}}};e.exports=c},31294:(e,t,n)=>{"use strict";var o=n(88367),r=n(78811),i=n(56808),a=n(35478),s=n(58280),u=n(75923),c=n(38229),l=n(97154),d=n(59283),h=n(31056),p={name:"labelEnd",tokenize:function(e,t,n){for(var o,r,i=this,s=i.events.length;s--;)if(("labelImage"===i.events[s][1].type||"labelLink"===i.events[s][1].type)&&!i.events[s][1]._balanced){o=i.events[s][1];break}return function(t){return o?o._inactive?c(t):(r=i.parser.defined.indexOf(a(i.sliceSerialize({start:o.end,end:i.now()})))>-1,e.enter("labelEnd"),e.enter("labelMarker"),e.consume(t),e.exit("labelMarker"),e.exit("labelEnd"),u):n(t)};function u(n){return 40===n?e.attempt(f,t,r?t:c)(n):91===n?e.attempt(g,t,r?e.attempt(m,t,c):c)(n):r?t(n):c(n)}function c(e){return o._balanced=!0,n(e)}},resolveTo:function(e,t){for(var n,o,a,c,l,d,h,p=e.length,f=0;p--;)if(c=e[p][1],l){if("link"===c.type||"labelLink"===c.type&&c._inactive)break;"enter"===e[p][0]&&"labelLink"===c.type&&(c._inactive=!0)}else if(d){if("enter"===e[p][0]&&("labelImage"===c.type||"labelLink"===c.type)&&!c._balanced&&(l=p,"labelLink"!==c.type)){f=2;break}}else"labelEnd"===c.type&&(d=p);return n={type:"labelLink"===e[l][1].type?"link":"image",start:u(e[l][1].start),end:u(e[e.length-1][1].end)},o={type:"label",start:u(e[l][1].start),end:u(e[d][1].end)},a={type:"labelText",start:u(e[l+f+2][1].end),end:u(e[d-2][1].start)},h=r(h=[["enter",n,t],["enter",o,t]],e.slice(l+1,l+f+3)),h=r(h,[["enter",a,t]]),h=r(h,s(t.parser.constructs.insideSpan.null,e.slice(l+f+4,d-3),t)),h=r(h,[["exit",a,t],e[d-2],e[d-1],["exit",o,t]]),h=r(h,e.slice(d+1)),h=r(h,[["exit",n,t]]),i(e,l,e.length,h),e},resolveAll:function(e){for(var t,n=-1;++n{"use strict";var o={name:"labelStartImage",tokenize:function(e,t,n){var o=this;return function(t){return e.enter("labelImage"),e.enter("labelImageMarker"),e.consume(t),e.exit("labelImageMarker"),r};function r(t){return 91===t?(e.enter("labelMarker"),e.consume(t),e.exit("labelMarker"),e.exit("labelImage"),i):n(t)}function i(e){return 94===e&&"_hiddenFootnoteSupport"in o.parser.constructs?n(e):t(e)}},resolveAll:n(31294).resolveAll};e.exports=o},60534:(e,t,n)=>{"use strict";var o={name:"labelStartLink",tokenize:function(e,t,n){var o=this;return function(t){return e.enter("labelLink"),e.enter("labelMarker"),e.consume(t),e.exit("labelMarker"),e.exit("labelLink"),r};function r(e){return 94===e&&"_hiddenFootnoteSupport"in o.parser.constructs?n(e):t(e)}},resolveAll:n(31294).resolveAll};e.exports=o},92607:(e,t,n)=>{"use strict";var o=n(52928),r={name:"lineEnding",tokenize:function(e,t){return function(n){return e.enter("lineEnding"),e.consume(n),e.exit("lineEnding"),o(e,t,"linePrefix")}}};e.exports=r},46931:(e,t,n)=>{"use strict";var o=n(73977),r=n(73654),i=n(15096),a=n(18892),s=n(52928),u=n(66532),c=n(37039),l={name:"list",tokenize:function(e,t,n){var s=this,l=i(s.events,"linePrefix"),h=0;return function(t){var r=s.containerState.type||(42===t||43===t||45===t?"listUnordered":"listOrdered");if("listUnordered"===r?!s.containerState.marker||t===s.containerState.marker:o(t)){if(s.containerState.type||(s.containerState.type=r,e.enter(r,{_container:!0})),"listUnordered"===r)return e.enter("listItemPrefix"),42===t||45===t?e.check(c,n,f)(t):f(t);if(!s.interrupt||49===t)return e.enter("listItemPrefix"),e.enter("listItemValue"),p(t)}return n(t)};function p(t){return o(t)&&++h<10?(e.consume(t),p):(!s.interrupt||h<2)&&(s.containerState.marker?t===s.containerState.marker:41===t||46===t)?(e.exit("listItemValue"),f(t)):n(t)}function f(t){return e.enter("listItemMarker"),e.consume(t),e.exit("listItemMarker"),s.containerState.marker=s.containerState.marker||t,e.check(u,s.interrupt?n:g,e.attempt(d,_,m))}function g(e){return s.containerState.initialBlankLine=!0,l++,_(e)}function m(t){return r(t)?(e.enter("listItemPrefixWhitespace"),e.consume(t),e.exit("listItemPrefixWhitespace"),_):n(t)}function _(n){return s.containerState.size=l+a(s.sliceStream(e.exit("listItemPrefix"))),t(n)}},continuation:{tokenize:function(e,t,n){var o=this;return o.containerState._closeFlow=void 0,e.check(u,(function(n){return o.containerState.furtherBlankLines=o.containerState.furtherBlankLines||o.containerState.initialBlankLine,s(e,t,"listItemIndent",o.containerState.size+1)(n)}),(function(n){return o.containerState.furtherBlankLines||!r(n)?(o.containerState.furtherBlankLines=o.containerState.initialBlankLine=void 0,i(n)):(o.containerState.furtherBlankLines=o.containerState.initialBlankLine=void 0,e.attempt(h,t,i)(n))}));function i(r){return o.containerState._closeFlow=!0,o.interrupt=void 0,s(e,e.attempt(l,t,n),"linePrefix",o.parser.constructs.disable.null.indexOf("codeIndented")>-1?void 0:4)(r)}}},exit:function(e){e.exit(this.containerState.type)}},d={tokenize:function(e,t,n){var o=this;return s(e,(function(e){return r(e)||!i(o.events,"listItemPrefixWhitespace")?n(e):t(e)}),"listItemPrefixWhitespace",o.parser.constructs.disable.null.indexOf("codeIndented")>-1?void 0:5)},partial:!0},h={tokenize:function(e,t,n){var o=this;return s(e,(function(e){return i(o.events,"listItemIndent")===o.containerState.size?t(e):n(e)}),"listItemIndent",o.containerState.size+1)},partial:!0};e.exports=l},66532:(e,t,n)=>{"use strict";var o=n(17238),r=n(52928),i={tokenize:function(e,t,n){return r(e,(function(e){return null===e||o(e)?t(e):n(e)}),"linePrefix")},partial:!0};e.exports=i},15874:(e,t,n)=>{"use strict";var o=n(17238),r=n(75923),i=n(52928),a={name:"setextUnderline",tokenize:function(e,t,n){for(var r,a,s=this,u=s.events.length;u--;)if("lineEnding"!==s.events[u][1].type&&"linePrefix"!==s.events[u][1].type&&"content"!==s.events[u][1].type){a="paragraph"===s.events[u][1].type;break}return function(t){return s.lazy||!s.interrupt&&!a?n(t):(e.enter("setextHeadingLine"),e.enter("setextHeadingLineSequence"),r=t,c(t))};function c(t){return t===r?(e.consume(t),c):(e.exit("setextHeadingLineSequence"),i(e,l,"lineSuffix")(t))}function l(r){return null===r||o(r)?(e.exit("setextHeadingLine"),t(r)):n(r)}},resolveTo:function(e,t){for(var n,o,i,a,s=e.length;s--;)if("enter"===e[s][0]){if("content"===e[s][1].type){n=s;break}"paragraph"===e[s][1].type&&(o=s)}else"content"===e[s][1].type&&e.splice(s,1),i||"definition"!==e[s][1].type||(i=s);return a={type:"setextHeading",start:r(e[o][1].start),end:r(e[e.length-1][1].end)},e[o][1].type="setextHeadingText",i?(e.splice(o,0,["enter",a,t]),e.splice(i+1,0,["exit",e[n][1],t]),e[n][1].end=r(e[i][1].end)):e[n][1]=a,e.push(["exit",a,t]),e}};e.exports=a},37039:(e,t,n)=>{"use strict";var o=n(17238),r=n(73654),i=n(52928),a={name:"thematicBreak",tokenize:function(e,t,n){var a,s=0;return function(t){return e.enter("thematicBreak"),a=t,u(t)};function u(l){return l===a?(e.enter("thematicBreakSequence"),c(l)):r(l)?i(e,u,"whitespace")(l):s<3||null!==l&&!o(l)?n(l):(e.exit("thematicBreak"),t(l))}function c(t){return t===a?(e.consume(t),s++,c):(e.exit("thematicBreakSequence"),u(t))}}};e.exports=a},78811:(e,t,n)=>{"use strict";var o=n(56808);e.exports=function(e,t){return e.length?(o(e,e.length,0,t),e):t}},56808:(e,t,n)=>{"use strict";var o=n(21362);e.exports=function(e,t,n,r){var i,a=e.length,s=0;if(t=t<0?-t>a?0:a+t:t>a?a:t,n=n>0?n:0,r.length<1e4)(i=Array.from(r)).unshift(t,n),o.apply(e,i);else for(n&&o.apply(e,[t,n]);s{"use strict";var o=n(88367),r=n(36996),i=n(10395);e.exports=function(e){return null===e||o(e)||i(e)?1:r(e)?2:void 0}},12952:(e,t,n)=>{"use strict";var o=n(46706),r=n(56808),i=n(28180);function a(e,t){var n,r,a,u;for(n in t)for(u in r=o.call(e,n)?e[n]:e[n]={},a=t[n])r[u]=s(i(a[u]),o.call(r,u)?r[u]:[])}function s(e,t){for(var n=-1,o=[];++n{"use strict";var o=n(99198),r=n(17238),i=n(78811),a=n(56808),s=n(28180),u=n(58280),c=n(23082),l=n(75923),d=n(12774);e.exports=function(e,t,n){var h=n?l(n):{line:1,column:1,offset:0},p={},f=[],g=[],m=[],_={consume:function(e){r(e)?(h.line++,h.column=1,h.offset+=-3===e?2:1,S()):-1!==e&&(h.column++,h.offset++),h._bufferIndex<0?h._index++:(h._bufferIndex++,h._bufferIndex===g[h._index].length&&(h._bufferIndex=-1,h._index++)),F.previous=e},enter:function(e,t){var n=t||{};return n.type=e,n.start=v(),F.events.push(["enter",n,F]),m.push(n),n},exit:function(e){var t=m.pop();return t.end=v(),F.events.push(["exit",t,F]),t},attempt:k((function(e,t){D(e,t.from)})),check:k(E),interrupt:k(E,{interrupt:!0}),lazy:k(E,{lazy:!0})},F={previous:null,events:[],parser:e,sliceStream:b,sliceSerialize:function(e){return c(b(e))},now:v,defineSkip:function(e){p[e.line]=e.column,S()},write:function(e){return g=i(g,e),function(){for(var e,t;h._index-1?g():e.tokenize.call(t?o({},F,t):F,_,f,g)(n)}}function f(t){return e(c,l),r}function g(e){return l.restore(),++u{"use strict";e.exports=function(e){return null==e?[]:"length"in e?e:[e]}},15644:e=>{"use strict";e.exports=function(e,t){return e.column+=t,e.offset+=t,e._bufferIndex+=t,e}},35478:e=>{"use strict";e.exports=function(e){return e.replace(/[\t\n\r ]+/g," ").replace(/^ | $/g,"").toLowerCase().toUpperCase()}},15096:(e,t,n)=>{"use strict";var o=n(18892);e.exports=function(e,t){var n=e[e.length-1];return n&&n[1].type===t?o(n[2].sliceStream(n[1])):0}},2841:(e,t,n)=>{"use strict";var o=n(93267);e.exports=function(e){return function(t){return e.test(o(t))}}},58280:e=>{"use strict";e.exports=function(e,t,n){for(var o,r=[],i=-1;++i{"use strict";var o=n(93267);e.exports=function(e,t){var n=parseInt(e,t);return n<9||11===n||n>13&&n<32||n>126&&n<160||n>55295&&n<57344||n>64975&&n<65008||65535==(65535&n)||65534==(65535&n)||n>1114111?"�":o(n)}},23082:(e,t,n)=>{"use strict";var o=n(93267);e.exports=function(e){for(var t,n,r,i=-1,a=[];++i{"use strict";var o=n(99198);e.exports=function(e){return o({},e)}},18892:e=>{"use strict";e.exports=function(e){for(var t=-1,n=0;++t{"use strict";e.exports=function(e,t){var n,o=t.start._index,r=t.start._bufferIndex,i=t.end._index,a=t.end._bufferIndex;return o===i?n=[e[o].slice(r,a)]:(n=e.slice(o,i),r>-1&&(n[0]=n[0].slice(r)),a>0&&n.push(e[i].slice(0,a))),n}},84423:(e,t,n)=>{"use strict";var o=n(99198),r=n(56808),i=n(75923);function a(e,t){for(var n,o,i,a,s,u,c=e[t][1],l=e[t][2],d=t-1,h=[],p=c._tokenizer||l.parser[c.contentType](c.start),f=p.events,g=[],m={};c;){for(;e[++d][1]!==c;);h.push(d),c._tokenizer||(n=l.sliceStream(c),c.next||n.push(null),o&&p.defineSkip(c.start),c.isInFirstContentOfListItem&&(p._gfmTasklistFirstContentOfListItem=!0),p.write(n),c.isInFirstContentOfListItem&&(p._gfmTasklistFirstContentOfListItem=void 0)),o=c,c=c.next}for(c=o,i=f.length;i--;)"enter"===f[i][0]?a=!0:a&&f[i][1].type===f[i-1][1].type&&f[i][1].start.line!==f[i][1].end.line&&(_(f.slice(i+1,s)),c._tokenizer=c.next=void 0,c=c.previous,s=i+1);for(p.events=c._tokenizer=c.next=void 0,_(f.slice(0,s)),i=-1,u=0;++i{var o=n(96240),r=n(29931);function i(e){this.rand=e||new r.Rand}e.exports=i,i.create=function(e){return new i(e)},i.prototype._randbelow=function(e){var t=e.bitLength(),n=Math.ceil(t/8);do{var r=new o(this.rand.generate(n))}while(r.cmp(e)>=0);return r},i.prototype._randrange=function(e,t){var n=t.sub(e);return e.add(this._randbelow(n))},i.prototype.test=function(e,t,n){var r=e.bitLength(),i=o.mont(e),a=new o(1).toRed(i);t||(t=Math.max(1,r/48|0));for(var s=e.subn(1),u=0;!s.testn(u);u++);for(var c=e.shrn(u),l=s.toRed(i);t>0;t--){var d=this._randrange(new o(2),s);n&&n(d);var h=d.toRed(i).redPow(c);if(0!==h.cmp(a)&&0!==h.cmp(l)){for(var p=1;p0;t--){var l=this._randrange(new o(2),a),d=e.gcd(l);if(0!==d.cmpn(1))return d;var h=l.toRed(r).redPow(u);if(0!==h.cmp(i)&&0!==h.cmp(c)){for(var p=1;p=65&&n<=70?n-55:n>=97&&n<=102?n-87:n-48&15}function u(e,t,n){var o=s(e,n);return n-1>=t&&(o|=s(e,n-1)<<4),o}function c(e,t,n,o){for(var r=0,i=Math.min(e.length,n),a=t;a=49?s-49+10:s>=17?s-17+10:s}return r}i.isBN=function(e){return e instanceof i||null!==e&&"object"==typeof e&&e.constructor.wordSize===i.wordSize&&Array.isArray(e.words)},i.max=function(e,t){return e.cmp(t)>0?e:t},i.min=function(e,t){return e.cmp(t)<0?e:t},i.prototype._init=function(e,t,n){if("number"==typeof e)return this._initNumber(e,t,n);if("object"==typeof e)return this._initArray(e,t,n);"hex"===t&&(t=16),o(t===(0|t)&&t>=2&&t<=36);var r=0;"-"===(e=e.toString().replace(/\s+/g,""))[0]&&(r++,this.negative=1),r=0;r-=3)a=e[r]|e[r-1]<<8|e[r-2]<<16,this.words[i]|=a<>>26-s&67108863,(s+=24)>=26&&(s-=26,i++);else if("le"===n)for(r=0,i=0;r>>26-s&67108863,(s+=24)>=26&&(s-=26,i++);return this.strip()},i.prototype._parseHex=function(e,t,n){this.length=Math.ceil((e.length-t)/6),this.words=new Array(this.length);for(var o=0;o=t;o-=2)r=u(e,t,o)<=18?(i-=18,a+=1,this.words[a]|=r>>>26):i+=8;else for(o=(e.length-t)%2==0?t+1:t;o=18?(i-=18,a+=1,this.words[a]|=r>>>26):i+=8;this.strip()},i.prototype._parseBase=function(e,t,n){this.words=[0],this.length=1;for(var o=0,r=1;r<=67108863;r*=t)o++;o--,r=r/t|0;for(var i=e.length-n,a=i%o,s=Math.min(i,i-a)+n,u=0,l=n;l1&&0===this.words[this.length-1];)this.length--;return this._normSign()},i.prototype._normSign=function(){return 1===this.length&&0===this.words[0]&&(this.negative=0),this},i.prototype.inspect=function(){return(this.red?""};var l=["","0","00","000","0000","00000","000000","0000000","00000000","000000000","0000000000","00000000000","000000000000","0000000000000","00000000000000","000000000000000","0000000000000000","00000000000000000","000000000000000000","0000000000000000000","00000000000000000000","000000000000000000000","0000000000000000000000","00000000000000000000000","000000000000000000000000","0000000000000000000000000"],d=[0,0,25,16,12,11,10,9,8,8,7,7,7,7,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5],h=[0,0,33554432,43046721,16777216,48828125,60466176,40353607,16777216,43046721,1e7,19487171,35831808,62748517,7529536,11390625,16777216,24137569,34012224,47045881,64e6,4084101,5153632,6436343,7962624,9765625,11881376,14348907,17210368,20511149,243e5,28629151,33554432,39135393,45435424,52521875,60466176];function p(e,t,n){n.negative=t.negative^e.negative;var o=e.length+t.length|0;n.length=o,o=o-1|0;var r=0|e.words[0],i=0|t.words[0],a=r*i,s=67108863&a,u=a/67108864|0;n.words[0]=s;for(var c=1;c>>26,d=67108863&u,h=Math.min(c,t.length-1),p=Math.max(0,c-e.length+1);p<=h;p++){var f=c-p|0;l+=(a=(r=0|e.words[f])*(i=0|t.words[p])+d)/67108864|0,d=67108863&a}n.words[c]=0|d,u=0|l}return 0!==u?n.words[c]=0|u:n.length--,n.strip()}i.prototype.toString=function(e,t){var n;if(t=0|t||1,16===(e=e||10)||"hex"===e){n="";for(var r=0,i=0,a=0;a>>24-r&16777215)||a!==this.length-1?l[6-u.length]+u+n:u+n,(r+=2)>=26&&(r-=26,a--)}for(0!==i&&(n=i.toString(16)+n);n.length%t!=0;)n="0"+n;return 0!==this.negative&&(n="-"+n),n}if(e===(0|e)&&e>=2&&e<=36){var c=d[e],p=h[e];n="";var f=this.clone();for(f.negative=0;!f.isZero();){var g=f.modn(p).toString(e);n=(f=f.idivn(p)).isZero()?g+n:l[c-g.length]+g+n}for(this.isZero()&&(n="0"+n);n.length%t!=0;)n="0"+n;return 0!==this.negative&&(n="-"+n),n}o(!1,"Base should be between 2 and 36")},i.prototype.toNumber=function(){var e=this.words[0];return 2===this.length?e+=67108864*this.words[1]:3===this.length&&1===this.words[2]?e+=4503599627370496+67108864*this.words[1]:this.length>2&&o(!1,"Number can only safely store up to 53 bits"),0!==this.negative?-e:e},i.prototype.toJSON=function(){return this.toString(16)},i.prototype.toBuffer=function(e,t){return o(void 0!==a),this.toArrayLike(a,e,t)},i.prototype.toArray=function(e,t){return this.toArrayLike(Array,e,t)},i.prototype.toArrayLike=function(e,t,n){var r=this.byteLength(),i=n||Math.max(1,r);o(r<=i,"byte array longer than desired length"),o(i>0,"Requested array length <= 0"),this.strip();var a,s,u="le"===t,c=new e(i),l=this.clone();if(u){for(s=0;!l.isZero();s++)a=l.andln(255),l.iushrn(8),c[s]=a;for(;s=4096&&(n+=13,t>>>=13),t>=64&&(n+=7,t>>>=7),t>=8&&(n+=4,t>>>=4),t>=2&&(n+=2,t>>>=2),n+t},i.prototype._zeroBits=function(e){if(0===e)return 26;var t=e,n=0;return 0==(8191&t)&&(n+=13,t>>>=13),0==(127&t)&&(n+=7,t>>>=7),0==(15&t)&&(n+=4,t>>>=4),0==(3&t)&&(n+=2,t>>>=2),0==(1&t)&&n++,n},i.prototype.bitLength=function(){var e=this.words[this.length-1],t=this._countBits(e);return 26*(this.length-1)+t},i.prototype.zeroBits=function(){if(this.isZero())return 0;for(var e=0,t=0;te.length?this.clone().ior(e):e.clone().ior(this)},i.prototype.uor=function(e){return this.length>e.length?this.clone().iuor(e):e.clone().iuor(this)},i.prototype.iuand=function(e){var t;t=this.length>e.length?e:this;for(var n=0;ne.length?this.clone().iand(e):e.clone().iand(this)},i.prototype.uand=function(e){return this.length>e.length?this.clone().iuand(e):e.clone().iuand(this)},i.prototype.iuxor=function(e){var t,n;this.length>e.length?(t=this,n=e):(t=e,n=this);for(var o=0;oe.length?this.clone().ixor(e):e.clone().ixor(this)},i.prototype.uxor=function(e){return this.length>e.length?this.clone().iuxor(e):e.clone().iuxor(this)},i.prototype.inotn=function(e){o("number"==typeof e&&e>=0);var t=0|Math.ceil(e/26),n=e%26;this._expand(t),n>0&&t--;for(var r=0;r0&&(this.words[r]=~this.words[r]&67108863>>26-n),this.strip()},i.prototype.notn=function(e){return this.clone().inotn(e)},i.prototype.setn=function(e,t){o("number"==typeof e&&e>=0);var n=e/26|0,r=e%26;return this._expand(n+1),this.words[n]=t?this.words[n]|1<e.length?(n=this,o=e):(n=e,o=this);for(var r=0,i=0;i>>26;for(;0!==r&&i>>26;if(this.length=n.length,0!==r)this.words[this.length]=r,this.length++;else if(n!==this)for(;ie.length?this.clone().iadd(e):e.clone().iadd(this)},i.prototype.isub=function(e){if(0!==e.negative){e.negative=0;var t=this.iadd(e);return e.negative=1,t._normSign()}if(0!==this.negative)return this.negative=0,this.iadd(e),this.negative=1,this._normSign();var n,o,r=this.cmp(e);if(0===r)return this.negative=0,this.length=1,this.words[0]=0,this;r>0?(n=this,o=e):(n=e,o=this);for(var i=0,a=0;a>26,this.words[a]=67108863&t;for(;0!==i&&a>26,this.words[a]=67108863&t;if(0===i&&a>>13,p=0|a[1],f=8191&p,g=p>>>13,m=0|a[2],_=8191&m,F=m>>>13,y=0|a[3],b=8191&y,v=y>>>13,w=0|a[4],E=8191&w,k=w>>>13,D=0|a[5],S=8191&D,x=D>>>13,C=0|a[6],A=8191&C,T=C>>>13,R=0|a[7],I=8191&R,M=R>>>13,O=0|a[8],B=8191&O,N=O>>>13,L=0|a[9],P=8191&L,U=L>>>13,j=0|s[0],q=8191&j,z=j>>>13,K=0|s[1],G=8191&K,$=K>>>13,H=0|s[2],V=8191&H,W=H>>>13,Y=0|s[3],Z=8191&Y,X=Y>>>13,J=0|s[4],Q=8191&J,ee=J>>>13,te=0|s[5],ne=8191&te,oe=te>>>13,re=0|s[6],ie=8191&re,ae=re>>>13,se=0|s[7],ue=8191&se,ce=se>>>13,le=0|s[8],de=8191&le,he=le>>>13,pe=0|s[9],fe=8191&pe,ge=pe>>>13;n.negative=e.negative^t.negative,n.length=19;var me=(c+(o=Math.imul(d,q))|0)+((8191&(r=(r=Math.imul(d,z))+Math.imul(h,q)|0))<<13)|0;c=((i=Math.imul(h,z))+(r>>>13)|0)+(me>>>26)|0,me&=67108863,o=Math.imul(f,q),r=(r=Math.imul(f,z))+Math.imul(g,q)|0,i=Math.imul(g,z);var _e=(c+(o=o+Math.imul(d,G)|0)|0)+((8191&(r=(r=r+Math.imul(d,$)|0)+Math.imul(h,G)|0))<<13)|0;c=((i=i+Math.imul(h,$)|0)+(r>>>13)|0)+(_e>>>26)|0,_e&=67108863,o=Math.imul(_,q),r=(r=Math.imul(_,z))+Math.imul(F,q)|0,i=Math.imul(F,z),o=o+Math.imul(f,G)|0,r=(r=r+Math.imul(f,$)|0)+Math.imul(g,G)|0,i=i+Math.imul(g,$)|0;var Fe=(c+(o=o+Math.imul(d,V)|0)|0)+((8191&(r=(r=r+Math.imul(d,W)|0)+Math.imul(h,V)|0))<<13)|0;c=((i=i+Math.imul(h,W)|0)+(r>>>13)|0)+(Fe>>>26)|0,Fe&=67108863,o=Math.imul(b,q),r=(r=Math.imul(b,z))+Math.imul(v,q)|0,i=Math.imul(v,z),o=o+Math.imul(_,G)|0,r=(r=r+Math.imul(_,$)|0)+Math.imul(F,G)|0,i=i+Math.imul(F,$)|0,o=o+Math.imul(f,V)|0,r=(r=r+Math.imul(f,W)|0)+Math.imul(g,V)|0,i=i+Math.imul(g,W)|0;var ye=(c+(o=o+Math.imul(d,Z)|0)|0)+((8191&(r=(r=r+Math.imul(d,X)|0)+Math.imul(h,Z)|0))<<13)|0;c=((i=i+Math.imul(h,X)|0)+(r>>>13)|0)+(ye>>>26)|0,ye&=67108863,o=Math.imul(E,q),r=(r=Math.imul(E,z))+Math.imul(k,q)|0,i=Math.imul(k,z),o=o+Math.imul(b,G)|0,r=(r=r+Math.imul(b,$)|0)+Math.imul(v,G)|0,i=i+Math.imul(v,$)|0,o=o+Math.imul(_,V)|0,r=(r=r+Math.imul(_,W)|0)+Math.imul(F,V)|0,i=i+Math.imul(F,W)|0,o=o+Math.imul(f,Z)|0,r=(r=r+Math.imul(f,X)|0)+Math.imul(g,Z)|0,i=i+Math.imul(g,X)|0;var be=(c+(o=o+Math.imul(d,Q)|0)|0)+((8191&(r=(r=r+Math.imul(d,ee)|0)+Math.imul(h,Q)|0))<<13)|0;c=((i=i+Math.imul(h,ee)|0)+(r>>>13)|0)+(be>>>26)|0,be&=67108863,o=Math.imul(S,q),r=(r=Math.imul(S,z))+Math.imul(x,q)|0,i=Math.imul(x,z),o=o+Math.imul(E,G)|0,r=(r=r+Math.imul(E,$)|0)+Math.imul(k,G)|0,i=i+Math.imul(k,$)|0,o=o+Math.imul(b,V)|0,r=(r=r+Math.imul(b,W)|0)+Math.imul(v,V)|0,i=i+Math.imul(v,W)|0,o=o+Math.imul(_,Z)|0,r=(r=r+Math.imul(_,X)|0)+Math.imul(F,Z)|0,i=i+Math.imul(F,X)|0,o=o+Math.imul(f,Q)|0,r=(r=r+Math.imul(f,ee)|0)+Math.imul(g,Q)|0,i=i+Math.imul(g,ee)|0;var ve=(c+(o=o+Math.imul(d,ne)|0)|0)+((8191&(r=(r=r+Math.imul(d,oe)|0)+Math.imul(h,ne)|0))<<13)|0;c=((i=i+Math.imul(h,oe)|0)+(r>>>13)|0)+(ve>>>26)|0,ve&=67108863,o=Math.imul(A,q),r=(r=Math.imul(A,z))+Math.imul(T,q)|0,i=Math.imul(T,z),o=o+Math.imul(S,G)|0,r=(r=r+Math.imul(S,$)|0)+Math.imul(x,G)|0,i=i+Math.imul(x,$)|0,o=o+Math.imul(E,V)|0,r=(r=r+Math.imul(E,W)|0)+Math.imul(k,V)|0,i=i+Math.imul(k,W)|0,o=o+Math.imul(b,Z)|0,r=(r=r+Math.imul(b,X)|0)+Math.imul(v,Z)|0,i=i+Math.imul(v,X)|0,o=o+Math.imul(_,Q)|0,r=(r=r+Math.imul(_,ee)|0)+Math.imul(F,Q)|0,i=i+Math.imul(F,ee)|0,o=o+Math.imul(f,ne)|0,r=(r=r+Math.imul(f,oe)|0)+Math.imul(g,ne)|0,i=i+Math.imul(g,oe)|0;var we=(c+(o=o+Math.imul(d,ie)|0)|0)+((8191&(r=(r=r+Math.imul(d,ae)|0)+Math.imul(h,ie)|0))<<13)|0;c=((i=i+Math.imul(h,ae)|0)+(r>>>13)|0)+(we>>>26)|0,we&=67108863,o=Math.imul(I,q),r=(r=Math.imul(I,z))+Math.imul(M,q)|0,i=Math.imul(M,z),o=o+Math.imul(A,G)|0,r=(r=r+Math.imul(A,$)|0)+Math.imul(T,G)|0,i=i+Math.imul(T,$)|0,o=o+Math.imul(S,V)|0,r=(r=r+Math.imul(S,W)|0)+Math.imul(x,V)|0,i=i+Math.imul(x,W)|0,o=o+Math.imul(E,Z)|0,r=(r=r+Math.imul(E,X)|0)+Math.imul(k,Z)|0,i=i+Math.imul(k,X)|0,o=o+Math.imul(b,Q)|0,r=(r=r+Math.imul(b,ee)|0)+Math.imul(v,Q)|0,i=i+Math.imul(v,ee)|0,o=o+Math.imul(_,ne)|0,r=(r=r+Math.imul(_,oe)|0)+Math.imul(F,ne)|0,i=i+Math.imul(F,oe)|0,o=o+Math.imul(f,ie)|0,r=(r=r+Math.imul(f,ae)|0)+Math.imul(g,ie)|0,i=i+Math.imul(g,ae)|0;var Ee=(c+(o=o+Math.imul(d,ue)|0)|0)+((8191&(r=(r=r+Math.imul(d,ce)|0)+Math.imul(h,ue)|0))<<13)|0;c=((i=i+Math.imul(h,ce)|0)+(r>>>13)|0)+(Ee>>>26)|0,Ee&=67108863,o=Math.imul(B,q),r=(r=Math.imul(B,z))+Math.imul(N,q)|0,i=Math.imul(N,z),o=o+Math.imul(I,G)|0,r=(r=r+Math.imul(I,$)|0)+Math.imul(M,G)|0,i=i+Math.imul(M,$)|0,o=o+Math.imul(A,V)|0,r=(r=r+Math.imul(A,W)|0)+Math.imul(T,V)|0,i=i+Math.imul(T,W)|0,o=o+Math.imul(S,Z)|0,r=(r=r+Math.imul(S,X)|0)+Math.imul(x,Z)|0,i=i+Math.imul(x,X)|0,o=o+Math.imul(E,Q)|0,r=(r=r+Math.imul(E,ee)|0)+Math.imul(k,Q)|0,i=i+Math.imul(k,ee)|0,o=o+Math.imul(b,ne)|0,r=(r=r+Math.imul(b,oe)|0)+Math.imul(v,ne)|0,i=i+Math.imul(v,oe)|0,o=o+Math.imul(_,ie)|0,r=(r=r+Math.imul(_,ae)|0)+Math.imul(F,ie)|0,i=i+Math.imul(F,ae)|0,o=o+Math.imul(f,ue)|0,r=(r=r+Math.imul(f,ce)|0)+Math.imul(g,ue)|0,i=i+Math.imul(g,ce)|0;var ke=(c+(o=o+Math.imul(d,de)|0)|0)+((8191&(r=(r=r+Math.imul(d,he)|0)+Math.imul(h,de)|0))<<13)|0;c=((i=i+Math.imul(h,he)|0)+(r>>>13)|0)+(ke>>>26)|0,ke&=67108863,o=Math.imul(P,q),r=(r=Math.imul(P,z))+Math.imul(U,q)|0,i=Math.imul(U,z),o=o+Math.imul(B,G)|0,r=(r=r+Math.imul(B,$)|0)+Math.imul(N,G)|0,i=i+Math.imul(N,$)|0,o=o+Math.imul(I,V)|0,r=(r=r+Math.imul(I,W)|0)+Math.imul(M,V)|0,i=i+Math.imul(M,W)|0,o=o+Math.imul(A,Z)|0,r=(r=r+Math.imul(A,X)|0)+Math.imul(T,Z)|0,i=i+Math.imul(T,X)|0,o=o+Math.imul(S,Q)|0,r=(r=r+Math.imul(S,ee)|0)+Math.imul(x,Q)|0,i=i+Math.imul(x,ee)|0,o=o+Math.imul(E,ne)|0,r=(r=r+Math.imul(E,oe)|0)+Math.imul(k,ne)|0,i=i+Math.imul(k,oe)|0,o=o+Math.imul(b,ie)|0,r=(r=r+Math.imul(b,ae)|0)+Math.imul(v,ie)|0,i=i+Math.imul(v,ae)|0,o=o+Math.imul(_,ue)|0,r=(r=r+Math.imul(_,ce)|0)+Math.imul(F,ue)|0,i=i+Math.imul(F,ce)|0,o=o+Math.imul(f,de)|0,r=(r=r+Math.imul(f,he)|0)+Math.imul(g,de)|0,i=i+Math.imul(g,he)|0;var De=(c+(o=o+Math.imul(d,fe)|0)|0)+((8191&(r=(r=r+Math.imul(d,ge)|0)+Math.imul(h,fe)|0))<<13)|0;c=((i=i+Math.imul(h,ge)|0)+(r>>>13)|0)+(De>>>26)|0,De&=67108863,o=Math.imul(P,G),r=(r=Math.imul(P,$))+Math.imul(U,G)|0,i=Math.imul(U,$),o=o+Math.imul(B,V)|0,r=(r=r+Math.imul(B,W)|0)+Math.imul(N,V)|0,i=i+Math.imul(N,W)|0,o=o+Math.imul(I,Z)|0,r=(r=r+Math.imul(I,X)|0)+Math.imul(M,Z)|0,i=i+Math.imul(M,X)|0,o=o+Math.imul(A,Q)|0,r=(r=r+Math.imul(A,ee)|0)+Math.imul(T,Q)|0,i=i+Math.imul(T,ee)|0,o=o+Math.imul(S,ne)|0,r=(r=r+Math.imul(S,oe)|0)+Math.imul(x,ne)|0,i=i+Math.imul(x,oe)|0,o=o+Math.imul(E,ie)|0,r=(r=r+Math.imul(E,ae)|0)+Math.imul(k,ie)|0,i=i+Math.imul(k,ae)|0,o=o+Math.imul(b,ue)|0,r=(r=r+Math.imul(b,ce)|0)+Math.imul(v,ue)|0,i=i+Math.imul(v,ce)|0,o=o+Math.imul(_,de)|0,r=(r=r+Math.imul(_,he)|0)+Math.imul(F,de)|0,i=i+Math.imul(F,he)|0;var Se=(c+(o=o+Math.imul(f,fe)|0)|0)+((8191&(r=(r=r+Math.imul(f,ge)|0)+Math.imul(g,fe)|0))<<13)|0;c=((i=i+Math.imul(g,ge)|0)+(r>>>13)|0)+(Se>>>26)|0,Se&=67108863,o=Math.imul(P,V),r=(r=Math.imul(P,W))+Math.imul(U,V)|0,i=Math.imul(U,W),o=o+Math.imul(B,Z)|0,r=(r=r+Math.imul(B,X)|0)+Math.imul(N,Z)|0,i=i+Math.imul(N,X)|0,o=o+Math.imul(I,Q)|0,r=(r=r+Math.imul(I,ee)|0)+Math.imul(M,Q)|0,i=i+Math.imul(M,ee)|0,o=o+Math.imul(A,ne)|0,r=(r=r+Math.imul(A,oe)|0)+Math.imul(T,ne)|0,i=i+Math.imul(T,oe)|0,o=o+Math.imul(S,ie)|0,r=(r=r+Math.imul(S,ae)|0)+Math.imul(x,ie)|0,i=i+Math.imul(x,ae)|0,o=o+Math.imul(E,ue)|0,r=(r=r+Math.imul(E,ce)|0)+Math.imul(k,ue)|0,i=i+Math.imul(k,ce)|0,o=o+Math.imul(b,de)|0,r=(r=r+Math.imul(b,he)|0)+Math.imul(v,de)|0,i=i+Math.imul(v,he)|0;var xe=(c+(o=o+Math.imul(_,fe)|0)|0)+((8191&(r=(r=r+Math.imul(_,ge)|0)+Math.imul(F,fe)|0))<<13)|0;c=((i=i+Math.imul(F,ge)|0)+(r>>>13)|0)+(xe>>>26)|0,xe&=67108863,o=Math.imul(P,Z),r=(r=Math.imul(P,X))+Math.imul(U,Z)|0,i=Math.imul(U,X),o=o+Math.imul(B,Q)|0,r=(r=r+Math.imul(B,ee)|0)+Math.imul(N,Q)|0,i=i+Math.imul(N,ee)|0,o=o+Math.imul(I,ne)|0,r=(r=r+Math.imul(I,oe)|0)+Math.imul(M,ne)|0,i=i+Math.imul(M,oe)|0,o=o+Math.imul(A,ie)|0,r=(r=r+Math.imul(A,ae)|0)+Math.imul(T,ie)|0,i=i+Math.imul(T,ae)|0,o=o+Math.imul(S,ue)|0,r=(r=r+Math.imul(S,ce)|0)+Math.imul(x,ue)|0,i=i+Math.imul(x,ce)|0,o=o+Math.imul(E,de)|0,r=(r=r+Math.imul(E,he)|0)+Math.imul(k,de)|0,i=i+Math.imul(k,he)|0;var Ce=(c+(o=o+Math.imul(b,fe)|0)|0)+((8191&(r=(r=r+Math.imul(b,ge)|0)+Math.imul(v,fe)|0))<<13)|0;c=((i=i+Math.imul(v,ge)|0)+(r>>>13)|0)+(Ce>>>26)|0,Ce&=67108863,o=Math.imul(P,Q),r=(r=Math.imul(P,ee))+Math.imul(U,Q)|0,i=Math.imul(U,ee),o=o+Math.imul(B,ne)|0,r=(r=r+Math.imul(B,oe)|0)+Math.imul(N,ne)|0,i=i+Math.imul(N,oe)|0,o=o+Math.imul(I,ie)|0,r=(r=r+Math.imul(I,ae)|0)+Math.imul(M,ie)|0,i=i+Math.imul(M,ae)|0,o=o+Math.imul(A,ue)|0,r=(r=r+Math.imul(A,ce)|0)+Math.imul(T,ue)|0,i=i+Math.imul(T,ce)|0,o=o+Math.imul(S,de)|0,r=(r=r+Math.imul(S,he)|0)+Math.imul(x,de)|0,i=i+Math.imul(x,he)|0;var Ae=(c+(o=o+Math.imul(E,fe)|0)|0)+((8191&(r=(r=r+Math.imul(E,ge)|0)+Math.imul(k,fe)|0))<<13)|0;c=((i=i+Math.imul(k,ge)|0)+(r>>>13)|0)+(Ae>>>26)|0,Ae&=67108863,o=Math.imul(P,ne),r=(r=Math.imul(P,oe))+Math.imul(U,ne)|0,i=Math.imul(U,oe),o=o+Math.imul(B,ie)|0,r=(r=r+Math.imul(B,ae)|0)+Math.imul(N,ie)|0,i=i+Math.imul(N,ae)|0,o=o+Math.imul(I,ue)|0,r=(r=r+Math.imul(I,ce)|0)+Math.imul(M,ue)|0,i=i+Math.imul(M,ce)|0,o=o+Math.imul(A,de)|0,r=(r=r+Math.imul(A,he)|0)+Math.imul(T,de)|0,i=i+Math.imul(T,he)|0;var Te=(c+(o=o+Math.imul(S,fe)|0)|0)+((8191&(r=(r=r+Math.imul(S,ge)|0)+Math.imul(x,fe)|0))<<13)|0;c=((i=i+Math.imul(x,ge)|0)+(r>>>13)|0)+(Te>>>26)|0,Te&=67108863,o=Math.imul(P,ie),r=(r=Math.imul(P,ae))+Math.imul(U,ie)|0,i=Math.imul(U,ae),o=o+Math.imul(B,ue)|0,r=(r=r+Math.imul(B,ce)|0)+Math.imul(N,ue)|0,i=i+Math.imul(N,ce)|0,o=o+Math.imul(I,de)|0,r=(r=r+Math.imul(I,he)|0)+Math.imul(M,de)|0,i=i+Math.imul(M,he)|0;var Re=(c+(o=o+Math.imul(A,fe)|0)|0)+((8191&(r=(r=r+Math.imul(A,ge)|0)+Math.imul(T,fe)|0))<<13)|0;c=((i=i+Math.imul(T,ge)|0)+(r>>>13)|0)+(Re>>>26)|0,Re&=67108863,o=Math.imul(P,ue),r=(r=Math.imul(P,ce))+Math.imul(U,ue)|0,i=Math.imul(U,ce),o=o+Math.imul(B,de)|0,r=(r=r+Math.imul(B,he)|0)+Math.imul(N,de)|0,i=i+Math.imul(N,he)|0;var Ie=(c+(o=o+Math.imul(I,fe)|0)|0)+((8191&(r=(r=r+Math.imul(I,ge)|0)+Math.imul(M,fe)|0))<<13)|0;c=((i=i+Math.imul(M,ge)|0)+(r>>>13)|0)+(Ie>>>26)|0,Ie&=67108863,o=Math.imul(P,de),r=(r=Math.imul(P,he))+Math.imul(U,de)|0,i=Math.imul(U,he);var Me=(c+(o=o+Math.imul(B,fe)|0)|0)+((8191&(r=(r=r+Math.imul(B,ge)|0)+Math.imul(N,fe)|0))<<13)|0;c=((i=i+Math.imul(N,ge)|0)+(r>>>13)|0)+(Me>>>26)|0,Me&=67108863;var Oe=(c+(o=Math.imul(P,fe))|0)+((8191&(r=(r=Math.imul(P,ge))+Math.imul(U,fe)|0))<<13)|0;return c=((i=Math.imul(U,ge))+(r>>>13)|0)+(Oe>>>26)|0,Oe&=67108863,u[0]=me,u[1]=_e,u[2]=Fe,u[3]=ye,u[4]=be,u[5]=ve,u[6]=we,u[7]=Ee,u[8]=ke,u[9]=De,u[10]=Se,u[11]=xe,u[12]=Ce,u[13]=Ae,u[14]=Te,u[15]=Re,u[16]=Ie,u[17]=Me,u[18]=Oe,0!==c&&(u[19]=c,n.length++),n};function g(e,t,n){return(new m).mulp(e,t,n)}function m(e,t){this.x=e,this.y=t}Math.imul||(f=p),i.prototype.mulTo=function(e,t){var n=this.length+e.length;return 10===this.length&&10===e.length?f(this,e,t):n<63?p(this,e,t):n<1024?function(e,t,n){n.negative=t.negative^e.negative,n.length=e.length+t.length;for(var o=0,r=0,i=0;i>>26)|0)>>>26,a&=67108863}n.words[i]=s,o=a,a=r}return 0!==o?n.words[i]=o:n.length--,n.strip()}(this,e,t):g(this,e,t)},m.prototype.makeRBT=function(e){for(var t=new Array(e),n=i.prototype._countBits(e)-1,o=0;o>=1;return o},m.prototype.permute=function(e,t,n,o,r,i){for(var a=0;a>>=1)r++;return 1<>>=13,n[2*a+1]=8191&i,i>>>=13;for(a=2*t;a>=26,t+=r/67108864|0,t+=i>>>26,this.words[n]=67108863&i}return 0!==t&&(this.words[n]=t,this.length++),this},i.prototype.muln=function(e){return this.clone().imuln(e)},i.prototype.sqr=function(){return this.mul(this)},i.prototype.isqr=function(){return this.imul(this.clone())},i.prototype.pow=function(e){var t=function(e){for(var t=new Array(e.bitLength()),n=0;n>>r}return t}(e);if(0===t.length)return new i(1);for(var n=this,o=0;o=0);var t,n=e%26,r=(e-n)/26,i=67108863>>>26-n<<26-n;if(0!==n){var a=0;for(t=0;t>>26-n}a&&(this.words[t]=a,this.length++)}if(0!==r){for(t=this.length-1;t>=0;t--)this.words[t+r]=this.words[t];for(t=0;t=0),r=t?(t-t%26)/26:0;var i=e%26,a=Math.min((e-i)/26,this.length),s=67108863^67108863>>>i<a)for(this.length-=a,c=0;c=0&&(0!==l||c>=r);c--){var d=0|this.words[c];this.words[c]=l<<26-i|d>>>i,l=d&s}return u&&0!==l&&(u.words[u.length++]=l),0===this.length&&(this.words[0]=0,this.length=1),this.strip()},i.prototype.ishrn=function(e,t,n){return o(0===this.negative),this.iushrn(e,t,n)},i.prototype.shln=function(e){return this.clone().ishln(e)},i.prototype.ushln=function(e){return this.clone().iushln(e)},i.prototype.shrn=function(e){return this.clone().ishrn(e)},i.prototype.ushrn=function(e){return this.clone().iushrn(e)},i.prototype.testn=function(e){o("number"==typeof e&&e>=0);var t=e%26,n=(e-t)/26,r=1<=0);var t=e%26,n=(e-t)/26;if(o(0===this.negative,"imaskn works only with positive numbers"),this.length<=n)return this;if(0!==t&&n++,this.length=Math.min(n,this.length),0!==t){var r=67108863^67108863>>>t<=67108864;t++)this.words[t]-=67108864,t===this.length-1?this.words[t+1]=1:this.words[t+1]++;return this.length=Math.max(this.length,t+1),this},i.prototype.isubn=function(e){if(o("number"==typeof e),o(e<67108864),e<0)return this.iaddn(-e);if(0!==this.negative)return this.negative=0,this.iaddn(e),this.negative=1,this;if(this.words[0]-=e,1===this.length&&this.words[0]<0)this.words[0]=-this.words[0],this.negative=1;else for(var t=0;t>26)-(u/67108864|0),this.words[r+n]=67108863&i}for(;r>26,this.words[r+n]=67108863&i;if(0===s)return this.strip();for(o(-1===s),s=0,r=0;r>26,this.words[r]=67108863&i;return this.negative=1,this.strip()},i.prototype._wordDiv=function(e,t){var n=(this.length,e.length),o=this.clone(),r=e,a=0|r.words[r.length-1];0!=(n=26-this._countBits(a))&&(r=r.ushln(n),o.iushln(n),a=0|r.words[r.length-1]);var s,u=o.length-r.length;if("mod"!==t){(s=new i(null)).length=u+1,s.words=new Array(s.length);for(var c=0;c=0;d--){var h=67108864*(0|o.words[r.length+d])+(0|o.words[r.length+d-1]);for(h=Math.min(h/a|0,67108863),o._ishlnsubmul(r,h,d);0!==o.negative;)h--,o.negative=0,o._ishlnsubmul(r,1,d),o.isZero()||(o.negative^=1);s&&(s.words[d]=h)}return s&&s.strip(),o.strip(),"div"!==t&&0!==n&&o.iushrn(n),{div:s||null,mod:o}},i.prototype.divmod=function(e,t,n){return o(!e.isZero()),this.isZero()?{div:new i(0),mod:new i(0)}:0!==this.negative&&0===e.negative?(s=this.neg().divmod(e,t),"mod"!==t&&(r=s.div.neg()),"div"!==t&&(a=s.mod.neg(),n&&0!==a.negative&&a.iadd(e)),{div:r,mod:a}):0===this.negative&&0!==e.negative?(s=this.divmod(e.neg(),t),"mod"!==t&&(r=s.div.neg()),{div:r,mod:s.mod}):0!=(this.negative&e.negative)?(s=this.neg().divmod(e.neg(),t),"div"!==t&&(a=s.mod.neg(),n&&0!==a.negative&&a.isub(e)),{div:s.div,mod:a}):e.length>this.length||this.cmp(e)<0?{div:new i(0),mod:this}:1===e.length?"div"===t?{div:this.divn(e.words[0]),mod:null}:"mod"===t?{div:null,mod:new i(this.modn(e.words[0]))}:{div:this.divn(e.words[0]),mod:new i(this.modn(e.words[0]))}:this._wordDiv(e,t);var r,a,s},i.prototype.div=function(e){return this.divmod(e,"div",!1).div},i.prototype.mod=function(e){return this.divmod(e,"mod",!1).mod},i.prototype.umod=function(e){return this.divmod(e,"mod",!0).mod},i.prototype.divRound=function(e){var t=this.divmod(e);if(t.mod.isZero())return t.div;var n=0!==t.div.negative?t.mod.isub(e):t.mod,o=e.ushrn(1),r=e.andln(1),i=n.cmp(o);return i<0||1===r&&0===i?t.div:0!==t.div.negative?t.div.isubn(1):t.div.iaddn(1)},i.prototype.modn=function(e){o(e<=67108863);for(var t=(1<<26)%e,n=0,r=this.length-1;r>=0;r--)n=(t*n+(0|this.words[r]))%e;return n},i.prototype.idivn=function(e){o(e<=67108863);for(var t=0,n=this.length-1;n>=0;n--){var r=(0|this.words[n])+67108864*t;this.words[n]=r/e|0,t=r%e}return this.strip()},i.prototype.divn=function(e){return this.clone().idivn(e)},i.prototype.egcd=function(e){o(0===e.negative),o(!e.isZero());var t=this,n=e.clone();t=0!==t.negative?t.umod(e):t.clone();for(var r=new i(1),a=new i(0),s=new i(0),u=new i(1),c=0;t.isEven()&&n.isEven();)t.iushrn(1),n.iushrn(1),++c;for(var l=n.clone(),d=t.clone();!t.isZero();){for(var h=0,p=1;0==(t.words[0]&p)&&h<26;++h,p<<=1);if(h>0)for(t.iushrn(h);h-- >0;)(r.isOdd()||a.isOdd())&&(r.iadd(l),a.isub(d)),r.iushrn(1),a.iushrn(1);for(var f=0,g=1;0==(n.words[0]&g)&&f<26;++f,g<<=1);if(f>0)for(n.iushrn(f);f-- >0;)(s.isOdd()||u.isOdd())&&(s.iadd(l),u.isub(d)),s.iushrn(1),u.iushrn(1);t.cmp(n)>=0?(t.isub(n),r.isub(s),a.isub(u)):(n.isub(t),s.isub(r),u.isub(a))}return{a:s,b:u,gcd:n.iushln(c)}},i.prototype._invmp=function(e){o(0===e.negative),o(!e.isZero());var t=this,n=e.clone();t=0!==t.negative?t.umod(e):t.clone();for(var r,a=new i(1),s=new i(0),u=n.clone();t.cmpn(1)>0&&n.cmpn(1)>0;){for(var c=0,l=1;0==(t.words[0]&l)&&c<26;++c,l<<=1);if(c>0)for(t.iushrn(c);c-- >0;)a.isOdd()&&a.iadd(u),a.iushrn(1);for(var d=0,h=1;0==(n.words[0]&h)&&d<26;++d,h<<=1);if(d>0)for(n.iushrn(d);d-- >0;)s.isOdd()&&s.iadd(u),s.iushrn(1);t.cmp(n)>=0?(t.isub(n),a.isub(s)):(n.isub(t),s.isub(a))}return(r=0===t.cmpn(1)?a:s).cmpn(0)<0&&r.iadd(e),r},i.prototype.gcd=function(e){if(this.isZero())return e.abs();if(e.isZero())return this.abs();var t=this.clone(),n=e.clone();t.negative=0,n.negative=0;for(var o=0;t.isEven()&&n.isEven();o++)t.iushrn(1),n.iushrn(1);for(;;){for(;t.isEven();)t.iushrn(1);for(;n.isEven();)n.iushrn(1);var r=t.cmp(n);if(r<0){var i=t;t=n,n=i}else if(0===r||0===n.cmpn(1))break;t.isub(n)}return n.iushln(o)},i.prototype.invm=function(e){return this.egcd(e).a.umod(e)},i.prototype.isEven=function(){return 0==(1&this.words[0])},i.prototype.isOdd=function(){return 1==(1&this.words[0])},i.prototype.andln=function(e){return this.words[0]&e},i.prototype.bincn=function(e){o("number"==typeof e);var t=e%26,n=(e-t)/26,r=1<>>26,s&=67108863,this.words[a]=s}return 0!==i&&(this.words[a]=i,this.length++),this},i.prototype.isZero=function(){return 1===this.length&&0===this.words[0]},i.prototype.cmpn=function(e){var t,n=e<0;if(0!==this.negative&&!n)return-1;if(0===this.negative&&n)return 1;if(this.strip(),this.length>1)t=1;else{n&&(e=-e),o(e<=67108863,"Number is too big");var r=0|this.words[0];t=r===e?0:re.length)return 1;if(this.length=0;n--){var o=0|this.words[n],r=0|e.words[n];if(o!==r){or&&(t=1);break}}return t},i.prototype.gtn=function(e){return 1===this.cmpn(e)},i.prototype.gt=function(e){return 1===this.cmp(e)},i.prototype.gten=function(e){return this.cmpn(e)>=0},i.prototype.gte=function(e){return this.cmp(e)>=0},i.prototype.ltn=function(e){return-1===this.cmpn(e)},i.prototype.lt=function(e){return-1===this.cmp(e)},i.prototype.lten=function(e){return this.cmpn(e)<=0},i.prototype.lte=function(e){return this.cmp(e)<=0},i.prototype.eqn=function(e){return 0===this.cmpn(e)},i.prototype.eq=function(e){return 0===this.cmp(e)},i.red=function(e){return new E(e)},i.prototype.toRed=function(e){return o(!this.red,"Already a number in reduction context"),o(0===this.negative,"red works only with positives"),e.convertTo(this)._forceRed(e)},i.prototype.fromRed=function(){return o(this.red,"fromRed works only with numbers in reduction context"),this.red.convertFrom(this)},i.prototype._forceRed=function(e){return this.red=e,this},i.prototype.forceRed=function(e){return o(!this.red,"Already a number in reduction context"),this._forceRed(e)},i.prototype.redAdd=function(e){return o(this.red,"redAdd works only with red numbers"),this.red.add(this,e)},i.prototype.redIAdd=function(e){return o(this.red,"redIAdd works only with red numbers"),this.red.iadd(this,e)},i.prototype.redSub=function(e){return o(this.red,"redSub works only with red numbers"),this.red.sub(this,e)},i.prototype.redISub=function(e){return o(this.red,"redISub works only with red numbers"),this.red.isub(this,e)},i.prototype.redShl=function(e){return o(this.red,"redShl works only with red numbers"),this.red.shl(this,e)},i.prototype.redMul=function(e){return o(this.red,"redMul works only with red numbers"),this.red._verify2(this,e),this.red.mul(this,e)},i.prototype.redIMul=function(e){return o(this.red,"redMul works only with red numbers"),this.red._verify2(this,e),this.red.imul(this,e)},i.prototype.redSqr=function(){return o(this.red,"redSqr works only with red numbers"),this.red._verify1(this),this.red.sqr(this)},i.prototype.redISqr=function(){return o(this.red,"redISqr works only with red numbers"),this.red._verify1(this),this.red.isqr(this)},i.prototype.redSqrt=function(){return o(this.red,"redSqrt works only with red numbers"),this.red._verify1(this),this.red.sqrt(this)},i.prototype.redInvm=function(){return o(this.red,"redInvm works only with red numbers"),this.red._verify1(this),this.red.invm(this)},i.prototype.redNeg=function(){return o(this.red,"redNeg works only with red numbers"),this.red._verify1(this),this.red.neg(this)},i.prototype.redPow=function(e){return o(this.red&&!e.red,"redPow(normalNum)"),this.red._verify1(this),this.red.pow(this,e)};var _={k256:null,p224:null,p192:null,p25519:null};function F(e,t){this.name=e,this.p=new i(t,16),this.n=this.p.bitLength(),this.k=new i(1).iushln(this.n).isub(this.p),this.tmp=this._tmp()}function y(){F.call(this,"k256","ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f")}function b(){F.call(this,"p224","ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001")}function v(){F.call(this,"p192","ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff")}function w(){F.call(this,"25519","7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed")}function E(e){if("string"==typeof e){var t=i._prime(e);this.m=t.p,this.prime=t}else o(e.gtn(1),"modulus must be greater than 1"),this.m=e,this.prime=null}function k(e){E.call(this,e),this.shift=this.m.bitLength(),this.shift%26!=0&&(this.shift+=26-this.shift%26),this.r=new i(1).iushln(this.shift),this.r2=this.imod(this.r.sqr()),this.rinv=this.r._invmp(this.m),this.minv=this.rinv.mul(this.r).isubn(1).div(this.m),this.minv=this.minv.umod(this.r),this.minv=this.r.sub(this.minv)}F.prototype._tmp=function(){var e=new i(null);return e.words=new Array(Math.ceil(this.n/13)),e},F.prototype.ireduce=function(e){var t,n=e;do{this.split(n,this.tmp),t=(n=(n=this.imulK(n)).iadd(this.tmp)).bitLength()}while(t>this.n);var o=t0?n.isub(this.p):void 0!==n.strip?n.strip():n._strip(),n},F.prototype.split=function(e,t){e.iushrn(this.n,0,t)},F.prototype.imulK=function(e){return e.imul(this.k)},r(y,F),y.prototype.split=function(e,t){for(var n=4194303,o=Math.min(e.length,9),r=0;r>>22,i=a}i>>>=22,e.words[r-10]=i,0===i&&e.length>10?e.length-=10:e.length-=9},y.prototype.imulK=function(e){e.words[e.length]=0,e.words[e.length+1]=0,e.length+=2;for(var t=0,n=0;n>>=26,e.words[n]=r,t=o}return 0!==t&&(e.words[e.length++]=t),e},i._prime=function(e){if(_[e])return _[e];var t;if("k256"===e)t=new y;else if("p224"===e)t=new b;else if("p192"===e)t=new v;else{if("p25519"!==e)throw new Error("Unknown prime "+e);t=new w}return _[e]=t,t},E.prototype._verify1=function(e){o(0===e.negative,"red works only with positives"),o(e.red,"red works only with red numbers")},E.prototype._verify2=function(e,t){o(0==(e.negative|t.negative),"red works only with positives"),o(e.red&&e.red===t.red,"red works only with red numbers")},E.prototype.imod=function(e){return this.prime?this.prime.ireduce(e)._forceRed(this):e.umod(this.m)._forceRed(this)},E.prototype.neg=function(e){return e.isZero()?e.clone():this.m.sub(e)._forceRed(this)},E.prototype.add=function(e,t){this._verify2(e,t);var n=e.add(t);return n.cmp(this.m)>=0&&n.isub(this.m),n._forceRed(this)},E.prototype.iadd=function(e,t){this._verify2(e,t);var n=e.iadd(t);return n.cmp(this.m)>=0&&n.isub(this.m),n},E.prototype.sub=function(e,t){this._verify2(e,t);var n=e.sub(t);return n.cmpn(0)<0&&n.iadd(this.m),n._forceRed(this)},E.prototype.isub=function(e,t){this._verify2(e,t);var n=e.isub(t);return n.cmpn(0)<0&&n.iadd(this.m),n},E.prototype.shl=function(e,t){return this._verify1(e),this.imod(e.ushln(t))},E.prototype.imul=function(e,t){return this._verify2(e,t),this.imod(e.imul(t))},E.prototype.mul=function(e,t){return this._verify2(e,t),this.imod(e.mul(t))},E.prototype.isqr=function(e){return this.imul(e,e.clone())},E.prototype.sqr=function(e){return this.mul(e,e)},E.prototype.sqrt=function(e){if(e.isZero())return e.clone();var t=this.m.andln(3);if(o(t%2==1),3===t){var n=this.m.add(new i(1)).iushrn(2);return this.pow(e,n)}for(var r=this.m.subn(1),a=0;!r.isZero()&&0===r.andln(1);)a++,r.iushrn(1);o(!r.isZero());var s=new i(1).toRed(this),u=s.redNeg(),c=this.m.subn(1).iushrn(1),l=this.m.bitLength();for(l=new i(2*l*l).toRed(this);0!==this.pow(l,c).cmp(u);)l.redIAdd(u);for(var d=this.pow(l,r),h=this.pow(e,r.addn(1).iushrn(1)),p=this.pow(e,r),f=a;0!==p.cmp(s);){for(var g=p,m=0;0!==g.cmp(s);m++)g=g.redSqr();o(m=0;o--){for(var c=t.words[o],l=u-1;l>=0;l--){var d=c>>l&1;r!==n[0]&&(r=this.sqr(r)),0!==d||0!==a?(a<<=1,a|=d,(4==++s||0===o&&0===l)&&(r=this.mul(r,n[a]),s=0,a=0)):s=0}u=26}return r},E.prototype.convertTo=function(e){var t=e.umod(this.m);return t===e?t.clone():t},E.prototype.convertFrom=function(e){var t=e.clone();return t.red=null,t},i.mont=function(e){return new k(e)},r(k,E),k.prototype.convertTo=function(e){return this.imod(e.ushln(this.shift))},k.prototype.convertFrom=function(e){var t=this.imod(e.mul(this.rinv));return t.red=null,t},k.prototype.imul=function(e,t){if(e.isZero()||t.isZero())return e.words[0]=0,e.length=1,e;var n=e.imul(t),o=n.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m),r=n.isub(o).iushrn(this.shift),i=r;return r.cmp(this.m)>=0?i=r.isub(this.m):r.cmpn(0)<0&&(i=r.iadd(this.m)),i._forceRed(this)},k.prototype.mul=function(e,t){if(e.isZero()||t.isZero())return new i(0)._forceRed(this);var n=e.mul(t),o=n.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m),r=n.isub(o).iushrn(this.shift),a=r;return r.cmp(this.m)>=0?a=r.isub(this.m):r.cmpn(0)<0&&(a=r.iadd(this.m)),a._forceRed(this)},k.prototype.invm=function(e){return this.imod(e._invmp(this.m).mul(this.r2))._forceRed(this)}}(e=n.nmd(e),this)},79746:e=>{function t(e,t){if(!e)throw new Error(t||"Assertion failed")}e.exports=t,t.equal=function(e,t,n){if(e!=t)throw new Error(n||"Assertion failed: "+e+" != "+t)}},34504:(e,t)=>{"use strict";var n=t;function o(e){return 1===e.length?"0"+e:e}function r(e){for(var t="",n=0;n>8,a=255&r;i?n.push(i,a):n.push(a)}return n},n.zero2=o,n.toHex=r,n.encode=function(e,t){return"hex"===t?r(e):e}},27418:e=>{"use strict";var t=Object.getOwnPropertySymbols,n=Object.prototype.hasOwnProperty,o=Object.prototype.propertyIsEnumerable;function r(e){if(null==e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}e.exports=function(){try{if(!Object.assign)return!1;var e=new String("abc");if(e[5]="de","5"===Object.getOwnPropertyNames(e)[0])return!1;for(var t={},n=0;n<10;n++)t["_"+String.fromCharCode(n)]=n;if("0123456789"!==Object.getOwnPropertyNames(t).map((function(e){return t[e]})).join(""))return!1;var o={};return"abcdefghijklmnopqrst".split("").forEach((function(e){o[e]=e})),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},o)).join("")}catch(e){return!1}}()?Object.assign:function(e,i){for(var a,s,u=r(e),c=1;c{var o="function"==typeof Map&&Map.prototype,r=Object.getOwnPropertyDescriptor&&o?Object.getOwnPropertyDescriptor(Map.prototype,"size"):null,i=o&&r&&"function"==typeof r.get?r.get:null,a=o&&Map.prototype.forEach,s="function"==typeof Set&&Set.prototype,u=Object.getOwnPropertyDescriptor&&s?Object.getOwnPropertyDescriptor(Set.prototype,"size"):null,c=s&&u&&"function"==typeof u.get?u.get:null,l=s&&Set.prototype.forEach,d="function"==typeof WeakMap&&WeakMap.prototype?WeakMap.prototype.has:null,h="function"==typeof WeakSet&&WeakSet.prototype?WeakSet.prototype.has:null,p=Boolean.prototype.valueOf,f=Object.prototype.toString,g=Function.prototype.toString,m=String.prototype.match,_="function"==typeof BigInt?BigInt.prototype.valueOf:null,F=Object.getOwnPropertySymbols,y="function"==typeof Symbol?Symbol.prototype.toString:null,b=Object.prototype.propertyIsEnumerable,v=n(24654).custom,w=v&&S(v)?v:null;function E(e,t,n){var o="double"===(n.quoteStyle||t)?'"':"'";return o+e+o}function k(e){return String(e).replace(/"/g,""")}function D(e){return"[object Array]"===A(e)}function S(e){return"[object Symbol]"===A(e)}e.exports=function e(t,n,o,r){var s=n||{};if(C(s,"quoteStyle")&&"single"!==s.quoteStyle&&"double"!==s.quoteStyle)throw new TypeError('option "quoteStyle" must be "single" or "double"');if(C(s,"maxStringLength")&&("number"==typeof s.maxStringLength?s.maxStringLength<0&&s.maxStringLength!==1/0:null!==s.maxStringLength))throw new TypeError('option "maxStringLength", if provided, must be a positive integer, Infinity, or `null`');var u=!C(s,"customInspect")||s.customInspect;if("boolean"!=typeof u)throw new TypeError('option "customInspect", if provided, must be `true` or `false`');if(C(s,"indent")&&null!==s.indent&&"\t"!==s.indent&&!(parseInt(s.indent,10)===s.indent&&s.indent>0))throw new TypeError('options "indent" must be "\\t", an integer > 0, or `null`');if(void 0===t)return"undefined";if(null===t)return"null";if("boolean"==typeof t)return t?"true":"false";if("string"==typeof t)return R(t,s);if("number"==typeof t)return 0===t?1/0/t>0?"0":"-0":String(t);if("bigint"==typeof t)return String(t)+"n";var f=void 0===s.depth?5:s.depth;if(void 0===o&&(o=0),o>=f&&f>0&&"object"==typeof t)return D(t)?"[Array]":"[Object]";var F,b=function(e,t){var n;if("\t"===e.indent)n="\t";else{if(!("number"==typeof e.indent&&e.indent>0))return null;n=Array(e.indent+1).join(" ")}return{base:n,prev:Array(t+1).join(n)}}(s,o);if(void 0===r)r=[];else if(T(r,t)>=0)return"[Circular]";function v(t,n,i){if(n&&(r=r.slice()).push(n),i){var a={depth:s.depth};return C(s,"quoteStyle")&&(a.quoteStyle=s.quoteStyle),e(t,a,o+1,r)}return e(t,s,o+1,r)}if("function"==typeof t){var x=function(e){if(e.name)return e.name;var t=m.call(g.call(e),/^function\s*([\w$]+)/);return t?t[1]:null}(t),I=L(t,v);return"[Function"+(x?": "+x:" (anonymous)")+"]"+(I.length>0?" { "+I.join(", ")+" }":"")}if(S(t)){var P=y.call(t);return"object"==typeof t?M(P):P}if((F=t)&&"object"==typeof F&&("undefined"!=typeof HTMLElement&&F instanceof HTMLElement||"string"==typeof F.nodeName&&"function"==typeof F.getAttribute)){for(var U="<"+String(t.nodeName).toLowerCase(),j=t.attributes||[],q=0;q"}if(D(t)){if(0===t.length)return"[]";var z=L(t,v);return b&&!function(e){for(var t=0;t=0)return!1;return!0}(z)?"["+N(z,b)+"]":"[ "+z.join(", ")+" ]"}if(function(e){return"[object Error]"===A(e)}(t)){var K=L(t,v);return 0===K.length?"["+String(t)+"]":"{ ["+String(t)+"] "+K.join(", ")+" }"}if("object"==typeof t&&u){if(w&&"function"==typeof t[w])return t[w]();if("function"==typeof t.inspect)return t.inspect()}if(function(e){if(!i||!e||"object"!=typeof e)return!1;try{i.call(e);try{c.call(e)}catch(e){return!0}return e instanceof Map}catch(e){}return!1}(t)){var G=[];return a.call(t,(function(e,n){G.push(v(n,t,!0)+" => "+v(e,t))})),B("Map",i.call(t),G,b)}if(function(e){if(!c||!e||"object"!=typeof e)return!1;try{c.call(e);try{i.call(e)}catch(e){return!0}return e instanceof Set}catch(e){}return!1}(t)){var $=[];return l.call(t,(function(e){$.push(v(e,t))})),B("Set",c.call(t),$,b)}if(function(e){if(!d||!e||"object"!=typeof e)return!1;try{d.call(e,d);try{h.call(e,h)}catch(e){return!0}return e instanceof WeakMap}catch(e){}return!1}(t))return O("WeakMap");if(function(e){if(!h||!e||"object"!=typeof e)return!1;try{h.call(e,h);try{d.call(e,d)}catch(e){return!0}return e instanceof WeakSet}catch(e){}return!1}(t))return O("WeakSet");if(function(e){return"[object Number]"===A(e)}(t))return M(v(Number(t)));if(function(e){return"[object BigInt]"===A(e)}(t))return M(v(_.call(t)));if(function(e){return"[object Boolean]"===A(e)}(t))return M(p.call(t));if(function(e){return"[object String]"===A(e)}(t))return M(v(String(t)));if(!function(e){return"[object Date]"===A(e)}(t)&&!function(e){return"[object RegExp]"===A(e)}(t)){var H=L(t,v);return 0===H.length?"{}":b?"{"+N(H,b)+"}":"{ "+H.join(", ")+" }"}return String(t)};var x=Object.prototype.hasOwnProperty||function(e){return e in this};function C(e,t){return x.call(e,t)}function A(e){return f.call(e)}function T(e,t){if(e.indexOf)return e.indexOf(t);for(var n=0,o=e.length;nt.maxStringLength){var n=e.length-t.maxStringLength,o="... "+n+" more character"+(n>1?"s":"");return R(e.slice(0,t.maxStringLength),t)+o}return E(e.replace(/(['\\])/g,"\\$1").replace(/[\x00-\x1f]/g,I),"single",t)}function I(e){var t=e.charCodeAt(0),n={8:"b",9:"t",10:"n",12:"f",13:"r"}[t];return n?"\\"+n:"\\x"+(t<16?"0":"")+t.toString(16).toUpperCase()}function M(e){return"Object("+e+")"}function O(e){return e+" { ? }"}function B(e,t,n,o){return e+" ("+t+") {"+(o?N(n,o):n.join(", "))+"}"}function N(e,t){if(0===e.length)return"";var n="\n"+t.prev+t.base;return n+e.join(","+n)+"\n"+t.prev}function L(e,t){var n=D(e),o=[];if(n){o.length=e.length;for(var r=0;r{e.exports=function(e,t){return parseInt(e.toString(),t||8)}},93011:(e,t,n)=>{var o,r,i,a,s,u,c=(s={},i=(i="undefined"!=typeof document&&document.currentScript?document.currentScript.src:void 0)||"/index.js",u=function(t){var a,u,c;if(t=t||{},a||(a=void 0!==t?t:{}),a.ready=new Promise((function(e){u=e})),"undefined"!=typeof window)c=function(e){window.crypto.getRandomValues(e)};else{if(!e.exports)throw Error("Cannot find global to attach library to");var l=n(55835);c=function(e){var t=l.randomBytes(e.length);e.set(t)},process=n.g.process}if("undefined"!=typeof OLM_OPTIONS)for(var d in OLM_OPTIONS)OLM_OPTIONS.hasOwnProperty(d)&&(a[d]=OLM_OPTIONS[d]);a.onRuntimeInitialized=function(){Ce=a._olm_error(),s.PRIVATE_KEY_LENGTH=a._olm_pk_private_key_length(),o&&o()},a.onAbort=function(e){r&&r(e)};var h,p,f,g,m,_={};for(h in a)a.hasOwnProperty(h)&&(_[h]=a[h]);p="object"==typeof window,f="function"==typeof importScripts,g="object"==typeof process&&"object"==typeof process.versions&&"string"==typeof process.versions.node,m=!p&&!g&&!f;var F,y,b,v,w="";g?(w=f?n(26470).dirname(w)+"/":"//",F=function(e,t){return b||(b=n(23384)),v||(v=n(26470)),e=v.normalize(e),b.readFileSync(e,t?null:"utf8")},y=function(e){return(e=F(e,!0)).buffer||(e=new Uint8Array(e)),e.buffer||ne("Assertion failed: undefined"),e},1>0]=0;break;case"i16":U[e>>1]=0;break;case"i32":j[e>>2]=0;break;case"i64":ie=[0,1<=+X(0)?~~+J(0)>>>0:0],j[e>>2]=ie[0],j[e+4>>2]=ie[1];break;case"float":q[e>>2]=0;break;case"double":z[e>>3]=0;break;default:ne("invalid type for setValue: "+t)}}function x(e,t){switch("*"===(t=t||"i8").charAt(t.length-1)&&(t="i32"),t){case"i1":case"i8":return L[e>>0];case"i16":return U[e>>1];case"i32":case"i64":return j[e>>2];case"float":return q[e>>2];case"double":return z[e>>3];default:ne("invalid type for getValue: "+t)}return null}_=null,a.wasmBinary&&(E=a.wasmBinary),a.noExitRuntime&&a.noExitRuntime,"object"!=typeof WebAssembly&&ne("no native wasm support detected");var C,A=new WebAssembly.Table({initial:9,maximum:9,element:"anyfunc"}),T=!1,R="undefined"!=typeof TextDecoder?new TextDecoder("utf8"):void 0;function I(e,t){if(e){var n=P,o=e+t;for(t=e;n[t]&&!(t>=o);)++t;if(16(r=224==(240&r)?(15&r)<<12|i<<6|a:(7&r)<<18|i<<12|a<<6|63&n[e++])?o+=String.fromCharCode(r):(r-=65536,o+=String.fromCharCode(55296|r>>10,56320|1023&r))}}else o+=String.fromCharCode(r)}e=o}}else e="";return e}function M(e,t,n,o){if(!(0=a&&(a=65536+((1023&a)<<10)|1023&e.charCodeAt(++i)),127>=a){if(n>=o)break;t[n++]=a}else{if(2047>=a){if(n+1>=o)break;t[n++]=192|a>>6}else{if(65535>=a){if(n+2>=o)break;t[n++]=224|a>>12}else{if(n+3>=o)break;t[n++]=240|a>>18,t[n++]=128|a>>12&63}t[n++]=128|a>>6&63}t[n++]=128|63&a}}return t[n]=0,n-r}function O(e){for(var t=0,n=0;n=o&&(o=65536+((1023&o)<<10)|1023&e.charCodeAt(++n)),127>=o?++t:t=2047>=o?t+2:65535>=o?t+3:t+4}return t}function B(e,t){for(var n=0;n>0]=e.charCodeAt(n)}var N,L,P,U,j,q,z,K=a.INITIAL_MEMORY||262144;(C=a.wasmMemory?a.wasmMemory:new WebAssembly.Memory({initial:K/65536,maximum:K/65536}))&&(N=C.buffer),K=N.byteLength;var G=N;function $(e){for(;0{var o=n(52479);function r(e){var t=function(){return t.called?t.value:(t.called=!0,t.value=e.apply(this,arguments))};return t.called=!1,t}function i(e){var t=function(){if(t.called)throw new Error(t.onceError);return t.called=!0,t.value=e.apply(this,arguments)},n=e.name||"Function wrapped with `once`";return t.onceError=n+" shouldn't be called more than once",t.called=!1,t}e.exports=o(r),e.exports.strict=o(i),r.proto=r((function(){Object.defineProperty(Function.prototype,"once",{value:function(){return r(this)},configurable:!0}),Object.defineProperty(Function.prototype,"onceStrict",{value:function(){return i(this)},configurable:!0})}))},873:e=>{"use strict";e.exports=JSON.parse('{"2.16.840.1.101.3.4.1.1":"aes-128-ecb","2.16.840.1.101.3.4.1.2":"aes-128-cbc","2.16.840.1.101.3.4.1.3":"aes-128-ofb","2.16.840.1.101.3.4.1.4":"aes-128-cfb","2.16.840.1.101.3.4.1.21":"aes-192-ecb","2.16.840.1.101.3.4.1.22":"aes-192-cbc","2.16.840.1.101.3.4.1.23":"aes-192-ofb","2.16.840.1.101.3.4.1.24":"aes-192-cfb","2.16.840.1.101.3.4.1.41":"aes-256-ecb","2.16.840.1.101.3.4.1.42":"aes-256-cbc","2.16.840.1.101.3.4.1.43":"aes-256-ofb","2.16.840.1.101.3.4.1.44":"aes-256-cfb"}')},52818:(e,t,n)=>{"use strict";var o=n(39809);t.certificate=n(41934);var r=o.define("RSAPrivateKey",(function(){this.seq().obj(this.key("version").int(),this.key("modulus").int(),this.key("publicExponent").int(),this.key("privateExponent").int(),this.key("prime1").int(),this.key("prime2").int(),this.key("exponent1").int(),this.key("exponent2").int(),this.key("coefficient").int())}));t.RSAPrivateKey=r;var i=o.define("RSAPublicKey",(function(){this.seq().obj(this.key("modulus").int(),this.key("publicExponent").int())}));t.RSAPublicKey=i;var a=o.define("SubjectPublicKeyInfo",(function(){this.seq().obj(this.key("algorithm").use(s),this.key("subjectPublicKey").bitstr())}));t.PublicKey=a;var s=o.define("AlgorithmIdentifier",(function(){this.seq().obj(this.key("algorithm").objid(),this.key("none").null_().optional(),this.key("curve").objid().optional(),this.key("params").seq().obj(this.key("p").int(),this.key("q").int(),this.key("g").int()).optional())})),u=o.define("PrivateKeyInfo",(function(){this.seq().obj(this.key("version").int(),this.key("algorithm").use(s),this.key("subjectPrivateKey").octstr())}));t.PrivateKey=u;var c=o.define("EncryptedPrivateKeyInfo",(function(){this.seq().obj(this.key("algorithm").seq().obj(this.key("id").objid(),this.key("decrypt").seq().obj(this.key("kde").seq().obj(this.key("id").objid(),this.key("kdeparams").seq().obj(this.key("salt").octstr(),this.key("iters").int())),this.key("cipher").seq().obj(this.key("algo").objid(),this.key("iv").octstr()))),this.key("subjectPrivateKey").octstr())}));t.EncryptedPrivateKey=c;var l=o.define("DSAPrivateKey",(function(){this.seq().obj(this.key("version").int(),this.key("p").int(),this.key("q").int(),this.key("g").int(),this.key("pub_key").int(),this.key("priv_key").int())}));t.DSAPrivateKey=l,t.DSAparam=o.define("DSAparam",(function(){this.int()}));var d=o.define("ECPrivateKey",(function(){this.seq().obj(this.key("version").int(),this.key("privateKey").octstr(),this.key("parameters").optional().explicit(0).use(h),this.key("publicKey").optional().explicit(1).bitstr())}));t.ECPrivateKey=d;var h=o.define("ECParameters",(function(){this.choice({namedCurve:this.objid()})}));t.signature=o.define("signature",(function(){this.seq().obj(this.key("r").int(),this.key("s").int())}))},41934:(e,t,n)=>{"use strict";var o=n(39809),r=o.define("Time",(function(){this.choice({utcTime:this.utctime(),generalTime:this.gentime()})})),i=o.define("AttributeTypeValue",(function(){this.seq().obj(this.key("type").objid(),this.key("value").any())})),a=o.define("AlgorithmIdentifier",(function(){this.seq().obj(this.key("algorithm").objid(),this.key("parameters").optional(),this.key("curve").objid().optional())})),s=o.define("SubjectPublicKeyInfo",(function(){this.seq().obj(this.key("algorithm").use(a),this.key("subjectPublicKey").bitstr())})),u=o.define("RelativeDistinguishedName",(function(){this.setof(i)})),c=o.define("RDNSequence",(function(){this.seqof(u)})),l=o.define("Name",(function(){this.choice({rdnSequence:this.use(c)})})),d=o.define("Validity",(function(){this.seq().obj(this.key("notBefore").use(r),this.key("notAfter").use(r))})),h=o.define("Extension",(function(){this.seq().obj(this.key("extnID").objid(),this.key("critical").bool().def(!1),this.key("extnValue").octstr())})),p=o.define("TBSCertificate",(function(){this.seq().obj(this.key("version").explicit(0).int().optional(),this.key("serialNumber").int(),this.key("signature").use(a),this.key("issuer").use(l),this.key("validity").use(d),this.key("subject").use(l),this.key("subjectPublicKeyInfo").use(s),this.key("issuerUniqueID").implicit(1).bitstr().optional(),this.key("subjectUniqueID").implicit(2).bitstr().optional(),this.key("extensions").explicit(3).seqof(h).optional())})),f=o.define("X509Certificate",(function(){this.seq().obj(this.key("tbsCertificate").use(p),this.key("signatureAlgorithm").use(a),this.key("signatureValue").bitstr())}));e.exports=f},77631:(e,t,n)=>{var o=/Proc-Type: 4,ENCRYPTED[\n\r]+DEK-Info: AES-((?:128)|(?:192)|(?:256))-CBC,([0-9A-H]+)[\n\r]+([0-9A-z\n\r+/=]+)[\n\r]+/m,r=/^-----BEGIN ((?:.*? KEY)|CERTIFICATE)-----/m,i=/^-----BEGIN ((?:.*? KEY)|CERTIFICATE)-----([0-9A-z\n\r+/=]+)-----END \1-----$/m,a=n(13048),s=n(44696),u=n(89509).Buffer;e.exports=function(e,t){var n,c=e.toString(),l=c.match(o);if(l){var d="aes"+l[1],h=u.from(l[2],"hex"),p=u.from(l[3].replace(/[\r\n]/g,""),"base64"),f=a(t,h.slice(0,8),parseInt(l[1],10)).key,g=[],m=s.createDecipheriv(d,f,h);g.push(m.update(p)),g.push(m.final()),n=u.concat(g)}else{var _=c.match(i);n=u.from(_[2].replace(/[\r\n]/g,""),"base64")}return{tag:c.match(r)[1],data:n}}},70980:(e,t,n)=>{var o=n(52818),r=n(873),i=n(77631),a=n(44696),s=n(25632),u=n(89509).Buffer;function c(e){var t;"object"!=typeof e||u.isBuffer(e)||(t=e.passphrase,e=e.key),"string"==typeof e&&(e=u.from(e));var n,c,l=i(e,t),d=l.tag,h=l.data;switch(d){case"CERTIFICATE":c=o.certificate.decode(h,"der").tbsCertificate.subjectPublicKeyInfo;case"PUBLIC KEY":switch(c||(c=o.PublicKey.decode(h,"der")),n=c.algorithm.algorithm.join(".")){case"1.2.840.113549.1.1.1":return o.RSAPublicKey.decode(c.subjectPublicKey.data,"der");case"1.2.840.10045.2.1":return c.subjectPrivateKey=c.subjectPublicKey,{type:"ec",data:c};case"1.2.840.10040.4.1":return c.algorithm.params.pub_key=o.DSAparam.decode(c.subjectPublicKey.data,"der"),{type:"dsa",data:c.algorithm.params};default:throw new Error("unknown key id "+n)}case"ENCRYPTED PRIVATE KEY":h=function(e,t){var n=e.algorithm.decrypt.kde.kdeparams.salt,o=parseInt(e.algorithm.decrypt.kde.kdeparams.iters.toString(),10),i=r[e.algorithm.decrypt.cipher.algo.join(".")],c=e.algorithm.decrypt.cipher.iv,l=e.subjectPrivateKey,d=parseInt(i.split("-")[1],10)/8,h=s.pbkdf2Sync(t,n,o,d,"sha1"),p=a.createDecipheriv(i,h,c),f=[];return f.push(p.update(l)),f.push(p.final()),u.concat(f)}(h=o.EncryptedPrivateKey.decode(h,"der"),t);case"PRIVATE KEY":switch(n=(c=o.PrivateKey.decode(h,"der")).algorithm.algorithm.join(".")){case"1.2.840.113549.1.1.1":return o.RSAPrivateKey.decode(c.subjectPrivateKey,"der");case"1.2.840.10045.2.1":return{curve:c.algorithm.curve,privateKey:o.ECPrivateKey.decode(c.subjectPrivateKey,"der").privateKey};case"1.2.840.10040.4.1":return c.algorithm.params.priv_key=o.DSAparam.decode(c.subjectPrivateKey,"der"),{type:"dsa",params:c.algorithm.params};default:throw new Error("unknown key id "+n)}case"RSA PUBLIC KEY":return o.RSAPublicKey.decode(h,"der");case"RSA PRIVATE KEY":return o.RSAPrivateKey.decode(h,"der");case"DSA PRIVATE KEY":return{type:"dsa",params:o.DSAPrivateKey.decode(h,"der")};case"EC PRIVATE KEY":return{curve:(h=o.ECPrivateKey.decode(h,"der")).parameters.value,privateKey:h.privateKey};default:throw new Error("unknown key type "+d)}}e.exports=c,c.signature=o.signature},89435:e=>{"use strict";var t;e.exports=function(e){var n,o="&"+e+";";return(t=t||document.createElement("i")).innerHTML=o,(59!==(n=t.textContent).charCodeAt(n.length-1)||"semi"===e)&&(n!==o&&n)}},57574:(e,t,n)=>{"use strict";var o=n(16588),r=n(6852),i=n(46195),a=n(79480),s=n(7961),u=n(89435);e.exports=function(e,t){var n,i,a={};for(i in t||(t={}),h)n=t[i],a[i]=null==n?h[i]:n;return(a.position.indent||a.position.start)&&(a.indent=a.position.indent||[],a.position=a.position.start),function(e,t){var n,i,a,h,b,v,w,E,k,D,S,x,C,A,T,R,I,M,O,B,N=t.additional,L=t.nonTerminated,P=t.text,U=t.reference,j=t.warning,q=t.textContext,z=t.referenceContext,K=t.warningContext,G=t.position,$=t.indent||[],H=e.length,V=0,W=-1,Y=G.column||1,Z=G.line||1,X="",J=[];for("string"==typeof N&&(N=N.charCodeAt(0)),R=Q(),E=j?function(e,t){var n=Q();n.column+=t,n.offset+=t,j.call(K,F[e],n,e)}:d,V--,H++;++V=55296&&B<=57343||B>1114111?(E(7,M),v=l(65533)):v in r?(E(6,M),v=r[v]):(D="",y(v)&&E(6,M),v>65535&&(D+=l((v-=65536)>>>10|55296),v=56320|1023&v),v=D+l(v))):A!==p&&E(4,M)),v?(ee(),R=Q(),V=O-1,Y+=O-C+1,J.push(v),(I=Q()).offset++,U&&U.call(z,v,{start:R,end:I},e.slice(C-1,O)),R=I):(h=e.slice(C-1,O),X+=h,Y+=h.length,V=O-1)}else 10===b&&(Z++,W++,Y=0),b==b?(X+=l(b),Y++):ee();return J.join("");function Q(){return{line:Z,column:Y,offset:V+(G.offset||0)}}function ee(){X&&(J.push(X),P&&P.call(q,X,{start:R,end:Q()}),X="")}}(e,a)};var c={}.hasOwnProperty,l=String.fromCharCode,d=Function.prototype,h={warning:null,reference:null,text:null,warningContext:null,referenceContext:null,textContext:null,position:{},additional:null,attribute:!1,nonTerminated:!0},p="named",f="hexadecimal",g="decimal",m={hexadecimal:16,decimal:10},_={};_.named=s,_[g]=i,_[f]=a;var F={};function y(e){return e>=1&&e<=8||11===e||e>=13&&e<=31||e>=127&&e<=159||e>=64976&&e<=65007||65535==(65535&e)||65534==(65535&e)}F[1]="Named character references must be terminated by a semicolon",F[2]="Numeric character references must be terminated by a semicolon",F[3]="Named character references cannot be empty",F[4]="Numeric character references cannot be empty",F[5]="Named character references must be known",F[6]="Numeric character references cannot be disallowed",F[7]="Numeric character references cannot be outside the permissible Unicode range"},26470:e=>{"use strict";function t(e){if("string"!=typeof e)throw new TypeError("Path must be a string. Received "+JSON.stringify(e))}function n(e,t){for(var n,o="",r=0,i=-1,a=0,s=0;s<=e.length;++s){if(s2){var u=o.lastIndexOf("/");if(u!==o.length-1){-1===u?(o="",r=0):r=(o=o.slice(0,u)).length-1-o.lastIndexOf("/"),i=s,a=0;continue}}else if(2===o.length||1===o.length){o="",r=0,i=s,a=0;continue}t&&(o.length>0?o+="/..":o="..",r=2)}else o.length>0?o+="/"+e.slice(i+1,s):o=e.slice(i+1,s),r=s-i-1;i=s,a=0}else 46===n&&-1!==a?++a:a=-1}return o}var o={resolve:function(){for(var e,o="",r=!1,i=arguments.length-1;i>=-1&&!r;i--){var a;i>=0?a=arguments[i]:(void 0===e&&(e=process.cwd()),a=e),t(a),0!==a.length&&(o=a+"/"+o,r=47===a.charCodeAt(0))}return o=n(o,!r),r?o.length>0?"/"+o:"/":o.length>0?o:"."},normalize:function(e){if(t(e),0===e.length)return".";var o=47===e.charCodeAt(0),r=47===e.charCodeAt(e.length-1);return 0!==(e=n(e,!o)).length||o||(e="."),e.length>0&&r&&(e+="/"),o?"/"+e:e},isAbsolute:function(e){return t(e),e.length>0&&47===e.charCodeAt(0)},join:function(){if(0===arguments.length)return".";for(var e,n=0;n0&&(void 0===e?e=r:e+="/"+r)}return void 0===e?".":o.normalize(e)},relative:function(e,n){if(t(e),t(n),e===n)return"";if((e=o.resolve(e))===(n=o.resolve(n)))return"";for(var r=1;rc){if(47===n.charCodeAt(s+d))return n.slice(s+d+1);if(0===d)return n.slice(s+d)}else a>c&&(47===e.charCodeAt(r+d)?l=d:0===d&&(l=0));break}var h=e.charCodeAt(r+d);if(h!==n.charCodeAt(s+d))break;47===h&&(l=d)}var p="";for(d=r+l+1;d<=i;++d)d!==i&&47!==e.charCodeAt(d)||(0===p.length?p+="..":p+="/..");return p.length>0?p+n.slice(s+l):(s+=l,47===n.charCodeAt(s)&&++s,n.slice(s))},_makeLong:function(e){return e},dirname:function(e){if(t(e),0===e.length)return".";for(var n=e.charCodeAt(0),o=47===n,r=-1,i=!0,a=e.length-1;a>=1;--a)if(47===(n=e.charCodeAt(a))){if(!i){r=a;break}}else i=!1;return-1===r?o?"/":".":o&&1===r?"//":e.slice(0,r)},basename:function(e,n){if(void 0!==n&&"string"!=typeof n)throw new TypeError('"ext" argument must be a string');t(e);var o,r=0,i=-1,a=!0;if(void 0!==n&&n.length>0&&n.length<=e.length){if(n.length===e.length&&n===e)return"";var s=n.length-1,u=-1;for(o=e.length-1;o>=0;--o){var c=e.charCodeAt(o);if(47===c){if(!a){r=o+1;break}}else-1===u&&(a=!1,u=o+1),s>=0&&(c===n.charCodeAt(s)?-1==--s&&(i=o):(s=-1,i=u))}return r===i?i=u:-1===i&&(i=e.length),e.slice(r,i)}for(o=e.length-1;o>=0;--o)if(47===e.charCodeAt(o)){if(!a){r=o+1;break}}else-1===i&&(a=!1,i=o+1);return-1===i?"":e.slice(r,i)},extname:function(e){t(e);for(var n=-1,o=0,r=-1,i=!0,a=0,s=e.length-1;s>=0;--s){var u=e.charCodeAt(s);if(47!==u)-1===r&&(i=!1,r=s+1),46===u?-1===n?n=s:1!==a&&(a=1):-1!==n&&(a=-1);else if(!i){o=s+1;break}}return-1===n||-1===r||0===a||1===a&&n===r-1&&n===o+1?"":e.slice(n,r)},format:function(e){if(null===e||"object"!=typeof e)throw new TypeError('The "pathObject" argument must be of type Object. Received type '+typeof e);return function(e,t){var n=t.dir||t.root,o=t.base||(t.name||"")+(t.ext||"");return n?n===t.root?n+o:n+"/"+o:o}(0,e)},parse:function(e){t(e);var n={root:"",dir:"",base:"",ext:"",name:""};if(0===e.length)return n;var o,r=e.charCodeAt(0),i=47===r;i?(n.root="/",o=1):o=0;for(var a=-1,s=0,u=-1,c=!0,l=e.length-1,d=0;l>=o;--l)if(47!==(r=e.charCodeAt(l)))-1===u&&(c=!1,u=l+1),46===r?-1===a?a=l:1!==d&&(d=1):-1!==a&&(d=-1);else if(!c){s=l+1;break}return-1===a||-1===u||0===d||1===d&&a===u-1&&a===s+1?-1!==u&&(n.base=n.name=0===s&&i?e.slice(1,u):e.slice(s,u)):(0===s&&i?(n.name=e.slice(1,a),n.base=e.slice(1,u)):(n.name=e.slice(s,a),n.base=e.slice(s,u)),n.ext=e.slice(a,u)),s>0?n.dir=e.slice(0,s-1):i&&(n.dir="/"),n},sep:"/",delimiter:":",win32:null,posix:null};o.posix=o,e.exports=o},25632:(e,t,n)=>{t.pbkdf2=n(88638),t.pbkdf2Sync=n(91257)},88638:(e,t,n)=>{var o,r=n(89509).Buffer,i=n(77357),a=n(12368),s=n(91257),u=n(57777),c=n.g.crypto&&n.g.crypto.subtle,l={sha:"SHA-1","sha-1":"SHA-1",sha1:"SHA-1",sha256:"SHA-256","sha-256":"SHA-256",sha384:"SHA-384","sha-384":"SHA-384","sha-512":"SHA-512",sha512:"SHA-512"},d=[];function h(e,t,n,o,i){return c.importKey("raw",e,{name:"PBKDF2"},!1,["deriveBits"]).then((function(e){return c.deriveBits({name:"PBKDF2",salt:t,iterations:n,hash:{name:i}},e,o<<3)})).then((function(e){return r.from(e)}))}e.exports=function(e,t,p,f,g,m){"function"==typeof g&&(m=g,g=void 0);var _=l[(g=g||"sha1").toLowerCase()];if(!_||"function"!=typeof n.g.Promise)return process.nextTick((function(){var n;try{n=s(e,t,p,f,g)}catch(e){return m(e)}m(null,n)}));if(i(p,f),e=u(e,a,"Password"),t=u(t,a,"Salt"),"function"!=typeof m)throw new Error("No callback provided to pbkdf2");!function(e,t){e.then((function(e){process.nextTick((function(){t(null,e)}))}),(function(e){process.nextTick((function(){t(e)}))}))}(function(e){if(n.g.process&&!n.g.process.browser)return Promise.resolve(!1);if(!c||!c.importKey||!c.deriveBits)return Promise.resolve(!1);if(void 0!==d[e])return d[e];var t=h(o=o||r.alloc(8),o,10,128,e).then((function(){return!0})).catch((function(){return!1}));return d[e]=t,t}(_).then((function(n){return n?h(e,t,p,f,_):s(e,t,p,f,g)})),m)}},12368:e=>{var t;t=process.browser?"utf-8":process.version?parseInt(process.version.split(".")[0].slice(1),10)>=6?"utf-8":"binary":"utf-8",e.exports=t},77357:e=>{var t=Math.pow(2,30)-1;e.exports=function(e,n){if("number"!=typeof e)throw new TypeError("Iterations not a number");if(e<0)throw new TypeError("Bad iterations");if("number"!=typeof n)throw new TypeError("Key length not a number");if(n<0||n>t||n!=n)throw new TypeError("Bad key length")}},91257:(e,t,n)=>{var o=n(78028),r=n(79785),i=n(89072),a=n(89509).Buffer,s=n(77357),u=n(12368),c=n(57777),l=a.alloc(128),d={md5:16,sha1:20,sha224:28,sha256:32,sha384:48,sha512:64,rmd160:20,ripemd160:20};function h(e,t,n){var s=function(e){return"rmd160"===e||"ripemd160"===e?function(e){return(new r).update(e).digest()}:"md5"===e?o:function(t){return i(e).update(t).digest()}}(e),u="sha512"===e||"sha384"===e?128:64;t.length>u?t=s(t):t.length{var o=n(89509).Buffer;e.exports=function(e,t,n){if(o.isBuffer(e))return e;if("string"==typeof e)return o.from(e,t);if(ArrayBuffer.isView(e))return o.from(e.buffer);throw new TypeError(n+" must be a string, a Buffer, a typed array or a DataView")}},28325:(e,t,n)=>{var o=function(e){var t=/\blang(?:uage)?-([\w-]+)\b/i,n=0,o={manual:e.Prism&&e.Prism.manual,disableWorkerMessageHandler:e.Prism&&e.Prism.disableWorkerMessageHandler,util:{encode:function e(t){return t instanceof r?new r(t.type,e(t.content),t.alias):Array.isArray(t)?t.map(e):t.replace(/&/g,"&").replace(/=d.reach);E+=w.value.length,w=w.next){var k=w.value;if(t.length>e.length)return;if(!(k instanceof r)){var D,S=1;if(F){if(!(D=i(v,E,e,_)))break;var x=D.index,C=D.index+D[0].length,A=E;for(A+=w.value.length;x>=A;)A+=(w=w.next).value.length;if(E=A-=w.value.length,w.value instanceof r)continue;for(var T=w;T!==t.tail&&(Ad.reach&&(d.reach=O);var B=w.prev;I&&(B=u(t,B,I),E+=I.length),c(t,B,S),w=u(t,B,new r(h,m?o.tokenize(R,m):R,y,R)),M&&u(t,w,M),S>1&&a(e,t,n,w.prev,E,{cause:h+","+f,reach:O})}}}}}function s(){var e={value:null,prev:null,next:null},t={value:null,prev:e,next:null};e.next=t,this.head=e,this.tail=t,this.length=0}function u(e,t,n){var o=t.next,r={value:n,prev:t,next:o};return t.next=r,o.prev=r,e.length++,r}function c(e,t,n){for(var o=t.next,r=0;r"+i.content+""},!e.document)return e.addEventListener?(o.disableWorkerMessageHandler||e.addEventListener("message",(function(t){var n=JSON.parse(t.data),r=n.language,i=n.code,a=n.immediateClose;e.postMessage(o.highlight(i,o.languages[r],r)),a&&e.close()}),!1),o):o;var l=o.util.currentScript();function d(){o.manual||o.highlightAll()}if(l&&(o.filename=l.src,l.hasAttribute("data-manual")&&(o.manual=!0)),!o.manual){var h=document.readyState;"loading"===h||"interactive"===h&&l&&l.defer?document.addEventListener("DOMContentLoaded",d):window.requestAnimationFrame?window.requestAnimationFrame(d):window.setTimeout(d,16)}return o}("undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{});e.exports&&(e.exports=o),void 0!==n.g&&(n.g.Prism=o)},88212:e=>{"use strict";"undefined"==typeof process||!process.version||0===process.version.indexOf("v0.")||0===process.version.indexOf("v1.")&&0!==process.version.indexOf("v1.8.")?e.exports={nextTick:function(e,t,n,o){if("function"!=typeof e)throw new TypeError('"callback" argument must be a function');var r,i,a=arguments.length;switch(a){case 0:case 1:return process.nextTick(e);case 2:return process.nextTick((function(){e.call(null,t)}));case 3:return process.nextTick((function(){e.call(null,t,n)}));case 4:return process.nextTick((function(){e.call(null,t,n,o)}));default:for(r=new Array(a-1),i=0;i{"use strict";var o=n(50414);function r(){}function i(){}i.resetWarningCache=r,e.exports=function(){function e(e,t,n,r,i,a){if(a!==o){var s=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw s.name="Invariant Violation",s}}function t(){return e}e.isRequired=e;var n={array:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,elementType:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t,checkPropTypes:i,resetWarningCache:r};return n.PropTypes=n,n}},45697:(e,t,n)=>{e.exports=n(92703)()},50414:e=>{"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},99560:(e,t,n)=>{"use strict";var o=n(66632),r=n(98805),i=n(89750),a="data";e.exports=function(e,t){var n=o(t),h=t,p=i;return n in e.normal?e.property[e.normal[n]]:(n.length>4&&n.slice(0,4)===a&&s.test(t)&&("-"===t.charAt(4)?h=function(e){var t=e.slice(5).replace(u,d);return a+t.charAt(0).toUpperCase()+t.slice(1)}(t):t=function(e){var t=e.slice(4);return u.test(t)?e:("-"!==(t=t.replace(c,l)).charAt(0)&&(t="-"+t),a+t)}(t),p=r),new p(h,t))};var s=/^data[-\w.:]+$/i,u=/-[a-z]/g,c=/[A-Z]/g;function l(e){return"-"+e.toLowerCase()}function d(e){return e.charAt(1).toUpperCase()}},93934:e=>{"use strict";e.exports=JSON.parse('{"classId":"classID","dataType":"datatype","itemId":"itemID","strokeDashArray":"strokeDasharray","strokeDashOffset":"strokeDashoffset","strokeLineCap":"strokeLinecap","strokeLineJoin":"strokeLinejoin","strokeMiterLimit":"strokeMiterlimit","typeOf":"typeof","xLinkActuate":"xlinkActuate","xLinkArcRole":"xlinkArcrole","xLinkHref":"xlinkHref","xLinkRole":"xlinkRole","xLinkShow":"xlinkShow","xLinkTitle":"xlinkTitle","xLinkType":"xlinkType","xmlnsXLink":"xmlnsXlink"}')},97247:(e,t,n)=>{"use strict";var o=n(19940),r=n(8289),i=n(5812),a=n(94397),s=n(67716),u=n(61805);e.exports=o([i,r,a,s,u])},67716:(e,t,n)=>{"use strict";var o=n(17e3),r=n(17596),i=o.booleanish,a=o.number,s=o.spaceSeparated;e.exports=r({transform:function(e,t){return"role"===t?t:"aria-"+t.slice(4).toLowerCase()},properties:{ariaActiveDescendant:null,ariaAtomic:i,ariaAutoComplete:null,ariaBusy:i,ariaChecked:i,ariaColCount:a,ariaColIndex:a,ariaColSpan:a,ariaControls:s,ariaCurrent:null,ariaDescribedBy:s,ariaDetails:null,ariaDisabled:i,ariaDropEffect:s,ariaErrorMessage:null,ariaExpanded:i,ariaFlowTo:s,ariaGrabbed:i,ariaHasPopup:null,ariaHidden:i,ariaInvalid:null,ariaKeyShortcuts:null,ariaLabel:null,ariaLabelledBy:s,ariaLevel:a,ariaLive:null,ariaModal:i,ariaMultiLine:i,ariaMultiSelectable:i,ariaOrientation:null,ariaOwns:s,ariaPlaceholder:null,ariaPosInSet:a,ariaPressed:i,ariaReadOnly:i,ariaRelevant:null,ariaRequired:i,ariaRoleDescription:s,ariaRowCount:a,ariaRowIndex:a,ariaRowSpan:a,ariaSelected:i,ariaSetSize:a,ariaSort:null,ariaValueMax:a,ariaValueMin:a,ariaValueNow:a,ariaValueText:null,role:null}})},61805:(e,t,n)=>{"use strict";var o=n(17e3),r=n(17596),i=n(10855),a=o.boolean,s=o.overloadedBoolean,u=o.booleanish,c=o.number,l=o.spaceSeparated,d=o.commaSeparated;e.exports=r({space:"html",attributes:{acceptcharset:"accept-charset",classname:"class",htmlfor:"for",httpequiv:"http-equiv"},transform:i,mustUseProperty:["checked","multiple","muted","selected"],properties:{abbr:null,accept:d,acceptCharset:l,accessKey:l,action:null,allow:null,allowFullScreen:a,allowPaymentRequest:a,allowUserMedia:a,alt:null,as:null,async:a,autoCapitalize:null,autoComplete:l,autoFocus:a,autoPlay:a,capture:a,charSet:null,checked:a,cite:null,className:l,cols:c,colSpan:null,content:null,contentEditable:u,controls:a,controlsList:l,coords:c|d,crossOrigin:null,data:null,dateTime:null,decoding:null,default:a,defer:a,dir:null,dirName:null,disabled:a,download:s,draggable:u,encType:null,enterKeyHint:null,form:null,formAction:null,formEncType:null,formMethod:null,formNoValidate:a,formTarget:null,headers:l,height:c,hidden:a,high:c,href:null,hrefLang:null,htmlFor:l,httpEquiv:l,id:null,imageSizes:null,imageSrcSet:d,inputMode:null,integrity:null,is:null,isMap:a,itemId:null,itemProp:l,itemRef:l,itemScope:a,itemType:l,kind:null,label:null,lang:null,language:null,list:null,loading:null,loop:a,low:c,manifest:null,max:null,maxLength:c,media:null,method:null,min:null,minLength:c,multiple:a,muted:a,name:null,nonce:null,noModule:a,noValidate:a,onAbort:null,onAfterPrint:null,onAuxClick:null,onBeforePrint:null,onBeforeUnload:null,onBlur:null,onCancel:null,onCanPlay:null,onCanPlayThrough:null,onChange:null,onClick:null,onClose:null,onContextMenu:null,onCopy:null,onCueChange:null,onCut:null,onDblClick:null,onDrag:null,onDragEnd:null,onDragEnter:null,onDragExit:null,onDragLeave:null,onDragOver:null,onDragStart:null,onDrop:null,onDurationChange:null,onEmptied:null,onEnded:null,onError:null,onFocus:null,onFormData:null,onHashChange:null,onInput:null,onInvalid:null,onKeyDown:null,onKeyPress:null,onKeyUp:null,onLanguageChange:null,onLoad:null,onLoadedData:null,onLoadedMetadata:null,onLoadEnd:null,onLoadStart:null,onMessage:null,onMessageError:null,onMouseDown:null,onMouseEnter:null,onMouseLeave:null,onMouseMove:null,onMouseOut:null,onMouseOver:null,onMouseUp:null,onOffline:null,onOnline:null,onPageHide:null,onPageShow:null,onPaste:null,onPause:null,onPlay:null,onPlaying:null,onPopState:null,onProgress:null,onRateChange:null,onRejectionHandled:null,onReset:null,onResize:null,onScroll:null,onSecurityPolicyViolation:null,onSeeked:null,onSeeking:null,onSelect:null,onSlotChange:null,onStalled:null,onStorage:null,onSubmit:null,onSuspend:null,onTimeUpdate:null,onToggle:null,onUnhandledRejection:null,onUnload:null,onVolumeChange:null,onWaiting:null,onWheel:null,open:a,optimum:c,pattern:null,ping:l,placeholder:null,playsInline:a,poster:null,preload:null,readOnly:a,referrerPolicy:null,rel:l,required:a,reversed:a,rows:c,rowSpan:c,sandbox:l,scope:null,scoped:a,seamless:a,selected:a,shape:null,size:c,sizes:null,slot:null,span:c,spellCheck:u,src:null,srcDoc:null,srcLang:null,srcSet:d,start:c,step:null,style:null,tabIndex:c,target:null,title:null,translate:null,type:null,typeMustMatch:a,useMap:null,value:u,width:c,wrap:null,align:null,aLink:null,archive:l,axis:null,background:null,bgColor:null,border:c,borderColor:null,bottomMargin:c,cellPadding:null,cellSpacing:null,char:null,charOff:null,classId:null,clear:null,code:null,codeBase:null,codeType:null,color:null,compact:a,declare:a,event:null,face:null,frame:null,frameBorder:null,hSpace:c,leftMargin:c,link:null,longDesc:null,lowSrc:null,marginHeight:c,marginWidth:c,noResize:a,noHref:a,noShade:a,noWrap:a,object:null,profile:null,prompt:null,rev:null,rightMargin:c,rules:null,scheme:null,scrolling:u,standby:null,summary:null,text:null,topMargin:c,valueType:null,version:null,vAlign:null,vLink:null,vSpace:c,allowTransparency:null,autoCorrect:null,autoSave:null,disablePictureInPicture:a,disableRemotePlayback:a,prefix:null,property:null,results:c,security:null,unselectable:null}})},97421:(e,t,n)=>{"use strict";var o=n(17e3),r=n(17596),i=n(28740),a=o.boolean,s=o.number,u=o.spaceSeparated,c=o.commaSeparated,l=o.commaOrSpaceSeparated;e.exports=r({space:"svg",attributes:{accentHeight:"accent-height",alignmentBaseline:"alignment-baseline",arabicForm:"arabic-form",baselineShift:"baseline-shift",capHeight:"cap-height",className:"class",clipPath:"clip-path",clipRule:"clip-rule",colorInterpolation:"color-interpolation",colorInterpolationFilters:"color-interpolation-filters",colorProfile:"color-profile",colorRendering:"color-rendering",crossOrigin:"crossorigin",dataType:"datatype",dominantBaseline:"dominant-baseline",enableBackground:"enable-background",fillOpacity:"fill-opacity",fillRule:"fill-rule",floodColor:"flood-color",floodOpacity:"flood-opacity",fontFamily:"font-family",fontSize:"font-size",fontSizeAdjust:"font-size-adjust",fontStretch:"font-stretch",fontStyle:"font-style",fontVariant:"font-variant",fontWeight:"font-weight",glyphName:"glyph-name",glyphOrientationHorizontal:"glyph-orientation-horizontal",glyphOrientationVertical:"glyph-orientation-vertical",hrefLang:"hreflang",horizAdvX:"horiz-adv-x",horizOriginX:"horiz-origin-x",horizOriginY:"horiz-origin-y",imageRendering:"image-rendering",letterSpacing:"letter-spacing",lightingColor:"lighting-color",markerEnd:"marker-end",markerMid:"marker-mid",markerStart:"marker-start",navDown:"nav-down",navDownLeft:"nav-down-left",navDownRight:"nav-down-right",navLeft:"nav-left",navNext:"nav-next",navPrev:"nav-prev",navRight:"nav-right",navUp:"nav-up",navUpLeft:"nav-up-left",navUpRight:"nav-up-right",onAbort:"onabort",onActivate:"onactivate",onAfterPrint:"onafterprint",onBeforePrint:"onbeforeprint",onBegin:"onbegin",onCancel:"oncancel",onCanPlay:"oncanplay",onCanPlayThrough:"oncanplaythrough",onChange:"onchange",onClick:"onclick",onClose:"onclose",onCopy:"oncopy",onCueChange:"oncuechange",onCut:"oncut",onDblClick:"ondblclick",onDrag:"ondrag",onDragEnd:"ondragend",onDragEnter:"ondragenter",onDragExit:"ondragexit",onDragLeave:"ondragleave",onDragOver:"ondragover",onDragStart:"ondragstart",onDrop:"ondrop",onDurationChange:"ondurationchange",onEmptied:"onemptied",onEnd:"onend",onEnded:"onended",onError:"onerror",onFocus:"onfocus",onFocusIn:"onfocusin",onFocusOut:"onfocusout",onHashChange:"onhashchange",onInput:"oninput",onInvalid:"oninvalid",onKeyDown:"onkeydown",onKeyPress:"onkeypress",onKeyUp:"onkeyup",onLoad:"onload",onLoadedData:"onloadeddata",onLoadedMetadata:"onloadedmetadata",onLoadStart:"onloadstart",onMessage:"onmessage",onMouseDown:"onmousedown",onMouseEnter:"onmouseenter",onMouseLeave:"onmouseleave",onMouseMove:"onmousemove",onMouseOut:"onmouseout",onMouseOver:"onmouseover",onMouseUp:"onmouseup",onMouseWheel:"onmousewheel",onOffline:"onoffline",onOnline:"ononline",onPageHide:"onpagehide",onPageShow:"onpageshow",onPaste:"onpaste",onPause:"onpause",onPlay:"onplay",onPlaying:"onplaying",onPopState:"onpopstate",onProgress:"onprogress",onRateChange:"onratechange",onRepeat:"onrepeat",onReset:"onreset",onResize:"onresize",onScroll:"onscroll",onSeeked:"onseeked",onSeeking:"onseeking",onSelect:"onselect",onShow:"onshow",onStalled:"onstalled",onStorage:"onstorage",onSubmit:"onsubmit",onSuspend:"onsuspend",onTimeUpdate:"ontimeupdate",onToggle:"ontoggle",onUnload:"onunload",onVolumeChange:"onvolumechange",onWaiting:"onwaiting",onZoom:"onzoom",overlinePosition:"overline-position",overlineThickness:"overline-thickness",paintOrder:"paint-order",panose1:"panose-1",pointerEvents:"pointer-events",referrerPolicy:"referrerpolicy",renderingIntent:"rendering-intent",shapeRendering:"shape-rendering",stopColor:"stop-color",stopOpacity:"stop-opacity",strikethroughPosition:"strikethrough-position",strikethroughThickness:"strikethrough-thickness",strokeDashArray:"stroke-dasharray",strokeDashOffset:"stroke-dashoffset",strokeLineCap:"stroke-linecap",strokeLineJoin:"stroke-linejoin",strokeMiterLimit:"stroke-miterlimit",strokeOpacity:"stroke-opacity",strokeWidth:"stroke-width",tabIndex:"tabindex",textAnchor:"text-anchor",textDecoration:"text-decoration",textRendering:"text-rendering",typeOf:"typeof",underlinePosition:"underline-position",underlineThickness:"underline-thickness",unicodeBidi:"unicode-bidi",unicodeRange:"unicode-range",unitsPerEm:"units-per-em",vAlphabetic:"v-alphabetic",vHanging:"v-hanging",vIdeographic:"v-ideographic",vMathematical:"v-mathematical",vectorEffect:"vector-effect",vertAdvY:"vert-adv-y",vertOriginX:"vert-origin-x",vertOriginY:"vert-origin-y",wordSpacing:"word-spacing",writingMode:"writing-mode",xHeight:"x-height",playbackOrder:"playbackorder",timelineBegin:"timelinebegin"},transform:i,properties:{about:l,accentHeight:s,accumulate:null,additive:null,alignmentBaseline:null,alphabetic:s,amplitude:s,arabicForm:null,ascent:s,attributeName:null,attributeType:null,azimuth:s,bandwidth:null,baselineShift:null,baseFrequency:null,baseProfile:null,bbox:null,begin:null,bias:s,by:null,calcMode:null,capHeight:s,className:u,clip:null,clipPath:null,clipPathUnits:null,clipRule:null,color:null,colorInterpolation:null,colorInterpolationFilters:null,colorProfile:null,colorRendering:null,content:null,contentScriptType:null,contentStyleType:null,crossOrigin:null,cursor:null,cx:null,cy:null,d:null,dataType:null,defaultAction:null,descent:s,diffuseConstant:s,direction:null,display:null,dur:null,divisor:s,dominantBaseline:null,download:a,dx:null,dy:null,edgeMode:null,editable:null,elevation:s,enableBackground:null,end:null,event:null,exponent:s,externalResourcesRequired:null,fill:null,fillOpacity:s,fillRule:null,filter:null,filterRes:null,filterUnits:null,floodColor:null,floodOpacity:null,focusable:null,focusHighlight:null,fontFamily:null,fontSize:null,fontSizeAdjust:null,fontStretch:null,fontStyle:null,fontVariant:null,fontWeight:null,format:null,fr:null,from:null,fx:null,fy:null,g1:c,g2:c,glyphName:c,glyphOrientationHorizontal:null,glyphOrientationVertical:null,glyphRef:null,gradientTransform:null,gradientUnits:null,handler:null,hanging:s,hatchContentUnits:null,hatchUnits:null,height:null,href:null,hrefLang:null,horizAdvX:s,horizOriginX:s,horizOriginY:s,id:null,ideographic:s,imageRendering:null,initialVisibility:null,in:null,in2:null,intercept:s,k:s,k1:s,k2:s,k3:s,k4:s,kernelMatrix:l,kernelUnitLength:null,keyPoints:null,keySplines:null,keyTimes:null,kerning:null,lang:null,lengthAdjust:null,letterSpacing:null,lightingColor:null,limitingConeAngle:s,local:null,markerEnd:null,markerMid:null,markerStart:null,markerHeight:null,markerUnits:null,markerWidth:null,mask:null,maskContentUnits:null,maskUnits:null,mathematical:null,max:null,media:null,mediaCharacterEncoding:null,mediaContentEncodings:null,mediaSize:s,mediaTime:null,method:null,min:null,mode:null,name:null,navDown:null,navDownLeft:null,navDownRight:null,navLeft:null,navNext:null,navPrev:null,navRight:null,navUp:null,navUpLeft:null,navUpRight:null,numOctaves:null,observer:null,offset:null,onAbort:null,onActivate:null,onAfterPrint:null,onBeforePrint:null,onBegin:null,onCancel:null,onCanPlay:null,onCanPlayThrough:null,onChange:null,onClick:null,onClose:null,onCopy:null,onCueChange:null,onCut:null,onDblClick:null,onDrag:null,onDragEnd:null,onDragEnter:null,onDragExit:null,onDragLeave:null,onDragOver:null,onDragStart:null,onDrop:null,onDurationChange:null,onEmptied:null,onEnd:null,onEnded:null,onError:null,onFocus:null,onFocusIn:null,onFocusOut:null,onHashChange:null,onInput:null,onInvalid:null,onKeyDown:null,onKeyPress:null,onKeyUp:null,onLoad:null,onLoadedData:null,onLoadedMetadata:null,onLoadStart:null,onMessage:null,onMouseDown:null,onMouseEnter:null,onMouseLeave:null,onMouseMove:null,onMouseOut:null,onMouseOver:null,onMouseUp:null,onMouseWheel:null,onOffline:null,onOnline:null,onPageHide:null,onPageShow:null,onPaste:null,onPause:null,onPlay:null,onPlaying:null,onPopState:null,onProgress:null,onRateChange:null,onRepeat:null,onReset:null,onResize:null,onScroll:null,onSeeked:null,onSeeking:null,onSelect:null,onShow:null,onStalled:null,onStorage:null,onSubmit:null,onSuspend:null,onTimeUpdate:null,onToggle:null,onUnload:null,onVolumeChange:null,onWaiting:null,onZoom:null,opacity:null,operator:null,order:null,orient:null,orientation:null,origin:null,overflow:null,overlay:null,overlinePosition:s,overlineThickness:s,paintOrder:null,panose1:null,path:null,pathLength:s,patternContentUnits:null,patternTransform:null,patternUnits:null,phase:null,ping:u,pitch:null,playbackOrder:null,pointerEvents:null,points:null,pointsAtX:s,pointsAtY:s,pointsAtZ:s,preserveAlpha:null,preserveAspectRatio:null,primitiveUnits:null,propagate:null,property:l,r:null,radius:null,referrerPolicy:null,refX:null,refY:null,rel:l,rev:l,renderingIntent:null,repeatCount:null,repeatDur:null,requiredExtensions:l,requiredFeatures:l,requiredFonts:l,requiredFormats:l,resource:null,restart:null,result:null,rotate:null,rx:null,ry:null,scale:null,seed:null,shapeRendering:null,side:null,slope:null,snapshotTime:null,specularConstant:s,specularExponent:s,spreadMethod:null,spacing:null,startOffset:null,stdDeviation:null,stemh:null,stemv:null,stitchTiles:null,stopColor:null,stopOpacity:null,strikethroughPosition:s,strikethroughThickness:s,string:null,stroke:null,strokeDashArray:l,strokeDashOffset:null,strokeLineCap:null,strokeLineJoin:null,strokeMiterLimit:s,strokeOpacity:s,strokeWidth:null,style:null,surfaceScale:s,syncBehavior:null,syncBehaviorDefault:null,syncMaster:null,syncTolerance:null,syncToleranceDefault:null,systemLanguage:l,tabIndex:s,tableValues:null,target:null,targetX:s,targetY:s,textAnchor:null,textDecoration:null,textRendering:null,textLength:null,timelineBegin:null,title:null,transformBehavior:null,type:null,typeOf:l,to:null,transform:null,u1:null,u2:null,underlinePosition:s,underlineThickness:s,unicode:null,unicodeBidi:null,unicodeRange:null,unitsPerEm:s,values:null,vAlphabetic:s,vMathematical:s,vectorEffect:null,vHanging:s,vIdeographic:s,version:null,vertAdvY:s,vertOriginX:s,vertOriginY:s,viewBox:null,viewTarget:null,visibility:null,width:null,widths:null,wordSpacing:null,writingMode:null,x:null,x1:null,x2:null,xChannelSelector:null,xHeight:s,y:null,y1:null,y2:null,yChannelSelector:null,z:null,zoomAndPan:null}})},10855:(e,t,n)=>{"use strict";var o=n(28740);e.exports=function(e,t){return o(e,t.toLowerCase())}},28740:e=>{"use strict";e.exports=function(e,t){return t in e?e[t]:t}},17596:(e,t,n)=>{"use strict";var o=n(66632),r=n(99607),i=n(98805);e.exports=function(e){var t,n,a=e.space,s=e.mustUseProperty||[],u=e.attributes||{},c=e.properties,l=e.transform,d={},h={};for(t in c)n=new i(t,l(u,t),c[t],a),-1!==s.indexOf(t)&&(n.mustUseProperty=!0),d[t]=n,h[o(t)]=t,h[o(n.attribute)]=t;return new r(d,h,a)}},98805:(e,t,n)=>{"use strict";var o=n(89750),r=n(17e3);e.exports=s,s.prototype=new o,s.prototype.defined=!0;var i=["boolean","booleanish","overloadedBoolean","number","commaSeparated","spaceSeparated","commaOrSpaceSeparated"],a=i.length;function s(e,t,n,s){var c,l=-1;for(u(this,"space",s),o.call(this,e,t);++l{"use strict";e.exports=n;var t=n.prototype;function n(e,t){this.property=e,this.attribute=t}t.space=null,t.attribute=null,t.property=null,t.boolean=!1,t.booleanish=!1,t.overloadedBoolean=!1,t.number=!1,t.commaSeparated=!1,t.spaceSeparated=!1,t.commaOrSpaceSeparated=!1,t.mustUseProperty=!1,t.defined=!1},19940:(e,t,n)=>{"use strict";var o=n(13351),r=n(99607);e.exports=function(e){for(var t,n,i=e.length,a=[],s=[],u=-1;++u{"use strict";e.exports=n;var t=n.prototype;function n(e,t,n){this.property=e,this.normal=t,n&&(this.space=n)}t.space=null,t.normal={},t.property={}},17e3:(e,t)=>{"use strict";var n=0;function o(){return Math.pow(2,++n)}t.boolean=o(),t.booleanish=o(),t.overloadedBoolean=o(),t.number=o(),t.spaceSeparated=o(),t.commaSeparated=o(),t.commaOrSpaceSeparated=o()},8289:(e,t,n)=>{"use strict";var o=n(17596);e.exports=o({space:"xlink",transform:function(e,t){return"xlink:"+t.slice(5).toLowerCase()},properties:{xLinkActuate:null,xLinkArcRole:null,xLinkHref:null,xLinkRole:null,xLinkShow:null,xLinkTitle:null,xLinkType:null}})},5812:(e,t,n)=>{"use strict";var o=n(17596);e.exports=o({space:"xml",transform:function(e,t){return"xml:"+t.slice(3).toLowerCase()},properties:{xmlLang:null,xmlBase:null,xmlSpace:null}})},94397:(e,t,n)=>{"use strict";var o=n(17596),r=n(10855);e.exports=o({space:"xmlns",attributes:{xmlnsxlink:"xmlns:xlink"},transform:r,properties:{xmlns:null,xmlnsXLink:null}})},13351:e=>{e.exports=function(){for(var e={},n=0;n{"use strict";e.exports=function(e){return e.toLowerCase()}},11218:(e,t,n)=>{"use strict";var o=n(19940),r=n(8289),i=n(5812),a=n(94397),s=n(67716),u=n(97421);e.exports=o([i,r,a,s,u])},90233:function(e){var t;t=function(){var e="function"==typeof Object.defineProperty?function(e,t,n){return Object.defineProperty(e,t,n),e}:function(e,t,n){return e[t]=n.value,e};return function(t,n,o,r){var i;if(r=function(e,t){var n="object"==typeof t,o=!n&&"string"==typeof t,r=function(e){return n?!!t[e]:!!o&&t.indexOf(e[0])>-1};return{enumerable:r("enumerable"),configurable:r("configurable"),writable:r("writable"),value:e}}(o,r),"object"==typeof n){for(i in n)Object.hasOwnProperty.call(n,i)&&(r.value=n[i],e(t,i,r));return t}return e(t,n,r)}},e.exports?e.exports=t():this.prr=t()},7900:(e,t,n)=>{t.publicEncrypt=n(16559),t.privateDecrypt=n(26138),t.privateEncrypt=function(e,n){return t.publicEncrypt(e,n,!0)},t.publicDecrypt=function(e,n){return t.privateDecrypt(e,n,!0)}},99199:(e,t,n)=>{var o=n(23482),r=n(89509).Buffer;function i(e){var t=r.allocUnsafe(4);return t.writeUInt32BE(e,0),t}e.exports=function(e,t){for(var n,a=r.alloc(0),s=0;a.length=65&&n<=70?n-55:n>=97&&n<=102?n-87:n-48&15}function u(e,t,n){var o=s(e,n);return n-1>=t&&(o|=s(e,n-1)<<4),o}function c(e,t,n,o){for(var r=0,i=Math.min(e.length,n),a=t;a=49?s-49+10:s>=17?s-17+10:s}return r}i.isBN=function(e){return e instanceof i||null!==e&&"object"==typeof e&&e.constructor.wordSize===i.wordSize&&Array.isArray(e.words)},i.max=function(e,t){return e.cmp(t)>0?e:t},i.min=function(e,t){return e.cmp(t)<0?e:t},i.prototype._init=function(e,t,n){if("number"==typeof e)return this._initNumber(e,t,n);if("object"==typeof e)return this._initArray(e,t,n);"hex"===t&&(t=16),o(t===(0|t)&&t>=2&&t<=36);var r=0;"-"===(e=e.toString().replace(/\s+/g,""))[0]&&(r++,this.negative=1),r=0;r-=3)a=e[r]|e[r-1]<<8|e[r-2]<<16,this.words[i]|=a<>>26-s&67108863,(s+=24)>=26&&(s-=26,i++);else if("le"===n)for(r=0,i=0;r>>26-s&67108863,(s+=24)>=26&&(s-=26,i++);return this.strip()},i.prototype._parseHex=function(e,t,n){this.length=Math.ceil((e.length-t)/6),this.words=new Array(this.length);for(var o=0;o=t;o-=2)r=u(e,t,o)<=18?(i-=18,a+=1,this.words[a]|=r>>>26):i+=8;else for(o=(e.length-t)%2==0?t+1:t;o=18?(i-=18,a+=1,this.words[a]|=r>>>26):i+=8;this.strip()},i.prototype._parseBase=function(e,t,n){this.words=[0],this.length=1;for(var o=0,r=1;r<=67108863;r*=t)o++;o--,r=r/t|0;for(var i=e.length-n,a=i%o,s=Math.min(i,i-a)+n,u=0,l=n;l1&&0===this.words[this.length-1];)this.length--;return this._normSign()},i.prototype._normSign=function(){return 1===this.length&&0===this.words[0]&&(this.negative=0),this},i.prototype.inspect=function(){return(this.red?""};var l=["","0","00","000","0000","00000","000000","0000000","00000000","000000000","0000000000","00000000000","000000000000","0000000000000","00000000000000","000000000000000","0000000000000000","00000000000000000","000000000000000000","0000000000000000000","00000000000000000000","000000000000000000000","0000000000000000000000","00000000000000000000000","000000000000000000000000","0000000000000000000000000"],d=[0,0,25,16,12,11,10,9,8,8,7,7,7,7,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5],h=[0,0,33554432,43046721,16777216,48828125,60466176,40353607,16777216,43046721,1e7,19487171,35831808,62748517,7529536,11390625,16777216,24137569,34012224,47045881,64e6,4084101,5153632,6436343,7962624,9765625,11881376,14348907,17210368,20511149,243e5,28629151,33554432,39135393,45435424,52521875,60466176];function p(e,t,n){n.negative=t.negative^e.negative;var o=e.length+t.length|0;n.length=o,o=o-1|0;var r=0|e.words[0],i=0|t.words[0],a=r*i,s=67108863&a,u=a/67108864|0;n.words[0]=s;for(var c=1;c>>26,d=67108863&u,h=Math.min(c,t.length-1),p=Math.max(0,c-e.length+1);p<=h;p++){var f=c-p|0;l+=(a=(r=0|e.words[f])*(i=0|t.words[p])+d)/67108864|0,d=67108863&a}n.words[c]=0|d,u=0|l}return 0!==u?n.words[c]=0|u:n.length--,n.strip()}i.prototype.toString=function(e,t){var n;if(t=0|t||1,16===(e=e||10)||"hex"===e){n="";for(var r=0,i=0,a=0;a>>24-r&16777215)||a!==this.length-1?l[6-u.length]+u+n:u+n,(r+=2)>=26&&(r-=26,a--)}for(0!==i&&(n=i.toString(16)+n);n.length%t!=0;)n="0"+n;return 0!==this.negative&&(n="-"+n),n}if(e===(0|e)&&e>=2&&e<=36){var c=d[e],p=h[e];n="";var f=this.clone();for(f.negative=0;!f.isZero();){var g=f.modn(p).toString(e);n=(f=f.idivn(p)).isZero()?g+n:l[c-g.length]+g+n}for(this.isZero()&&(n="0"+n);n.length%t!=0;)n="0"+n;return 0!==this.negative&&(n="-"+n),n}o(!1,"Base should be between 2 and 36")},i.prototype.toNumber=function(){var e=this.words[0];return 2===this.length?e+=67108864*this.words[1]:3===this.length&&1===this.words[2]?e+=4503599627370496+67108864*this.words[1]:this.length>2&&o(!1,"Number can only safely store up to 53 bits"),0!==this.negative?-e:e},i.prototype.toJSON=function(){return this.toString(16)},i.prototype.toBuffer=function(e,t){return o(void 0!==a),this.toArrayLike(a,e,t)},i.prototype.toArray=function(e,t){return this.toArrayLike(Array,e,t)},i.prototype.toArrayLike=function(e,t,n){var r=this.byteLength(),i=n||Math.max(1,r);o(r<=i,"byte array longer than desired length"),o(i>0,"Requested array length <= 0"),this.strip();var a,s,u="le"===t,c=new e(i),l=this.clone();if(u){for(s=0;!l.isZero();s++)a=l.andln(255),l.iushrn(8),c[s]=a;for(;s=4096&&(n+=13,t>>>=13),t>=64&&(n+=7,t>>>=7),t>=8&&(n+=4,t>>>=4),t>=2&&(n+=2,t>>>=2),n+t},i.prototype._zeroBits=function(e){if(0===e)return 26;var t=e,n=0;return 0==(8191&t)&&(n+=13,t>>>=13),0==(127&t)&&(n+=7,t>>>=7),0==(15&t)&&(n+=4,t>>>=4),0==(3&t)&&(n+=2,t>>>=2),0==(1&t)&&n++,n},i.prototype.bitLength=function(){var e=this.words[this.length-1],t=this._countBits(e);return 26*(this.length-1)+t},i.prototype.zeroBits=function(){if(this.isZero())return 0;for(var e=0,t=0;te.length?this.clone().ior(e):e.clone().ior(this)},i.prototype.uor=function(e){return this.length>e.length?this.clone().iuor(e):e.clone().iuor(this)},i.prototype.iuand=function(e){var t;t=this.length>e.length?e:this;for(var n=0;ne.length?this.clone().iand(e):e.clone().iand(this)},i.prototype.uand=function(e){return this.length>e.length?this.clone().iuand(e):e.clone().iuand(this)},i.prototype.iuxor=function(e){var t,n;this.length>e.length?(t=this,n=e):(t=e,n=this);for(var o=0;oe.length?this.clone().ixor(e):e.clone().ixor(this)},i.prototype.uxor=function(e){return this.length>e.length?this.clone().iuxor(e):e.clone().iuxor(this)},i.prototype.inotn=function(e){o("number"==typeof e&&e>=0);var t=0|Math.ceil(e/26),n=e%26;this._expand(t),n>0&&t--;for(var r=0;r0&&(this.words[r]=~this.words[r]&67108863>>26-n),this.strip()},i.prototype.notn=function(e){return this.clone().inotn(e)},i.prototype.setn=function(e,t){o("number"==typeof e&&e>=0);var n=e/26|0,r=e%26;return this._expand(n+1),this.words[n]=t?this.words[n]|1<e.length?(n=this,o=e):(n=e,o=this);for(var r=0,i=0;i>>26;for(;0!==r&&i>>26;if(this.length=n.length,0!==r)this.words[this.length]=r,this.length++;else if(n!==this)for(;ie.length?this.clone().iadd(e):e.clone().iadd(this)},i.prototype.isub=function(e){if(0!==e.negative){e.negative=0;var t=this.iadd(e);return e.negative=1,t._normSign()}if(0!==this.negative)return this.negative=0,this.iadd(e),this.negative=1,this._normSign();var n,o,r=this.cmp(e);if(0===r)return this.negative=0,this.length=1,this.words[0]=0,this;r>0?(n=this,o=e):(n=e,o=this);for(var i=0,a=0;a>26,this.words[a]=67108863&t;for(;0!==i&&a>26,this.words[a]=67108863&t;if(0===i&&a>>13,p=0|a[1],f=8191&p,g=p>>>13,m=0|a[2],_=8191&m,F=m>>>13,y=0|a[3],b=8191&y,v=y>>>13,w=0|a[4],E=8191&w,k=w>>>13,D=0|a[5],S=8191&D,x=D>>>13,C=0|a[6],A=8191&C,T=C>>>13,R=0|a[7],I=8191&R,M=R>>>13,O=0|a[8],B=8191&O,N=O>>>13,L=0|a[9],P=8191&L,U=L>>>13,j=0|s[0],q=8191&j,z=j>>>13,K=0|s[1],G=8191&K,$=K>>>13,H=0|s[2],V=8191&H,W=H>>>13,Y=0|s[3],Z=8191&Y,X=Y>>>13,J=0|s[4],Q=8191&J,ee=J>>>13,te=0|s[5],ne=8191&te,oe=te>>>13,re=0|s[6],ie=8191&re,ae=re>>>13,se=0|s[7],ue=8191&se,ce=se>>>13,le=0|s[8],de=8191&le,he=le>>>13,pe=0|s[9],fe=8191&pe,ge=pe>>>13;n.negative=e.negative^t.negative,n.length=19;var me=(c+(o=Math.imul(d,q))|0)+((8191&(r=(r=Math.imul(d,z))+Math.imul(h,q)|0))<<13)|0;c=((i=Math.imul(h,z))+(r>>>13)|0)+(me>>>26)|0,me&=67108863,o=Math.imul(f,q),r=(r=Math.imul(f,z))+Math.imul(g,q)|0,i=Math.imul(g,z);var _e=(c+(o=o+Math.imul(d,G)|0)|0)+((8191&(r=(r=r+Math.imul(d,$)|0)+Math.imul(h,G)|0))<<13)|0;c=((i=i+Math.imul(h,$)|0)+(r>>>13)|0)+(_e>>>26)|0,_e&=67108863,o=Math.imul(_,q),r=(r=Math.imul(_,z))+Math.imul(F,q)|0,i=Math.imul(F,z),o=o+Math.imul(f,G)|0,r=(r=r+Math.imul(f,$)|0)+Math.imul(g,G)|0,i=i+Math.imul(g,$)|0;var Fe=(c+(o=o+Math.imul(d,V)|0)|0)+((8191&(r=(r=r+Math.imul(d,W)|0)+Math.imul(h,V)|0))<<13)|0;c=((i=i+Math.imul(h,W)|0)+(r>>>13)|0)+(Fe>>>26)|0,Fe&=67108863,o=Math.imul(b,q),r=(r=Math.imul(b,z))+Math.imul(v,q)|0,i=Math.imul(v,z),o=o+Math.imul(_,G)|0,r=(r=r+Math.imul(_,$)|0)+Math.imul(F,G)|0,i=i+Math.imul(F,$)|0,o=o+Math.imul(f,V)|0,r=(r=r+Math.imul(f,W)|0)+Math.imul(g,V)|0,i=i+Math.imul(g,W)|0;var ye=(c+(o=o+Math.imul(d,Z)|0)|0)+((8191&(r=(r=r+Math.imul(d,X)|0)+Math.imul(h,Z)|0))<<13)|0;c=((i=i+Math.imul(h,X)|0)+(r>>>13)|0)+(ye>>>26)|0,ye&=67108863,o=Math.imul(E,q),r=(r=Math.imul(E,z))+Math.imul(k,q)|0,i=Math.imul(k,z),o=o+Math.imul(b,G)|0,r=(r=r+Math.imul(b,$)|0)+Math.imul(v,G)|0,i=i+Math.imul(v,$)|0,o=o+Math.imul(_,V)|0,r=(r=r+Math.imul(_,W)|0)+Math.imul(F,V)|0,i=i+Math.imul(F,W)|0,o=o+Math.imul(f,Z)|0,r=(r=r+Math.imul(f,X)|0)+Math.imul(g,Z)|0,i=i+Math.imul(g,X)|0;var be=(c+(o=o+Math.imul(d,Q)|0)|0)+((8191&(r=(r=r+Math.imul(d,ee)|0)+Math.imul(h,Q)|0))<<13)|0;c=((i=i+Math.imul(h,ee)|0)+(r>>>13)|0)+(be>>>26)|0,be&=67108863,o=Math.imul(S,q),r=(r=Math.imul(S,z))+Math.imul(x,q)|0,i=Math.imul(x,z),o=o+Math.imul(E,G)|0,r=(r=r+Math.imul(E,$)|0)+Math.imul(k,G)|0,i=i+Math.imul(k,$)|0,o=o+Math.imul(b,V)|0,r=(r=r+Math.imul(b,W)|0)+Math.imul(v,V)|0,i=i+Math.imul(v,W)|0,o=o+Math.imul(_,Z)|0,r=(r=r+Math.imul(_,X)|0)+Math.imul(F,Z)|0,i=i+Math.imul(F,X)|0,o=o+Math.imul(f,Q)|0,r=(r=r+Math.imul(f,ee)|0)+Math.imul(g,Q)|0,i=i+Math.imul(g,ee)|0;var ve=(c+(o=o+Math.imul(d,ne)|0)|0)+((8191&(r=(r=r+Math.imul(d,oe)|0)+Math.imul(h,ne)|0))<<13)|0;c=((i=i+Math.imul(h,oe)|0)+(r>>>13)|0)+(ve>>>26)|0,ve&=67108863,o=Math.imul(A,q),r=(r=Math.imul(A,z))+Math.imul(T,q)|0,i=Math.imul(T,z),o=o+Math.imul(S,G)|0,r=(r=r+Math.imul(S,$)|0)+Math.imul(x,G)|0,i=i+Math.imul(x,$)|0,o=o+Math.imul(E,V)|0,r=(r=r+Math.imul(E,W)|0)+Math.imul(k,V)|0,i=i+Math.imul(k,W)|0,o=o+Math.imul(b,Z)|0,r=(r=r+Math.imul(b,X)|0)+Math.imul(v,Z)|0,i=i+Math.imul(v,X)|0,o=o+Math.imul(_,Q)|0,r=(r=r+Math.imul(_,ee)|0)+Math.imul(F,Q)|0,i=i+Math.imul(F,ee)|0,o=o+Math.imul(f,ne)|0,r=(r=r+Math.imul(f,oe)|0)+Math.imul(g,ne)|0,i=i+Math.imul(g,oe)|0;var we=(c+(o=o+Math.imul(d,ie)|0)|0)+((8191&(r=(r=r+Math.imul(d,ae)|0)+Math.imul(h,ie)|0))<<13)|0;c=((i=i+Math.imul(h,ae)|0)+(r>>>13)|0)+(we>>>26)|0,we&=67108863,o=Math.imul(I,q),r=(r=Math.imul(I,z))+Math.imul(M,q)|0,i=Math.imul(M,z),o=o+Math.imul(A,G)|0,r=(r=r+Math.imul(A,$)|0)+Math.imul(T,G)|0,i=i+Math.imul(T,$)|0,o=o+Math.imul(S,V)|0,r=(r=r+Math.imul(S,W)|0)+Math.imul(x,V)|0,i=i+Math.imul(x,W)|0,o=o+Math.imul(E,Z)|0,r=(r=r+Math.imul(E,X)|0)+Math.imul(k,Z)|0,i=i+Math.imul(k,X)|0,o=o+Math.imul(b,Q)|0,r=(r=r+Math.imul(b,ee)|0)+Math.imul(v,Q)|0,i=i+Math.imul(v,ee)|0,o=o+Math.imul(_,ne)|0,r=(r=r+Math.imul(_,oe)|0)+Math.imul(F,ne)|0,i=i+Math.imul(F,oe)|0,o=o+Math.imul(f,ie)|0,r=(r=r+Math.imul(f,ae)|0)+Math.imul(g,ie)|0,i=i+Math.imul(g,ae)|0;var Ee=(c+(o=o+Math.imul(d,ue)|0)|0)+((8191&(r=(r=r+Math.imul(d,ce)|0)+Math.imul(h,ue)|0))<<13)|0;c=((i=i+Math.imul(h,ce)|0)+(r>>>13)|0)+(Ee>>>26)|0,Ee&=67108863,o=Math.imul(B,q),r=(r=Math.imul(B,z))+Math.imul(N,q)|0,i=Math.imul(N,z),o=o+Math.imul(I,G)|0,r=(r=r+Math.imul(I,$)|0)+Math.imul(M,G)|0,i=i+Math.imul(M,$)|0,o=o+Math.imul(A,V)|0,r=(r=r+Math.imul(A,W)|0)+Math.imul(T,V)|0,i=i+Math.imul(T,W)|0,o=o+Math.imul(S,Z)|0,r=(r=r+Math.imul(S,X)|0)+Math.imul(x,Z)|0,i=i+Math.imul(x,X)|0,o=o+Math.imul(E,Q)|0,r=(r=r+Math.imul(E,ee)|0)+Math.imul(k,Q)|0,i=i+Math.imul(k,ee)|0,o=o+Math.imul(b,ne)|0,r=(r=r+Math.imul(b,oe)|0)+Math.imul(v,ne)|0,i=i+Math.imul(v,oe)|0,o=o+Math.imul(_,ie)|0,r=(r=r+Math.imul(_,ae)|0)+Math.imul(F,ie)|0,i=i+Math.imul(F,ae)|0,o=o+Math.imul(f,ue)|0,r=(r=r+Math.imul(f,ce)|0)+Math.imul(g,ue)|0,i=i+Math.imul(g,ce)|0;var ke=(c+(o=o+Math.imul(d,de)|0)|0)+((8191&(r=(r=r+Math.imul(d,he)|0)+Math.imul(h,de)|0))<<13)|0;c=((i=i+Math.imul(h,he)|0)+(r>>>13)|0)+(ke>>>26)|0,ke&=67108863,o=Math.imul(P,q),r=(r=Math.imul(P,z))+Math.imul(U,q)|0,i=Math.imul(U,z),o=o+Math.imul(B,G)|0,r=(r=r+Math.imul(B,$)|0)+Math.imul(N,G)|0,i=i+Math.imul(N,$)|0,o=o+Math.imul(I,V)|0,r=(r=r+Math.imul(I,W)|0)+Math.imul(M,V)|0,i=i+Math.imul(M,W)|0,o=o+Math.imul(A,Z)|0,r=(r=r+Math.imul(A,X)|0)+Math.imul(T,Z)|0,i=i+Math.imul(T,X)|0,o=o+Math.imul(S,Q)|0,r=(r=r+Math.imul(S,ee)|0)+Math.imul(x,Q)|0,i=i+Math.imul(x,ee)|0,o=o+Math.imul(E,ne)|0,r=(r=r+Math.imul(E,oe)|0)+Math.imul(k,ne)|0,i=i+Math.imul(k,oe)|0,o=o+Math.imul(b,ie)|0,r=(r=r+Math.imul(b,ae)|0)+Math.imul(v,ie)|0,i=i+Math.imul(v,ae)|0,o=o+Math.imul(_,ue)|0,r=(r=r+Math.imul(_,ce)|0)+Math.imul(F,ue)|0,i=i+Math.imul(F,ce)|0,o=o+Math.imul(f,de)|0,r=(r=r+Math.imul(f,he)|0)+Math.imul(g,de)|0,i=i+Math.imul(g,he)|0;var De=(c+(o=o+Math.imul(d,fe)|0)|0)+((8191&(r=(r=r+Math.imul(d,ge)|0)+Math.imul(h,fe)|0))<<13)|0;c=((i=i+Math.imul(h,ge)|0)+(r>>>13)|0)+(De>>>26)|0,De&=67108863,o=Math.imul(P,G),r=(r=Math.imul(P,$))+Math.imul(U,G)|0,i=Math.imul(U,$),o=o+Math.imul(B,V)|0,r=(r=r+Math.imul(B,W)|0)+Math.imul(N,V)|0,i=i+Math.imul(N,W)|0,o=o+Math.imul(I,Z)|0,r=(r=r+Math.imul(I,X)|0)+Math.imul(M,Z)|0,i=i+Math.imul(M,X)|0,o=o+Math.imul(A,Q)|0,r=(r=r+Math.imul(A,ee)|0)+Math.imul(T,Q)|0,i=i+Math.imul(T,ee)|0,o=o+Math.imul(S,ne)|0,r=(r=r+Math.imul(S,oe)|0)+Math.imul(x,ne)|0,i=i+Math.imul(x,oe)|0,o=o+Math.imul(E,ie)|0,r=(r=r+Math.imul(E,ae)|0)+Math.imul(k,ie)|0,i=i+Math.imul(k,ae)|0,o=o+Math.imul(b,ue)|0,r=(r=r+Math.imul(b,ce)|0)+Math.imul(v,ue)|0,i=i+Math.imul(v,ce)|0,o=o+Math.imul(_,de)|0,r=(r=r+Math.imul(_,he)|0)+Math.imul(F,de)|0,i=i+Math.imul(F,he)|0;var Se=(c+(o=o+Math.imul(f,fe)|0)|0)+((8191&(r=(r=r+Math.imul(f,ge)|0)+Math.imul(g,fe)|0))<<13)|0;c=((i=i+Math.imul(g,ge)|0)+(r>>>13)|0)+(Se>>>26)|0,Se&=67108863,o=Math.imul(P,V),r=(r=Math.imul(P,W))+Math.imul(U,V)|0,i=Math.imul(U,W),o=o+Math.imul(B,Z)|0,r=(r=r+Math.imul(B,X)|0)+Math.imul(N,Z)|0,i=i+Math.imul(N,X)|0,o=o+Math.imul(I,Q)|0,r=(r=r+Math.imul(I,ee)|0)+Math.imul(M,Q)|0,i=i+Math.imul(M,ee)|0,o=o+Math.imul(A,ne)|0,r=(r=r+Math.imul(A,oe)|0)+Math.imul(T,ne)|0,i=i+Math.imul(T,oe)|0,o=o+Math.imul(S,ie)|0,r=(r=r+Math.imul(S,ae)|0)+Math.imul(x,ie)|0,i=i+Math.imul(x,ae)|0,o=o+Math.imul(E,ue)|0,r=(r=r+Math.imul(E,ce)|0)+Math.imul(k,ue)|0,i=i+Math.imul(k,ce)|0,o=o+Math.imul(b,de)|0,r=(r=r+Math.imul(b,he)|0)+Math.imul(v,de)|0,i=i+Math.imul(v,he)|0;var xe=(c+(o=o+Math.imul(_,fe)|0)|0)+((8191&(r=(r=r+Math.imul(_,ge)|0)+Math.imul(F,fe)|0))<<13)|0;c=((i=i+Math.imul(F,ge)|0)+(r>>>13)|0)+(xe>>>26)|0,xe&=67108863,o=Math.imul(P,Z),r=(r=Math.imul(P,X))+Math.imul(U,Z)|0,i=Math.imul(U,X),o=o+Math.imul(B,Q)|0,r=(r=r+Math.imul(B,ee)|0)+Math.imul(N,Q)|0,i=i+Math.imul(N,ee)|0,o=o+Math.imul(I,ne)|0,r=(r=r+Math.imul(I,oe)|0)+Math.imul(M,ne)|0,i=i+Math.imul(M,oe)|0,o=o+Math.imul(A,ie)|0,r=(r=r+Math.imul(A,ae)|0)+Math.imul(T,ie)|0,i=i+Math.imul(T,ae)|0,o=o+Math.imul(S,ue)|0,r=(r=r+Math.imul(S,ce)|0)+Math.imul(x,ue)|0,i=i+Math.imul(x,ce)|0,o=o+Math.imul(E,de)|0,r=(r=r+Math.imul(E,he)|0)+Math.imul(k,de)|0,i=i+Math.imul(k,he)|0;var Ce=(c+(o=o+Math.imul(b,fe)|0)|0)+((8191&(r=(r=r+Math.imul(b,ge)|0)+Math.imul(v,fe)|0))<<13)|0;c=((i=i+Math.imul(v,ge)|0)+(r>>>13)|0)+(Ce>>>26)|0,Ce&=67108863,o=Math.imul(P,Q),r=(r=Math.imul(P,ee))+Math.imul(U,Q)|0,i=Math.imul(U,ee),o=o+Math.imul(B,ne)|0,r=(r=r+Math.imul(B,oe)|0)+Math.imul(N,ne)|0,i=i+Math.imul(N,oe)|0,o=o+Math.imul(I,ie)|0,r=(r=r+Math.imul(I,ae)|0)+Math.imul(M,ie)|0,i=i+Math.imul(M,ae)|0,o=o+Math.imul(A,ue)|0,r=(r=r+Math.imul(A,ce)|0)+Math.imul(T,ue)|0,i=i+Math.imul(T,ce)|0,o=o+Math.imul(S,de)|0,r=(r=r+Math.imul(S,he)|0)+Math.imul(x,de)|0,i=i+Math.imul(x,he)|0;var Ae=(c+(o=o+Math.imul(E,fe)|0)|0)+((8191&(r=(r=r+Math.imul(E,ge)|0)+Math.imul(k,fe)|0))<<13)|0;c=((i=i+Math.imul(k,ge)|0)+(r>>>13)|0)+(Ae>>>26)|0,Ae&=67108863,o=Math.imul(P,ne),r=(r=Math.imul(P,oe))+Math.imul(U,ne)|0,i=Math.imul(U,oe),o=o+Math.imul(B,ie)|0,r=(r=r+Math.imul(B,ae)|0)+Math.imul(N,ie)|0,i=i+Math.imul(N,ae)|0,o=o+Math.imul(I,ue)|0,r=(r=r+Math.imul(I,ce)|0)+Math.imul(M,ue)|0,i=i+Math.imul(M,ce)|0,o=o+Math.imul(A,de)|0,r=(r=r+Math.imul(A,he)|0)+Math.imul(T,de)|0,i=i+Math.imul(T,he)|0;var Te=(c+(o=o+Math.imul(S,fe)|0)|0)+((8191&(r=(r=r+Math.imul(S,ge)|0)+Math.imul(x,fe)|0))<<13)|0;c=((i=i+Math.imul(x,ge)|0)+(r>>>13)|0)+(Te>>>26)|0,Te&=67108863,o=Math.imul(P,ie),r=(r=Math.imul(P,ae))+Math.imul(U,ie)|0,i=Math.imul(U,ae),o=o+Math.imul(B,ue)|0,r=(r=r+Math.imul(B,ce)|0)+Math.imul(N,ue)|0,i=i+Math.imul(N,ce)|0,o=o+Math.imul(I,de)|0,r=(r=r+Math.imul(I,he)|0)+Math.imul(M,de)|0,i=i+Math.imul(M,he)|0;var Re=(c+(o=o+Math.imul(A,fe)|0)|0)+((8191&(r=(r=r+Math.imul(A,ge)|0)+Math.imul(T,fe)|0))<<13)|0;c=((i=i+Math.imul(T,ge)|0)+(r>>>13)|0)+(Re>>>26)|0,Re&=67108863,o=Math.imul(P,ue),r=(r=Math.imul(P,ce))+Math.imul(U,ue)|0,i=Math.imul(U,ce),o=o+Math.imul(B,de)|0,r=(r=r+Math.imul(B,he)|0)+Math.imul(N,de)|0,i=i+Math.imul(N,he)|0;var Ie=(c+(o=o+Math.imul(I,fe)|0)|0)+((8191&(r=(r=r+Math.imul(I,ge)|0)+Math.imul(M,fe)|0))<<13)|0;c=((i=i+Math.imul(M,ge)|0)+(r>>>13)|0)+(Ie>>>26)|0,Ie&=67108863,o=Math.imul(P,de),r=(r=Math.imul(P,he))+Math.imul(U,de)|0,i=Math.imul(U,he);var Me=(c+(o=o+Math.imul(B,fe)|0)|0)+((8191&(r=(r=r+Math.imul(B,ge)|0)+Math.imul(N,fe)|0))<<13)|0;c=((i=i+Math.imul(N,ge)|0)+(r>>>13)|0)+(Me>>>26)|0,Me&=67108863;var Oe=(c+(o=Math.imul(P,fe))|0)+((8191&(r=(r=Math.imul(P,ge))+Math.imul(U,fe)|0))<<13)|0;return c=((i=Math.imul(U,ge))+(r>>>13)|0)+(Oe>>>26)|0,Oe&=67108863,u[0]=me,u[1]=_e,u[2]=Fe,u[3]=ye,u[4]=be,u[5]=ve,u[6]=we,u[7]=Ee,u[8]=ke,u[9]=De,u[10]=Se,u[11]=xe,u[12]=Ce,u[13]=Ae,u[14]=Te,u[15]=Re,u[16]=Ie,u[17]=Me,u[18]=Oe,0!==c&&(u[19]=c,n.length++),n};function g(e,t,n){return(new m).mulp(e,t,n)}function m(e,t){this.x=e,this.y=t}Math.imul||(f=p),i.prototype.mulTo=function(e,t){var n=this.length+e.length;return 10===this.length&&10===e.length?f(this,e,t):n<63?p(this,e,t):n<1024?function(e,t,n){n.negative=t.negative^e.negative,n.length=e.length+t.length;for(var o=0,r=0,i=0;i>>26)|0)>>>26,a&=67108863}n.words[i]=s,o=a,a=r}return 0!==o?n.words[i]=o:n.length--,n.strip()}(this,e,t):g(this,e,t)},m.prototype.makeRBT=function(e){for(var t=new Array(e),n=i.prototype._countBits(e)-1,o=0;o>=1;return o},m.prototype.permute=function(e,t,n,o,r,i){for(var a=0;a>>=1)r++;return 1<>>=13,n[2*a+1]=8191&i,i>>>=13;for(a=2*t;a>=26,t+=r/67108864|0,t+=i>>>26,this.words[n]=67108863&i}return 0!==t&&(this.words[n]=t,this.length++),this},i.prototype.muln=function(e){return this.clone().imuln(e)},i.prototype.sqr=function(){return this.mul(this)},i.prototype.isqr=function(){return this.imul(this.clone())},i.prototype.pow=function(e){var t=function(e){for(var t=new Array(e.bitLength()),n=0;n>>r}return t}(e);if(0===t.length)return new i(1);for(var n=this,o=0;o=0);var t,n=e%26,r=(e-n)/26,i=67108863>>>26-n<<26-n;if(0!==n){var a=0;for(t=0;t>>26-n}a&&(this.words[t]=a,this.length++)}if(0!==r){for(t=this.length-1;t>=0;t--)this.words[t+r]=this.words[t];for(t=0;t=0),r=t?(t-t%26)/26:0;var i=e%26,a=Math.min((e-i)/26,this.length),s=67108863^67108863>>>i<a)for(this.length-=a,c=0;c=0&&(0!==l||c>=r);c--){var d=0|this.words[c];this.words[c]=l<<26-i|d>>>i,l=d&s}return u&&0!==l&&(u.words[u.length++]=l),0===this.length&&(this.words[0]=0,this.length=1),this.strip()},i.prototype.ishrn=function(e,t,n){return o(0===this.negative),this.iushrn(e,t,n)},i.prototype.shln=function(e){return this.clone().ishln(e)},i.prototype.ushln=function(e){return this.clone().iushln(e)},i.prototype.shrn=function(e){return this.clone().ishrn(e)},i.prototype.ushrn=function(e){return this.clone().iushrn(e)},i.prototype.testn=function(e){o("number"==typeof e&&e>=0);var t=e%26,n=(e-t)/26,r=1<=0);var t=e%26,n=(e-t)/26;if(o(0===this.negative,"imaskn works only with positive numbers"),this.length<=n)return this;if(0!==t&&n++,this.length=Math.min(n,this.length),0!==t){var r=67108863^67108863>>>t<=67108864;t++)this.words[t]-=67108864,t===this.length-1?this.words[t+1]=1:this.words[t+1]++;return this.length=Math.max(this.length,t+1),this},i.prototype.isubn=function(e){if(o("number"==typeof e),o(e<67108864),e<0)return this.iaddn(-e);if(0!==this.negative)return this.negative=0,this.iaddn(e),this.negative=1,this;if(this.words[0]-=e,1===this.length&&this.words[0]<0)this.words[0]=-this.words[0],this.negative=1;else for(var t=0;t>26)-(u/67108864|0),this.words[r+n]=67108863&i}for(;r>26,this.words[r+n]=67108863&i;if(0===s)return this.strip();for(o(-1===s),s=0,r=0;r>26,this.words[r]=67108863&i;return this.negative=1,this.strip()},i.prototype._wordDiv=function(e,t){var n=(this.length,e.length),o=this.clone(),r=e,a=0|r.words[r.length-1];0!=(n=26-this._countBits(a))&&(r=r.ushln(n),o.iushln(n),a=0|r.words[r.length-1]);var s,u=o.length-r.length;if("mod"!==t){(s=new i(null)).length=u+1,s.words=new Array(s.length);for(var c=0;c=0;d--){var h=67108864*(0|o.words[r.length+d])+(0|o.words[r.length+d-1]);for(h=Math.min(h/a|0,67108863),o._ishlnsubmul(r,h,d);0!==o.negative;)h--,o.negative=0,o._ishlnsubmul(r,1,d),o.isZero()||(o.negative^=1);s&&(s.words[d]=h)}return s&&s.strip(),o.strip(),"div"!==t&&0!==n&&o.iushrn(n),{div:s||null,mod:o}},i.prototype.divmod=function(e,t,n){return o(!e.isZero()),this.isZero()?{div:new i(0),mod:new i(0)}:0!==this.negative&&0===e.negative?(s=this.neg().divmod(e,t),"mod"!==t&&(r=s.div.neg()),"div"!==t&&(a=s.mod.neg(),n&&0!==a.negative&&a.iadd(e)),{div:r,mod:a}):0===this.negative&&0!==e.negative?(s=this.divmod(e.neg(),t),"mod"!==t&&(r=s.div.neg()),{div:r,mod:s.mod}):0!=(this.negative&e.negative)?(s=this.neg().divmod(e.neg(),t),"div"!==t&&(a=s.mod.neg(),n&&0!==a.negative&&a.isub(e)),{div:s.div,mod:a}):e.length>this.length||this.cmp(e)<0?{div:new i(0),mod:this}:1===e.length?"div"===t?{div:this.divn(e.words[0]),mod:null}:"mod"===t?{div:null,mod:new i(this.modn(e.words[0]))}:{div:this.divn(e.words[0]),mod:new i(this.modn(e.words[0]))}:this._wordDiv(e,t);var r,a,s},i.prototype.div=function(e){return this.divmod(e,"div",!1).div},i.prototype.mod=function(e){return this.divmod(e,"mod",!1).mod},i.prototype.umod=function(e){return this.divmod(e,"mod",!0).mod},i.prototype.divRound=function(e){var t=this.divmod(e);if(t.mod.isZero())return t.div;var n=0!==t.div.negative?t.mod.isub(e):t.mod,o=e.ushrn(1),r=e.andln(1),i=n.cmp(o);return i<0||1===r&&0===i?t.div:0!==t.div.negative?t.div.isubn(1):t.div.iaddn(1)},i.prototype.modn=function(e){o(e<=67108863);for(var t=(1<<26)%e,n=0,r=this.length-1;r>=0;r--)n=(t*n+(0|this.words[r]))%e;return n},i.prototype.idivn=function(e){o(e<=67108863);for(var t=0,n=this.length-1;n>=0;n--){var r=(0|this.words[n])+67108864*t;this.words[n]=r/e|0,t=r%e}return this.strip()},i.prototype.divn=function(e){return this.clone().idivn(e)},i.prototype.egcd=function(e){o(0===e.negative),o(!e.isZero());var t=this,n=e.clone();t=0!==t.negative?t.umod(e):t.clone();for(var r=new i(1),a=new i(0),s=new i(0),u=new i(1),c=0;t.isEven()&&n.isEven();)t.iushrn(1),n.iushrn(1),++c;for(var l=n.clone(),d=t.clone();!t.isZero();){for(var h=0,p=1;0==(t.words[0]&p)&&h<26;++h,p<<=1);if(h>0)for(t.iushrn(h);h-- >0;)(r.isOdd()||a.isOdd())&&(r.iadd(l),a.isub(d)),r.iushrn(1),a.iushrn(1);for(var f=0,g=1;0==(n.words[0]&g)&&f<26;++f,g<<=1);if(f>0)for(n.iushrn(f);f-- >0;)(s.isOdd()||u.isOdd())&&(s.iadd(l),u.isub(d)),s.iushrn(1),u.iushrn(1);t.cmp(n)>=0?(t.isub(n),r.isub(s),a.isub(u)):(n.isub(t),s.isub(r),u.isub(a))}return{a:s,b:u,gcd:n.iushln(c)}},i.prototype._invmp=function(e){o(0===e.negative),o(!e.isZero());var t=this,n=e.clone();t=0!==t.negative?t.umod(e):t.clone();for(var r,a=new i(1),s=new i(0),u=n.clone();t.cmpn(1)>0&&n.cmpn(1)>0;){for(var c=0,l=1;0==(t.words[0]&l)&&c<26;++c,l<<=1);if(c>0)for(t.iushrn(c);c-- >0;)a.isOdd()&&a.iadd(u),a.iushrn(1);for(var d=0,h=1;0==(n.words[0]&h)&&d<26;++d,h<<=1);if(d>0)for(n.iushrn(d);d-- >0;)s.isOdd()&&s.iadd(u),s.iushrn(1);t.cmp(n)>=0?(t.isub(n),a.isub(s)):(n.isub(t),s.isub(a))}return(r=0===t.cmpn(1)?a:s).cmpn(0)<0&&r.iadd(e),r},i.prototype.gcd=function(e){if(this.isZero())return e.abs();if(e.isZero())return this.abs();var t=this.clone(),n=e.clone();t.negative=0,n.negative=0;for(var o=0;t.isEven()&&n.isEven();o++)t.iushrn(1),n.iushrn(1);for(;;){for(;t.isEven();)t.iushrn(1);for(;n.isEven();)n.iushrn(1);var r=t.cmp(n);if(r<0){var i=t;t=n,n=i}else if(0===r||0===n.cmpn(1))break;t.isub(n)}return n.iushln(o)},i.prototype.invm=function(e){return this.egcd(e).a.umod(e)},i.prototype.isEven=function(){return 0==(1&this.words[0])},i.prototype.isOdd=function(){return 1==(1&this.words[0])},i.prototype.andln=function(e){return this.words[0]&e},i.prototype.bincn=function(e){o("number"==typeof e);var t=e%26,n=(e-t)/26,r=1<>>26,s&=67108863,this.words[a]=s}return 0!==i&&(this.words[a]=i,this.length++),this},i.prototype.isZero=function(){return 1===this.length&&0===this.words[0]},i.prototype.cmpn=function(e){var t,n=e<0;if(0!==this.negative&&!n)return-1;if(0===this.negative&&n)return 1;if(this.strip(),this.length>1)t=1;else{n&&(e=-e),o(e<=67108863,"Number is too big");var r=0|this.words[0];t=r===e?0:re.length)return 1;if(this.length=0;n--){var o=0|this.words[n],r=0|e.words[n];if(o!==r){or&&(t=1);break}}return t},i.prototype.gtn=function(e){return 1===this.cmpn(e)},i.prototype.gt=function(e){return 1===this.cmp(e)},i.prototype.gten=function(e){return this.cmpn(e)>=0},i.prototype.gte=function(e){return this.cmp(e)>=0},i.prototype.ltn=function(e){return-1===this.cmpn(e)},i.prototype.lt=function(e){return-1===this.cmp(e)},i.prototype.lten=function(e){return this.cmpn(e)<=0},i.prototype.lte=function(e){return this.cmp(e)<=0},i.prototype.eqn=function(e){return 0===this.cmpn(e)},i.prototype.eq=function(e){return 0===this.cmp(e)},i.red=function(e){return new E(e)},i.prototype.toRed=function(e){return o(!this.red,"Already a number in reduction context"),o(0===this.negative,"red works only with positives"),e.convertTo(this)._forceRed(e)},i.prototype.fromRed=function(){return o(this.red,"fromRed works only with numbers in reduction context"),this.red.convertFrom(this)},i.prototype._forceRed=function(e){return this.red=e,this},i.prototype.forceRed=function(e){return o(!this.red,"Already a number in reduction context"),this._forceRed(e)},i.prototype.redAdd=function(e){return o(this.red,"redAdd works only with red numbers"),this.red.add(this,e)},i.prototype.redIAdd=function(e){return o(this.red,"redIAdd works only with red numbers"),this.red.iadd(this,e)},i.prototype.redSub=function(e){return o(this.red,"redSub works only with red numbers"),this.red.sub(this,e)},i.prototype.redISub=function(e){return o(this.red,"redISub works only with red numbers"),this.red.isub(this,e)},i.prototype.redShl=function(e){return o(this.red,"redShl works only with red numbers"),this.red.shl(this,e)},i.prototype.redMul=function(e){return o(this.red,"redMul works only with red numbers"),this.red._verify2(this,e),this.red.mul(this,e)},i.prototype.redIMul=function(e){return o(this.red,"redMul works only with red numbers"),this.red._verify2(this,e),this.red.imul(this,e)},i.prototype.redSqr=function(){return o(this.red,"redSqr works only with red numbers"),this.red._verify1(this),this.red.sqr(this)},i.prototype.redISqr=function(){return o(this.red,"redISqr works only with red numbers"),this.red._verify1(this),this.red.isqr(this)},i.prototype.redSqrt=function(){return o(this.red,"redSqrt works only with red numbers"),this.red._verify1(this),this.red.sqrt(this)},i.prototype.redInvm=function(){return o(this.red,"redInvm works only with red numbers"),this.red._verify1(this),this.red.invm(this)},i.prototype.redNeg=function(){return o(this.red,"redNeg works only with red numbers"),this.red._verify1(this),this.red.neg(this)},i.prototype.redPow=function(e){return o(this.red&&!e.red,"redPow(normalNum)"),this.red._verify1(this),this.red.pow(this,e)};var _={k256:null,p224:null,p192:null,p25519:null};function F(e,t){this.name=e,this.p=new i(t,16),this.n=this.p.bitLength(),this.k=new i(1).iushln(this.n).isub(this.p),this.tmp=this._tmp()}function y(){F.call(this,"k256","ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f")}function b(){F.call(this,"p224","ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001")}function v(){F.call(this,"p192","ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff")}function w(){F.call(this,"25519","7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed")}function E(e){if("string"==typeof e){var t=i._prime(e);this.m=t.p,this.prime=t}else o(e.gtn(1),"modulus must be greater than 1"),this.m=e,this.prime=null}function k(e){E.call(this,e),this.shift=this.m.bitLength(),this.shift%26!=0&&(this.shift+=26-this.shift%26),this.r=new i(1).iushln(this.shift),this.r2=this.imod(this.r.sqr()),this.rinv=this.r._invmp(this.m),this.minv=this.rinv.mul(this.r).isubn(1).div(this.m),this.minv=this.minv.umod(this.r),this.minv=this.r.sub(this.minv)}F.prototype._tmp=function(){var e=new i(null);return e.words=new Array(Math.ceil(this.n/13)),e},F.prototype.ireduce=function(e){var t,n=e;do{this.split(n,this.tmp),t=(n=(n=this.imulK(n)).iadd(this.tmp)).bitLength()}while(t>this.n);var o=t0?n.isub(this.p):void 0!==n.strip?n.strip():n._strip(),n},F.prototype.split=function(e,t){e.iushrn(this.n,0,t)},F.prototype.imulK=function(e){return e.imul(this.k)},r(y,F),y.prototype.split=function(e,t){for(var n=4194303,o=Math.min(e.length,9),r=0;r>>22,i=a}i>>>=22,e.words[r-10]=i,0===i&&e.length>10?e.length-=10:e.length-=9},y.prototype.imulK=function(e){e.words[e.length]=0,e.words[e.length+1]=0,e.length+=2;for(var t=0,n=0;n>>=26,e.words[n]=r,t=o}return 0!==t&&(e.words[e.length++]=t),e},i._prime=function(e){if(_[e])return _[e];var t;if("k256"===e)t=new y;else if("p224"===e)t=new b;else if("p192"===e)t=new v;else{if("p25519"!==e)throw new Error("Unknown prime "+e);t=new w}return _[e]=t,t},E.prototype._verify1=function(e){o(0===e.negative,"red works only with positives"),o(e.red,"red works only with red numbers")},E.prototype._verify2=function(e,t){o(0==(e.negative|t.negative),"red works only with positives"),o(e.red&&e.red===t.red,"red works only with red numbers")},E.prototype.imod=function(e){return this.prime?this.prime.ireduce(e)._forceRed(this):e.umod(this.m)._forceRed(this)},E.prototype.neg=function(e){return e.isZero()?e.clone():this.m.sub(e)._forceRed(this)},E.prototype.add=function(e,t){this._verify2(e,t);var n=e.add(t);return n.cmp(this.m)>=0&&n.isub(this.m),n._forceRed(this)},E.prototype.iadd=function(e,t){this._verify2(e,t);var n=e.iadd(t);return n.cmp(this.m)>=0&&n.isub(this.m),n},E.prototype.sub=function(e,t){this._verify2(e,t);var n=e.sub(t);return n.cmpn(0)<0&&n.iadd(this.m),n._forceRed(this)},E.prototype.isub=function(e,t){this._verify2(e,t);var n=e.isub(t);return n.cmpn(0)<0&&n.iadd(this.m),n},E.prototype.shl=function(e,t){return this._verify1(e),this.imod(e.ushln(t))},E.prototype.imul=function(e,t){return this._verify2(e,t),this.imod(e.imul(t))},E.prototype.mul=function(e,t){return this._verify2(e,t),this.imod(e.mul(t))},E.prototype.isqr=function(e){return this.imul(e,e.clone())},E.prototype.sqr=function(e){return this.mul(e,e)},E.prototype.sqrt=function(e){if(e.isZero())return e.clone();var t=this.m.andln(3);if(o(t%2==1),3===t){var n=this.m.add(new i(1)).iushrn(2);return this.pow(e,n)}for(var r=this.m.subn(1),a=0;!r.isZero()&&0===r.andln(1);)a++,r.iushrn(1);o(!r.isZero());var s=new i(1).toRed(this),u=s.redNeg(),c=this.m.subn(1).iushrn(1),l=this.m.bitLength();for(l=new i(2*l*l).toRed(this);0!==this.pow(l,c).cmp(u);)l.redIAdd(u);for(var d=this.pow(l,r),h=this.pow(e,r.addn(1).iushrn(1)),p=this.pow(e,r),f=a;0!==p.cmp(s);){for(var g=p,m=0;0!==g.cmp(s);m++)g=g.redSqr();o(m=0;o--){for(var c=t.words[o],l=u-1;l>=0;l--){var d=c>>l&1;r!==n[0]&&(r=this.sqr(r)),0!==d||0!==a?(a<<=1,a|=d,(4==++s||0===o&&0===l)&&(r=this.mul(r,n[a]),s=0,a=0)):s=0}u=26}return r},E.prototype.convertTo=function(e){var t=e.umod(this.m);return t===e?t.clone():t},E.prototype.convertFrom=function(e){var t=e.clone();return t.red=null,t},i.mont=function(e){return new k(e)},r(k,E),k.prototype.convertTo=function(e){return this.imod(e.ushln(this.shift))},k.prototype.convertFrom=function(e){var t=this.imod(e.mul(this.rinv));return t.red=null,t},k.prototype.imul=function(e,t){if(e.isZero()||t.isZero())return e.words[0]=0,e.length=1,e;var n=e.imul(t),o=n.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m),r=n.isub(o).iushrn(this.shift),i=r;return r.cmp(this.m)>=0?i=r.isub(this.m):r.cmpn(0)<0&&(i=r.iadd(this.m)),i._forceRed(this)},k.prototype.mul=function(e,t){if(e.isZero()||t.isZero())return new i(0)._forceRed(this);var n=e.mul(t),o=n.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m),r=n.isub(o).iushrn(this.shift),a=r;return r.cmp(this.m)>=0?a=r.isub(this.m):r.cmpn(0)<0&&(a=r.iadd(this.m)),a._forceRed(this)},k.prototype.invm=function(e){return this.imod(e._invmp(this.m).mul(this.r2))._forceRed(this)}}(e=n.nmd(e),this)},26138:(e,t,n)=>{var o=n(70980),r=n(99199),i=n(57859),a=n(92144),s=n(23663),u=n(23482),c=n(84818),l=n(89509).Buffer;e.exports=function(e,t,n){var d;d=e.padding?e.padding:n?1:4;var h,p=o(e),f=p.modulus.byteLength();if(t.length>f||new a(t).cmp(p.modulus)>=0)throw new Error("decryption error");h=n?c(new a(t),p):s(t,p);var g=l.alloc(f-h.length);if(h=l.concat([g,h],f),4===d)return function(e,t){var n=e.modulus.byteLength(),o=u("sha1").update(l.alloc(0)).digest(),a=o.length;if(0!==t[0])throw new Error("decryption error");var s=t.slice(1,a+1),c=t.slice(a+1),d=i(s,r(c,a)),h=i(c,r(d,n-a-1));if(function(e,t){e=l.from(e),t=l.from(t);var n=0,o=e.length;e.length!==t.length&&(n++,o=Math.min(e.length,t.length));for(var r=-1;++r=t.length){i++;break}var a=t.slice(2,r-1);if(("0002"!==o.toString("hex")&&!n||"0001"!==o.toString("hex")&&n)&&i++,a.length<8&&i++,i)throw new Error("decryption error");return t.slice(r)}(0,h,n);if(3===d)return h;throw new Error("unknown padding")}},16559:(e,t,n)=>{var o=n(70980),r=n(61798),i=n(23482),a=n(99199),s=n(57859),u=n(92144),c=n(84818),l=n(23663),d=n(89509).Buffer;e.exports=function(e,t,n){var h;h=e.padding?e.padding:n?1:4;var p,f=o(e);if(4===h)p=function(e,t){var n=e.modulus.byteLength(),o=t.length,c=i("sha1").update(d.alloc(0)).digest(),l=c.length,h=2*l;if(o>n-h-2)throw new Error("message too long");var p=d.alloc(n-o-h-2),f=n-l-1,g=r(l),m=s(d.concat([c,p,d.alloc(1,1),t],f),a(g,f)),_=s(g,a(m,l));return new u(d.concat([d.alloc(1),_,m],n))}(f,t);else if(1===h)p=function(e,t,n){var o,i=t.length,a=e.modulus.byteLength();if(i>a-11)throw new Error("message too long");return o=n?d.alloc(a-i-3,255):function(e){for(var t,n=d.allocUnsafe(e),o=0,i=r(2*e),a=0;o=0)throw new Error("data too long for modulus")}return n?l(p,f):c(p,f)}},84818:(e,t,n)=>{var o=n(92144),r=n(89509).Buffer;e.exports=function(e,t){return r.from(e.toRed(o.mont(t.modulus)).redPow(new o(t.publicExponent)).fromRed().toArray())}},57859:e=>{e.exports=function(e,t){for(var n=e.length,o=-1;++o{"use strict";var t=String.prototype.replace,n=/%20/g,o="RFC3986";e.exports={default:o,formatters:{RFC1738:function(e){return t.call(e,n,"+")},RFC3986:function(e){return String(e)}},RFC1738:"RFC1738",RFC3986:o}},80129:(e,t,n)=>{"use strict";var o=n(58261),r=n(55235),i=n(55798);e.exports={formats:i,parse:r,stringify:o}},55235:(e,t,n)=>{"use strict";var o=n(12769),r=Object.prototype.hasOwnProperty,i=Array.isArray,a={allowDots:!1,allowPrototypes:!1,allowSparse:!1,arrayLimit:20,charset:"utf-8",charsetSentinel:!1,comma:!1,decoder:o.decode,delimiter:"&",depth:5,ignoreQueryPrefix:!1,interpretNumericEntities:!1,parameterLimit:1e3,parseArrays:!0,plainObjects:!1,strictNullHandling:!1},s=function(e){return e.replace(/&#(\d+);/g,(function(e,t){return String.fromCharCode(parseInt(t,10))}))},u=function(e,t){return e&&"string"==typeof e&&t.comma&&e.indexOf(",")>-1?e.split(","):e},c=function(e,t,n,o){if(e){var i=n.allowDots?e.replace(/\.([^.[]+)/g,"[$1]"):e,a=/(\[[^[\]]*])/g,s=n.depth>0&&/(\[[^[\]]*])/.exec(i),c=s?i.slice(0,s.index):i,l=[];if(c){if(!n.plainObjects&&r.call(Object.prototype,c)&&!n.allowPrototypes)return;l.push(c)}for(var d=0;n.depth>0&&null!==(s=a.exec(i))&&d=0;--i){var a,s=e[i];if("[]"===s&&n.parseArrays)a=[].concat(r);else{a=n.plainObjects?Object.create(null):{};var c="["===s.charAt(0)&&"]"===s.charAt(s.length-1)?s.slice(1,-1):s,l=parseInt(c,10);n.parseArrays||""!==c?!isNaN(l)&&s!==c&&String(l)===c&&l>=0&&n.parseArrays&&l<=n.arrayLimit?(a=[])[l]=r:a[c]=r:a={0:r}}r=a}return r}(l,t,n,o)}};e.exports=function(e,t){var n=function(e){if(!e)return a;if(null!==e.decoder&&void 0!==e.decoder&&"function"!=typeof e.decoder)throw new TypeError("Decoder has to be a function.");if(void 0!==e.charset&&"utf-8"!==e.charset&&"iso-8859-1"!==e.charset)throw new TypeError("The charset option must be either utf-8, iso-8859-1, or undefined");var t=void 0===e.charset?a.charset:e.charset;return{allowDots:void 0===e.allowDots?a.allowDots:!!e.allowDots,allowPrototypes:"boolean"==typeof e.allowPrototypes?e.allowPrototypes:a.allowPrototypes,allowSparse:"boolean"==typeof e.allowSparse?e.allowSparse:a.allowSparse,arrayLimit:"number"==typeof e.arrayLimit?e.arrayLimit:a.arrayLimit,charset:t,charsetSentinel:"boolean"==typeof e.charsetSentinel?e.charsetSentinel:a.charsetSentinel,comma:"boolean"==typeof e.comma?e.comma:a.comma,decoder:"function"==typeof e.decoder?e.decoder:a.decoder,delimiter:"string"==typeof e.delimiter||o.isRegExp(e.delimiter)?e.delimiter:a.delimiter,depth:"number"==typeof e.depth||!1===e.depth?+e.depth:a.depth,ignoreQueryPrefix:!0===e.ignoreQueryPrefix,interpretNumericEntities:"boolean"==typeof e.interpretNumericEntities?e.interpretNumericEntities:a.interpretNumericEntities,parameterLimit:"number"==typeof e.parameterLimit?e.parameterLimit:a.parameterLimit,parseArrays:!1!==e.parseArrays,plainObjects:"boolean"==typeof e.plainObjects?e.plainObjects:a.plainObjects,strictNullHandling:"boolean"==typeof e.strictNullHandling?e.strictNullHandling:a.strictNullHandling}}(t);if(""===e||null==e)return n.plainObjects?Object.create(null):{};for(var l="string"==typeof e?function(e,t){var n,c={},l=t.ignoreQueryPrefix?e.replace(/^\?/,""):e,d=t.parameterLimit===1/0?void 0:t.parameterLimit,h=l.split(t.delimiter,d),p=-1,f=t.charset;if(t.charsetSentinel)for(n=0;n-1&&(m=i(m)?[m]:m),r.call(c,g)?c[g]=o.combine(c[g],m):c[g]=m}return c}(e,n):e,d=n.plainObjects?Object.create(null):{},h=Object.keys(l),p=0;p{"use strict";var o=n(37478),r=n(12769),i=n(55798),a=Object.prototype.hasOwnProperty,s={brackets:function(e){return e+"[]"},comma:"comma",indices:function(e,t){return e+"["+t+"]"},repeat:function(e){return e}},u=Array.isArray,c=Array.prototype.push,l=function(e,t){c.apply(e,u(t)?t:[t])},d=Date.prototype.toISOString,h=i.default,p={addQueryPrefix:!1,allowDots:!1,charset:"utf-8",charsetSentinel:!1,delimiter:"&",encode:!0,encoder:r.encode,encodeValuesOnly:!1,format:h,formatter:i.formatters[h],indices:!1,serializeDate:function(e){return d.call(e)},skipNulls:!1,strictNullHandling:!1},f=function e(t,n,i,a,s,c,d,h,f,g,m,_,F,y,b){var v,w=t;if(b.has(t))throw new RangeError("Cyclic object value");if("function"==typeof d?w=d(n,w):w instanceof Date?w=g(w):"comma"===i&&u(w)&&(w=r.maybeMap(w,(function(e){return e instanceof Date?g(e):e}))),null===w){if(a)return c&&!F?c(n,p.encoder,y,"key",m):n;w=""}if("string"==typeof(v=w)||"number"==typeof v||"boolean"==typeof v||"symbol"==typeof v||"bigint"==typeof v||r.isBuffer(w))return c?[_(F?n:c(n,p.encoder,y,"key",m))+"="+_(c(w,p.encoder,y,"value",m))]:[_(n)+"="+_(String(w))];var E,k=[];if(void 0===w)return k;if("comma"===i&&u(w))E=[{value:w.length>0?w.join(",")||null:void 0}];else if(u(d))E=d;else{var D=Object.keys(w);E=h?D.sort(h):D}for(var S=0;S0?b+y:""}},12769:(e,t,n)=>{"use strict";var o=n(55798),r=Object.prototype.hasOwnProperty,i=Array.isArray,a=function(){for(var e=[],t=0;t<256;++t)e.push("%"+((t<16?"0":"")+t.toString(16)).toUpperCase());return e}(),s=function(e,t){for(var n=t&&t.plainObjects?Object.create(null):{},o=0;o1;){var t=e.pop(),n=t.obj[t.prop];if(i(n)){for(var o=[],r=0;r=48&&l<=57||l>=65&&l<=90||l>=97&&l<=122||i===o.RFC1738&&(40===l||41===l)?u+=s.charAt(c):l<128?u+=a[l]:l<2048?u+=a[192|l>>6]+a[128|63&l]:l<55296||l>=57344?u+=a[224|l>>12]+a[128|l>>6&63]+a[128|63&l]:(c+=1,l=65536+((1023&l)<<10|1023&s.charCodeAt(c)),u+=a[240|l>>18]+a[128|l>>12&63]+a[128|l>>6&63]+a[128|63&l])}return u},isBuffer:function(e){return!(!e||"object"!=typeof e||!(e.constructor&&e.constructor.isBuffer&&e.constructor.isBuffer(e)))},isRegExp:function(e){return"[object RegExp]"===Object.prototype.toString.call(e)},maybeMap:function(e,t){if(i(e)){for(var n=[],o=0;o{"use strict";function t(e,t){return Object.prototype.hasOwnProperty.call(e,t)}e.exports=function(e,n,o,r){n=n||"&",o=o||"=";var i={};if("string"!=typeof e||0===e.length)return i;var a=/\+/g;e=e.split(n);var s=1e3;r&&"number"==typeof r.maxKeys&&(s=r.maxKeys);var u=e.length;s>0&&u>s&&(u=s);for(var c=0;c=0?(l=f.substr(0,g),d=f.substr(g+1)):(l=f,d=""),h=decodeURIComponent(l),p=decodeURIComponent(d),t(i,h)?Array.isArray(i[h])?i[h].push(p):i[h]=[i[h],p]:i[h]=p}return i}},12361:e=>{"use strict";var t=function(e){switch(typeof e){case"string":return e;case"boolean":return e?"true":"false";case"number":return isFinite(e)?e:"";default:return""}};e.exports=function(e,n,o,r){return n=n||"&",o=o||"=",null===e&&(e=void 0),"object"==typeof e?Object.keys(e).map((function(r){var i=encodeURIComponent(t(r))+o;return Array.isArray(e[r])?e[r].map((function(e){return i+encodeURIComponent(t(e))})).join(n):i+encodeURIComponent(t(e[r]))})).join(n):r?encodeURIComponent(t(r))+o+encodeURIComponent(t(e)):""}},17673:(e,t,n)=>{"use strict";t.decode=t.parse=n(62587),t.encode=t.stringify=n(12361)},61798:(e,t,n)=>{"use strict";var o=65536,r=n(89509).Buffer,i=n.g.crypto||n.g.msCrypto;i&&i.getRandomValues?e.exports=function(e,t){if(e>4294967295)throw new RangeError("requested too many random bytes");var n=r.allocUnsafe(e);if(e>0)if(e>o)for(var a=0;a{"use strict";function o(){throw new Error("secure random number generation not supported by this browser\nuse chrome, FireFox or Internet Explorer 11")}var r=n(89509),i=n(61798),a=r.Buffer,s=r.kMaxLength,u=n.g.crypto||n.g.msCrypto,c=Math.pow(2,32)-1;function l(e,t){if("number"!=typeof e||e!=e)throw new TypeError("offset must be a number");if(e>c||e<0)throw new TypeError("offset must be a uint32");if(e>s||e>t)throw new RangeError("offset out of range")}function d(e,t,n){if("number"!=typeof e||e!=e)throw new TypeError("size must be a number");if(e>c||e<0)throw new TypeError("size must be a uint32");if(e+t>n||e>s)throw new RangeError("buffer too small")}function h(e,t,n,o){if(process.browser){var r=e.buffer,a=new Uint8Array(r,t,n);return u.getRandomValues(a),o?void process.nextTick((function(){o(null,e)})):e}if(!o)return i(n).copy(e,t),e;i(n,(function(n,r){if(n)return o(n);r.copy(e,t),o(null,e)}))}u&&u.getRandomValues||!process.browser?(t.randomFill=function(e,t,o,r){if(!(a.isBuffer(e)||e instanceof n.g.Uint8Array))throw new TypeError('"buf" argument must be a Buffer or Uint8Array');if("function"==typeof t)r=t,t=0,o=e.length;else if("function"==typeof o)r=o,o=e.length-t;else if("function"!=typeof r)throw new TypeError('"cb" argument must be a function');return l(t,e.length),d(o,t,e.length),h(e,t,o,r)},t.randomFillSync=function(e,t,o){if(void 0===t&&(t=0),!(a.isBuffer(e)||e instanceof n.g.Uint8Array))throw new TypeError('"buf" argument must be a Buffer or Uint8Array');return l(t,e.length),void 0===o&&(o=e.length-t),d(o,t,e.length),h(e,t,o)}):(t.randomFill=o,t.randomFillSync=o)},4857:function(e,t,n){"use strict";var o,r=this&&this.__extends||(o=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n])},function(e,t){function n(){this.constructor=e}o(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}),i=this&&this.__assign||Object.assign||function(e){for(var t,n=1,o=arguments.length;n{"use strict";var o=n(4857);t.Z=o.TextareaAutosize},64448:(e,t,n)=>{"use strict";var o=n(67294),r=n(27418),i=n(63840);function a(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n
    ")})),l=function(){var t=/(?:)/,r=t.exec;t.exec=function(){return r.apply(this,arguments)};var n="ab".split(t);return 2===n.length&&"a"===n[0]&&"b"===n[1]}();t.exports=function(t,r,n){var h=a(t),v=!o((function(){var r={};return r[h]=function(){return 7},7!=""[t](r)})),p=v?!o((function(){var r=!1,n=/a/;return n.exec=function(){return r=!0,null},"split"===t&&(n.constructor={},n.constructor[s]=function(){return n}),n[h](""),!r})):void 0;if(!v||!p||"replace"===t&&!f||"split"===t&&!l){var g=/./[h],d=n(u,h,""[t],(function(t,r,n,e,i){return r.exec===c?v&&!i?{done:!0,value:g.call(r,n,e)}:{done:!0,value:t.call(n,r,e)}:{done:!1}})),y=d[0],x=d[1];e(String.prototype,t,y),i(RegExp.prototype,h,2==r?function(t,r){return x.call(t,this,r)}:function(t){return x.call(t,this)})}}},53218:(t,r,n)=>{"use strict";var e=n(27007);t.exports=function(){var t=e(this),r="";return t.global&&(r+="g"),t.ignoreCase&&(r+="i"),t.multiline&&(r+="m"),t.unicode&&(r+="u"),t.sticky&&(r+="y"),r}},13325:(t,r,n)=>{"use strict";var e=n(4302),i=n(55286),o=n(10875),u=n(741),a=n(86314)("isConcatSpreadable");t.exports=function t(r,n,c,s,f,l,h,v){for(var p,g,d=f,y=0,x=!!h&&u(h,v,3);y0)d=t(r,n,p,o(p.length),d,l-1)-1;else{if(d>=9007199254740991)throw TypeError();r[d]=p}d++}y++}return d}},3531:(t,r,n)=>{var e=n(741),i=n(28851),o=n(86555),u=n(27007),a=n(10875),c=n(69002),s={},f={},l=t.exports=function(t,r,n,l,h){var v,p,g,d,y=h?function(){return t}:c(t),x=e(n,l,r?2:1),b=0;if("function"!=typeof y)throw TypeError(t+" is not iterable!");if(o(y)){for(v=a(t.length);v>b;b++)if((d=r?x(u(p=t[b])[0],p[1]):x(t[b]))===s||d===f)return d}else for(g=y.call(t);!(p=g.next()).done;)if((d=i(g,x,p.value,r))===s||d===f)return d};l.BREAK=s,l.RETURN=f},40018:(t,r,n)=>{t.exports=n(3825)("native-function-to-string",Function.toString)},3816:t=>{var r=t.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=r)},79181:t=>{var r={}.hasOwnProperty;t.exports=function(t,n){return r.call(t,n)}},87728:(t,r,n)=>{var e=n(99275),i=n(90681);t.exports=n(67057)?function(t,r,n){return e.f(t,r,i(1,n))}:function(t,r,n){return t[r]=n,t}},40639:(t,r,n)=>{var e=n(3816).document;t.exports=e&&e.documentElement},1734:(t,r,n)=>{t.exports=!n(67057)&&!n(74253)((function(){return 7!=Object.defineProperty(n(62457)("div"),"a",{get:function(){return 7}}).a}))},40266:(t,r,n)=>{var e=n(55286),i=n(27375).set;t.exports=function(t,r,n){var o,u=r.constructor;return u!==n&&"function"==typeof u&&(o=u.prototype)!==n.prototype&&e(o)&&i&&i(t,o),t}},97242:t=>{t.exports=function(t,r,n){var e=void 0===n;switch(r.length){case 0:return e?t():t.call(n);case 1:return e?t(r[0]):t.call(n,r[0]);case 2:return e?t(r[0],r[1]):t.call(n,r[0],r[1]);case 3:return e?t(r[0],r[1],r[2]):t.call(n,r[0],r[1],r[2]);case 4:return e?t(r[0],r[1],r[2],r[3]):t.call(n,r[0],r[1],r[2],r[3])}return t.apply(n,r)}},49797:(t,r,n)=>{var e=n(92032);t.exports=Object("z").propertyIsEnumerable(0)?Object:function(t){return"String"==e(t)?t.split(""):Object(t)}},86555:(t,r,n)=>{var e=n(87234),i=n(86314)("iterator"),o=Array.prototype;t.exports=function(t){return void 0!==t&&(e.Array===t||o[i]===t)}},4302:(t,r,n)=>{var e=n(92032);t.exports=Array.isArray||function(t){return"Array"==e(t)}},18367:(t,r,n)=>{var e=n(55286),i=Math.floor;t.exports=function(t){return!e(t)&&isFinite(t)&&i(t)===t}},55286:t=>{t.exports=function(t){return"object"==typeof t?null!==t:"function"==typeof t}},55364:(t,r,n)=>{var e=n(55286),i=n(92032),o=n(86314)("match");t.exports=function(t){var r;return e(t)&&(void 0!==(r=t[o])?!!r:"RegExp"==i(t))}},28851:(t,r,n)=>{var e=n(27007);t.exports=function(t,r,n,i){try{return i?r(e(n)[0],n[1]):r(n)}catch(r){var o=t.return;throw void 0!==o&&e(o.call(t)),r}}},49988:(t,r,n)=>{"use strict";var e=n(42503),i=n(90681),o=n(22943),u={};n(87728)(u,n(86314)("iterator"),(function(){return this})),t.exports=function(t,r,n){t.prototype=e(u,{next:i(1,n)}),o(t,r+" Iterator")}},42923:(t,r,n)=>{"use strict";var e=n(4461),i=n(42985),o=n(77234),u=n(87728),a=n(87234),c=n(49988),s=n(22943),f=n(468),l=n(86314)("iterator"),h=!([].keys&&"next"in[].keys()),v="keys",p="values",g=function(){return this};t.exports=function(t,r,n,d,y,x,b){c(n,r,d);var m,S,w,_=function(t){if(!h&&t in P)return P[t];switch(t){case v:case p:return function(){return new n(this,t)}}return function(){return new n(this,t)}},E=r+" Iterator",O=y==p,M=!1,P=t.prototype,F=P[l]||P["@@iterator"]||y&&P[y],A=F||_(y),I=y?O?_("entries"):A:void 0,j="Array"==r&&P.entries||F;if(j&&(w=f(j.call(new t)))!==Object.prototype&&w.next&&(s(w,E,!0),e||"function"==typeof w[l]||u(w,l,g)),O&&F&&F.name!==p&&(M=!0,A=function(){return F.call(this)}),e&&!b||!h&&!M&&P[l]||u(P,l,A),a[r]=A,a[E]=g,y)if(m={values:O?A:_(p),keys:x?A:_(v),entries:I},b)for(S in m)S in P||o(P,S,m[S]);else i(i.P+i.F*(h||M),r,m);return m}},7462:(t,r,n)=>{var e=n(86314)("iterator"),i=!1;try{var o=[7][e]();o.return=function(){i=!0},Array.from(o,(function(){throw 2}))}catch(t){}t.exports=function(t,r){if(!r&&!i)return!1;var n=!1;try{var o=[7],u=o[e]();u.next=function(){return{done:n=!0}},o[e]=function(){return u},t(o)}catch(t){}return n}},15436:t=>{t.exports=function(t,r){return{value:r,done:!!t}}},87234:t=>{t.exports={}},4461:t=>{t.exports=!1},13086:t=>{var r=Math.expm1;t.exports=!r||r(10)>22025.465794806718||r(10)<22025.465794806718||-2e-17!=r(-2e-17)?function(t){return 0==(t=+t)?t:t>-1e-6&&t<1e-6?t+t*t/2:Math.exp(t)-1}:r},34934:(t,r,n)=>{var e=n(61801),i=Math.pow,o=i(2,-52),u=i(2,-23),a=i(2,127)*(2-u),c=i(2,-126);t.exports=Math.fround||function(t){var r,n,i=Math.abs(t),s=e(t);return ia||n!=n?s*(1/0):s*n}},46206:t=>{t.exports=Math.log1p||function(t){return(t=+t)>-1e-8&&t<1e-8?t-t*t/2:Math.log(1+t)}},68757:t=>{t.exports=Math.scale||function(t,r,n,e,i){return 0===arguments.length||t!=t||r!=r||n!=n||e!=e||i!=i?NaN:t===1/0||t===-1/0?t:(t-r)*(i-e)/(n-r)+e}},61801:t=>{t.exports=Math.sign||function(t){return 0==(t=+t)||t!=t?t:t<0?-1:1}},84728:(t,r,n)=>{var e=n(93953)("meta"),i=n(55286),o=n(79181),u=n(99275).f,a=0,c=Object.isExtensible||function(){return!0},s=!n(74253)((function(){return c(Object.preventExtensions({}))})),f=function(t){u(t,e,{value:{i:"O"+ ++a,w:{}}})},l=t.exports={KEY:e,NEED:!1,fastKey:function(t,r){if(!i(t))return"symbol"==typeof t?t:("string"==typeof t?"S":"P")+t;if(!o(t,e)){if(!c(t))return"F";if(!r)return"E";f(t)}return t[e].i},getWeak:function(t,r){if(!o(t,e)){if(!c(t))return!0;if(!r)return!1;f(t)}return t[e].w},onFreeze:function(t){return s&&l.NEED&&c(t)&&!o(t,e)&&f(t),t}}},50133:(t,r,n)=>{var e=n(88416),i=n(42985),o=n(3825)("metadata"),u=o.store||(o.store=new(n(30147))),a=function(t,r,n){var i=u.get(t);if(!i){if(!n)return;u.set(t,i=new e)}var o=i.get(r);if(!o){if(!n)return;i.set(r,o=new e)}return o};t.exports={store:u,map:a,has:function(t,r,n){var e=a(r,n,!1);return void 0!==e&&e.has(t)},get:function(t,r,n){var e=a(r,n,!1);return void 0===e?void 0:e.get(t)},set:function(t,r,n,e){a(n,e,!0).set(t,r)},keys:function(t,r){var n=a(t,r,!1),e=[];return n&&n.forEach((function(t,r){e.push(r)})),e},key:function(t){return void 0===t||"symbol"==typeof t?t:String(t)},exp:function(t){i(i.S,"Reflect",t)}}},14351:(t,r,n)=>{var e=n(3816),i=n(74193).set,o=e.MutationObserver||e.WebKitMutationObserver,u=e.process,a=e.Promise,c="process"==n(92032)(u);t.exports=function(){var t,r,n,s=function(){var e,i;for(c&&(e=u.domain)&&e.exit();t;){i=t.fn,t=t.next;try{i()}catch(e){throw t?n():r=void 0,e}}r=void 0,e&&e.enter()};if(c)n=function(){u.nextTick(s)};else if(!o||e.navigator&&e.navigator.standalone)if(a&&a.resolve){var f=a.resolve(void 0);n=function(){f.then(s)}}else n=function(){i.call(e,s)};else{var l=!0,h=document.createTextNode("");new o(s).observe(h,{characterData:!0}),n=function(){h.data=l=!l}}return function(e){var i={fn:e,next:void 0};r&&(r.next=i),t||(t=i,n()),r=i}}},43499:(t,r,n)=>{"use strict";var e=n(24963);function i(t){var r,n;this.promise=new t((function(t,e){if(void 0!==r||void 0!==n)throw TypeError("Bad Promise constructor");r=t,n=e})),this.resolve=e(r),this.reject=e(n)}t.exports.f=function(t){return new i(t)}},35345:(t,r,n)=>{"use strict";var e=n(67057),i=n(47184),o=n(64548),u=n(14682),a=n(20508),c=n(49797),s=Object.assign;t.exports=!s||n(74253)((function(){var t={},r={},n=Symbol(),e="abcdefghijklmnopqrst";return t[n]=7,e.split("").forEach((function(t){r[t]=t})),7!=s({},t)[n]||Object.keys(s({},r)).join("")!=e}))?function(t,r){for(var n=a(t),s=arguments.length,f=1,l=o.f,h=u.f;s>f;)for(var v,p=c(arguments[f++]),g=l?i(p).concat(l(p)):i(p),d=g.length,y=0;d>y;)v=g[y++],e&&!h.call(p,v)||(n[v]=p[v]);return n}:s},42503:(t,r,n)=>{var e=n(27007),i=n(35588),o=n(74430),u=n(69335)("IE_PROTO"),a=function(){},c=function(){var t,r=n(62457)("iframe"),e=o.length;for(r.style.display="none",n(40639).appendChild(r),r.src="javascript:",(t=r.contentWindow.document).open(),t.write("
    \ No newline at end of file diff --git a/dist/main.7e67114cb989c8c9f008.bundle.css b/dist/main.7e67114cb989c8c9f008.bundle.css deleted file mode 100644 index d549aee6f..000000000 --- a/dist/main.7e67114cb989c8c9f008.bundle.css +++ /dev/null @@ -1 +0,0 @@ -@import url(https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,300;0,400;0,500;0,700;1,300;1,400;1,500;1,700&display=swap);:root{--bg-surface:#fff;--bg-surface-low:#f6f6f6;--bg-surface-hover:rgba(0,0,0,3%);--bg-surface-active:rgba(0,0,0,5%);--bg-surface-border:rgba(0,0,0,6%);--bg-primary:#536eea;--bg-primary-hover:rgba(83,110,234,80%);--bg-primary-active:rgba(83,110,234,70%);--bg-primary-border:rgba(83,110,234,38%);--bg-positive:#45b83b;--bg-caution:#ffb300;--bg-caution-hover:rgba(255,179,0,8%);--bg-caution-active:rgba(255,179,0,15%);--bg-caution-border:rgba(255,179,0,40%);--bg-danger:#f04747;--bg-danger-hover:rgba(240,71,71,5%);--bg-danger-active:rgba(240,71,71,10%);--bg-danger-border:rgba(240,71,71,20%);--bg-tooltip:#353535;--tc-surface-high:#000;--tc-surface-normal:rgba(0,0,0,68%);--tc-surface-low:rgba(0,0,0,38%);--tc-primary-high:#fff;--tc-primary-normal:rgba(255,255,255,68%);--tc-primary-low:rgba(255,255,255,40%);--tc-caution-high:var(--bg-caution);--tc-caution-normal:rgb(255,179,0,80%);--tc-caution-low:rgb(255,179,0,60%);--tc-danger-high:var(--bg-danger);--tc-danger-normal:rgba(240,71,71,88%);--tc-danger-low:rgba(240,71,71,60%);--tc-code:#e62498;--tc-tooltip:#fff;--ic-surface-normal:#626262;--ic-primary-normal:#fff;--ic-caution-normal:rgba(255,179,0,80%);--ic-danger-normal:rgba(240,71,71,0.7);--ic-large:38px;--ic-normal:24px;--ic-small:20px;--ic-extra-small:18px;--av-large:80px;--av-normal:42px;--av-small:36px;--av-extra-small:24px;--bg-overlay:rgba(0,0,0,20%);--bs-popup:0 0 16px rgba(0,0,0,10%);--bs-surface-border:inset 0 0 0 1px var(--bg-surface-border);--bs-surface-outline:0 0 0 2px var(--bg-surface-border);--bs-primary-border:inset 0 0 0 1px var(--bg-primary-border);--bs-primary-outline:0 0 0 2px var(--bg-primary-border);--bs-caution-border:inset 0 0 0 1px var(--bg-caution-border);--bs-caution-outline:0 0 0 2px var(--bg-caution-border);--bs-danger-border:inset 0 0 0 1px var(--bg-danger-border);--bs-danger-outline:0 0 0 2px var(--bg-danger-border);--bo-radius:8px;--fs-h1:36px;--ls-h1:-1.5px;--lh-h1:38px;--fs-h2:24px;--ls-h2:-0.5px;--lh-h2:30px;--fs-s1:18px;--ls-s1:-0.2px;--lh-s1:24px;--fs-b1:16px;--ls-b1:0.1px;--lh-b1:24px;--fs-b2:14px;--ls-b2:0.2px;--lh-b2:20px;--fs-b3:12px;--ls-b3:0px;--lh-b3:16px;--sp-none:0px;--sp-ultra-tight:4px;--sp-extra-tight:8px;--sp-tight:12px;--sp-normal:16px;--sp-loose:20px;--sp-extra-loose:32px;--border-width:1px;--header-height:54px;--navigation-sidebar-width:calc(64px + var(--border-width));--navigation-drawer-width:calc(280px + var(--border-width));--navigation-width:calc(var(--navigation-sidebar-width) + var(--navigation-drawer-width));--people-drawer-width:calc(268px - var(--border-width));--font-family:"Roboto","Supreme",sans-serif}.silver-theme{--bg-surface:#f2f2f2;--bg-surface-low:#e8e8e8}.butter-theme,.dark-theme{--bg-surface:#2f3337;--bg-surface-low:#26292c;--bg-surface-hover:rgba(255,255,255,3%);--bg-surface-active:rgba(255,255,255,5%);--bg-surface-border:rgba(0,0,0,20%);--bg-primary:#3b77bf;--bg-primary-hover:rgba(59,119,191,80%);--bg-primary-active:rgba(59,119,191,70%);--bg-primary-border:rgba(59,119,191,38%);--bg-tooltip:#000;--tc-surface-high:rgba(255,255,255,94%);--tc-surface-normal:rgba(255,255,255,74%);--tc-surface-low:rgba(255,255,255,38%);--tc-primary-high:#fff;--tc-primary-normal:hsla(0,0%,100%,0.68);--tc-primary-low:hsla(0,0%,100%,0.4);--tc-code:#e565b1;--ic-surface-normal:rgba(255,255,255,68%);--ic-primary-normal:#fff;--bg-overlay:rgba(0,0,0,50%);--bs-popup:0 0 16px rgba(0,0,0,25%);--bs-surface-border:inset 0 0 0 1px var(--bg-surface-border);--bs-surface-outline:0 0 0 2px var(--bg-surface-border);--bs-primary-border:inset 0 0 0 1px var(--bg-primary-border);--bs-primary-outline:0 0 0 2px var(--bg-primary-border);--font-family:"Supreme","Roboto",sans-serif}.butter-theme{--bg-surface:#262622;--bg-surface-low:#1b1b18;--tc-surface-high:rgb(255,251,222,94%);--tc-surface-normal:rgba(255,251,222,74%);--tc-surface-low:rgba(255,251,222,38%);--ic-surface-normal:rgb(255 251 222/68%)}body,html{height:100%}body{margin:0;padding:0;font-family:var(--font-family);font-size:16px;background-color:var(--bg-surface-low)}#root{width:100%;height:100%}*,:after,:before{box-sizing:border-box;-webkit-tap-highlight-color:rgba(0,0,0,0);-webkit-tap-highlight-color:transparent}a{color:var(--bg-primary);text-decoration:none}b{font-weight:500}button,label,textarea{margin:0;padding:0}button,textarea{background-color:transparent;font-family:inherit;font-size:inherit;font-weight:inherit;line-height:inherit;letter-spacing:inherit;border:none}button{max-width:100%;text-transform:none;text-align:inherit;overflow:visible;-webkit-appearance:button}textarea{color:inherit;word-spacing:inherit}.noselect{-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.flex,.flex--center,.flex--center-baseline,.flex--end,.flex--end-center,.flex--spaceBetween,.flex--spaceBetween-center,.inline-flex--center{display:flex}.flex-v,.flex-v--center,.flex-v--end{display:flex;flex-direction:column}.flex--center,.flex--center-baseline,.flex--end-center,.flex--spaceBetween-center,.inline-flex--center{justify-content:center;align-items:center}.flex--spaceBetween,.flex--spaceBetween-center{justify-content:space-between}.flex--end,.flex--end-center{justify-content:flex-end}.inline-flex--center{display:inline-flex}.flex--center-baseline{align-items:baseline}.flex-v--center{justify-content:center}.flex-v--end{justify-content:flex-end}.auth__wrapper{min-height:100vh;padding:var(--sp-loose);background-color:var(--bg-surface-low);background-image:url(https://images.unsplash.com/photo-1562619371-b67725b6fde2?auto=format&fit=crop&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&q=80&w=1950);background-size:cover;background-repeat:no-repeat;background-position:50%}.auth__wrapper .auth-card{width:462px;min-height:644px;background-color:var(--bg-surface-low);border-radius:var(--bo-radius);box-shadow:var(--bs-popup);overflow:hidden;display:flex;flex-flow:row nowrap}.auth__wrapper .auth-card__interactive{flex:1;min-width:0;padding:calc(var(--sp-normal) + var(--sp-extra-loose));padding-bottom:var(--sp-extra-loose);background-color:var(--bg-surface)}.app-ident{margin-bottom:var(--sp-extra-loose)}.app-ident__logo{width:60px;height:60px}.app-ident__text{margin-left:calc(var(--sp-loose) + var(--sp-ultra-tight))}.app-ident__text .text-s1{margin-top:var(--sp-tight);color:var(--tc-surface-normal)}[dir=rtl] .app-ident__text{margin-left:0;margin-right:calc(var(--sp-loose) + var(--sp-ultra-tight))}.auth-form>.text{margin-bottom:var(--sp-loose);margin-top:var(--sp-loose)}.auth-form>.input-container{margin-top:var(--sp-tight)}.auth-form .submit-btn__wrapper{margin-top:var(--sp-extra-loose);margin-bottom:var(--sp-loose);align-items:flex-start}.auth-form .submit-btn__wrapper>.error-message{display:none;flex:1;color:var(--tc-danger-normal);margin-right:var(--sp-normal);word-break:break}[dir=rtl] .auth-form .submit-btn__wrapper>.error-message{margin-right:0;margin-left:var(--sp-normal)}.auth-form__wrapper{height:100%}.username__wrapper{display:flex;align-items:flex-end}.username__wrapper>:first-child{flex:1}.username__wrapper>:first-child .input{border-radius:var(--bo-radius) 0 0 var(--bo-radius)}[dir=rtl] .username__wrapper>:first-child .input{border-radius:0 var(--bo-radius) var(--bo-radius) 0}.username__wrapper>:last-child{width:110px}.username__wrapper>:last-child .input{border-left-width:0;background-color:var(--bg-surface);border-radius:0 var(--bo-radius) var(--bo-radius) 0}[dir=rtl] .username__wrapper>:last-child .input{border-left-width:1px;border-right-width:0;border-radius:var(--bo-radius) 0 0 var(--bo-radius)}@media(max-width:462px){.auth__wrapper{padding:0;background-image:none;background-color:var(--bg-surface)}.auth__wrapper .auth-card{border-radius:0;box-shadow:none}.auth__wrapper .auth-card__interactive{padding:var(--sp-extra-loose)}}.process-wrapper{display:flex;flex-direction:column;justify-content:center;align-items:center;min-height:100%;width:100%;background-color:var(--bg-surface-low);opacity:.96;position:fixed;top:0;left:0;z-index:999}.text-b1,.text-b2,.text-b3,.text-h1,.text-h2,.text-s1{margin:0;padding:0;color:var(--tc-surface-high)}.text-h1{font-size:var(--fs-h1);font-weight:500;letter-spacing:var(--ls-h1);line-height:var(--lh-h1)}.text-h2{font-size:var(--fs-h2);font-weight:500;letter-spacing:var(--ls-h2);line-height:var(--lh-h2)}.text-s1{font-size:var(--fs-s1);font-weight:400;letter-spacing:var(--ls-s1);line-height:var(--lh-s1)}.text-b1{font-size:var(--fs-b1);letter-spacing:var(--ls-b1);line-height:var(--lh-b1)}.text-b1,.text-b2{font-weight:400;color:var(--tc-surface-normal)}.text-b2{font-size:var(--fs-b2);letter-spacing:var(--ls-b2);line-height:var(--lh-b2)}.text-b3{font-size:var(--fs-b3);font-weight:400;letter-spacing:var(--ls-b3);line-height:var(--lh-b3);color:var(--tc-surface-low)}.btn-caution,.btn-danger,.btn-primary,.btn-surface{display:inline-flex;align-items:center;justify-content:center;min-width:80px;padding:var(--sp-extra-tight) var(--sp-normal);background-color:transparent;border:none;border-radius:var(--bo-radius);cursor:pointer}.btn-caution:disabled,.btn-danger:disabled,.btn-primary:disabled,.btn-surface:disabled{opacity:.4;cursor:no-drop}.btn-caution--icon,.btn-danger--icon,.btn-primary--icon,.btn-surface--icon{padding-left:var(--sp-tight);padding-right:var(--sp-loose)}[dir=rtl] .btn-caution--icon,[dir=rtl] .btn-danger--icon,[dir=rtl] .btn-primary--icon,[dir=rtl] .btn-surface--icon{padding-left:var(--sp-loose);padding-right:var(--sp-tight)}.btn-caution--icon .ic-raw,.btn-danger--icon .ic-raw,.btn-primary--icon .ic-raw,.btn-surface--icon .ic-raw{margin-right:var(--sp-extra-tight)}[dir=rtl] .btn-caution--icon .ic-raw,[dir=rtl] .btn-danger--icon .ic-raw,[dir=rtl] .btn-primary--icon .ic-raw,[dir=rtl] .btn-surface--icon .ic-raw{margin-right:0;margin-left:var(--sp-extra-tight)}.btn-surface{box-shadow:var(--bs-surface-border)}.btn-surface .text{color:var(--tc-surface-high)}.btn-surface .ic-raw{background-color:var(--ic-surface-normal)}@media(hover:hover){.btn-surface:hover{background-color:var(--bg-surface-hover)}}.btn-surface:focus{outline:none;box-shadow:var(--bs-surface-outline)}.btn-surface:active{background-color:var(--bg-surface-active)!important}.btn-primary{background-color:var(--bg-primary)}.btn-primary .text{color:var(--tc-primary-high)}.btn-primary .ic-raw{background-color:var(--ic-primary-normal)}@media(hover:hover){.btn-primary:hover{background-color:var(--bg-primary-hover)}}.btn-primary:focus{outline:none;box-shadow:var(--bs-primary-outline)}.btn-primary:active{background-color:var(--bg-primary-active)!important}.btn-caution{box-shadow:var(--bs-caution-border)}.btn-caution .text{color:var(--tc-caution-high)}.btn-caution .ic-raw{background-color:var(--ic-caution-normal)}@media(hover:hover){.btn-caution:hover{background-color:var(--bg-caution-hover)}}.btn-caution:focus{outline:none;box-shadow:var(--bs-caution-outline)}.btn-caution:active{background-color:var(--bg-caution-active)!important}.btn-danger{box-shadow:var(--bs-danger-border)}.btn-danger .text{color:var(--tc-danger-high)}.btn-danger .ic-raw{background-color:var(--ic-danger-normal)}@media(hover:hover){.btn-danger:hover{background-color:var(--bg-danger-hover)}}.btn-danger:focus{outline:none;box-shadow:var(--bs-danger-outline)}.btn-danger:active{background-color:var(--bg-danger-active)!important}.ic-raw{display:inline-block;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:cover;mask-size:cover;background-color:var(--ic-surface-normal)}.ic-raw-large{width:var(--ic-large);height:var(--ic-large)}.ic-raw-normal{width:var(--ic-normal);height:var(--ic-normal)}.ic-raw-small{width:var(--ic-small);height:var(--ic-small)}.ic-raw-extra-small{width:var(--ic-extra-small);height:var(--ic-extra-small)}.input{display:block;width:100%;min-width:0;padding:var(--sp-tight) var(--sp-normal);background-color:var(--bg-surface-low);color:var(--tc-surface-normal);box-shadow:none;border-radius:var(--bo-radius);border:1px solid var(--bg-surface-border);font-size:var(--fs-b2);letter-spacing:var(--ls-b2);line-height:var(--lh-b2)}.input__label{display:inline-block;margin-bottom:var(--sp-ultra-tight);color:var(--tc-surface-low)}.input--resizable{resize:vertical!important}.input--success{border:1px solid var(--bg-positive);box-shadow:none!important}.input--error{border:1px solid var(--bg-danger);box-shadow:none!important}.input:focus{outline:none;box-shadow:var(--bs-primary-border)}.input::placeholder{color:var(--tc-surface-low)}.donut-spinner{display:inline-block;border:4px solid var(--bg-surface-border);border-left-color:var(--tc-surface-normal);border-radius:50%;animation:donut-spin 1.2s cubic-bezier(.73,.32,.67,.86) infinite}.donut-spinner--normal{width:40px;height:40px}.donut-spinner--small{width:28px;height:28px}@keyframes donut-spin{to{transform:rotate(1turn)}}.client-container{display:flex;height:100%}.navigation__wrapper{width:var(--navigation-width)}.channel__wrapper{flex:1;min-width:0;background-color:var(--bg-surface)}.loading-display{position:absolute;top:0;left:0;width:100vw;height:100vh;display:flex;flex-direction:column;justify-content:center;align-items:center}.loading__message{margin-top:var(--sp-normal)}.loading__appname{position:absolute;bottom:var(--sp-normal)}.navigation{width:100%;height:100%;background-color:var(--bg-surface-low);display:flex}.featured-container,.sidebar,.sidebar__flexBox,.space-container,.sticky-container{display:flex;flex-direction:column;justify-content:flex-start;align-items:center}.sidebar{width:var(--navigation-sidebar-width);height:100%;border-right:1px solid var(--bg-surface-border)}[dir=rtl] .sidebar{border-right:none;border-left:1px solid var(--bg-surface-border)}.sidebar__scrollable,.sidebar__sticky{width:100%}.sidebar__scrollable{flex:1;min-height:0}.sidebar__sticky{align-items:center}.scrollable-content:after{content:"";display:block;width:100%;height:8px;background:transparent;position:sticky;bottom:0;left:0}.featured-container,.space-container,.sticky-container{padding:var(--sp-ultra-tight) 0}.featured-container>.avatar-container,.featured-container>.sidebar-avatar,.space-container>.avatar-container,.space-container>.sidebar-avatar,.sticky-container>.avatar-container,.sticky-container>.sidebar-avatar{margin:calc(var(--sp-tight)/2) 0}.sidebar-divider{margin:auto;width:24px;height:1px;background-color:var(--bg-surface-border)}.firefox-scrollbar,.scrollbar,.scrollbar--auto-hide:hover{scrollbar-width:thin;scrollbar-color:var(--bg-surface-hover) transparent}.firefox-scrollbar--transparent,.scrollbar--auto-hide{scrollbar-color:transparent transparent}.scrollbar::-webkit-scrollbar,.webkit-scrollbar::-webkit-scrollbar{width:8px;height:8px}.scrollbar::-webkit-scrollbar-track,.webkit-scrollbar-track::-webkit-scrollbar-track{background-color:transparent}.scrollbar--auto-hide:hover::-webkit-scrollbar-thumb,.scrollbar::-webkit-scrollbar-thumb,.webkit-scrollbar-thumb::-webkit-scrollbar-thumb{background-color:var(--bg-surface-hover)}.scrollbar--auto-hide::-webkit-scrollbar-thumb:hover,.scrollbar::-webkit-scrollbar-thumb:hover,.webkit-scrollbar-thumb::-webkit-scrollbar-thumb:hover{background-color:var(--bg-surface-active)}.scrollbar--auto-hide::-webkit-scrollbar-thumb,.webkit-scrollbar-thumb--transparent::-webkit-scrollbar-thumb{background-color:transparent}.scrollbar{width:100%;height:100%;overflow:hidden}.scrollbar__h{overflow-x:scroll}.scrollbar__v{overflow-y:scroll}.scrollbar--invisible{-ms-overflow-style:none;scrollbar-width:none}.scrollbar--invisible::-webkit-scrollbar{display:none}.sidebar-avatar-tippy{padding:var(--sp-extra-tight) var(--sp-normal);background-color:var(--bg-tooltip);border-radius:var(--bo-radius);box-shadow:var(--bs-popup)}.sidebar-avatar-tippy .text{color:var(--tc-tooltip)}.sidebar-avatar{position:relative;display:flex;justify-content:center;align-items:center;width:100%;cursor:pointer}.sidebar-avatar .notification-badge{position:absolute;right:var(--sp-extra-tight);top:calc(var(--sp-ultra-tight)*-1);box-shadow:0 0 0 2px var(--bg-surface-low)}.sidebar-avatar:focus{outline:none}.sidebar-avatar:active .avatar-container{box-shadow:var(--bs-surface-outline)}.sidebar-avatar--active:before,.sidebar-avatar:focus:before,.sidebar-avatar:hover:before{content:"";display:block;position:absolute;left:0;top:50%;transform:translateY(-50%);width:3px;height:12px;background-color:var(--ic-surface-normal);border-radius:0 4px 4px 0;transition:height .2s linear}[dir=rtl] .sidebar-avatar--active:before,[dir=rtl] .sidebar-avatar:focus:before,[dir=rtl] .sidebar-avatar:hover:before{right:0;border-radius:4px 0 0 4px}.sidebar-avatar--active:before,.sidebar-avatar--active:focus:before,.sidebar-avatar--active:hover:before{height:28px}.sidebar-avatar--active .avatar-container{background-color:var(--bg-surface)}.avatar-container{display:inline-flex;width:42px;height:42px;border-radius:var(--bo-radius);position:relative}.avatar-container__large{width:var(--av-large);height:var(--av-large)}.avatar-container__normal{width:var(--av-normal);height:var(--av-normal)}.avatar-container__small{width:var(--av-small);height:var(--av-small)}.avatar-container__extra-small{width:var(--av-extra-small);height:var(--av-extra-small)}.avatar-container img{width:100%;height:100%;object-fit:cover;border-radius:inherit}.avatar-container .avatar__bordered{box-shadow:var(--bs-surface-border)}.avatar-container .avatar__border{position:absolute;top:0;left:0;width:100%;height:100%;border-radius:inherit}.avatar-container .avatar__border .text{color:var(--tc-primary-high)}.notification-badge{min-width:18px;padding:1px var(--sp-ultra-tight);background-color:var(--tc-surface-low);border-radius:9px}.notification-badge .text{color:var(--bg-surface-low);text-align:center}.notification-badge--alert{background-color:var(--bg-positive)}.notification-badge--alert .text{color:#fff}.context-menu{background-color:var(--bg-surface);box-shadow:var(--bs-popup);border-radius:var(--bo-radius);overflow:hidden}.context-menu:focus{outline:none}.context-menu .tippy-content>div>.scrollbar{max-height:90vh}.context-menu__click-wrapper{display:inline-flex}.context-menu__click-wrapper:focus{outline:none}.context-menu__header{height:34px;padding:0 var(--sp-tight);margin-bottom:var(--sp-ultra-tight);display:flex;align-items:center;border-bottom:1px solid var(--bg-surface-border)}.context-menu__header .text{color:var(--tc-surface-low)}.context-menu__header:not(:first-child){margin-top:var(--sp-normal);border-top:1px solid var(--bg-surface-border)}.context-menu__item button[class^=btn]{width:100%;justify-content:start;border-radius:0;box-shadow:none}.context-menu__item button[class^=btn] .text:first-child{margin-left:calc(var(--ic-small) + var(--sp-ultra-tight));margin-right:var(--sp-extra-tight)}[dir=rtl] .context-menu__item button[class^=btn] .text:first-child{margin-left:var(--sp-extra-tight);margin-right:calc(var(--ic-small) + var(--sp-ultra-tight))}.context-menu__item .btn-surface:focus{background-color:var(--bg-surface-hover)}.context-menu__item .btn-caution:focus{background-color:var(--bg-caution-hover)}.context-menu__item .btn-danger:focus{background-color:var(--bg-danger-hover)}.tippy-box[data-animation=scale-extreme][data-placement^=top]{transform-origin:bottom}.tippy-box[data-animation=scale-extreme][data-placement^=bottom]{transform-origin:top}.tippy-box[data-animation=scale-extreme][data-placement^=left]{transform-origin:right}.tippy-box[data-animation=scale-extreme][data-placement^=right]{transform-origin:left}.tippy-box[data-animation=scale-extreme][data-state=hidden]{transform:scale(0);opacity:.25}.drawer,.drawer-flexBox,.drawer__content-wrapper{display:flex;flex-direction:column}.channels__wrapper,.drawer,.drawer-flexItem,.drawer__content-wrapper{flex:1;min-height:0}.drawer{min-width:0;border-right:1px solid var(--bg-surface-border)}[dir=rtl] .drawer{border-right:none;border-left:1px solid var(--bg-surface-border)}.breadcrumb__wrapper{display:none;height:var(--header-height)}.channels-container{padding-bottom:var(--sp-extra-loose)}.channels-container>.channel-selector__button-wrapper:first-child{margin-top:var(--sp-extra-tight)}.channels-container .cat-header{margin:var(--sp-normal);margin-bottom:var(--sp-extra-tight);text-transform:uppercase;font-weight:600}.header{padding-left:var(--sp-normal);padding-right:var(--sp-extra-tight);width:100%;height:var(--header-height);border-bottom:1px solid var(--bg-surface-border);display:flex;align-items:center}[dir=rtl] .header{padding-left:var(--sp-extra-tight);padding-right:var(--sp-normal)}.header__title-wrapper{flex:1;min-width:0;display:flex;align-items:center;margin:0 var(--sp-tight)}.header__title-wrapper:first-child{margin-left:0}[dir=rtl] .header__title-wrapper:first-child{margin-right:0}.header__title-wrapper>.text:first-child{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.header__title-wrapper>.text-b3{flex:1;min-width:0;margin-top:var(--sp-ultra-tight);margin-left:var(--sp-tight);padding-left:var(--sp-tight);border-left:1px solid var(--bg-surface-border);max-height:calc(var(--lh-b3)*2);overflow:hidden;-webkit-box-orient:vertical;-webkit-line-clamp:2;display:-webkit-box}[dir=rtl] .header__title-wrapper>.text-b3{margin-left:0;padding-left:0;border-left:none;margin-right:var(--sp-tight);padding-right:var(--sp-tight);border-right:1px solid var(--bg-surface-border)}.ic-btn-caution,.ic-btn-danger,.ic-btn-primary,.ic-btn-surface{padding:var(--sp-extra-tight);border:none;border-radius:var(--bo-radius);background-color:transparent;font-size:0;line-height:0;cursor:pointer}.ic-btn-caution:disabled,.ic-btn-danger:disabled,.ic-btn-primary:disabled,.ic-btn-surface:disabled{opacity:.4;cursor:no-drop}.ic-btn-surface .ic-raw{background-color:var(--ic-surface-normal)}@media(hover:hover){.ic-btn-surface:hover{background-color:var(--bg-surface-hover)}}.ic-btn-surface:focus{outline:none;background-color:var(--bg-surface-hover)}.ic-btn-surface:active{background-color:var(--bg-surface-active)!important}.ic-btn-tippy{padding:var(--sp-extra-tight) var(--sp-normal);background-color:var(--bg-tooltip);border-radius:var(--bo-radius);box-shadow:var(--bs-popup)}.ic-btn-tippy .text{color:var(--tc-tooltip)}.channel-selector__button-wrapper{display:block;width:calc(100% - var(--sp-extra-tight));margin-left:auto;padding:var(--sp-extra-tight) var(--sp-extra-tight);border:1px solid transparent;border-radius:var(--bo-radius);cursor:pointer}[dir=rtl] .channel-selector__button-wrapper{margin-left:0;margin-right:auto}@media(hover:hover){.channel-selector__button-wrapper:hover{background-color:var(--bg-surface-hover)}}.channel-selector__button-wrapper:focus{outline:none;background-color:var(--bg-surface-hover)}.channel-selector__button-wrapper:active{background-color:var(--bg-surface-active)}.channel-selector{display:flex;align-items:center}.channel-selector__icon{width:24px;height:24px}.channel-selector__icon .avatar__border{box-shadow:none}.channel-selector__text-container{flex:1;min-width:0;margin:0 var(--sp-extra-tight)}.channel-selector__text-container .text{color:var(--tc-surface-normal);overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.channel-selector--unread{margin:0 var(--sp-ultra-tight);height:8px;width:8px;background-color:var(--tc-surface-low);border-radius:50%;opacity:.4}.channel-selector--selected{background-color:var(--bg-surface);border-color:var(--bg-surface-border)}.channel-container{display:flex;height:100%}.app-welcome{width:100%;height:100%}.app-welcome>div{max-width:600px;align-items:center}.app-welcome__logo{width:64px;height:64px}.app-welcome__heading{margin:var(--sp-extra-loose) 0 var(--sp-tight);color:var(--tc-surface-high)}.app-welcome__subheading{color:var(--tc-surface-normal)}.channel-view,.channel-view-flexBox,.channel-view__content-wrapper{display:flex;flex-direction:column}.channel-view,.channel-view-flexItem,.channel-view__content-wrapper,.channel-view__scrollable{flex:1;min-height:0;min-width:0}.channel-view__scrollable{position:relative}.channel-view__content{min-height:100%;display:flex;flex-direction:column;justify-content:flex-end}.channel-view__content .timeline__wrapper{--typing-noti-height:28px;min-height:0;min-width:0;padding-bottom:var(--typing-noti-height)}.channel-view__typing{display:flex;padding:var(--sp-ultra-tight) var(--sp-normal);background:var(--bg-surface);transition:transform .2s ease-in-out}.channel-view__typing b{color:var(--tc-surface-high)}.channel-view__typing--open{transform:translateY(-99%)}.channel-view__typing .text{flex:1;min-width:0;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;margin:0 var(--sp-tight)}.channel-view .bouncingLoader{transform:translateY(2px);margin:0 calc(var(--sp-ultra-tight)/2)}.channel-view .bouncingLoader:after,.channel-view .bouncingLoader:before,.channel-view .bouncingLoader>div{display:inline-block;width:8px;height:8px;background:var(--tc-surface-high);border-radius:50%;animation:bouncing-loader .6s infinite alternate}.channel-view .bouncingLoader:after,.channel-view .bouncingLoader:before{content:""}.channel-view .bouncingLoader>div{margin:0 4px;animation-delay:.2s}.channel-view .bouncingLoader:after{animation-delay:.4s}@keyframes bouncing-loader{to{opacity:.1;transform:translate3d(0,-4px,0)}}.channel-view__STB{position:absolute;right:var(--sp-normal);bottom:0;border-radius:var(--bo-radius);box-shadow:var(--bs-surface-border);background-color:var(--bg-surface-low);transition:transform .2s ease-in-out;transform:translateY(100%) scale(0)}[dir=rtl] .channel-view__STB{right:unset;left:var(--sp-normal)}.channel-view__STB--open{transform:translateY(-28px) scale(1)}.channel-view__sticky{min-height:85px;position:relative;background:var(--bg-surface);border-top:1px solid var(--bg-surface-border)}.channel-input{padding:var(--sp-extra-tight) calc(var(--sp-normal) - 2px);display:flex;min-height:48px}.channel-input__space{min-width:0;align-self:center;margin:auto;padding:0 var(--sp-tight)}.channel-input__input-container{flex:1;min-width:0;display:flex;align-items:center;margin:0 calc(var(--sp-tight) - 2px);background-color:var(--bg-surface-low);box-shadow:var(--bs-surface-border);border-radius:var(--bo-radius)}.channel-input__input-container>.ic-raw{transform:scale(.8);margin-left:var(--sp-extra-tight)}[dir=rtl] .channel-input__input-container>.ic-raw{margin-left:0;margin-right:var(--sp-extra-tight)}.channel-input__input-container .scrollbar{max-height:50vh}.channel-input__textarea-wrapper{min-height:40px;display:flex;align-items:center}.channel-input__textarea-wrapper textarea{resize:none;width:100%;min-width:0;min-height:100%;padding:var(--sp-ultra-tight) calc(var(--sp-tight) - 2px)}.channel-input__textarea-wrapper textarea::placeholder{color:var(--tc-surface-low)}.channel-input__textarea-wrapper textarea:focus{outline:none}.channel-cmd-bar{--cmd-bar-height:28px;min-height:var(--cmd-bar-height)}.channel-cmd-bar .timeline-change{justify-content:flex-end;padding:var(--sp-ultra-tight) var(--sp-normal)}.channel-cmd-bar .timeline-change__content{margin:0;flex:unset}.channel-cmd-bar .timeline-change__content>.text{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.channel-cmd-bar .timeline-change__content>.text b{color:var(--tc-surface-normal)}.channel-attachment{--side-spacing:calc(var(--sp-normal) + var(--av-small) + var(--sp-tight));display:flex;align-items:center;margin-left:var(--side-spacing);margin-top:var(--sp-extra-tight);line-height:0}[dir=rtl] .channel-attachment{margin-left:0;margin-right:var(--side-spacing)}.channel-attachment__preview>img{max-height:40px;border-radius:var(--bo-radius)}.channel-attachment__icon{padding:var(--sp-extra-tight);background-color:var(--bg-surface-low);box-shadow:var(--bs-surface-border);border-radius:var(--bo-radius)}.channel-attachment__info{flex:1;min-width:0;margin:0 var(--sp-tight)}.channel-attachment__option button{transition:transform .2s ease-in-out;transform:translateY(-48px)}.channel-attachment__option button .ic-raw{transition:transform .2s ease-in-out;transform:rotate(45deg);background-color:var(--bg-caution)}.divider{--local-divider-color:var(--bg-surface-border);margin:var(--sp-extra-tight) var(--sp-normal);margin-right:var(--sp-extra-tight);display:flex;align-items:center;position:relative}.divider:before{content:"";display:inline-block;flex:1;margin-left:calc(var(--av-small) + var(--sp-tight));border-bottom:1px solid var(--local-divider-color);opacity:.18}[dir=rtl] .divider:before{margin-left:0;margin-right:calc(var(--av-small) + var(--sp-tight))}.divider__text{margin-left:var(--sp-normal)}[dir=rtl] .divider{margin-left:var(--sp-extra-tight);margin-right:var(--sp-normal)}[dir=rtl] .divider__text{margin-left:0;margin-right:var(--sp-normal)}.divider--surface{--local-divider-color:var(--tc-surface-low)}.divider--surface .divider__text{color:var(--tc-surface-low)}.divider--primary{--local-divider-color:var(--bg-primary)}.divider--primary .divider__text{color:var(--bg-primary)}.divider--danger{--local-divider-color:var(--bg-danger)}.divider--danger .divider__text{color:var(--bg-danger)}.divider--caution{--local-divider-color:var(--bg-caution)}.divider--caution .divider__text{color:var(--bg-caution)}.firefox-scrollbar,.message code,.message code:hover{scrollbar-width:thin;scrollbar-color:var(--bg-surface-hover) transparent}.firefox-scrollbar--transparent,.message code{scrollbar-color:transparent transparent}.message code::-webkit-scrollbar,.webkit-scrollbar::-webkit-scrollbar{width:8px;height:8px}.message code::-webkit-scrollbar-track,.webkit-scrollbar-track::-webkit-scrollbar-track{background-color:transparent}.message code::-webkit-scrollbar-thumb,.message code:hover::-webkit-scrollbar-thumb,.webkit-scrollbar-thumb::-webkit-scrollbar-thumb{background-color:var(--bg-surface-hover)}.message code::-webkit-scrollbar-thumb:hover,.webkit-scrollbar-thumb::-webkit-scrollbar-thumb:hover{background-color:var(--bg-surface-active)}.message code::-webkit-scrollbar-thumb,.webkit-scrollbar-thumb--transparent::-webkit-scrollbar-thumb{background-color:transparent}.message,.ph-msg{padding:var(--sp-ultra-tight) var(--sp-normal);padding-right:var(--sp-extra-tight);display:flex}.message:hover,.ph-msg:hover{background-color:var(--bg-surface-hover)}[dir=rtl] .message,[dir=rtl] .ph-msg{padding-left:var(--sp-extra-tight);padding-right:var(--sp-normal)}.message__avatar-container,.ph-msg__avatar-container{padding-top:6px}.message__avatar-container,.message__profile,.ph-msg__avatar-container,.ph-msg__profile{margin-right:var(--sp-tight)}[dir=rtl] .message__avatar-container,[dir=rtl] .message__profile,[dir=rtl] .ph-msg__avatar-container,[dir=rtl] .ph-msg__profile{margin-left:var(--sp-tight);margin-right:0}.message__main-container,.ph-msg__main-container{flex:1;min-width:0}.message+.timeline-change,.message--content-only+.message--full,.message--full+.message--full,.timeline-change+.message{margin-top:var(--sp-normal)}.message__avatar-container{width:var(--av-small)}.message__reply-content .text{color:var(--tc-surface-low);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.message__reply-content .ic-raw{width:16px;height:14px}.message__edited{color:var(--tc-surface-low)}.message__reactions{margin-top:var(--sp-ultra-tight)}.ph-msg__avatar{width:var(--av-small);height:var(--av-small);background-color:var(--bg-surface-hover);border-radius:var(--bo-radius)}.ph-msg__content>div,.ph-msg__header{margin:var(--sp-ultra-tight) 0;margin-right:var(--sp-extra-tight);height:var(--fs-b1);width:100%;max-width:100px;background-color:var(--bg-surface-hover);border-radius:calc(var(--bo-radius)/2)}[dir=rtl] .ph-msg__content>div,[dir=rtl] .ph-msg__header{margin-right:0;margin-left:var(--sp-extra-tight)}.ph-msg__content{display:flex;flex-wrap:wrap}.ph-msg__content>div:nth-child(1n){max-width:10%}.ph-msg__content>div:nth-child(2n){max-width:50%}.message__header{display:flex;align-items:baseline}.message__header .message__profile{flex:1;min-width:0;color:var(--tc-surface-high)}.message__header .message__profile>.text{color:inherit;font-weight:500;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.message__header .message__time>.text{color:var(--tc-surface-low)}.message__content{max-width:640px;word-break:break-word}.message__content>.text>*{white-space:pre-wrap}.message__content a{word-break:break-all}.msg__reaction{--reaction-height:24px;--reaction-padding:6px;--reaction-radius:calc(var(--bo-radius)/2);display:inline-flex;align-items:center;color:var(--tc-surface-normal);border:1px solid var(--bg-surface-border);padding:0 var(--reaction-padding);border-radius:var(--reaction-radius);cursor:pointer;height:var(--reaction-height);margin-right:var(--sp-extra-tight)}[dir=rtl] .msg__reaction{margin-right:0;margin-left:var(--sp-extra-tight)}@media(hover:hover){.msg__reaction:hover{background-color:var(--bg-surface-hover)}}.msg__reaction:active{background-color:var(--bg-surface-active)}.msg__reaction--active{background-color:var(--bg-caution-active)}@media(hover:hover){.msg__reaction--active:hover{background-color:var(--bg-caution-hover)}}.msg__reaction--active:active{background-color:var(--bg-caution-active)}.message h1,.message h2{color:var(--tc-surface-high);margin:var(--sp-extra-loose) 0 var(--sp-normal);line-height:var(--lh-h1)}.message h3,.message h4{color:var(--tc-surface-high);margin:var(--sp-loose) 0 var(--sp-tight);line-height:var(--lh-h2)}.message h5,.message h6{color:var(--tc-surface-high);margin:var(--sp-normal) 0 var(--sp-extra-tight);line-height:var(--lh-s1)}.message hr{border-color:var(--bg-surface-border)}.message .text img{margin:var(--sp-ultra-tight) 0;max-width:296px;border-radius:calc(var(--bo-radius)/2)}.message blockquote,.message p,.message pre{margin:0;padding:0}.message blockquote,.message pre{margin:var(--sp-ultra-tight) 0;padding:var(--sp-extra-tight);background-color:var(--bg-surface-hover)!important;border-radius:calc(var(--bo-radius)/2)}.message pre div{margin:0!important}.message pre div,.message pre span{background:none!important}.message pre .linenumber{min-width:2.25em!important}.message code{padding:0!important;color:var(--tc-code)!important;white-space:pre-wrap;overflow:hidden;overflow-x:scroll}.message pre code{color:var(--tc-surface-normal)!important}.message blockquote{padding-left:var(--sp-extra-tight);border-left:4px solid var(--bg-surface-active);white-space:normal!important}.message blockquote>*{white-space:pre-wrap}[dir=rtl] .message blockquote{padding-left:0;padding-right:var(--sp-extra-tight);border-left:none;border-right:4px solid var(--bg-surface-active)}.message ol,.message ul{margin:var(--sp-ultra-tight) 0;padding-left:24px;white-space:normal!important}.message ol>*,.message ul>*{white-space:pre-wrap}[dir=rtl] .message ol,[dir=rtl] .message ul{padding-left:0;padding-right:24px}.file-header{display:flex;align-items:center;padding:var(--sp-ultra-tight) var(--sp-tight);min-height:42px}.file-header .file-name{flex:1;color:var(--tc-surface-low);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.file-container{--media-max-width:296px;background-color:var(--bg-surface-hover);border-radius:calc(var(--bo-radius)/2);overflow:hidden;max-width:var(--media-max-width);white-space:normal}.audio-container,.image-container,.video-container{font-size:0;line-height:0;display:flex;justify-content:center;align-items:center;background-position:50%;background-repeat:no-repeat;background-size:cover}.image-container img{max-width:unset!important;width:100%!important;border-radius:0!important;margin:0!important}.video-container .ic-btn-surface{background-color:var(--bg-surface-low)}.audio-container audio,.video-container video{width:100%}.timeline-change{padding:var(--sp-ultra-tight) var(--sp-normal);padding-right:var(--sp-extra-tight);display:flex;align-items:center}.timeline-change:hover{background-color:var(--bg-surface-hover)}[dir=rtl] .timeline-change{padding-left:var(--sp-extra-tight);padding-right:var(--sp-normal)}.timeline-change__avatar-container{width:var(--av-small);display:inline-flex;justify-content:center;align-items:center;opacity:.38}.timeline-change__avatar-container .ic-raw{background-color:var(--tc-surface-low)}.timeline-change .text{color:var(--tc-surface-low)}.timeline-change__content{flex:1;min-width:0;margin:0 var(--sp-tight)}.channel-intro{margin-top:calc(var(--sp-extra-loose)*2);margin-bottom:var(--sp-extra-loose);padding-left:calc(var(--sp-normal) + var(--av-small) + var(--sp-tight));padding-right:var(--sp-extra-tight)}[dir=rtl] .channel-intro{padding-left:var(--sp-extra-tight);padding-right:calc(var(--sp-normal) + var(--av-small) + var(--sp-tight))}.channel-intro .channel-intro__content{margin-top:var(--sp-extra-loose);max-width:640px}.channel-intro__name{color:var(--tc-surface-high)}.channel-intro__desc{color:var(--tc-surface-normal);margin:var(--sp-tight) 0 var(--sp-extra-tight)}.channel-intro__desc a{word-break:break-all}.channel-intro__time{color:var(--tc-surface-low)}.emoji-board-flexBoxV,.emoji-board__content,.emoji-board__nav{display:flex;flex-direction:column}.emoji-board-flexItem,.emoji-board__content,.emoji-board__emojis,.emoji-board__search .input-container{flex:1;min-height:0;min-width:0}.emoji-board{display:flex}.emoji-board__content{height:360px}.emoji-board__nav{padding:4px 6px;background-color:var(--bg-surface-low);border-left:1px solid var(--bg-surface-border)}[dir=rtl] .emoji-board__nav{border-left:none;border-right:1px solid var(--bg-surface-border)}.emoji-board__nav>.ic-btn-surface{margin:calc(var(--sp-ultra-tight)/2) 0}.emoji-board__search{display:flex;align-items:center;padding:calc(var(--sp-ultra-tight)/2) var(--sp-normal)}.emoji-board__search .input-container .input{min-width:100%;width:0;background-color:transparent;border:none!important;box-shadow:none!important}.emoji-group{--emoji-padding:6px;position:relative;margin-bottom:var(--sp-normal)}.emoji-group__header{position:sticky;top:0;z-index:99;background-color:var(--bg-surface);padding:var(--sp-tight) var(--sp-normal);text-transform:uppercase;font-weight:600}.emoji-group .emoji-set{margin:0 calc(var(--sp-normal) - var(--emoji-padding));margin-right:calc(var(--sp-extra-tight) - var(--emoji-padding))}[dir=rtl] .emoji-group .emoji-set{margin-right:calc(var(--sp-normal) - var(--emoji-padding));margin-left:calc(var(--sp-extra-tight) - var(--emoji-padding))}.emoji-group .emoji{width:38px;padding:var(--emoji-padding);cursor:pointer}.emoji-group .emoji:hover{background-color:var(--bg-surface-hover);border-radius:var(--bo-radius)}.people-drawer,.people-drawer-flexBox,.people-drawer__content-wrapper{display:flex;flex-direction:column}.people-drawer-flexItem,.people-drawer__content-wrapper,.people-drawer__scrollable{flex:1;min-height:0;min-width:0}.people-drawer{width:var(--people-drawer-width);background-color:var(--bg-surface-low);border-left:1px solid var(--bg-surface-border)}[dir=rtl] .people-drawer{border-left:none;border-right:1px solid var(--bg-surface-hover)}.people-drawer__member-count{color:var(--tc-surface-low)}.people-drawer__sticky{display:none}.people-drawer__sticky .people-search{min-height:48px;margin:0 var(--sp-normal);position:relative;bottom:var(--sp-normal)}.people-drawer__sticky .people-search .input{height:48px}.people-drawer__content{padding-top:var(--sp-extra-tight);padding-bottom:calc(var(--sp-extra-tight) + var(--sp-normal))}.people-drawer__load-more{padding:var(--sp-normal);padding-bottom:0;padding-right:var(--sp-extra-tight)}[dir=rtl] .people-drawer__load-more{padding-right:var(--sp-normal);padding-left:var(--sp-extra-tight)}.people-drawer__load-more .btn-surface{width:100%}.people-selector{width:100%;padding:var(--sp-extra-tight);padding-left:var(--sp-normal);display:flex;align-items:center;cursor:pointer}[dir=rtl] .people-selector{padding-left:var(--sp-extra-tight);padding-right:var(--sp-normal)}@media(hover:hover){.people-selector:hover{background-color:var(--bg-surface-hover)}}.people-selector:focus{outline:none;background-color:var(--bg-surface-hover)}.people-selector:active{background-color:var(--bg-surface-active)}.people-selector__name{flex:1;min-width:0;margin:0 var(--sp-tight);color:var(--tc-surface-normal);overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.people-selector__role{color:var(--tc-surface-low)}.invites-content{margin:0 var(--sp-normal);margin-right:var(--sp-extra-tight)}.invites-content__subheading{margin-top:var(--sp-extra-loose)}.invites-content__subheading .text{text-transform:uppercase;font-weight:600}.invites-content__subheading:first-child{margin-top:var(--sp-tight)}.invites-content .channel-tile{margin-top:var(--sp-normal)}.invites-content .channel-tile__options{align-self:flex-end}.invites-content .invite-btn__container .btn-surface{margin-right:var(--sp-normal)}[dir=rtl] .invites-content .invite-btn__container .btn-surface{margin-right:0;margin-left:var(--sp-normal)}[dir=rtl] .invites-content{margin-left:var(--sp-extra-tight);margin-right:var(--sp-normal)}.pw-model{--modal-height:656px;max-height:var(--modal-height)!important;height:100%}.pw{--popup-window-drawer-width:312px;width:100%;height:100%;background-color:var(--bg-surface);display:flex}.pw__drawer{width:var(--popup-window-drawer-width);background-color:var(--bg-surface-low);border-right:1px solid var(--bg-surface-border)}[dir=rtl] .pw__drawer{border-right:none;border-left:1px solid var(--bg-surface-border)}.pw__content{flex:1;min-width:0}.pw__content,.pw__drawer{display:flex;flex-direction:column}.pw__content-container,.pw__drawer__content{padding-top:var(--sp-extra-tight);padding-bottom:var(--sp-extra-loose)}.pw__content__wrapper,.pw__drawer__content__wrapper{flex:1;min-height:0}.pw__drawer .header{padding-left:var(--sp-extra-tight)}.pw__drawer .header .ic-btn-surface:first-child{margin-right:var(--sp-ultra-tight)}[dir=rtl] .pw__drawer .header{padding-right:var(--sp-extra-tight)}[dir=rtl] .pw__drawer .header .ic-btn-surface:first-child{margin-right:0;margin-left:var(--sp-ultra-tight)}.pw-content-selector--selected{border:1px solid var(--bg-surface-border);border-width:1px 0;background-color:var(--bg-surface)}.pw-content-selector--selected .context-menu__item>button:hover{background-color:transparent}.pw-content-selector .context-menu__item>button{padding-left:var(--sp-normal)}.pw-content-selector .context-menu__item>button .text{color:var(--tc-surface-normal)}.pw-content-selector .context-menu__item>button .ic-raw{margin-right:var(--sp-tight)}[dir=rtl] .pw-content-selector .context-menu__item>button{padding-right:var(--sp-normal)}[dir=rtl] .pw-content-selector .context-menu__item>button .ic-raw{margin-right:0;margin-left:var(--sp-tight)}.ReactModal__Overlay{opacity:0;transition:opacity .2s cubic-bezier(.13,.56,.25,.99)}.ReactModal__Overlay--after-open{opacity:1}.ReactModal__Overlay--before-close{opacity:0}.ReactModal__Content{transform:translateY(100%);transition:transform .2s cubic-bezier(.13,.56,.25,.99)}.ReactModal__Content--after-open{transform:translateY(0)}.ReactModal__Content--before-close{transform:translateY(100%)}.raw-modal{--small-modal-width:525px;--medium-modal-width:712px;--large-modal-width:1024px;width:100%;max-height:100%;border-radius:var(--bo-radius);box-shadow:var(--bs-popup);outline:none;overflow:hidden}.raw-modal__small{max-width:var(--small-modal-width)}.raw-modal__medium{max-width:var(--medium-modal-width)}.raw-modal__large{max-width:var(--large-modal-width)}.raw-modal__overlay{position:fixed;top:0;left:0;z-index:999;display:flex;justify-content:center;align-items:center;padding:var(--sp-normal);width:100%;height:100%;background-color:var(--bg-overlay)}.channel-tile{display:flex}.channel-tile__content{flex:1;min-width:0;margin:0 var(--sp-normal)}.channel-tile__content__desc{white-space:pre-wrap}.channel-tile__content__desc a{white-space:wrap}.channel-tile__content .text:not(:first-child){margin-top:var(--sp-ultra-tight)}.public-channels{margin:0 var(--sp-normal);margin-right:var(--sp-extra-tight);margin-top:var(--sp-extra-tight)}.public-channels__form{display:flex;align-items:flex-end}.public-channels__form .btn-primary{padding-top:11px;padding-bottom:11px}.public-channels__input-wrapper{flex:1;min-width:0;display:flex;margin-right:var(--sp-normal)}[dir=rtl] .public-channels__input-wrapper{margin-right:0;margin-left:var(--sp-normal)}.public-channels__input-wrapper>div:first-child{flex:1;min-width:0}.public-channels__input-wrapper>div:first-child .input{border-radius:var(--bo-radius) 0 0 var(--bo-radius)}[dir=rtl] .public-channels__input-wrapper>div:first-child .input{border-radius:0 var(--bo-radius) var(--bo-radius) 0}.public-channels__input-wrapper>div:last-child .input{width:120px;border-left-width:0;border-radius:0 var(--bo-radius) var(--bo-radius) 0}[dir=rtl] .public-channels__input-wrapper>div:last-child .input{border-left-width:1px;border-right-width:0;border-radius:var(--bo-radius) 0 0 var(--bo-radius)}.public-channels__search-status{margin-top:var(--sp-extra-loose);margin-bottom:var(--sp-tight)}.public-channels__search-status .donut-spinner{margin:0 var(--sp-tight)}.public-channels__search-error{color:var(--bg-danger)}.public-channels__content{border-top:1px solid var(--bg-surface-border)}.public-channels__view-more{margin-top:var(--sp-loose);margin-left:calc(var(--av-normal) + var(--sp-normal))}[dir=rtl] .public-channels__view-more{margin-left:0;margin-right:calc(var(--av-normal) + var(--sp-normal))}.public-channels .channel-tile{margin-top:var(--sp-normal)}.public-channels .channel-tile__options{align-self:flex-end}[dir=rtl] .public-channels{margin-left:var(--sp-extra-tight);margin-right:var(--sp-normal)}.create-channel{margin:0 var(--sp-normal);margin-right:var(--sp-extra-tight)}.create-channel__form>*{margin-top:var(--sp-normal)}.create-channel__form>:first-child{margin-top:var(--sp-extra-tight)}.create-channel__address{display:flex}.create-channel__address__label{color:var(--tc-surface-low);margin-bottom:var(--sp-ultra-tight)}.create-channel__address__tip{margin-left:46px;margin-top:var(--sp-ultra-tight)}[dir=rtl] .create-channel__address__tip{margin-left:0;margin-right:46px}.create-channel__address .text{display:flex;align-items:center;padding:0 var(--sp-normal);border:1px solid var(--bg-surface-border);border-radius:var(--bo-radius);color:var(--tc-surface-low)}.create-channel__address :nth-child(2){flex:1;min-width:0}.create-channel__address :nth-child(2) .input{border-radius:0}.create-channel__address .text:first-child{border-right-width:0;border-radius:var(--bo-radius) 0 0 var(--bo-radius)}.create-channel__address .text:last-child{border-left-width:0;border-radius:0 var(--bo-radius) var(--bo-radius) 0}[dir=rtl] .create-channel__address .text:first-child{border-left-width:0;border-right-width:1px;border-radius:0 var(--bo-radius) var(--bo-radius) 0}[dir=rtl] .create-channel__address .text:last-child{border-right-width:0;border-left-width:1px;border-radius:var(--bo-radius) 0 0 var(--bo-radius)}.create-channel__name-wrapper{display:flex;align-items:flex-end}.create-channel__name-wrapper .input-container{flex:1;min-width:0;margin-right:var(--sp-normal)}[dir=rtl] .create-channel__name-wrapper .input-container{margin-right:0;margin-left:var(--sp-normal)}.create-channel__name-wrapper .btn-primary{padding-top:11px;padding-bottom:11px}.create-channel__loading{display:flex;justify-content:center;align-items:center}.create-channel__loading .text{margin-left:var(--sp-normal)}[dir=rtl] .create-channel__loading .text{margin-left:0;margin-right:var(--sp-normal)}.create-channel__error{text-align:center;color:var(--bg-danger)!important}[dir=rtl] .create-channel{margin-right:var(--sp-normal);margin-left:var(--sp-extra-tight)}.toggle{width:44px;height:24px;padding:0 var(--sp-ultra-tight);display:flex;align-items:center;border-radius:var(--bo-radius);box-shadow:var(--bs-surface-border);cursor:pointer;background-color:var(--bg-surface-low);transition:background .2s ease-in-out}.toggle:before{content:"";display:inline-block;width:16px;height:16px;background-color:var(--tc-surface-low);border-radius:calc(var(--bo-radius)/2);transition:transform .2s ease-in-out,opacity .2s ease-in-out;opacity:.6}.toggle--active{background-color:var(--bg-positive)}.toggle--active:before{background-color:#fff;transform:translateX(125%);opacity:1}[dir=rtl] .toggle--active:before{transform:translateX(-125%)}.setting-tile__title__wrapper{display:flex;align-items:center}.setting-tile__title{flex:1;min-width:0;margin-right:var(--sp-normal)}[dir=rtl] .setting-tile__title{margin-right:0;margin-left:var(--sp-normal)}.invite-user{margin:0 var(--sp-normal);margin-right:var(--sp-extra-tight);margin-top:var(--sp-extra-tight)}.invite-user__form{display:flex;align-items:flex-end}.invite-user__form .input-container{flex:1;min-width:0;margin-right:var(--sp-normal)}[dir=rtl] .invite-user__form .input-container{margin-right:0;margin-left:var(--sp-normal)}.invite-user__form .btn-primary{padding-top:11px;padding-bottom:11px}.invite-user__search-status{margin-top:var(--sp-extra-loose);margin-bottom:var(--sp-tight)}.invite-user__search-status .donut-spinner{margin:0 var(--sp-tight)}.invite-user__search-error{color:var(--bg-danger)}.invite-user__content{border-top:1px solid var(--bg-surface-border)}.invite-user .channel-tile{margin-top:var(--sp-normal)}.invite-user .channel-tile__options{align-self:flex-end}[dir=rtl] .invite-user{margin-left:var(--sp-extra-tight);margin-right:var(--sp-normal)}.settings-window .pw__content-container{height:100%}.settings-content{margin:0 var(--sp-normal);margin-right:var(--sp-extra-tight);display:flex;flex-direction:column;height:100%}[dir=rtl] .settings-content{margin-left:var(--sp-extra-tight);margin-right:var(--sp-normal)}.settings__about{text-align:center}.segmented-controls{background-color:var(--bg-surface-low);border-radius:var(--bo-radius);border:1px solid var(--bg-surface-border);display:inline-flex;overflow:hidden}.segment-btn{padding:var(--sp-extra-tight) 0;cursor:pointer}@media(hover:hover){.segment-btn:hover{background-color:var(--bg-surface-hover)}}.segment-btn:active{background-color:var(--bg-surface-active)!important}.segment-btn__base{padding:0 var(--sp-normal);display:flex;align-items:center;justify-content:center;border-left:1px solid var(--bg-surface-border)}[dir=rtl] .segment-btn__base{border-left:none;border-right:1px solid var(--bg-surface-border)}.segment-btn__base .text:nth-child(2){margin:0 var(--sp-extra-tight)}.segment-btn:first-child .segment-btn__base{border:none}.segment-btn--active{background-color:var(--bg-surface);border:1px solid var(--bg-surface-border);border-width:0 1px}.segment-btn--active+.segment-btn .segment-btn__base,.segment-btn--active .segment-btn__base{border:none}.segment-btn--active:first-child{border-left:none}.segment-btn--active:last-child{border-right:none}[dir=rtl] .segment-btn--active{border-left:1px solid var(--bg-surface-border);border-right:1px solid var(--bg-surface-border)}[dir=rtl] .segment-btn--active:first-child{border-right:none}[dir=rtl] .segment-btn--active:last-child{border-left:none} \ No newline at end of file diff --git a/dist/main.b16695b6316dfd5b68d4.bundle.js b/dist/main.b16695b6316dfd5b68d4.bundle.js deleted file mode 100644 index 09b1de102..000000000 --- a/dist/main.b16695b6316dfd5b68d4.bundle.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! For license information please see main.b16695b6316dfd5b68d4.bundle.js.LICENSE.txt */ -(()=>{var e={59713:e=>{e.exports=function(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e},e.exports.default=e.exports,e.exports.__esModule=!0},95318:e=>{e.exports=function(e){return e&&e.__esModule?e:{default:e}},e.exports.default=e.exports,e.exports.__esModule=!0},20862:(e,t,n)=>{var o=n(50008).default;function r(){if("function"!=typeof WeakMap)return null;var e=new WeakMap;return r=function(){return e},e}e.exports=function(e){if(e&&e.__esModule)return e;if(null===e||"object"!==o(e)&&"function"!=typeof e)return{default:e};var t=r();if(t&&t.has(e))return t.get(e);var n={},i=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in e)if(Object.prototype.hasOwnProperty.call(e,a)){var s=i?Object.getOwnPropertyDescriptor(e,a):null;s&&(s.get||s.set)?Object.defineProperty(n,a,s):n[a]=e[a]}return n.default=e,t&&t.set(e,n),n},e.exports.default=e.exports,e.exports.__esModule=!0},50008:e=>{function t(n){return"function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?(e.exports=t=function(e){return typeof e},e.exports.default=e.exports,e.exports.__esModule=!0):(e.exports=t=function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},e.exports.default=e.exports,e.exports.__esModule=!0),t(n)}e.exports=t,e.exports.default=e.exports,e.exports.__esModule=!0},18508:e=>{function t(e){this._db=e,this._operations=[],this._written=!1}t.prototype._checkWritten=function(){if(this._written)throw new Error("write() already called on this batch")},t.prototype.put=function(e,t){this._checkWritten();var n=this._db._checkKeyValue(e,"key",this._db._isBuffer);if(n)throw n;if(n=this._db._checkKeyValue(t,"value",this._db._isBuffer))throw n;return this._db._isBuffer(e)||(e=String(e)),this._db._isBuffer(t)||(t=String(t)),"function"==typeof this._put?this._put(e,t):this._operations.push({type:"put",key:e,value:t}),this},t.prototype.del=function(e){this._checkWritten();var t=this._db._checkKeyValue(e,"key",this._db._isBuffer);if(t)throw t;return this._db._isBuffer(e)||(e=String(e)),"function"==typeof this._del?this._del(e):this._operations.push({type:"del",key:e}),this},t.prototype.clear=function(){return this._checkWritten(),this._operations=[],"function"==typeof this._clear&&this._clear(),this},t.prototype.write=function(e,t){if(this._checkWritten(),"function"==typeof e&&(t=e),"function"!=typeof t)throw new Error("write() requires a callback argument");return"object"!=typeof e&&(e={}),this._written=!0,"function"==typeof this._write?this._write(t):"function"==typeof this._db._batch?this._db._batch(this._operations,e,t):void process.nextTick(t)},e.exports=t},43538:e=>{function t(e){this.db=e,this._ended=!1,this._nexting=!1}t.prototype.next=function(e){var t=this;if("function"!=typeof e)throw new Error("next() requires a callback argument");return t._ended?e(new Error("cannot call next() after end()")):t._nexting?e(new Error("cannot call next() before previous next() has completed")):(t._nexting=!0,"function"==typeof t._next?t._next((function(){t._nexting=!1,e.apply(null,arguments)})):void process.nextTick((function(){t._nexting=!1,e()})))},t.prototype.end=function(e){if("function"!=typeof e)throw new Error("end() requires a callback argument");return this._ended?e(new Error("end() already called on iterator")):(this._ended=!0,"function"==typeof this._end?this._end(e):void process.nextTick(e))},e.exports=t},32554:(e,t,n)=>{var o=n(77915),r=n(43538),i=n(18508);function a(e){if(!arguments.length||void 0===e)throw new Error("constructor requires at least a location argument");if("string"!=typeof e)throw new Error("constructor requires a location string argument");this.location=e}a.prototype.open=function(e,t){if("function"==typeof e&&(t=e),"function"!=typeof t)throw new Error("open() requires a callback argument");if("object"!=typeof e&&(e={}),"function"==typeof this._open)return this._open(e,t);process.nextTick(t)},a.prototype.close=function(e){if("function"!=typeof e)throw new Error("close() requires a callback argument");if("function"==typeof this._close)return this._close(e);process.nextTick(e)},a.prototype.get=function(e,t,n){var o;if("function"==typeof t&&(n=t),"function"!=typeof n)throw new Error("get() requires a callback argument");return(o=this._checkKeyValue(e,"key",this._isBuffer))?n(o):(this._isBuffer(e)||(e=String(e)),"object"!=typeof t&&(t={}),"function"==typeof this._get?this._get(e,t,n):void process.nextTick((function(){n(new Error("NotFound"))})))},a.prototype.put=function(e,t,n,o){var r;if("function"==typeof n&&(o=n),"function"!=typeof o)throw new Error("put() requires a callback argument");return(r=this._checkKeyValue(e,"key",this._isBuffer))||(r=this._checkKeyValue(t,"value",this._isBuffer))?o(r):(this._isBuffer(e)||(e=String(e)),this._isBuffer(t)||process.browser||(t=String(t)),"object"!=typeof n&&(n={}),"function"==typeof this._put?this._put(e,t,n,o):void process.nextTick(o))},a.prototype.del=function(e,t,n){var o;if("function"==typeof t&&(n=t),"function"!=typeof n)throw new Error("del() requires a callback argument");return(o=this._checkKeyValue(e,"key",this._isBuffer))?n(o):(this._isBuffer(e)||(e=String(e)),"object"!=typeof t&&(t={}),"function"==typeof this._del?this._del(e,t,n):void process.nextTick(n))},a.prototype.batch=function(e,t,n){if(!arguments.length)return this._chainedBatch();if("function"==typeof t&&(n=t),"function"!=typeof n)throw new Error("batch(array) requires a callback argument");if(!Array.isArray(e))return n(new Error("batch(array) requires an array argument"));"object"!=typeof t&&(t={});for(var o,r,i=0,a=e.length;i{e.exports=function(){for(var e={},t=0;t{"use strict";for(var t=/[\\\"\x00-\x1F]/g,n={},o=0;o<32;++o)n[String.fromCharCode(o)]="\\U"+("0000"+o.toString(16)).slice(-4).toUpperCase();function r(e){return t.lastIndex=0,e.replace(t,(function(e){return n[e]}))}n["\b"]="\\b",n["\t"]="\\t",n["\n"]="\\n",n["\f"]="\\f",n["\r"]="\\r",n['"']='\\"',n["\\"]="\\\\",e.exports={stringify:function e(t){switch(typeof t){case"string":return'"'+r(t)+'"';case"number":return isFinite(t)?t:"null";case"boolean":return t;case"object":return null===t?"null":Array.isArray(t)?function(t){for(var n="[",o="",r=0;r{e.exports=function(e,n,o){if(e.filter)return e.filter(n,o);if(null==e)throw new TypeError;if("function"!=typeof n)throw new TypeError;for(var r=[],i=0;i{"use strict";const o=t;o.bignum=n(4590),o.define=n(22500).define,o.base=n(71979),o.constants=n(36826),o.decoders=n(78307),o.encoders=n(56579)},22500:(e,t,n)=>{"use strict";const o=n(56579),r=n(78307),i=n(35717);function a(e,t){this.name=e,this.body=t,this.decoders={},this.encoders={}}t.define=function(e,t){return new a(e,t)},a.prototype._createNamed=function(e){const t=this.name;function n(e){this._initNamed(e,t)}return i(n,e),n.prototype._initNamed=function(t,n){e.call(this,t,n)},new n(this)},a.prototype._getDecoder=function(e){return e=e||"der",this.decoders.hasOwnProperty(e)||(this.decoders[e]=this._createNamed(r[e])),this.decoders[e]},a.prototype.decode=function(e,t,n){return this._getDecoder(t).decode(e,n)},a.prototype._getEncoder=function(e){return e=e||"der",this.encoders.hasOwnProperty(e)||(this.encoders[e]=this._createNamed(o[e])),this.encoders[e]},a.prototype.encode=function(e,t,n){return this._getEncoder(t).encode(e,n)}},36625:(e,t,n)=>{"use strict";const o=n(35717),r=n(98465).b,i=n(2399).Buffer;function a(e,t){r.call(this,t),i.isBuffer(e)?(this.base=e,this.offset=0,this.length=e.length):this.error("Input not Buffer")}function s(e,t){if(Array.isArray(e))this.length=0,this.value=e.map((function(e){return s.isEncoderBuffer(e)||(e=new s(e,t)),this.length+=e.length,e}),this);else if("number"==typeof e){if(!(0<=e&&e<=255))return t.error("non-byte EncoderBuffer value");this.value=e,this.length=1}else if("string"==typeof e)this.value=e,this.length=i.byteLength(e);else{if(!i.isBuffer(e))return t.error("Unsupported type: "+typeof e);this.value=e,this.length=e.length}}o(a,r),t.C=a,a.isDecoderBuffer=function(e){return e instanceof a||"object"==typeof e&&i.isBuffer(e.base)&&"DecoderBuffer"===e.constructor.name&&"number"==typeof e.offset&&"number"==typeof e.length&&"function"==typeof e.save&&"function"==typeof e.restore&&"function"==typeof e.isEmpty&&"function"==typeof e.readUInt8&&"function"==typeof e.skip&&"function"==typeof e.raw},a.prototype.save=function(){return{offset:this.offset,reporter:r.prototype.save.call(this)}},a.prototype.restore=function(e){const t=new a(this.base);return t.offset=e.offset,t.length=this.offset,this.offset=e.offset,r.prototype.restore.call(this,e.reporter),t},a.prototype.isEmpty=function(){return this.offset===this.length},a.prototype.readUInt8=function(e){return this.offset+1<=this.length?this.base.readUInt8(this.offset++,!0):this.error(e||"DecoderBuffer overrun")},a.prototype.skip=function(e,t){if(!(this.offset+e<=this.length))return this.error(t||"DecoderBuffer overrun");const n=new a(this.base);return n._reporterState=this._reporterState,n.offset=this.offset,n.length=this.offset+e,this.offset+=e,n},a.prototype.raw=function(e){return this.base.slice(e?e.offset:this.offset,this.length)},t.R=s,s.isEncoderBuffer=function(e){return e instanceof s||"object"==typeof e&&"EncoderBuffer"===e.constructor.name&&"number"==typeof e.length&&"function"==typeof e.join},s.prototype.join=function(e,t){return e||(e=i.alloc(this.length)),t||(t=0),0===this.length||(Array.isArray(this.value)?this.value.forEach((function(n){n.join(e,t),t+=n.length})):("number"==typeof this.value?e[t]=this.value:"string"==typeof this.value?e.write(this.value,t):i.isBuffer(this.value)&&this.value.copy(e,t),t+=this.length)),e}},71979:(e,t,n)=>{"use strict";const o=t;o.Reporter=n(98465).b,o.DecoderBuffer=n(36625).C,o.EncoderBuffer=n(36625).R,o.Node=n(41949)},41949:(e,t,n)=>{"use strict";const o=n(98465).b,r=n(36625).R,i=n(36625).C,a=n(79746),s=["seq","seqof","set","setof","objid","bool","gentime","utctime","null_","enum","int","objDesc","bitstr","bmpstr","charstr","genstr","graphstr","ia5str","iso646str","numstr","octstr","printstr","t61str","unistr","utf8str","videostr"],u=["key","obj","use","optional","explicit","implicit","def","choice","any","contains"].concat(s);function c(e,t,n){const o={};this._baseState=o,o.name=n,o.enc=e,o.parent=t||null,o.children=null,o.tag=null,o.args=null,o.reverseArgs=null,o.choice=null,o.optional=!1,o.any=!1,o.obj=!1,o.use=null,o.useDecoder=null,o.key=null,o.default=null,o.explicit=null,o.implicit=null,o.contains=null,o.parent||(o.children=[],this._wrap())}e.exports=c;const l=["enc","parent","children","tag","args","reverseArgs","choice","optional","any","obj","use","alteredUse","key","default","explicit","implicit","contains"];c.prototype.clone=function(){const e=this._baseState,t={};l.forEach((function(n){t[n]=e[n]}));const n=new this.constructor(t.parent);return n._baseState=t,n},c.prototype._wrap=function(){const e=this._baseState;u.forEach((function(t){this[t]=function(){const n=new this.constructor(this);return e.children.push(n),n[t].apply(n,arguments)}}),this)},c.prototype._init=function(e){const t=this._baseState;a(null===t.parent),e.call(this),t.children=t.children.filter((function(e){return e._baseState.parent===this}),this),a.equal(t.children.length,1,"Root node can have only one child")},c.prototype._useArgs=function(e){const t=this._baseState,n=e.filter((function(e){return e instanceof this.constructor}),this);e=e.filter((function(e){return!(e instanceof this.constructor)}),this),0!==n.length&&(a(null===t.children),t.children=n,n.forEach((function(e){e._baseState.parent=this}),this)),0!==e.length&&(a(null===t.args),t.args=e,t.reverseArgs=e.map((function(e){if("object"!=typeof e||e.constructor!==Object)return e;const t={};return Object.keys(e).forEach((function(n){n==(0|n)&&(n|=0);const o=e[n];t[o]=n})),t})))},["_peekTag","_decodeTag","_use","_decodeStr","_decodeObjid","_decodeTime","_decodeNull","_decodeInt","_decodeBool","_decodeList","_encodeComposite","_encodeStr","_encodeObjid","_encodeTime","_encodeNull","_encodeInt","_encodeBool"].forEach((function(e){c.prototype[e]=function(){const t=this._baseState;throw new Error(e+" not implemented for encoding: "+t.enc)}})),s.forEach((function(e){c.prototype[e]=function(){const t=this._baseState,n=Array.prototype.slice.call(arguments);return a(null===t.tag),t.tag=e,this._useArgs(n),this}})),c.prototype.use=function(e){a(e);const t=this._baseState;return a(null===t.use),t.use=e,this},c.prototype.optional=function(){return this._baseState.optional=!0,this},c.prototype.def=function(e){const t=this._baseState;return a(null===t.default),t.default=e,t.optional=!0,this},c.prototype.explicit=function(e){const t=this._baseState;return a(null===t.explicit&&null===t.implicit),t.explicit=e,this},c.prototype.implicit=function(e){const t=this._baseState;return a(null===t.explicit&&null===t.implicit),t.implicit=e,this},c.prototype.obj=function(){const e=this._baseState,t=Array.prototype.slice.call(arguments);return e.obj=!0,0!==t.length&&this._useArgs(t),this},c.prototype.key=function(e){const t=this._baseState;return a(null===t.key),t.key=e,this},c.prototype.any=function(){return this._baseState.any=!0,this},c.prototype.choice=function(e){const t=this._baseState;return a(null===t.choice),t.choice=e,this._useArgs(Object.keys(e).map((function(t){return e[t]}))),this},c.prototype.contains=function(e){const t=this._baseState;return a(null===t.use),t.contains=e,this},c.prototype._decode=function(e,t){const n=this._baseState;if(null===n.parent)return e.wrapResult(n.children[0]._decode(e,t));let o,r=n.default,a=!0,s=null;if(null!==n.key&&(s=e.enterKey(n.key)),n.optional){let o=null;if(null!==n.explicit?o=n.explicit:null!==n.implicit?o=n.implicit:null!==n.tag&&(o=n.tag),null!==o||n.any){if(a=this._peekTag(e,o,n.any),e.isError(a))return a}else{const o=e.save();try{null===n.choice?this._decodeGeneric(n.tag,e,t):this._decodeChoice(e,t),a=!0}catch(e){a=!1}e.restore(o)}}if(n.obj&&a&&(o=e.enterObject()),a){if(null!==n.explicit){const t=this._decodeTag(e,n.explicit);if(e.isError(t))return t;e=t}const o=e.offset;if(null===n.use&&null===n.choice){let t;n.any&&(t=e.save());const o=this._decodeTag(e,null!==n.implicit?n.implicit:n.tag,n.any);if(e.isError(o))return o;n.any?r=e.raw(t):e=o}if(t&&t.track&&null!==n.tag&&t.track(e.path(),o,e.length,"tagged"),t&&t.track&&null!==n.tag&&t.track(e.path(),e.offset,e.length,"content"),n.any||(r=null===n.choice?this._decodeGeneric(n.tag,e,t):this._decodeChoice(e,t)),e.isError(r))return r;if(n.any||null!==n.choice||null===n.children||n.children.forEach((function(n){n._decode(e,t)})),n.contains&&("octstr"===n.tag||"bitstr"===n.tag)){const o=new i(r);r=this._getUse(n.contains,e._reporterState.obj)._decode(o,t)}}return n.obj&&a&&(r=e.leaveObject(o)),null===n.key||null===r&&!0!==a?null!==s&&e.exitKey(s):e.leaveKey(s,n.key,r),r},c.prototype._decodeGeneric=function(e,t,n){const o=this._baseState;return"seq"===e||"set"===e?null:"seqof"===e||"setof"===e?this._decodeList(t,e,o.args[0],n):/str$/.test(e)?this._decodeStr(t,e,n):"objid"===e&&o.args?this._decodeObjid(t,o.args[0],o.args[1],n):"objid"===e?this._decodeObjid(t,null,null,n):"gentime"===e||"utctime"===e?this._decodeTime(t,e,n):"null_"===e?this._decodeNull(t,n):"bool"===e?this._decodeBool(t,n):"objDesc"===e?this._decodeStr(t,e,n):"int"===e||"enum"===e?this._decodeInt(t,o.args&&o.args[0],n):null!==o.use?this._getUse(o.use,t._reporterState.obj)._decode(t,n):t.error("unknown tag: "+e)},c.prototype._getUse=function(e,t){const n=this._baseState;return n.useDecoder=this._use(e,t),a(null===n.useDecoder._baseState.parent),n.useDecoder=n.useDecoder._baseState.children[0],n.implicit!==n.useDecoder._baseState.implicit&&(n.useDecoder=n.useDecoder.clone(),n.useDecoder._baseState.implicit=n.implicit),n.useDecoder},c.prototype._decodeChoice=function(e,t){const n=this._baseState;let o=null,r=!1;return Object.keys(n.choice).some((function(i){const a=e.save(),s=n.choice[i];try{const n=s._decode(e,t);if(e.isError(n))return!1;o={type:i,value:n},r=!0}catch(t){return e.restore(a),!1}return!0}),this),r?o:e.error("Choice not matched")},c.prototype._createEncoderBuffer=function(e){return new r(e,this.reporter)},c.prototype._encode=function(e,t,n){const o=this._baseState;if(null!==o.default&&o.default===e)return;const r=this._encodeValue(e,t,n);return void 0===r||this._skipDefault(r,t,n)?void 0:r},c.prototype._encodeValue=function(e,t,n){const r=this._baseState;if(null===r.parent)return r.children[0]._encode(e,t||new o);let i=null;if(this.reporter=t,r.optional&&void 0===e){if(null===r.default)return;e=r.default}let a=null,s=!1;if(r.any)i=this._createEncoderBuffer(e);else if(r.choice)i=this._encodeChoice(e,t);else if(r.contains)a=this._getUse(r.contains,n)._encode(e,t),s=!0;else if(r.children)a=r.children.map((function(n){if("null_"===n._baseState.tag)return n._encode(null,t,e);if(null===n._baseState.key)return t.error("Child should have a key");const o=t.enterKey(n._baseState.key);if("object"!=typeof e)return t.error("Child expected, but input is not object");const r=n._encode(e[n._baseState.key],t,e);return t.leaveKey(o),r}),this).filter((function(e){return e})),a=this._createEncoderBuffer(a);else if("seqof"===r.tag||"setof"===r.tag){if(!r.args||1!==r.args.length)return t.error("Too many args for : "+r.tag);if(!Array.isArray(e))return t.error("seqof/setof, but data is not Array");const n=this.clone();n._baseState.implicit=null,a=this._createEncoderBuffer(e.map((function(n){const o=this._baseState;return this._getUse(o.args[0],e)._encode(n,t)}),n))}else null!==r.use?i=this._getUse(r.use,n)._encode(e,t):(a=this._encodePrimitive(r.tag,e),s=!0);if(!r.any&&null===r.choice){const e=null!==r.implicit?r.implicit:r.tag,n=null===r.implicit?"universal":"context";null===e?null===r.use&&t.error("Tag could be omitted only for .use()"):null===r.use&&(i=this._encodeComposite(e,s,n,a))}return null!==r.explicit&&(i=this._encodeComposite(r.explicit,!1,"context",i)),i},c.prototype._encodeChoice=function(e,t){const n=this._baseState,o=n.choice[e.type];return o||a(!1,e.type+" not found in "+JSON.stringify(Object.keys(n.choice))),o._encode(e.value,t)},c.prototype._encodePrimitive=function(e,t){const n=this._baseState;if(/str$/.test(e))return this._encodeStr(t,e);if("objid"===e&&n.args)return this._encodeObjid(t,n.reverseArgs[0],n.args[1]);if("objid"===e)return this._encodeObjid(t,null,null);if("gentime"===e||"utctime"===e)return this._encodeTime(t,e);if("null_"===e)return this._encodeNull();if("int"===e||"enum"===e)return this._encodeInt(t,n.args&&n.reverseArgs[0]);if("bool"===e)return this._encodeBool(t);if("objDesc"===e)return this._encodeStr(t,e);throw new Error("Unsupported tag: "+e)},c.prototype._isNumstr=function(e){return/^[0-9 ]*$/.test(e)},c.prototype._isPrintstr=function(e){return/^[A-Za-z0-9 '()+,-./:=?]*$/.test(e)}},98465:(e,t,n)=>{"use strict";const o=n(35717);function r(e){this._reporterState={obj:null,path:[],options:e||{},errors:[]}}function i(e,t){this.path=e,this.rethrow(t)}t.b=r,r.prototype.isError=function(e){return e instanceof i},r.prototype.save=function(){const e=this._reporterState;return{obj:e.obj,pathLen:e.path.length}},r.prototype.restore=function(e){const t=this._reporterState;t.obj=e.obj,t.path=t.path.slice(0,e.pathLen)},r.prototype.enterKey=function(e){return this._reporterState.path.push(e)},r.prototype.exitKey=function(e){const t=this._reporterState;t.path=t.path.slice(0,e-1)},r.prototype.leaveKey=function(e,t,n){const o=this._reporterState;this.exitKey(e),null!==o.obj&&(o.obj[t]=n)},r.prototype.path=function(){return this._reporterState.path.join("/")},r.prototype.enterObject=function(){const e=this._reporterState,t=e.obj;return e.obj={},t},r.prototype.leaveObject=function(e){const t=this._reporterState,n=t.obj;return t.obj=e,n},r.prototype.error=function(e){let t;const n=this._reporterState,o=e instanceof i;if(t=o?e:new i(n.path.map((function(e){return"["+JSON.stringify(e)+"]"})).join(""),e.message||e,e.stack),!n.options.partial)throw t;return o||n.errors.push(t),t},r.prototype.wrapResult=function(e){const t=this._reporterState;return t.options.partial?{result:this.isError(e)?null:e,errors:t.errors}:e},o(i,Error),i.prototype.rethrow=function(e){if(this.message=e+" at: "+(this.path||"(shallow)"),Error.captureStackTrace&&Error.captureStackTrace(this,i),!this.stack)try{throw new Error(this.message)}catch(e){this.stack=e.stack}return this}},70160:(e,t)=>{"use strict";function n(e){const t={};return Object.keys(e).forEach((function(n){(0|n)==n&&(n|=0);const o=e[n];t[o]=n})),t}t.tagClass={0:"universal",1:"application",2:"context",3:"private"},t.tagClassByName=n(t.tagClass),t.tag={0:"end",1:"bool",2:"int",3:"bitstr",4:"octstr",5:"null_",6:"objid",7:"objDesc",8:"external",9:"real",10:"enum",11:"embed",12:"utf8str",13:"relativeOid",16:"seq",17:"set",18:"numstr",19:"printstr",20:"t61str",21:"videostr",22:"ia5str",23:"utctime",24:"gentime",25:"graphstr",26:"iso646str",27:"genstr",28:"unistr",29:"charstr",30:"bmpstr"},t.tagByName=n(t.tag)},36826:(e,t,n)=>{"use strict";const o=t;o._reverse=function(e){const t={};return Object.keys(e).forEach((function(n){(0|n)==n&&(n|=0);const o=e[n];t[o]=n})),t},o.der=n(70160)},41671:(e,t,n)=>{"use strict";const o=n(35717),r=n(4590),i=n(36625).C,a=n(41949),s=n(70160);function u(e){this.enc="der",this.name=e.name,this.entity=e,this.tree=new c,this.tree._init(e.body)}function c(e){a.call(this,"der",e)}function l(e,t){let n=e.readUInt8(t);if(e.isError(n))return n;const o=s.tagClass[n>>6],r=0==(32&n);if(31==(31&n)){let o=n;for(n=0;128==(128&o);){if(o=e.readUInt8(t),e.isError(o))return o;n<<=7,n|=127&o}}else n&=31;return{cls:o,primitive:r,tag:n,tagStr:s.tag[n]}}function d(e,t,n){let o=e.readUInt8(n);if(e.isError(o))return o;if(!t&&128===o)return null;if(0==(128&o))return o;const r=127&o;if(r>4)return e.error("length octect is too long");o=0;for(let t=0;t{"use strict";const o=t;o.der=n(41671),o.pem=n(59631)},59631:(e,t,n)=>{"use strict";const o=n(35717),r=n(2399).Buffer,i=n(41671);function a(e){i.call(this,e),this.enc="pem"}o(a,i),e.exports=a,a.prototype.decode=function(e,t){const n=e.toString().split(/[\r\n]+/g),o=t.label.toUpperCase(),a=/^-----(BEGIN|END) ([^-]+)-----$/;let s=-1,u=-1;for(let e=0;e{"use strict";const o=n(35717),r=n(2399).Buffer,i=n(41949),a=n(70160);function s(e){this.enc="der",this.name=e.name,this.entity=e,this.tree=new u,this.tree._init(e.body)}function u(e){i.call(this,"der",e)}function c(e){return e<10?"0"+e:e}e.exports=s,s.prototype.encode=function(e,t){return this.tree._encode(e,t).join()},o(u,i),u.prototype._encodeComposite=function(e,t,n,o){const i=function(e,t,n,o){let r;if("seqof"===e?e="seq":"setof"===e&&(e="set"),a.tagByName.hasOwnProperty(e))r=a.tagByName[e];else{if("number"!=typeof e||(0|e)!==e)return o.error("Unknown tag: "+e);r=e}return r>=31?o.error("Multi-octet tag encoding unsupported"):(t||(r|=32),r|=a.tagClassByName[n||"universal"]<<6,r)}(e,t,n,this.reporter);if(o.length<128){const e=r.alloc(2);return e[0]=i,e[1]=o.length,this._createEncoderBuffer([e,o])}let s=1;for(let e=o.length;e>=256;e>>=8)s++;const u=r.alloc(2+s);u[0]=i,u[1]=128|s;for(let e=1+s,t=o.length;t>0;e--,t>>=8)u[e]=255&t;return this._createEncoderBuffer([u,o])},u.prototype._encodeStr=function(e,t){if("bitstr"===t)return this._createEncoderBuffer([0|e.unused,e.data]);if("bmpstr"===t){const t=r.alloc(2*e.length);for(let n=0;n=40)return this.reporter.error("Second objid identifier OOB");e.splice(0,2,40*e[0]+e[1])}let o=0;for(let t=0;t=128;n>>=7)o++}const i=r.alloc(o);let a=i.length-1;for(let t=e.length-1;t>=0;t--){let n=e[t];for(i[a--]=127&n;(n>>=7)>0;)i[a--]=128|127&n}return this._createEncoderBuffer(i)},u.prototype._encodeTime=function(e,t){let n;const o=new Date(e);return"gentime"===t?n=[c(o.getUTCFullYear()),c(o.getUTCMonth()+1),c(o.getUTCDate()),c(o.getUTCHours()),c(o.getUTCMinutes()),c(o.getUTCSeconds()),"Z"].join(""):"utctime"===t?n=[c(o.getUTCFullYear()%100),c(o.getUTCMonth()+1),c(o.getUTCDate()),c(o.getUTCHours()),c(o.getUTCMinutes()),c(o.getUTCSeconds()),"Z"].join(""):this.reporter.error("Encoding "+t+" time is not supported yet"),this._encodeStr(n,"octstr")},u.prototype._encodeNull=function(){return this._createEncoderBuffer("")},u.prototype._encodeInt=function(e,t){if("string"==typeof e){if(!t)return this.reporter.error("String int or enum given, but no values map");if(!t.hasOwnProperty(e))return this.reporter.error("Values map doesn't contain: "+JSON.stringify(e));e=t[e]}if("number"!=typeof e&&!r.isBuffer(e)){const t=e.toArray();!e.sign&&128&t[0]&&t.unshift(0),e=r.from(t)}if(r.isBuffer(e)){let t=e.length;0===e.length&&t++;const n=r.alloc(t);return e.copy(n),0===e.length&&(n[0]=0),this._createEncoderBuffer(n)}if(e<128)return this._createEncoderBuffer(e);if(e<256)return this._createEncoderBuffer([0,e]);let n=1;for(let t=e;t>=256;t>>=8)n++;const o=new Array(n);for(let t=o.length-1;t>=0;t--)o[t]=255&e,e>>=8;return 128&o[0]&&o.unshift(0),this._createEncoderBuffer(r.from(o))},u.prototype._encodeBool=function(e){return this._createEncoderBuffer(e?255:0)},u.prototype._use=function(e,t){return"function"==typeof e&&(e=e(t)),e._getEncoder("der").tree},u.prototype._skipDefault=function(e,t,n){const o=this._baseState;let r;if(null===o.default)return!1;const i=e.join();if(void 0===o.defaultBuffer&&(o.defaultBuffer=this._encodeValue(o.default,t,n).join()),i.length!==o.defaultBuffer.length)return!1;for(r=0;r{"use strict";const o=t;o.der=n(66984),o.pem=n(2883)},2883:(e,t,n)=>{"use strict";const o=n(35717),r=n(66984);function i(e){r.call(this,e),this.enc="pem"}o(i,r),e.exports=i,i.prototype.encode=function(e,t){const n=r.prototype.encode.call(this,e).toString("base64"),o=["-----BEGIN "+t.label+"-----"];for(let e=0;e=65&&n<=70?n-55:n>=97&&n<=102?n-87:n-48&15}function u(e,t,n){var o=s(e,n);return n-1>=t&&(o|=s(e,n-1)<<4),o}function c(e,t,n,o){for(var r=0,i=Math.min(e.length,n),a=t;a=49?s-49+10:s>=17?s-17+10:s}return r}i.isBN=function(e){return e instanceof i||null!==e&&"object"==typeof e&&e.constructor.wordSize===i.wordSize&&Array.isArray(e.words)},i.max=function(e,t){return e.cmp(t)>0?e:t},i.min=function(e,t){return e.cmp(t)<0?e:t},i.prototype._init=function(e,t,n){if("number"==typeof e)return this._initNumber(e,t,n);if("object"==typeof e)return this._initArray(e,t,n);"hex"===t&&(t=16),o(t===(0|t)&&t>=2&&t<=36);var r=0;"-"===(e=e.toString().replace(/\s+/g,""))[0]&&(r++,this.negative=1),r=0;r-=3)a=e[r]|e[r-1]<<8|e[r-2]<<16,this.words[i]|=a<>>26-s&67108863,(s+=24)>=26&&(s-=26,i++);else if("le"===n)for(r=0,i=0;r>>26-s&67108863,(s+=24)>=26&&(s-=26,i++);return this.strip()},i.prototype._parseHex=function(e,t,n){this.length=Math.ceil((e.length-t)/6),this.words=new Array(this.length);for(var o=0;o=t;o-=2)r=u(e,t,o)<=18?(i-=18,a+=1,this.words[a]|=r>>>26):i+=8;else for(o=(e.length-t)%2==0?t+1:t;o=18?(i-=18,a+=1,this.words[a]|=r>>>26):i+=8;this.strip()},i.prototype._parseBase=function(e,t,n){this.words=[0],this.length=1;for(var o=0,r=1;r<=67108863;r*=t)o++;o--,r=r/t|0;for(var i=e.length-n,a=i%o,s=Math.min(i,i-a)+n,u=0,l=n;l1&&0===this.words[this.length-1];)this.length--;return this._normSign()},i.prototype._normSign=function(){return 1===this.length&&0===this.words[0]&&(this.negative=0),this},i.prototype.inspect=function(){return(this.red?""};var l=["","0","00","000","0000","00000","000000","0000000","00000000","000000000","0000000000","00000000000","000000000000","0000000000000","00000000000000","000000000000000","0000000000000000","00000000000000000","000000000000000000","0000000000000000000","00000000000000000000","000000000000000000000","0000000000000000000000","00000000000000000000000","000000000000000000000000","0000000000000000000000000"],d=[0,0,25,16,12,11,10,9,8,8,7,7,7,7,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5],h=[0,0,33554432,43046721,16777216,48828125,60466176,40353607,16777216,43046721,1e7,19487171,35831808,62748517,7529536,11390625,16777216,24137569,34012224,47045881,64e6,4084101,5153632,6436343,7962624,9765625,11881376,14348907,17210368,20511149,243e5,28629151,33554432,39135393,45435424,52521875,60466176];function p(e,t,n){n.negative=t.negative^e.negative;var o=e.length+t.length|0;n.length=o,o=o-1|0;var r=0|e.words[0],i=0|t.words[0],a=r*i,s=67108863&a,u=a/67108864|0;n.words[0]=s;for(var c=1;c>>26,d=67108863&u,h=Math.min(c,t.length-1),p=Math.max(0,c-e.length+1);p<=h;p++){var f=c-p|0;l+=(a=(r=0|e.words[f])*(i=0|t.words[p])+d)/67108864|0,d=67108863&a}n.words[c]=0|d,u=0|l}return 0!==u?n.words[c]=0|u:n.length--,n.strip()}i.prototype.toString=function(e,t){var n;if(t=0|t||1,16===(e=e||10)||"hex"===e){n="";for(var r=0,i=0,a=0;a>>24-r&16777215)||a!==this.length-1?l[6-u.length]+u+n:u+n,(r+=2)>=26&&(r-=26,a--)}for(0!==i&&(n=i.toString(16)+n);n.length%t!=0;)n="0"+n;return 0!==this.negative&&(n="-"+n),n}if(e===(0|e)&&e>=2&&e<=36){var c=d[e],p=h[e];n="";var f=this.clone();for(f.negative=0;!f.isZero();){var g=f.modn(p).toString(e);n=(f=f.idivn(p)).isZero()?g+n:l[c-g.length]+g+n}for(this.isZero()&&(n="0"+n);n.length%t!=0;)n="0"+n;return 0!==this.negative&&(n="-"+n),n}o(!1,"Base should be between 2 and 36")},i.prototype.toNumber=function(){var e=this.words[0];return 2===this.length?e+=67108864*this.words[1]:3===this.length&&1===this.words[2]?e+=4503599627370496+67108864*this.words[1]:this.length>2&&o(!1,"Number can only safely store up to 53 bits"),0!==this.negative?-e:e},i.prototype.toJSON=function(){return this.toString(16)},i.prototype.toBuffer=function(e,t){return o(void 0!==a),this.toArrayLike(a,e,t)},i.prototype.toArray=function(e,t){return this.toArrayLike(Array,e,t)},i.prototype.toArrayLike=function(e,t,n){var r=this.byteLength(),i=n||Math.max(1,r);o(r<=i,"byte array longer than desired length"),o(i>0,"Requested array length <= 0"),this.strip();var a,s,u="le"===t,c=new e(i),l=this.clone();if(u){for(s=0;!l.isZero();s++)a=l.andln(255),l.iushrn(8),c[s]=a;for(;s=4096&&(n+=13,t>>>=13),t>=64&&(n+=7,t>>>=7),t>=8&&(n+=4,t>>>=4),t>=2&&(n+=2,t>>>=2),n+t},i.prototype._zeroBits=function(e){if(0===e)return 26;var t=e,n=0;return 0==(8191&t)&&(n+=13,t>>>=13),0==(127&t)&&(n+=7,t>>>=7),0==(15&t)&&(n+=4,t>>>=4),0==(3&t)&&(n+=2,t>>>=2),0==(1&t)&&n++,n},i.prototype.bitLength=function(){var e=this.words[this.length-1],t=this._countBits(e);return 26*(this.length-1)+t},i.prototype.zeroBits=function(){if(this.isZero())return 0;for(var e=0,t=0;te.length?this.clone().ior(e):e.clone().ior(this)},i.prototype.uor=function(e){return this.length>e.length?this.clone().iuor(e):e.clone().iuor(this)},i.prototype.iuand=function(e){var t;t=this.length>e.length?e:this;for(var n=0;ne.length?this.clone().iand(e):e.clone().iand(this)},i.prototype.uand=function(e){return this.length>e.length?this.clone().iuand(e):e.clone().iuand(this)},i.prototype.iuxor=function(e){var t,n;this.length>e.length?(t=this,n=e):(t=e,n=this);for(var o=0;oe.length?this.clone().ixor(e):e.clone().ixor(this)},i.prototype.uxor=function(e){return this.length>e.length?this.clone().iuxor(e):e.clone().iuxor(this)},i.prototype.inotn=function(e){o("number"==typeof e&&e>=0);var t=0|Math.ceil(e/26),n=e%26;this._expand(t),n>0&&t--;for(var r=0;r0&&(this.words[r]=~this.words[r]&67108863>>26-n),this.strip()},i.prototype.notn=function(e){return this.clone().inotn(e)},i.prototype.setn=function(e,t){o("number"==typeof e&&e>=0);var n=e/26|0,r=e%26;return this._expand(n+1),this.words[n]=t?this.words[n]|1<e.length?(n=this,o=e):(n=e,o=this);for(var r=0,i=0;i>>26;for(;0!==r&&i>>26;if(this.length=n.length,0!==r)this.words[this.length]=r,this.length++;else if(n!==this)for(;ie.length?this.clone().iadd(e):e.clone().iadd(this)},i.prototype.isub=function(e){if(0!==e.negative){e.negative=0;var t=this.iadd(e);return e.negative=1,t._normSign()}if(0!==this.negative)return this.negative=0,this.iadd(e),this.negative=1,this._normSign();var n,o,r=this.cmp(e);if(0===r)return this.negative=0,this.length=1,this.words[0]=0,this;r>0?(n=this,o=e):(n=e,o=this);for(var i=0,a=0;a>26,this.words[a]=67108863&t;for(;0!==i&&a>26,this.words[a]=67108863&t;if(0===i&&a>>13,p=0|a[1],f=8191&p,g=p>>>13,m=0|a[2],_=8191&m,F=m>>>13,y=0|a[3],b=8191&y,v=y>>>13,w=0|a[4],E=8191&w,k=w>>>13,D=0|a[5],S=8191&D,x=D>>>13,C=0|a[6],A=8191&C,T=C>>>13,R=0|a[7],I=8191&R,M=R>>>13,O=0|a[8],B=8191&O,N=O>>>13,L=0|a[9],P=8191&L,U=L>>>13,j=0|s[0],q=8191&j,z=j>>>13,K=0|s[1],G=8191&K,$=K>>>13,H=0|s[2],V=8191&H,W=H>>>13,Y=0|s[3],Z=8191&Y,X=Y>>>13,J=0|s[4],Q=8191&J,ee=J>>>13,te=0|s[5],ne=8191&te,oe=te>>>13,re=0|s[6],ie=8191&re,ae=re>>>13,se=0|s[7],ue=8191&se,ce=se>>>13,le=0|s[8],de=8191&le,he=le>>>13,pe=0|s[9],fe=8191&pe,ge=pe>>>13;n.negative=e.negative^t.negative,n.length=19;var me=(c+(o=Math.imul(d,q))|0)+((8191&(r=(r=Math.imul(d,z))+Math.imul(h,q)|0))<<13)|0;c=((i=Math.imul(h,z))+(r>>>13)|0)+(me>>>26)|0,me&=67108863,o=Math.imul(f,q),r=(r=Math.imul(f,z))+Math.imul(g,q)|0,i=Math.imul(g,z);var _e=(c+(o=o+Math.imul(d,G)|0)|0)+((8191&(r=(r=r+Math.imul(d,$)|0)+Math.imul(h,G)|0))<<13)|0;c=((i=i+Math.imul(h,$)|0)+(r>>>13)|0)+(_e>>>26)|0,_e&=67108863,o=Math.imul(_,q),r=(r=Math.imul(_,z))+Math.imul(F,q)|0,i=Math.imul(F,z),o=o+Math.imul(f,G)|0,r=(r=r+Math.imul(f,$)|0)+Math.imul(g,G)|0,i=i+Math.imul(g,$)|0;var Fe=(c+(o=o+Math.imul(d,V)|0)|0)+((8191&(r=(r=r+Math.imul(d,W)|0)+Math.imul(h,V)|0))<<13)|0;c=((i=i+Math.imul(h,W)|0)+(r>>>13)|0)+(Fe>>>26)|0,Fe&=67108863,o=Math.imul(b,q),r=(r=Math.imul(b,z))+Math.imul(v,q)|0,i=Math.imul(v,z),o=o+Math.imul(_,G)|0,r=(r=r+Math.imul(_,$)|0)+Math.imul(F,G)|0,i=i+Math.imul(F,$)|0,o=o+Math.imul(f,V)|0,r=(r=r+Math.imul(f,W)|0)+Math.imul(g,V)|0,i=i+Math.imul(g,W)|0;var ye=(c+(o=o+Math.imul(d,Z)|0)|0)+((8191&(r=(r=r+Math.imul(d,X)|0)+Math.imul(h,Z)|0))<<13)|0;c=((i=i+Math.imul(h,X)|0)+(r>>>13)|0)+(ye>>>26)|0,ye&=67108863,o=Math.imul(E,q),r=(r=Math.imul(E,z))+Math.imul(k,q)|0,i=Math.imul(k,z),o=o+Math.imul(b,G)|0,r=(r=r+Math.imul(b,$)|0)+Math.imul(v,G)|0,i=i+Math.imul(v,$)|0,o=o+Math.imul(_,V)|0,r=(r=r+Math.imul(_,W)|0)+Math.imul(F,V)|0,i=i+Math.imul(F,W)|0,o=o+Math.imul(f,Z)|0,r=(r=r+Math.imul(f,X)|0)+Math.imul(g,Z)|0,i=i+Math.imul(g,X)|0;var be=(c+(o=o+Math.imul(d,Q)|0)|0)+((8191&(r=(r=r+Math.imul(d,ee)|0)+Math.imul(h,Q)|0))<<13)|0;c=((i=i+Math.imul(h,ee)|0)+(r>>>13)|0)+(be>>>26)|0,be&=67108863,o=Math.imul(S,q),r=(r=Math.imul(S,z))+Math.imul(x,q)|0,i=Math.imul(x,z),o=o+Math.imul(E,G)|0,r=(r=r+Math.imul(E,$)|0)+Math.imul(k,G)|0,i=i+Math.imul(k,$)|0,o=o+Math.imul(b,V)|0,r=(r=r+Math.imul(b,W)|0)+Math.imul(v,V)|0,i=i+Math.imul(v,W)|0,o=o+Math.imul(_,Z)|0,r=(r=r+Math.imul(_,X)|0)+Math.imul(F,Z)|0,i=i+Math.imul(F,X)|0,o=o+Math.imul(f,Q)|0,r=(r=r+Math.imul(f,ee)|0)+Math.imul(g,Q)|0,i=i+Math.imul(g,ee)|0;var ve=(c+(o=o+Math.imul(d,ne)|0)|0)+((8191&(r=(r=r+Math.imul(d,oe)|0)+Math.imul(h,ne)|0))<<13)|0;c=((i=i+Math.imul(h,oe)|0)+(r>>>13)|0)+(ve>>>26)|0,ve&=67108863,o=Math.imul(A,q),r=(r=Math.imul(A,z))+Math.imul(T,q)|0,i=Math.imul(T,z),o=o+Math.imul(S,G)|0,r=(r=r+Math.imul(S,$)|0)+Math.imul(x,G)|0,i=i+Math.imul(x,$)|0,o=o+Math.imul(E,V)|0,r=(r=r+Math.imul(E,W)|0)+Math.imul(k,V)|0,i=i+Math.imul(k,W)|0,o=o+Math.imul(b,Z)|0,r=(r=r+Math.imul(b,X)|0)+Math.imul(v,Z)|0,i=i+Math.imul(v,X)|0,o=o+Math.imul(_,Q)|0,r=(r=r+Math.imul(_,ee)|0)+Math.imul(F,Q)|0,i=i+Math.imul(F,ee)|0,o=o+Math.imul(f,ne)|0,r=(r=r+Math.imul(f,oe)|0)+Math.imul(g,ne)|0,i=i+Math.imul(g,oe)|0;var we=(c+(o=o+Math.imul(d,ie)|0)|0)+((8191&(r=(r=r+Math.imul(d,ae)|0)+Math.imul(h,ie)|0))<<13)|0;c=((i=i+Math.imul(h,ae)|0)+(r>>>13)|0)+(we>>>26)|0,we&=67108863,o=Math.imul(I,q),r=(r=Math.imul(I,z))+Math.imul(M,q)|0,i=Math.imul(M,z),o=o+Math.imul(A,G)|0,r=(r=r+Math.imul(A,$)|0)+Math.imul(T,G)|0,i=i+Math.imul(T,$)|0,o=o+Math.imul(S,V)|0,r=(r=r+Math.imul(S,W)|0)+Math.imul(x,V)|0,i=i+Math.imul(x,W)|0,o=o+Math.imul(E,Z)|0,r=(r=r+Math.imul(E,X)|0)+Math.imul(k,Z)|0,i=i+Math.imul(k,X)|0,o=o+Math.imul(b,Q)|0,r=(r=r+Math.imul(b,ee)|0)+Math.imul(v,Q)|0,i=i+Math.imul(v,ee)|0,o=o+Math.imul(_,ne)|0,r=(r=r+Math.imul(_,oe)|0)+Math.imul(F,ne)|0,i=i+Math.imul(F,oe)|0,o=o+Math.imul(f,ie)|0,r=(r=r+Math.imul(f,ae)|0)+Math.imul(g,ie)|0,i=i+Math.imul(g,ae)|0;var Ee=(c+(o=o+Math.imul(d,ue)|0)|0)+((8191&(r=(r=r+Math.imul(d,ce)|0)+Math.imul(h,ue)|0))<<13)|0;c=((i=i+Math.imul(h,ce)|0)+(r>>>13)|0)+(Ee>>>26)|0,Ee&=67108863,o=Math.imul(B,q),r=(r=Math.imul(B,z))+Math.imul(N,q)|0,i=Math.imul(N,z),o=o+Math.imul(I,G)|0,r=(r=r+Math.imul(I,$)|0)+Math.imul(M,G)|0,i=i+Math.imul(M,$)|0,o=o+Math.imul(A,V)|0,r=(r=r+Math.imul(A,W)|0)+Math.imul(T,V)|0,i=i+Math.imul(T,W)|0,o=o+Math.imul(S,Z)|0,r=(r=r+Math.imul(S,X)|0)+Math.imul(x,Z)|0,i=i+Math.imul(x,X)|0,o=o+Math.imul(E,Q)|0,r=(r=r+Math.imul(E,ee)|0)+Math.imul(k,Q)|0,i=i+Math.imul(k,ee)|0,o=o+Math.imul(b,ne)|0,r=(r=r+Math.imul(b,oe)|0)+Math.imul(v,ne)|0,i=i+Math.imul(v,oe)|0,o=o+Math.imul(_,ie)|0,r=(r=r+Math.imul(_,ae)|0)+Math.imul(F,ie)|0,i=i+Math.imul(F,ae)|0,o=o+Math.imul(f,ue)|0,r=(r=r+Math.imul(f,ce)|0)+Math.imul(g,ue)|0,i=i+Math.imul(g,ce)|0;var ke=(c+(o=o+Math.imul(d,de)|0)|0)+((8191&(r=(r=r+Math.imul(d,he)|0)+Math.imul(h,de)|0))<<13)|0;c=((i=i+Math.imul(h,he)|0)+(r>>>13)|0)+(ke>>>26)|0,ke&=67108863,o=Math.imul(P,q),r=(r=Math.imul(P,z))+Math.imul(U,q)|0,i=Math.imul(U,z),o=o+Math.imul(B,G)|0,r=(r=r+Math.imul(B,$)|0)+Math.imul(N,G)|0,i=i+Math.imul(N,$)|0,o=o+Math.imul(I,V)|0,r=(r=r+Math.imul(I,W)|0)+Math.imul(M,V)|0,i=i+Math.imul(M,W)|0,o=o+Math.imul(A,Z)|0,r=(r=r+Math.imul(A,X)|0)+Math.imul(T,Z)|0,i=i+Math.imul(T,X)|0,o=o+Math.imul(S,Q)|0,r=(r=r+Math.imul(S,ee)|0)+Math.imul(x,Q)|0,i=i+Math.imul(x,ee)|0,o=o+Math.imul(E,ne)|0,r=(r=r+Math.imul(E,oe)|0)+Math.imul(k,ne)|0,i=i+Math.imul(k,oe)|0,o=o+Math.imul(b,ie)|0,r=(r=r+Math.imul(b,ae)|0)+Math.imul(v,ie)|0,i=i+Math.imul(v,ae)|0,o=o+Math.imul(_,ue)|0,r=(r=r+Math.imul(_,ce)|0)+Math.imul(F,ue)|0,i=i+Math.imul(F,ce)|0,o=o+Math.imul(f,de)|0,r=(r=r+Math.imul(f,he)|0)+Math.imul(g,de)|0,i=i+Math.imul(g,he)|0;var De=(c+(o=o+Math.imul(d,fe)|0)|0)+((8191&(r=(r=r+Math.imul(d,ge)|0)+Math.imul(h,fe)|0))<<13)|0;c=((i=i+Math.imul(h,ge)|0)+(r>>>13)|0)+(De>>>26)|0,De&=67108863,o=Math.imul(P,G),r=(r=Math.imul(P,$))+Math.imul(U,G)|0,i=Math.imul(U,$),o=o+Math.imul(B,V)|0,r=(r=r+Math.imul(B,W)|0)+Math.imul(N,V)|0,i=i+Math.imul(N,W)|0,o=o+Math.imul(I,Z)|0,r=(r=r+Math.imul(I,X)|0)+Math.imul(M,Z)|0,i=i+Math.imul(M,X)|0,o=o+Math.imul(A,Q)|0,r=(r=r+Math.imul(A,ee)|0)+Math.imul(T,Q)|0,i=i+Math.imul(T,ee)|0,o=o+Math.imul(S,ne)|0,r=(r=r+Math.imul(S,oe)|0)+Math.imul(x,ne)|0,i=i+Math.imul(x,oe)|0,o=o+Math.imul(E,ie)|0,r=(r=r+Math.imul(E,ae)|0)+Math.imul(k,ie)|0,i=i+Math.imul(k,ae)|0,o=o+Math.imul(b,ue)|0,r=(r=r+Math.imul(b,ce)|0)+Math.imul(v,ue)|0,i=i+Math.imul(v,ce)|0,o=o+Math.imul(_,de)|0,r=(r=r+Math.imul(_,he)|0)+Math.imul(F,de)|0,i=i+Math.imul(F,he)|0;var Se=(c+(o=o+Math.imul(f,fe)|0)|0)+((8191&(r=(r=r+Math.imul(f,ge)|0)+Math.imul(g,fe)|0))<<13)|0;c=((i=i+Math.imul(g,ge)|0)+(r>>>13)|0)+(Se>>>26)|0,Se&=67108863,o=Math.imul(P,V),r=(r=Math.imul(P,W))+Math.imul(U,V)|0,i=Math.imul(U,W),o=o+Math.imul(B,Z)|0,r=(r=r+Math.imul(B,X)|0)+Math.imul(N,Z)|0,i=i+Math.imul(N,X)|0,o=o+Math.imul(I,Q)|0,r=(r=r+Math.imul(I,ee)|0)+Math.imul(M,Q)|0,i=i+Math.imul(M,ee)|0,o=o+Math.imul(A,ne)|0,r=(r=r+Math.imul(A,oe)|0)+Math.imul(T,ne)|0,i=i+Math.imul(T,oe)|0,o=o+Math.imul(S,ie)|0,r=(r=r+Math.imul(S,ae)|0)+Math.imul(x,ie)|0,i=i+Math.imul(x,ae)|0,o=o+Math.imul(E,ue)|0,r=(r=r+Math.imul(E,ce)|0)+Math.imul(k,ue)|0,i=i+Math.imul(k,ce)|0,o=o+Math.imul(b,de)|0,r=(r=r+Math.imul(b,he)|0)+Math.imul(v,de)|0,i=i+Math.imul(v,he)|0;var xe=(c+(o=o+Math.imul(_,fe)|0)|0)+((8191&(r=(r=r+Math.imul(_,ge)|0)+Math.imul(F,fe)|0))<<13)|0;c=((i=i+Math.imul(F,ge)|0)+(r>>>13)|0)+(xe>>>26)|0,xe&=67108863,o=Math.imul(P,Z),r=(r=Math.imul(P,X))+Math.imul(U,Z)|0,i=Math.imul(U,X),o=o+Math.imul(B,Q)|0,r=(r=r+Math.imul(B,ee)|0)+Math.imul(N,Q)|0,i=i+Math.imul(N,ee)|0,o=o+Math.imul(I,ne)|0,r=(r=r+Math.imul(I,oe)|0)+Math.imul(M,ne)|0,i=i+Math.imul(M,oe)|0,o=o+Math.imul(A,ie)|0,r=(r=r+Math.imul(A,ae)|0)+Math.imul(T,ie)|0,i=i+Math.imul(T,ae)|0,o=o+Math.imul(S,ue)|0,r=(r=r+Math.imul(S,ce)|0)+Math.imul(x,ue)|0,i=i+Math.imul(x,ce)|0,o=o+Math.imul(E,de)|0,r=(r=r+Math.imul(E,he)|0)+Math.imul(k,de)|0,i=i+Math.imul(k,he)|0;var Ce=(c+(o=o+Math.imul(b,fe)|0)|0)+((8191&(r=(r=r+Math.imul(b,ge)|0)+Math.imul(v,fe)|0))<<13)|0;c=((i=i+Math.imul(v,ge)|0)+(r>>>13)|0)+(Ce>>>26)|0,Ce&=67108863,o=Math.imul(P,Q),r=(r=Math.imul(P,ee))+Math.imul(U,Q)|0,i=Math.imul(U,ee),o=o+Math.imul(B,ne)|0,r=(r=r+Math.imul(B,oe)|0)+Math.imul(N,ne)|0,i=i+Math.imul(N,oe)|0,o=o+Math.imul(I,ie)|0,r=(r=r+Math.imul(I,ae)|0)+Math.imul(M,ie)|0,i=i+Math.imul(M,ae)|0,o=o+Math.imul(A,ue)|0,r=(r=r+Math.imul(A,ce)|0)+Math.imul(T,ue)|0,i=i+Math.imul(T,ce)|0,o=o+Math.imul(S,de)|0,r=(r=r+Math.imul(S,he)|0)+Math.imul(x,de)|0,i=i+Math.imul(x,he)|0;var Ae=(c+(o=o+Math.imul(E,fe)|0)|0)+((8191&(r=(r=r+Math.imul(E,ge)|0)+Math.imul(k,fe)|0))<<13)|0;c=((i=i+Math.imul(k,ge)|0)+(r>>>13)|0)+(Ae>>>26)|0,Ae&=67108863,o=Math.imul(P,ne),r=(r=Math.imul(P,oe))+Math.imul(U,ne)|0,i=Math.imul(U,oe),o=o+Math.imul(B,ie)|0,r=(r=r+Math.imul(B,ae)|0)+Math.imul(N,ie)|0,i=i+Math.imul(N,ae)|0,o=o+Math.imul(I,ue)|0,r=(r=r+Math.imul(I,ce)|0)+Math.imul(M,ue)|0,i=i+Math.imul(M,ce)|0,o=o+Math.imul(A,de)|0,r=(r=r+Math.imul(A,he)|0)+Math.imul(T,de)|0,i=i+Math.imul(T,he)|0;var Te=(c+(o=o+Math.imul(S,fe)|0)|0)+((8191&(r=(r=r+Math.imul(S,ge)|0)+Math.imul(x,fe)|0))<<13)|0;c=((i=i+Math.imul(x,ge)|0)+(r>>>13)|0)+(Te>>>26)|0,Te&=67108863,o=Math.imul(P,ie),r=(r=Math.imul(P,ae))+Math.imul(U,ie)|0,i=Math.imul(U,ae),o=o+Math.imul(B,ue)|0,r=(r=r+Math.imul(B,ce)|0)+Math.imul(N,ue)|0,i=i+Math.imul(N,ce)|0,o=o+Math.imul(I,de)|0,r=(r=r+Math.imul(I,he)|0)+Math.imul(M,de)|0,i=i+Math.imul(M,he)|0;var Re=(c+(o=o+Math.imul(A,fe)|0)|0)+((8191&(r=(r=r+Math.imul(A,ge)|0)+Math.imul(T,fe)|0))<<13)|0;c=((i=i+Math.imul(T,ge)|0)+(r>>>13)|0)+(Re>>>26)|0,Re&=67108863,o=Math.imul(P,ue),r=(r=Math.imul(P,ce))+Math.imul(U,ue)|0,i=Math.imul(U,ce),o=o+Math.imul(B,de)|0,r=(r=r+Math.imul(B,he)|0)+Math.imul(N,de)|0,i=i+Math.imul(N,he)|0;var Ie=(c+(o=o+Math.imul(I,fe)|0)|0)+((8191&(r=(r=r+Math.imul(I,ge)|0)+Math.imul(M,fe)|0))<<13)|0;c=((i=i+Math.imul(M,ge)|0)+(r>>>13)|0)+(Ie>>>26)|0,Ie&=67108863,o=Math.imul(P,de),r=(r=Math.imul(P,he))+Math.imul(U,de)|0,i=Math.imul(U,he);var Me=(c+(o=o+Math.imul(B,fe)|0)|0)+((8191&(r=(r=r+Math.imul(B,ge)|0)+Math.imul(N,fe)|0))<<13)|0;c=((i=i+Math.imul(N,ge)|0)+(r>>>13)|0)+(Me>>>26)|0,Me&=67108863;var Oe=(c+(o=Math.imul(P,fe))|0)+((8191&(r=(r=Math.imul(P,ge))+Math.imul(U,fe)|0))<<13)|0;return c=((i=Math.imul(U,ge))+(r>>>13)|0)+(Oe>>>26)|0,Oe&=67108863,u[0]=me,u[1]=_e,u[2]=Fe,u[3]=ye,u[4]=be,u[5]=ve,u[6]=we,u[7]=Ee,u[8]=ke,u[9]=De,u[10]=Se,u[11]=xe,u[12]=Ce,u[13]=Ae,u[14]=Te,u[15]=Re,u[16]=Ie,u[17]=Me,u[18]=Oe,0!==c&&(u[19]=c,n.length++),n};function g(e,t,n){return(new m).mulp(e,t,n)}function m(e,t){this.x=e,this.y=t}Math.imul||(f=p),i.prototype.mulTo=function(e,t){var n=this.length+e.length;return 10===this.length&&10===e.length?f(this,e,t):n<63?p(this,e,t):n<1024?function(e,t,n){n.negative=t.negative^e.negative,n.length=e.length+t.length;for(var o=0,r=0,i=0;i>>26)|0)>>>26,a&=67108863}n.words[i]=s,o=a,a=r}return 0!==o?n.words[i]=o:n.length--,n.strip()}(this,e,t):g(this,e,t)},m.prototype.makeRBT=function(e){for(var t=new Array(e),n=i.prototype._countBits(e)-1,o=0;o>=1;return o},m.prototype.permute=function(e,t,n,o,r,i){for(var a=0;a>>=1)r++;return 1<>>=13,n[2*a+1]=8191&i,i>>>=13;for(a=2*t;a>=26,t+=r/67108864|0,t+=i>>>26,this.words[n]=67108863&i}return 0!==t&&(this.words[n]=t,this.length++),this},i.prototype.muln=function(e){return this.clone().imuln(e)},i.prototype.sqr=function(){return this.mul(this)},i.prototype.isqr=function(){return this.imul(this.clone())},i.prototype.pow=function(e){var t=function(e){for(var t=new Array(e.bitLength()),n=0;n>>r}return t}(e);if(0===t.length)return new i(1);for(var n=this,o=0;o=0);var t,n=e%26,r=(e-n)/26,i=67108863>>>26-n<<26-n;if(0!==n){var a=0;for(t=0;t>>26-n}a&&(this.words[t]=a,this.length++)}if(0!==r){for(t=this.length-1;t>=0;t--)this.words[t+r]=this.words[t];for(t=0;t=0),r=t?(t-t%26)/26:0;var i=e%26,a=Math.min((e-i)/26,this.length),s=67108863^67108863>>>i<a)for(this.length-=a,c=0;c=0&&(0!==l||c>=r);c--){var d=0|this.words[c];this.words[c]=l<<26-i|d>>>i,l=d&s}return u&&0!==l&&(u.words[u.length++]=l),0===this.length&&(this.words[0]=0,this.length=1),this.strip()},i.prototype.ishrn=function(e,t,n){return o(0===this.negative),this.iushrn(e,t,n)},i.prototype.shln=function(e){return this.clone().ishln(e)},i.prototype.ushln=function(e){return this.clone().iushln(e)},i.prototype.shrn=function(e){return this.clone().ishrn(e)},i.prototype.ushrn=function(e){return this.clone().iushrn(e)},i.prototype.testn=function(e){o("number"==typeof e&&e>=0);var t=e%26,n=(e-t)/26,r=1<=0);var t=e%26,n=(e-t)/26;if(o(0===this.negative,"imaskn works only with positive numbers"),this.length<=n)return this;if(0!==t&&n++,this.length=Math.min(n,this.length),0!==t){var r=67108863^67108863>>>t<=67108864;t++)this.words[t]-=67108864,t===this.length-1?this.words[t+1]=1:this.words[t+1]++;return this.length=Math.max(this.length,t+1),this},i.prototype.isubn=function(e){if(o("number"==typeof e),o(e<67108864),e<0)return this.iaddn(-e);if(0!==this.negative)return this.negative=0,this.iaddn(e),this.negative=1,this;if(this.words[0]-=e,1===this.length&&this.words[0]<0)this.words[0]=-this.words[0],this.negative=1;else for(var t=0;t>26)-(u/67108864|0),this.words[r+n]=67108863&i}for(;r>26,this.words[r+n]=67108863&i;if(0===s)return this.strip();for(o(-1===s),s=0,r=0;r>26,this.words[r]=67108863&i;return this.negative=1,this.strip()},i.prototype._wordDiv=function(e,t){var n=(this.length,e.length),o=this.clone(),r=e,a=0|r.words[r.length-1];0!=(n=26-this._countBits(a))&&(r=r.ushln(n),o.iushln(n),a=0|r.words[r.length-1]);var s,u=o.length-r.length;if("mod"!==t){(s=new i(null)).length=u+1,s.words=new Array(s.length);for(var c=0;c=0;d--){var h=67108864*(0|o.words[r.length+d])+(0|o.words[r.length+d-1]);for(h=Math.min(h/a|0,67108863),o._ishlnsubmul(r,h,d);0!==o.negative;)h--,o.negative=0,o._ishlnsubmul(r,1,d),o.isZero()||(o.negative^=1);s&&(s.words[d]=h)}return s&&s.strip(),o.strip(),"div"!==t&&0!==n&&o.iushrn(n),{div:s||null,mod:o}},i.prototype.divmod=function(e,t,n){return o(!e.isZero()),this.isZero()?{div:new i(0),mod:new i(0)}:0!==this.negative&&0===e.negative?(s=this.neg().divmod(e,t),"mod"!==t&&(r=s.div.neg()),"div"!==t&&(a=s.mod.neg(),n&&0!==a.negative&&a.iadd(e)),{div:r,mod:a}):0===this.negative&&0!==e.negative?(s=this.divmod(e.neg(),t),"mod"!==t&&(r=s.div.neg()),{div:r,mod:s.mod}):0!=(this.negative&e.negative)?(s=this.neg().divmod(e.neg(),t),"div"!==t&&(a=s.mod.neg(),n&&0!==a.negative&&a.isub(e)),{div:s.div,mod:a}):e.length>this.length||this.cmp(e)<0?{div:new i(0),mod:this}:1===e.length?"div"===t?{div:this.divn(e.words[0]),mod:null}:"mod"===t?{div:null,mod:new i(this.modn(e.words[0]))}:{div:this.divn(e.words[0]),mod:new i(this.modn(e.words[0]))}:this._wordDiv(e,t);var r,a,s},i.prototype.div=function(e){return this.divmod(e,"div",!1).div},i.prototype.mod=function(e){return this.divmod(e,"mod",!1).mod},i.prototype.umod=function(e){return this.divmod(e,"mod",!0).mod},i.prototype.divRound=function(e){var t=this.divmod(e);if(t.mod.isZero())return t.div;var n=0!==t.div.negative?t.mod.isub(e):t.mod,o=e.ushrn(1),r=e.andln(1),i=n.cmp(o);return i<0||1===r&&0===i?t.div:0!==t.div.negative?t.div.isubn(1):t.div.iaddn(1)},i.prototype.modn=function(e){o(e<=67108863);for(var t=(1<<26)%e,n=0,r=this.length-1;r>=0;r--)n=(t*n+(0|this.words[r]))%e;return n},i.prototype.idivn=function(e){o(e<=67108863);for(var t=0,n=this.length-1;n>=0;n--){var r=(0|this.words[n])+67108864*t;this.words[n]=r/e|0,t=r%e}return this.strip()},i.prototype.divn=function(e){return this.clone().idivn(e)},i.prototype.egcd=function(e){o(0===e.negative),o(!e.isZero());var t=this,n=e.clone();t=0!==t.negative?t.umod(e):t.clone();for(var r=new i(1),a=new i(0),s=new i(0),u=new i(1),c=0;t.isEven()&&n.isEven();)t.iushrn(1),n.iushrn(1),++c;for(var l=n.clone(),d=t.clone();!t.isZero();){for(var h=0,p=1;0==(t.words[0]&p)&&h<26;++h,p<<=1);if(h>0)for(t.iushrn(h);h-- >0;)(r.isOdd()||a.isOdd())&&(r.iadd(l),a.isub(d)),r.iushrn(1),a.iushrn(1);for(var f=0,g=1;0==(n.words[0]&g)&&f<26;++f,g<<=1);if(f>0)for(n.iushrn(f);f-- >0;)(s.isOdd()||u.isOdd())&&(s.iadd(l),u.isub(d)),s.iushrn(1),u.iushrn(1);t.cmp(n)>=0?(t.isub(n),r.isub(s),a.isub(u)):(n.isub(t),s.isub(r),u.isub(a))}return{a:s,b:u,gcd:n.iushln(c)}},i.prototype._invmp=function(e){o(0===e.negative),o(!e.isZero());var t=this,n=e.clone();t=0!==t.negative?t.umod(e):t.clone();for(var r,a=new i(1),s=new i(0),u=n.clone();t.cmpn(1)>0&&n.cmpn(1)>0;){for(var c=0,l=1;0==(t.words[0]&l)&&c<26;++c,l<<=1);if(c>0)for(t.iushrn(c);c-- >0;)a.isOdd()&&a.iadd(u),a.iushrn(1);for(var d=0,h=1;0==(n.words[0]&h)&&d<26;++d,h<<=1);if(d>0)for(n.iushrn(d);d-- >0;)s.isOdd()&&s.iadd(u),s.iushrn(1);t.cmp(n)>=0?(t.isub(n),a.isub(s)):(n.isub(t),s.isub(a))}return(r=0===t.cmpn(1)?a:s).cmpn(0)<0&&r.iadd(e),r},i.prototype.gcd=function(e){if(this.isZero())return e.abs();if(e.isZero())return this.abs();var t=this.clone(),n=e.clone();t.negative=0,n.negative=0;for(var o=0;t.isEven()&&n.isEven();o++)t.iushrn(1),n.iushrn(1);for(;;){for(;t.isEven();)t.iushrn(1);for(;n.isEven();)n.iushrn(1);var r=t.cmp(n);if(r<0){var i=t;t=n,n=i}else if(0===r||0===n.cmpn(1))break;t.isub(n)}return n.iushln(o)},i.prototype.invm=function(e){return this.egcd(e).a.umod(e)},i.prototype.isEven=function(){return 0==(1&this.words[0])},i.prototype.isOdd=function(){return 1==(1&this.words[0])},i.prototype.andln=function(e){return this.words[0]&e},i.prototype.bincn=function(e){o("number"==typeof e);var t=e%26,n=(e-t)/26,r=1<>>26,s&=67108863,this.words[a]=s}return 0!==i&&(this.words[a]=i,this.length++),this},i.prototype.isZero=function(){return 1===this.length&&0===this.words[0]},i.prototype.cmpn=function(e){var t,n=e<0;if(0!==this.negative&&!n)return-1;if(0===this.negative&&n)return 1;if(this.strip(),this.length>1)t=1;else{n&&(e=-e),o(e<=67108863,"Number is too big");var r=0|this.words[0];t=r===e?0:re.length)return 1;if(this.length=0;n--){var o=0|this.words[n],r=0|e.words[n];if(o!==r){or&&(t=1);break}}return t},i.prototype.gtn=function(e){return 1===this.cmpn(e)},i.prototype.gt=function(e){return 1===this.cmp(e)},i.prototype.gten=function(e){return this.cmpn(e)>=0},i.prototype.gte=function(e){return this.cmp(e)>=0},i.prototype.ltn=function(e){return-1===this.cmpn(e)},i.prototype.lt=function(e){return-1===this.cmp(e)},i.prototype.lten=function(e){return this.cmpn(e)<=0},i.prototype.lte=function(e){return this.cmp(e)<=0},i.prototype.eqn=function(e){return 0===this.cmpn(e)},i.prototype.eq=function(e){return 0===this.cmp(e)},i.red=function(e){return new E(e)},i.prototype.toRed=function(e){return o(!this.red,"Already a number in reduction context"),o(0===this.negative,"red works only with positives"),e.convertTo(this)._forceRed(e)},i.prototype.fromRed=function(){return o(this.red,"fromRed works only with numbers in reduction context"),this.red.convertFrom(this)},i.prototype._forceRed=function(e){return this.red=e,this},i.prototype.forceRed=function(e){return o(!this.red,"Already a number in reduction context"),this._forceRed(e)},i.prototype.redAdd=function(e){return o(this.red,"redAdd works only with red numbers"),this.red.add(this,e)},i.prototype.redIAdd=function(e){return o(this.red,"redIAdd works only with red numbers"),this.red.iadd(this,e)},i.prototype.redSub=function(e){return o(this.red,"redSub works only with red numbers"),this.red.sub(this,e)},i.prototype.redISub=function(e){return o(this.red,"redISub works only with red numbers"),this.red.isub(this,e)},i.prototype.redShl=function(e){return o(this.red,"redShl works only with red numbers"),this.red.shl(this,e)},i.prototype.redMul=function(e){return o(this.red,"redMul works only with red numbers"),this.red._verify2(this,e),this.red.mul(this,e)},i.prototype.redIMul=function(e){return o(this.red,"redMul works only with red numbers"),this.red._verify2(this,e),this.red.imul(this,e)},i.prototype.redSqr=function(){return o(this.red,"redSqr works only with red numbers"),this.red._verify1(this),this.red.sqr(this)},i.prototype.redISqr=function(){return o(this.red,"redISqr works only with red numbers"),this.red._verify1(this),this.red.isqr(this)},i.prototype.redSqrt=function(){return o(this.red,"redSqrt works only with red numbers"),this.red._verify1(this),this.red.sqrt(this)},i.prototype.redInvm=function(){return o(this.red,"redInvm works only with red numbers"),this.red._verify1(this),this.red.invm(this)},i.prototype.redNeg=function(){return o(this.red,"redNeg works only with red numbers"),this.red._verify1(this),this.red.neg(this)},i.prototype.redPow=function(e){return o(this.red&&!e.red,"redPow(normalNum)"),this.red._verify1(this),this.red.pow(this,e)};var _={k256:null,p224:null,p192:null,p25519:null};function F(e,t){this.name=e,this.p=new i(t,16),this.n=this.p.bitLength(),this.k=new i(1).iushln(this.n).isub(this.p),this.tmp=this._tmp()}function y(){F.call(this,"k256","ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f")}function b(){F.call(this,"p224","ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001")}function v(){F.call(this,"p192","ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff")}function w(){F.call(this,"25519","7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed")}function E(e){if("string"==typeof e){var t=i._prime(e);this.m=t.p,this.prime=t}else o(e.gtn(1),"modulus must be greater than 1"),this.m=e,this.prime=null}function k(e){E.call(this,e),this.shift=this.m.bitLength(),this.shift%26!=0&&(this.shift+=26-this.shift%26),this.r=new i(1).iushln(this.shift),this.r2=this.imod(this.r.sqr()),this.rinv=this.r._invmp(this.m),this.minv=this.rinv.mul(this.r).isubn(1).div(this.m),this.minv=this.minv.umod(this.r),this.minv=this.r.sub(this.minv)}F.prototype._tmp=function(){var e=new i(null);return e.words=new Array(Math.ceil(this.n/13)),e},F.prototype.ireduce=function(e){var t,n=e;do{this.split(n,this.tmp),t=(n=(n=this.imulK(n)).iadd(this.tmp)).bitLength()}while(t>this.n);var o=t0?n.isub(this.p):void 0!==n.strip?n.strip():n._strip(),n},F.prototype.split=function(e,t){e.iushrn(this.n,0,t)},F.prototype.imulK=function(e){return e.imul(this.k)},r(y,F),y.prototype.split=function(e,t){for(var n=4194303,o=Math.min(e.length,9),r=0;r>>22,i=a}i>>>=22,e.words[r-10]=i,0===i&&e.length>10?e.length-=10:e.length-=9},y.prototype.imulK=function(e){e.words[e.length]=0,e.words[e.length+1]=0,e.length+=2;for(var t=0,n=0;n>>=26,e.words[n]=r,t=o}return 0!==t&&(e.words[e.length++]=t),e},i._prime=function(e){if(_[e])return _[e];var t;if("k256"===e)t=new y;else if("p224"===e)t=new b;else if("p192"===e)t=new v;else{if("p25519"!==e)throw new Error("Unknown prime "+e);t=new w}return _[e]=t,t},E.prototype._verify1=function(e){o(0===e.negative,"red works only with positives"),o(e.red,"red works only with red numbers")},E.prototype._verify2=function(e,t){o(0==(e.negative|t.negative),"red works only with positives"),o(e.red&&e.red===t.red,"red works only with red numbers")},E.prototype.imod=function(e){return this.prime?this.prime.ireduce(e)._forceRed(this):e.umod(this.m)._forceRed(this)},E.prototype.neg=function(e){return e.isZero()?e.clone():this.m.sub(e)._forceRed(this)},E.prototype.add=function(e,t){this._verify2(e,t);var n=e.add(t);return n.cmp(this.m)>=0&&n.isub(this.m),n._forceRed(this)},E.prototype.iadd=function(e,t){this._verify2(e,t);var n=e.iadd(t);return n.cmp(this.m)>=0&&n.isub(this.m),n},E.prototype.sub=function(e,t){this._verify2(e,t);var n=e.sub(t);return n.cmpn(0)<0&&n.iadd(this.m),n._forceRed(this)},E.prototype.isub=function(e,t){this._verify2(e,t);var n=e.isub(t);return n.cmpn(0)<0&&n.iadd(this.m),n},E.prototype.shl=function(e,t){return this._verify1(e),this.imod(e.ushln(t))},E.prototype.imul=function(e,t){return this._verify2(e,t),this.imod(e.imul(t))},E.prototype.mul=function(e,t){return this._verify2(e,t),this.imod(e.mul(t))},E.prototype.isqr=function(e){return this.imul(e,e.clone())},E.prototype.sqr=function(e){return this.mul(e,e)},E.prototype.sqrt=function(e){if(e.isZero())return e.clone();var t=this.m.andln(3);if(o(t%2==1),3===t){var n=this.m.add(new i(1)).iushrn(2);return this.pow(e,n)}for(var r=this.m.subn(1),a=0;!r.isZero()&&0===r.andln(1);)a++,r.iushrn(1);o(!r.isZero());var s=new i(1).toRed(this),u=s.redNeg(),c=this.m.subn(1).iushrn(1),l=this.m.bitLength();for(l=new i(2*l*l).toRed(this);0!==this.pow(l,c).cmp(u);)l.redIAdd(u);for(var d=this.pow(l,r),h=this.pow(e,r.addn(1).iushrn(1)),p=this.pow(e,r),f=a;0!==p.cmp(s);){for(var g=p,m=0;0!==g.cmp(s);m++)g=g.redSqr();o(m=0;o--){for(var c=t.words[o],l=u-1;l>=0;l--){var d=c>>l&1;r!==n[0]&&(r=this.sqr(r)),0!==d||0!==a?(a<<=1,a|=d,(4==++s||0===o&&0===l)&&(r=this.mul(r,n[a]),s=0,a=0)):s=0}u=26}return r},E.prototype.convertTo=function(e){var t=e.umod(this.m);return t===e?t.clone():t},E.prototype.convertFrom=function(e){var t=e.clone();return t.red=null,t},i.mont=function(e){return new k(e)},r(k,E),k.prototype.convertTo=function(e){return this.imod(e.ushln(this.shift))},k.prototype.convertFrom=function(e){var t=this.imod(e.mul(this.rinv));return t.red=null,t},k.prototype.imul=function(e,t){if(e.isZero()||t.isZero())return e.words[0]=0,e.length=1,e;var n=e.imul(t),o=n.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m),r=n.isub(o).iushrn(this.shift),i=r;return r.cmp(this.m)>=0?i=r.isub(this.m):r.cmpn(0)<0&&(i=r.iadd(this.m)),i._forceRed(this)},k.prototype.mul=function(e,t){if(e.isZero()||t.isZero())return new i(0)._forceRed(this);var n=e.mul(t),o=n.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m),r=n.isub(o).iushrn(this.shift),a=r;return r.cmp(this.m)>=0?a=r.isub(this.m):r.cmpn(0)<0&&(a=r.iadd(this.m)),a._forceRed(this)},k.prototype.invm=function(e){return this.imod(e._invmp(this.m).mul(this.r2))._forceRed(this)}}(e=n.nmd(e),this)},79367:function(e,t){var n,o;void 0===(o="function"==typeof(n=function(e,t){"use strict";var n,o,r="function"==typeof Map?new Map:(n=[],o=[],{has:function(e){return n.indexOf(e)>-1},get:function(e){return o[n.indexOf(e)]},set:function(e,t){-1===n.indexOf(e)&&(n.push(e),o.push(t))},delete:function(e){var t=n.indexOf(e);t>-1&&(n.splice(t,1),o.splice(t,1))}}),i=function(e){return new Event(e,{bubbles:!0})};try{new Event("test")}catch(e){i=function(e){var t=document.createEvent("Event");return t.initEvent(e,!0,!1),t}}function a(e){if(e&&e.nodeName&&"TEXTAREA"===e.nodeName&&!r.has(e)){var t=null,n=null,o=null,a=function(){e.clientWidth!==n&&d()},s=function(t){window.removeEventListener("resize",a,!1),e.removeEventListener("input",d,!1),e.removeEventListener("keyup",d,!1),e.removeEventListener("autosize:destroy",s,!1),e.removeEventListener("autosize:update",d,!1),Object.keys(t).forEach((function(n){e.style[n]=t[n]})),r.delete(e)}.bind(e,{height:e.style.height,resize:e.style.resize,overflowY:e.style.overflowY,overflowX:e.style.overflowX,wordWrap:e.style.wordWrap});e.addEventListener("autosize:destroy",s,!1),"onpropertychange"in e&&"oninput"in e&&e.addEventListener("keyup",d,!1),window.addEventListener("resize",a,!1),e.addEventListener("input",d,!1),e.addEventListener("autosize:update",d,!1),e.style.overflowX="hidden",e.style.wordWrap="break-word",r.set(e,{destroy:s,update:d}),"vertical"===(u=window.getComputedStyle(e,null)).resize?e.style.resize="none":"both"===u.resize&&(e.style.resize="horizontal"),t="content-box"===u.boxSizing?-(parseFloat(u.paddingTop)+parseFloat(u.paddingBottom)):parseFloat(u.borderTopWidth)+parseFloat(u.borderBottomWidth),isNaN(t)&&(t=0),d()}var u;function c(t){var n=e.style.width;e.style.width="0px",e.offsetWidth,e.style.width=n,e.style.overflowY=t}function l(){if(0!==e.scrollHeight){var o=function(e){for(var t=[];e&&e.parentNode&&e.parentNode instanceof Element;)e.parentNode.scrollTop&&t.push({node:e.parentNode,scrollTop:e.parentNode.scrollTop}),e=e.parentNode;return t}(e),r=document.documentElement&&document.documentElement.scrollTop;e.style.height="",e.style.height=e.scrollHeight+t+"px",n=e.clientWidth,o.forEach((function(e){e.node.scrollTop=e.scrollTop})),r&&(document.documentElement.scrollTop=r)}}function d(){l();var t=Math.round(parseFloat(e.style.height)),n=window.getComputedStyle(e,null),r="content-box"===n.boxSizing?Math.round(parseFloat(n.height)):e.offsetHeight;if(r{"use strict";var o=n(2190);e.exports=function(){return o(["BigInt64Array","BigUint64Array","Float32Array","Float64Array","Int16Array","Int32Array","Int8Array","Uint16Array","Uint32Array","Uint8Array","Uint8ClampedArray"],(function(e){return"function"==typeof n.g[e]}))}},79456:(e,t,n)=>{"use strict";var o=n(67294),r=n(73935);function i(e,t){for(var n=0;n=0;l--){var d=r[l];"."===d?p(r,l):".."===d?(p(r,l),c++):c&&(p(r,l),c--)}if(!s)for(;c--;c)r.unshift("..");!s||""===r[0]||r[0]&&h(r[0])||r.unshift("");var f=r.join("/");return n&&"/"!==f.substr(-1)&&(f+="/"),f}(r.pathname,o.pathname)):r.pathname=o.pathname:r.pathname||(r.pathname="/"),r}function w(){var e=null,t=[];return{setPrompt:function(t){return e=t,function(){e===t&&(e=null)}},confirmTransitionTo:function(t,n,o,r){if(null!=e){var i="function"==typeof e?e(t,n):e;"string"==typeof i?"function"==typeof o?o(i,r):r(!0):r(!1!==i)}else r(!0)},appendListener:function(e){var n=!0;function o(){n&&e.apply(void 0,arguments)}return t.push(o),function(){n=!1,t=t.filter((function(e){return e!==o}))}},notifyListeners:function(){for(var e=arguments.length,n=new Array(e),o=0;o=0||(r[n]=e[n]);return r}n(59864);var N=n(8679),L=n.n(N),P=function(e){var t=I();return t.displayName="Router-History",t}(),U=function(e){var t=I();return t.displayName="Router",t}(),j=function(e){function t(t){var n;return(n=e.call(this,t)||this).state={location:t.history.location},n._isMounted=!1,n._pendingLocation=null,t.staticContext||(n.unlisten=t.history.listen((function(e){n._isMounted?n.setState({location:e}):n._pendingLocation=e}))),n}u(t,e),t.computeRootMatch=function(e){return{path:"/",url:"/",params:{},isExact:"/"===e}};var n=t.prototype;return n.componentDidMount=function(){this._isMounted=!0,this._pendingLocation&&this.setState({location:this._pendingLocation})},n.componentWillUnmount=function(){this.unlisten&&this.unlisten()},n.render=function(){return o.createElement(U.Provider,{value:{history:this.props.history,location:this.state.location,match:t.computeRootMatch(this.state.location.pathname),staticContext:this.props.staticContext}},o.createElement(P.Provider,{children:this.props.children||null,value:this.props.history}))},t}(o.Component);o.Component;var q=function(e){function t(){return e.apply(this,arguments)||this}u(t,e);var n=t.prototype;return n.componentDidMount=function(){this.props.onMount&&this.props.onMount.call(this,this)},n.componentDidUpdate=function(e){this.props.onUpdate&&this.props.onUpdate.call(this,this,e)},n.componentWillUnmount=function(){this.props.onUnmount&&this.props.onUnmount.call(this,this)},n.render=function(){return null},t}(o.Component),z={},K=0;function G(e,t){return void 0===e&&(e="/"),void 0===t&&(t={}),"/"===e?e:function(e){if(z[e])return z[e];var t=O().compile(e);return K<1e4&&(z[e]=t,K++),t}(e)(t,{pretty:!0})}function $(e){var t=e.computedMatch,n=e.to,r=e.push,i=void 0!==r&&r;return o.createElement(U.Consumer,null,(function(e){e||m(!1);var r=e.history,a=e.staticContext,s=i?r.push:r.replace,u=v(t?"string"==typeof n?G(n,t.params):d({},n,{pathname:G(n.pathname,t.params)}):n);return a?(s(u),null):o.createElement(q,{onMount:function(){s(u)},onUpdate:function(e,t){var n,o,r=v(t.to);n=r,o=d({},u,{key:r.key}),n.pathname===o.pathname&&n.search===o.search&&n.hash===o.hash&&n.key===o.key&&g(n.state,o.state)||s(u)},to:n})}))}var H={},V=0;function W(e,t){void 0===t&&(t={}),("string"==typeof t||Array.isArray(t))&&(t={path:t});var n=t,o=n.path,r=n.exact,i=void 0!==r&&r,a=n.strict,s=void 0!==a&&a,u=n.sensitive,c=void 0!==u&&u;return[].concat(o).reduce((function(t,n){if(!n&&""!==n)return null;if(t)return t;var o=function(e,t){var n=""+t.end+t.strict+t.sensitive,o=H[n]||(H[n]={});if(o[e])return o[e];var r=[],i={regexp:O()(e,r,t),keys:r};return V<1e4&&(o[e]=i,V++),i}(n,{end:i,strict:s,sensitive:c}),r=o.regexp,a=o.keys,u=r.exec(e);if(!u)return null;var l=u[0],d=u.slice(1),h=e===l;return i&&!h?null:{path:n,url:"/"===n&&""===l?"/":l,isExact:h,params:a.reduce((function(e,t,n){return e[t.name]=d[n],e}),{})}}),null)}var Y=function(e){function t(){return e.apply(this,arguments)||this}return u(t,e),t.prototype.render=function(){var e=this;return o.createElement(U.Consumer,null,(function(t){t||m(!1);var n=e.props.location||t.location,r=d({},t,{location:n,match:e.props.computedMatch?e.props.computedMatch:e.props.path?W(n.pathname,e.props):t.match}),i=e.props,a=i.children,s=i.component,u=i.render;return Array.isArray(a)&&0===a.length&&(a=null),o.createElement(U.Provider,{value:r},r.match?a?"function"==typeof a?a(r):a:s?o.createElement(s,r):u?u(r):null:"function"==typeof a?a(r):null)}))},t}(o.Component);o.Component;var Z=function(e){function t(){return e.apply(this,arguments)||this}return u(t,e),t.prototype.render=function(){var e=this;return o.createElement(U.Consumer,null,(function(t){t||m(!1);var n,r,i=e.props.location||t.location;return o.Children.forEach(e.props.children,(function(e){if(null==r&&o.isValidElement(e)){n=e;var a=e.props.path||e.props.from;r=a?W(i.pathname,d({},e.props,{path:a})):t.match}})),r?o.cloneElement(n,{location:i,computedMatch:r}):null}))},t}(o.Component);o.useContext;var X=function(e){function t(){for(var t,n=arguments.length,o=new Array(n),r=0;r=0||(r[n]=e[n]);return r}(e,["sitekey","onChange","theme","type","tabindex","onExpired","onErrored","size","stoken","grecaptcha","badge","hl"]));return o.createElement("div",de({},t,{ref:this.handleRecaptchaRef}))},r}(o.Component);function fe(){return(fe=Object.assign||function(e){for(var t=1;t-1&&t[n].parentNode&&t[n].parentNode.removeChild(t[n]);var o=_e[e];o&&(delete o.observers[this.asyncScriptLoaderGetScriptLoaderID()],!0===me.removeOnUnmount&&delete _e[e])},a.render=function(){var t=me.globalName,n=this.props,r=(n.asyncScriptOnLoad,n.forwardedRef),i=function(e,t){if(null==e)return{};var n,o,r={},i=Object.keys(e);for(o=0;o=0||(r[n]=e[n]);return r}(n,["asyncScriptOnLoad","forwardedRef"]);return t&&"undefined"!=typeof window&&(i[t]=void 0!==window[t]?window[t]:void 0),i.ref=r,(0,o.createElement)(e,i)},i}(o.Component),r=(0,o.forwardRef)((function(e,t){return(0,o.createElement)(n,fe({},e,{forwardedRef:t}))}));return r.displayName="AsyncScriptLoader("+t+")",r.propTypes={asyncScriptOnLoad:l().func},L()(r,e)})(pe);var ve=n(8743),we=n(17187),Ee=n.n(we);const ke=new(n(65203).Dispatcher);function De(e){return(De="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function Se(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function xe(e,t){for(var n=0;n600&&(i=Math.floor(i*(600/a)),a=600),i>800&&(a=Math.floor(a*(800/i)),i=800);var s=document.createElement("canvas");s.width=i,s.height=a,s.getContext("2d").drawImage(e,0,0,i,a),s.toBlob((function(e){r({thumbnail:e,info:{w:i,h:a,mimetype:e.type,size:e.size}})}),o)}))}const Ge=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&Ne(e,t)}(c,e);var t,n,o,r,i,a,s,u=(a=c,s=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,t=Pe(a);if(s){var n=Pe(this).constructor;e=Reflect.construct(t,arguments,n)}else e=t.apply(this,arguments);return Le(this,e)});function c(e){var t;return function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,c),(t=u.call(this)).matrixClient=e,t.roomIdToInput=new Map,t}return t=c,(n=[{key:"cleanEmptyEntry",value:function(e){var t=this.getInput(e);void 0===t.attachment&&(void 0===t.message||""===t.message)&&this.roomIdToInput.delete(e)}},{key:"getInput",value:function(e){return this.roomIdToInput.get(e)||{}}},{key:"setMessage",value:function(e,t){var n=this.getInput(e);n.message=t,this.roomIdToInput.set(e,n),""===t&&this.cleanEmptyEntry(e)}},{key:"getMessage",value:function(e){var t=this.getInput(e);return void 0===t.message?"":t.message}},{key:"setAttachment",value:function(e,t){var n=this.getInput(e);n.attachment={file:t},this.roomIdToInput.set(e,n)}},{key:"getAttachment",value:function(e){var t=this.getInput(e);return void 0===t.attachment?null:t.attachment.file}},{key:"cancelAttachment",value:function(e){var t=this.getInput(e);if(void 0!==t.attachment){var n=t.attachment.uploadingPromise;n&&(this.matrixClient.cancelUpload(n),delete t.attachment.uploadingPromise),t.message?(delete t.attachment,delete t.isSending,this.roomIdToInput.set(e,t)):this.roomIdToInput.delete(e),this.emit(se.events.roomsInput.ATTACHMENT_CANCELED,e)}}},{key:"isSending",value:function(e){var t;return(null===(t=this.roomIdToInput.get(e))||void 0===t?void 0:t.isSending)||!1}},{key:"sendInput",value:(i=je(regeneratorRuntime.mark((function e(t){var n,o;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if((n=this.getInput(t)).isSending=!0,this.roomIdToInput.set(t,n),!n.attachment){e.next=6;break}return e.next=6,this.sendFile(t,n.attachment.file);case 6:""!==this.getMessage(t).trim()&&(o={body:n.message,msgtype:"m.text"},this.matrixClient.sendMessage(t,o)),this.isSending(t)&&this.roomIdToInput.delete(t),this.emit(se.events.roomsInput.MESSAGE_SENT,t);case 9:case"end":return e.stop()}}),e,this)}))),function(e){return i.apply(this,arguments)})},{key:"sendFile",value:(r=je(regeneratorRuntime.mark((function e(t,n){var o,r,i,a,s,u,c,l,d=this;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(o=n.type.slice(0,n.type.indexOf("/")),r={mimetype:n.type,size:n.size},i={info:r},a=null,"image"!==o){e.next=14;break}return e.next=7,qe(n);case 7:s=e.sent,r.w=s.w,r.h=s.h,i.msgtype="m.image",i.body=n.name||"Image",e.next=40;break;case 14:if("video"!==o){e.next=39;break}return i.msgtype="m.video",i.body=n.name||"Video",e.prev=17,e.next=20,ze(n);case 20:return u=e.sent,r.w=u.videoWidth,r.h=u.videoHeight,e.next=25,Ke(u,u.videoWidth,u.videoHeight,"image/jpeg");case 25:return c=e.sent,e.next=28,this.uploadFile(t,c.thumbnail);case 28:l=e.sent,r.thumbnail_info=c.info,this.matrixClient.isRoomEncrypted(t)?r.thumbnail_file=l.file:r.thumbnail_url=l.url,e.next=37;break;case 33:return e.prev=33,e.t0=e.catch(17),this.emit(se.events.roomsInput.FILE_UPLOAD_CANCELED,t),e.abrupt("return");case 37:e.next=40;break;case 39:"audio"===o?(i.msgtype="m.audio",i.body=n.name||"Audio"):(i.msgtype="m.file",i.body=n.name||"File");case 40:return e.prev=40,e.next=43,this.uploadFile(t,n,(function(e){d.emit(se.events.roomsInput.UPLOAD_PROGRESS_CHANGES,t,e)}));case 43:a=e.sent,this.emit(se.events.roomsInput.FILE_UPLOADED,t),e.next=51;break;case 47:return e.prev=47,e.t1=e.catch(40),this.emit(se.events.roomsInput.FILE_UPLOAD_CANCELED,t),e.abrupt("return");case 51:if(!this.matrixClient.isRoomEncrypted(t)){e.next=57;break}return i.file=a.file,e.next=55,this.matrixClient.sendMessage(t,i);case 55:e.next=60;break;case 57:return i.url=a.url,e.next=60,this.matrixClient.sendMessage(t,i);case 60:case"end":return e.stop()}}),e,this,[[17,33],[40,47]])}))),function(e,t){return r.apply(this,arguments)})},{key:"uploadFile",value:(o=je(regeneratorRuntime.mark((function e(t,n,o){var r,i,a,s,u,c,l,d;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(r=this.matrixClient.isRoomEncrypted(t),i=null,a=null,!r){e.next=16;break}return e.next=6,n.arrayBuffer();case 6:if(s=e.sent,void 0!==this.getInput(t).attachment){e.next=9;break}throw new Error("Attachment canceled");case 9:return e.next=11,Me.encryptAttachment(s);case 11:if(u=e.sent,void 0!==this.getInput(t).attachment){e.next=14;break}throw new Error("Attachment canceled");case 14:i=u.info,a=new Blob([u.data]);case 16:return c=this.matrixClient.uploadContent(r?a:n,{includeFilename:!r,progressHandler:o}),(l=this.getInput(t)).attachment.uploadingPromise=c,this.roomIdToInput.set(t,l),e.next=22,c;case 22:if(d=e.sent,delete l.attachment.uploadingPromise,this.roomIdToInput.set(t,l),!r){e.next=29;break}return i.url=d,n.type&&(i.mimetype=n.type),e.abrupt("return",{file:i});case 29:return e.abrupt("return",{url:d});case 30:case"end":return e.stop()}}),e,this)}))),function(e,t,n){return o.apply(this,arguments)})}])&&Be(t.prototype,n),c}(Ee());function $e(e){return($e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function He(e,t,n,o,r,i,a){try{var s=e[i](a),u=s.value}catch(e){return void n(e)}s.done?t(u):Promise.resolve(u).then(o,r)}function Ve(e){return function(){var t=this,n=arguments;return new Promise((function(o,r){var i=e.apply(t,n);function a(e){He(i,o,r,a,s,"next",e)}function s(e){He(i,o,r,a,s,"throw",e)}a(void 0)}))}}function We(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function Ye(e,t){for(var n=0;n=0;o-=1)return e.timeline[o].getId()!==n;return!0}function ct(e,t,n,o,r,i,a){try{var s=e[i](a),u=s.value}catch(e){return void n(e)}s.done?t(u):Promise.resolve(u).then(o,r)}function lt(e){return function(){var t=this,n=arguments;return new Promise((function(o,r){var i=e.apply(t,n);function a(e){ct(i,o,r,a,s,"next",e)}function s(e){ct(i,o,r,a,s,"throw",e)}a(void 0)}))}}function dt(){return(dt=lt(regeneratorRuntime.mark((function e(t,n,o){var r,i,a,s,u;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return a=null,e.prev=1,e.next=4,ot(n);case 4:a=e.sent,e.next=10;break;case 7:e.prev=7,e.t0=e.catch(1),a="https://".concat(n);case 10:if(void 0!==a){e.next=12;break}throw new Error("Homeserver not found");case 12:return s=ve.createClient({baseUrl:a}),e.next=15,s.login("m.login.password",{user:"@".concat(t,":").concat(n),password:o,initial_device_display_name:se.DEVICE_DISPLAY_NAME});case 15:u=e.sent,localStorage.setItem(se.secretKey.ACCESS_TOKEN,u.access_token),localStorage.setItem(se.secretKey.DEVICE_ID,u.device_id),localStorage.setItem(se.secretKey.USER_ID,u.user_id),localStorage.setItem(se.secretKey.BASE_URL,(null==u||null===(r=u.well_known)||void 0===r||null===(i=r["m.homeserver"])||void 0===i?void 0:i.base_url)||a);case 20:case"end":return e.stop()}}),e,null,[[1,7]])})))).apply(this,arguments)}function ht(e,t){return pt.apply(this,arguments)}function pt(){return(pt=lt(regeneratorRuntime.mark((function e(t,n){var o,r;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.prev=0,e.next=3,fetch("".concat(t,"/_matrix/client/r0/register"),{method:"POST",body:JSON.stringify(n),headers:{"Content-Type":"application/json; charset=utf-8"},credentials:"same-origin"});case 3:return o=e.sent,e.next=6,o.json();case 6:return r=e.sent,e.abrupt("return",r);case 10:throw e.prev=10,e.t0=e.catch(0),new Error(e.t0);case 13:case"end":return e.stop()}}),e,null,[[0,10]])})))).apply(this,arguments)}function ft(e,t){return gt.apply(this,arguments)}function gt(){return(gt=lt(regeneratorRuntime.mark((function e(t,n){var o,r;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.prev=0,e.next=3,fetch("".concat(t,"/_matrix/client/r0/register/email/requestToken "),{method:"POST",body:JSON.stringify(n),headers:{"Content-Type":"application/json; charset=utf-8"},credentials:"same-origin"});case 3:return o=e.sent,e.next=6,o.json();case 6:return r=e.sent,e.abrupt("return",r);case 10:throw e.prev=10,e.t0=e.catch(0),new Error(e.t0);case 13:case"end":return e.stop()}}),e,null,[[0,10]])})))).apply(this,arguments)}var mt=null,_t=null,Ft=null;function yt(){return(yt=lt(regeneratorRuntime.mark((function e(t,n,o,r,i,a,s){var u,c,l,d,h,p;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,ot(n);case 2:if(void 0!==(u=e.sent)){e.next=5;break}throw new Error("Homeserver not found");case 5:return c=ve.createClient({baseUrl:u}),e.next=8,c.isUsernameAvailable(t);case 8:if(e.sent){e.next=11;break}throw new Error("Username not available");case 11:if("string"!=typeof i){e.next=16;break}return e.next=14,ht(u,{auth:{type:"m.login.recaptcha",session:mt,response:i}});case 14:e.next=30;break;case 16:if(!0!==a){e.next=21;break}return e.next=19,ht(u,{auth:{type:"m.login.terms",session:mt}});case 19:e.next=30;break;case 21:if(!0===s){e.next=30;break}return mt=null,_t=c.generateClientSecret(),e.next=26,ft(u,{email:r,client_secret:_t,send_attempt:1});case 26:if("string"!=typeof(l=e.sent).error){e.next=29;break}throw new Error(l.error);case 29:Ft=l.sid;case 30:return e.next=32,ht(u,{auth:{session:null!==mt?mt:void 0}});case 32:if(d=e.sent,mt=d.session,void 0!==d.completed&&0!==d.completed.length){e.next=36;break}return e.abrupt("return",{type:"recaptcha",public_key:d.params["m.login.recaptcha"].public_key});case 36:if("m.login.recaptcha"!==d.completed.find((function(e){return"m.login.recaptcha"===e}))||d.completed.find((function(e){return"m.login.terms"===e}))){e.next=38;break}return e.abrupt("return",{type:"terms",en:d.params["m.login.terms"].policies.privacy_policy.en});case 38:if(!s&&"m.login.terms"!==d.completed.find((function(e){return"m.login.terms"===e}))){e.next=50;break}return h={client_secret:_t,sid:Ft},e.next=42,ht(u,{auth:{session:mt,type:"m.login.email.identity",threepidCreds:h,threepid_creds:h},username:t,password:o});case 42:if("M_UNAUTHORIZED"!==(p=e.sent).errcode){e.next=45;break}return e.abrupt("return",{type:"email"});case 45:return localStorage.setItem(se.secretKey.ACCESS_TOKEN,p.access_token),localStorage.setItem(se.secretKey.DEVICE_ID,p.device_id),localStorage.setItem(se.secretKey.USER_ID,p.user_id),localStorage.setItem(se.secretKey.BASE_URL,u),e.abrupt("return",{type:"done"});case 50:return e.abrupt("return",{});case 51:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function bt(e){var t=e.id,n=e.className,r=e.variant,i=e.children,a=""!==n?"".concat(n," "):"";return"h1"===r?o.createElement("h1",{id:""===t?void 0:t,className:"".concat(a,"text text-h1")},i):"h2"===r?o.createElement("h2",{id:""===t?void 0:t,className:"".concat(a,"text text-h2")},i):"s1"===r?o.createElement("h4",{id:""===t?void 0:t,className:"".concat(a,"text text-s1")},i):o.createElement("p",{id:""===t?void 0:t,className:"".concat(a,"text text-").concat(r)},i)}bt.defaultProps={id:"",className:"",variant:"b1"},bt.propTypes={id:l().string,className:l().string,variant:l().oneOf(["h1","h2","s1","b1","b2","b3"]),children:l().node.isRequired};const vt=bt;function wt(e){var t=e.color,n=e.size,r=e.src,i={WebkitMaskImage:"url(".concat(r,")"),maskImage:"url(".concat(r,")")};return null!==t&&(i.backgroundColor=t),o.createElement("span",{className:"ic-raw ic-raw-".concat(n),style:i}," ")}wt.defaultProps={color:null,size:"normal"},wt.propTypes={color:l().string,size:l().oneOf(["large","normal","small","extra-small"]),src:l().string.isRequired};const Et=wt;function kt(e){return(kt="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function Dt(e,t){for(var n=e.nativeEvent.composedPath(),o=function(e){return n[e]===document?(console.warn(Dt,"blurOnBubbling: not found selector in bubbling path"),"break"):n[e].matches(t)?(setTimeout((function(){return n[e].blur()}),50),{v:!0}):void 0},r=0;re.length)&&(t=e.length);for(var n=0,o=new Array(t);n255?Ht(u.current,"Your user ID, including the hostname, can't be more than 255 characters long."):p():Ht(h.current,Kt):Ht(d.current,qt):Ht(l.current,jt):Ht(u.current,Lt)};return o.createElement(o.Fragment,null,"loading"===(null==a?void 0:a.type)&&o.createElement(Zt,{message:a.message}),"recaptcha"===(null==a?void 0:a.type)&&o.createElement(Xt,{message:"Please check the box below to proceed.",sitekey:a.sitekey,onChange:function(e){"string"==typeof e&&p(e)}}),"terms"===(null==a?void 0:a.type)&&o.createElement(Jt,{url:a.en.url,onSubmit:p}),"email"===(null==a?void 0:a.type)&&o.createElement(Qt,null,o.createElement("div",{style:{margin:"var(--sp-normal)",maxWidth:"450px"}},o.createElement(vt,{variant:"h2"},"Verify email"),o.createElement("div",{style:{margin:"var(--sp-normal) 0"}},o.createElement(vt,{variant:"b1"},"Please check your email"," ",o.createElement("b",null,"(".concat(h.current.value,")"))," ","and validate before continuing further.")),o.createElement(xt,{variant:"primary",onClick:function(){return p(void 0,void 0,!0)}},"Continue"))),o.createElement(Yt,null,o.createElement("div",{className:"auth-form__wrapper flex-v--center"},o.createElement("form",{onSubmit:f,className:"auth-form"},o.createElement(vt,{variant:"h2"},"login"===r?"Login":"Register"),o.createElement("div",{className:"username__wrapper"},o.createElement(Tt,{forwardRef:u,onChange:function(e){return Vt(e,"login"===r?Bt:Nt,Lt)},id:"auth_username",label:"Username",required:!0}),o.createElement(Tt,{forwardRef:c,id:"auth_homeserver",placeholder:"Homeserver",value:"matrix.org",required:!0})),o.createElement(Tt,{forwardRef:l,onChange:function(e){return Vt(e,"login"===r?Pt:Ut,jt)},id:"auth_password",type:"password",label:"Password",required:!0}),"register"===r&&o.createElement(o.Fragment,null,o.createElement(Tt,{forwardRef:d,onChange:function(e){return Vt(e,new RegExp("^(".concat(l.current.value,")$")),qt)},id:"auth_confirmPassword",type:"password",label:"Confirm password",required:!0}),o.createElement(Tt,{forwardRef:h,onChange:function(e){return Vt(e,zt,Kt)},id:"auth_email",type:"email",label:"Email",required:!0})),o.createElement("div",{className:"submit-btn__wrapper flex--end"},o.createElement(vt,{id:"auth_error",className:"error-message",variant:"b3"},"Error"),o.createElement(xt,{id:"auth_submit-btn",variant:"primary",type:"submit"},"login"===r?"Login":"Register")))),o.createElement("div",{className:"flex--center"},o.createElement(vt,{variant:"b2"},"".concat("login"===r?"Don't have":"Already have"," an account?"),o.createElement(oe,{to:"login"===r?"/register":"/login"},"login"===r?" Register":" Login")))))}function Yt(e){var t=e.children;return o.createElement("div",{className:"auth__wrapper flex--center"},o.createElement("div",{className:"auth-card"},o.createElement("div",{className:"auth-card__interactive flex-v"},o.createElement("div",{className:"app-ident flex"},o.createElement("img",{className:"app-ident__logo noselect",src:Mt,alt:"Cinny logo"}),o.createElement("div",{className:"app-ident__text flex-v--center"},o.createElement(vt,{variant:"h2"},"Cinny"),o.createElement(vt,{variant:"b2"},"Yet another matrix client."))),t)))}function Zt(e){var t=e.message;return o.createElement(Qt,null,o.createElement(It,null),o.createElement("div",{style:{marginTop:"var(--sp-normal)"}},o.createElement(vt,{variant:"b1"},t)))}function Xt(e){var t=e.message,n=e.sitekey,r=e.onChange;return o.createElement(Qt,null,o.createElement("div",{style:{marginBottom:"var(--sp-normal)"}},o.createElement(vt,{variant:"s1"},t)),o.createElement(be,{sitekey:n,onChange:r}))}function Jt(e){var t=e.url,n=e.onSubmit;return o.createElement(Qt,null,o.createElement("form",{onSubmit:function(){return n(void 0,!0)}},o.createElement("div",{style:{margin:"var(--sp-normal)",maxWidth:"450px"}},o.createElement(vt,{variant:"h2"},"Agree with terms"),o.createElement("div",{style:{marginBottom:"var(--sp-normal)"}}),o.createElement(vt,{variant:"b1"},"In order to complete registration, you need to agree with terms and conditions."),o.createElement("div",{style:{display:"flex",alignItems:"center",margin:"var(--sp-normal) 0"}},o.createElement("input",{id:"termsCheckbox",type:"checkbox",required:!0}),o.createElement(vt,{variant:"b1"},"I accept ",o.createElement("a",{style:{cursor:"pointer"},href:t,rel:"noreferrer",target:"_blank"},"Terms and Conditions"))),o.createElement(xt,{id:"termsBtn",type:"submit",variant:"primary"},"Submit"))))}function Qt(e){var t=e.children;return o.createElement("div",{className:"process-wrapper"},t)}Wt.propTypes={type:l().string.isRequired},Yt.propTypes={children:l().node.isRequired},Zt.propTypes={message:l().string.isRequired},Xt.propTypes={message:l().string.isRequired,sitekey:l().string.isRequired,onChange:l().func.isRequired},Jt.propTypes={url:l().string.isRequired,onSubmit:l().func.isRequired},Qt.propTypes={children:l().node.isRequired};const en=Wt;function tn(e){return(tn="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function nn(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function on(e,t){for(var n=0;n=0?e.ownerDocument.body:En(e)&&An(e)?e:Mn(In(e))}function On(e,t){var n;void 0===t&&(t=[]);var o=Mn(e),r=o===(null==(n=e.ownerDocument)?void 0:n.body),i=bn(o),a=r?[i].concat(i.visualViewport||[],An(o)?o:[]):o,s=t.concat(a);return r?s:s.concat(On(In(a)))}function Bn(e){return["table","td","th"].indexOf(Dn(e))>=0}function Nn(e){return En(e)&&"fixed"!==Cn(e).position?e.offsetParent:null}function Ln(e){for(var t=bn(e),n=Nn(e);n&&Bn(n)&&"static"===Cn(n).position;)n=Nn(n);return n&&("html"===Dn(n)||"body"===Dn(n)&&"static"===Cn(n).position)?t:n||function(e){var t=-1!==navigator.userAgent.toLowerCase().indexOf("firefox");if(-1!==navigator.userAgent.indexOf("Trident")&&En(e)&&"fixed"===Cn(e).position)return null;for(var n=In(e);En(n)&&["html","body"].indexOf(Dn(n))<0;){var o=Cn(n);if("none"!==o.transform||"none"!==o.perspective||"paint"===o.contain||-1!==["transform","perspective"].indexOf(o.willChange)||t&&"filter"===o.willChange||t&&o.filter&&"none"!==o.filter)return n;n=n.parentNode}return null}(e)||t}var Pn="top",Un="bottom",jn="right",qn="left",zn="auto",Kn=[Pn,Un,jn,qn],Gn="start",$n="end",Hn="viewport",Vn="popper",Wn=Kn.reduce((function(e,t){return e.concat([t+"-"+Gn,t+"-"+$n])}),[]),Yn=[].concat(Kn,[zn]).reduce((function(e,t){return e.concat([t,t+"-"+Gn,t+"-"+$n])}),[]),Zn=["beforeRead","read","afterRead","beforeMain","main","afterMain","beforeWrite","write","afterWrite"];function Xn(e){var t=new Map,n=new Set,o=[];function r(e){n.add(e.name),[].concat(e.requires||[],e.requiresIfExists||[]).forEach((function(e){if(!n.has(e)){var o=t.get(e);o&&r(o)}})),o.push(e)}return e.forEach((function(e){t.set(e.name,e)})),e.forEach((function(e){n.has(e.name)||r(e)})),o}var Jn={placement:"bottom",modifiers:[],strategy:"absolute"};function Qn(){for(var e=arguments.length,t=new Array(e),n=0;n=0?"x":"y"}function ao(e){var t,n=e.reference,o=e.element,r=e.placement,i=r?oo(r):null,a=r?ro(r):null,s=n.x+n.width/2-o.width/2,u=n.y+n.height/2-o.height/2;switch(i){case Pn:t={x:s,y:n.y-o.height};break;case Un:t={x:s,y:n.y+n.height};break;case jn:t={x:n.x+n.width,y:u};break;case qn:t={x:n.x-o.width,y:u};break;default:t={x:n.x,y:n.y}}var c=i?io(i):null;if(null!=c){var l="y"===c?"height":"width";switch(a){case Gn:t[c]=t[c]-(n[l]/2-o[l]/2);break;case $n:t[c]=t[c]+(n[l]/2-o[l]/2)}}return t}const so={name:"popperOffsets",enabled:!0,phase:"read",fn:function(e){var t=e.state,n=e.name;t.modifiersData[n]=ao({reference:t.rects.reference,element:t.rects.popper,strategy:"absolute",placement:t.placement})},data:{}};var uo=Math.max,co=Math.min,lo=Math.round,ho={top:"auto",right:"auto",bottom:"auto",left:"auto"};function po(e){var t,n=e.popper,o=e.popperRect,r=e.placement,i=e.offsets,a=e.position,s=e.gpuAcceleration,u=e.adaptive,c=e.roundOffsets,l=!0===c?function(e){var t=e.x,n=e.y,o=window.devicePixelRatio||1;return{x:lo(lo(t*o)/o)||0,y:lo(lo(n*o)/o)||0}}(i):"function"==typeof c?c(i):i,d=l.x,h=void 0===d?0:d,p=l.y,f=void 0===p?0:p,g=i.hasOwnProperty("x"),m=i.hasOwnProperty("y"),_=qn,F=Pn,y=window;if(u){var b=Ln(n),v="clientHeight",w="clientWidth";b===bn(n)&&"static"!==Cn(b=Sn(n)).position&&(v="scrollHeight",w="scrollWidth"),b=b,r===Pn&&(F=Un,f-=b[v]-o.height,f*=s?1:-1),r===qn&&(_=jn,h-=b[w]-o.width,h*=s?1:-1)}var E,k=Object.assign({position:a},u&&ho);return s?Object.assign({},k,((E={})[F]=m?"0":"",E[_]=g?"0":"",E.transform=(y.devicePixelRatio||1)<2?"translate("+h+"px, "+f+"px)":"translate3d("+h+"px, "+f+"px, 0)",E)):Object.assign({},k,((t={})[F]=m?f+"px":"",t[_]=g?h+"px":"",t.transform="",t))}const fo={name:"applyStyles",enabled:!0,phase:"write",fn:function(e){var t=e.state;Object.keys(t.elements).forEach((function(e){var n=t.styles[e]||{},o=t.attributes[e]||{},r=t.elements[e];En(r)&&Dn(r)&&(Object.assign(r.style,n),Object.keys(o).forEach((function(e){var t=o[e];!1===t?r.removeAttribute(e):r.setAttribute(e,!0===t?"":t)})))}))},effect:function(e){var t=e.state,n={popper:{position:t.options.strategy,left:"0",top:"0",margin:"0"},arrow:{position:"absolute"},reference:{}};return Object.assign(t.elements.popper.style,n.popper),t.styles=n,t.elements.arrow&&Object.assign(t.elements.arrow.style,n.arrow),function(){Object.keys(t.elements).forEach((function(e){var o=t.elements[e],r=t.attributes[e]||{},i=Object.keys(t.styles.hasOwnProperty(e)?t.styles[e]:n[e]).reduce((function(e,t){return e[t]="",e}),{});En(o)&&Dn(o)&&(Object.assign(o.style,i),Object.keys(r).forEach((function(e){o.removeAttribute(e)})))}))}},requires:["computeStyles"]};var go={left:"right",right:"left",bottom:"top",top:"bottom"};function mo(e){return e.replace(/left|right|bottom|top/g,(function(e){return go[e]}))}var _o={start:"end",end:"start"};function Fo(e){return e.replace(/start|end/g,(function(e){return _o[e]}))}function yo(e,t){var n=t.getRootNode&&t.getRootNode();if(e.contains(t))return!0;if(n&&kn(n)){var o=t;do{if(o&&e.isSameNode(o))return!0;o=o.parentNode||o.host}while(o)}return!1}function bo(e){return Object.assign({},e,{left:e.x,top:e.y,right:e.x+e.width,bottom:e.y+e.height})}function vo(e,t){return t===Hn?bo(function(e){var t=bn(e),n=Sn(e),o=t.visualViewport,r=n.clientWidth,i=n.clientHeight,a=0,s=0;return o&&(r=o.width,i=o.height,/^((?!chrome|android).)*safari/i.test(navigator.userAgent)||(a=o.offsetLeft,s=o.offsetTop)),{width:r,height:i,x:a+xn(e),y:s}}(e)):En(t)?function(e){var t=yn(e);return t.top=t.top+e.clientTop,t.left=t.left+e.clientLeft,t.bottom=t.top+e.clientHeight,t.right=t.left+e.clientWidth,t.width=e.clientWidth,t.height=e.clientHeight,t.x=t.left,t.y=t.top,t}(t):bo(function(e){var t,n=Sn(e),o=vn(e),r=null==(t=e.ownerDocument)?void 0:t.body,i=uo(n.scrollWidth,n.clientWidth,r?r.scrollWidth:0,r?r.clientWidth:0),a=uo(n.scrollHeight,n.clientHeight,r?r.scrollHeight:0,r?r.clientHeight:0),s=-o.scrollLeft+xn(e),u=-o.scrollTop;return"rtl"===Cn(r||n).direction&&(s+=uo(n.clientWidth,r?r.clientWidth:0)-i),{width:i,height:a,x:s,y:u}}(Sn(e)))}function wo(e){return Object.assign({},{top:0,right:0,bottom:0,left:0},e)}function Eo(e,t){return t.reduce((function(t,n){return t[n]=e,t}),{})}function ko(e,t){void 0===t&&(t={});var n=t,o=n.placement,r=void 0===o?e.placement:o,i=n.boundary,a=void 0===i?"clippingParents":i,s=n.rootBoundary,u=void 0===s?Hn:s,c=n.elementContext,l=void 0===c?Vn:c,d=n.altBoundary,h=void 0!==d&&d,p=n.padding,f=void 0===p?0:p,g=wo("number"!=typeof f?f:Eo(f,Kn)),m=l===Vn?"reference":Vn,_=e.elements.reference,F=e.rects.popper,y=e.elements[h?m:l],b=function(e,t,n){var o="clippingParents"===t?function(e){var t=On(In(e)),n=["absolute","fixed"].indexOf(Cn(e).position)>=0&&En(e)?Ln(e):e;return wn(n)?t.filter((function(e){return wn(e)&&yo(e,n)&&"body"!==Dn(e)})):[]}(e):[].concat(t),r=[].concat(o,[n]),i=r[0],a=r.reduce((function(t,n){var o=vo(e,n);return t.top=uo(o.top,t.top),t.right=co(o.right,t.right),t.bottom=co(o.bottom,t.bottom),t.left=uo(o.left,t.left),t}),vo(e,i));return a.width=a.right-a.left,a.height=a.bottom-a.top,a.x=a.left,a.y=a.top,a}(wn(y)?y:y.contextElement||Sn(e.elements.popper),a,u),v=yn(_),w=ao({reference:v,element:F,strategy:"absolute",placement:r}),E=bo(Object.assign({},F,w)),k=l===Vn?E:v,D={top:b.top-k.top+g.top,bottom:k.bottom-b.bottom+g.bottom,left:b.left-k.left+g.left,right:k.right-b.right+g.right},S=e.modifiersData.offset;if(l===Vn&&S){var x=S[r];Object.keys(D).forEach((function(e){var t=[jn,Un].indexOf(e)>=0?1:-1,n=[Pn,Un].indexOf(e)>=0?"y":"x";D[e]+=x[n]*t}))}return D}function Do(e,t,n){return uo(e,co(t,n))}function So(e,t,n){return void 0===n&&(n={x:0,y:0}),{top:e.top-t.height-n.y,right:e.right-t.width+n.x,bottom:e.bottom-t.height+n.y,left:e.left-t.width-n.x}}function xo(e){return[Pn,jn,Un,qn].some((function(t){return e[t]>=0}))}var Co=eo({defaultModifiers:[no,so,{name:"computeStyles",enabled:!0,phase:"beforeWrite",fn:function(e){var t=e.state,n=e.options,o=n.gpuAcceleration,r=void 0===o||o,i=n.adaptive,a=void 0===i||i,s=n.roundOffsets,u=void 0===s||s,c={placement:oo(t.placement),popper:t.elements.popper,popperRect:t.rects.popper,gpuAcceleration:r};null!=t.modifiersData.popperOffsets&&(t.styles.popper=Object.assign({},t.styles.popper,po(Object.assign({},c,{offsets:t.modifiersData.popperOffsets,position:t.options.strategy,adaptive:a,roundOffsets:u})))),null!=t.modifiersData.arrow&&(t.styles.arrow=Object.assign({},t.styles.arrow,po(Object.assign({},c,{offsets:t.modifiersData.arrow,position:"absolute",adaptive:!1,roundOffsets:u})))),t.attributes.popper=Object.assign({},t.attributes.popper,{"data-popper-placement":t.placement})},data:{}},fo,{name:"offset",enabled:!0,phase:"main",requires:["popperOffsets"],fn:function(e){var t=e.state,n=e.options,o=e.name,r=n.offset,i=void 0===r?[0,0]:r,a=Yn.reduce((function(e,n){return e[n]=function(e,t,n){var o=oo(e),r=[qn,Pn].indexOf(o)>=0?-1:1,i="function"==typeof n?n(Object.assign({},t,{placement:e})):n,a=i[0],s=i[1];return a=a||0,s=(s||0)*r,[qn,jn].indexOf(o)>=0?{x:s,y:a}:{x:a,y:s}}(n,t.rects,i),e}),{}),s=a[t.placement],u=s.x,c=s.y;null!=t.modifiersData.popperOffsets&&(t.modifiersData.popperOffsets.x+=u,t.modifiersData.popperOffsets.y+=c),t.modifiersData[o]=a}},{name:"flip",enabled:!0,phase:"main",fn:function(e){var t=e.state,n=e.options,o=e.name;if(!t.modifiersData[o]._skip){for(var r=n.mainAxis,i=void 0===r||r,a=n.altAxis,s=void 0===a||a,u=n.fallbackPlacements,c=n.padding,l=n.boundary,d=n.rootBoundary,h=n.altBoundary,p=n.flipVariations,f=void 0===p||p,g=n.allowedAutoPlacements,m=t.options.placement,_=oo(m),F=u||(_!==m&&f?function(e){if(oo(e)===zn)return[];var t=mo(e);return[Fo(e),t,Fo(t)]}(m):[mo(m)]),y=[m].concat(F).reduce((function(e,n){return e.concat(oo(n)===zn?function(e,t){void 0===t&&(t={});var n=t,o=n.placement,r=n.boundary,i=n.rootBoundary,a=n.padding,s=n.flipVariations,u=n.allowedAutoPlacements,c=void 0===u?Yn:u,l=ro(o),d=l?s?Wn:Wn.filter((function(e){return ro(e)===l})):Kn,h=d.filter((function(e){return c.indexOf(e)>=0}));0===h.length&&(h=d);var p=h.reduce((function(t,n){return t[n]=ko(e,{placement:n,boundary:r,rootBoundary:i,padding:a})[oo(n)],t}),{});return Object.keys(p).sort((function(e,t){return p[e]-p[t]}))}(t,{placement:n,boundary:l,rootBoundary:d,padding:c,flipVariations:f,allowedAutoPlacements:g}):n)}),[]),b=t.rects.reference,v=t.rects.popper,w=new Map,E=!0,k=y[0],D=0;D=0,T=A?"width":"height",R=ko(t,{placement:S,boundary:l,rootBoundary:d,altBoundary:h,padding:c}),I=A?C?jn:qn:C?Un:Pn;b[T]>v[T]&&(I=mo(I));var M=mo(I),O=[];if(i&&O.push(R[x]<=0),s&&O.push(R[I]<=0,R[M]<=0),O.every((function(e){return e}))){k=S,E=!1;break}w.set(S,O)}if(E)for(var B=function(e){var t=y.find((function(t){var n=w.get(t);if(n)return n.slice(0,e).every((function(e){return e}))}));if(t)return k=t,"break"},N=f?3:1;N>0&&"break"!==B(N);N--);t.placement!==k&&(t.modifiersData[o]._skip=!0,t.placement=k,t.reset=!0)}},requiresIfExists:["offset"],data:{_skip:!1}},{name:"preventOverflow",enabled:!0,phase:"main",fn:function(e){var t=e.state,n=e.options,o=e.name,r=n.mainAxis,i=void 0===r||r,a=n.altAxis,s=void 0!==a&&a,u=n.boundary,c=n.rootBoundary,l=n.altBoundary,d=n.padding,h=n.tether,p=void 0===h||h,f=n.tetherOffset,g=void 0===f?0:f,m=ko(t,{boundary:u,rootBoundary:c,padding:d,altBoundary:l}),_=oo(t.placement),F=ro(t.placement),y=!F,b=io(_),v="x"===b?"y":"x",w=t.modifiersData.popperOffsets,E=t.rects.reference,k=t.rects.popper,D="function"==typeof g?g(Object.assign({},t.rects,{placement:t.placement})):g,S={x:0,y:0};if(w){if(i||s){var x="y"===b?Pn:qn,C="y"===b?Un:jn,A="y"===b?"height":"width",T=w[b],R=w[b]+m[x],I=w[b]-m[C],M=p?-k[A]/2:0,O=F===Gn?E[A]:k[A],B=F===Gn?-k[A]:-E[A],N=t.elements.arrow,L=p&&N?Rn(N):{width:0,height:0},P=t.modifiersData["arrow#persistent"]?t.modifiersData["arrow#persistent"].padding:{top:0,right:0,bottom:0,left:0},U=P[x],j=P[C],q=Do(0,E[A],L[A]),z=y?E[A]/2-M-q-U-D:O-q-U-D,K=y?-E[A]/2+M+q+j+D:B+q+j+D,G=t.elements.arrow&&Ln(t.elements.arrow),$=G?"y"===b?G.clientTop||0:G.clientLeft||0:0,H=t.modifiersData.offset?t.modifiersData.offset[t.placement][b]:0,V=w[b]+z-H-$,W=w[b]+K-H;if(i){var Y=Do(p?co(R,V):R,T,p?uo(I,W):I);w[b]=Y,S[b]=Y-T}if(s){var Z="x"===b?Pn:qn,X="x"===b?Un:jn,J=w[v],Q=J+m[Z],ee=J-m[X],te=Do(p?co(Q,V):Q,J,p?uo(ee,W):ee);w[v]=te,S[v]=te-J}}t.modifiersData[o]=S}},requiresIfExists:["offset"]},{name:"arrow",enabled:!0,phase:"main",fn:function(e){var t,n=e.state,o=e.name,r=e.options,i=n.elements.arrow,a=n.modifiersData.popperOffsets,s=oo(n.placement),u=io(s),c=[qn,jn].indexOf(s)>=0?"height":"width";if(i&&a){var l=function(e,t){return wo("number"!=typeof(e="function"==typeof e?e(Object.assign({},t.rects,{placement:t.placement})):e)?e:Eo(e,Kn))}(r.padding,n),d=Rn(i),h="y"===u?Pn:qn,p="y"===u?Un:jn,f=n.rects.reference[c]+n.rects.reference[u]-a[u]-n.rects.popper[c],g=a[u]-n.rects.reference[u],m=Ln(i),_=m?"y"===u?m.clientHeight||0:m.clientWidth||0:0,F=f/2-g/2,y=l[h],b=_-d[c]-l[p],v=_/2-d[c]/2+F,w=Do(y,v,b),E=u;n.modifiersData[o]=((t={})[E]=w,t.centerOffset=w-v,t)}},effect:function(e){var t=e.state,n=e.options.element,o=void 0===n?"[data-popper-arrow]":n;null!=o&&("string"!=typeof o||(o=t.elements.popper.querySelector(o)))&&yo(t.elements.popper,o)&&(t.elements.arrow=o)},requires:["popperOffsets"],requiresIfExists:["preventOverflow"]},{name:"hide",enabled:!0,phase:"main",requiresIfExists:["preventOverflow"],fn:function(e){var t=e.state,n=e.name,o=t.rects.reference,r=t.rects.popper,i=t.modifiersData.preventOverflow,a=ko(t,{elementContext:"reference"}),s=ko(t,{altBoundary:!0}),u=So(a,o),c=So(s,r,i),l=xo(u),d=xo(c);t.modifiersData[n]={referenceClippingOffsets:u,popperEscapeOffsets:c,isReferenceHidden:l,hasPopperEscaped:d},t.attributes.popper=Object.assign({},t.attributes.popper,{"data-popper-reference-hidden":l,"data-popper-escaped":d})}}]}),Ao="tippy-content",To="tippy-arrow",Ro="tippy-svg-arrow",Io={passive:!0,capture:!0};function Mo(e,t,n){if(Array.isArray(e)){var o=e[t];return null==o?Array.isArray(n)?n[t]:n:o}return e}function Oo(e,t){var n={}.toString.call(e);return 0===n.indexOf("[object")&&n.indexOf(t+"]")>-1}function Bo(e,t){return"function"==typeof e?e.apply(void 0,t):e}function No(e,t){return 0===t?e:function(o){clearTimeout(n),n=setTimeout((function(){e(o)}),t)};var n}function Lo(e){return[].concat(e)}function Po(e,t){-1===e.indexOf(t)&&e.push(t)}function Uo(e){return[].slice.call(e)}function jo(){return document.createElement("div")}function qo(e){return["Element","Fragment"].some((function(t){return Oo(e,t)}))}function zo(e,t){e.forEach((function(e){e&&(e.style.transitionDuration=t+"ms")}))}function Ko(e,t){e.forEach((function(e){e&&e.setAttribute("data-state",t)}))}function Go(e,t,n){var o=t+"EventListener";["transitionend","webkitTransitionEnd"].forEach((function(t){e[o](t,n)}))}var $o={isTouch:!1},Ho=0;function Vo(){$o.isTouch||($o.isTouch=!0,window.performance&&document.addEventListener("mousemove",Wo))}function Wo(){var e=performance.now();e-Ho<20&&($o.isTouch=!1,document.removeEventListener("mousemove",Wo)),Ho=e}function Yo(){var e,t=document.activeElement;if((e=t)&&e._tippy&&e._tippy.reference===e){var n=t._tippy;t.blur&&!n.state.isVisible&&t.blur()}}var Zo="undefined"!=typeof window&&"undefined"!=typeof document?navigator.userAgent:"",Xo=/MSIE |Trident\//.test(Zo),Jo=Object.assign({appendTo:function(){return document.body},aria:{content:"auto",expanded:"auto"},delay:0,duration:[300,250],getReferenceClientRect:null,hideOnClick:!0,ignoreAttributes:!1,interactive:!1,interactiveBorder:2,interactiveDebounce:0,moveTransition:"",offset:[0,10],onAfterUpdate:function(){},onBeforeUpdate:function(){},onCreate:function(){},onDestroy:function(){},onHidden:function(){},onHide:function(){},onMount:function(){},onShow:function(){},onShown:function(){},onTrigger:function(){},onUntrigger:function(){},onClickOutside:function(){},placement:"top",plugins:[],popperOptions:{},render:null,showOnCreate:!1,touch:!0,trigger:"mouseenter focus",triggerTarget:null},{animateFill:!1,followCursor:!1,inlinePositioning:!1,sticky:!1},{},{allowHTML:!1,animation:"fade",arrow:!0,content:"",inertia:!1,maxWidth:350,role:"tooltip",theme:"",zIndex:9999}),Qo=Object.keys(Jo);function er(e){var t=(e.plugins||[]).reduce((function(t,n){var o=n.name,r=n.defaultValue;return o&&(t[o]=void 0!==e[o]?e[o]:r),t}),{});return Object.assign({},e,{},t)}function tr(e,t){var n=Object.assign({},t,{content:Bo(t.content,[e])},t.ignoreAttributes?{}:function(e,t){return(t?Object.keys(er(Object.assign({},Jo,{plugins:t}))):Qo).reduce((function(t,n){var o=(e.getAttribute("data-tippy-"+n)||"").trim();if(!o)return t;if("content"===n)t[n]=o;else try{t[n]=JSON.parse(o)}catch(e){t[n]=o}return t}),{})}(e,t.plugins));return n.aria=Object.assign({},Jo.aria,{},n.aria),n.aria={expanded:"auto"===n.aria.expanded?t.interactive:n.aria.expanded,content:"auto"===n.aria.content?t.interactive?null:"describedby":n.aria.content},n}function nr(e,t){e.innerHTML=t}function or(e){var t=jo();return!0===e?t.className=To:(t.className=Ro,qo(e)?t.appendChild(e):nr(t,e)),t}function rr(e,t){qo(t.content)?(nr(e,""),e.appendChild(t.content)):"function"!=typeof t.content&&(t.allowHTML?nr(e,t.content):e.textContent=t.content)}function ir(e){var t=e.firstElementChild,n=Uo(t.children);return{box:t,content:n.find((function(e){return e.classList.contains(Ao)})),arrow:n.find((function(e){return e.classList.contains(To)||e.classList.contains(Ro)})),backdrop:n.find((function(e){return e.classList.contains("tippy-backdrop")}))}}function ar(e){var t=jo(),n=jo();n.className="tippy-box",n.setAttribute("data-state","hidden"),n.setAttribute("tabindex","-1");var o=jo();function r(n,o){var r=ir(t),i=r.box,a=r.content,s=r.arrow;o.theme?i.setAttribute("data-theme",o.theme):i.removeAttribute("data-theme"),"string"==typeof o.animation?i.setAttribute("data-animation",o.animation):i.removeAttribute("data-animation"),o.inertia?i.setAttribute("data-inertia",""):i.removeAttribute("data-inertia"),i.style.maxWidth="number"==typeof o.maxWidth?o.maxWidth+"px":o.maxWidth,o.role?i.setAttribute("role",o.role):i.removeAttribute("role"),n.content===o.content&&n.allowHTML===o.allowHTML||rr(a,e.props),o.arrow?s?n.arrow!==o.arrow&&(i.removeChild(s),i.appendChild(or(o.arrow))):i.appendChild(or(o.arrow)):s&&i.removeChild(s)}return o.className=Ao,o.setAttribute("data-state","hidden"),rr(o,e.props),t.appendChild(n),n.appendChild(o),r(e.props,e.props),{popper:t,onUpdate:r}}ar.$$tippy=!0;var sr=1,ur=[],cr=[];function lr(e,t){var n,o,r,i,a,s,u,c,l,d=tr(e,Object.assign({},Jo,{},er((n=t,Object.keys(n).reduce((function(e,t){return void 0!==n[t]&&(e[t]=n[t]),e}),{}))))),h=!1,p=!1,f=!1,g=!1,m=[],_=No(W,d.interactiveDebounce),F=sr++,y=(l=d.plugins).filter((function(e,t){return l.indexOf(e)===t})),b={id:F,reference:e,popper:jo(),popperInstance:null,props:d,state:{isEnabled:!0,isVisible:!1,isDestroyed:!1,isMounted:!1,isShown:!1},plugins:y,clearDelayTimeouts:function(){clearTimeout(o),clearTimeout(r),cancelAnimationFrame(i)},setProps:function(t){if(!b.state.isDestroyed){O("onBeforeUpdate",[b,t]),H();var n=b.props,o=tr(e,Object.assign({},b.props,{},t,{ignoreAttributes:!0}));b.props=o,$(),n.interactiveDebounce!==o.interactiveDebounce&&(L(),_=No(W,o.interactiveDebounce)),n.triggerTarget&&!o.triggerTarget?Lo(n.triggerTarget).forEach((function(e){e.removeAttribute("aria-expanded")})):o.triggerTarget&&e.removeAttribute("aria-expanded"),N(),M(),E&&E(n,o),b.popperInstance&&(J(),ee().forEach((function(e){requestAnimationFrame(e._tippy.popperInstance.forceUpdate)}))),O("onAfterUpdate",[b,t])}},setContent:function(e){b.setProps({content:e})},show:function(){var e=b.state.isVisible,t=b.state.isDestroyed,n=!b.state.isEnabled,o=$o.isTouch&&!b.props.touch,r=Mo(b.props.duration,0,Jo.duration);if(!(e||t||n||o||A().hasAttribute("disabled")||(O("onShow",[b],!1),!1===b.props.onShow(b)))){if(b.state.isVisible=!0,C()&&(w.style.visibility="visible"),M(),q(),b.state.isMounted||(w.style.transition="none"),C()){var i=R();zo([i.box,i.content],0)}var a,s,c;u=function(){var e;if(b.state.isVisible&&!g){if(g=!0,w.offsetHeight,w.style.transition=b.props.moveTransition,C()&&b.props.animation){var t=R(),n=t.box,o=t.content;zo([n,o],r),Ko([n,o],"visible")}B(),N(),Po(cr,b),null==(e=b.popperInstance)||e.forceUpdate(),b.state.isMounted=!0,O("onMount",[b]),b.props.animation&&C()&&function(e,t){K(e,(function(){b.state.isShown=!0,O("onShown",[b])}))}(r)}},s=b.props.appendTo,c=A(),(a=b.props.interactive&&s===Jo.appendTo||"parent"===s?c.parentNode:Bo(s,[c])).contains(w)||a.appendChild(w),J()}},hide:function(){var e=!b.state.isVisible,t=b.state.isDestroyed,n=!b.state.isEnabled,o=Mo(b.props.duration,1,Jo.duration);if(!(e||t||n)&&(O("onHide",[b],!1),!1!==b.props.onHide(b))){if(b.state.isVisible=!1,b.state.isShown=!1,g=!1,h=!1,C()&&(w.style.visibility="hidden"),L(),z(),M(),C()){var r=R(),i=r.box,a=r.content;b.props.animation&&(zo([i,a],o),Ko([i,a],"hidden"))}B(),N(),b.props.animation?C()&&function(e,t){K(e,(function(){!b.state.isVisible&&w.parentNode&&w.parentNode.contains(w)&&t()}))}(o,b.unmount):b.unmount()}},hideWithInteractivity:function(e){T().addEventListener("mousemove",_),Po(ur,_),_(e)},enable:function(){b.state.isEnabled=!0},disable:function(){b.hide(),b.state.isEnabled=!1},unmount:function(){b.state.isVisible&&b.hide(),b.state.isMounted&&(Q(),ee().forEach((function(e){e._tippy.unmount()})),w.parentNode&&w.parentNode.removeChild(w),cr=cr.filter((function(e){return e!==b})),b.state.isMounted=!1,O("onHidden",[b]))},destroy:function(){b.state.isDestroyed||(b.clearDelayTimeouts(),b.unmount(),H(),delete e._tippy,b.state.isDestroyed=!0,O("onDestroy",[b]))}};if(!d.render)return b;var v=d.render(b),w=v.popper,E=v.onUpdate;w.setAttribute("data-tippy-root",""),w.id="tippy-"+b.id,b.popper=w,e._tippy=b,w._tippy=b;var k=y.map((function(e){return e.fn(b)})),D=e.hasAttribute("aria-expanded");return $(),N(),M(),O("onCreate",[b]),d.showOnCreate&&te(),w.addEventListener("mouseenter",(function(){b.props.interactive&&b.state.isVisible&&b.clearDelayTimeouts()})),w.addEventListener("mouseleave",(function(e){b.props.interactive&&b.props.trigger.indexOf("mouseenter")>=0&&(T().addEventListener("mousemove",_),_(e))})),b;function S(){var e=b.props.touch;return Array.isArray(e)?e:[e,0]}function x(){return"hold"===S()[0]}function C(){var e;return!!(null==(e=b.props.render)?void 0:e.$$tippy)}function A(){return c||e}function T(){var e,t,n=A().parentNode;return n?(null==(t=Lo(n)[0])||null==(e=t.ownerDocument)?void 0:e.body)?t.ownerDocument:document:document}function R(){return ir(w)}function I(e){return b.state.isMounted&&!b.state.isVisible||$o.isTouch||a&&"focus"===a.type?0:Mo(b.props.delay,e?0:1,Jo.delay)}function M(){w.style.pointerEvents=b.props.interactive&&b.state.isVisible?"":"none",w.style.zIndex=""+b.props.zIndex}function O(e,t,n){var o;void 0===n&&(n=!0),k.forEach((function(n){n[e]&&n[e].apply(void 0,t)})),n&&(o=b.props)[e].apply(o,t)}function B(){var t=b.props.aria;if(t.content){var n="aria-"+t.content,o=w.id;Lo(b.props.triggerTarget||e).forEach((function(e){var t=e.getAttribute(n);if(b.state.isVisible)e.setAttribute(n,t?t+" "+o:o);else{var r=t&&t.replace(o,"").trim();r?e.setAttribute(n,r):e.removeAttribute(n)}}))}}function N(){!D&&b.props.aria.expanded&&Lo(b.props.triggerTarget||e).forEach((function(e){b.props.interactive?e.setAttribute("aria-expanded",b.state.isVisible&&e===A()?"true":"false"):e.removeAttribute("aria-expanded")}))}function L(){T().removeEventListener("mousemove",_),ur=ur.filter((function(e){return e!==_}))}function P(e){if(!($o.isTouch&&(f||"mousedown"===e.type)||b.props.interactive&&w.contains(e.target))){if(A().contains(e.target)){if($o.isTouch)return;if(b.state.isVisible&&b.props.trigger.indexOf("click")>=0)return}else O("onClickOutside",[b,e]);!0===b.props.hideOnClick&&(b.clearDelayTimeouts(),b.hide(),p=!0,setTimeout((function(){p=!1})),b.state.isMounted||z())}}function U(){f=!0}function j(){f=!1}function q(){var e=T();e.addEventListener("mousedown",P,!0),e.addEventListener("touchend",P,Io),e.addEventListener("touchstart",j,Io),e.addEventListener("touchmove",U,Io)}function z(){var e=T();e.removeEventListener("mousedown",P,!0),e.removeEventListener("touchend",P,Io),e.removeEventListener("touchstart",j,Io),e.removeEventListener("touchmove",U,Io)}function K(e,t){var n=R().box;function o(e){e.target===n&&(Go(n,"remove",o),t())}if(0===e)return t();Go(n,"remove",s),Go(n,"add",o),s=o}function G(t,n,o){void 0===o&&(o=!1),Lo(b.props.triggerTarget||e).forEach((function(e){e.addEventListener(t,n,o),m.push({node:e,eventType:t,handler:n,options:o})}))}function $(){var e;x()&&(G("touchstart",V,{passive:!0}),G("touchend",Y,{passive:!0})),(e=b.props.trigger,e.split(/\s+/).filter(Boolean)).forEach((function(e){if("manual"!==e)switch(G(e,V),e){case"mouseenter":G("mouseleave",Y);break;case"focus":G(Xo?"focusout":"blur",Z);break;case"focusin":G("focusout",Z)}}))}function H(){m.forEach((function(e){var t=e.node,n=e.eventType,o=e.handler,r=e.options;t.removeEventListener(n,o,r)})),m=[]}function V(e){var t,n=!1;if(b.state.isEnabled&&!X(e)&&!p){var o="focus"===(null==(t=a)?void 0:t.type);a=e,c=e.currentTarget,N(),!b.state.isVisible&&Oo(e,"MouseEvent")&&ur.forEach((function(t){return t(e)})),"click"===e.type&&(b.props.trigger.indexOf("mouseenter")<0||h)&&!1!==b.props.hideOnClick&&b.state.isVisible?n=!0:te(e),"click"===e.type&&(h=!n),n&&!o&&ne(e)}}function W(e){var t=e.target,n=A().contains(t)||w.contains(t);"mousemove"===e.type&&n||function(e,t){var n=t.clientX,o=t.clientY;return e.every((function(e){var t=e.popperRect,r=e.popperState,i=e.props.interactiveBorder,a=r.placement.split("-")[0],s=r.modifiersData.offset;if(!s)return!0;var u="bottom"===a?s.top.y:0,c="top"===a?s.bottom.y:0,l="right"===a?s.left.x:0,d="left"===a?s.right.x:0,h=t.top-o+u>i,p=o-t.bottom-c>i,f=t.left-n+l>i,g=n-t.right-d>i;return h||p||f||g}))}(ee().concat(w).map((function(e){var t,n=null==(t=e._tippy.popperInstance)?void 0:t.state;return n?{popperRect:e.getBoundingClientRect(),popperState:n,props:d}:null})).filter(Boolean),e)&&(L(),ne(e))}function Y(e){X(e)||b.props.trigger.indexOf("click")>=0&&h||(b.props.interactive?b.hideWithInteractivity(e):ne(e))}function Z(e){b.props.trigger.indexOf("focusin")<0&&e.target!==A()||b.props.interactive&&e.relatedTarget&&w.contains(e.relatedTarget)||ne(e)}function X(e){return!!$o.isTouch&&x()!==e.type.indexOf("touch")>=0}function J(){Q();var t=b.props,n=t.popperOptions,o=t.placement,r=t.offset,i=t.getReferenceClientRect,a=t.moveTransition,s=C()?ir(w).arrow:null,c=i?{getBoundingClientRect:i,contextElement:i.contextElement||A()}:e,l=[{name:"offset",options:{offset:r}},{name:"preventOverflow",options:{padding:{top:2,bottom:2,left:5,right:5}}},{name:"flip",options:{padding:5}},{name:"computeStyles",options:{adaptive:!a}},{name:"$$tippy",enabled:!0,phase:"beforeWrite",requires:["computeStyles"],fn:function(e){var t=e.state;if(C()){var n=R().box;["placement","reference-hidden","escaped"].forEach((function(e){"placement"===e?n.setAttribute("data-placement",t.placement):t.attributes.popper["data-popper-"+e]?n.setAttribute("data-"+e,""):n.removeAttribute("data-"+e)})),t.attributes.popper={}}}}];C()&&s&&l.push({name:"arrow",options:{element:s,padding:3}}),l.push.apply(l,(null==n?void 0:n.modifiers)||[]),b.popperInstance=Co(c,w,Object.assign({},n,{placement:o,onFirstUpdate:u,modifiers:l}))}function Q(){b.popperInstance&&(b.popperInstance.destroy(),b.popperInstance=null)}function ee(){return Uo(w.querySelectorAll("[data-tippy-root]"))}function te(e){b.clearDelayTimeouts(),e&&O("onTrigger",[b,e]),q();var t=I(!0),n=S(),r=n[0],i=n[1];$o.isTouch&&"hold"===r&&i&&(t=i),t?o=setTimeout((function(){b.show()}),t):b.show()}function ne(e){if(b.clearDelayTimeouts(),O("onUntrigger",[b,e]),b.state.isVisible){if(!(b.props.trigger.indexOf("mouseenter")>=0&&b.props.trigger.indexOf("click")>=0&&["mouseleave","mousemove"].indexOf(e.type)>=0&&h)){var t=I(!1);t?r=setTimeout((function(){b.state.isVisible&&b.hide()}),t):i=requestAnimationFrame((function(){b.hide()}))}}else z()}}function dr(e,t){void 0===t&&(t={});var n=Jo.plugins.concat(t.plugins||[]);document.addEventListener("touchstart",Vo,Io),window.addEventListener("blur",Yo);var o,r=Object.assign({},t,{plugins:n}),i=(o=e,qo(o)?[o]:function(e){return Oo(e,"NodeList")}(o)?Uo(o):Array.isArray(o)?o:Uo(document.querySelectorAll(o))).reduce((function(e,t){var n=t&&lr(t,r);return n&&e.push(n),e}),[]);return qo(e)?i[0]:i}dr.defaultProps=Jo,dr.setDefaultProps=function(e){Object.keys(e).forEach((function(t){Jo[t]=e[t]}))},dr.currentInput=$o,Object.assign({},fo,{effect:function(e){var t=e.state,n={popper:{position:t.options.strategy,left:"0",top:"0",margin:"0"},arrow:{position:"absolute"},reference:{}};Object.assign(t.elements.popper.style,n.popper),t.styles=n,t.elements.arrow&&Object.assign(t.elements.arrow.style,n.arrow)}}),dr.setDefaultProps({render:ar});const hr=dr;function pr(e,t){if(null==e)return{};var n,o,r={},i=Object.keys(e);for(o=0;o=0||(r[n]=e[n]);return r}var fr="undefined"!=typeof window&&"undefined"!=typeof document;function gr(e,t){e&&("function"==typeof e&&e(t),{}.hasOwnProperty.call(e,"current")&&(e.current=t))}function mr(){return fr&&document.createElement("div")}function _r(e,t){if(e===t)return!0;if("object"==typeof e&&null!=e&&"object"==typeof t&&null!=t){if(Object.keys(e).length!==Object.keys(t).length)return!1;for(var n in e){if(!t.hasOwnProperty(n))return!1;if(!_r(e[n],t[n]))return!1}return!0}return!1}function Fr(e){var t=[];return e.forEach((function(e){t.find((function(t){return _r(e,t)}))||t.push(e)})),t}var yr=fr?o.useLayoutEffect:o.useEffect;function br(e,t,n){n.split(/\s+/).forEach((function(n){n&&e.classList[t](n)}))}var vr={name:"className",defaultValue:"",fn:function(e){var t=e.popper.firstElementChild,n=function(){var t;return!!(null==(t=e.props.render)?void 0:t.$$tippy)};function o(){e.props.className&&!n()||br(t,"add",e.props.className)}return{onCreate:o,onBeforeUpdate:function(){n()&&br(t,"remove",e.props.className)},onAfterUpdate:o}}};function wr(e){return function(t){var n,i,a=t.children,s=t.content,u=t.visible,c=t.singleton,l=t.render,d=t.reference,h=t.disabled,p=void 0!==h&&h,f=t.ignoreAttributes,g=void 0===f||f,m=(t.__source,t.__self,pr(t,["children","content","visible","singleton","render","reference","disabled","ignoreAttributes","__source","__self"])),_=void 0!==u,F=void 0!==c,y=(0,o.useState)(!1),b=y[0],v=y[1],w=(0,o.useState)({}),E=w[0],k=w[1],D=(0,o.useState)(),S=D[0],x=D[1],C=(n=function(){return{container:mr(),renders:1}},(i=(0,o.useRef)()).current||(i.current="function"==typeof n?n():n),i.current),A=Object.assign({ignoreAttributes:g},m,{content:C.container});_&&(A.trigger="manual",A.hideOnClick=!1),F&&(p=!0);var T=A,R=A.plugins||[];l&&(T=Object.assign({},A,{plugins:F?[].concat(R,[{fn:function(){return{onTrigger:function(e,t){var n=c.data.children.find((function(e){return e.instance.reference===t.currentTarget})).content;x(n)}}}}]):R,render:function(){return{popper:C.container}}}));var I=[d].concat(a?[a.type]:[]);return yr((function(){var t=d;d&&d.hasOwnProperty("current")&&(t=d.current);var n=e(t||C.ref||mr(),Object.assign({},T,{plugins:[vr].concat(A.plugins||[])}));return C.instance=n,p&&n.disable(),u&&n.show(),F&&c.hook({instance:n,content:s,props:T}),v(!0),function(){n.destroy(),null==c||c.cleanup(n)}}),I),yr((function(){var e,t,n,o,r;if(1!==C.renders){var i=C.instance;i.setProps((t=i.props,n=T,Object.assign({},n,{popperOptions:Object.assign({},t.popperOptions,n.popperOptions,{modifiers:Fr([].concat((null==(o=t.popperOptions)?void 0:o.modifiers)||[],(null==(r=n.popperOptions)?void 0:r.modifiers)||[]))})}))),null==(e=i.popperInstance)||e.forceUpdate(),p?i.disable():i.enable(),_&&(u?i.show():i.hide()),F&&c.hook({instance:i,content:s,props:T})}else C.renders++})),yr((function(){var e;if(l){var t=C.instance;t.setProps({popperOptions:Object.assign({},t.props.popperOptions,{modifiers:[].concat(((null==(e=t.props.popperOptions)?void 0:e.modifiers)||[]).filter((function(e){return"$$tippyReact"!==e.name})),[{name:"$$tippyReact",enabled:!0,phase:"beforeWrite",requires:["computeStyles"],fn:function(e){var t,n=e.state,o=null==(t=n.modifiersData)?void 0:t.hide;E.placement===n.placement&&E.referenceHidden===(null==o?void 0:o.isReferenceHidden)&&E.escaped===(null==o?void 0:o.hasPopperEscaped)||k({placement:n.placement,referenceHidden:null==o?void 0:o.isReferenceHidden,escaped:null==o?void 0:o.hasPopperEscaped}),n.attributes.popper={}}}])})})}}),[E.placement,E.referenceHidden,E.escaped].concat(I)),o.createElement(o.Fragment,null,a?(0,o.cloneElement)(a,{ref:function(e){C.ref=e,gr(a.ref,e)}}):null,b&&(0,r.createPortal)(l?l(function(e){var t={"data-placement":e.placement};return e.referenceHidden&&(t["data-reference-hidden"]=""),e.escaped&&(t["data-escaped"]=""),t}(E),S,C.instance):s,C.container))}}const Er=function(e,t){return(0,o.forwardRef)((function(n,r){var i=n.children,a=pr(n,["children"]);return o.createElement(e,Object.assign({},t,a),i?(0,o.cloneElement)(i,{ref:function(e){gr(r,e),gr(i.ref,e)}}):null)}))}(wr(hr));function kr(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,o=new Array(t);ne.length)&&(t=e.length);for(var n=0,o=new Array(t);ne.length)&&(t=e.length);for(var n=0,o=new Array(t);ne.length)&&(t=e.length);for(var n=0,o=new Array(t);no.toLowerCase()?1:0}function ci(e){var t=e.tabId;return o.createElement(Hr,null,o.createElement(Vr,null,o.createElement(vt,{variant:"s1"},"channels"===t?"Home":"Direct messages")),"dm"===t?o.createElement(Yr,{onClick:function(){return pn()},tooltip:"Start DM",src:Jr,size:"normal"}):o.createElement(Ir,{content:function(e){return o.createElement(o.Fragment,null,o.createElement(Mr,null,"Add channel"),o.createElement(Or,{iconSrc:ti,onClick:function(){e(),ke.dispatch({type:se.actions.navigation.OPEN_CREATE_CHANNEL})}},"Create new channel"),o.createElement(Or,{iconSrc:Pr,onClick:function(){e(),hn()}},"Add Public channel"))},render:function(e){return o.createElement(Yr,{onClick:e,tooltip:"Add channel",src:Jr,size:"normal"})}}))}function li(){return o.createElement("div",{className:"breadcrumb__wrapper"},o.createElement(Fn,{horizontal:!0,vertical:!1},o.createElement("div",null)))}function di(e,t,n,r){var i,a=Qe.matrixClient,s=null===(i=e.getAvatarFallbackMember())||void 0===i?void 0:i.getAvatarUrl(a.baseUrl,24,24,"crop");return void 0===s&&(s=null),o.createElement(Xr,{key:t,iconSrc:r?null:e.isSpaceRoom()?"invite"===e.getJoinRule()?oi:ni:"invite"===e.getJoinRule()?ei:Qr,imageSrc:r?s:null,roomId:t,unread:ut(e),onClick:function(){return ln(t)},notificationCount:e.getUnreadNotificationCount("total"),alert:0!==e.getUnreadNotificationCount("highlight"),selected:n},e.name)}function hi(e){var t=e.selectedRoomId,n=Qe.matrixClient;return ii(Qe.roomList.directs).sort(ui).map((function(e){return di(n.getRoom(e),e,t===e,!0)}))}function pi(e){var t=e.selectedRoomId,n=Qe.matrixClient,r=ii(Qe.roomList.spaces).sort(ui),i=ii(Qe.roomList.rooms).sort(ui);return o.createElement(o.Fragment,null,0!==r.length&&o.createElement(vt,{className:"cat-header",variant:"b3"},"Spaces"),r.map((function(e){return di(n.getRoom(e),e,t===e,!1)})),0!==i.length&&o.createElement(vt,{className:"cat-header",variant:"b3"},"Channels"),i.map((function(e){return di(n.getRoom(e),e,t===e,!1)})))}function fi(e){var t=e.tabId,n=ri((0,o.useState)(null),2),r=n[0],i=n[1],a=ri((0,o.useState)(),2)[1],s=function(e){return i(e)},u=function(){return a({})},c=function(){var e=Qe.roomList,t=e.spaces,n=e.rooms,o=e.directs;t.has(r)||n.has(r)||o.has(r)||ln(null)};return(0,o.useEffect)((function(){return cn.on(se.events.navigation.ROOM_SELECTED,s),Qe.roomList.on(se.events.roomList.ROOMLIST_UPDATED,u),function(){cn.removeListener(se.events.navigation.ROOM_SELECTED,s),Qe.roomList.removeListener(se.events.roomList.ROOMLIST_UPDATED,u)}}),[]),(0,o.useEffect)((function(){return Qe.roomList.on(se.events.roomList.ROOMLIST_UPDATED,c),function(){Qe.roomList.removeListener(se.events.roomList.ROOMLIST_UPDATED,c)}}),[r]),o.createElement("div",{className:"channels-container"},"channels"===t?o.createElement(pi,{selectedRoomId:r}):o.createElement(hi,{selectedRoomId:r}))}function gi(e){var t=e.tabId;return o.createElement("div",{className:"drawer"},o.createElement(ci,{tabId:t}),o.createElement("div",{className:"drawer__content-wrapper"},o.createElement(li,null),o.createElement("div",{className:"channels__wrapper"},o.createElement(Fn,{autoHide:!0},o.createElement(fi,{tabId:t})))))}ci.propTypes={tabId:l().string.isRequired},hi.defaultProps={selectedRoomId:null},hi.propTypes={selectedRoomId:l().string},pi.defaultProps={selectedRoomId:null},pi.propTypes={selectedRoomId:l().string},fi.propTypes={tabId:l().string.isRequired},gi.propTypes={tabId:l().string.isRequired};const mi=gi;function _i(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,o=new Array(t);ne.length)&&(t=e.length);for(var n=0,o=new Array(t);n0&&(t.ongoingDecryptionCount-=1),t.timeline=t.room.timeline,0===t.ongoingDecryptionCount&&t.emit(se.events.roomTimeline.EVENT))},t._listenTypingEvent=function(e,n){var o;n.roomId===t.roomId&&(n.typing?t.typingMembers.add(n.userId):t.typingMembers.delete(n.userId),t.emit(se.events.roomTimeline.TYPING_MEMBERS_UPDATED,new Set(function(e){if(Array.isArray(e))return ki(e)}(o=t.typingMembers)||function(e){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(e))return Array.from(e)}(o)||function(e,t){if(e){if("string"==typeof e)return ki(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?ki(e,t):void 0}}(o)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}())))},t._listenReciptEvent=function(e,n){if(n.roomId===t.roomId){var o=e.getContent();if(0!==t.timeline.length){var r=o[t.timeline[t.timeline.length-1].getId()];void 0!==r&&r["m.read"]&&t.emit(se.events.roomTimeline.READ_RECEIPT)}}},t.matrixClient.on("Room.timeline",t._listenRoomTimeline),t.matrixClient.on("Event.decrypted",t._listenDecryptEvent),t.matrixClient.on("RoomMember.typing",t._listenTypingEvent),t.matrixClient.on("Room.receipt",t._listenReciptEvent),window.selectedRoom=Ci(t),t.isEncryptedRoom()&&t.room.decryptAllEvents(),t}return t=a,(n=[{key:"isEncryptedRoom",value:function(){return this.matrixClient.isRoomEncrypted(this.roomId)}},{key:"isEdited",value:function(e){var t;return"m.replace"===(null===(t=e.getRelation())||void 0===t?void 0:t.rel_type)}},{key:"getRelateToId",value:function(e){var t=e.getRelation();return t&&t.event_id}},{key:"addToMap",value:function(e,t){var n=this.getRelateToId(t);return null===n?null:(void 0===e.get(n)&&e.set(n,[]),e.get(n).push(t),t)}},{key:"getEditedTimeline",value:function(){var e=this,t=new Map;return this.timeline.forEach((function(n){e.isEdited(n)&&e.addToMap(t,n)})),t}},{key:"isReaction",value:function(e){return"m.reaction"===e.getType()}},{key:"getReactionTimeline",value:function(){var e=this,t=new Map;return this.timeline.forEach((function(n){e.isReaction(n)&&e.addToMap(t,n)})),t}},{key:"paginateBack",value:function(){var e=this;this.isOngoingPagination||(this.isOngoingPagination=!0,this.matrixClient.scrollback(this.room,30).then(function(){var t,n=(t=regeneratorRuntime.mark((function t(n){return regeneratorRuntime.wrap((function(t){for(;;)switch(t.prev=t.next){case 0:if(null!==n.oldState.paginationToken){t.next=7;break}if(e.isOngoingPagination=!1,!e.isEncryptedRoom()){t.next=5;break}return t.next=5,e.room.decryptAllEvents();case 5:return e.emit(se.events.roomTimeline.PAGINATED,!1),t.abrupt("return");case 7:if(e.editedTimeline=e.getEditedTimeline(),e.reactionTimeline=e.getReactionTimeline(),e.isOngoingPagination=!1,!e.isEncryptedRoom()){t.next=13;break}return t.next=13,e.room.decryptAllEvents();case 13:e.emit(se.events.roomTimeline.PAGINATED,!0);case 14:case"end":return t.stop()}}),t)})),function(){var e=this,n=arguments;return new Promise((function(o,r){var i=t.apply(e,n);function a(e){Ei(i,o,r,a,s,"next",e)}function s(e){Ei(i,o,r,a,s,"throw",e)}a(void 0)}))});return function(e){return n.apply(this,arguments)}}()))}},{key:"removeInternalListeners",value:function(){this.matrixClient.removeListener("Room.timeline",this._listenRoomTimeline),this.matrixClient.removeListener("Event.decrypted",this._listenDecryptEvent),this.matrixClient.removeListener("RoomMember.typing",this._listenTypingEvent),this.matrixClient.removeListener("Room.receipt",this._listenReciptEvent)}}])&&Di(t.prototype,n),a}(Ee());function Ri(e,t,n,o,r,i,a){try{var s=e[i](a),u=s.value}catch(e){return void n(e)}s.done?t(u):Promise.resolve(u).then(o,r)}function Ii(e){return function(){var t=this,n=arguments;return new Promise((function(o,r){var i=e.apply(t,n);function a(e){Ri(i,o,r,a,s,"next",e)}function s(e){Ri(i,o,r,a,s,"throw",e)}a(void 0)}))}}function Mi(e,t){var n=Qe.matrixClient,o=n.getAccountData("m.direct"),r={};if(void 0!==o&&(r=o.getContent()),Object.keys(r).forEach((function(n){var o=r[n];if(n!==t){var i=o.indexOf(e);i>-1&&o.splice(i,1)}})),t){var i=r[t]||[];-1===i.indexOf(e)&&i.push(e),r[t]=i}return n.setAccountData("m.direct",r)}function Oi(e,t){var n,o;return e.getJoinedMembers().forEach((function(e){e.userId!==t&&(void 0===n||e.events.member&&e.events.member.getTs()e.length)&&(t=e.length);for(var n=0,o=new Array(t);n=4?[t[0],t[1],t[2],t[3],"".concat(t[0],".").concat(t[1]),"".concat(t[0],".").concat(t[2]),"".concat(t[0],".").concat(t[3]),"".concat(t[1],".").concat(t[0]),"".concat(t[1],".").concat(t[2]),"".concat(t[1],".").concat(t[3]),"".concat(t[2],".").concat(t[0]),"".concat(t[2],".").concat(t[1]),"".concat(t[2],".").concat(t[3]),"".concat(t[3],".").concat(t[0]),"".concat(t[3],".").concat(t[1]),"".concat(t[3],".").concat(t[2]),"".concat(t[0],".").concat(t[1],".").concat(t[2]),"".concat(t[0],".").concat(t[1],".").concat(t[3]),"".concat(t[0],".").concat(t[2],".").concat(t[1]),"".concat(t[0],".").concat(t[2],".").concat(t[3]),"".concat(t[0],".").concat(t[3],".").concat(t[1]),"".concat(t[0],".").concat(t[3],".").concat(t[2]),"".concat(t[1],".").concat(t[0],".").concat(t[2]),"".concat(t[1],".").concat(t[0],".").concat(t[3]),"".concat(t[1],".").concat(t[2],".").concat(t[0]),"".concat(t[1],".").concat(t[2],".").concat(t[3]),"".concat(t[1],".").concat(t[3],".").concat(t[0]),"".concat(t[1],".").concat(t[3],".").concat(t[2]),"".concat(t[2],".").concat(t[0],".").concat(t[1]),"".concat(t[2],".").concat(t[0],".").concat(t[3]),"".concat(t[2],".").concat(t[1],".").concat(t[0]),"".concat(t[2],".").concat(t[1],".").concat(t[3]),"".concat(t[2],".").concat(t[3],".").concat(t[0]),"".concat(t[2],".").concat(t[3],".").concat(t[1]),"".concat(t[3],".").concat(t[0],".").concat(t[1]),"".concat(t[3],".").concat(t[0],".").concat(t[2]),"".concat(t[3],".").concat(t[1],".").concat(t[0]),"".concat(t[3],".").concat(t[1],".").concat(t[2]),"".concat(t[3],".").concat(t[2],".").concat(t[0]),"".concat(t[3],".").concat(t[2],".").concat(t[1]),"".concat(t[0],".").concat(t[1],".").concat(t[2],".").concat(t[3]),"".concat(t[0],".").concat(t[1],".").concat(t[3],".").concat(t[2]),"".concat(t[0],".").concat(t[2],".").concat(t[1],".").concat(t[3]),"".concat(t[0],".").concat(t[2],".").concat(t[3],".").concat(t[1]),"".concat(t[0],".").concat(t[3],".").concat(t[1],".").concat(t[2]),"".concat(t[0],".").concat(t[3],".").concat(t[2],".").concat(t[1]),"".concat(t[1],".").concat(t[0],".").concat(t[2],".").concat(t[3]),"".concat(t[1],".").concat(t[0],".").concat(t[3],".").concat(t[2]),"".concat(t[1],".").concat(t[2],".").concat(t[0],".").concat(t[3]),"".concat(t[1],".").concat(t[2],".").concat(t[3],".").concat(t[0]),"".concat(t[1],".").concat(t[3],".").concat(t[0],".").concat(t[2]),"".concat(t[1],".").concat(t[3],".").concat(t[2],".").concat(t[0]),"".concat(t[2],".").concat(t[0],".").concat(t[1],".").concat(t[3]),"".concat(t[2],".").concat(t[0],".").concat(t[3],".").concat(t[1]),"".concat(t[2],".").concat(t[1],".").concat(t[0],".").concat(t[3]),"".concat(t[2],".").concat(t[1],".").concat(t[3],".").concat(t[0]),"".concat(t[2],".").concat(t[3],".").concat(t[0],".").concat(t[1]),"".concat(t[2],".").concat(t[3],".").concat(t[1],".").concat(t[0]),"".concat(t[3],".").concat(t[0],".").concat(t[1],".").concat(t[2]),"".concat(t[3],".").concat(t[0],".").concat(t[2],".").concat(t[1]),"".concat(t[3],".").concat(t[1],".").concat(t[0],".").concat(t[2]),"".concat(t[3],".").concat(t[1],".").concat(t[2],".").concat(t[0]),"".concat(t[3],".").concat(t[2],".").concat(t[0],".").concat(t[1]),"".concat(t[3],".").concat(t[2],".").concat(t[1],".").concat(t[0])]:void 0),ea[o]}function na(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=arguments.length>2?arguments[2]:void 0,o=e.filter((function(e){return"token"!==e})),r=ta(o);return r.reduce((function(e,t){return Qi({},e,n[t])}),t)}function oa(e){return e.join(" ")}function ra(e){var t=e.node,n=e.stylesheet,r=e.style,i=void 0===r?{}:r,a=e.useInlineStyles,s=e.key,u=t.properties,c=t.type,l=t.tagName,h=t.value;if("text"===c)return h;if(l){var p,f=function(e,t){var n=0;return function(o){return n+=1,o.map((function(o,r){return ra({node:o,stylesheet:e,useInlineStyles:t,key:"code-segment-".concat(n,"-").concat(r)})}))}}(n,a);if(a){var g=Object.keys(n).reduce((function(e,t){return t.split(".").forEach((function(t){e.includes(t)||e.push(t)})),e}),[]),m=u.className&&u.className.includes("token")?["token"]:[],_=u.className&&m.concat(u.className.filter((function(e){return!g.includes(e)})));p=Qi({},u,{className:oa(_)||void 0,style:na(u.className,Object.assign({},u.style,i),n)})}else p=Qi({},u,{className:oa(u.className)});var F=f(t.children);return o.createElement(l,d({key:s},p),F)}}var ia=/\n/g;function aa(e){var t=e.codeString,n=e.codeStyle,r=e.containerStyle,i=void 0===r?{float:"left",paddingRight:"10px"}:r,a=e.numberStyle,s=void 0===a?{}:a,u=e.startingLineNumber;return o.createElement("code",{style:Object.assign({},n,i)},function(e){var t=e.startingLineNumber,n=e.style;return e.lines.map((function(e,r){var i=r+t;return o.createElement("span",{key:"line-".concat(r),className:"react-syntax-highlighter-line-number",style:"function"==typeof n?n(i):n},"".concat(i,"\n"))}))}({lines:t.replace(/\n$/,"").split("\n"),style:s,startingLineNumber:u}))}function sa(e,t){return{type:"element",tagName:"span",properties:{key:"line-number--".concat(e),className:["comment","linenumber","react-syntax-highlighter-line-number"],style:t},children:[{type:"text",value:e}]}}function ua(e,t,n){var o;return Qi({},{display:"inline-block",minWidth:(o=n,"".concat(o.toString().length,".25em")),paddingRight:"1em",textAlign:"right",userSelect:"none"},"function"==typeof e?e(t):e)}function ca(e){var t=e.children,n=e.lineNumber,o=e.lineNumberStyle,r=e.largestLineNumber,i=e.showInlineLineNumbers,a=e.lineProps,s=void 0===a?{}:a,u=e.className,c=void 0===u?[]:u,l=e.showLineNumbers,d=e.wrapLongLines,h="function"==typeof s?s(n):s;if(h.className=c,n&&i){var p=ua(o,n,r);t.unshift(sa(n,p))}return d&l&&(h.style=Qi({},h.style,{display:"flex"})),{type:"element",tagName:"span",properties:h,children:t}}function la(e){for(var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[],n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[],o=0;o2&&void 0!==arguments[2]?arguments[2]:[];return ca({children:e,lineNumber:t,lineNumberStyle:s,largestLineNumber:a,showInlineLineNumbers:r,lineProps:n,className:i,showLineNumbers:o,wrapLongLines:u})}function g(e,t){if(o&&t&&r){var n=ua(s,t,a);e.unshift(sa(t,n))}return e}function m(e,n){var o=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[];return t||o.length>0?f(e,n,o):g(e,n)}for(var _=function(){var e=l[p],t=e.children[0].value;if(t.match(ia)){var n=t.split("\n");n.forEach((function(t,r){var a=o&&d.length+i,s={type:"text",value:"".concat(t,"\n")};if(0===r){var u=m(l.slice(h+1,p).concat(ca({children:[s],className:e.properties.className})),a);d.push(u)}else if(r===n.length-1)if(l[p+1]&&l[p+1].children&&l[p+1].children[0]){var c=ca({children:[{type:"text",value:"".concat(t)}],className:e.properties.className});l.splice(p+1,0,c)}else{var f=m([s],a,e.properties.className);d.push(f)}else{var g=m([s],a,e.properties.className);d.push(g)}})),h=p}p++};p code[class*="language-"]':{background:"#f5f2f0",padding:".1em",borderRadius:".3em",whiteSpace:"normal"},comment:{color:"slategray"},prolog:{color:"slategray"},doctype:{color:"slategray"},cdata:{color:"slategray"},punctuation:{color:"#999"},namespace:{Opacity:".7"},property:{color:"#905"},tag:{color:"#905"},boolean:{color:"#905"},number:{color:"#905"},constant:{color:"#905"},symbol:{color:"#905"},deleted:{color:"#905"},selector:{color:"#690"},"attr-name":{color:"#690"},string:{color:"#690"},char:{color:"#690"},builtin:{color:"#690"},inserted:{color:"#690"},operator:{color:"#9a6e3a",background:"hsla(0, 0%, 100%, .5)"},entity:{color:"#9a6e3a",background:"hsla(0, 0%, 100%, .5)",cursor:"help"},url:{color:"#9a6e3a",background:"hsla(0, 0%, 100%, .5)"},".language-css .token.string":{color:"#9a6e3a",background:"hsla(0, 0%, 100%, .5)"},".style .token.string":{color:"#9a6e3a",background:"hsla(0, 0%, 100%, .5)"},atrule:{color:"#07a"},"attr-value":{color:"#07a"},keyword:{color:"#07a"},function:{color:"#DD4A68"},"class-name":{color:"#DD4A68"},regex:{color:"#e90"},important:{color:"#e90",fontWeight:"bold"},variable:{color:"#e90"},bold:{fontWeight:"bold"},italic:{fontStyle:"italic"}},function(e){var t=e.language,n=e.children,r=e.style,i=void 0===r?ga:r,a=e.customStyle,s=void 0===a?{}:a,u=e.codeTagProps,c=void 0===u?{className:t?"language-".concat(t):void 0,style:Qi({},i['code[class*="language-"]'],i['code[class*="language-'.concat(t,'"]')])}:u,l=e.useInlineStyles,d=void 0===l||l,h=e.showLineNumbers,p=void 0!==h&&h,f=e.showInlineLineNumbers,g=void 0===f||f,m=e.startingLineNumber,_=void 0===m?1:m,F=e.lineNumberContainerStyle,y=e.lineNumberStyle,b=void 0===y?{}:y,v=e.wrapLines,w=e.wrapLongLines,E=void 0!==w&&w,k=e.lineProps,D=void 0===k?{}:k,S=e.renderer,x=e.PreTag,C=void 0===x?"pre":x,A=e.CodeTag,T=void 0===A?"code":A,R=e.code,I=void 0===R?Array.isArray(n)?n[0]:n:R,M=e.astGenerator,O=function(e,t){if(null==e)return{};var n,o,r=B(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}(e,["language","children","style","customStyle","codeTagProps","useInlineStyles","showLineNumbers","showInlineLineNumbers","startingLineNumber","lineNumberContainerStyle","lineNumberStyle","wrapLines","wrapLongLines","lineProps","renderer","PreTag","CodeTag","code","astGenerator"]);M=M||fa;var N=p?o.createElement(aa,{containerStyle:F,codeStyle:c.style||{},numberStyle:b,startingLineNumber:_,codeString:I}):null,L=i.hljs||i['pre[class*="language-"]']||{backgroundColor:"#fff"},P=pa(M)?"hljs":"prismjs",U=d?Object.assign({},O,{style:Object.assign({},L,s)}):Object.assign({},O,{className:O.className?"".concat(P," ").concat(O.className):P,style:Object.assign({},s)});if(!M)return o.createElement(C,U,N,o.createElement(T,c,I));(void 0===v&&S||E)&&(v=!0),S=S||ha;var j=[{type:"text",value:I}],q=function(e){var t=e.astGenerator,n=e.language,o=e.code,r=e.defaultCodeValue;if(pa(t)){var i=function(e,t){return-1!==e.listLanguages().indexOf(t)}(t,n);return"text"===n?{value:r,language:"text"}:i?t.highlight(n,o):t.highlightAuto(o)}try{return n&&"text"!==n?{value:t.highlight(o,n)}:{value:r}}catch(e){return{value:r}}}({astGenerator:M,language:t,code:I,defaultCodeValue:j});null===q.language&&(q.value=j);var z=da(q,v,D,p,g,_,q.value.length+_,b,E);return c.style=Qi({},c.style,E?{whiteSpace:"pre-wrap"}:{whiteSpace:"pre"}),o.createElement(C,U,o.createElement(T,c,!g&&N,S({rows:z,stylesheet:i,useInlineStyles:d})))});_a.supportedLanguages=["abap","abnf","actionscript","ada","agda","al","antlr4","apacheconf","apl","applescript","aql","arduino","arff","asciidoc","asm6502","aspnet","autohotkey","autoit","bash","basic","batch","bbcode","birb","bison","bnf","brainfuck","brightscript","bro","bsl","c","cil","clike","clojure","cmake","coffeescript","concurnas","cpp","crystal","csharp","csp","css-extras","css","cypher","d","dart","dax","dhall","diff","django","dns-zone-file","docker","ebnf","editorconfig","eiffel","ejs","elixir","elm","erb","erlang","etlua","excel-formula","factor","firestore-security-rules","flow","fortran","fsharp","ftl","gcode","gdscript","gedcom","gherkin","git","glsl","gml","go","graphql","groovy","haml","handlebars","haskell","haxe","hcl","hlsl","hpkp","hsts","http","ichigojam","icon","iecst","ignore","inform7","ini","io","j","java","javadoc","javadoclike","javascript","javastacktrace","jolie","jq","js-extras","js-templates","jsdoc","json","json5","jsonp","jsstacktrace","jsx","julia","keyman","kotlin","latex","latte","less","lilypond","liquid","lisp","livescript","llvm","lolcode","lua","makefile","markdown","markup-templating","markup","matlab","mel","mizar","mongodb","monkey","moonscript","n1ql","n4js","nand2tetris-hdl","naniscript","nasm","neon","nginx","nim","nix","nsis","objectivec","ocaml","opencl","oz","parigp","parser","pascal","pascaligo","pcaxis","peoplecode","perl","php-extras","php","phpdoc","plsql","powerquery","powershell","processing","prolog","properties","protobuf","pug","puppet","pure","purebasic","purescript","python","q","qml","qore","r","racket","reason","regex","renpy","rest","rip","roboconf","robotframework","ruby","rust","sas","sass","scala","scheme","scss","shell-session","smali","smalltalk","smarty","sml","solidity","solution-file","soy","sparql","splunk-spl","sqf","sql","stan","stylus","swift","t4-cs","t4-templating","t4-vb","tap","tcl","textile","toml","tsx","tt2","turtle","twig","typescript","typoscript","unrealscript","vala","vbnet","velocity","verilog","vhdl","vim","visual-basic","warpscript","wasm","wiki","xeora","xml-doc","xojo","xquery","yaml","yang","zig"];const Fa=_a,ya={'code[class*="language-"]':{color:"black",background:"none",fontFamily:"Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace",fontSize:"1em",textAlign:"left",whiteSpace:"pre",wordSpacing:"normal",wordBreak:"normal",wordWrap:"normal",lineHeight:"1.5",MozTabSize:"4",OTabSize:"4",tabSize:"4",WebkitHyphens:"none",MozHyphens:"none",msHyphens:"none",hyphens:"none",maxHeight:"inherit",height:"inherit",padding:"0 1em",display:"block",overflow:"auto"},'pre[class*="language-"]':{color:"black",background:"none",fontFamily:"Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace",fontSize:"1em",textAlign:"left",whiteSpace:"pre",wordSpacing:"normal",wordBreak:"normal",wordWrap:"normal",lineHeight:"1.5",MozTabSize:"4",OTabSize:"4",tabSize:"4",WebkitHyphens:"none",MozHyphens:"none",msHyphens:"none",hyphens:"none",position:"relative",margin:".5em 0",overflow:"visible",padding:"0",backgroundColor:"#fdfdfd",WebkitBoxSizing:"border-box",MozBoxSizing:"border-box",boxSizing:"border-box",marginBottom:"1em"},'pre[class*="language-"]>code':{position:"relative",borderLeft:"10px solid #358ccb",boxShadow:"-1px 0px 0px 0px #358ccb, 0px 0px 0px 1px #dfdfdf",backgroundColor:"#fdfdfd",backgroundImage:"linear-gradient(transparent 50%, rgba(69, 142, 209, 0.04) 50%)",backgroundSize:"3em 3em",backgroundOrigin:"content-box",backgroundAttachment:"local"},':not(pre) > code[class*="language-"]':{backgroundColor:"#fdfdfd",WebkitBoxSizing:"border-box",MozBoxSizing:"border-box",boxSizing:"border-box",marginBottom:"1em",position:"relative",padding:".2em",borderRadius:"0.3em",color:"#c92c2c",border:"1px solid rgba(0, 0, 0, 0.1)",display:"inline",whiteSpace:"normal"},'pre[class*="language-"]:before':{content:"''",zIndex:"-2",display:"block",position:"absolute",bottom:"0.75em",left:"0.18em",width:"40%",height:"20%",maxHeight:"13em",boxShadow:"0px 13px 8px #979797",WebkitTransform:"rotate(-2deg)",MozTransform:"rotate(-2deg)",msTransform:"rotate(-2deg)",OTransform:"rotate(-2deg)",transform:"rotate(-2deg)"},'pre[class*="language-"]:after':{content:"''",zIndex:"-2",display:"block",position:"absolute",bottom:"0.75em",left:"auto",width:"40%",height:"20%",maxHeight:"13em",boxShadow:"0px 13px 8px #979797",WebkitTransform:"rotate(2deg)",MozTransform:"rotate(2deg)",msTransform:"rotate(2deg)",OTransform:"rotate(2deg)",transform:"rotate(2deg)",right:"0.75em"},comment:{color:"#7D8B99"},"block-comment":{color:"#7D8B99"},prolog:{color:"#7D8B99"},doctype:{color:"#7D8B99"},cdata:{color:"#7D8B99"},punctuation:{color:"#5F6364"},property:{color:"#c92c2c"},tag:{color:"#c92c2c"},boolean:{color:"#c92c2c"},number:{color:"#c92c2c"},"function-name":{color:"#c92c2c"},constant:{color:"#c92c2c"},symbol:{color:"#c92c2c"},deleted:{color:"#c92c2c"},selector:{color:"#2f9c0a"},"attr-name":{color:"#2f9c0a"},string:{color:"#2f9c0a"},char:{color:"#2f9c0a"},function:{color:"#2f9c0a"},builtin:{color:"#2f9c0a"},inserted:{color:"#2f9c0a"},operator:{color:"#a67f59",background:"rgba(255, 255, 255, 0.5)"},entity:{color:"#a67f59",background:"rgba(255, 255, 255, 0.5)",cursor:"help"},url:{color:"#a67f59",background:"rgba(255, 255, 255, 0.5)"},variable:{color:"#a67f59",background:"rgba(255, 255, 255, 0.5)"},atrule:{color:"#1990b8"},"attr-value":{color:"#1990b8"},keyword:{color:"#1990b8"},"class-name":{color:"#1990b8"},regex:{color:"#e90"},important:{color:"#e90",fontWeight:"normal"},".language-css .token.string":{color:"#a67f59",background:"rgba(255, 255, 255, 0.5)"},".style .token.string":{color:"#a67f59",background:"rgba(255, 255, 255, 0.5)"},bold:{fontWeight:"bold"},italic:{fontStyle:"italic"},namespace:{Opacity:".7"},'pre[class*="language-"].line-numbers.line-numbers':{paddingLeft:"0"},'pre[class*="language-"].line-numbers.line-numbers code':{paddingLeft:"3.8em"},'pre[class*="language-"].line-numbers.line-numbers .line-numbers-rows':{left:"0"},'pre[class*="language-"][data-line]':{paddingTop:"0",paddingBottom:"0",paddingLeft:"0"},"pre[data-line] code":{position:"relative",paddingLeft:"4em"},"pre .line-highlight":{marginTop:"0"}},ba=n.p+"assets/reply-arrow.4652dfc3651a804bb60877d388196c95.svg";var va={code:function(e){var t=e.inline,n=e.className,r=e.children,i=/language-(\w+)/.exec(n||"");return!t&&i?o.createElement(Fa,{style:ya,language:i[1],PreTag:"div",showLineNumbers:!0},String(r).replace(/\n$/,"")):o.createElement("code",{className:n},String(r))}};function wa(){return o.createElement("div",{className:"ph-msg"},o.createElement("div",{className:"ph-msg__avatar-container"},o.createElement("div",{className:"ph-msg__avatar"})),o.createElement("div",{className:"ph-msg__main-container"},o.createElement("div",{className:"ph-msg__header"}),o.createElement("div",{className:"ph-msg__content"},o.createElement("div",null),o.createElement("div",null),o.createElement("div",null),o.createElement("div",null))))}function Ea(e){var t=e.color,n=e.avatarSrc,r=e.name,i=e.content,a=e.time,s=e.markdown,u=e.contentOnly,c=e.reply,l=e.edited,d=e.reactions,h=u?"message--content-only":"message--full";return o.createElement("div",{className:"message ".concat(h)},o.createElement("div",{className:"message__avatar-container"},!u&&o.createElement(Sr,{imageSrc:n,text:r.slice(0,1),bgColor:t,size:"small"})),o.createElement("div",{className:"message__main-container"},!u&&o.createElement("div",{className:"message__header"},o.createElement("div",{style:{color:t},className:"message__profile"},o.createElement(vt,{variant:"b1"},r)),o.createElement("div",{className:"message__time"},o.createElement(vt,{variant:"b3"},a))),o.createElement("div",{className:"message__content"},null!==c&&o.createElement("div",{className:"message__reply-content"},o.createElement(vt,{variant:"b2"},o.createElement(Et,{color:c.color,size:"extra-small",src:ba}),o.createElement("span",{style:{color:c.color}},c.to),o.createElement(o.Fragment,null," ".concat(c.content)))),o.createElement("div",{className:"text text-b1"},s?function(e){return o.createElement(Vi(),{remarkPlugins:[Yi()],components:va,linkTarget:"_blank"},e)}(i):function(e){return o.createElement($i(),{options:{target:{url:"_blank"}}},e)}(i)),l&&o.createElement(vt,{className:"message__edited",variant:"b3"},"(edited)"),d&&o.createElement("div",{className:"message__reactions text text-b3 noselect"},d.map((function(e){return o.createElement("button",{key:e.id,onClick:function(){return alert("Sending reactions is yet to be implemented.")},type:"button",className:"msg__reaction".concat(e.active?" msg__reaction--active":"")},"".concat(e.key," ").concat(e.count))}))))))}Ea.defaultProps={color:"var(--tc-surface-high)",avatarSrc:null,markdown:!1,contentOnly:!1,reply:null,edited:!1,reactions:null},Ea.propTypes={color:l().string,avatarSrc:l().string,name:l().string.isRequired,content:l().node.isRequired,time:l().string.isRequired,markdown:l().bool,contentOnly:l().bool,reply:l().shape({color:l().string.isRequired,to:l().string.isRequired,content:l().string.isRequired}),edited:l().bool,reactions:l().arrayOf(l().exact({id:l().string,key:l().string,count:l().number,active:l().bool}))};const ka=n.p+"assets/download.ab30aec19573b4189334338c801b4180.svg",Da=n.p+"assets/external.c37f42201429884adc1da8fc5ee65b88.svg",Sa=n.p+"assets/play.8838e717b724f8097895aae1dad87e92.svg";function xa(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(e)){var n=[],o=!0,r=!1,i=void 0;try{for(var a,s=e[Symbol.iterator]();!(o=(a=s.next()).done)&&(n.push(a.value),!t||n.length!==t);o=!0);}catch(e){r=!0,i=e}finally{try{o||null==s.return||s.return()}finally{if(r)throw i}}return n}}(e,t)||function(e,t){if(e){if("string"==typeof e)return Ca(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?Ca(e,t):void 0}}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function Ca(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,o=new Array(t);n>10),56320+(1023&t))},toCodePoint:_},onerror:function(){this.parentNode&&this.parentNode.replaceChild(u(this.alt,!1),this)},parse:function(t,n){return n&&"function"!=typeof n||(n={callback:n}),("string"==typeof t?p:h)(t,{callback:n.callback||c,attributes:"function"==typeof n.attributes?n.attributes:g,base:"string"==typeof n.base?n.base:e.base,ext:n.ext||e.ext,size:n.folder||(o=n.size||e.size,"number"==typeof o?o+"x"+o:o),className:n.className||e.className,onerror:n.onerror||e.onerror});var o},replace:m,test:function(e){n.lastIndex=0;var t=n.test(e);return n.lastIndex=0,t}},t={"&":"&","<":"<",">":">","'":"'",'"':"""},n=/(?:\ud83d\udc68\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffc-\udfff]|\ud83e\uddd1\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb\udffd-\udfff]|\ud83e\uddd1\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb\udffc\udffe\udfff]|\ud83e\uddd1\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb-\udffd\udfff]|\ud83e\uddd1\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb-\udffe]|\ud83d\udc68\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffc-\udfff]|\ud83d\udc68\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffd-\udfff]|\ud83d\udc68\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc68\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffd\udfff]|\ud83d\udc68\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffe]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffc-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffc-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffd-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb\udffd-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc69\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffd\udfff]|\ud83d\udc69\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb-\udffd\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffe]|\ud83d\udc69\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb-\udffe]|\ud83e\uddd1\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffc-\udfff]|\ud83e\uddd1\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb\udffd-\udfff]|\ud83e\uddd1\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb\udffc\udffe\udfff]|\ud83e\uddd1\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb-\udffd\udfff]|\ud83e\uddd1\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb-\udffe]|\ud83e\uddd1\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83d\udc68\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68|\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d[\udc68\udc69]|\ud83d\udc68\u200d\u2764\ufe0f\u200d\ud83d\udc68|\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d[\udc68\udc69]|\ud83e\uddd1\u200d\ud83e\udd1d\u200d\ud83e\uddd1|\ud83d\udc6b\ud83c[\udffb-\udfff]|\ud83d\udc6c\ud83c[\udffb-\udfff]|\ud83d\udc6d\ud83c[\udffb-\udfff]|\ud83d\udc8f\ud83c[\udffb-\udfff]|\ud83d\udc91\ud83c[\udffb-\udfff]|\ud83d[\udc6b-\udc6d\udc8f\udc91])|(?:\ud83d[\udc68\udc69]|\ud83e\uddd1)(?:\ud83c[\udffb-\udfff])?\u200d(?:\u2695\ufe0f|\u2696\ufe0f|\u2708\ufe0f|\ud83c[\udf3e\udf73\udf7c\udf84\udf93\udfa4\udfa8\udfeb\udfed]|\ud83d[\udcbb\udcbc\udd27\udd2c\ude80\ude92]|\ud83e[\uddaf-\uddb3\uddbc\uddbd])|(?:\ud83c[\udfcb\udfcc]|\ud83d[\udd74\udd75]|\u26f9)((?:\ud83c[\udffb-\udfff]|\ufe0f)\u200d[\u2640\u2642]\ufe0f)|(?:\ud83c[\udfc3\udfc4\udfca]|\ud83d[\udc6e\udc70\udc71\udc73\udc77\udc81\udc82\udc86\udc87\ude45-\ude47\ude4b\ude4d\ude4e\udea3\udeb4-\udeb6]|\ud83e[\udd26\udd35\udd37-\udd39\udd3d\udd3e\uddb8\uddb9\uddcd-\uddcf\uddd4\uddd6-\udddd])(?:\ud83c[\udffb-\udfff])?\u200d[\u2640\u2642]\ufe0f|(?:\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83c\udff3\ufe0f\u200d\u26a7\ufe0f|\ud83c\udff3\ufe0f\u200d\ud83c\udf08|\ud83d\ude36\u200d\ud83c\udf2b\ufe0f|\u2764\ufe0f\u200d\ud83d\udd25|\u2764\ufe0f\u200d\ud83e\ude79|\ud83c\udff4\u200d\u2620\ufe0f|\ud83d\udc15\u200d\ud83e\uddba|\ud83d\udc3b\u200d\u2744\ufe0f|\ud83d\udc41\u200d\ud83d\udde8|\ud83d\udc68\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83d\udc6f\u200d\u2640\ufe0f|\ud83d\udc6f\u200d\u2642\ufe0f|\ud83d\ude2e\u200d\ud83d\udca8|\ud83d\ude35\u200d\ud83d\udcab|\ud83e\udd3c\u200d\u2640\ufe0f|\ud83e\udd3c\u200d\u2642\ufe0f|\ud83e\uddde\u200d\u2640\ufe0f|\ud83e\uddde\u200d\u2642\ufe0f|\ud83e\udddf\u200d\u2640\ufe0f|\ud83e\udddf\u200d\u2642\ufe0f|\ud83d\udc08\u200d\u2b1b)|[#*0-9]\ufe0f?\u20e3|(?:[©®\u2122\u265f]\ufe0f)|(?:\ud83c[\udc04\udd70\udd71\udd7e\udd7f\ude02\ude1a\ude2f\ude37\udf21\udf24-\udf2c\udf36\udf7d\udf96\udf97\udf99-\udf9b\udf9e\udf9f\udfcd\udfce\udfd4-\udfdf\udff3\udff5\udff7]|\ud83d[\udc3f\udc41\udcfd\udd49\udd4a\udd6f\udd70\udd73\udd76-\udd79\udd87\udd8a-\udd8d\udda5\udda8\uddb1\uddb2\uddbc\uddc2-\uddc4\uddd1-\uddd3\udddc-\uddde\udde1\udde3\udde8\uddef\uddf3\uddfa\udecb\udecd-\udecf\udee0-\udee5\udee9\udef0\udef3]|[\u203c\u2049\u2139\u2194-\u2199\u21a9\u21aa\u231a\u231b\u2328\u23cf\u23ed-\u23ef\u23f1\u23f2\u23f8-\u23fa\u24c2\u25aa\u25ab\u25b6\u25c0\u25fb-\u25fe\u2600-\u2604\u260e\u2611\u2614\u2615\u2618\u2620\u2622\u2623\u2626\u262a\u262e\u262f\u2638-\u263a\u2640\u2642\u2648-\u2653\u2660\u2663\u2665\u2666\u2668\u267b\u267f\u2692-\u2697\u2699\u269b\u269c\u26a0\u26a1\u26a7\u26aa\u26ab\u26b0\u26b1\u26bd\u26be\u26c4\u26c5\u26c8\u26cf\u26d1\u26d3\u26d4\u26e9\u26ea\u26f0-\u26f5\u26f8\u26fa\u26fd\u2702\u2708\u2709\u270f\u2712\u2714\u2716\u271d\u2721\u2733\u2734\u2744\u2747\u2757\u2763\u2764\u27a1\u2934\u2935\u2b05-\u2b07\u2b1b\u2b1c\u2b50\u2b55\u3030\u303d\u3297\u3299])(?:\ufe0f|(?!\ufe0e))|(?:(?:\ud83c[\udfcb\udfcc]|\ud83d[\udd74\udd75\udd90]|[\u261d\u26f7\u26f9\u270c\u270d])(?:\ufe0f|(?!\ufe0e))|(?:\ud83c[\udf85\udfc2-\udfc4\udfc7\udfca]|\ud83d[\udc42\udc43\udc46-\udc50\udc66-\udc69\udc6e\udc70-\udc78\udc7c\udc81-\udc83\udc85-\udc87\udcaa\udd7a\udd95\udd96\ude45-\ude47\ude4b-\ude4f\udea3\udeb4-\udeb6\udec0\udecc]|\ud83e[\udd0c\udd0f\udd18-\udd1c\udd1e\udd1f\udd26\udd30-\udd39\udd3d\udd3e\udd77\uddb5\uddb6\uddb8\uddb9\uddbb\uddcd-\uddcf\uddd1-\udddd]|[\u270a\u270b]))(?:\ud83c[\udffb-\udfff])?|(?:\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc65\udb40\udc6e\udb40\udc67\udb40\udc7f|\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc73\udb40\udc63\udb40\udc74\udb40\udc7f|\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc77\udb40\udc6c\udb40\udc73\udb40\udc7f|\ud83c\udde6\ud83c[\udde8-\uddec\uddee\uddf1\uddf2\uddf4\uddf6-\uddfa\uddfc\uddfd\uddff]|\ud83c\udde7\ud83c[\udde6\udde7\udde9-\uddef\uddf1-\uddf4\uddf6-\uddf9\uddfb\uddfc\uddfe\uddff]|\ud83c\udde8\ud83c[\udde6\udde8\udde9\uddeb-\uddee\uddf0-\uddf5\uddf7\uddfa-\uddff]|\ud83c\udde9\ud83c[\uddea\uddec\uddef\uddf0\uddf2\uddf4\uddff]|\ud83c\uddea\ud83c[\udde6\udde8\uddea\uddec\udded\uddf7-\uddfa]|\ud83c\uddeb\ud83c[\uddee-\uddf0\uddf2\uddf4\uddf7]|\ud83c\uddec\ud83c[\udde6\udde7\udde9-\uddee\uddf1-\uddf3\uddf5-\uddfa\uddfc\uddfe]|\ud83c\udded\ud83c[\uddf0\uddf2\uddf3\uddf7\uddf9\uddfa]|\ud83c\uddee\ud83c[\udde8-\uddea\uddf1-\uddf4\uddf6-\uddf9]|\ud83c\uddef\ud83c[\uddea\uddf2\uddf4\uddf5]|\ud83c\uddf0\ud83c[\uddea\uddec-\uddee\uddf2\uddf3\uddf5\uddf7\uddfc\uddfe\uddff]|\ud83c\uddf1\ud83c[\udde6-\udde8\uddee\uddf0\uddf7-\uddfb\uddfe]|\ud83c\uddf2\ud83c[\udde6\udde8-\udded\uddf0-\uddff]|\ud83c\uddf3\ud83c[\udde6\udde8\uddea-\uddec\uddee\uddf1\uddf4\uddf5\uddf7\uddfa\uddff]|\ud83c\uddf4\ud83c\uddf2|\ud83c\uddf5\ud83c[\udde6\uddea-\udded\uddf0-\uddf3\uddf7-\uddf9\uddfc\uddfe]|\ud83c\uddf6\ud83c\udde6|\ud83c\uddf7\ud83c[\uddea\uddf4\uddf8\uddfa\uddfc]|\ud83c\uddf8\ud83c[\udde6-\uddea\uddec-\uddf4\uddf7-\uddf9\uddfb\uddfd-\uddff]|\ud83c\uddf9\ud83c[\udde6\udde8\udde9\uddeb-\udded\uddef-\uddf4\uddf7\uddf9\uddfb\uddfc\uddff]|\ud83c\uddfa\ud83c[\udde6\uddec\uddf2\uddf3\uddf8\uddfe\uddff]|\ud83c\uddfb\ud83c[\udde6\udde8\uddea\uddec\uddee\uddf3\uddfa]|\ud83c\uddfc\ud83c[\uddeb\uddf8]|\ud83c\uddfd\ud83c\uddf0|\ud83c\uddfe\ud83c[\uddea\uddf9]|\ud83c\uddff\ud83c[\udde6\uddf2\uddfc]|\ud83c[\udccf\udd8e\udd91-\udd9a\udde6-\uddff\ude01\ude32-\ude36\ude38-\ude3a\ude50\ude51\udf00-\udf20\udf2d-\udf35\udf37-\udf7c\udf7e-\udf84\udf86-\udf93\udfa0-\udfc1\udfc5\udfc6\udfc8\udfc9\udfcf-\udfd3\udfe0-\udff0\udff4\udff8-\udfff]|\ud83d[\udc00-\udc3e\udc40\udc44\udc45\udc51-\udc65\udc6a\udc6f\udc79-\udc7b\udc7d-\udc80\udc84\udc88-\udc8e\udc90\udc92-\udca9\udcab-\udcfc\udcff-\udd3d\udd4b-\udd4e\udd50-\udd67\udda4\uddfb-\ude44\ude48-\ude4a\ude80-\udea2\udea4-\udeb3\udeb7-\udebf\udec1-\udec5\uded0-\uded2\uded5-\uded7\udeeb\udeec\udef4-\udefc\udfe0-\udfeb]|\ud83e[\udd0d\udd0e\udd10-\udd17\udd1d\udd20-\udd25\udd27-\udd2f\udd3a\udd3c\udd3f-\udd45\udd47-\udd76\udd78\udd7a-\uddb4\uddb7\uddba\uddbc-\uddcb\uddd0\uddde-\uddff\ude70-\ude74\ude78-\ude7a\ude80-\ude86\ude90-\udea8\udeb0-\udeb6\udec0-\udec2\uded0-\uded6]|[\u23e9-\u23ec\u23f0\u23f3\u267e\u26ce\u2705\u2728\u274c\u274e\u2753-\u2755\u2795-\u2797\u27b0\u27bf\ue50a])|\ufe0f/g,o=/\uFE0F/g,r=String.fromCharCode(8205),i=/[&<>'"]/g,a=/^(?:iframe|noframes|noscript|script|select|style|textarea)$/,s=String.fromCharCode;return e;function u(e,t){return document.createTextNode(t?e.replace(o,""):e)}function c(e,t){return"".concat(t.base,t.size,"/",e,t.ext)}function l(e,t){for(var n,o,r=e.childNodes,i=r.length;i--;)3===(o=(n=r[i]).nodeType)?t.push(n):1!==o||"ownerSVGElement"in n||a.test(n.nodeName.toLowerCase())||l(n,t);return t}function d(e){return _(e.indexOf(r)<0?e.replace(o,""):e)}function h(e,t){for(var o,r,i,a,s,c,h,p,f,g,m,_,F,y=l(e,[]),b=y.length;b--;){for(i=!1,a=document.createDocumentFragment(),c=(s=y[b]).nodeValue,p=0;h=n.exec(c);){if((f=h.index)!==p&&a.appendChild(u(c.slice(p,f),!0)),_=d(m=h[0]),p=f+m.length,F=t.callback(_,t),_&&F){for(r in(g=new Image).onerror=t.onerror,g.setAttribute("draggable","false"),o=t.attributes(m,_))o.hasOwnProperty(r)&&0!==r.indexOf("on")&&!g.hasAttribute(r)&&g.setAttribute(r,o[r]);g.className=t.className,g.alt=m,g.src=F,i=!0,a.appendChild(g)}g||a.appendChild(u(m,!1)),g=null}i&&(p")}return r}))}function f(e){return t[e]}function g(){return null}function m(e,t){return String(e).replace(n,t)}function _(e,t){for(var n=[],o=0,r=0,i=0;i"},{"annotation":"smiling face with halo","group":0,"hexcode":"1F607","order":13,"tags":["angel","face","fantasy","halo","innocent"],"unicode":"😇","emoticon":"o:)"},{"annotation":"smiling face with hearts","group":0,"hexcode":"1F970","order":14,"tags":["adore","crush","hearts","in love"],"unicode":"🥰"},{"annotation":"smiling face with heart-eyes","group":0,"hexcode":"1F60D","order":15,"tags":["eye","face","love","smile"],"unicode":"😍"},{"annotation":"star-struck","group":0,"hexcode":"1F929","order":16,"tags":["eyes","face","grinning","star"],"unicode":"🤩"},{"annotation":"face blowing a kiss","group":0,"hexcode":"1F618","order":17,"tags":["face","kiss"],"unicode":"😘","emoticon":":x"},{"annotation":"kissing face","group":0,"hexcode":"1F617","order":18,"tags":["face","kiss"],"unicode":"😗"},{"annotation":"smiling face","group":0,"hexcode":"263A","order":20,"tags":["face","outlined","relaxed","smile"],"unicode":"☺️"},{"annotation":"kissing face with closed eyes","group":0,"hexcode":"1F61A","order":21,"tags":["closed","eye","face","kiss"],"unicode":"😚","emoticon":":*"},{"annotation":"kissing face with smiling eyes","group":0,"hexcode":"1F619","order":22,"tags":["eye","face","kiss","smile"],"unicode":"😙"},{"annotation":"smiling face with tear","group":0,"hexcode":"1F972","order":23,"tags":["grateful","proud","relieved","smiling","tear","touched"],"unicode":"🥲"},{"annotation":"face savoring food","group":0,"hexcode":"1F60B","order":24,"tags":["delicious","face","savouring","smile","yum"],"unicode":"😋"},{"annotation":"face with tongue","group":0,"hexcode":"1F61B","order":25,"tags":["face","tongue"],"unicode":"😛","emoticon":":p"},{"annotation":"winking face with tongue","group":0,"hexcode":"1F61C","order":26,"tags":["eye","face","joke","tongue","wink"],"unicode":"😜","emoticon":";p"},{"annotation":"zany face","group":0,"hexcode":"1F92A","order":27,"tags":["eye","goofy","large","small"],"unicode":"🤪"},{"annotation":"squinting face with tongue","group":0,"hexcode":"1F61D","order":28,"tags":["eye","face","horrible","taste","tongue"],"unicode":"😝","emoticon":"xp"},{"annotation":"money-mouth face","group":0,"hexcode":"1F911","order":29,"tags":["face","money","mouth"],"unicode":"🤑"},{"annotation":"hugging face","group":0,"hexcode":"1F917","order":30,"tags":["face","hug","hugging"],"unicode":"🤗"},{"annotation":"face with hand over mouth","group":0,"hexcode":"1F92D","order":31,"tags":["whoops"],"unicode":"🤭"},{"annotation":"shushing face","group":0,"hexcode":"1F92B","order":32,"tags":["quiet","shush"],"unicode":"🤫"},{"annotation":"thinking face","group":0,"hexcode":"1F914","order":33,"tags":["face","thinking"],"unicode":"🤔","emoticon":":l"},{"annotation":"zipper-mouth face","group":0,"hexcode":"1F910","order":34,"tags":["face","mouth","zipper"],"unicode":"🤐","emoticon":":z"},{"annotation":"face with raised eyebrow","group":0,"hexcode":"1F928","order":35,"tags":["distrust","skeptic"],"unicode":"🤨"},{"annotation":"neutral face","group":0,"hexcode":"1F610","order":36,"tags":["deadpan","face","meh","neutral"],"unicode":"😐️","emoticon":":|"},{"annotation":"expressionless face","group":0,"hexcode":"1F611","order":37,"tags":["expressionless","face","inexpressive","meh","unexpressive"],"unicode":"😑"},{"annotation":"face without mouth","group":0,"hexcode":"1F636","order":38,"tags":["face","mouth","quiet","silent"],"unicode":"😶","emoticon":":#"},{"annotation":"face in clouds","group":0,"hexcode":"1F636-200D-1F32B-FE0F","order":39,"tags":["absentminded","face in the fog","head in clouds"],"unicode":"😶‍🌫️"},{"annotation":"smirking face","group":0,"hexcode":"1F60F","order":41,"tags":["face","smirk"],"unicode":"😏","emoticon":":j"},{"annotation":"unamused face","group":0,"hexcode":"1F612","order":42,"tags":["face","unamused","unhappy"],"unicode":"😒","emoticon":":?"},{"annotation":"face with rolling eyes","group":0,"hexcode":"1F644","order":43,"tags":["eyeroll","eyes","face","rolling"],"unicode":"🙄"},{"annotation":"grimacing face","group":0,"hexcode":"1F62C","order":44,"tags":["face","grimace"],"unicode":"😬","emoticon":"8D"},{"annotation":"face exhaling","group":0,"hexcode":"1F62E-200D-1F4A8","order":45,"tags":["exhale","gasp","groan","relief","whisper","whistle"],"unicode":"😮‍💨"},{"annotation":"lying face","group":0,"hexcode":"1F925","order":46,"tags":["face","lie","pinocchio"],"unicode":"🤥"},{"annotation":"relieved face","group":0,"hexcode":"1F60C","order":47,"tags":["face","relieved"],"unicode":"😌"},{"annotation":"pensive face","group":0,"hexcode":"1F614","order":48,"tags":["dejected","face","pensive"],"unicode":"😔"},{"annotation":"sleepy face","group":0,"hexcode":"1F62A","order":49,"tags":["face","sleep"],"unicode":"😪"},{"annotation":"drooling face","group":0,"hexcode":"1F924","order":50,"tags":["drooling","face"],"unicode":"🤤"},{"annotation":"sleeping face","group":0,"hexcode":"1F634","order":51,"tags":["face","sleep","zzz"],"unicode":"😴"},{"annotation":"face with medical mask","group":0,"hexcode":"1F637","order":52,"tags":["cold","doctor","face","mask","sick"],"unicode":"😷"},{"annotation":"face with thermometer","group":0,"hexcode":"1F912","order":53,"tags":["face","ill","sick","thermometer"],"unicode":"🤒"},{"annotation":"face with head-bandage","group":0,"hexcode":"1F915","order":54,"tags":["bandage","face","hurt","injury"],"unicode":"🤕"},{"annotation":"nauseated face","group":0,"hexcode":"1F922","order":55,"tags":["face","nauseated","vomit"],"unicode":"🤢","emoticon":"%("},{"annotation":"face vomiting","group":0,"hexcode":"1F92E","order":56,"tags":["puke","sick","vomit"],"unicode":"🤮"},{"annotation":"sneezing face","group":0,"hexcode":"1F927","order":57,"tags":["face","gesundheit","sneeze"],"unicode":"🤧"},{"annotation":"hot face","group":0,"hexcode":"1F975","order":58,"tags":["feverish","heat stroke","hot","red-faced","sweating"],"unicode":"🥵"},{"annotation":"cold face","group":0,"hexcode":"1F976","order":59,"tags":["blue-faced","cold","freezing","frostbite","icicles"],"unicode":"🥶"},{"annotation":"woozy face","group":0,"hexcode":"1F974","order":60,"tags":["dizzy","intoxicated","tipsy","uneven eyes","wavy mouth"],"unicode":"🥴","emoticon":":&"},{"annotation":"knocked-out face","group":0,"hexcode":"1F635","order":61,"tags":["dead","face","knocked out"],"unicode":"😵","emoticon":"xo"},{"annotation":"face with spiral eyes","group":0,"hexcode":"1F635-200D-1F4AB","order":62,"tags":["dizzy","hypnotized","spiral","trouble","whoa"],"unicode":"😵‍💫"},{"annotation":"exploding head","group":0,"hexcode":"1F92F","order":63,"tags":["mind blown","shocked"],"unicode":"🤯"},{"annotation":"cowboy hat face","group":0,"hexcode":"1F920","order":64,"tags":["cowboy","cowgirl","face","hat"],"unicode":"🤠"},{"annotation":"partying face","group":0,"hexcode":"1F973","order":65,"tags":["celebration","hat","horn","party"],"unicode":"🥳"},{"annotation":"disguised face","group":0,"hexcode":"1F978","order":66,"tags":["disguise","face","glasses","incognito","nose"],"unicode":"🥸"},{"annotation":"smiling face with sunglasses","group":0,"hexcode":"1F60E","order":67,"tags":["bright","cool","face","sun","sunglasses"],"unicode":"😎","emoticon":"8)"},{"annotation":"nerd face","group":0,"hexcode":"1F913","order":68,"tags":["face","geek","nerd"],"unicode":"🤓","emoticon":":B"},{"annotation":"face with monocle","group":0,"hexcode":"1F9D0","order":69,"tags":["stuffy"],"unicode":"🧐"},{"annotation":"confused face","group":0,"hexcode":"1F615","order":70,"tags":["confused","face","meh"],"unicode":"😕","emoticon":":/"},{"annotation":"worried face","group":0,"hexcode":"1F61F","order":71,"tags":["face","worried"],"unicode":"😟"},{"annotation":"slightly frowning face","group":0,"hexcode":"1F641","order":72,"tags":["face","frown"],"unicode":"🙁"},{"annotation":"frowning face","group":0,"hexcode":"2639","order":74,"tags":["face","frown"],"unicode":"☹️","emoticon":":("},{"annotation":"face with open mouth","group":0,"hexcode":"1F62E","order":75,"tags":["face","mouth","open","sympathy"],"unicode":"😮"},{"annotation":"hushed face","group":0,"hexcode":"1F62F","order":76,"tags":["face","hushed","stunned","surprised"],"unicode":"😯"},{"annotation":"astonished face","group":0,"hexcode":"1F632","order":77,"tags":["astonished","face","shocked","totally"],"unicode":"😲","emoticon":":o"},{"annotation":"flushed face","group":0,"hexcode":"1F633","order":78,"tags":["dazed","face","flushed"],"unicode":"😳","emoticon":":$"},{"annotation":"pleading face","group":0,"hexcode":"1F97A","order":79,"tags":["begging","mercy","puppy eyes"],"unicode":"🥺"},{"annotation":"frowning face with open mouth","group":0,"hexcode":"1F626","order":80,"tags":["face","frown","mouth","open"],"unicode":"😦"},{"annotation":"anguished face","group":0,"hexcode":"1F627","order":81,"tags":["anguished","face"],"unicode":"😧","emoticon":":s"},{"annotation":"fearful face","group":0,"hexcode":"1F628","order":82,"tags":["face","fear","fearful","scared"],"unicode":"😨"},{"annotation":"anxious face with sweat","group":0,"hexcode":"1F630","order":83,"tags":["blue","cold","face","rushed","sweat"],"unicode":"😰"},{"annotation":"sad but relieved face","group":0,"hexcode":"1F625","order":84,"tags":["disappointed","face","relieved","whew"],"unicode":"😥"},{"annotation":"crying face","group":0,"hexcode":"1F622","order":85,"tags":["cry","face","sad","tear"],"unicode":"😢","emoticon":":\'("},{"annotation":"loudly crying face","group":0,"hexcode":"1F62D","order":86,"tags":["cry","face","sad","sob","tear"],"unicode":"😭","emoticon":":\'o"},{"annotation":"face screaming in fear","group":0,"hexcode":"1F631","order":87,"tags":["face","fear","munch","scared","scream"],"unicode":"😱","emoticon":"Dx"},{"annotation":"confounded face","group":0,"hexcode":"1F616","order":88,"tags":["confounded","face"],"unicode":"😖","emoticon":"x("},{"annotation":"persevering face","group":0,"hexcode":"1F623","order":89,"tags":["face","persevere"],"unicode":"😣"},{"annotation":"disappointed face","group":0,"hexcode":"1F61E","order":90,"tags":["disappointed","face"],"unicode":"😞"},{"annotation":"downcast face with sweat","group":0,"hexcode":"1F613","order":91,"tags":["cold","face","sweat"],"unicode":"😓","emoticon":":<"},{"annotation":"weary face","group":0,"hexcode":"1F629","order":92,"tags":["face","tired","weary"],"unicode":"😩","emoticon":"D:"},{"annotation":"tired face","group":0,"hexcode":"1F62B","order":93,"tags":["face","tired"],"unicode":"😫","emoticon":":c"},{"annotation":"yawning face","group":0,"hexcode":"1F971","order":94,"tags":["bored","tired","yawn"],"unicode":"🥱"},{"annotation":"face with steam from nose","group":0,"hexcode":"1F624","order":95,"tags":["face","triumph","won"],"unicode":"😤"},{"annotation":"pouting face","group":0,"hexcode":"1F621","order":96,"tags":["angry","face","mad","pouting","rage","red"],"unicode":"😡","emoticon":">:/"},{"annotation":"angry face","group":0,"hexcode":"1F620","order":97,"tags":["anger","angry","face","mad"],"unicode":"😠"},{"annotation":"face with symbols on mouth","group":0,"hexcode":"1F92C","order":98,"tags":["swearing"],"unicode":"🤬","emoticon":":@"},{"annotation":"smiling face with horns","group":0,"hexcode":"1F608","order":99,"tags":["face","fairy tale","fantasy","horns","smile"],"unicode":"😈","emoticon":">:)"},{"annotation":"angry face with horns","group":0,"hexcode":"1F47F","order":100,"tags":["demon","devil","face","fantasy","imp"],"unicode":"👿","emoticon":">:("},{"annotation":"skull","group":0,"hexcode":"1F480","order":101,"tags":["death","face","fairy tale","monster"],"unicode":"💀"},{"annotation":"skull and crossbones","group":0,"hexcode":"2620","order":103,"tags":["crossbones","death","face","monster","skull"],"unicode":"☠️"},{"annotation":"pile of poo","group":0,"hexcode":"1F4A9","order":104,"tags":["dung","face","monster","poo","poop"],"unicode":"💩"},{"annotation":"clown face","group":0,"hexcode":"1F921","order":105,"tags":["clown","face"],"unicode":"🤡"},{"annotation":"ogre","group":0,"hexcode":"1F479","order":106,"tags":["creature","face","fairy tale","fantasy","monster"],"unicode":"👹","emoticon":">0)"},{"annotation":"goblin","group":0,"hexcode":"1F47A","order":107,"tags":["creature","face","fairy tale","fantasy","monster"],"unicode":"👺"},{"annotation":"ghost","group":0,"hexcode":"1F47B","order":108,"tags":["creature","face","fairy tale","fantasy","monster"],"unicode":"👻"},{"annotation":"alien","group":0,"hexcode":"1F47D","order":109,"tags":["creature","extraterrestrial","face","fantasy","ufo"],"unicode":"👽️"},{"annotation":"alien monster","group":0,"hexcode":"1F47E","order":110,"tags":["alien","creature","extraterrestrial","face","monster","ufo"],"unicode":"👾"},{"annotation":"robot","group":0,"hexcode":"1F916","order":111,"tags":["face","monster"],"unicode":"🤖"},{"annotation":"grinning cat","group":0,"hexcode":"1F63A","order":112,"tags":["cat","face","grinning","mouth","open","smile"],"unicode":"😺"},{"annotation":"grinning cat with smiling eyes","group":0,"hexcode":"1F638","order":113,"tags":["cat","eye","face","grin","smile"],"unicode":"😸"},{"annotation":"cat with tears of joy","group":0,"hexcode":"1F639","order":114,"tags":["cat","face","joy","tear"],"unicode":"😹"},{"annotation":"smiling cat with heart-eyes","group":0,"hexcode":"1F63B","order":115,"tags":["cat","eye","face","heart","love","smile"],"unicode":"😻"},{"annotation":"cat with wry smile","group":0,"hexcode":"1F63C","order":116,"tags":["cat","face","ironic","smile","wry"],"unicode":"😼"},{"annotation":"kissing cat","group":0,"hexcode":"1F63D","order":117,"tags":["cat","eye","face","kiss"],"unicode":"😽","emoticon":":3"},{"annotation":"weary cat","group":0,"hexcode":"1F640","order":118,"tags":["cat","face","oh","surprised","weary"],"unicode":"🙀"},{"annotation":"crying cat","group":0,"hexcode":"1F63F","order":119,"tags":["cat","cry","face","sad","tear"],"unicode":"😿"},{"annotation":"pouting cat","group":0,"hexcode":"1F63E","order":120,"tags":["cat","face","pouting"],"unicode":"😾"},{"annotation":"see-no-evil monkey","group":0,"hexcode":"1F648","order":121,"tags":["evil","face","forbidden","monkey","see"],"unicode":"🙈"},{"annotation":"hear-no-evil monkey","group":0,"hexcode":"1F649","order":122,"tags":["evil","face","forbidden","hear","monkey"],"unicode":"🙉"},{"annotation":"speak-no-evil monkey","group":0,"hexcode":"1F64A","order":123,"tags":["evil","face","forbidden","monkey","speak"],"unicode":"🙊"},{"annotation":"kiss mark","group":0,"hexcode":"1F48B","order":124,"tags":["kiss","lips"],"unicode":"💋"},{"annotation":"love letter","group":0,"hexcode":"1F48C","order":125,"tags":["heart","letter","love","mail"],"unicode":"💌"},{"annotation":"heart with arrow","group":0,"hexcode":"1F498","order":126,"tags":["arrow","cupid"],"unicode":"💘"},{"annotation":"heart with ribbon","group":0,"hexcode":"1F49D","order":127,"tags":["ribbon","valentine"],"unicode":"💝"},{"annotation":"sparkling heart","group":0,"hexcode":"1F496","order":128,"tags":["excited","sparkle"],"unicode":"💖"},{"annotation":"growing heart","group":0,"hexcode":"1F497","order":129,"tags":["excited","growing","nervous","pulse"],"unicode":"💗"},{"annotation":"beating heart","group":0,"hexcode":"1F493","order":130,"tags":["beating","heartbeat","pulsating"],"unicode":"💓"},{"annotation":"revolving hearts","group":0,"hexcode":"1F49E","order":131,"tags":["revolving"],"unicode":"💞"},{"annotation":"two hearts","group":0,"hexcode":"1F495","order":132,"tags":["love"],"unicode":"💕"},{"annotation":"heart decoration","group":0,"hexcode":"1F49F","order":133,"tags":["heart"],"unicode":"💟"},{"annotation":"heart exclamation","group":0,"hexcode":"2763","order":135,"tags":["exclamation","mark","punctuation"],"unicode":"❣️"},{"annotation":"broken heart","group":0,"hexcode":"1F494","order":136,"tags":["break","broken"],"unicode":"💔","emoticon":"","skins":[{"annotation":"man mage: light skin tone","group":1,"hexcode":"1F9D9-1F3FB-200D-2642-FE0F","order":1623,"unicode":"🧙🏻‍♂️"},{"annotation":"man mage: medium-light skin tone","group":1,"hexcode":"1F9D9-1F3FC-200D-2642-FE0F","order":1625,"unicode":"🧙🏼‍♂️"},{"annotation":"man mage: medium skin tone","group":1,"hexcode":"1F9D9-1F3FD-200D-2642-FE0F","order":1627,"unicode":"🧙🏽‍♂️"},{"annotation":"man mage: medium-dark skin tone","group":1,"hexcode":"1F9D9-1F3FE-200D-2642-FE0F","order":1629,"unicode":"🧙🏾‍♂️"},{"annotation":"man mage: dark skin tone","group":1,"hexcode":"1F9D9-1F3FF-200D-2642-FE0F","order":1631,"unicode":"🧙🏿‍♂️"}]},{"annotation":"woman mage","group":1,"hexcode":"1F9D9-200D-2640-FE0F","order":1633,"tags":["sorceress","witch"],"unicode":"🧙‍♀️","skins":[{"annotation":"woman mage: light skin tone","group":1,"hexcode":"1F9D9-1F3FB-200D-2640-FE0F","order":1635,"unicode":"🧙🏻‍♀️"},{"annotation":"woman mage: medium-light skin tone","group":1,"hexcode":"1F9D9-1F3FC-200D-2640-FE0F","order":1637,"unicode":"🧙🏼‍♀️"},{"annotation":"woman mage: medium skin tone","group":1,"hexcode":"1F9D9-1F3FD-200D-2640-FE0F","order":1639,"unicode":"🧙🏽‍♀️"},{"annotation":"woman mage: medium-dark skin tone","group":1,"hexcode":"1F9D9-1F3FE-200D-2640-FE0F","order":1641,"unicode":"🧙🏾‍♀️"},{"annotation":"woman mage: dark skin tone","group":1,"hexcode":"1F9D9-1F3FF-200D-2640-FE0F","order":1643,"unicode":"🧙🏿‍♀️"}]},{"annotation":"fairy","group":1,"hexcode":"1F9DA","order":1645,"tags":["oberon","puck","titania"],"unicode":"🧚","skins":[{"annotation":"fairy: light skin tone","group":1,"hexcode":"1F9DA-1F3FB","order":1646,"unicode":"🧚🏻"},{"annotation":"fairy: medium-light skin tone","group":1,"hexcode":"1F9DA-1F3FC","order":1647,"unicode":"🧚🏼"},{"annotation":"fairy: medium skin tone","group":1,"hexcode":"1F9DA-1F3FD","order":1648,"unicode":"🧚🏽"},{"annotation":"fairy: medium-dark skin tone","group":1,"hexcode":"1F9DA-1F3FE","order":1649,"unicode":"🧚🏾"},{"annotation":"fairy: dark skin tone","group":1,"hexcode":"1F9DA-1F3FF","order":1650,"unicode":"🧚🏿"}]},{"annotation":"man fairy","group":1,"hexcode":"1F9DA-200D-2642-FE0F","order":1651,"tags":["oberon","puck"],"unicode":"🧚‍♂️","skins":[{"annotation":"man fairy: light skin tone","group":1,"hexcode":"1F9DA-1F3FB-200D-2642-FE0F","order":1653,"unicode":"🧚🏻‍♂️"},{"annotation":"man fairy: medium-light skin tone","group":1,"hexcode":"1F9DA-1F3FC-200D-2642-FE0F","order":1655,"unicode":"🧚🏼‍♂️"},{"annotation":"man fairy: medium skin tone","group":1,"hexcode":"1F9DA-1F3FD-200D-2642-FE0F","order":1657,"unicode":"🧚🏽‍♂️"},{"annotation":"man fairy: medium-dark skin tone","group":1,"hexcode":"1F9DA-1F3FE-200D-2642-FE0F","order":1659,"unicode":"🧚🏾‍♂️"},{"annotation":"man fairy: dark skin tone","group":1,"hexcode":"1F9DA-1F3FF-200D-2642-FE0F","order":1661,"unicode":"🧚🏿‍♂️"}]},{"annotation":"woman fairy","group":1,"hexcode":"1F9DA-200D-2640-FE0F","order":1663,"tags":["titania"],"unicode":"🧚‍♀️","skins":[{"annotation":"woman fairy: light skin tone","group":1,"hexcode":"1F9DA-1F3FB-200D-2640-FE0F","order":1665,"unicode":"🧚🏻‍♀️"},{"annotation":"woman fairy: medium-light skin tone","group":1,"hexcode":"1F9DA-1F3FC-200D-2640-FE0F","order":1667,"unicode":"🧚🏼‍♀️"},{"annotation":"woman fairy: medium skin tone","group":1,"hexcode":"1F9DA-1F3FD-200D-2640-FE0F","order":1669,"unicode":"🧚🏽‍♀️"},{"annotation":"woman fairy: medium-dark skin tone","group":1,"hexcode":"1F9DA-1F3FE-200D-2640-FE0F","order":1671,"unicode":"🧚🏾‍♀️"},{"annotation":"woman fairy: dark skin tone","group":1,"hexcode":"1F9DA-1F3FF-200D-2640-FE0F","order":1673,"unicode":"🧚🏿‍♀️"}]},{"annotation":"vampire","group":1,"hexcode":"1F9DB","order":1675,"tags":["dracula","undead"],"unicode":"🧛","emoticon":":E","skins":[{"annotation":"vampire: light skin tone","group":1,"hexcode":"1F9DB-1F3FB","order":1676,"unicode":"🧛🏻"},{"annotation":"vampire: medium-light skin tone","group":1,"hexcode":"1F9DB-1F3FC","order":1677,"unicode":"🧛🏼"},{"annotation":"vampire: medium skin tone","group":1,"hexcode":"1F9DB-1F3FD","order":1678,"unicode":"🧛🏽"},{"annotation":"vampire: medium-dark skin tone","group":1,"hexcode":"1F9DB-1F3FE","order":1679,"unicode":"🧛🏾"},{"annotation":"vampire: dark skin tone","group":1,"hexcode":"1F9DB-1F3FF","order":1680,"unicode":"🧛🏿"}]},{"annotation":"man vampire","group":1,"hexcode":"1F9DB-200D-2642-FE0F","order":1681,"tags":["dracula","undead"],"unicode":"🧛‍♂️","skins":[{"annotation":"man vampire: light skin tone","group":1,"hexcode":"1F9DB-1F3FB-200D-2642-FE0F","order":1683,"unicode":"🧛🏻‍♂️"},{"annotation":"man vampire: medium-light skin tone","group":1,"hexcode":"1F9DB-1F3FC-200D-2642-FE0F","order":1685,"unicode":"🧛🏼‍♂️"},{"annotation":"man vampire: medium skin tone","group":1,"hexcode":"1F9DB-1F3FD-200D-2642-FE0F","order":1687,"unicode":"🧛🏽‍♂️"},{"annotation":"man vampire: medium-dark skin tone","group":1,"hexcode":"1F9DB-1F3FE-200D-2642-FE0F","order":1689,"unicode":"🧛🏾‍♂️"},{"annotation":"man vampire: dark skin tone","group":1,"hexcode":"1F9DB-1F3FF-200D-2642-FE0F","order":1691,"unicode":"🧛🏿‍♂️"}]},{"annotation":"woman vampire","group":1,"hexcode":"1F9DB-200D-2640-FE0F","order":1693,"tags":["undead"],"unicode":"🧛‍♀️","skins":[{"annotation":"woman vampire: light skin tone","group":1,"hexcode":"1F9DB-1F3FB-200D-2640-FE0F","order":1695,"unicode":"🧛🏻‍♀️"},{"annotation":"woman vampire: medium-light skin tone","group":1,"hexcode":"1F9DB-1F3FC-200D-2640-FE0F","order":1697,"unicode":"🧛🏼‍♀️"},{"annotation":"woman vampire: medium skin tone","group":1,"hexcode":"1F9DB-1F3FD-200D-2640-FE0F","order":1699,"unicode":"🧛🏽‍♀️"},{"annotation":"woman vampire: medium-dark skin tone","group":1,"hexcode":"1F9DB-1F3FE-200D-2640-FE0F","order":1701,"unicode":"🧛🏾‍♀️"},{"annotation":"woman vampire: dark skin tone","group":1,"hexcode":"1F9DB-1F3FF-200D-2640-FE0F","order":1703,"unicode":"🧛🏿‍♀️"}]},{"annotation":"merperson","group":1,"hexcode":"1F9DC","order":1705,"tags":["mermaid","merman","merwoman"],"unicode":"🧜","skins":[{"annotation":"merperson: light skin tone","group":1,"hexcode":"1F9DC-1F3FB","order":1706,"unicode":"🧜🏻"},{"annotation":"merperson: medium-light skin tone","group":1,"hexcode":"1F9DC-1F3FC","order":1707,"unicode":"🧜🏼"},{"annotation":"merperson: medium skin tone","group":1,"hexcode":"1F9DC-1F3FD","order":1708,"unicode":"🧜🏽"},{"annotation":"merperson: medium-dark skin tone","group":1,"hexcode":"1F9DC-1F3FE","order":1709,"unicode":"🧜🏾"},{"annotation":"merperson: dark skin tone","group":1,"hexcode":"1F9DC-1F3FF","order":1710,"unicode":"🧜🏿"}]},{"annotation":"merman","group":1,"hexcode":"1F9DC-200D-2642-FE0F","order":1711,"tags":["triton"],"unicode":"🧜‍♂️","skins":[{"annotation":"merman: light skin tone","group":1,"hexcode":"1F9DC-1F3FB-200D-2642-FE0F","order":1713,"unicode":"🧜🏻‍♂️"},{"annotation":"merman: medium-light skin tone","group":1,"hexcode":"1F9DC-1F3FC-200D-2642-FE0F","order":1715,"unicode":"🧜🏼‍♂️"},{"annotation":"merman: medium skin tone","group":1,"hexcode":"1F9DC-1F3FD-200D-2642-FE0F","order":1717,"unicode":"🧜🏽‍♂️"},{"annotation":"merman: medium-dark skin tone","group":1,"hexcode":"1F9DC-1F3FE-200D-2642-FE0F","order":1719,"unicode":"🧜🏾‍♂️"},{"annotation":"merman: dark skin tone","group":1,"hexcode":"1F9DC-1F3FF-200D-2642-FE0F","order":1721,"unicode":"🧜🏿‍♂️"}]},{"annotation":"mermaid","group":1,"hexcode":"1F9DC-200D-2640-FE0F","order":1723,"tags":["merwoman"],"unicode":"🧜‍♀️","skins":[{"annotation":"mermaid: light skin tone","group":1,"hexcode":"1F9DC-1F3FB-200D-2640-FE0F","order":1725,"unicode":"🧜🏻‍♀️"},{"annotation":"mermaid: medium-light skin tone","group":1,"hexcode":"1F9DC-1F3FC-200D-2640-FE0F","order":1727,"unicode":"🧜🏼‍♀️"},{"annotation":"mermaid: medium skin tone","group":1,"hexcode":"1F9DC-1F3FD-200D-2640-FE0F","order":1729,"unicode":"🧜🏽‍♀️"},{"annotation":"mermaid: medium-dark skin tone","group":1,"hexcode":"1F9DC-1F3FE-200D-2640-FE0F","order":1731,"unicode":"🧜🏾‍♀️"},{"annotation":"mermaid: dark skin tone","group":1,"hexcode":"1F9DC-1F3FF-200D-2640-FE0F","order":1733,"unicode":"🧜🏿‍♀️"}]},{"annotation":"elf","group":1,"hexcode":"1F9DD","order":1735,"tags":["magical"],"unicode":"🧝","skins":[{"annotation":"elf: light skin tone","group":1,"hexcode":"1F9DD-1F3FB","order":1736,"unicode":"🧝🏻"},{"annotation":"elf: medium-light skin tone","group":1,"hexcode":"1F9DD-1F3FC","order":1737,"unicode":"🧝🏼"},{"annotation":"elf: medium skin tone","group":1,"hexcode":"1F9DD-1F3FD","order":1738,"unicode":"🧝🏽"},{"annotation":"elf: medium-dark skin tone","group":1,"hexcode":"1F9DD-1F3FE","order":1739,"unicode":"🧝🏾"},{"annotation":"elf: dark skin tone","group":1,"hexcode":"1F9DD-1F3FF","order":1740,"unicode":"🧝🏿"}]},{"annotation":"man elf","group":1,"hexcode":"1F9DD-200D-2642-FE0F","order":1741,"tags":["magical"],"unicode":"🧝‍♂️","skins":[{"annotation":"man elf: light skin tone","group":1,"hexcode":"1F9DD-1F3FB-200D-2642-FE0F","order":1743,"unicode":"🧝🏻‍♂️"},{"annotation":"man elf: medium-light skin tone","group":1,"hexcode":"1F9DD-1F3FC-200D-2642-FE0F","order":1745,"unicode":"🧝🏼‍♂️"},{"annotation":"man elf: medium skin tone","group":1,"hexcode":"1F9DD-1F3FD-200D-2642-FE0F","order":1747,"unicode":"🧝🏽‍♂️"},{"annotation":"man elf: medium-dark skin tone","group":1,"hexcode":"1F9DD-1F3FE-200D-2642-FE0F","order":1749,"unicode":"🧝🏾‍♂️"},{"annotation":"man elf: dark skin tone","group":1,"hexcode":"1F9DD-1F3FF-200D-2642-FE0F","order":1751,"unicode":"🧝🏿‍♂️"}]},{"annotation":"woman elf","group":1,"hexcode":"1F9DD-200D-2640-FE0F","order":1753,"tags":["magical"],"unicode":"🧝‍♀️","skins":[{"annotation":"woman elf: light skin tone","group":1,"hexcode":"1F9DD-1F3FB-200D-2640-FE0F","order":1755,"unicode":"🧝🏻‍♀️"},{"annotation":"woman elf: medium-light skin tone","group":1,"hexcode":"1F9DD-1F3FC-200D-2640-FE0F","order":1757,"unicode":"🧝🏼‍♀️"},{"annotation":"woman elf: medium skin tone","group":1,"hexcode":"1F9DD-1F3FD-200D-2640-FE0F","order":1759,"unicode":"🧝🏽‍♀️"},{"annotation":"woman elf: medium-dark skin tone","group":1,"hexcode":"1F9DD-1F3FE-200D-2640-FE0F","order":1761,"unicode":"🧝🏾‍♀️"},{"annotation":"woman elf: dark skin tone","group":1,"hexcode":"1F9DD-1F3FF-200D-2640-FE0F","order":1763,"unicode":"🧝🏿‍♀️"}]},{"annotation":"genie","group":1,"hexcode":"1F9DE","order":1765,"tags":["djinn"],"unicode":"🧞"},{"annotation":"man genie","group":1,"hexcode":"1F9DE-200D-2642-FE0F","order":1766,"tags":["djinn"],"unicode":"🧞‍♂️"},{"annotation":"woman genie","group":1,"hexcode":"1F9DE-200D-2640-FE0F","order":1768,"tags":["djinn"],"unicode":"🧞‍♀️"},{"annotation":"zombie","group":1,"hexcode":"1F9DF","order":1770,"tags":["undead","walking dead"],"unicode":"🧟","emoticon":"8#"},{"annotation":"man zombie","group":1,"hexcode":"1F9DF-200D-2642-FE0F","order":1771,"tags":["undead","walking dead"],"unicode":"🧟‍♂️"},{"annotation":"woman zombie","group":1,"hexcode":"1F9DF-200D-2640-FE0F","order":1773,"tags":["undead","walking dead"],"unicode":"🧟‍♀️"},{"annotation":"person getting massage","group":1,"hexcode":"1F486","order":1775,"tags":["face","massage","salon"],"unicode":"💆","skins":[{"annotation":"person getting massage: light skin tone","group":1,"hexcode":"1F486-1F3FB","order":1776,"unicode":"💆🏻"},{"annotation":"person getting massage: medium-light skin tone","group":1,"hexcode":"1F486-1F3FC","order":1777,"unicode":"💆🏼"},{"annotation":"person getting massage: medium skin tone","group":1,"hexcode":"1F486-1F3FD","order":1778,"unicode":"💆🏽"},{"annotation":"person getting massage: medium-dark skin tone","group":1,"hexcode":"1F486-1F3FE","order":1779,"unicode":"💆🏾"},{"annotation":"person getting massage: dark skin tone","group":1,"hexcode":"1F486-1F3FF","order":1780,"unicode":"💆🏿"}]},{"annotation":"man getting massage","group":1,"hexcode":"1F486-200D-2642-FE0F","order":1781,"tags":["face","man","massage"],"unicode":"💆‍♂️","skins":[{"annotation":"man getting massage: light skin tone","group":1,"hexcode":"1F486-1F3FB-200D-2642-FE0F","order":1783,"unicode":"💆🏻‍♂️"},{"annotation":"man getting massage: medium-light skin tone","group":1,"hexcode":"1F486-1F3FC-200D-2642-FE0F","order":1785,"unicode":"💆🏼‍♂️"},{"annotation":"man getting massage: medium skin tone","group":1,"hexcode":"1F486-1F3FD-200D-2642-FE0F","order":1787,"unicode":"💆🏽‍♂️"},{"annotation":"man getting massage: medium-dark skin tone","group":1,"hexcode":"1F486-1F3FE-200D-2642-FE0F","order":1789,"unicode":"💆🏾‍♂️"},{"annotation":"man getting massage: dark skin tone","group":1,"hexcode":"1F486-1F3FF-200D-2642-FE0F","order":1791,"unicode":"💆🏿‍♂️"}]},{"annotation":"woman getting massage","group":1,"hexcode":"1F486-200D-2640-FE0F","order":1793,"tags":["face","massage","woman"],"unicode":"💆‍♀️","skins":[{"annotation":"woman getting massage: light skin tone","group":1,"hexcode":"1F486-1F3FB-200D-2640-FE0F","order":1795,"unicode":"💆🏻‍♀️"},{"annotation":"woman getting massage: medium-light skin tone","group":1,"hexcode":"1F486-1F3FC-200D-2640-FE0F","order":1797,"unicode":"💆🏼‍♀️"},{"annotation":"woman getting massage: medium skin tone","group":1,"hexcode":"1F486-1F3FD-200D-2640-FE0F","order":1799,"unicode":"💆🏽‍♀️"},{"annotation":"woman getting massage: medium-dark skin tone","group":1,"hexcode":"1F486-1F3FE-200D-2640-FE0F","order":1801,"unicode":"💆🏾‍♀️"},{"annotation":"woman getting massage: dark skin tone","group":1,"hexcode":"1F486-1F3FF-200D-2640-FE0F","order":1803,"unicode":"💆🏿‍♀️"}]},{"annotation":"person getting haircut","group":1,"hexcode":"1F487","order":1805,"tags":["barber","beauty","haircut","parlor"],"unicode":"💇","skins":[{"annotation":"person getting haircut: light skin tone","group":1,"hexcode":"1F487-1F3FB","order":1806,"unicode":"💇🏻"},{"annotation":"person getting haircut: medium-light skin tone","group":1,"hexcode":"1F487-1F3FC","order":1807,"unicode":"💇🏼"},{"annotation":"person getting haircut: medium skin tone","group":1,"hexcode":"1F487-1F3FD","order":1808,"unicode":"💇🏽"},{"annotation":"person getting haircut: medium-dark skin tone","group":1,"hexcode":"1F487-1F3FE","order":1809,"unicode":"💇🏾"},{"annotation":"person getting haircut: dark skin tone","group":1,"hexcode":"1F487-1F3FF","order":1810,"unicode":"💇🏿"}]},{"annotation":"man getting haircut","group":1,"hexcode":"1F487-200D-2642-FE0F","order":1811,"tags":["haircut","man"],"unicode":"💇‍♂️","skins":[{"annotation":"man getting haircut: light skin tone","group":1,"hexcode":"1F487-1F3FB-200D-2642-FE0F","order":1813,"unicode":"💇🏻‍♂️"},{"annotation":"man getting haircut: medium-light skin tone","group":1,"hexcode":"1F487-1F3FC-200D-2642-FE0F","order":1815,"unicode":"💇🏼‍♂️"},{"annotation":"man getting haircut: medium skin tone","group":1,"hexcode":"1F487-1F3FD-200D-2642-FE0F","order":1817,"unicode":"💇🏽‍♂️"},{"annotation":"man getting haircut: medium-dark skin tone","group":1,"hexcode":"1F487-1F3FE-200D-2642-FE0F","order":1819,"unicode":"💇🏾‍♂️"},{"annotation":"man getting haircut: dark skin tone","group":1,"hexcode":"1F487-1F3FF-200D-2642-FE0F","order":1821,"unicode":"💇🏿‍♂️"}]},{"annotation":"woman getting haircut","group":1,"hexcode":"1F487-200D-2640-FE0F","order":1823,"tags":["haircut","woman"],"unicode":"💇‍♀️","skins":[{"annotation":"woman getting haircut: light skin tone","group":1,"hexcode":"1F487-1F3FB-200D-2640-FE0F","order":1825,"unicode":"💇🏻‍♀️"},{"annotation":"woman getting haircut: medium-light skin tone","group":1,"hexcode":"1F487-1F3FC-200D-2640-FE0F","order":1827,"unicode":"💇🏼‍♀️"},{"annotation":"woman getting haircut: medium skin tone","group":1,"hexcode":"1F487-1F3FD-200D-2640-FE0F","order":1829,"unicode":"💇🏽‍♀️"},{"annotation":"woman getting haircut: medium-dark skin tone","group":1,"hexcode":"1F487-1F3FE-200D-2640-FE0F","order":1831,"unicode":"💇🏾‍♀️"},{"annotation":"woman getting haircut: dark skin tone","group":1,"hexcode":"1F487-1F3FF-200D-2640-FE0F","order":1833,"unicode":"💇🏿‍♀️"}]},{"annotation":"person walking","group":1,"hexcode":"1F6B6","order":1835,"tags":["hike","walk","walking"],"unicode":"🚶","skins":[{"annotation":"person walking: light skin tone","group":1,"hexcode":"1F6B6-1F3FB","order":1836,"unicode":"🚶🏻"},{"annotation":"person walking: medium-light skin tone","group":1,"hexcode":"1F6B6-1F3FC","order":1837,"unicode":"🚶🏼"},{"annotation":"person walking: medium skin tone","group":1,"hexcode":"1F6B6-1F3FD","order":1838,"unicode":"🚶🏽"},{"annotation":"person walking: medium-dark skin tone","group":1,"hexcode":"1F6B6-1F3FE","order":1839,"unicode":"🚶🏾"},{"annotation":"person walking: dark skin tone","group":1,"hexcode":"1F6B6-1F3FF","order":1840,"unicode":"🚶🏿"}]},{"annotation":"man walking","group":1,"hexcode":"1F6B6-200D-2642-FE0F","order":1841,"tags":["hike","man","walk"],"unicode":"🚶‍♂️","skins":[{"annotation":"man walking: light skin tone","group":1,"hexcode":"1F6B6-1F3FB-200D-2642-FE0F","order":1843,"unicode":"🚶🏻‍♂️"},{"annotation":"man walking: medium-light skin tone","group":1,"hexcode":"1F6B6-1F3FC-200D-2642-FE0F","order":1845,"unicode":"🚶🏼‍♂️"},{"annotation":"man walking: medium skin tone","group":1,"hexcode":"1F6B6-1F3FD-200D-2642-FE0F","order":1847,"unicode":"🚶🏽‍♂️"},{"annotation":"man walking: medium-dark skin tone","group":1,"hexcode":"1F6B6-1F3FE-200D-2642-FE0F","order":1849,"unicode":"🚶🏾‍♂️"},{"annotation":"man walking: dark skin tone","group":1,"hexcode":"1F6B6-1F3FF-200D-2642-FE0F","order":1851,"unicode":"🚶🏿‍♂️"}]},{"annotation":"woman walking","group":1,"hexcode":"1F6B6-200D-2640-FE0F","order":1853,"tags":["hike","walk","woman"],"unicode":"🚶‍♀️","skins":[{"annotation":"woman walking: light skin tone","group":1,"hexcode":"1F6B6-1F3FB-200D-2640-FE0F","order":1855,"unicode":"🚶🏻‍♀️"},{"annotation":"woman walking: medium-light skin tone","group":1,"hexcode":"1F6B6-1F3FC-200D-2640-FE0F","order":1857,"unicode":"🚶🏼‍♀️"},{"annotation":"woman walking: medium skin tone","group":1,"hexcode":"1F6B6-1F3FD-200D-2640-FE0F","order":1859,"unicode":"🚶🏽‍♀️"},{"annotation":"woman walking: medium-dark skin tone","group":1,"hexcode":"1F6B6-1F3FE-200D-2640-FE0F","order":1861,"unicode":"🚶🏾‍♀️"},{"annotation":"woman walking: dark skin tone","group":1,"hexcode":"1F6B6-1F3FF-200D-2640-FE0F","order":1863,"unicode":"🚶🏿‍♀️"}]},{"annotation":"person standing","group":1,"hexcode":"1F9CD","order":1865,"tags":["stand","standing"],"unicode":"🧍","skins":[{"annotation":"person standing: light skin tone","group":1,"hexcode":"1F9CD-1F3FB","order":1866,"unicode":"🧍🏻"},{"annotation":"person standing: medium-light skin tone","group":1,"hexcode":"1F9CD-1F3FC","order":1867,"unicode":"🧍🏼"},{"annotation":"person standing: medium skin tone","group":1,"hexcode":"1F9CD-1F3FD","order":1868,"unicode":"🧍🏽"},{"annotation":"person standing: medium-dark skin tone","group":1,"hexcode":"1F9CD-1F3FE","order":1869,"unicode":"🧍🏾"},{"annotation":"person standing: dark skin tone","group":1,"hexcode":"1F9CD-1F3FF","order":1870,"unicode":"🧍🏿"}]},{"annotation":"man standing","group":1,"hexcode":"1F9CD-200D-2642-FE0F","order":1871,"tags":["man","standing"],"unicode":"🧍‍♂️","skins":[{"annotation":"man standing: light skin tone","group":1,"hexcode":"1F9CD-1F3FB-200D-2642-FE0F","order":1873,"unicode":"🧍🏻‍♂️"},{"annotation":"man standing: medium-light skin tone","group":1,"hexcode":"1F9CD-1F3FC-200D-2642-FE0F","order":1875,"unicode":"🧍🏼‍♂️"},{"annotation":"man standing: medium skin tone","group":1,"hexcode":"1F9CD-1F3FD-200D-2642-FE0F","order":1877,"unicode":"🧍🏽‍♂️"},{"annotation":"man standing: medium-dark skin tone","group":1,"hexcode":"1F9CD-1F3FE-200D-2642-FE0F","order":1879,"unicode":"🧍🏾‍♂️"},{"annotation":"man standing: dark skin tone","group":1,"hexcode":"1F9CD-1F3FF-200D-2642-FE0F","order":1881,"unicode":"🧍🏿‍♂️"}]},{"annotation":"woman standing","group":1,"hexcode":"1F9CD-200D-2640-FE0F","order":1883,"tags":["standing","woman"],"unicode":"🧍‍♀️","skins":[{"annotation":"woman standing: light skin tone","group":1,"hexcode":"1F9CD-1F3FB-200D-2640-FE0F","order":1885,"unicode":"🧍🏻‍♀️"},{"annotation":"woman standing: medium-light skin tone","group":1,"hexcode":"1F9CD-1F3FC-200D-2640-FE0F","order":1887,"unicode":"🧍🏼‍♀️"},{"annotation":"woman standing: medium skin tone","group":1,"hexcode":"1F9CD-1F3FD-200D-2640-FE0F","order":1889,"unicode":"🧍🏽‍♀️"},{"annotation":"woman standing: medium-dark skin tone","group":1,"hexcode":"1F9CD-1F3FE-200D-2640-FE0F","order":1891,"unicode":"🧍🏾‍♀️"},{"annotation":"woman standing: dark skin tone","group":1,"hexcode":"1F9CD-1F3FF-200D-2640-FE0F","order":1893,"unicode":"🧍🏿‍♀️"}]},{"annotation":"person kneeling","group":1,"hexcode":"1F9CE","order":1895,"tags":["kneel","kneeling"],"unicode":"🧎","skins":[{"annotation":"person kneeling: light skin tone","group":1,"hexcode":"1F9CE-1F3FB","order":1896,"unicode":"🧎🏻"},{"annotation":"person kneeling: medium-light skin tone","group":1,"hexcode":"1F9CE-1F3FC","order":1897,"unicode":"🧎🏼"},{"annotation":"person kneeling: medium skin tone","group":1,"hexcode":"1F9CE-1F3FD","order":1898,"unicode":"🧎🏽"},{"annotation":"person kneeling: medium-dark skin tone","group":1,"hexcode":"1F9CE-1F3FE","order":1899,"unicode":"🧎🏾"},{"annotation":"person kneeling: dark skin tone","group":1,"hexcode":"1F9CE-1F3FF","order":1900,"unicode":"🧎🏿"}]},{"annotation":"man kneeling","group":1,"hexcode":"1F9CE-200D-2642-FE0F","order":1901,"tags":["kneeling","man"],"unicode":"🧎‍♂️","skins":[{"annotation":"man kneeling: light skin tone","group":1,"hexcode":"1F9CE-1F3FB-200D-2642-FE0F","order":1903,"unicode":"🧎🏻‍♂️"},{"annotation":"man kneeling: medium-light skin tone","group":1,"hexcode":"1F9CE-1F3FC-200D-2642-FE0F","order":1905,"unicode":"🧎🏼‍♂️"},{"annotation":"man kneeling: medium skin tone","group":1,"hexcode":"1F9CE-1F3FD-200D-2642-FE0F","order":1907,"unicode":"🧎🏽‍♂️"},{"annotation":"man kneeling: medium-dark skin tone","group":1,"hexcode":"1F9CE-1F3FE-200D-2642-FE0F","order":1909,"unicode":"🧎🏾‍♂️"},{"annotation":"man kneeling: dark skin tone","group":1,"hexcode":"1F9CE-1F3FF-200D-2642-FE0F","order":1911,"unicode":"🧎🏿‍♂️"}]},{"annotation":"woman kneeling","group":1,"hexcode":"1F9CE-200D-2640-FE0F","order":1913,"tags":["kneeling","woman"],"unicode":"🧎‍♀️","skins":[{"annotation":"woman kneeling: light skin tone","group":1,"hexcode":"1F9CE-1F3FB-200D-2640-FE0F","order":1915,"unicode":"🧎🏻‍♀️"},{"annotation":"woman kneeling: medium-light skin tone","group":1,"hexcode":"1F9CE-1F3FC-200D-2640-FE0F","order":1917,"unicode":"🧎🏼‍♀️"},{"annotation":"woman kneeling: medium skin tone","group":1,"hexcode":"1F9CE-1F3FD-200D-2640-FE0F","order":1919,"unicode":"🧎🏽‍♀️"},{"annotation":"woman kneeling: medium-dark skin tone","group":1,"hexcode":"1F9CE-1F3FE-200D-2640-FE0F","order":1921,"unicode":"🧎🏾‍♀️"},{"annotation":"woman kneeling: dark skin tone","group":1,"hexcode":"1F9CE-1F3FF-200D-2640-FE0F","order":1923,"unicode":"🧎🏿‍♀️"}]},{"annotation":"person with white cane","group":1,"hexcode":"1F9D1-200D-1F9AF","order":1925,"tags":["accessibility","blind"],"unicode":"🧑‍🦯","skins":[{"annotation":"person with white cane: light skin tone","group":1,"hexcode":"1F9D1-1F3FB-200D-1F9AF","order":1926,"unicode":"🧑🏻‍🦯"},{"annotation":"person with white cane: medium-light skin tone","group":1,"hexcode":"1F9D1-1F3FC-200D-1F9AF","order":1927,"unicode":"🧑🏼‍🦯"},{"annotation":"person with white cane: medium skin tone","group":1,"hexcode":"1F9D1-1F3FD-200D-1F9AF","order":1928,"unicode":"🧑🏽‍🦯"},{"annotation":"person with white cane: medium-dark skin tone","group":1,"hexcode":"1F9D1-1F3FE-200D-1F9AF","order":1929,"unicode":"🧑🏾‍🦯"},{"annotation":"person with white cane: dark skin tone","group":1,"hexcode":"1F9D1-1F3FF-200D-1F9AF","order":1930,"unicode":"🧑🏿‍🦯"}]},{"annotation":"man with white cane","group":1,"hexcode":"1F468-200D-1F9AF","order":1931,"tags":["accessibility","blind","man"],"unicode":"👨‍🦯","skins":[{"annotation":"man with white cane: light skin tone","group":1,"hexcode":"1F468-1F3FB-200D-1F9AF","order":1932,"unicode":"👨🏻‍🦯"},{"annotation":"man with white cane: medium-light skin tone","group":1,"hexcode":"1F468-1F3FC-200D-1F9AF","order":1933,"unicode":"👨🏼‍🦯"},{"annotation":"man with white cane: medium skin tone","group":1,"hexcode":"1F468-1F3FD-200D-1F9AF","order":1934,"unicode":"👨🏽‍🦯"},{"annotation":"man with white cane: medium-dark skin tone","group":1,"hexcode":"1F468-1F3FE-200D-1F9AF","order":1935,"unicode":"👨🏾‍🦯"},{"annotation":"man with white cane: dark skin tone","group":1,"hexcode":"1F468-1F3FF-200D-1F9AF","order":1936,"unicode":"👨🏿‍🦯"}]},{"annotation":"woman with white cane","group":1,"hexcode":"1F469-200D-1F9AF","order":1937,"tags":["accessibility","blind","woman"],"unicode":"👩‍🦯","skins":[{"annotation":"woman with white cane: light skin tone","group":1,"hexcode":"1F469-1F3FB-200D-1F9AF","order":1938,"unicode":"👩🏻‍🦯"},{"annotation":"woman with white cane: medium-light skin tone","group":1,"hexcode":"1F469-1F3FC-200D-1F9AF","order":1939,"unicode":"👩🏼‍🦯"},{"annotation":"woman with white cane: medium skin tone","group":1,"hexcode":"1F469-1F3FD-200D-1F9AF","order":1940,"unicode":"👩🏽‍🦯"},{"annotation":"woman with white cane: medium-dark skin tone","group":1,"hexcode":"1F469-1F3FE-200D-1F9AF","order":1941,"unicode":"👩🏾‍🦯"},{"annotation":"woman with white cane: dark skin tone","group":1,"hexcode":"1F469-1F3FF-200D-1F9AF","order":1942,"unicode":"👩🏿‍🦯"}]},{"annotation":"person in motorized wheelchair","group":1,"hexcode":"1F9D1-200D-1F9BC","order":1943,"tags":["accessibility","wheelchair"],"unicode":"🧑‍🦼","skins":[{"annotation":"person in motorized wheelchair: light skin tone","group":1,"hexcode":"1F9D1-1F3FB-200D-1F9BC","order":1944,"unicode":"🧑🏻‍🦼"},{"annotation":"person in motorized wheelchair: medium-light skin tone","group":1,"hexcode":"1F9D1-1F3FC-200D-1F9BC","order":1945,"unicode":"🧑🏼‍🦼"},{"annotation":"person in motorized wheelchair: medium skin tone","group":1,"hexcode":"1F9D1-1F3FD-200D-1F9BC","order":1946,"unicode":"🧑🏽‍🦼"},{"annotation":"person in motorized wheelchair: medium-dark skin tone","group":1,"hexcode":"1F9D1-1F3FE-200D-1F9BC","order":1947,"unicode":"🧑🏾‍🦼"},{"annotation":"person in motorized wheelchair: dark skin tone","group":1,"hexcode":"1F9D1-1F3FF-200D-1F9BC","order":1948,"unicode":"🧑🏿‍🦼"}]},{"annotation":"man in motorized wheelchair","group":1,"hexcode":"1F468-200D-1F9BC","order":1949,"tags":["accessibility","man","wheelchair"],"unicode":"👨‍🦼","skins":[{"annotation":"man in motorized wheelchair: light skin tone","group":1,"hexcode":"1F468-1F3FB-200D-1F9BC","order":1950,"unicode":"👨🏻‍🦼"},{"annotation":"man in motorized wheelchair: medium-light skin tone","group":1,"hexcode":"1F468-1F3FC-200D-1F9BC","order":1951,"unicode":"👨🏼‍🦼"},{"annotation":"man in motorized wheelchair: medium skin tone","group":1,"hexcode":"1F468-1F3FD-200D-1F9BC","order":1952,"unicode":"👨🏽‍🦼"},{"annotation":"man in motorized wheelchair: medium-dark skin tone","group":1,"hexcode":"1F468-1F3FE-200D-1F9BC","order":1953,"unicode":"👨🏾‍🦼"},{"annotation":"man in motorized wheelchair: dark skin tone","group":1,"hexcode":"1F468-1F3FF-200D-1F9BC","order":1954,"unicode":"👨🏿‍🦼"}]},{"annotation":"woman in motorized wheelchair","group":1,"hexcode":"1F469-200D-1F9BC","order":1955,"tags":["accessibility","wheelchair","woman"],"unicode":"👩‍🦼","skins":[{"annotation":"woman in motorized wheelchair: light skin tone","group":1,"hexcode":"1F469-1F3FB-200D-1F9BC","order":1956,"unicode":"👩🏻‍🦼"},{"annotation":"woman in motorized wheelchair: medium-light skin tone","group":1,"hexcode":"1F469-1F3FC-200D-1F9BC","order":1957,"unicode":"👩🏼‍🦼"},{"annotation":"woman in motorized wheelchair: medium skin tone","group":1,"hexcode":"1F469-1F3FD-200D-1F9BC","order":1958,"unicode":"👩🏽‍🦼"},{"annotation":"woman in motorized wheelchair: medium-dark skin tone","group":1,"hexcode":"1F469-1F3FE-200D-1F9BC","order":1959,"unicode":"👩🏾‍🦼"},{"annotation":"woman in motorized wheelchair: dark skin tone","group":1,"hexcode":"1F469-1F3FF-200D-1F9BC","order":1960,"unicode":"👩🏿‍🦼"}]},{"annotation":"person in manual wheelchair","group":1,"hexcode":"1F9D1-200D-1F9BD","order":1961,"tags":["accessibility","wheelchair"],"unicode":"🧑‍🦽","skins":[{"annotation":"person in manual wheelchair: light skin tone","group":1,"hexcode":"1F9D1-1F3FB-200D-1F9BD","order":1962,"unicode":"🧑🏻‍🦽"},{"annotation":"person in manual wheelchair: medium-light skin tone","group":1,"hexcode":"1F9D1-1F3FC-200D-1F9BD","order":1963,"unicode":"🧑🏼‍🦽"},{"annotation":"person in manual wheelchair: medium skin tone","group":1,"hexcode":"1F9D1-1F3FD-200D-1F9BD","order":1964,"unicode":"🧑🏽‍🦽"},{"annotation":"person in manual wheelchair: medium-dark skin tone","group":1,"hexcode":"1F9D1-1F3FE-200D-1F9BD","order":1965,"unicode":"🧑🏾‍🦽"},{"annotation":"person in manual wheelchair: dark skin tone","group":1,"hexcode":"1F9D1-1F3FF-200D-1F9BD","order":1966,"unicode":"🧑🏿‍🦽"}]},{"annotation":"man in manual wheelchair","group":1,"hexcode":"1F468-200D-1F9BD","order":1967,"tags":["accessibility","man","wheelchair"],"unicode":"👨‍🦽","skins":[{"annotation":"man in manual wheelchair: light skin tone","group":1,"hexcode":"1F468-1F3FB-200D-1F9BD","order":1968,"unicode":"👨🏻‍🦽"},{"annotation":"man in manual wheelchair: medium-light skin tone","group":1,"hexcode":"1F468-1F3FC-200D-1F9BD","order":1969,"unicode":"👨🏼‍🦽"},{"annotation":"man in manual wheelchair: medium skin tone","group":1,"hexcode":"1F468-1F3FD-200D-1F9BD","order":1970,"unicode":"👨🏽‍🦽"},{"annotation":"man in manual wheelchair: medium-dark skin tone","group":1,"hexcode":"1F468-1F3FE-200D-1F9BD","order":1971,"unicode":"👨🏾‍🦽"},{"annotation":"man in manual wheelchair: dark skin tone","group":1,"hexcode":"1F468-1F3FF-200D-1F9BD","order":1972,"unicode":"👨🏿‍🦽"}]},{"annotation":"woman in manual wheelchair","group":1,"hexcode":"1F469-200D-1F9BD","order":1973,"tags":["accessibility","wheelchair","woman"],"unicode":"👩‍🦽","skins":[{"annotation":"woman in manual wheelchair: light skin tone","group":1,"hexcode":"1F469-1F3FB-200D-1F9BD","order":1974,"unicode":"👩🏻‍🦽"},{"annotation":"woman in manual wheelchair: medium-light skin tone","group":1,"hexcode":"1F469-1F3FC-200D-1F9BD","order":1975,"unicode":"👩🏼‍🦽"},{"annotation":"woman in manual wheelchair: medium skin tone","group":1,"hexcode":"1F469-1F3FD-200D-1F9BD","order":1976,"unicode":"👩🏽‍🦽"},{"annotation":"woman in manual wheelchair: medium-dark skin tone","group":1,"hexcode":"1F469-1F3FE-200D-1F9BD","order":1977,"unicode":"👩🏾‍🦽"},{"annotation":"woman in manual wheelchair: dark skin tone","group":1,"hexcode":"1F469-1F3FF-200D-1F9BD","order":1978,"unicode":"👩🏿‍🦽"}]},{"annotation":"person running","group":1,"hexcode":"1F3C3","order":1979,"tags":["marathon","running"],"unicode":"🏃","skins":[{"annotation":"person running: light skin tone","group":1,"hexcode":"1F3C3-1F3FB","order":1980,"unicode":"🏃🏻"},{"annotation":"person running: medium-light skin tone","group":1,"hexcode":"1F3C3-1F3FC","order":1981,"unicode":"🏃🏼"},{"annotation":"person running: medium skin tone","group":1,"hexcode":"1F3C3-1F3FD","order":1982,"unicode":"🏃🏽"},{"annotation":"person running: medium-dark skin tone","group":1,"hexcode":"1F3C3-1F3FE","order":1983,"unicode":"🏃🏾"},{"annotation":"person running: dark skin tone","group":1,"hexcode":"1F3C3-1F3FF","order":1984,"unicode":"🏃🏿"}]},{"annotation":"man running","group":1,"hexcode":"1F3C3-200D-2642-FE0F","order":1985,"tags":["man","marathon","racing","running"],"unicode":"🏃‍♂️","skins":[{"annotation":"man running: light skin tone","group":1,"hexcode":"1F3C3-1F3FB-200D-2642-FE0F","order":1987,"unicode":"🏃🏻‍♂️"},{"annotation":"man running: medium-light skin tone","group":1,"hexcode":"1F3C3-1F3FC-200D-2642-FE0F","order":1989,"unicode":"🏃🏼‍♂️"},{"annotation":"man running: medium skin tone","group":1,"hexcode":"1F3C3-1F3FD-200D-2642-FE0F","order":1991,"unicode":"🏃🏽‍♂️"},{"annotation":"man running: medium-dark skin tone","group":1,"hexcode":"1F3C3-1F3FE-200D-2642-FE0F","order":1993,"unicode":"🏃🏾‍♂️"},{"annotation":"man running: dark skin tone","group":1,"hexcode":"1F3C3-1F3FF-200D-2642-FE0F","order":1995,"unicode":"🏃🏿‍♂️"}]},{"annotation":"woman running","group":1,"hexcode":"1F3C3-200D-2640-FE0F","order":1997,"tags":["marathon","racing","running","woman"],"unicode":"🏃‍♀️","skins":[{"annotation":"woman running: light skin tone","group":1,"hexcode":"1F3C3-1F3FB-200D-2640-FE0F","order":1999,"unicode":"🏃🏻‍♀️"},{"annotation":"woman running: medium-light skin tone","group":1,"hexcode":"1F3C3-1F3FC-200D-2640-FE0F","order":2001,"unicode":"🏃🏼‍♀️"},{"annotation":"woman running: medium skin tone","group":1,"hexcode":"1F3C3-1F3FD-200D-2640-FE0F","order":2003,"unicode":"🏃🏽‍♀️"},{"annotation":"woman running: medium-dark skin tone","group":1,"hexcode":"1F3C3-1F3FE-200D-2640-FE0F","order":2005,"unicode":"🏃🏾‍♀️"},{"annotation":"woman running: dark skin tone","group":1,"hexcode":"1F3C3-1F3FF-200D-2640-FE0F","order":2007,"unicode":"🏃🏿‍♀️"}]},{"annotation":"woman dancing","group":1,"hexcode":"1F483","order":2009,"tags":["dance","dancing","woman"],"unicode":"💃","skins":[{"annotation":"woman dancing: light skin tone","group":1,"hexcode":"1F483-1F3FB","order":2010,"unicode":"💃🏻"},{"annotation":"woman dancing: medium-light skin tone","group":1,"hexcode":"1F483-1F3FC","order":2011,"unicode":"💃🏼"},{"annotation":"woman dancing: medium skin tone","group":1,"hexcode":"1F483-1F3FD","order":2012,"unicode":"💃🏽"},{"annotation":"woman dancing: medium-dark skin tone","group":1,"hexcode":"1F483-1F3FE","order":2013,"unicode":"💃🏾"},{"annotation":"woman dancing: dark skin tone","group":1,"hexcode":"1F483-1F3FF","order":2014,"unicode":"💃🏿"}]},{"annotation":"man dancing","group":1,"hexcode":"1F57A","order":2015,"tags":["dance","dancing","man"],"unicode":"🕺","skins":[{"annotation":"man dancing: light skin tone","group":1,"hexcode":"1F57A-1F3FB","order":2016,"unicode":"🕺🏻"},{"annotation":"man dancing: medium-light skin tone","group":1,"hexcode":"1F57A-1F3FC","order":2017,"unicode":"🕺🏼"},{"annotation":"man dancing: medium skin tone","group":1,"hexcode":"1F57A-1F3FD","order":2018,"unicode":"🕺🏽"},{"annotation":"man dancing: medium-dark skin tone","group":1,"hexcode":"1F57A-1F3FE","order":2019,"unicode":"🕺🏾"},{"annotation":"man dancing: dark skin tone","group":1,"hexcode":"1F57A-1F3FF","order":2020,"unicode":"🕺🏿"}]},{"annotation":"person in suit levitating","group":1,"hexcode":"1F574","order":2022,"tags":["business","person","suit"],"unicode":"🕴️","skins":[{"annotation":"person in suit levitating: light skin tone","group":1,"hexcode":"1F574-1F3FB","order":2023,"unicode":"🕴🏻"},{"annotation":"person in suit levitating: medium-light skin tone","group":1,"hexcode":"1F574-1F3FC","order":2024,"unicode":"🕴🏼"},{"annotation":"person in suit levitating: medium skin tone","group":1,"hexcode":"1F574-1F3FD","order":2025,"unicode":"🕴🏽"},{"annotation":"person in suit levitating: medium-dark skin tone","group":1,"hexcode":"1F574-1F3FE","order":2026,"unicode":"🕴🏾"},{"annotation":"person in suit levitating: dark skin tone","group":1,"hexcode":"1F574-1F3FF","order":2027,"unicode":"🕴🏿"}]},{"annotation":"people with bunny ears","group":1,"hexcode":"1F46F","order":2028,"tags":["bunny ear","dancer","partying"],"unicode":"👯"},{"annotation":"men with bunny ears","group":1,"hexcode":"1F46F-200D-2642-FE0F","order":2029,"tags":["bunny ear","dancer","men","partying"],"unicode":"👯‍♂️"},{"annotation":"women with bunny ears","group":1,"hexcode":"1F46F-200D-2640-FE0F","order":2031,"tags":["bunny ear","dancer","partying","women"],"unicode":"👯‍♀️"},{"annotation":"person in steamy room","group":1,"hexcode":"1F9D6","order":2033,"tags":["sauna","steam room"],"unicode":"🧖","skins":[{"annotation":"person in steamy room: light skin tone","group":1,"hexcode":"1F9D6-1F3FB","order":2034,"unicode":"🧖🏻"},{"annotation":"person in steamy room: medium-light skin tone","group":1,"hexcode":"1F9D6-1F3FC","order":2035,"unicode":"🧖🏼"},{"annotation":"person in steamy room: medium skin tone","group":1,"hexcode":"1F9D6-1F3FD","order":2036,"unicode":"🧖🏽"},{"annotation":"person in steamy room: medium-dark skin tone","group":1,"hexcode":"1F9D6-1F3FE","order":2037,"unicode":"🧖🏾"},{"annotation":"person in steamy room: dark skin tone","group":1,"hexcode":"1F9D6-1F3FF","order":2038,"unicode":"🧖🏿"}]},{"annotation":"man in steamy room","group":1,"hexcode":"1F9D6-200D-2642-FE0F","order":2039,"tags":["sauna","steam room"],"unicode":"🧖‍♂️","skins":[{"annotation":"man in steamy room: light skin tone","group":1,"hexcode":"1F9D6-1F3FB-200D-2642-FE0F","order":2041,"unicode":"🧖🏻‍♂️"},{"annotation":"man in steamy room: medium-light skin tone","group":1,"hexcode":"1F9D6-1F3FC-200D-2642-FE0F","order":2043,"unicode":"🧖🏼‍♂️"},{"annotation":"man in steamy room: medium skin tone","group":1,"hexcode":"1F9D6-1F3FD-200D-2642-FE0F","order":2045,"unicode":"🧖🏽‍♂️"},{"annotation":"man in steamy room: medium-dark skin tone","group":1,"hexcode":"1F9D6-1F3FE-200D-2642-FE0F","order":2047,"unicode":"🧖🏾‍♂️"},{"annotation":"man in steamy room: dark skin tone","group":1,"hexcode":"1F9D6-1F3FF-200D-2642-FE0F","order":2049,"unicode":"🧖🏿‍♂️"}]},{"annotation":"woman in steamy room","group":1,"hexcode":"1F9D6-200D-2640-FE0F","order":2051,"tags":["sauna","steam room"],"unicode":"🧖‍♀️","skins":[{"annotation":"woman in steamy room: light skin tone","group":1,"hexcode":"1F9D6-1F3FB-200D-2640-FE0F","order":2053,"unicode":"🧖🏻‍♀️"},{"annotation":"woman in steamy room: medium-light skin tone","group":1,"hexcode":"1F9D6-1F3FC-200D-2640-FE0F","order":2055,"unicode":"🧖🏼‍♀️"},{"annotation":"woman in steamy room: medium skin tone","group":1,"hexcode":"1F9D6-1F3FD-200D-2640-FE0F","order":2057,"unicode":"🧖🏽‍♀️"},{"annotation":"woman in steamy room: medium-dark skin tone","group":1,"hexcode":"1F9D6-1F3FE-200D-2640-FE0F","order":2059,"unicode":"🧖🏾‍♀️"},{"annotation":"woman in steamy room: dark skin tone","group":1,"hexcode":"1F9D6-1F3FF-200D-2640-FE0F","order":2061,"unicode":"🧖🏿‍♀️"}]},{"annotation":"person climbing","group":1,"hexcode":"1F9D7","order":2063,"tags":["climber"],"unicode":"🧗","skins":[{"annotation":"person climbing: light skin tone","group":1,"hexcode":"1F9D7-1F3FB","order":2064,"unicode":"🧗🏻"},{"annotation":"person climbing: medium-light skin tone","group":1,"hexcode":"1F9D7-1F3FC","order":2065,"unicode":"🧗🏼"},{"annotation":"person climbing: medium skin tone","group":1,"hexcode":"1F9D7-1F3FD","order":2066,"unicode":"🧗🏽"},{"annotation":"person climbing: medium-dark skin tone","group":1,"hexcode":"1F9D7-1F3FE","order":2067,"unicode":"🧗🏾"},{"annotation":"person climbing: dark skin tone","group":1,"hexcode":"1F9D7-1F3FF","order":2068,"unicode":"🧗🏿"}]},{"annotation":"man climbing","group":1,"hexcode":"1F9D7-200D-2642-FE0F","order":2069,"tags":["climber"],"unicode":"🧗‍♂️","skins":[{"annotation":"man climbing: light skin tone","group":1,"hexcode":"1F9D7-1F3FB-200D-2642-FE0F","order":2071,"unicode":"🧗🏻‍♂️"},{"annotation":"man climbing: medium-light skin tone","group":1,"hexcode":"1F9D7-1F3FC-200D-2642-FE0F","order":2073,"unicode":"🧗🏼‍♂️"},{"annotation":"man climbing: medium skin tone","group":1,"hexcode":"1F9D7-1F3FD-200D-2642-FE0F","order":2075,"unicode":"🧗🏽‍♂️"},{"annotation":"man climbing: medium-dark skin tone","group":1,"hexcode":"1F9D7-1F3FE-200D-2642-FE0F","order":2077,"unicode":"🧗🏾‍♂️"},{"annotation":"man climbing: dark skin tone","group":1,"hexcode":"1F9D7-1F3FF-200D-2642-FE0F","order":2079,"unicode":"🧗🏿‍♂️"}]},{"annotation":"woman climbing","group":1,"hexcode":"1F9D7-200D-2640-FE0F","order":2081,"tags":["climber"],"unicode":"🧗‍♀️","skins":[{"annotation":"woman climbing: light skin tone","group":1,"hexcode":"1F9D7-1F3FB-200D-2640-FE0F","order":2083,"unicode":"🧗🏻‍♀️"},{"annotation":"woman climbing: medium-light skin tone","group":1,"hexcode":"1F9D7-1F3FC-200D-2640-FE0F","order":2085,"unicode":"🧗🏼‍♀️"},{"annotation":"woman climbing: medium skin tone","group":1,"hexcode":"1F9D7-1F3FD-200D-2640-FE0F","order":2087,"unicode":"🧗🏽‍♀️"},{"annotation":"woman climbing: medium-dark skin tone","group":1,"hexcode":"1F9D7-1F3FE-200D-2640-FE0F","order":2089,"unicode":"🧗🏾‍♀️"},{"annotation":"woman climbing: dark skin tone","group":1,"hexcode":"1F9D7-1F3FF-200D-2640-FE0F","order":2091,"unicode":"🧗🏿‍♀️"}]},{"annotation":"person fencing","group":1,"hexcode":"1F93A","order":2093,"tags":["fencer","fencing","sword"],"unicode":"🤺"},{"annotation":"horse racing","group":1,"hexcode":"1F3C7","order":2094,"tags":["horse","jockey","racehorse","racing"],"unicode":"🏇","skins":[{"annotation":"horse racing: light skin tone","group":1,"hexcode":"1F3C7-1F3FB","order":2095,"unicode":"🏇🏻"},{"annotation":"horse racing: medium-light skin tone","group":1,"hexcode":"1F3C7-1F3FC","order":2096,"unicode":"🏇🏼"},{"annotation":"horse racing: medium skin tone","group":1,"hexcode":"1F3C7-1F3FD","order":2097,"unicode":"🏇🏽"},{"annotation":"horse racing: medium-dark skin tone","group":1,"hexcode":"1F3C7-1F3FE","order":2098,"unicode":"🏇🏾"},{"annotation":"horse racing: dark skin tone","group":1,"hexcode":"1F3C7-1F3FF","order":2099,"unicode":"🏇🏿"}]},{"annotation":"skier","group":1,"hexcode":"26F7","order":2101,"tags":["ski","snow"],"unicode":"⛷️"},{"annotation":"snowboarder","group":1,"hexcode":"1F3C2","order":2102,"tags":["ski","snow","snowboard"],"unicode":"🏂️","skins":[{"annotation":"snowboarder: light skin tone","group":1,"hexcode":"1F3C2-1F3FB","order":2103,"unicode":"🏂🏻"},{"annotation":"snowboarder: medium-light skin tone","group":1,"hexcode":"1F3C2-1F3FC","order":2104,"unicode":"🏂🏼"},{"annotation":"snowboarder: medium skin tone","group":1,"hexcode":"1F3C2-1F3FD","order":2105,"unicode":"🏂🏽"},{"annotation":"snowboarder: medium-dark skin tone","group":1,"hexcode":"1F3C2-1F3FE","order":2106,"unicode":"🏂🏾"},{"annotation":"snowboarder: dark skin tone","group":1,"hexcode":"1F3C2-1F3FF","order":2107,"unicode":"🏂🏿"}]},{"annotation":"person golfing","group":1,"hexcode":"1F3CC","order":2109,"tags":["ball","golf"],"unicode":"🏌️","skins":[{"annotation":"person golfing: light skin tone","group":1,"hexcode":"1F3CC-1F3FB","order":2110,"unicode":"🏌🏻"},{"annotation":"person golfing: medium-light skin tone","group":1,"hexcode":"1F3CC-1F3FC","order":2111,"unicode":"🏌🏼"},{"annotation":"person golfing: medium skin tone","group":1,"hexcode":"1F3CC-1F3FD","order":2112,"unicode":"🏌🏽"},{"annotation":"person golfing: medium-dark skin tone","group":1,"hexcode":"1F3CC-1F3FE","order":2113,"unicode":"🏌🏾"},{"annotation":"person golfing: dark skin tone","group":1,"hexcode":"1F3CC-1F3FF","order":2114,"unicode":"🏌🏿"}]},{"annotation":"man golfing","group":1,"hexcode":"1F3CC-FE0F-200D-2642-FE0F","order":2115,"tags":["golf","man"],"unicode":"🏌️‍♂️","skins":[{"annotation":"man golfing: light skin tone","group":1,"hexcode":"1F3CC-1F3FB-200D-2642-FE0F","order":2119,"unicode":"🏌🏻‍♂️"},{"annotation":"man golfing: medium-light skin tone","group":1,"hexcode":"1F3CC-1F3FC-200D-2642-FE0F","order":2121,"unicode":"🏌🏼‍♂️"},{"annotation":"man golfing: medium skin tone","group":1,"hexcode":"1F3CC-1F3FD-200D-2642-FE0F","order":2123,"unicode":"🏌🏽‍♂️"},{"annotation":"man golfing: medium-dark skin tone","group":1,"hexcode":"1F3CC-1F3FE-200D-2642-FE0F","order":2125,"unicode":"🏌🏾‍♂️"},{"annotation":"man golfing: dark skin tone","group":1,"hexcode":"1F3CC-1F3FF-200D-2642-FE0F","order":2127,"unicode":"🏌🏿‍♂️"}]},{"annotation":"woman golfing","group":1,"hexcode":"1F3CC-FE0F-200D-2640-FE0F","order":2129,"tags":["golf","woman"],"unicode":"🏌️‍♀️","skins":[{"annotation":"woman golfing: light skin tone","group":1,"hexcode":"1F3CC-1F3FB-200D-2640-FE0F","order":2133,"unicode":"🏌🏻‍♀️"},{"annotation":"woman golfing: medium-light skin tone","group":1,"hexcode":"1F3CC-1F3FC-200D-2640-FE0F","order":2135,"unicode":"🏌🏼‍♀️"},{"annotation":"woman golfing: medium skin tone","group":1,"hexcode":"1F3CC-1F3FD-200D-2640-FE0F","order":2137,"unicode":"🏌🏽‍♀️"},{"annotation":"woman golfing: medium-dark skin tone","group":1,"hexcode":"1F3CC-1F3FE-200D-2640-FE0F","order":2139,"unicode":"🏌🏾‍♀️"},{"annotation":"woman golfing: dark skin tone","group":1,"hexcode":"1F3CC-1F3FF-200D-2640-FE0F","order":2141,"unicode":"🏌🏿‍♀️"}]},{"annotation":"person surfing","group":1,"hexcode":"1F3C4","order":2143,"tags":["surfing"],"unicode":"🏄️","skins":[{"annotation":"person surfing: light skin tone","group":1,"hexcode":"1F3C4-1F3FB","order":2144,"unicode":"🏄🏻"},{"annotation":"person surfing: medium-light skin tone","group":1,"hexcode":"1F3C4-1F3FC","order":2145,"unicode":"🏄🏼"},{"annotation":"person surfing: medium skin tone","group":1,"hexcode":"1F3C4-1F3FD","order":2146,"unicode":"🏄🏽"},{"annotation":"person surfing: medium-dark skin tone","group":1,"hexcode":"1F3C4-1F3FE","order":2147,"unicode":"🏄🏾"},{"annotation":"person surfing: dark skin tone","group":1,"hexcode":"1F3C4-1F3FF","order":2148,"unicode":"🏄🏿"}]},{"annotation":"man surfing","group":1,"hexcode":"1F3C4-200D-2642-FE0F","order":2149,"tags":["man","surfing"],"unicode":"🏄‍♂️","skins":[{"annotation":"man surfing: light skin tone","group":1,"hexcode":"1F3C4-1F3FB-200D-2642-FE0F","order":2151,"unicode":"🏄🏻‍♂️"},{"annotation":"man surfing: medium-light skin tone","group":1,"hexcode":"1F3C4-1F3FC-200D-2642-FE0F","order":2153,"unicode":"🏄🏼‍♂️"},{"annotation":"man surfing: medium skin tone","group":1,"hexcode":"1F3C4-1F3FD-200D-2642-FE0F","order":2155,"unicode":"🏄🏽‍♂️"},{"annotation":"man surfing: medium-dark skin tone","group":1,"hexcode":"1F3C4-1F3FE-200D-2642-FE0F","order":2157,"unicode":"🏄🏾‍♂️"},{"annotation":"man surfing: dark skin tone","group":1,"hexcode":"1F3C4-1F3FF-200D-2642-FE0F","order":2159,"unicode":"🏄🏿‍♂️"}]},{"annotation":"woman surfing","group":1,"hexcode":"1F3C4-200D-2640-FE0F","order":2161,"tags":["surfing","woman"],"unicode":"🏄‍♀️","skins":[{"annotation":"woman surfing: light skin tone","group":1,"hexcode":"1F3C4-1F3FB-200D-2640-FE0F","order":2163,"unicode":"🏄🏻‍♀️"},{"annotation":"woman surfing: medium-light skin tone","group":1,"hexcode":"1F3C4-1F3FC-200D-2640-FE0F","order":2165,"unicode":"🏄🏼‍♀️"},{"annotation":"woman surfing: medium skin tone","group":1,"hexcode":"1F3C4-1F3FD-200D-2640-FE0F","order":2167,"unicode":"🏄🏽‍♀️"},{"annotation":"woman surfing: medium-dark skin tone","group":1,"hexcode":"1F3C4-1F3FE-200D-2640-FE0F","order":2169,"unicode":"🏄🏾‍♀️"},{"annotation":"woman surfing: dark skin tone","group":1,"hexcode":"1F3C4-1F3FF-200D-2640-FE0F","order":2171,"unicode":"🏄🏿‍♀️"}]},{"annotation":"person rowing boat","group":1,"hexcode":"1F6A3","order":2173,"tags":["boat","rowboat"],"unicode":"🚣","skins":[{"annotation":"person rowing boat: light skin tone","group":1,"hexcode":"1F6A3-1F3FB","order":2174,"unicode":"🚣🏻"},{"annotation":"person rowing boat: medium-light skin tone","group":1,"hexcode":"1F6A3-1F3FC","order":2175,"unicode":"🚣🏼"},{"annotation":"person rowing boat: medium skin tone","group":1,"hexcode":"1F6A3-1F3FD","order":2176,"unicode":"🚣🏽"},{"annotation":"person rowing boat: medium-dark skin tone","group":1,"hexcode":"1F6A3-1F3FE","order":2177,"unicode":"🚣🏾"},{"annotation":"person rowing boat: dark skin tone","group":1,"hexcode":"1F6A3-1F3FF","order":2178,"unicode":"🚣🏿"}]},{"annotation":"man rowing boat","group":1,"hexcode":"1F6A3-200D-2642-FE0F","order":2179,"tags":["boat","man","rowboat"],"unicode":"🚣‍♂️","skins":[{"annotation":"man rowing boat: light skin tone","group":1,"hexcode":"1F6A3-1F3FB-200D-2642-FE0F","order":2181,"unicode":"🚣🏻‍♂️"},{"annotation":"man rowing boat: medium-light skin tone","group":1,"hexcode":"1F6A3-1F3FC-200D-2642-FE0F","order":2183,"unicode":"🚣🏼‍♂️"},{"annotation":"man rowing boat: medium skin tone","group":1,"hexcode":"1F6A3-1F3FD-200D-2642-FE0F","order":2185,"unicode":"🚣🏽‍♂️"},{"annotation":"man rowing boat: medium-dark skin tone","group":1,"hexcode":"1F6A3-1F3FE-200D-2642-FE0F","order":2187,"unicode":"🚣🏾‍♂️"},{"annotation":"man rowing boat: dark skin tone","group":1,"hexcode":"1F6A3-1F3FF-200D-2642-FE0F","order":2189,"unicode":"🚣🏿‍♂️"}]},{"annotation":"woman rowing boat","group":1,"hexcode":"1F6A3-200D-2640-FE0F","order":2191,"tags":["boat","rowboat","woman"],"unicode":"🚣‍♀️","skins":[{"annotation":"woman rowing boat: light skin tone","group":1,"hexcode":"1F6A3-1F3FB-200D-2640-FE0F","order":2193,"unicode":"🚣🏻‍♀️"},{"annotation":"woman rowing boat: medium-light skin tone","group":1,"hexcode":"1F6A3-1F3FC-200D-2640-FE0F","order":2195,"unicode":"🚣🏼‍♀️"},{"annotation":"woman rowing boat: medium skin tone","group":1,"hexcode":"1F6A3-1F3FD-200D-2640-FE0F","order":2197,"unicode":"🚣🏽‍♀️"},{"annotation":"woman rowing boat: medium-dark skin tone","group":1,"hexcode":"1F6A3-1F3FE-200D-2640-FE0F","order":2199,"unicode":"🚣🏾‍♀️"},{"annotation":"woman rowing boat: dark skin tone","group":1,"hexcode":"1F6A3-1F3FF-200D-2640-FE0F","order":2201,"unicode":"🚣🏿‍♀️"}]},{"annotation":"person swimming","group":1,"hexcode":"1F3CA","order":2203,"tags":["swim"],"unicode":"🏊️","skins":[{"annotation":"person swimming: light skin tone","group":1,"hexcode":"1F3CA-1F3FB","order":2204,"unicode":"🏊🏻"},{"annotation":"person swimming: medium-light skin tone","group":1,"hexcode":"1F3CA-1F3FC","order":2205,"unicode":"🏊🏼"},{"annotation":"person swimming: medium skin tone","group":1,"hexcode":"1F3CA-1F3FD","order":2206,"unicode":"🏊🏽"},{"annotation":"person swimming: medium-dark skin tone","group":1,"hexcode":"1F3CA-1F3FE","order":2207,"unicode":"🏊🏾"},{"annotation":"person swimming: dark skin tone","group":1,"hexcode":"1F3CA-1F3FF","order":2208,"unicode":"🏊🏿"}]},{"annotation":"man swimming","group":1,"hexcode":"1F3CA-200D-2642-FE0F","order":2209,"tags":["man","swim"],"unicode":"🏊‍♂️","skins":[{"annotation":"man swimming: light skin tone","group":1,"hexcode":"1F3CA-1F3FB-200D-2642-FE0F","order":2211,"unicode":"🏊🏻‍♂️"},{"annotation":"man swimming: medium-light skin tone","group":1,"hexcode":"1F3CA-1F3FC-200D-2642-FE0F","order":2213,"unicode":"🏊🏼‍♂️"},{"annotation":"man swimming: medium skin tone","group":1,"hexcode":"1F3CA-1F3FD-200D-2642-FE0F","order":2215,"unicode":"🏊🏽‍♂️"},{"annotation":"man swimming: medium-dark skin tone","group":1,"hexcode":"1F3CA-1F3FE-200D-2642-FE0F","order":2217,"unicode":"🏊🏾‍♂️"},{"annotation":"man swimming: dark skin tone","group":1,"hexcode":"1F3CA-1F3FF-200D-2642-FE0F","order":2219,"unicode":"🏊🏿‍♂️"}]},{"annotation":"woman swimming","group":1,"hexcode":"1F3CA-200D-2640-FE0F","order":2221,"tags":["swim","woman"],"unicode":"🏊‍♀️","skins":[{"annotation":"woman swimming: light skin tone","group":1,"hexcode":"1F3CA-1F3FB-200D-2640-FE0F","order":2223,"unicode":"🏊🏻‍♀️"},{"annotation":"woman swimming: medium-light skin tone","group":1,"hexcode":"1F3CA-1F3FC-200D-2640-FE0F","order":2225,"unicode":"🏊🏼‍♀️"},{"annotation":"woman swimming: medium skin tone","group":1,"hexcode":"1F3CA-1F3FD-200D-2640-FE0F","order":2227,"unicode":"🏊🏽‍♀️"},{"annotation":"woman swimming: medium-dark skin tone","group":1,"hexcode":"1F3CA-1F3FE-200D-2640-FE0F","order":2229,"unicode":"🏊🏾‍♀️"},{"annotation":"woman swimming: dark skin tone","group":1,"hexcode":"1F3CA-1F3FF-200D-2640-FE0F","order":2231,"unicode":"🏊🏿‍♀️"}]},{"annotation":"person bouncing ball","group":1,"hexcode":"26F9","order":2234,"tags":["ball"],"unicode":"⛹️","skins":[{"annotation":"person bouncing ball: light skin tone","group":1,"hexcode":"26F9-1F3FB","order":2235,"unicode":"⛹🏻"},{"annotation":"person bouncing ball: medium-light skin tone","group":1,"hexcode":"26F9-1F3FC","order":2236,"unicode":"⛹🏼"},{"annotation":"person bouncing ball: medium skin tone","group":1,"hexcode":"26F9-1F3FD","order":2237,"unicode":"⛹🏽"},{"annotation":"person bouncing ball: medium-dark skin tone","group":1,"hexcode":"26F9-1F3FE","order":2238,"unicode":"⛹🏾"},{"annotation":"person bouncing ball: dark skin tone","group":1,"hexcode":"26F9-1F3FF","order":2239,"unicode":"⛹🏿"}]},{"annotation":"man bouncing ball","group":1,"hexcode":"26F9-FE0F-200D-2642-FE0F","order":2240,"tags":["ball","man"],"unicode":"⛹️‍♂️","skins":[{"annotation":"man bouncing ball: light skin tone","group":1,"hexcode":"26F9-1F3FB-200D-2642-FE0F","order":2244,"unicode":"⛹🏻‍♂️"},{"annotation":"man bouncing ball: medium-light skin tone","group":1,"hexcode":"26F9-1F3FC-200D-2642-FE0F","order":2246,"unicode":"⛹🏼‍♂️"},{"annotation":"man bouncing ball: medium skin tone","group":1,"hexcode":"26F9-1F3FD-200D-2642-FE0F","order":2248,"unicode":"⛹🏽‍♂️"},{"annotation":"man bouncing ball: medium-dark skin tone","group":1,"hexcode":"26F9-1F3FE-200D-2642-FE0F","order":2250,"unicode":"⛹🏾‍♂️"},{"annotation":"man bouncing ball: dark skin tone","group":1,"hexcode":"26F9-1F3FF-200D-2642-FE0F","order":2252,"unicode":"⛹🏿‍♂️"}]},{"annotation":"woman bouncing ball","group":1,"hexcode":"26F9-FE0F-200D-2640-FE0F","order":2254,"tags":["ball","woman"],"unicode":"⛹️‍♀️","skins":[{"annotation":"woman bouncing ball: light skin tone","group":1,"hexcode":"26F9-1F3FB-200D-2640-FE0F","order":2258,"unicode":"⛹🏻‍♀️"},{"annotation":"woman bouncing ball: medium-light skin tone","group":1,"hexcode":"26F9-1F3FC-200D-2640-FE0F","order":2260,"unicode":"⛹🏼‍♀️"},{"annotation":"woman bouncing ball: medium skin tone","group":1,"hexcode":"26F9-1F3FD-200D-2640-FE0F","order":2262,"unicode":"⛹🏽‍♀️"},{"annotation":"woman bouncing ball: medium-dark skin tone","group":1,"hexcode":"26F9-1F3FE-200D-2640-FE0F","order":2264,"unicode":"⛹🏾‍♀️"},{"annotation":"woman bouncing ball: dark skin tone","group":1,"hexcode":"26F9-1F3FF-200D-2640-FE0F","order":2266,"unicode":"⛹🏿‍♀️"}]},{"annotation":"person lifting weights","group":1,"hexcode":"1F3CB","order":2269,"tags":["lifter","weight"],"unicode":"🏋️","skins":[{"annotation":"person lifting weights: light skin tone","group":1,"hexcode":"1F3CB-1F3FB","order":2270,"unicode":"🏋🏻"},{"annotation":"person lifting weights: medium-light skin tone","group":1,"hexcode":"1F3CB-1F3FC","order":2271,"unicode":"🏋🏼"},{"annotation":"person lifting weights: medium skin tone","group":1,"hexcode":"1F3CB-1F3FD","order":2272,"unicode":"🏋🏽"},{"annotation":"person lifting weights: medium-dark skin tone","group":1,"hexcode":"1F3CB-1F3FE","order":2273,"unicode":"🏋🏾"},{"annotation":"person lifting weights: dark skin tone","group":1,"hexcode":"1F3CB-1F3FF","order":2274,"unicode":"🏋🏿"}]},{"annotation":"man lifting weights","group":1,"hexcode":"1F3CB-FE0F-200D-2642-FE0F","order":2275,"tags":["man","weight lifter"],"unicode":"🏋️‍♂️","skins":[{"annotation":"man lifting weights: light skin tone","group":1,"hexcode":"1F3CB-1F3FB-200D-2642-FE0F","order":2279,"unicode":"🏋🏻‍♂️"},{"annotation":"man lifting weights: medium-light skin tone","group":1,"hexcode":"1F3CB-1F3FC-200D-2642-FE0F","order":2281,"unicode":"🏋🏼‍♂️"},{"annotation":"man lifting weights: medium skin tone","group":1,"hexcode":"1F3CB-1F3FD-200D-2642-FE0F","order":2283,"unicode":"🏋🏽‍♂️"},{"annotation":"man lifting weights: medium-dark skin tone","group":1,"hexcode":"1F3CB-1F3FE-200D-2642-FE0F","order":2285,"unicode":"🏋🏾‍♂️"},{"annotation":"man lifting weights: dark skin tone","group":1,"hexcode":"1F3CB-1F3FF-200D-2642-FE0F","order":2287,"unicode":"🏋🏿‍♂️"}]},{"annotation":"woman lifting weights","group":1,"hexcode":"1F3CB-FE0F-200D-2640-FE0F","order":2289,"tags":["weight lifter","woman"],"unicode":"🏋️‍♀️","skins":[{"annotation":"woman lifting weights: light skin tone","group":1,"hexcode":"1F3CB-1F3FB-200D-2640-FE0F","order":2293,"unicode":"🏋🏻‍♀️"},{"annotation":"woman lifting weights: medium-light skin tone","group":1,"hexcode":"1F3CB-1F3FC-200D-2640-FE0F","order":2295,"unicode":"🏋🏼‍♀️"},{"annotation":"woman lifting weights: medium skin tone","group":1,"hexcode":"1F3CB-1F3FD-200D-2640-FE0F","order":2297,"unicode":"🏋🏽‍♀️"},{"annotation":"woman lifting weights: medium-dark skin tone","group":1,"hexcode":"1F3CB-1F3FE-200D-2640-FE0F","order":2299,"unicode":"🏋🏾‍♀️"},{"annotation":"woman lifting weights: dark skin tone","group":1,"hexcode":"1F3CB-1F3FF-200D-2640-FE0F","order":2301,"unicode":"🏋🏿‍♀️"}]},{"annotation":"person biking","group":1,"hexcode":"1F6B4","order":2303,"tags":["bicycle","biking","cyclist"],"unicode":"🚴","skins":[{"annotation":"person biking: light skin tone","group":1,"hexcode":"1F6B4-1F3FB","order":2304,"unicode":"🚴🏻"},{"annotation":"person biking: medium-light skin tone","group":1,"hexcode":"1F6B4-1F3FC","order":2305,"unicode":"🚴🏼"},{"annotation":"person biking: medium skin tone","group":1,"hexcode":"1F6B4-1F3FD","order":2306,"unicode":"🚴🏽"},{"annotation":"person biking: medium-dark skin tone","group":1,"hexcode":"1F6B4-1F3FE","order":2307,"unicode":"🚴🏾"},{"annotation":"person biking: dark skin tone","group":1,"hexcode":"1F6B4-1F3FF","order":2308,"unicode":"🚴🏿"}]},{"annotation":"man biking","group":1,"hexcode":"1F6B4-200D-2642-FE0F","order":2309,"tags":["bicycle","biking","cyclist","man"],"unicode":"🚴‍♂️","skins":[{"annotation":"man biking: light skin tone","group":1,"hexcode":"1F6B4-1F3FB-200D-2642-FE0F","order":2311,"unicode":"🚴🏻‍♂️"},{"annotation":"man biking: medium-light skin tone","group":1,"hexcode":"1F6B4-1F3FC-200D-2642-FE0F","order":2313,"unicode":"🚴🏼‍♂️"},{"annotation":"man biking: medium skin tone","group":1,"hexcode":"1F6B4-1F3FD-200D-2642-FE0F","order":2315,"unicode":"🚴🏽‍♂️"},{"annotation":"man biking: medium-dark skin tone","group":1,"hexcode":"1F6B4-1F3FE-200D-2642-FE0F","order":2317,"unicode":"🚴🏾‍♂️"},{"annotation":"man biking: dark skin tone","group":1,"hexcode":"1F6B4-1F3FF-200D-2642-FE0F","order":2319,"unicode":"🚴🏿‍♂️"}]},{"annotation":"woman biking","group":1,"hexcode":"1F6B4-200D-2640-FE0F","order":2321,"tags":["bicycle","biking","cyclist","woman"],"unicode":"🚴‍♀️","skins":[{"annotation":"woman biking: light skin tone","group":1,"hexcode":"1F6B4-1F3FB-200D-2640-FE0F","order":2323,"unicode":"🚴🏻‍♀️"},{"annotation":"woman biking: medium-light skin tone","group":1,"hexcode":"1F6B4-1F3FC-200D-2640-FE0F","order":2325,"unicode":"🚴🏼‍♀️"},{"annotation":"woman biking: medium skin tone","group":1,"hexcode":"1F6B4-1F3FD-200D-2640-FE0F","order":2327,"unicode":"🚴🏽‍♀️"},{"annotation":"woman biking: medium-dark skin tone","group":1,"hexcode":"1F6B4-1F3FE-200D-2640-FE0F","order":2329,"unicode":"🚴🏾‍♀️"},{"annotation":"woman biking: dark skin tone","group":1,"hexcode":"1F6B4-1F3FF-200D-2640-FE0F","order":2331,"unicode":"🚴🏿‍♀️"}]},{"annotation":"person mountain biking","group":1,"hexcode":"1F6B5","order":2333,"tags":["bicycle","bicyclist","bike","cyclist","mountain"],"unicode":"🚵","skins":[{"annotation":"person mountain biking: light skin tone","group":1,"hexcode":"1F6B5-1F3FB","order":2334,"unicode":"🚵🏻"},{"annotation":"person mountain biking: medium-light skin tone","group":1,"hexcode":"1F6B5-1F3FC","order":2335,"unicode":"🚵🏼"},{"annotation":"person mountain biking: medium skin tone","group":1,"hexcode":"1F6B5-1F3FD","order":2336,"unicode":"🚵🏽"},{"annotation":"person mountain biking: medium-dark skin tone","group":1,"hexcode":"1F6B5-1F3FE","order":2337,"unicode":"🚵🏾"},{"annotation":"person mountain biking: dark skin tone","group":1,"hexcode":"1F6B5-1F3FF","order":2338,"unicode":"🚵🏿"}]},{"annotation":"man mountain biking","group":1,"hexcode":"1F6B5-200D-2642-FE0F","order":2339,"tags":["bicycle","bike","cyclist","man","mountain"],"unicode":"🚵‍♂️","skins":[{"annotation":"man mountain biking: light skin tone","group":1,"hexcode":"1F6B5-1F3FB-200D-2642-FE0F","order":2341,"unicode":"🚵🏻‍♂️"},{"annotation":"man mountain biking: medium-light skin tone","group":1,"hexcode":"1F6B5-1F3FC-200D-2642-FE0F","order":2343,"unicode":"🚵🏼‍♂️"},{"annotation":"man mountain biking: medium skin tone","group":1,"hexcode":"1F6B5-1F3FD-200D-2642-FE0F","order":2345,"unicode":"🚵🏽‍♂️"},{"annotation":"man mountain biking: medium-dark skin tone","group":1,"hexcode":"1F6B5-1F3FE-200D-2642-FE0F","order":2347,"unicode":"🚵🏾‍♂️"},{"annotation":"man mountain biking: dark skin tone","group":1,"hexcode":"1F6B5-1F3FF-200D-2642-FE0F","order":2349,"unicode":"🚵🏿‍♂️"}]},{"annotation":"woman mountain biking","group":1,"hexcode":"1F6B5-200D-2640-FE0F","order":2351,"tags":["bicycle","bike","biking","cyclist","mountain","woman"],"unicode":"🚵‍♀️","skins":[{"annotation":"woman mountain biking: light skin tone","group":1,"hexcode":"1F6B5-1F3FB-200D-2640-FE0F","order":2353,"unicode":"🚵🏻‍♀️"},{"annotation":"woman mountain biking: medium-light skin tone","group":1,"hexcode":"1F6B5-1F3FC-200D-2640-FE0F","order":2355,"unicode":"🚵🏼‍♀️"},{"annotation":"woman mountain biking: medium skin tone","group":1,"hexcode":"1F6B5-1F3FD-200D-2640-FE0F","order":2357,"unicode":"🚵🏽‍♀️"},{"annotation":"woman mountain biking: medium-dark skin tone","group":1,"hexcode":"1F6B5-1F3FE-200D-2640-FE0F","order":2359,"unicode":"🚵🏾‍♀️"},{"annotation":"woman mountain biking: dark skin tone","group":1,"hexcode":"1F6B5-1F3FF-200D-2640-FE0F","order":2361,"unicode":"🚵🏿‍♀️"}]},{"annotation":"person cartwheeling","group":1,"hexcode":"1F938","order":2363,"tags":["cartwheel","gymnastics"],"unicode":"🤸","skins":[{"annotation":"person cartwheeling: light skin tone","group":1,"hexcode":"1F938-1F3FB","order":2364,"unicode":"🤸🏻"},{"annotation":"person cartwheeling: medium-light skin tone","group":1,"hexcode":"1F938-1F3FC","order":2365,"unicode":"🤸🏼"},{"annotation":"person cartwheeling: medium skin tone","group":1,"hexcode":"1F938-1F3FD","order":2366,"unicode":"🤸🏽"},{"annotation":"person cartwheeling: medium-dark skin tone","group":1,"hexcode":"1F938-1F3FE","order":2367,"unicode":"🤸🏾"},{"annotation":"person cartwheeling: dark skin tone","group":1,"hexcode":"1F938-1F3FF","order":2368,"unicode":"🤸🏿"}]},{"annotation":"man cartwheeling","group":1,"hexcode":"1F938-200D-2642-FE0F","order":2369,"tags":["cartwheel","gymnastics","man"],"unicode":"🤸‍♂️","skins":[{"annotation":"man cartwheeling: light skin tone","group":1,"hexcode":"1F938-1F3FB-200D-2642-FE0F","order":2371,"unicode":"🤸🏻‍♂️"},{"annotation":"man cartwheeling: medium-light skin tone","group":1,"hexcode":"1F938-1F3FC-200D-2642-FE0F","order":2373,"unicode":"🤸🏼‍♂️"},{"annotation":"man cartwheeling: medium skin tone","group":1,"hexcode":"1F938-1F3FD-200D-2642-FE0F","order":2375,"unicode":"🤸🏽‍♂️"},{"annotation":"man cartwheeling: medium-dark skin tone","group":1,"hexcode":"1F938-1F3FE-200D-2642-FE0F","order":2377,"unicode":"🤸🏾‍♂️"},{"annotation":"man cartwheeling: dark skin tone","group":1,"hexcode":"1F938-1F3FF-200D-2642-FE0F","order":2379,"unicode":"🤸🏿‍♂️"}]},{"annotation":"woman cartwheeling","group":1,"hexcode":"1F938-200D-2640-FE0F","order":2381,"tags":["cartwheel","gymnastics","woman"],"unicode":"🤸‍♀️","skins":[{"annotation":"woman cartwheeling: light skin tone","group":1,"hexcode":"1F938-1F3FB-200D-2640-FE0F","order":2383,"unicode":"🤸🏻‍♀️"},{"annotation":"woman cartwheeling: medium-light skin tone","group":1,"hexcode":"1F938-1F3FC-200D-2640-FE0F","order":2385,"unicode":"🤸🏼‍♀️"},{"annotation":"woman cartwheeling: medium skin tone","group":1,"hexcode":"1F938-1F3FD-200D-2640-FE0F","order":2387,"unicode":"🤸🏽‍♀️"},{"annotation":"woman cartwheeling: medium-dark skin tone","group":1,"hexcode":"1F938-1F3FE-200D-2640-FE0F","order":2389,"unicode":"🤸🏾‍♀️"},{"annotation":"woman cartwheeling: dark skin tone","group":1,"hexcode":"1F938-1F3FF-200D-2640-FE0F","order":2391,"unicode":"🤸🏿‍♀️"}]},{"annotation":"people wrestling","group":1,"hexcode":"1F93C","order":2393,"tags":["wrestle","wrestler"],"unicode":"🤼"},{"annotation":"men wrestling","group":1,"hexcode":"1F93C-200D-2642-FE0F","order":2394,"tags":["men","wrestle"],"unicode":"🤼‍♂️"},{"annotation":"women wrestling","group":1,"hexcode":"1F93C-200D-2640-FE0F","order":2396,"tags":["women","wrestle"],"unicode":"🤼‍♀️"},{"annotation":"person playing water polo","group":1,"hexcode":"1F93D","order":2398,"tags":["polo","water"],"unicode":"🤽","skins":[{"annotation":"person playing water polo: light skin tone","group":1,"hexcode":"1F93D-1F3FB","order":2399,"unicode":"🤽🏻"},{"annotation":"person playing water polo: medium-light skin tone","group":1,"hexcode":"1F93D-1F3FC","order":2400,"unicode":"🤽🏼"},{"annotation":"person playing water polo: medium skin tone","group":1,"hexcode":"1F93D-1F3FD","order":2401,"unicode":"🤽🏽"},{"annotation":"person playing water polo: medium-dark skin tone","group":1,"hexcode":"1F93D-1F3FE","order":2402,"unicode":"🤽🏾"},{"annotation":"person playing water polo: dark skin tone","group":1,"hexcode":"1F93D-1F3FF","order":2403,"unicode":"🤽🏿"}]},{"annotation":"man playing water polo","group":1,"hexcode":"1F93D-200D-2642-FE0F","order":2404,"tags":["man","water polo"],"unicode":"🤽‍♂️","skins":[{"annotation":"man playing water polo: light skin tone","group":1,"hexcode":"1F93D-1F3FB-200D-2642-FE0F","order":2406,"unicode":"🤽🏻‍♂️"},{"annotation":"man playing water polo: medium-light skin tone","group":1,"hexcode":"1F93D-1F3FC-200D-2642-FE0F","order":2408,"unicode":"🤽🏼‍♂️"},{"annotation":"man playing water polo: medium skin tone","group":1,"hexcode":"1F93D-1F3FD-200D-2642-FE0F","order":2410,"unicode":"🤽🏽‍♂️"},{"annotation":"man playing water polo: medium-dark skin tone","group":1,"hexcode":"1F93D-1F3FE-200D-2642-FE0F","order":2412,"unicode":"🤽🏾‍♂️"},{"annotation":"man playing water polo: dark skin tone","group":1,"hexcode":"1F93D-1F3FF-200D-2642-FE0F","order":2414,"unicode":"🤽🏿‍♂️"}]},{"annotation":"woman playing water polo","group":1,"hexcode":"1F93D-200D-2640-FE0F","order":2416,"tags":["water polo","woman"],"unicode":"🤽‍♀️","skins":[{"annotation":"woman playing water polo: light skin tone","group":1,"hexcode":"1F93D-1F3FB-200D-2640-FE0F","order":2418,"unicode":"🤽🏻‍♀️"},{"annotation":"woman playing water polo: medium-light skin tone","group":1,"hexcode":"1F93D-1F3FC-200D-2640-FE0F","order":2420,"unicode":"🤽🏼‍♀️"},{"annotation":"woman playing water polo: medium skin tone","group":1,"hexcode":"1F93D-1F3FD-200D-2640-FE0F","order":2422,"unicode":"🤽🏽‍♀️"},{"annotation":"woman playing water polo: medium-dark skin tone","group":1,"hexcode":"1F93D-1F3FE-200D-2640-FE0F","order":2424,"unicode":"🤽🏾‍♀️"},{"annotation":"woman playing water polo: dark skin tone","group":1,"hexcode":"1F93D-1F3FF-200D-2640-FE0F","order":2426,"unicode":"🤽🏿‍♀️"}]},{"annotation":"person playing handball","group":1,"hexcode":"1F93E","order":2428,"tags":["ball","handball"],"unicode":"🤾","skins":[{"annotation":"person playing handball: light skin tone","group":1,"hexcode":"1F93E-1F3FB","order":2429,"unicode":"🤾🏻"},{"annotation":"person playing handball: medium-light skin tone","group":1,"hexcode":"1F93E-1F3FC","order":2430,"unicode":"🤾🏼"},{"annotation":"person playing handball: medium skin tone","group":1,"hexcode":"1F93E-1F3FD","order":2431,"unicode":"🤾🏽"},{"annotation":"person playing handball: medium-dark skin tone","group":1,"hexcode":"1F93E-1F3FE","order":2432,"unicode":"🤾🏾"},{"annotation":"person playing handball: dark skin tone","group":1,"hexcode":"1F93E-1F3FF","order":2433,"unicode":"🤾🏿"}]},{"annotation":"man playing handball","group":1,"hexcode":"1F93E-200D-2642-FE0F","order":2434,"tags":["handball","man"],"unicode":"🤾‍♂️","skins":[{"annotation":"man playing handball: light skin tone","group":1,"hexcode":"1F93E-1F3FB-200D-2642-FE0F","order":2436,"unicode":"🤾🏻‍♂️"},{"annotation":"man playing handball: medium-light skin tone","group":1,"hexcode":"1F93E-1F3FC-200D-2642-FE0F","order":2438,"unicode":"🤾🏼‍♂️"},{"annotation":"man playing handball: medium skin tone","group":1,"hexcode":"1F93E-1F3FD-200D-2642-FE0F","order":2440,"unicode":"🤾🏽‍♂️"},{"annotation":"man playing handball: medium-dark skin tone","group":1,"hexcode":"1F93E-1F3FE-200D-2642-FE0F","order":2442,"unicode":"🤾🏾‍♂️"},{"annotation":"man playing handball: dark skin tone","group":1,"hexcode":"1F93E-1F3FF-200D-2642-FE0F","order":2444,"unicode":"🤾🏿‍♂️"}]},{"annotation":"woman playing handball","group":1,"hexcode":"1F93E-200D-2640-FE0F","order":2446,"tags":["handball","woman"],"unicode":"🤾‍♀️","skins":[{"annotation":"woman playing handball: light skin tone","group":1,"hexcode":"1F93E-1F3FB-200D-2640-FE0F","order":2448,"unicode":"🤾🏻‍♀️"},{"annotation":"woman playing handball: medium-light skin tone","group":1,"hexcode":"1F93E-1F3FC-200D-2640-FE0F","order":2450,"unicode":"🤾🏼‍♀️"},{"annotation":"woman playing handball: medium skin tone","group":1,"hexcode":"1F93E-1F3FD-200D-2640-FE0F","order":2452,"unicode":"🤾🏽‍♀️"},{"annotation":"woman playing handball: medium-dark skin tone","group":1,"hexcode":"1F93E-1F3FE-200D-2640-FE0F","order":2454,"unicode":"🤾🏾‍♀️"},{"annotation":"woman playing handball: dark skin tone","group":1,"hexcode":"1F93E-1F3FF-200D-2640-FE0F","order":2456,"unicode":"🤾🏿‍♀️"}]},{"annotation":"person juggling","group":1,"hexcode":"1F939","order":2458,"tags":["balance","juggle","multitask","skill"],"unicode":"🤹","skins":[{"annotation":"person juggling: light skin tone","group":1,"hexcode":"1F939-1F3FB","order":2459,"unicode":"🤹🏻"},{"annotation":"person juggling: medium-light skin tone","group":1,"hexcode":"1F939-1F3FC","order":2460,"unicode":"🤹🏼"},{"annotation":"person juggling: medium skin tone","group":1,"hexcode":"1F939-1F3FD","order":2461,"unicode":"🤹🏽"},{"annotation":"person juggling: medium-dark skin tone","group":1,"hexcode":"1F939-1F3FE","order":2462,"unicode":"🤹🏾"},{"annotation":"person juggling: dark skin tone","group":1,"hexcode":"1F939-1F3FF","order":2463,"unicode":"🤹🏿"}]},{"annotation":"man juggling","group":1,"hexcode":"1F939-200D-2642-FE0F","order":2464,"tags":["juggling","man","multitask"],"unicode":"🤹‍♂️","skins":[{"annotation":"man juggling: light skin tone","group":1,"hexcode":"1F939-1F3FB-200D-2642-FE0F","order":2466,"unicode":"🤹🏻‍♂️"},{"annotation":"man juggling: medium-light skin tone","group":1,"hexcode":"1F939-1F3FC-200D-2642-FE0F","order":2468,"unicode":"🤹🏼‍♂️"},{"annotation":"man juggling: medium skin tone","group":1,"hexcode":"1F939-1F3FD-200D-2642-FE0F","order":2470,"unicode":"🤹🏽‍♂️"},{"annotation":"man juggling: medium-dark skin tone","group":1,"hexcode":"1F939-1F3FE-200D-2642-FE0F","order":2472,"unicode":"🤹🏾‍♂️"},{"annotation":"man juggling: dark skin tone","group":1,"hexcode":"1F939-1F3FF-200D-2642-FE0F","order":2474,"unicode":"🤹🏿‍♂️"}]},{"annotation":"woman juggling","group":1,"hexcode":"1F939-200D-2640-FE0F","order":2476,"tags":["juggling","multitask","woman"],"unicode":"🤹‍♀️","skins":[{"annotation":"woman juggling: light skin tone","group":1,"hexcode":"1F939-1F3FB-200D-2640-FE0F","order":2478,"unicode":"🤹🏻‍♀️"},{"annotation":"woman juggling: medium-light skin tone","group":1,"hexcode":"1F939-1F3FC-200D-2640-FE0F","order":2480,"unicode":"🤹🏼‍♀️"},{"annotation":"woman juggling: medium skin tone","group":1,"hexcode":"1F939-1F3FD-200D-2640-FE0F","order":2482,"unicode":"🤹🏽‍♀️"},{"annotation":"woman juggling: medium-dark skin tone","group":1,"hexcode":"1F939-1F3FE-200D-2640-FE0F","order":2484,"unicode":"🤹🏾‍♀️"},{"annotation":"woman juggling: dark skin tone","group":1,"hexcode":"1F939-1F3FF-200D-2640-FE0F","order":2486,"unicode":"🤹🏿‍♀️"}]},{"annotation":"person in lotus position","group":1,"hexcode":"1F9D8","order":2488,"tags":["meditation","yoga"],"unicode":"🧘","skins":[{"annotation":"person in lotus position: light skin tone","group":1,"hexcode":"1F9D8-1F3FB","order":2489,"unicode":"🧘🏻"},{"annotation":"person in lotus position: medium-light skin tone","group":1,"hexcode":"1F9D8-1F3FC","order":2490,"unicode":"🧘🏼"},{"annotation":"person in lotus position: medium skin tone","group":1,"hexcode":"1F9D8-1F3FD","order":2491,"unicode":"🧘🏽"},{"annotation":"person in lotus position: medium-dark skin tone","group":1,"hexcode":"1F9D8-1F3FE","order":2492,"unicode":"🧘🏾"},{"annotation":"person in lotus position: dark skin tone","group":1,"hexcode":"1F9D8-1F3FF","order":2493,"unicode":"🧘🏿"}]},{"annotation":"man in lotus position","group":1,"hexcode":"1F9D8-200D-2642-FE0F","order":2494,"tags":["meditation","yoga"],"unicode":"🧘‍♂️","skins":[{"annotation":"man in lotus position: light skin tone","group":1,"hexcode":"1F9D8-1F3FB-200D-2642-FE0F","order":2496,"unicode":"🧘🏻‍♂️"},{"annotation":"man in lotus position: medium-light skin tone","group":1,"hexcode":"1F9D8-1F3FC-200D-2642-FE0F","order":2498,"unicode":"🧘🏼‍♂️"},{"annotation":"man in lotus position: medium skin tone","group":1,"hexcode":"1F9D8-1F3FD-200D-2642-FE0F","order":2500,"unicode":"🧘🏽‍♂️"},{"annotation":"man in lotus position: medium-dark skin tone","group":1,"hexcode":"1F9D8-1F3FE-200D-2642-FE0F","order":2502,"unicode":"🧘🏾‍♂️"},{"annotation":"man in lotus position: dark skin tone","group":1,"hexcode":"1F9D8-1F3FF-200D-2642-FE0F","order":2504,"unicode":"🧘🏿‍♂️"}]},{"annotation":"woman in lotus position","group":1,"hexcode":"1F9D8-200D-2640-FE0F","order":2506,"tags":["meditation","yoga"],"unicode":"🧘‍♀️","skins":[{"annotation":"woman in lotus position: light skin tone","group":1,"hexcode":"1F9D8-1F3FB-200D-2640-FE0F","order":2508,"unicode":"🧘🏻‍♀️"},{"annotation":"woman in lotus position: medium-light skin tone","group":1,"hexcode":"1F9D8-1F3FC-200D-2640-FE0F","order":2510,"unicode":"🧘🏼‍♀️"},{"annotation":"woman in lotus position: medium skin tone","group":1,"hexcode":"1F9D8-1F3FD-200D-2640-FE0F","order":2512,"unicode":"🧘🏽‍♀️"},{"annotation":"woman in lotus position: medium-dark skin tone","group":1,"hexcode":"1F9D8-1F3FE-200D-2640-FE0F","order":2514,"unicode":"🧘🏾‍♀️"},{"annotation":"woman in lotus position: dark skin tone","group":1,"hexcode":"1F9D8-1F3FF-200D-2640-FE0F","order":2516,"unicode":"🧘🏿‍♀️"}]},{"annotation":"person taking bath","group":1,"hexcode":"1F6C0","order":2518,"tags":["bath","bathtub"],"unicode":"🛀","skins":[{"annotation":"person taking bath: light skin tone","group":1,"hexcode":"1F6C0-1F3FB","order":2519,"unicode":"🛀🏻"},{"annotation":"person taking bath: medium-light skin tone","group":1,"hexcode":"1F6C0-1F3FC","order":2520,"unicode":"🛀🏼"},{"annotation":"person taking bath: medium skin tone","group":1,"hexcode":"1F6C0-1F3FD","order":2521,"unicode":"🛀🏽"},{"annotation":"person taking bath: medium-dark skin tone","group":1,"hexcode":"1F6C0-1F3FE","order":2522,"unicode":"🛀🏾"},{"annotation":"person taking bath: dark skin tone","group":1,"hexcode":"1F6C0-1F3FF","order":2523,"unicode":"🛀🏿"}]},{"annotation":"person in bed","group":1,"hexcode":"1F6CC","order":2524,"tags":["hotel","sleep"],"unicode":"🛌","skins":[{"annotation":"person in bed: light skin tone","group":1,"hexcode":"1F6CC-1F3FB","order":2525,"unicode":"🛌🏻"},{"annotation":"person in bed: medium-light skin tone","group":1,"hexcode":"1F6CC-1F3FC","order":2526,"unicode":"🛌🏼"},{"annotation":"person in bed: medium skin tone","group":1,"hexcode":"1F6CC-1F3FD","order":2527,"unicode":"🛌🏽"},{"annotation":"person in bed: medium-dark skin tone","group":1,"hexcode":"1F6CC-1F3FE","order":2528,"unicode":"🛌🏾"},{"annotation":"person in bed: dark skin tone","group":1,"hexcode":"1F6CC-1F3FF","order":2529,"unicode":"🛌🏿"}]},{"annotation":"people holding hands","group":1,"hexcode":"1F9D1-200D-1F91D-200D-1F9D1","order":2530,"tags":["couple","hand","hold","holding hands","person"],"unicode":"🧑‍🤝‍🧑","skins":[{"annotation":"people holding hands: light skin tone","group":1,"hexcode":"1F9D1-1F3FB-200D-1F91D-200D-1F9D1-1F3FB","order":2531,"unicode":"🧑🏻‍🤝‍🧑🏻"},{"annotation":"people holding hands: light skin tone, medium-light skin tone","group":1,"hexcode":"1F9D1-1F3FB-200D-1F91D-200D-1F9D1-1F3FC","order":2532,"unicode":"🧑🏻‍🤝‍🧑🏼"},{"annotation":"people holding hands: light skin tone, medium skin tone","group":1,"hexcode":"1F9D1-1F3FB-200D-1F91D-200D-1F9D1-1F3FD","order":2533,"unicode":"🧑🏻‍🤝‍🧑🏽"},{"annotation":"people holding hands: light skin tone, medium-dark skin tone","group":1,"hexcode":"1F9D1-1F3FB-200D-1F91D-200D-1F9D1-1F3FE","order":2534,"unicode":"🧑🏻‍🤝‍🧑🏾"},{"annotation":"people holding hands: light skin tone, dark skin tone","group":1,"hexcode":"1F9D1-1F3FB-200D-1F91D-200D-1F9D1-1F3FF","order":2535,"unicode":"🧑🏻‍🤝‍🧑🏿"},{"annotation":"people holding hands: medium-light skin tone, light skin tone","group":1,"hexcode":"1F9D1-1F3FC-200D-1F91D-200D-1F9D1-1F3FB","order":2536,"unicode":"🧑🏼‍🤝‍🧑🏻"},{"annotation":"people holding hands: medium-light skin tone","group":1,"hexcode":"1F9D1-1F3FC-200D-1F91D-200D-1F9D1-1F3FC","order":2537,"unicode":"🧑🏼‍🤝‍🧑🏼"},{"annotation":"people holding hands: medium-light skin tone, medium skin tone","group":1,"hexcode":"1F9D1-1F3FC-200D-1F91D-200D-1F9D1-1F3FD","order":2538,"unicode":"🧑🏼‍🤝‍🧑🏽"},{"annotation":"people holding hands: medium-light skin tone, medium-dark skin tone","group":1,"hexcode":"1F9D1-1F3FC-200D-1F91D-200D-1F9D1-1F3FE","order":2539,"unicode":"🧑🏼‍🤝‍🧑🏾"},{"annotation":"people holding hands: medium-light skin tone, dark skin tone","group":1,"hexcode":"1F9D1-1F3FC-200D-1F91D-200D-1F9D1-1F3FF","order":2540,"unicode":"🧑🏼‍🤝‍🧑🏿"},{"annotation":"people holding hands: medium skin tone, light skin tone","group":1,"hexcode":"1F9D1-1F3FD-200D-1F91D-200D-1F9D1-1F3FB","order":2541,"unicode":"🧑🏽‍🤝‍🧑🏻"},{"annotation":"people holding hands: medium skin tone, medium-light skin tone","group":1,"hexcode":"1F9D1-1F3FD-200D-1F91D-200D-1F9D1-1F3FC","order":2542,"unicode":"🧑🏽‍🤝‍🧑🏼"},{"annotation":"people holding hands: medium skin tone","group":1,"hexcode":"1F9D1-1F3FD-200D-1F91D-200D-1F9D1-1F3FD","order":2543,"unicode":"🧑🏽‍🤝‍🧑🏽"},{"annotation":"people holding hands: medium skin tone, medium-dark skin tone","group":1,"hexcode":"1F9D1-1F3FD-200D-1F91D-200D-1F9D1-1F3FE","order":2544,"unicode":"🧑🏽‍🤝‍🧑🏾"},{"annotation":"people holding hands: medium skin tone, dark skin tone","group":1,"hexcode":"1F9D1-1F3FD-200D-1F91D-200D-1F9D1-1F3FF","order":2545,"unicode":"🧑🏽‍🤝‍🧑🏿"},{"annotation":"people holding hands: medium-dark skin tone, light skin tone","group":1,"hexcode":"1F9D1-1F3FE-200D-1F91D-200D-1F9D1-1F3FB","order":2546,"unicode":"🧑🏾‍🤝‍🧑🏻"},{"annotation":"people holding hands: medium-dark skin tone, medium-light skin tone","group":1,"hexcode":"1F9D1-1F3FE-200D-1F91D-200D-1F9D1-1F3FC","order":2547,"unicode":"🧑🏾‍🤝‍🧑🏼"},{"annotation":"people holding hands: medium-dark skin tone, medium skin tone","group":1,"hexcode":"1F9D1-1F3FE-200D-1F91D-200D-1F9D1-1F3FD","order":2548,"unicode":"🧑🏾‍🤝‍🧑🏽"},{"annotation":"people holding hands: medium-dark skin tone","group":1,"hexcode":"1F9D1-1F3FE-200D-1F91D-200D-1F9D1-1F3FE","order":2549,"unicode":"🧑🏾‍🤝‍🧑🏾"},{"annotation":"people holding hands: medium-dark skin tone, dark skin tone","group":1,"hexcode":"1F9D1-1F3FE-200D-1F91D-200D-1F9D1-1F3FF","order":2550,"unicode":"🧑🏾‍🤝‍🧑🏿"},{"annotation":"people holding hands: dark skin tone, light skin tone","group":1,"hexcode":"1F9D1-1F3FF-200D-1F91D-200D-1F9D1-1F3FB","order":2551,"unicode":"🧑🏿‍🤝‍🧑🏻"},{"annotation":"people holding hands: dark skin tone, medium-light skin tone","group":1,"hexcode":"1F9D1-1F3FF-200D-1F91D-200D-1F9D1-1F3FC","order":2552,"unicode":"🧑🏿‍🤝‍🧑🏼"},{"annotation":"people holding hands: dark skin tone, medium skin tone","group":1,"hexcode":"1F9D1-1F3FF-200D-1F91D-200D-1F9D1-1F3FD","order":2553,"unicode":"🧑🏿‍🤝‍🧑🏽"},{"annotation":"people holding hands: dark skin tone, medium-dark skin tone","group":1,"hexcode":"1F9D1-1F3FF-200D-1F91D-200D-1F9D1-1F3FE","order":2554,"unicode":"🧑🏿‍🤝‍🧑🏾"},{"annotation":"people holding hands: dark skin tone","group":1,"hexcode":"1F9D1-1F3FF-200D-1F91D-200D-1F9D1-1F3FF","order":2555,"unicode":"🧑🏿‍🤝‍🧑🏿"}]},{"annotation":"women holding hands","group":1,"hexcode":"1F46D","order":2556,"tags":["couple","hand","holding hands","women"],"unicode":"👭","skins":[{"annotation":"women holding hands: light skin tone","group":1,"hexcode":"1F46D-1F3FB","order":2557,"unicode":"👭🏻"},{"annotation":"women holding hands: medium-light skin tone","group":1,"hexcode":"1F46D-1F3FC","order":2563,"unicode":"👭🏼"},{"annotation":"women holding hands: medium skin tone","group":1,"hexcode":"1F46D-1F3FD","order":2569,"unicode":"👭🏽"},{"annotation":"women holding hands: medium-dark skin tone","group":1,"hexcode":"1F46D-1F3FE","order":2575,"unicode":"👭🏾"},{"annotation":"women holding hands: dark skin tone","group":1,"hexcode":"1F46D-1F3FF","order":2581,"unicode":"👭🏿"},{"annotation":"women holding hands: light skin tone, medium-light skin tone","group":1,"hexcode":"1F469-1F3FB-200D-1F91D-200D-1F469-1F3FC","order":2558,"unicode":"👩🏻‍🤝‍👩🏼"},{"annotation":"women holding hands: light skin tone, medium skin tone","group":1,"hexcode":"1F469-1F3FB-200D-1F91D-200D-1F469-1F3FD","order":2559,"unicode":"👩🏻‍🤝‍👩🏽"},{"annotation":"women holding hands: light skin tone, medium-dark skin tone","group":1,"hexcode":"1F469-1F3FB-200D-1F91D-200D-1F469-1F3FE","order":2560,"unicode":"👩🏻‍🤝‍👩🏾"},{"annotation":"women holding hands: light skin tone, dark skin tone","group":1,"hexcode":"1F469-1F3FB-200D-1F91D-200D-1F469-1F3FF","order":2561,"unicode":"👩🏻‍🤝‍👩🏿"},{"annotation":"women holding hands: medium-light skin tone, light skin tone","group":1,"hexcode":"1F469-1F3FC-200D-1F91D-200D-1F469-1F3FB","order":2562,"unicode":"👩🏼‍🤝‍👩🏻"},{"annotation":"women holding hands: medium-light skin tone, medium skin tone","group":1,"hexcode":"1F469-1F3FC-200D-1F91D-200D-1F469-1F3FD","order":2564,"unicode":"👩🏼‍🤝‍👩🏽"},{"annotation":"women holding hands: medium-light skin tone, medium-dark skin tone","group":1,"hexcode":"1F469-1F3FC-200D-1F91D-200D-1F469-1F3FE","order":2565,"unicode":"👩🏼‍🤝‍👩🏾"},{"annotation":"women holding hands: medium-light skin tone, dark skin tone","group":1,"hexcode":"1F469-1F3FC-200D-1F91D-200D-1F469-1F3FF","order":2566,"unicode":"👩🏼‍🤝‍👩🏿"},{"annotation":"women holding hands: medium skin tone, light skin tone","group":1,"hexcode":"1F469-1F3FD-200D-1F91D-200D-1F469-1F3FB","order":2567,"unicode":"👩🏽‍🤝‍👩🏻"},{"annotation":"women holding hands: medium skin tone, medium-light skin tone","group":1,"hexcode":"1F469-1F3FD-200D-1F91D-200D-1F469-1F3FC","order":2568,"unicode":"👩🏽‍🤝‍👩🏼"},{"annotation":"women holding hands: medium skin tone, medium-dark skin tone","group":1,"hexcode":"1F469-1F3FD-200D-1F91D-200D-1F469-1F3FE","order":2570,"unicode":"👩🏽‍🤝‍👩🏾"},{"annotation":"women holding hands: medium skin tone, dark skin tone","group":1,"hexcode":"1F469-1F3FD-200D-1F91D-200D-1F469-1F3FF","order":2571,"unicode":"👩🏽‍🤝‍👩🏿"},{"annotation":"women holding hands: medium-dark skin tone, light skin tone","group":1,"hexcode":"1F469-1F3FE-200D-1F91D-200D-1F469-1F3FB","order":2572,"unicode":"👩🏾‍🤝‍👩🏻"},{"annotation":"women holding hands: medium-dark skin tone, medium-light skin tone","group":1,"hexcode":"1F469-1F3FE-200D-1F91D-200D-1F469-1F3FC","order":2573,"unicode":"👩🏾‍🤝‍👩🏼"},{"annotation":"women holding hands: medium-dark skin tone, medium skin tone","group":1,"hexcode":"1F469-1F3FE-200D-1F91D-200D-1F469-1F3FD","order":2574,"unicode":"👩🏾‍🤝‍👩🏽"},{"annotation":"women holding hands: medium-dark skin tone, dark skin tone","group":1,"hexcode":"1F469-1F3FE-200D-1F91D-200D-1F469-1F3FF","order":2576,"unicode":"👩🏾‍🤝‍👩🏿"},{"annotation":"women holding hands: dark skin tone, light skin tone","group":1,"hexcode":"1F469-1F3FF-200D-1F91D-200D-1F469-1F3FB","order":2577,"unicode":"👩🏿‍🤝‍👩🏻"},{"annotation":"women holding hands: dark skin tone, medium-light skin tone","group":1,"hexcode":"1F469-1F3FF-200D-1F91D-200D-1F469-1F3FC","order":2578,"unicode":"👩🏿‍🤝‍👩🏼"},{"annotation":"women holding hands: dark skin tone, medium skin tone","group":1,"hexcode":"1F469-1F3FF-200D-1F91D-200D-1F469-1F3FD","order":2579,"unicode":"👩🏿‍🤝‍👩🏽"},{"annotation":"women holding hands: dark skin tone, medium-dark skin tone","group":1,"hexcode":"1F469-1F3FF-200D-1F91D-200D-1F469-1F3FE","order":2580,"unicode":"👩🏿‍🤝‍👩🏾"}]},{"annotation":"woman and man holding hands","group":1,"hexcode":"1F46B","order":2582,"tags":["couple","hand","hold","holding hands","man","woman"],"unicode":"👫","skins":[{"annotation":"woman and man holding hands: light skin tone","group":1,"hexcode":"1F46B-1F3FB","order":2583,"unicode":"👫🏻"},{"annotation":"woman and man holding hands: medium-light skin tone","group":1,"hexcode":"1F46B-1F3FC","order":2589,"unicode":"👫🏼"},{"annotation":"woman and man holding hands: medium skin tone","group":1,"hexcode":"1F46B-1F3FD","order":2595,"unicode":"👫🏽"},{"annotation":"woman and man holding hands: medium-dark skin tone","group":1,"hexcode":"1F46B-1F3FE","order":2601,"unicode":"👫🏾"},{"annotation":"woman and man holding hands: dark skin tone","group":1,"hexcode":"1F46B-1F3FF","order":2607,"unicode":"👫🏿"},{"annotation":"woman and man holding hands: light skin tone, medium-light skin tone","group":1,"hexcode":"1F469-1F3FB-200D-1F91D-200D-1F468-1F3FC","order":2584,"unicode":"👩🏻‍🤝‍👨🏼"},{"annotation":"woman and man holding hands: light skin tone, medium skin tone","group":1,"hexcode":"1F469-1F3FB-200D-1F91D-200D-1F468-1F3FD","order":2585,"unicode":"👩🏻‍🤝‍👨🏽"},{"annotation":"woman and man holding hands: light skin tone, medium-dark skin tone","group":1,"hexcode":"1F469-1F3FB-200D-1F91D-200D-1F468-1F3FE","order":2586,"unicode":"👩🏻‍🤝‍👨🏾"},{"annotation":"woman and man holding hands: light skin tone, dark skin tone","group":1,"hexcode":"1F469-1F3FB-200D-1F91D-200D-1F468-1F3FF","order":2587,"unicode":"👩🏻‍🤝‍👨🏿"},{"annotation":"woman and man holding hands: medium-light skin tone, light skin tone","group":1,"hexcode":"1F469-1F3FC-200D-1F91D-200D-1F468-1F3FB","order":2588,"unicode":"👩🏼‍🤝‍👨🏻"},{"annotation":"woman and man holding hands: medium-light skin tone, medium skin tone","group":1,"hexcode":"1F469-1F3FC-200D-1F91D-200D-1F468-1F3FD","order":2590,"unicode":"👩🏼‍🤝‍👨🏽"},{"annotation":"woman and man holding hands: medium-light skin tone, medium-dark skin tone","group":1,"hexcode":"1F469-1F3FC-200D-1F91D-200D-1F468-1F3FE","order":2591,"unicode":"👩🏼‍🤝‍👨🏾"},{"annotation":"woman and man holding hands: medium-light skin tone, dark skin tone","group":1,"hexcode":"1F469-1F3FC-200D-1F91D-200D-1F468-1F3FF","order":2592,"unicode":"👩🏼‍🤝‍👨🏿"},{"annotation":"woman and man holding hands: medium skin tone, light skin tone","group":1,"hexcode":"1F469-1F3FD-200D-1F91D-200D-1F468-1F3FB","order":2593,"unicode":"👩🏽‍🤝‍👨🏻"},{"annotation":"woman and man holding hands: medium skin tone, medium-light skin tone","group":1,"hexcode":"1F469-1F3FD-200D-1F91D-200D-1F468-1F3FC","order":2594,"unicode":"👩🏽‍🤝‍👨🏼"},{"annotation":"woman and man holding hands: medium skin tone, medium-dark skin tone","group":1,"hexcode":"1F469-1F3FD-200D-1F91D-200D-1F468-1F3FE","order":2596,"unicode":"👩🏽‍🤝‍👨🏾"},{"annotation":"woman and man holding hands: medium skin tone, dark skin tone","group":1,"hexcode":"1F469-1F3FD-200D-1F91D-200D-1F468-1F3FF","order":2597,"unicode":"👩🏽‍🤝‍👨🏿"},{"annotation":"woman and man holding hands: medium-dark skin tone, light skin tone","group":1,"hexcode":"1F469-1F3FE-200D-1F91D-200D-1F468-1F3FB","order":2598,"unicode":"👩🏾‍🤝‍👨🏻"},{"annotation":"woman and man holding hands: medium-dark skin tone, medium-light skin tone","group":1,"hexcode":"1F469-1F3FE-200D-1F91D-200D-1F468-1F3FC","order":2599,"unicode":"👩🏾‍🤝‍👨🏼"},{"annotation":"woman and man holding hands: medium-dark skin tone, medium skin tone","group":1,"hexcode":"1F469-1F3FE-200D-1F91D-200D-1F468-1F3FD","order":2600,"unicode":"👩🏾‍🤝‍👨🏽"},{"annotation":"woman and man holding hands: medium-dark skin tone, dark skin tone","group":1,"hexcode":"1F469-1F3FE-200D-1F91D-200D-1F468-1F3FF","order":2602,"unicode":"👩🏾‍🤝‍👨🏿"},{"annotation":"woman and man holding hands: dark skin tone, light skin tone","group":1,"hexcode":"1F469-1F3FF-200D-1F91D-200D-1F468-1F3FB","order":2603,"unicode":"👩🏿‍🤝‍👨🏻"},{"annotation":"woman and man holding hands: dark skin tone, medium-light skin tone","group":1,"hexcode":"1F469-1F3FF-200D-1F91D-200D-1F468-1F3FC","order":2604,"unicode":"👩🏿‍🤝‍👨🏼"},{"annotation":"woman and man holding hands: dark skin tone, medium skin tone","group":1,"hexcode":"1F469-1F3FF-200D-1F91D-200D-1F468-1F3FD","order":2605,"unicode":"👩🏿‍🤝‍👨🏽"},{"annotation":"woman and man holding hands: dark skin tone, medium-dark skin tone","group":1,"hexcode":"1F469-1F3FF-200D-1F91D-200D-1F468-1F3FE","order":2606,"unicode":"👩🏿‍🤝‍👨🏾"}]},{"annotation":"men holding hands","group":1,"hexcode":"1F46C","order":2608,"tags":["couple","gemini","holding hands","man","men","twins","zodiac"],"unicode":"👬","skins":[{"annotation":"men holding hands: light skin tone","group":1,"hexcode":"1F46C-1F3FB","order":2609,"unicode":"👬🏻"},{"annotation":"men holding hands: medium-light skin tone","group":1,"hexcode":"1F46C-1F3FC","order":2615,"unicode":"👬🏼"},{"annotation":"men holding hands: medium skin tone","group":1,"hexcode":"1F46C-1F3FD","order":2621,"unicode":"👬🏽"},{"annotation":"men holding hands: medium-dark skin tone","group":1,"hexcode":"1F46C-1F3FE","order":2627,"unicode":"👬🏾"},{"annotation":"men holding hands: dark skin tone","group":1,"hexcode":"1F46C-1F3FF","order":2633,"unicode":"👬🏿"},{"annotation":"men holding hands: light skin tone, medium-light skin tone","group":1,"hexcode":"1F468-1F3FB-200D-1F91D-200D-1F468-1F3FC","order":2610,"unicode":"👨🏻‍🤝‍👨🏼"},{"annotation":"men holding hands: light skin tone, medium skin tone","group":1,"hexcode":"1F468-1F3FB-200D-1F91D-200D-1F468-1F3FD","order":2611,"unicode":"👨🏻‍🤝‍👨🏽"},{"annotation":"men holding hands: light skin tone, medium-dark skin tone","group":1,"hexcode":"1F468-1F3FB-200D-1F91D-200D-1F468-1F3FE","order":2612,"unicode":"👨🏻‍🤝‍👨🏾"},{"annotation":"men holding hands: light skin tone, dark skin tone","group":1,"hexcode":"1F468-1F3FB-200D-1F91D-200D-1F468-1F3FF","order":2613,"unicode":"👨🏻‍🤝‍👨🏿"},{"annotation":"men holding hands: medium-light skin tone, light skin tone","group":1,"hexcode":"1F468-1F3FC-200D-1F91D-200D-1F468-1F3FB","order":2614,"unicode":"👨🏼‍🤝‍👨🏻"},{"annotation":"men holding hands: medium-light skin tone, medium skin tone","group":1,"hexcode":"1F468-1F3FC-200D-1F91D-200D-1F468-1F3FD","order":2616,"unicode":"👨🏼‍🤝‍👨🏽"},{"annotation":"men holding hands: medium-light skin tone, medium-dark skin tone","group":1,"hexcode":"1F468-1F3FC-200D-1F91D-200D-1F468-1F3FE","order":2617,"unicode":"👨🏼‍🤝‍👨🏾"},{"annotation":"men holding hands: medium-light skin tone, dark skin tone","group":1,"hexcode":"1F468-1F3FC-200D-1F91D-200D-1F468-1F3FF","order":2618,"unicode":"👨🏼‍🤝‍👨🏿"},{"annotation":"men holding hands: medium skin tone, light skin tone","group":1,"hexcode":"1F468-1F3FD-200D-1F91D-200D-1F468-1F3FB","order":2619,"unicode":"👨🏽‍🤝‍👨🏻"},{"annotation":"men holding hands: medium skin tone, medium-light skin tone","group":1,"hexcode":"1F468-1F3FD-200D-1F91D-200D-1F468-1F3FC","order":2620,"unicode":"👨🏽‍🤝‍👨🏼"},{"annotation":"men holding hands: medium skin tone, medium-dark skin tone","group":1,"hexcode":"1F468-1F3FD-200D-1F91D-200D-1F468-1F3FE","order":2622,"unicode":"👨🏽‍🤝‍👨🏾"},{"annotation":"men holding hands: medium skin tone, dark skin tone","group":1,"hexcode":"1F468-1F3FD-200D-1F91D-200D-1F468-1F3FF","order":2623,"unicode":"👨🏽‍🤝‍👨🏿"},{"annotation":"men holding hands: medium-dark skin tone, light skin tone","group":1,"hexcode":"1F468-1F3FE-200D-1F91D-200D-1F468-1F3FB","order":2624,"unicode":"👨🏾‍🤝‍👨🏻"},{"annotation":"men holding hands: medium-dark skin tone, medium-light skin tone","group":1,"hexcode":"1F468-1F3FE-200D-1F91D-200D-1F468-1F3FC","order":2625,"unicode":"👨🏾‍🤝‍👨🏼"},{"annotation":"men holding hands: medium-dark skin tone, medium skin tone","group":1,"hexcode":"1F468-1F3FE-200D-1F91D-200D-1F468-1F3FD","order":2626,"unicode":"👨🏾‍🤝‍👨🏽"},{"annotation":"men holding hands: medium-dark skin tone, dark skin tone","group":1,"hexcode":"1F468-1F3FE-200D-1F91D-200D-1F468-1F3FF","order":2628,"unicode":"👨🏾‍🤝‍👨🏿"},{"annotation":"men holding hands: dark skin tone, light skin tone","group":1,"hexcode":"1F468-1F3FF-200D-1F91D-200D-1F468-1F3FB","order":2629,"unicode":"👨🏿‍🤝‍👨🏻"},{"annotation":"men holding hands: dark skin tone, medium-light skin tone","group":1,"hexcode":"1F468-1F3FF-200D-1F91D-200D-1F468-1F3FC","order":2630,"unicode":"👨🏿‍🤝‍👨🏼"},{"annotation":"men holding hands: dark skin tone, medium skin tone","group":1,"hexcode":"1F468-1F3FF-200D-1F91D-200D-1F468-1F3FD","order":2631,"unicode":"👨🏿‍🤝‍👨🏽"},{"annotation":"men holding hands: dark skin tone, medium-dark skin tone","group":1,"hexcode":"1F468-1F3FF-200D-1F91D-200D-1F468-1F3FE","order":2632,"unicode":"👨🏿‍🤝‍👨🏾"}]},{"annotation":"kiss","group":1,"hexcode":"1F48F","order":2634,"tags":["couple"],"unicode":"💏","skins":[{"annotation":"kiss: light skin tone","group":1,"hexcode":"1F48F-1F3FB","order":2635,"unicode":"💏🏻"},{"annotation":"kiss: medium-light skin tone","group":1,"hexcode":"1F48F-1F3FC","order":2636,"unicode":"💏🏼"},{"annotation":"kiss: medium skin tone","group":1,"hexcode":"1F48F-1F3FD","order":2637,"unicode":"💏🏽"},{"annotation":"kiss: medium-dark skin tone","group":1,"hexcode":"1F48F-1F3FE","order":2638,"unicode":"💏🏾"},{"annotation":"kiss: dark skin tone","group":1,"hexcode":"1F48F-1F3FF","order":2639,"unicode":"💏🏿"},{"annotation":"kiss: person, person, light skin tone, medium-light skin tone","group":1,"hexcode":"1F9D1-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FC","order":2640,"unicode":"🧑🏻‍❤️‍💋‍🧑🏼"},{"annotation":"kiss: person, person, light skin tone, medium skin tone","group":1,"hexcode":"1F9D1-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FD","order":2642,"unicode":"🧑🏻‍❤️‍💋‍🧑🏽"},{"annotation":"kiss: person, person, light skin tone, medium-dark skin tone","group":1,"hexcode":"1F9D1-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FE","order":2644,"unicode":"🧑🏻‍❤️‍💋‍🧑🏾"},{"annotation":"kiss: person, person, light skin tone, dark skin tone","group":1,"hexcode":"1F9D1-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FF","order":2646,"unicode":"🧑🏻‍❤️‍💋‍🧑🏿"},{"annotation":"kiss: person, person, medium-light skin tone, light skin tone","group":1,"hexcode":"1F9D1-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FB","order":2648,"unicode":"🧑🏼‍❤️‍💋‍🧑🏻"},{"annotation":"kiss: person, person, medium-light skin tone, medium skin tone","group":1,"hexcode":"1F9D1-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FD","order":2650,"unicode":"🧑🏼‍❤️‍💋‍🧑🏽"},{"annotation":"kiss: person, person, medium-light skin tone, medium-dark skin tone","group":1,"hexcode":"1F9D1-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FE","order":2652,"unicode":"🧑🏼‍❤️‍💋‍🧑🏾"},{"annotation":"kiss: person, person, medium-light skin tone, dark skin tone","group":1,"hexcode":"1F9D1-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FF","order":2654,"unicode":"🧑🏼‍❤️‍💋‍🧑🏿"},{"annotation":"kiss: person, person, medium skin tone, light skin tone","group":1,"hexcode":"1F9D1-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FB","order":2656,"unicode":"🧑🏽‍❤️‍💋‍🧑🏻"},{"annotation":"kiss: person, person, medium skin tone, medium-light skin tone","group":1,"hexcode":"1F9D1-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FC","order":2658,"unicode":"🧑🏽‍❤️‍💋‍🧑🏼"},{"annotation":"kiss: person, person, medium skin tone, medium-dark skin tone","group":1,"hexcode":"1F9D1-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FE","order":2660,"unicode":"🧑🏽‍❤️‍💋‍🧑🏾"},{"annotation":"kiss: person, person, medium skin tone, dark skin tone","group":1,"hexcode":"1F9D1-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FF","order":2662,"unicode":"🧑🏽‍❤️‍💋‍🧑🏿"},{"annotation":"kiss: person, person, medium-dark skin tone, light skin tone","group":1,"hexcode":"1F9D1-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FB","order":2664,"unicode":"🧑🏾‍❤️‍💋‍🧑🏻"},{"annotation":"kiss: person, person, medium-dark skin tone, medium-light skin tone","group":1,"hexcode":"1F9D1-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FC","order":2666,"unicode":"🧑🏾‍❤️‍💋‍🧑🏼"},{"annotation":"kiss: person, person, medium-dark skin tone, medium skin tone","group":1,"hexcode":"1F9D1-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FD","order":2668,"unicode":"🧑🏾‍❤️‍💋‍🧑🏽"},{"annotation":"kiss: person, person, medium-dark skin tone, dark skin tone","group":1,"hexcode":"1F9D1-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FF","order":2670,"unicode":"🧑🏾‍❤️‍💋‍🧑🏿"},{"annotation":"kiss: person, person, dark skin tone, light skin tone","group":1,"hexcode":"1F9D1-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FB","order":2672,"unicode":"🧑🏿‍❤️‍💋‍🧑🏻"},{"annotation":"kiss: person, person, dark skin tone, medium-light skin tone","group":1,"hexcode":"1F9D1-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FC","order":2674,"unicode":"🧑🏿‍❤️‍💋‍🧑🏼"},{"annotation":"kiss: person, person, dark skin tone, medium skin tone","group":1,"hexcode":"1F9D1-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FD","order":2676,"unicode":"🧑🏿‍❤️‍💋‍🧑🏽"},{"annotation":"kiss: person, person, dark skin tone, medium-dark skin tone","group":1,"hexcode":"1F9D1-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FE","order":2678,"unicode":"🧑🏿‍❤️‍💋‍🧑🏾"}]},{"annotation":"kiss: woman, man","group":1,"hexcode":"1F469-200D-2764-FE0F-200D-1F48B-200D-1F468","order":2680,"tags":["couple","kiss","man","woman"],"unicode":"👩‍❤️‍💋‍👨","skins":[{"annotation":"kiss: woman, man, light skin tone","group":1,"hexcode":"1F469-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FB","order":2682,"unicode":"👩🏻‍❤️‍💋‍👨🏻"},{"annotation":"kiss: woman, man, light skin tone, medium-light skin tone","group":1,"hexcode":"1F469-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FC","order":2684,"unicode":"👩🏻‍❤️‍💋‍👨🏼"},{"annotation":"kiss: woman, man, light skin tone, medium skin tone","group":1,"hexcode":"1F469-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FD","order":2686,"unicode":"👩🏻‍❤️‍💋‍👨🏽"},{"annotation":"kiss: woman, man, light skin tone, medium-dark skin tone","group":1,"hexcode":"1F469-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FE","order":2688,"unicode":"👩🏻‍❤️‍💋‍👨🏾"},{"annotation":"kiss: woman, man, light skin tone, dark skin tone","group":1,"hexcode":"1F469-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FF","order":2690,"unicode":"👩🏻‍❤️‍💋‍👨🏿"},{"annotation":"kiss: woman, man, medium-light skin tone, light skin tone","group":1,"hexcode":"1F469-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FB","order":2692,"unicode":"👩🏼‍❤️‍💋‍👨🏻"},{"annotation":"kiss: woman, man, medium-light skin tone","group":1,"hexcode":"1F469-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FC","order":2694,"unicode":"👩🏼‍❤️‍💋‍👨🏼"},{"annotation":"kiss: woman, man, medium-light skin tone, medium skin tone","group":1,"hexcode":"1F469-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FD","order":2696,"unicode":"👩🏼‍❤️‍💋‍👨🏽"},{"annotation":"kiss: woman, man, medium-light skin tone, medium-dark skin tone","group":1,"hexcode":"1F469-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FE","order":2698,"unicode":"👩🏼‍❤️‍💋‍👨🏾"},{"annotation":"kiss: woman, man, medium-light skin tone, dark skin tone","group":1,"hexcode":"1F469-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FF","order":2700,"unicode":"👩🏼‍❤️‍💋‍👨🏿"},{"annotation":"kiss: woman, man, medium skin tone, light skin tone","group":1,"hexcode":"1F469-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FB","order":2702,"unicode":"👩🏽‍❤️‍💋‍👨🏻"},{"annotation":"kiss: woman, man, medium skin tone, medium-light skin tone","group":1,"hexcode":"1F469-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FC","order":2704,"unicode":"👩🏽‍❤️‍💋‍👨🏼"},{"annotation":"kiss: woman, man, medium skin tone","group":1,"hexcode":"1F469-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FD","order":2706,"unicode":"👩🏽‍❤️‍💋‍👨🏽"},{"annotation":"kiss: woman, man, medium skin tone, medium-dark skin tone","group":1,"hexcode":"1F469-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FE","order":2708,"unicode":"👩🏽‍❤️‍💋‍👨🏾"},{"annotation":"kiss: woman, man, medium skin tone, dark skin tone","group":1,"hexcode":"1F469-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FF","order":2710,"unicode":"👩🏽‍❤️‍💋‍👨🏿"},{"annotation":"kiss: woman, man, medium-dark skin tone, light skin tone","group":1,"hexcode":"1F469-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FB","order":2712,"unicode":"👩🏾‍❤️‍💋‍👨🏻"},{"annotation":"kiss: woman, man, medium-dark skin tone, medium-light skin tone","group":1,"hexcode":"1F469-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FC","order":2714,"unicode":"👩🏾‍❤️‍💋‍👨🏼"},{"annotation":"kiss: woman, man, medium-dark skin tone, medium skin tone","group":1,"hexcode":"1F469-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FD","order":2716,"unicode":"👩🏾‍❤️‍💋‍👨🏽"},{"annotation":"kiss: woman, man, medium-dark skin tone","group":1,"hexcode":"1F469-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FE","order":2718,"unicode":"👩🏾‍❤️‍💋‍👨🏾"},{"annotation":"kiss: woman, man, medium-dark skin tone, dark skin tone","group":1,"hexcode":"1F469-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FF","order":2720,"unicode":"👩🏾‍❤️‍💋‍👨🏿"},{"annotation":"kiss: woman, man, dark skin tone, light skin tone","group":1,"hexcode":"1F469-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FB","order":2722,"unicode":"👩🏿‍❤️‍💋‍👨🏻"},{"annotation":"kiss: woman, man, dark skin tone, medium-light skin tone","group":1,"hexcode":"1F469-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FC","order":2724,"unicode":"👩🏿‍❤️‍💋‍👨🏼"},{"annotation":"kiss: woman, man, dark skin tone, medium skin tone","group":1,"hexcode":"1F469-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FD","order":2726,"unicode":"👩🏿‍❤️‍💋‍👨🏽"},{"annotation":"kiss: woman, man, dark skin tone, medium-dark skin tone","group":1,"hexcode":"1F469-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FE","order":2728,"unicode":"👩🏿‍❤️‍💋‍👨🏾"},{"annotation":"kiss: woman, man, dark skin tone","group":1,"hexcode":"1F469-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FF","order":2730,"unicode":"👩🏿‍❤️‍💋‍👨🏿"}]},{"annotation":"kiss: man, man","group":1,"hexcode":"1F468-200D-2764-FE0F-200D-1F48B-200D-1F468","order":2732,"tags":["couple","kiss","man"],"unicode":"👨‍❤️‍💋‍👨","skins":[{"annotation":"kiss: man, man, light skin tone","group":1,"hexcode":"1F468-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FB","order":2734,"unicode":"👨🏻‍❤️‍💋‍👨🏻"},{"annotation":"kiss: man, man, light skin tone, medium-light skin tone","group":1,"hexcode":"1F468-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FC","order":2736,"unicode":"👨🏻‍❤️‍💋‍👨🏼"},{"annotation":"kiss: man, man, light skin tone, medium skin tone","group":1,"hexcode":"1F468-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FD","order":2738,"unicode":"👨🏻‍❤️‍💋‍👨🏽"},{"annotation":"kiss: man, man, light skin tone, medium-dark skin tone","group":1,"hexcode":"1F468-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FE","order":2740,"unicode":"👨🏻‍❤️‍💋‍👨🏾"},{"annotation":"kiss: man, man, light skin tone, dark skin tone","group":1,"hexcode":"1F468-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FF","order":2742,"unicode":"👨🏻‍❤️‍💋‍👨🏿"},{"annotation":"kiss: man, man, medium-light skin tone, light skin tone","group":1,"hexcode":"1F468-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FB","order":2744,"unicode":"👨🏼‍❤️‍💋‍👨🏻"},{"annotation":"kiss: man, man, medium-light skin tone","group":1,"hexcode":"1F468-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FC","order":2746,"unicode":"👨🏼‍❤️‍💋‍👨🏼"},{"annotation":"kiss: man, man, medium-light skin tone, medium skin tone","group":1,"hexcode":"1F468-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FD","order":2748,"unicode":"👨🏼‍❤️‍💋‍👨🏽"},{"annotation":"kiss: man, man, medium-light skin tone, medium-dark skin tone","group":1,"hexcode":"1F468-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FE","order":2750,"unicode":"👨🏼‍❤️‍💋‍👨🏾"},{"annotation":"kiss: man, man, medium-light skin tone, dark skin tone","group":1,"hexcode":"1F468-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FF","order":2752,"unicode":"👨🏼‍❤️‍💋‍👨🏿"},{"annotation":"kiss: man, man, medium skin tone, light skin tone","group":1,"hexcode":"1F468-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FB","order":2754,"unicode":"👨🏽‍❤️‍💋‍👨🏻"},{"annotation":"kiss: man, man, medium skin tone, medium-light skin tone","group":1,"hexcode":"1F468-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FC","order":2756,"unicode":"👨🏽‍❤️‍💋‍👨🏼"},{"annotation":"kiss: man, man, medium skin tone","group":1,"hexcode":"1F468-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FD","order":2758,"unicode":"👨🏽‍❤️‍💋‍👨🏽"},{"annotation":"kiss: man, man, medium skin tone, medium-dark skin tone","group":1,"hexcode":"1F468-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FE","order":2760,"unicode":"👨🏽‍❤️‍💋‍👨🏾"},{"annotation":"kiss: man, man, medium skin tone, dark skin tone","group":1,"hexcode":"1F468-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FF","order":2762,"unicode":"👨🏽‍❤️‍💋‍👨🏿"},{"annotation":"kiss: man, man, medium-dark skin tone, light skin tone","group":1,"hexcode":"1F468-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FB","order":2764,"unicode":"👨🏾‍❤️‍💋‍👨🏻"},{"annotation":"kiss: man, man, medium-dark skin tone, medium-light skin tone","group":1,"hexcode":"1F468-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FC","order":2766,"unicode":"👨🏾‍❤️‍💋‍👨🏼"},{"annotation":"kiss: man, man, medium-dark skin tone, medium skin tone","group":1,"hexcode":"1F468-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FD","order":2768,"unicode":"👨🏾‍❤️‍💋‍👨🏽"},{"annotation":"kiss: man, man, medium-dark skin tone","group":1,"hexcode":"1F468-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FE","order":2770,"unicode":"👨🏾‍❤️‍💋‍👨🏾"},{"annotation":"kiss: man, man, medium-dark skin tone, dark skin tone","group":1,"hexcode":"1F468-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FF","order":2772,"unicode":"👨🏾‍❤️‍💋‍👨🏿"},{"annotation":"kiss: man, man, dark skin tone, light skin tone","group":1,"hexcode":"1F468-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FB","order":2774,"unicode":"👨🏿‍❤️‍💋‍👨🏻"},{"annotation":"kiss: man, man, dark skin tone, medium-light skin tone","group":1,"hexcode":"1F468-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FC","order":2776,"unicode":"👨🏿‍❤️‍💋‍👨🏼"},{"annotation":"kiss: man, man, dark skin tone, medium skin tone","group":1,"hexcode":"1F468-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FD","order":2778,"unicode":"👨🏿‍❤️‍💋‍👨🏽"},{"annotation":"kiss: man, man, dark skin tone, medium-dark skin tone","group":1,"hexcode":"1F468-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FE","order":2780,"unicode":"👨🏿‍❤️‍💋‍👨🏾"},{"annotation":"kiss: man, man, dark skin tone","group":1,"hexcode":"1F468-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FF","order":2782,"unicode":"👨🏿‍❤️‍💋‍👨🏿"}]},{"annotation":"kiss: woman, woman","group":1,"hexcode":"1F469-200D-2764-FE0F-200D-1F48B-200D-1F469","order":2784,"tags":["couple","kiss","woman"],"unicode":"👩‍❤️‍💋‍👩","skins":[{"annotation":"kiss: woman, woman, light skin tone","group":1,"hexcode":"1F469-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FB","order":2786,"unicode":"👩🏻‍❤️‍💋‍👩🏻"},{"annotation":"kiss: woman, woman, light skin tone, medium-light skin tone","group":1,"hexcode":"1F469-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FC","order":2788,"unicode":"👩🏻‍❤️‍💋‍👩🏼"},{"annotation":"kiss: woman, woman, light skin tone, medium skin tone","group":1,"hexcode":"1F469-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FD","order":2790,"unicode":"👩🏻‍❤️‍💋‍👩🏽"},{"annotation":"kiss: woman, woman, light skin tone, medium-dark skin tone","group":1,"hexcode":"1F469-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FE","order":2792,"unicode":"👩🏻‍❤️‍💋‍👩🏾"},{"annotation":"kiss: woman, woman, light skin tone, dark skin tone","group":1,"hexcode":"1F469-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FF","order":2794,"unicode":"👩🏻‍❤️‍💋‍👩🏿"},{"annotation":"kiss: woman, woman, medium-light skin tone, light skin tone","group":1,"hexcode":"1F469-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FB","order":2796,"unicode":"👩🏼‍❤️‍💋‍👩🏻"},{"annotation":"kiss: woman, woman, medium-light skin tone","group":1,"hexcode":"1F469-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FC","order":2798,"unicode":"👩🏼‍❤️‍💋‍👩🏼"},{"annotation":"kiss: woman, woman, medium-light skin tone, medium skin tone","group":1,"hexcode":"1F469-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FD","order":2800,"unicode":"👩🏼‍❤️‍💋‍👩🏽"},{"annotation":"kiss: woman, woman, medium-light skin tone, medium-dark skin tone","group":1,"hexcode":"1F469-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FE","order":2802,"unicode":"👩🏼‍❤️‍💋‍👩🏾"},{"annotation":"kiss: woman, woman, medium-light skin tone, dark skin tone","group":1,"hexcode":"1F469-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FF","order":2804,"unicode":"👩🏼‍❤️‍💋‍👩🏿"},{"annotation":"kiss: woman, woman, medium skin tone, light skin tone","group":1,"hexcode":"1F469-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FB","order":2806,"unicode":"👩🏽‍❤️‍💋‍👩🏻"},{"annotation":"kiss: woman, woman, medium skin tone, medium-light skin tone","group":1,"hexcode":"1F469-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FC","order":2808,"unicode":"👩🏽‍❤️‍💋‍👩🏼"},{"annotation":"kiss: woman, woman, medium skin tone","group":1,"hexcode":"1F469-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FD","order":2810,"unicode":"👩🏽‍❤️‍💋‍👩🏽"},{"annotation":"kiss: woman, woman, medium skin tone, medium-dark skin tone","group":1,"hexcode":"1F469-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FE","order":2812,"unicode":"👩🏽‍❤️‍💋‍👩🏾"},{"annotation":"kiss: woman, woman, medium skin tone, dark skin tone","group":1,"hexcode":"1F469-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FF","order":2814,"unicode":"👩🏽‍❤️‍💋‍👩🏿"},{"annotation":"kiss: woman, woman, medium-dark skin tone, light skin tone","group":1,"hexcode":"1F469-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FB","order":2816,"unicode":"👩🏾‍❤️‍💋‍👩🏻"},{"annotation":"kiss: woman, woman, medium-dark skin tone, medium-light skin tone","group":1,"hexcode":"1F469-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FC","order":2818,"unicode":"👩🏾‍❤️‍💋‍👩🏼"},{"annotation":"kiss: woman, woman, medium-dark skin tone, medium skin tone","group":1,"hexcode":"1F469-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FD","order":2820,"unicode":"👩🏾‍❤️‍💋‍👩🏽"},{"annotation":"kiss: woman, woman, medium-dark skin tone","group":1,"hexcode":"1F469-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FE","order":2822,"unicode":"👩🏾‍❤️‍💋‍👩🏾"},{"annotation":"kiss: woman, woman, medium-dark skin tone, dark skin tone","group":1,"hexcode":"1F469-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FF","order":2824,"unicode":"👩🏾‍❤️‍💋‍👩🏿"},{"annotation":"kiss: woman, woman, dark skin tone, light skin tone","group":1,"hexcode":"1F469-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FB","order":2826,"unicode":"👩🏿‍❤️‍💋‍👩🏻"},{"annotation":"kiss: woman, woman, dark skin tone, medium-light skin tone","group":1,"hexcode":"1F469-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FC","order":2828,"unicode":"👩🏿‍❤️‍💋‍👩🏼"},{"annotation":"kiss: woman, woman, dark skin tone, medium skin tone","group":1,"hexcode":"1F469-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FD","order":2830,"unicode":"👩🏿‍❤️‍💋‍👩🏽"},{"annotation":"kiss: woman, woman, dark skin tone, medium-dark skin tone","group":1,"hexcode":"1F469-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FE","order":2832,"unicode":"👩🏿‍❤️‍💋‍👩🏾"},{"annotation":"kiss: woman, woman, dark skin tone","group":1,"hexcode":"1F469-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FF","order":2834,"unicode":"👩🏿‍❤️‍💋‍👩🏿"}]},{"annotation":"couple with heart","group":1,"hexcode":"1F491","order":2836,"tags":["couple","love"],"unicode":"💑","skins":[{"annotation":"couple with heart: light skin tone","group":1,"hexcode":"1F491-1F3FB","order":2837,"unicode":"💑🏻"},{"annotation":"couple with heart: medium-light skin tone","group":1,"hexcode":"1F491-1F3FC","order":2838,"unicode":"💑🏼"},{"annotation":"couple with heart: medium skin tone","group":1,"hexcode":"1F491-1F3FD","order":2839,"unicode":"💑🏽"},{"annotation":"couple with heart: medium-dark skin tone","group":1,"hexcode":"1F491-1F3FE","order":2840,"unicode":"💑🏾"},{"annotation":"couple with heart: dark skin tone","group":1,"hexcode":"1F491-1F3FF","order":2841,"unicode":"💑🏿"},{"annotation":"couple with heart: person, person, light skin tone, medium-light skin tone","group":1,"hexcode":"1F9D1-1F3FB-200D-2764-FE0F-200D-1F9D1-1F3FC","order":2842,"unicode":"🧑🏻‍❤️‍🧑🏼"},{"annotation":"couple with heart: person, person, light skin tone, medium skin tone","group":1,"hexcode":"1F9D1-1F3FB-200D-2764-FE0F-200D-1F9D1-1F3FD","order":2844,"unicode":"🧑🏻‍❤️‍🧑🏽"},{"annotation":"couple with heart: person, person, light skin tone, medium-dark skin tone","group":1,"hexcode":"1F9D1-1F3FB-200D-2764-FE0F-200D-1F9D1-1F3FE","order":2846,"unicode":"🧑🏻‍❤️‍🧑🏾"},{"annotation":"couple with heart: person, person, light skin tone, dark skin tone","group":1,"hexcode":"1F9D1-1F3FB-200D-2764-FE0F-200D-1F9D1-1F3FF","order":2848,"unicode":"🧑🏻‍❤️‍🧑🏿"},{"annotation":"couple with heart: person, person, medium-light skin tone, light skin tone","group":1,"hexcode":"1F9D1-1F3FC-200D-2764-FE0F-200D-1F9D1-1F3FB","order":2850,"unicode":"🧑🏼‍❤️‍🧑🏻"},{"annotation":"couple with heart: person, person, medium-light skin tone, medium skin tone","group":1,"hexcode":"1F9D1-1F3FC-200D-2764-FE0F-200D-1F9D1-1F3FD","order":2852,"unicode":"🧑🏼‍❤️‍🧑🏽"},{"annotation":"couple with heart: person, person, medium-light skin tone, medium-dark skin tone","group":1,"hexcode":"1F9D1-1F3FC-200D-2764-FE0F-200D-1F9D1-1F3FE","order":2854,"unicode":"🧑🏼‍❤️‍🧑🏾"},{"annotation":"couple with heart: person, person, medium-light skin tone, dark skin tone","group":1,"hexcode":"1F9D1-1F3FC-200D-2764-FE0F-200D-1F9D1-1F3FF","order":2856,"unicode":"🧑🏼‍❤️‍🧑🏿"},{"annotation":"couple with heart: person, person, medium skin tone, light skin tone","group":1,"hexcode":"1F9D1-1F3FD-200D-2764-FE0F-200D-1F9D1-1F3FB","order":2858,"unicode":"🧑🏽‍❤️‍🧑🏻"},{"annotation":"couple with heart: person, person, medium skin tone, medium-light skin tone","group":1,"hexcode":"1F9D1-1F3FD-200D-2764-FE0F-200D-1F9D1-1F3FC","order":2860,"unicode":"🧑🏽‍❤️‍🧑🏼"},{"annotation":"couple with heart: person, person, medium skin tone, medium-dark skin tone","group":1,"hexcode":"1F9D1-1F3FD-200D-2764-FE0F-200D-1F9D1-1F3FE","order":2862,"unicode":"🧑🏽‍❤️‍🧑🏾"},{"annotation":"couple with heart: person, person, medium skin tone, dark skin tone","group":1,"hexcode":"1F9D1-1F3FD-200D-2764-FE0F-200D-1F9D1-1F3FF","order":2864,"unicode":"🧑🏽‍❤️‍🧑🏿"},{"annotation":"couple with heart: person, person, medium-dark skin tone, light skin tone","group":1,"hexcode":"1F9D1-1F3FE-200D-2764-FE0F-200D-1F9D1-1F3FB","order":2866,"unicode":"🧑🏾‍❤️‍🧑🏻"},{"annotation":"couple with heart: person, person, medium-dark skin tone, medium-light skin tone","group":1,"hexcode":"1F9D1-1F3FE-200D-2764-FE0F-200D-1F9D1-1F3FC","order":2868,"unicode":"🧑🏾‍❤️‍🧑🏼"},{"annotation":"couple with heart: person, person, medium-dark skin tone, medium skin tone","group":1,"hexcode":"1F9D1-1F3FE-200D-2764-FE0F-200D-1F9D1-1F3FD","order":2870,"unicode":"🧑🏾‍❤️‍🧑🏽"},{"annotation":"couple with heart: person, person, medium-dark skin tone, dark skin tone","group":1,"hexcode":"1F9D1-1F3FE-200D-2764-FE0F-200D-1F9D1-1F3FF","order":2872,"unicode":"🧑🏾‍❤️‍🧑🏿"},{"annotation":"couple with heart: person, person, dark skin tone, light skin tone","group":1,"hexcode":"1F9D1-1F3FF-200D-2764-FE0F-200D-1F9D1-1F3FB","order":2874,"unicode":"🧑🏿‍❤️‍🧑🏻"},{"annotation":"couple with heart: person, person, dark skin tone, medium-light skin tone","group":1,"hexcode":"1F9D1-1F3FF-200D-2764-FE0F-200D-1F9D1-1F3FC","order":2876,"unicode":"🧑🏿‍❤️‍🧑🏼"},{"annotation":"couple with heart: person, person, dark skin tone, medium skin tone","group":1,"hexcode":"1F9D1-1F3FF-200D-2764-FE0F-200D-1F9D1-1F3FD","order":2878,"unicode":"🧑🏿‍❤️‍🧑🏽"},{"annotation":"couple with heart: person, person, dark skin tone, medium-dark skin tone","group":1,"hexcode":"1F9D1-1F3FF-200D-2764-FE0F-200D-1F9D1-1F3FE","order":2880,"unicode":"🧑🏿‍❤️‍🧑🏾"}]},{"annotation":"couple with heart: woman, man","group":1,"hexcode":"1F469-200D-2764-FE0F-200D-1F468","order":2882,"tags":["couple","couple with heart","love","man","woman"],"unicode":"👩‍❤️‍👨","skins":[{"annotation":"couple with heart: woman, man, light skin tone","group":1,"hexcode":"1F469-1F3FB-200D-2764-FE0F-200D-1F468-1F3FB","order":2884,"unicode":"👩🏻‍❤️‍👨🏻"},{"annotation":"couple with heart: woman, man, light skin tone, medium-light skin tone","group":1,"hexcode":"1F469-1F3FB-200D-2764-FE0F-200D-1F468-1F3FC","order":2886,"unicode":"👩🏻‍❤️‍👨🏼"},{"annotation":"couple with heart: woman, man, light skin tone, medium skin tone","group":1,"hexcode":"1F469-1F3FB-200D-2764-FE0F-200D-1F468-1F3FD","order":2888,"unicode":"👩🏻‍❤️‍👨🏽"},{"annotation":"couple with heart: woman, man, light skin tone, medium-dark skin tone","group":1,"hexcode":"1F469-1F3FB-200D-2764-FE0F-200D-1F468-1F3FE","order":2890,"unicode":"👩🏻‍❤️‍👨🏾"},{"annotation":"couple with heart: woman, man, light skin tone, dark skin tone","group":1,"hexcode":"1F469-1F3FB-200D-2764-FE0F-200D-1F468-1F3FF","order":2892,"unicode":"👩🏻‍❤️‍👨🏿"},{"annotation":"couple with heart: woman, man, medium-light skin tone, light skin tone","group":1,"hexcode":"1F469-1F3FC-200D-2764-FE0F-200D-1F468-1F3FB","order":2894,"unicode":"👩🏼‍❤️‍👨🏻"},{"annotation":"couple with heart: woman, man, medium-light skin tone","group":1,"hexcode":"1F469-1F3FC-200D-2764-FE0F-200D-1F468-1F3FC","order":2896,"unicode":"👩🏼‍❤️‍👨🏼"},{"annotation":"couple with heart: woman, man, medium-light skin tone, medium skin tone","group":1,"hexcode":"1F469-1F3FC-200D-2764-FE0F-200D-1F468-1F3FD","order":2898,"unicode":"👩🏼‍❤️‍👨🏽"},{"annotation":"couple with heart: woman, man, medium-light skin tone, medium-dark skin tone","group":1,"hexcode":"1F469-1F3FC-200D-2764-FE0F-200D-1F468-1F3FE","order":2900,"unicode":"👩🏼‍❤️‍👨🏾"},{"annotation":"couple with heart: woman, man, medium-light skin tone, dark skin tone","group":1,"hexcode":"1F469-1F3FC-200D-2764-FE0F-200D-1F468-1F3FF","order":2902,"unicode":"👩🏼‍❤️‍👨🏿"},{"annotation":"couple with heart: woman, man, medium skin tone, light skin tone","group":1,"hexcode":"1F469-1F3FD-200D-2764-FE0F-200D-1F468-1F3FB","order":2904,"unicode":"👩🏽‍❤️‍👨🏻"},{"annotation":"couple with heart: woman, man, medium skin tone, medium-light skin tone","group":1,"hexcode":"1F469-1F3FD-200D-2764-FE0F-200D-1F468-1F3FC","order":2906,"unicode":"👩🏽‍❤️‍👨🏼"},{"annotation":"couple with heart: woman, man, medium skin tone","group":1,"hexcode":"1F469-1F3FD-200D-2764-FE0F-200D-1F468-1F3FD","order":2908,"unicode":"👩🏽‍❤️‍👨🏽"},{"annotation":"couple with heart: woman, man, medium skin tone, medium-dark skin tone","group":1,"hexcode":"1F469-1F3FD-200D-2764-FE0F-200D-1F468-1F3FE","order":2910,"unicode":"👩🏽‍❤️‍👨🏾"},{"annotation":"couple with heart: woman, man, medium skin tone, dark skin tone","group":1,"hexcode":"1F469-1F3FD-200D-2764-FE0F-200D-1F468-1F3FF","order":2912,"unicode":"👩🏽‍❤️‍👨🏿"},{"annotation":"couple with heart: woman, man, medium-dark skin tone, light skin tone","group":1,"hexcode":"1F469-1F3FE-200D-2764-FE0F-200D-1F468-1F3FB","order":2914,"unicode":"👩🏾‍❤️‍👨🏻"},{"annotation":"couple with heart: woman, man, medium-dark skin tone, medium-light skin tone","group":1,"hexcode":"1F469-1F3FE-200D-2764-FE0F-200D-1F468-1F3FC","order":2916,"unicode":"👩🏾‍❤️‍👨🏼"},{"annotation":"couple with heart: woman, man, medium-dark skin tone, medium skin tone","group":1,"hexcode":"1F469-1F3FE-200D-2764-FE0F-200D-1F468-1F3FD","order":2918,"unicode":"👩🏾‍❤️‍👨🏽"},{"annotation":"couple with heart: woman, man, medium-dark skin tone","group":1,"hexcode":"1F469-1F3FE-200D-2764-FE0F-200D-1F468-1F3FE","order":2920,"unicode":"👩🏾‍❤️‍👨🏾"},{"annotation":"couple with heart: woman, man, medium-dark skin tone, dark skin tone","group":1,"hexcode":"1F469-1F3FE-200D-2764-FE0F-200D-1F468-1F3FF","order":2922,"unicode":"👩🏾‍❤️‍👨🏿"},{"annotation":"couple with heart: woman, man, dark skin tone, light skin tone","group":1,"hexcode":"1F469-1F3FF-200D-2764-FE0F-200D-1F468-1F3FB","order":2924,"unicode":"👩🏿‍❤️‍👨🏻"},{"annotation":"couple with heart: woman, man, dark skin tone, medium-light skin tone","group":1,"hexcode":"1F469-1F3FF-200D-2764-FE0F-200D-1F468-1F3FC","order":2926,"unicode":"👩🏿‍❤️‍👨🏼"},{"annotation":"couple with heart: woman, man, dark skin tone, medium skin tone","group":1,"hexcode":"1F469-1F3FF-200D-2764-FE0F-200D-1F468-1F3FD","order":2928,"unicode":"👩🏿‍❤️‍👨🏽"},{"annotation":"couple with heart: woman, man, dark skin tone, medium-dark skin tone","group":1,"hexcode":"1F469-1F3FF-200D-2764-FE0F-200D-1F468-1F3FE","order":2930,"unicode":"👩🏿‍❤️‍👨🏾"},{"annotation":"couple with heart: woman, man, dark skin tone","group":1,"hexcode":"1F469-1F3FF-200D-2764-FE0F-200D-1F468-1F3FF","order":2932,"unicode":"👩🏿‍❤️‍👨🏿"}]},{"annotation":"couple with heart: man, man","group":1,"hexcode":"1F468-200D-2764-FE0F-200D-1F468","order":2934,"tags":["couple","couple with heart","love","man"],"unicode":"👨‍❤️‍👨","skins":[{"annotation":"couple with heart: man, man, light skin tone","group":1,"hexcode":"1F468-1F3FB-200D-2764-FE0F-200D-1F468-1F3FB","order":2936,"unicode":"👨🏻‍❤️‍👨🏻"},{"annotation":"couple with heart: man, man, light skin tone, medium-light skin tone","group":1,"hexcode":"1F468-1F3FB-200D-2764-FE0F-200D-1F468-1F3FC","order":2938,"unicode":"👨🏻‍❤️‍👨🏼"},{"annotation":"couple with heart: man, man, light skin tone, medium skin tone","group":1,"hexcode":"1F468-1F3FB-200D-2764-FE0F-200D-1F468-1F3FD","order":2940,"unicode":"👨🏻‍❤️‍👨🏽"},{"annotation":"couple with heart: man, man, light skin tone, medium-dark skin tone","group":1,"hexcode":"1F468-1F3FB-200D-2764-FE0F-200D-1F468-1F3FE","order":2942,"unicode":"👨🏻‍❤️‍👨🏾"},{"annotation":"couple with heart: man, man, light skin tone, dark skin tone","group":1,"hexcode":"1F468-1F3FB-200D-2764-FE0F-200D-1F468-1F3FF","order":2944,"unicode":"👨🏻‍❤️‍👨🏿"},{"annotation":"couple with heart: man, man, medium-light skin tone, light skin tone","group":1,"hexcode":"1F468-1F3FC-200D-2764-FE0F-200D-1F468-1F3FB","order":2946,"unicode":"👨🏼‍❤️‍👨🏻"},{"annotation":"couple with heart: man, man, medium-light skin tone","group":1,"hexcode":"1F468-1F3FC-200D-2764-FE0F-200D-1F468-1F3FC","order":2948,"unicode":"👨🏼‍❤️‍👨🏼"},{"annotation":"couple with heart: man, man, medium-light skin tone, medium skin tone","group":1,"hexcode":"1F468-1F3FC-200D-2764-FE0F-200D-1F468-1F3FD","order":2950,"unicode":"👨🏼‍❤️‍👨🏽"},{"annotation":"couple with heart: man, man, medium-light skin tone, medium-dark skin tone","group":1,"hexcode":"1F468-1F3FC-200D-2764-FE0F-200D-1F468-1F3FE","order":2952,"unicode":"👨🏼‍❤️‍👨🏾"},{"annotation":"couple with heart: man, man, medium-light skin tone, dark skin tone","group":1,"hexcode":"1F468-1F3FC-200D-2764-FE0F-200D-1F468-1F3FF","order":2954,"unicode":"👨🏼‍❤️‍👨🏿"},{"annotation":"couple with heart: man, man, medium skin tone, light skin tone","group":1,"hexcode":"1F468-1F3FD-200D-2764-FE0F-200D-1F468-1F3FB","order":2956,"unicode":"👨🏽‍❤️‍👨🏻"},{"annotation":"couple with heart: man, man, medium skin tone, medium-light skin tone","group":1,"hexcode":"1F468-1F3FD-200D-2764-FE0F-200D-1F468-1F3FC","order":2958,"unicode":"👨🏽‍❤️‍👨🏼"},{"annotation":"couple with heart: man, man, medium skin tone","group":1,"hexcode":"1F468-1F3FD-200D-2764-FE0F-200D-1F468-1F3FD","order":2960,"unicode":"👨🏽‍❤️‍👨🏽"},{"annotation":"couple with heart: man, man, medium skin tone, medium-dark skin tone","group":1,"hexcode":"1F468-1F3FD-200D-2764-FE0F-200D-1F468-1F3FE","order":2962,"unicode":"👨🏽‍❤️‍👨🏾"},{"annotation":"couple with heart: man, man, medium skin tone, dark skin tone","group":1,"hexcode":"1F468-1F3FD-200D-2764-FE0F-200D-1F468-1F3FF","order":2964,"unicode":"👨🏽‍❤️‍👨🏿"},{"annotation":"couple with heart: man, man, medium-dark skin tone, light skin tone","group":1,"hexcode":"1F468-1F3FE-200D-2764-FE0F-200D-1F468-1F3FB","order":2966,"unicode":"👨🏾‍❤️‍👨🏻"},{"annotation":"couple with heart: man, man, medium-dark skin tone, medium-light skin tone","group":1,"hexcode":"1F468-1F3FE-200D-2764-FE0F-200D-1F468-1F3FC","order":2968,"unicode":"👨🏾‍❤️‍👨🏼"},{"annotation":"couple with heart: man, man, medium-dark skin tone, medium skin tone","group":1,"hexcode":"1F468-1F3FE-200D-2764-FE0F-200D-1F468-1F3FD","order":2970,"unicode":"👨🏾‍❤️‍👨🏽"},{"annotation":"couple with heart: man, man, medium-dark skin tone","group":1,"hexcode":"1F468-1F3FE-200D-2764-FE0F-200D-1F468-1F3FE","order":2972,"unicode":"👨🏾‍❤️‍👨🏾"},{"annotation":"couple with heart: man, man, medium-dark skin tone, dark skin tone","group":1,"hexcode":"1F468-1F3FE-200D-2764-FE0F-200D-1F468-1F3FF","order":2974,"unicode":"👨🏾‍❤️‍👨🏿"},{"annotation":"couple with heart: man, man, dark skin tone, light skin tone","group":1,"hexcode":"1F468-1F3FF-200D-2764-FE0F-200D-1F468-1F3FB","order":2976,"unicode":"👨🏿‍❤️‍👨🏻"},{"annotation":"couple with heart: man, man, dark skin tone, medium-light skin tone","group":1,"hexcode":"1F468-1F3FF-200D-2764-FE0F-200D-1F468-1F3FC","order":2978,"unicode":"👨🏿‍❤️‍👨🏼"},{"annotation":"couple with heart: man, man, dark skin tone, medium skin tone","group":1,"hexcode":"1F468-1F3FF-200D-2764-FE0F-200D-1F468-1F3FD","order":2980,"unicode":"👨🏿‍❤️‍👨🏽"},{"annotation":"couple with heart: man, man, dark skin tone, medium-dark skin tone","group":1,"hexcode":"1F468-1F3FF-200D-2764-FE0F-200D-1F468-1F3FE","order":2982,"unicode":"👨🏿‍❤️‍👨🏾"},{"annotation":"couple with heart: man, man, dark skin tone","group":1,"hexcode":"1F468-1F3FF-200D-2764-FE0F-200D-1F468-1F3FF","order":2984,"unicode":"👨🏿‍❤️‍👨🏿"}]},{"annotation":"couple with heart: woman, woman","group":1,"hexcode":"1F469-200D-2764-FE0F-200D-1F469","order":2986,"tags":["couple","couple with heart","love","woman"],"unicode":"👩‍❤️‍👩","skins":[{"annotation":"couple with heart: woman, woman, light skin tone","group":1,"hexcode":"1F469-1F3FB-200D-2764-FE0F-200D-1F469-1F3FB","order":2988,"unicode":"👩🏻‍❤️‍👩🏻"},{"annotation":"couple with heart: woman, woman, light skin tone, medium-light skin tone","group":1,"hexcode":"1F469-1F3FB-200D-2764-FE0F-200D-1F469-1F3FC","order":2990,"unicode":"👩🏻‍❤️‍👩🏼"},{"annotation":"couple with heart: woman, woman, light skin tone, medium skin tone","group":1,"hexcode":"1F469-1F3FB-200D-2764-FE0F-200D-1F469-1F3FD","order":2992,"unicode":"👩🏻‍❤️‍👩🏽"},{"annotation":"couple with heart: woman, woman, light skin tone, medium-dark skin tone","group":1,"hexcode":"1F469-1F3FB-200D-2764-FE0F-200D-1F469-1F3FE","order":2994,"unicode":"👩🏻‍❤️‍👩🏾"},{"annotation":"couple with heart: woman, woman, light skin tone, dark skin tone","group":1,"hexcode":"1F469-1F3FB-200D-2764-FE0F-200D-1F469-1F3FF","order":2996,"unicode":"👩🏻‍❤️‍👩🏿"},{"annotation":"couple with heart: woman, woman, medium-light skin tone, light skin tone","group":1,"hexcode":"1F469-1F3FC-200D-2764-FE0F-200D-1F469-1F3FB","order":2998,"unicode":"👩🏼‍❤️‍👩🏻"},{"annotation":"couple with heart: woman, woman, medium-light skin tone","group":1,"hexcode":"1F469-1F3FC-200D-2764-FE0F-200D-1F469-1F3FC","order":3000,"unicode":"👩🏼‍❤️‍👩🏼"},{"annotation":"couple with heart: woman, woman, medium-light skin tone, medium skin tone","group":1,"hexcode":"1F469-1F3FC-200D-2764-FE0F-200D-1F469-1F3FD","order":3002,"unicode":"👩🏼‍❤️‍👩🏽"},{"annotation":"couple with heart: woman, woman, medium-light skin tone, medium-dark skin tone","group":1,"hexcode":"1F469-1F3FC-200D-2764-FE0F-200D-1F469-1F3FE","order":3004,"unicode":"👩🏼‍❤️‍👩🏾"},{"annotation":"couple with heart: woman, woman, medium-light skin tone, dark skin tone","group":1,"hexcode":"1F469-1F3FC-200D-2764-FE0F-200D-1F469-1F3FF","order":3006,"unicode":"👩🏼‍❤️‍👩🏿"},{"annotation":"couple with heart: woman, woman, medium skin tone, light skin tone","group":1,"hexcode":"1F469-1F3FD-200D-2764-FE0F-200D-1F469-1F3FB","order":3008,"unicode":"👩🏽‍❤️‍👩🏻"},{"annotation":"couple with heart: woman, woman, medium skin tone, medium-light skin tone","group":1,"hexcode":"1F469-1F3FD-200D-2764-FE0F-200D-1F469-1F3FC","order":3010,"unicode":"👩🏽‍❤️‍👩🏼"},{"annotation":"couple with heart: woman, woman, medium skin tone","group":1,"hexcode":"1F469-1F3FD-200D-2764-FE0F-200D-1F469-1F3FD","order":3012,"unicode":"👩🏽‍❤️‍👩🏽"},{"annotation":"couple with heart: woman, woman, medium skin tone, medium-dark skin tone","group":1,"hexcode":"1F469-1F3FD-200D-2764-FE0F-200D-1F469-1F3FE","order":3014,"unicode":"👩🏽‍❤️‍👩🏾"},{"annotation":"couple with heart: woman, woman, medium skin tone, dark skin tone","group":1,"hexcode":"1F469-1F3FD-200D-2764-FE0F-200D-1F469-1F3FF","order":3016,"unicode":"👩🏽‍❤️‍👩🏿"},{"annotation":"couple with heart: woman, woman, medium-dark skin tone, light skin tone","group":1,"hexcode":"1F469-1F3FE-200D-2764-FE0F-200D-1F469-1F3FB","order":3018,"unicode":"👩🏾‍❤️‍👩🏻"},{"annotation":"couple with heart: woman, woman, medium-dark skin tone, medium-light skin tone","group":1,"hexcode":"1F469-1F3FE-200D-2764-FE0F-200D-1F469-1F3FC","order":3020,"unicode":"👩🏾‍❤️‍👩🏼"},{"annotation":"couple with heart: woman, woman, medium-dark skin tone, medium skin tone","group":1,"hexcode":"1F469-1F3FE-200D-2764-FE0F-200D-1F469-1F3FD","order":3022,"unicode":"👩🏾‍❤️‍👩🏽"},{"annotation":"couple with heart: woman, woman, medium-dark skin tone","group":1,"hexcode":"1F469-1F3FE-200D-2764-FE0F-200D-1F469-1F3FE","order":3024,"unicode":"👩🏾‍❤️‍👩🏾"},{"annotation":"couple with heart: woman, woman, medium-dark skin tone, dark skin tone","group":1,"hexcode":"1F469-1F3FE-200D-2764-FE0F-200D-1F469-1F3FF","order":3026,"unicode":"👩🏾‍❤️‍👩🏿"},{"annotation":"couple with heart: woman, woman, dark skin tone, light skin tone","group":1,"hexcode":"1F469-1F3FF-200D-2764-FE0F-200D-1F469-1F3FB","order":3028,"unicode":"👩🏿‍❤️‍👩🏻"},{"annotation":"couple with heart: woman, woman, dark skin tone, medium-light skin tone","group":1,"hexcode":"1F469-1F3FF-200D-2764-FE0F-200D-1F469-1F3FC","order":3030,"unicode":"👩🏿‍❤️‍👩🏼"},{"annotation":"couple with heart: woman, woman, dark skin tone, medium skin tone","group":1,"hexcode":"1F469-1F3FF-200D-2764-FE0F-200D-1F469-1F3FD","order":3032,"unicode":"👩🏿‍❤️‍👩🏽"},{"annotation":"couple with heart: woman, woman, dark skin tone, medium-dark skin tone","group":1,"hexcode":"1F469-1F3FF-200D-2764-FE0F-200D-1F469-1F3FE","order":3034,"unicode":"👩🏿‍❤️‍👩🏾"},{"annotation":"couple with heart: woman, woman, dark skin tone","group":1,"hexcode":"1F469-1F3FF-200D-2764-FE0F-200D-1F469-1F3FF","order":3036,"unicode":"👩🏿‍❤️‍👩🏿"}]},{"annotation":"family","group":1,"hexcode":"1F46A","order":3038,"tags":["family"],"unicode":"👪️"},{"annotation":"family: man, woman, boy","group":1,"hexcode":"1F468-200D-1F469-200D-1F466","order":3039,"tags":["boy","family","man","woman"],"unicode":"👨‍👩‍👦"},{"annotation":"family: man, woman, girl","group":1,"hexcode":"1F468-200D-1F469-200D-1F467","order":3040,"tags":["family","girl","man","woman"],"unicode":"👨‍👩‍👧"},{"annotation":"family: man, woman, girl, boy","group":1,"hexcode":"1F468-200D-1F469-200D-1F467-200D-1F466","order":3041,"tags":["boy","family","girl","man","woman"],"unicode":"👨‍👩‍👧‍👦"},{"annotation":"family: man, woman, boy, boy","group":1,"hexcode":"1F468-200D-1F469-200D-1F466-200D-1F466","order":3042,"tags":["boy","family","man","woman"],"unicode":"👨‍👩‍👦‍👦"},{"annotation":"family: man, woman, girl, girl","group":1,"hexcode":"1F468-200D-1F469-200D-1F467-200D-1F467","order":3043,"tags":["family","girl","man","woman"],"unicode":"👨‍👩‍👧‍👧"},{"annotation":"family: man, man, boy","group":1,"hexcode":"1F468-200D-1F468-200D-1F466","order":3044,"tags":["boy","family","man"],"unicode":"👨‍👨‍👦"},{"annotation":"family: man, man, girl","group":1,"hexcode":"1F468-200D-1F468-200D-1F467","order":3045,"tags":["family","girl","man"],"unicode":"👨‍👨‍👧"},{"annotation":"family: man, man, girl, boy","group":1,"hexcode":"1F468-200D-1F468-200D-1F467-200D-1F466","order":3046,"tags":["boy","family","girl","man"],"unicode":"👨‍👨‍👧‍👦"},{"annotation":"family: man, man, boy, boy","group":1,"hexcode":"1F468-200D-1F468-200D-1F466-200D-1F466","order":3047,"tags":["boy","family","man"],"unicode":"👨‍👨‍👦‍👦"},{"annotation":"family: man, man, girl, girl","group":1,"hexcode":"1F468-200D-1F468-200D-1F467-200D-1F467","order":3048,"tags":["family","girl","man"],"unicode":"👨‍👨‍👧‍👧"},{"annotation":"family: woman, woman, boy","group":1,"hexcode":"1F469-200D-1F469-200D-1F466","order":3049,"tags":["boy","family","woman"],"unicode":"👩‍👩‍👦"},{"annotation":"family: woman, woman, girl","group":1,"hexcode":"1F469-200D-1F469-200D-1F467","order":3050,"tags":["family","girl","woman"],"unicode":"👩‍👩‍👧"},{"annotation":"family: woman, woman, girl, boy","group":1,"hexcode":"1F469-200D-1F469-200D-1F467-200D-1F466","order":3051,"tags":["boy","family","girl","woman"],"unicode":"👩‍👩‍👧‍👦"},{"annotation":"family: woman, woman, boy, boy","group":1,"hexcode":"1F469-200D-1F469-200D-1F466-200D-1F466","order":3052,"tags":["boy","family","woman"],"unicode":"👩‍👩‍👦‍👦"},{"annotation":"family: woman, woman, girl, girl","group":1,"hexcode":"1F469-200D-1F469-200D-1F467-200D-1F467","order":3053,"tags":["family","girl","woman"],"unicode":"👩‍👩‍👧‍👧"},{"annotation":"family: man, boy","group":1,"hexcode":"1F468-200D-1F466","order":3054,"tags":["boy","family","man"],"unicode":"👨‍👦"},{"annotation":"family: man, boy, boy","group":1,"hexcode":"1F468-200D-1F466-200D-1F466","order":3055,"tags":["boy","family","man"],"unicode":"👨‍👦‍👦"},{"annotation":"family: man, girl","group":1,"hexcode":"1F468-200D-1F467","order":3056,"tags":["family","girl","man"],"unicode":"👨‍👧"},{"annotation":"family: man, girl, boy","group":1,"hexcode":"1F468-200D-1F467-200D-1F466","order":3057,"tags":["boy","family","girl","man"],"unicode":"👨‍👧‍👦"},{"annotation":"family: man, girl, girl","group":1,"hexcode":"1F468-200D-1F467-200D-1F467","order":3058,"tags":["family","girl","man"],"unicode":"👨‍👧‍👧"},{"annotation":"family: woman, boy","group":1,"hexcode":"1F469-200D-1F466","order":3059,"tags":["boy","family","woman"],"unicode":"👩‍👦"},{"annotation":"family: woman, boy, boy","group":1,"hexcode":"1F469-200D-1F466-200D-1F466","order":3060,"tags":["boy","family","woman"],"unicode":"👩‍👦‍👦"},{"annotation":"family: woman, girl","group":1,"hexcode":"1F469-200D-1F467","order":3061,"tags":["family","girl","woman"],"unicode":"👩‍👧"},{"annotation":"family: woman, girl, boy","group":1,"hexcode":"1F469-200D-1F467-200D-1F466","order":3062,"tags":["boy","family","girl","woman"],"unicode":"👩‍👧‍👦"},{"annotation":"family: woman, girl, girl","group":1,"hexcode":"1F469-200D-1F467-200D-1F467","order":3063,"tags":["family","girl","woman"],"unicode":"👩‍👧‍👧"},{"annotation":"speaking head","group":1,"hexcode":"1F5E3","order":3065,"tags":["face","head","silhouette","speak","speaking"],"unicode":"🗣️"},{"annotation":"bust in silhouette","group":1,"hexcode":"1F464","order":3066,"tags":["bust","silhouette"],"unicode":"👤"},{"annotation":"busts in silhouette","group":1,"hexcode":"1F465","order":3067,"tags":["bust","silhouette"],"unicode":"👥"},{"annotation":"people hugging","group":1,"hexcode":"1FAC2","order":3068,"tags":["goodbye","hello","hug","thanks"],"unicode":"🫂"},{"annotation":"footprints","group":1,"hexcode":"1F463","order":3069,"tags":["clothing","footprint","print"],"unicode":"👣"},{"annotation":"light skin tone","group":2,"hexcode":"1F3FB","order":3070,"tags":["skin tone","type 1–2"],"unicode":"🏻"},{"annotation":"medium-light skin tone","group":2,"hexcode":"1F3FC","order":3071,"tags":["skin tone","type 3"],"unicode":"🏼"},{"annotation":"medium skin tone","group":2,"hexcode":"1F3FD","order":3072,"tags":["skin tone","type 4"],"unicode":"🏽"},{"annotation":"medium-dark skin tone","group":2,"hexcode":"1F3FE","order":3073,"tags":["skin tone","type 5"],"unicode":"🏾"},{"annotation":"dark skin tone","group":2,"hexcode":"1F3FF","order":3074,"tags":["skin tone","type 6"],"unicode":"🏿"},{"annotation":"red hair","group":2,"hexcode":"1F9B0","order":3075,"tags":["ginger","redhead"],"unicode":"🦰"},{"annotation":"curly hair","group":2,"hexcode":"1F9B1","order":3076,"tags":["afro","curly","ringlets"],"unicode":"🦱"},{"annotation":"white hair","group":2,"hexcode":"1F9B3","order":3077,"tags":["gray","hair","old","white"],"unicode":"🦳"},{"annotation":"bald","group":2,"hexcode":"1F9B2","order":3078,"tags":["chemotherapy","hairless","no hair","shaven"],"unicode":"🦲"},{"annotation":"monkey face","group":3,"hexcode":"1F435","order":3079,"tags":["face","monkey"],"unicode":"🐵"},{"annotation":"monkey","group":3,"hexcode":"1F412","order":3080,"tags":["monkey"],"unicode":"🐒"},{"annotation":"gorilla","group":3,"hexcode":"1F98D","order":3081,"tags":["gorilla"],"unicode":"🦍"},{"annotation":"orangutan","group":3,"hexcode":"1F9A7","order":3082,"tags":["ape"],"unicode":"🦧"},{"annotation":"dog face","group":3,"hexcode":"1F436","order":3083,"tags":["dog","face","pet"],"unicode":"🐶"},{"annotation":"dog","group":3,"hexcode":"1F415","order":3084,"tags":["pet"],"unicode":"🐕️"},{"annotation":"guide dog","group":3,"hexcode":"1F9AE","order":3085,"tags":["accessibility","blind","guide"],"unicode":"🦮"},{"annotation":"service dog","group":3,"hexcode":"1F415-200D-1F9BA","order":3086,"tags":["accessibility","assistance","dog","service"],"unicode":"🐕‍🦺"},{"annotation":"poodle","group":3,"hexcode":"1F429","order":3087,"tags":["dog"],"unicode":"🐩"},{"annotation":"wolf","group":3,"hexcode":"1F43A","order":3088,"tags":["face"],"unicode":"🐺"},{"annotation":"fox","group":3,"hexcode":"1F98A","order":3089,"tags":["face"],"unicode":"🦊"},{"annotation":"raccoon","group":3,"hexcode":"1F99D","order":3090,"tags":["curious","sly"],"unicode":"🦝"},{"annotation":"cat face","group":3,"hexcode":"1F431","order":3091,"tags":["cat","face","pet"],"unicode":"🐱"},{"annotation":"cat","group":3,"hexcode":"1F408","order":3092,"tags":["pet"],"unicode":"🐈️"},{"annotation":"black cat","group":3,"hexcode":"1F408-200D-2B1B","order":3093,"tags":["black","cat","unlucky"],"unicode":"🐈‍⬛"},{"annotation":"lion","group":3,"hexcode":"1F981","order":3094,"tags":["face","leo","zodiac"],"unicode":"🦁"},{"annotation":"tiger face","group":3,"hexcode":"1F42F","order":3095,"tags":["face","tiger"],"unicode":"🐯"},{"annotation":"tiger","group":3,"hexcode":"1F405","order":3096,"tags":["tiger"],"unicode":"🐅"},{"annotation":"leopard","group":3,"hexcode":"1F406","order":3097,"tags":["leopard"],"unicode":"🐆"},{"annotation":"horse face","group":3,"hexcode":"1F434","order":3098,"tags":["face","horse"],"unicode":"🐴"},{"annotation":"horse","group":3,"hexcode":"1F40E","order":3099,"tags":["equestrian","racehorse","racing"],"unicode":"🐎"},{"annotation":"unicorn","group":3,"hexcode":"1F984","order":3100,"tags":["face"],"unicode":"🦄"},{"annotation":"zebra","group":3,"hexcode":"1F993","order":3101,"tags":["stripe"],"unicode":"🦓"},{"annotation":"deer","group":3,"hexcode":"1F98C","order":3102,"tags":["deer"],"unicode":"🦌"},{"annotation":"bison","group":3,"hexcode":"1F9AC","order":3103,"tags":["buffalo","herd","wisent"],"unicode":"🦬"},{"annotation":"cow face","group":3,"hexcode":"1F42E","order":3104,"tags":["cow","face"],"unicode":"🐮"},{"annotation":"ox","group":3,"hexcode":"1F402","order":3105,"tags":["bull","taurus","zodiac"],"unicode":"🐂"},{"annotation":"water buffalo","group":3,"hexcode":"1F403","order":3106,"tags":["buffalo","water"],"unicode":"🐃"},{"annotation":"cow","group":3,"hexcode":"1F404","order":3107,"tags":["cow"],"unicode":"🐄"},{"annotation":"pig face","group":3,"hexcode":"1F437","order":3108,"tags":["face","pig"],"unicode":"🐷"},{"annotation":"pig","group":3,"hexcode":"1F416","order":3109,"tags":["sow"],"unicode":"🐖"},{"annotation":"boar","group":3,"hexcode":"1F417","order":3110,"tags":["pig"],"unicode":"🐗"},{"annotation":"pig nose","group":3,"hexcode":"1F43D","order":3111,"tags":["face","nose","pig"],"unicode":"🐽"},{"annotation":"ram","group":3,"hexcode":"1F40F","order":3112,"tags":["aries","male","sheep","zodiac"],"unicode":"🐏"},{"annotation":"ewe","group":3,"hexcode":"1F411","order":3113,"tags":["female","sheep"],"unicode":"🐑"},{"annotation":"goat","group":3,"hexcode":"1F410","order":3114,"tags":["capricorn","zodiac"],"unicode":"🐐"},{"annotation":"camel","group":3,"hexcode":"1F42A","order":3115,"tags":["dromedary","hump"],"unicode":"🐪"},{"annotation":"two-hump camel","group":3,"hexcode":"1F42B","order":3116,"tags":["bactrian","camel","hump"],"unicode":"🐫"},{"annotation":"llama","group":3,"hexcode":"1F999","order":3117,"tags":["alpaca","guanaco","vicuña","wool"],"unicode":"🦙"},{"annotation":"giraffe","group":3,"hexcode":"1F992","order":3118,"tags":["spots"],"unicode":"🦒"},{"annotation":"elephant","group":3,"hexcode":"1F418","order":3119,"tags":["elephant"],"unicode":"🐘"},{"annotation":"mammoth","group":3,"hexcode":"1F9A3","order":3120,"tags":["extinction","large","tusk","woolly"],"unicode":"🦣"},{"annotation":"rhinoceros","group":3,"hexcode":"1F98F","order":3121,"tags":["rhinoceros"],"unicode":"🦏"},{"annotation":"hippopotamus","group":3,"hexcode":"1F99B","order":3122,"tags":["hippo"],"unicode":"🦛"},{"annotation":"mouse face","group":3,"hexcode":"1F42D","order":3123,"tags":["face","mouse"],"unicode":"🐭"},{"annotation":"mouse","group":3,"hexcode":"1F401","order":3124,"tags":["mouse"],"unicode":"🐁"},{"annotation":"rat","group":3,"hexcode":"1F400","order":3125,"tags":["rat"],"unicode":"🐀"},{"annotation":"hamster","group":3,"hexcode":"1F439","order":3126,"tags":["face","pet"],"unicode":"🐹"},{"annotation":"rabbit face","group":3,"hexcode":"1F430","order":3127,"tags":["bunny","face","pet","rabbit"],"unicode":"🐰"},{"annotation":"rabbit","group":3,"hexcode":"1F407","order":3128,"tags":["bunny","pet"],"unicode":"🐇"},{"annotation":"chipmunk","group":3,"hexcode":"1F43F","order":3130,"tags":["squirrel"],"unicode":"🐿️"},{"annotation":"beaver","group":3,"hexcode":"1F9AB","order":3131,"tags":["dam"],"unicode":"🦫"},{"annotation":"hedgehog","group":3,"hexcode":"1F994","order":3132,"tags":["spiny"],"unicode":"🦔"},{"annotation":"bat","group":3,"hexcode":"1F987","order":3133,"tags":["vampire"],"unicode":"🦇"},{"annotation":"bear","group":3,"hexcode":"1F43B","order":3134,"tags":["face"],"unicode":"🐻"},{"annotation":"polar bear","group":3,"hexcode":"1F43B-200D-2744-FE0F","order":3135,"tags":["arctic","bear","white"],"unicode":"🐻‍❄️"},{"annotation":"koala","group":3,"hexcode":"1F428","order":3137,"tags":["bear"],"unicode":"🐨"},{"annotation":"panda","group":3,"hexcode":"1F43C","order":3138,"tags":["face"],"unicode":"🐼"},{"annotation":"sloth","group":3,"hexcode":"1F9A5","order":3139,"tags":["lazy","slow"],"unicode":"🦥"},{"annotation":"otter","group":3,"hexcode":"1F9A6","order":3140,"tags":["fishing","playful"],"unicode":"🦦"},{"annotation":"skunk","group":3,"hexcode":"1F9A8","order":3141,"tags":["stink"],"unicode":"🦨"},{"annotation":"kangaroo","group":3,"hexcode":"1F998","order":3142,"tags":["australia","joey","jump","marsupial"],"unicode":"🦘"},{"annotation":"badger","group":3,"hexcode":"1F9A1","order":3143,"tags":["honey badger","pester"],"unicode":"🦡"},{"annotation":"paw prints","group":3,"hexcode":"1F43E","order":3144,"tags":["feet","paw","print"],"unicode":"🐾"},{"annotation":"turkey","group":3,"hexcode":"1F983","order":3145,"tags":["bird"],"unicode":"🦃"},{"annotation":"chicken","group":3,"hexcode":"1F414","order":3146,"tags":["bird"],"unicode":"🐔"},{"annotation":"rooster","group":3,"hexcode":"1F413","order":3147,"tags":["bird"],"unicode":"🐓"},{"annotation":"hatching chick","group":3,"hexcode":"1F423","order":3148,"tags":["baby","bird","chick","hatching"],"unicode":"🐣"},{"annotation":"baby chick","group":3,"hexcode":"1F424","order":3149,"tags":["baby","bird","chick"],"unicode":"🐤"},{"annotation":"front-facing baby chick","group":3,"hexcode":"1F425","order":3150,"tags":["baby","bird","chick"],"unicode":"🐥"},{"annotation":"bird","group":3,"hexcode":"1F426","order":3151,"tags":["bird"],"unicode":"🐦️"},{"annotation":"penguin","group":3,"hexcode":"1F427","order":3152,"tags":["bird"],"unicode":"🐧"},{"annotation":"dove","group":3,"hexcode":"1F54A","order":3154,"tags":["bird","fly","peace"],"unicode":"🕊️"},{"annotation":"eagle","group":3,"hexcode":"1F985","order":3155,"tags":["bird"],"unicode":"🦅"},{"annotation":"duck","group":3,"hexcode":"1F986","order":3156,"tags":["bird"],"unicode":"🦆"},{"annotation":"swan","group":3,"hexcode":"1F9A2","order":3157,"tags":["bird","cygnet","ugly duckling"],"unicode":"🦢"},{"annotation":"owl","group":3,"hexcode":"1F989","order":3158,"tags":["bird","wise"],"unicode":"🦉"},{"annotation":"dodo","group":3,"hexcode":"1F9A4","order":3159,"tags":["extinction","large","mauritius"],"unicode":"🦤"},{"annotation":"feather","group":3,"hexcode":"1FAB6","order":3160,"tags":["bird","flight","light","plumage"],"unicode":"🪶"},{"annotation":"flamingo","group":3,"hexcode":"1F9A9","order":3161,"tags":["flamboyant","tropical"],"unicode":"🦩"},{"annotation":"peacock","group":3,"hexcode":"1F99A","order":3162,"tags":["bird","ostentatious","peahen","proud"],"unicode":"🦚"},{"annotation":"parrot","group":3,"hexcode":"1F99C","order":3163,"tags":["bird","pirate","talk"],"unicode":"🦜"},{"annotation":"frog","group":3,"hexcode":"1F438","order":3164,"tags":["face"],"unicode":"🐸"},{"annotation":"crocodile","group":3,"hexcode":"1F40A","order":3165,"tags":["crocodile"],"unicode":"🐊"},{"annotation":"turtle","group":3,"hexcode":"1F422","order":3166,"tags":["terrapin","tortoise"],"unicode":"🐢"},{"annotation":"lizard","group":3,"hexcode":"1F98E","order":3167,"tags":["reptile"],"unicode":"🦎"},{"annotation":"snake","group":3,"hexcode":"1F40D","order":3168,"tags":["bearer","ophiuchus","serpent","zodiac"],"unicode":"🐍"},{"annotation":"dragon face","group":3,"hexcode":"1F432","order":3169,"tags":["dragon","face","fairy tale"],"unicode":"🐲"},{"annotation":"dragon","group":3,"hexcode":"1F409","order":3170,"tags":["fairy tale"],"unicode":"🐉"},{"annotation":"sauropod","group":3,"hexcode":"1F995","order":3171,"tags":["brachiosaurus","brontosaurus","diplodocus"],"unicode":"🦕"},{"annotation":"T-Rex","group":3,"hexcode":"1F996","order":3172,"tags":["t-rex","tyrannosaurus rex"],"unicode":"🦖"},{"annotation":"spouting whale","group":3,"hexcode":"1F433","order":3173,"tags":["face","spouting","whale"],"unicode":"🐳"},{"annotation":"whale","group":3,"hexcode":"1F40B","order":3174,"tags":["whale"],"unicode":"🐋"},{"annotation":"dolphin","group":3,"hexcode":"1F42C","order":3175,"tags":["flipper"],"unicode":"🐬"},{"annotation":"seal","group":3,"hexcode":"1F9AD","order":3176,"tags":["sea lion"],"unicode":"🦭"},{"annotation":"fish","group":3,"hexcode":"1F41F","order":3177,"tags":["pisces","zodiac"],"unicode":"🐟️"},{"annotation":"tropical fish","group":3,"hexcode":"1F420","order":3178,"tags":["fish","tropical"],"unicode":"🐠"},{"annotation":"blowfish","group":3,"hexcode":"1F421","order":3179,"tags":["fish"],"unicode":"🐡"},{"annotation":"shark","group":3,"hexcode":"1F988","order":3180,"tags":["fish"],"unicode":"🦈"},{"annotation":"octopus","group":3,"hexcode":"1F419","order":3181,"tags":["octopus"],"unicode":"🐙"},{"annotation":"spiral shell","group":3,"hexcode":"1F41A","order":3182,"tags":["shell","spiral"],"unicode":"🐚"},{"annotation":"snail","group":3,"hexcode":"1F40C","order":3183,"tags":["snail"],"unicode":"🐌"},{"annotation":"butterfly","group":3,"hexcode":"1F98B","order":3184,"tags":["insect","pretty"],"unicode":"🦋"},{"annotation":"bug","group":3,"hexcode":"1F41B","order":3185,"tags":["insect"],"unicode":"🐛"},{"annotation":"ant","group":3,"hexcode":"1F41C","order":3186,"tags":["insect"],"unicode":"🐜"},{"annotation":"honeybee","group":3,"hexcode":"1F41D","order":3187,"tags":["bee","insect"],"unicode":"🐝"},{"annotation":"beetle","group":3,"hexcode":"1FAB2","order":3188,"tags":["bug","insect"],"unicode":"🪲"},{"annotation":"lady beetle","group":3,"hexcode":"1F41E","order":3189,"tags":["beetle","insect","ladybird","ladybug"],"unicode":"🐞"},{"annotation":"cricket","group":3,"hexcode":"1F997","order":3190,"tags":["grasshopper"],"unicode":"🦗"},{"annotation":"cockroach","group":3,"hexcode":"1FAB3","order":3191,"tags":["insect","pest","roach"],"unicode":"🪳"},{"annotation":"spider","group":3,"hexcode":"1F577","order":3193,"tags":["insect"],"unicode":"🕷️"},{"annotation":"spider web","group":3,"hexcode":"1F578","order":3195,"tags":["spider","web"],"unicode":"🕸️"},{"annotation":"scorpion","group":3,"hexcode":"1F982","order":3196,"tags":["scorpio","zodiac"],"unicode":"🦂"},{"annotation":"mosquito","group":3,"hexcode":"1F99F","order":3197,"tags":["disease","fever","malaria","pest","virus"],"unicode":"🦟"},{"annotation":"fly","group":3,"hexcode":"1FAB0","order":3198,"tags":["disease","maggot","pest","rotting"],"unicode":"🪰"},{"annotation":"worm","group":3,"hexcode":"1FAB1","order":3199,"tags":["annelid","earthworm","parasite"],"unicode":"🪱"},{"annotation":"microbe","group":3,"hexcode":"1F9A0","order":3200,"tags":["amoeba","bacteria","virus"],"unicode":"🦠"},{"annotation":"bouquet","group":3,"hexcode":"1F490","order":3201,"tags":["flower"],"unicode":"💐"},{"annotation":"cherry blossom","group":3,"hexcode":"1F338","order":3202,"tags":["blossom","cherry","flower"],"unicode":"🌸"},{"annotation":"white flower","group":3,"hexcode":"1F4AE","order":3203,"tags":["flower"],"unicode":"💮"},{"annotation":"rosette","group":3,"hexcode":"1F3F5","order":3205,"tags":["plant"],"unicode":"🏵️"},{"annotation":"rose","group":3,"hexcode":"1F339","order":3206,"tags":["flower"],"unicode":"🌹"},{"annotation":"wilted flower","group":3,"hexcode":"1F940","order":3207,"tags":["flower","wilted"],"unicode":"🥀"},{"annotation":"hibiscus","group":3,"hexcode":"1F33A","order":3208,"tags":["flower"],"unicode":"🌺"},{"annotation":"sunflower","group":3,"hexcode":"1F33B","order":3209,"tags":["flower","sun"],"unicode":"🌻"},{"annotation":"blossom","group":3,"hexcode":"1F33C","order":3210,"tags":["flower"],"unicode":"🌼"},{"annotation":"tulip","group":3,"hexcode":"1F337","order":3211,"tags":["flower"],"unicode":"🌷"},{"annotation":"seedling","group":3,"hexcode":"1F331","order":3212,"tags":["young"],"unicode":"🌱"},{"annotation":"potted plant","group":3,"hexcode":"1FAB4","order":3213,"tags":["boring","grow","house","nurturing","plant","useless"],"unicode":"🪴"},{"annotation":"evergreen tree","group":3,"hexcode":"1F332","order":3214,"tags":["tree"],"unicode":"🌲"},{"annotation":"deciduous tree","group":3,"hexcode":"1F333","order":3215,"tags":["deciduous","shedding","tree"],"unicode":"🌳"},{"annotation":"palm tree","group":3,"hexcode":"1F334","order":3216,"tags":["palm","tree"],"unicode":"🌴"},{"annotation":"cactus","group":3,"hexcode":"1F335","order":3217,"tags":["plant"],"unicode":"🌵"},{"annotation":"sheaf of rice","group":3,"hexcode":"1F33E","order":3218,"tags":["ear","grain","rice"],"unicode":"🌾"},{"annotation":"herb","group":3,"hexcode":"1F33F","order":3219,"tags":["leaf"],"unicode":"🌿"},{"annotation":"shamrock","group":3,"hexcode":"2618","order":3221,"tags":["plant"],"unicode":"☘️"},{"annotation":"four leaf clover","group":3,"hexcode":"1F340","order":3222,"tags":["4","clover","four","four-leaf clover","leaf"],"unicode":"🍀"},{"annotation":"maple leaf","group":3,"hexcode":"1F341","order":3223,"tags":["falling","leaf","maple"],"unicode":"🍁"},{"annotation":"fallen leaf","group":3,"hexcode":"1F342","order":3224,"tags":["falling","leaf"],"unicode":"🍂"},{"annotation":"leaf fluttering in wind","group":3,"hexcode":"1F343","order":3225,"tags":["blow","flutter","leaf","wind"],"unicode":"🍃"},{"annotation":"grapes","group":4,"hexcode":"1F347","order":3226,"tags":["fruit","grape"],"unicode":"🍇"},{"annotation":"melon","group":4,"hexcode":"1F348","order":3227,"tags":["fruit"],"unicode":"🍈"},{"annotation":"watermelon","group":4,"hexcode":"1F349","order":3228,"tags":["fruit"],"unicode":"🍉"},{"annotation":"tangerine","group":4,"hexcode":"1F34A","order":3229,"tags":["fruit","orange"],"unicode":"🍊"},{"annotation":"lemon","group":4,"hexcode":"1F34B","order":3230,"tags":["citrus","fruit"],"unicode":"🍋"},{"annotation":"banana","group":4,"hexcode":"1F34C","order":3231,"tags":["fruit"],"unicode":"🍌"},{"annotation":"pineapple","group":4,"hexcode":"1F34D","order":3232,"tags":["fruit"],"unicode":"🍍"},{"annotation":"mango","group":4,"hexcode":"1F96D","order":3233,"tags":["fruit","tropical"],"unicode":"🥭"},{"annotation":"red apple","group":4,"hexcode":"1F34E","order":3234,"tags":["apple","fruit","red"],"unicode":"🍎"},{"annotation":"green apple","group":4,"hexcode":"1F34F","order":3235,"tags":["apple","fruit","green"],"unicode":"🍏"},{"annotation":"pear","group":4,"hexcode":"1F350","order":3236,"tags":["fruit"],"unicode":"🍐"},{"annotation":"peach","group":4,"hexcode":"1F351","order":3237,"tags":["fruit"],"unicode":"🍑"},{"annotation":"cherries","group":4,"hexcode":"1F352","order":3238,"tags":["berries","cherry","fruit","red"],"unicode":"🍒"},{"annotation":"strawberry","group":4,"hexcode":"1F353","order":3239,"tags":["berry","fruit"],"unicode":"🍓"},{"annotation":"blueberries","group":4,"hexcode":"1FAD0","order":3240,"tags":["berry","bilberry","blue","blueberry"],"unicode":"🫐"},{"annotation":"kiwi fruit","group":4,"hexcode":"1F95D","order":3241,"tags":["food","fruit","kiwi"],"unicode":"🥝"},{"annotation":"tomato","group":4,"hexcode":"1F345","order":3242,"tags":["fruit","vegetable"],"unicode":"🍅"},{"annotation":"olive","group":4,"hexcode":"1FAD2","order":3243,"tags":["food"],"unicode":"🫒"},{"annotation":"coconut","group":4,"hexcode":"1F965","order":3244,"tags":["palm","piña colada"],"unicode":"🥥"},{"annotation":"avocado","group":4,"hexcode":"1F951","order":3245,"tags":["food","fruit"],"unicode":"🥑"},{"annotation":"eggplant","group":4,"hexcode":"1F346","order":3246,"tags":["aubergine","vegetable"],"unicode":"🍆"},{"annotation":"potato","group":4,"hexcode":"1F954","order":3247,"tags":["food","vegetable"],"unicode":"🥔"},{"annotation":"carrot","group":4,"hexcode":"1F955","order":3248,"tags":["food","vegetable"],"unicode":"🥕"},{"annotation":"ear of corn","group":4,"hexcode":"1F33D","order":3249,"tags":["corn","ear","maize","maze"],"unicode":"🌽"},{"annotation":"hot pepper","group":4,"hexcode":"1F336","order":3251,"tags":["hot","pepper"],"unicode":"🌶️"},{"annotation":"bell pepper","group":4,"hexcode":"1FAD1","order":3252,"tags":["capsicum","pepper","vegetable"],"unicode":"🫑"},{"annotation":"cucumber","group":4,"hexcode":"1F952","order":3253,"tags":["food","pickle","vegetable"],"unicode":"🥒"},{"annotation":"leafy green","group":4,"hexcode":"1F96C","order":3254,"tags":["bok choy","cabbage","kale","lettuce"],"unicode":"🥬"},{"annotation":"broccoli","group":4,"hexcode":"1F966","order":3255,"tags":["wild cabbage"],"unicode":"🥦"},{"annotation":"garlic","group":4,"hexcode":"1F9C4","order":3256,"tags":["flavoring"],"unicode":"🧄"},{"annotation":"onion","group":4,"hexcode":"1F9C5","order":3257,"tags":["flavoring"],"unicode":"🧅"},{"annotation":"mushroom","group":4,"hexcode":"1F344","order":3258,"tags":["toadstool"],"unicode":"🍄"},{"annotation":"peanuts","group":4,"hexcode":"1F95C","order":3259,"tags":["food","nut","peanut","vegetable"],"unicode":"🥜"},{"annotation":"chestnut","group":4,"hexcode":"1F330","order":3260,"tags":["plant"],"unicode":"🌰"},{"annotation":"bread","group":4,"hexcode":"1F35E","order":3261,"tags":["loaf"],"unicode":"🍞"},{"annotation":"croissant","group":4,"hexcode":"1F950","order":3262,"tags":["bread","breakfast","food","french","roll"],"unicode":"🥐"},{"annotation":"baguette bread","group":4,"hexcode":"1F956","order":3263,"tags":["baguette","bread","food","french"],"unicode":"🥖"},{"annotation":"flatbread","group":4,"hexcode":"1FAD3","order":3264,"tags":["arepa","lavash","naan","pita"],"unicode":"🫓"},{"annotation":"pretzel","group":4,"hexcode":"1F968","order":3265,"tags":["twisted"],"unicode":"🥨"},{"annotation":"bagel","group":4,"hexcode":"1F96F","order":3266,"tags":["bakery","breakfast","schmear"],"unicode":"🥯"},{"annotation":"pancakes","group":4,"hexcode":"1F95E","order":3267,"tags":["breakfast","crêpe","food","hotcake","pancake"],"unicode":"🥞"},{"annotation":"waffle","group":4,"hexcode":"1F9C7","order":3268,"tags":["breakfast","indecisive","iron"],"unicode":"🧇"},{"annotation":"cheese wedge","group":4,"hexcode":"1F9C0","order":3269,"tags":["cheese"],"unicode":"🧀"},{"annotation":"meat on bone","group":4,"hexcode":"1F356","order":3270,"tags":["bone","meat"],"unicode":"🍖"},{"annotation":"poultry leg","group":4,"hexcode":"1F357","order":3271,"tags":["bone","chicken","drumstick","leg","poultry"],"unicode":"🍗"},{"annotation":"cut of meat","group":4,"hexcode":"1F969","order":3272,"tags":["chop","lambchop","porkchop","steak"],"unicode":"🥩"},{"annotation":"bacon","group":4,"hexcode":"1F953","order":3273,"tags":["breakfast","food","meat"],"unicode":"🥓"},{"annotation":"hamburger","group":4,"hexcode":"1F354","order":3274,"tags":["burger"],"unicode":"🍔"},{"annotation":"french fries","group":4,"hexcode":"1F35F","order":3275,"tags":["french","fries"],"unicode":"🍟"},{"annotation":"pizza","group":4,"hexcode":"1F355","order":3276,"tags":["cheese","slice"],"unicode":"🍕"},{"annotation":"hot dog","group":4,"hexcode":"1F32D","order":3277,"tags":["frankfurter","hotdog","sausage"],"unicode":"🌭"},{"annotation":"sandwich","group":4,"hexcode":"1F96A","order":3278,"tags":["bread"],"unicode":"🥪"},{"annotation":"taco","group":4,"hexcode":"1F32E","order":3279,"tags":["mexican"],"unicode":"🌮"},{"annotation":"burrito","group":4,"hexcode":"1F32F","order":3280,"tags":["mexican","wrap"],"unicode":"🌯"},{"annotation":"tamale","group":4,"hexcode":"1FAD4","order":3281,"tags":["mexican","wrapped"],"unicode":"🫔"},{"annotation":"stuffed flatbread","group":4,"hexcode":"1F959","order":3282,"tags":["falafel","flatbread","food","gyro","kebab","stuffed"],"unicode":"🥙"},{"annotation":"falafel","group":4,"hexcode":"1F9C6","order":3283,"tags":["chickpea","meatball"],"unicode":"🧆"},{"annotation":"egg","group":4,"hexcode":"1F95A","order":3284,"tags":["breakfast","food"],"unicode":"🥚"},{"annotation":"cooking","group":4,"hexcode":"1F373","order":3285,"tags":["breakfast","egg","frying","pan"],"unicode":"🍳"},{"annotation":"shallow pan of food","group":4,"hexcode":"1F958","order":3286,"tags":["casserole","food","paella","pan","shallow"],"unicode":"🥘"},{"annotation":"pot of food","group":4,"hexcode":"1F372","order":3287,"tags":["pot","stew"],"unicode":"🍲"},{"annotation":"fondue","group":4,"hexcode":"1FAD5","order":3288,"tags":["cheese","chocolate","melted","pot","swiss"],"unicode":"🫕"},{"annotation":"bowl with spoon","group":4,"hexcode":"1F963","order":3289,"tags":["breakfast","cereal","congee"],"unicode":"🥣"},{"annotation":"green salad","group":4,"hexcode":"1F957","order":3290,"tags":["food","green","salad"],"unicode":"🥗"},{"annotation":"popcorn","group":4,"hexcode":"1F37F","order":3291,"tags":["popcorn"],"unicode":"🍿"},{"annotation":"butter","group":4,"hexcode":"1F9C8","order":3292,"tags":["dairy"],"unicode":"🧈"},{"annotation":"salt","group":4,"hexcode":"1F9C2","order":3293,"tags":["condiment","shaker"],"unicode":"🧂"},{"annotation":"canned food","group":4,"hexcode":"1F96B","order":3294,"tags":["can"],"unicode":"🥫"},{"annotation":"bento box","group":4,"hexcode":"1F371","order":3295,"tags":["bento","box"],"unicode":"🍱"},{"annotation":"rice cracker","group":4,"hexcode":"1F358","order":3296,"tags":["cracker","rice"],"unicode":"🍘"},{"annotation":"rice ball","group":4,"hexcode":"1F359","order":3297,"tags":["ball","japanese","rice"],"unicode":"🍙"},{"annotation":"cooked rice","group":4,"hexcode":"1F35A","order":3298,"tags":["cooked","rice"],"unicode":"🍚"},{"annotation":"curry rice","group":4,"hexcode":"1F35B","order":3299,"tags":["curry","rice"],"unicode":"🍛"},{"annotation":"steaming bowl","group":4,"hexcode":"1F35C","order":3300,"tags":["bowl","noodle","ramen","steaming"],"unicode":"🍜"},{"annotation":"spaghetti","group":4,"hexcode":"1F35D","order":3301,"tags":["pasta"],"unicode":"🍝"},{"annotation":"roasted sweet potato","group":4,"hexcode":"1F360","order":3302,"tags":["potato","roasted","sweet"],"unicode":"🍠"},{"annotation":"oden","group":4,"hexcode":"1F362","order":3303,"tags":["kebab","seafood","skewer","stick"],"unicode":"🍢"},{"annotation":"sushi","group":4,"hexcode":"1F363","order":3304,"tags":["sushi"],"unicode":"🍣"},{"annotation":"fried shrimp","group":4,"hexcode":"1F364","order":3305,"tags":["fried","prawn","shrimp","tempura"],"unicode":"🍤"},{"annotation":"fish cake with swirl","group":4,"hexcode":"1F365","order":3306,"tags":["cake","fish","pastry","swirl"],"unicode":"🍥"},{"annotation":"moon cake","group":4,"hexcode":"1F96E","order":3307,"tags":["autumn","festival","yuèbǐng"],"unicode":"🥮"},{"annotation":"dango","group":4,"hexcode":"1F361","order":3308,"tags":["dessert","japanese","skewer","stick","sweet"],"unicode":"🍡"},{"annotation":"dumpling","group":4,"hexcode":"1F95F","order":3309,"tags":["empanada","gyōza","jiaozi","pierogi","potsticker"],"unicode":"🥟"},{"annotation":"fortune cookie","group":4,"hexcode":"1F960","order":3310,"tags":["prophecy"],"unicode":"🥠"},{"annotation":"takeout box","group":4,"hexcode":"1F961","order":3311,"tags":["oyster pail"],"unicode":"🥡"},{"annotation":"crab","group":4,"hexcode":"1F980","order":3312,"tags":["cancer","zodiac"],"unicode":"🦀"},{"annotation":"lobster","group":4,"hexcode":"1F99E","order":3313,"tags":["bisque","claws","seafood"],"unicode":"🦞"},{"annotation":"shrimp","group":4,"hexcode":"1F990","order":3314,"tags":["food","shellfish","small"],"unicode":"🦐"},{"annotation":"squid","group":4,"hexcode":"1F991","order":3315,"tags":["food","molusc"],"unicode":"🦑"},{"annotation":"oyster","group":4,"hexcode":"1F9AA","order":3316,"tags":["diving","pearl"],"unicode":"🦪"},{"annotation":"soft ice cream","group":4,"hexcode":"1F366","order":3317,"tags":["cream","dessert","ice","icecream","soft","sweet"],"unicode":"🍦"},{"annotation":"shaved ice","group":4,"hexcode":"1F367","order":3318,"tags":["dessert","ice","shaved","sweet"],"unicode":"🍧"},{"annotation":"ice cream","group":4,"hexcode":"1F368","order":3319,"tags":["cream","dessert","ice","sweet"],"unicode":"🍨"},{"annotation":"doughnut","group":4,"hexcode":"1F369","order":3320,"tags":["breakfast","dessert","donut","sweet"],"unicode":"🍩"},{"annotation":"cookie","group":4,"hexcode":"1F36A","order":3321,"tags":["dessert","sweet"],"unicode":"🍪"},{"annotation":"birthday cake","group":4,"hexcode":"1F382","order":3322,"tags":["birthday","cake","celebration","dessert","pastry","sweet"],"unicode":"🎂"},{"annotation":"shortcake","group":4,"hexcode":"1F370","order":3323,"tags":["cake","dessert","pastry","slice","sweet"],"unicode":"🍰"},{"annotation":"cupcake","group":4,"hexcode":"1F9C1","order":3324,"tags":["bakery","sweet"],"unicode":"🧁"},{"annotation":"pie","group":4,"hexcode":"1F967","order":3325,"tags":["filling","pastry"],"unicode":"🥧"},{"annotation":"chocolate bar","group":4,"hexcode":"1F36B","order":3326,"tags":["bar","chocolate","dessert","sweet"],"unicode":"🍫"},{"annotation":"candy","group":4,"hexcode":"1F36C","order":3327,"tags":["dessert","sweet"],"unicode":"🍬"},{"annotation":"lollipop","group":4,"hexcode":"1F36D","order":3328,"tags":["candy","dessert","sweet"],"unicode":"🍭"},{"annotation":"custard","group":4,"hexcode":"1F36E","order":3329,"tags":["dessert","pudding","sweet"],"unicode":"🍮"},{"annotation":"honey pot","group":4,"hexcode":"1F36F","order":3330,"tags":["honey","honeypot","pot","sweet"],"unicode":"🍯"},{"annotation":"baby bottle","group":4,"hexcode":"1F37C","order":3331,"tags":["baby","bottle","drink","milk"],"unicode":"🍼"},{"annotation":"glass of milk","group":4,"hexcode":"1F95B","order":3332,"tags":["drink","glass","milk"],"unicode":"🥛"},{"annotation":"hot beverage","group":4,"hexcode":"2615","order":3333,"tags":["beverage","coffee","drink","hot","steaming","tea"],"unicode":"☕️"},{"annotation":"teapot","group":4,"hexcode":"1FAD6","order":3334,"tags":["drink","pot","tea"],"unicode":"🫖"},{"annotation":"teacup without handle","group":4,"hexcode":"1F375","order":3335,"tags":["beverage","cup","drink","tea","teacup"],"unicode":"🍵"},{"annotation":"sake","group":4,"hexcode":"1F376","order":3336,"tags":["bar","beverage","bottle","cup","drink"],"unicode":"🍶"},{"annotation":"bottle with popping cork","group":4,"hexcode":"1F37E","order":3337,"tags":["bar","bottle","cork","drink","popping"],"unicode":"🍾"},{"annotation":"wine glass","group":4,"hexcode":"1F377","order":3338,"tags":["bar","beverage","drink","glass","wine"],"unicode":"🍷"},{"annotation":"cocktail glass","group":4,"hexcode":"1F378","order":3339,"tags":["bar","cocktail","drink","glass"],"unicode":"🍸️"},{"annotation":"tropical drink","group":4,"hexcode":"1F379","order":3340,"tags":["bar","drink","tropical"],"unicode":"🍹"},{"annotation":"beer mug","group":4,"hexcode":"1F37A","order":3341,"tags":["bar","beer","drink","mug"],"unicode":"🍺"},{"annotation":"clinking beer mugs","group":4,"hexcode":"1F37B","order":3342,"tags":["bar","beer","clink","drink","mug"],"unicode":"🍻"},{"annotation":"clinking glasses","group":4,"hexcode":"1F942","order":3343,"tags":["celebrate","clink","drink","glass"],"unicode":"🥂"},{"annotation":"tumbler glass","group":4,"hexcode":"1F943","order":3344,"tags":["glass","liquor","shot","tumbler","whisky"],"unicode":"🥃"},{"annotation":"cup with straw","group":4,"hexcode":"1F964","order":3345,"tags":["juice","soda"],"unicode":"🥤"},{"annotation":"bubble tea","group":4,"hexcode":"1F9CB","order":3346,"tags":["bubble","milk","pearl","tea"],"unicode":"🧋"},{"annotation":"beverage box","group":4,"hexcode":"1F9C3","order":3347,"tags":["beverage","box","juice","straw","sweet"],"unicode":"🧃"},{"annotation":"mate","group":4,"hexcode":"1F9C9","order":3348,"tags":["drink"],"unicode":"🧉"},{"annotation":"ice","group":4,"hexcode":"1F9CA","order":3349,"tags":["cold","ice cube","iceberg"],"unicode":"🧊"},{"annotation":"chopsticks","group":4,"hexcode":"1F962","order":3350,"tags":["hashi"],"unicode":"🥢"},{"annotation":"fork and knife with plate","group":4,"hexcode":"1F37D","order":3352,"tags":["cooking","fork","knife","plate"],"unicode":"🍽️"},{"annotation":"fork and knife","group":4,"hexcode":"1F374","order":3353,"tags":["cooking","cutlery","fork","knife"],"unicode":"🍴"},{"annotation":"spoon","group":4,"hexcode":"1F944","order":3354,"tags":["tableware"],"unicode":"🥄"},{"annotation":"kitchen knife","group":4,"hexcode":"1F52A","order":3355,"tags":["cooking","hocho","knife","tool","weapon"],"unicode":"🔪"},{"annotation":"amphora","group":4,"hexcode":"1F3FA","order":3356,"tags":["aquarius","cooking","drink","jug","zodiac"],"unicode":"🏺"},{"annotation":"globe showing Europe-Africa","group":5,"hexcode":"1F30D","order":3357,"tags":["africa","earth","europe","globe","globe showing europe-africa","world"],"unicode":"🌍️"},{"annotation":"globe showing Americas","group":5,"hexcode":"1F30E","order":3358,"tags":["americas","earth","globe","globe showing americas","world"],"unicode":"🌎️"},{"annotation":"globe showing Asia-Australia","group":5,"hexcode":"1F30F","order":3359,"tags":["asia","australia","earth","globe","globe showing asia-australia","world"],"unicode":"🌏️"},{"annotation":"globe with meridians","group":5,"hexcode":"1F310","order":3360,"tags":["earth","globe","meridians","world"],"unicode":"🌐"},{"annotation":"world map","group":5,"hexcode":"1F5FA","order":3362,"tags":["map","world"],"unicode":"🗺️"},{"annotation":"map of Japan","group":5,"hexcode":"1F5FE","order":3363,"tags":["japan","map","map of japan"],"unicode":"🗾"},{"annotation":"compass","group":5,"hexcode":"1F9ED","order":3364,"tags":["magnetic","navigation","orienteering"],"unicode":"🧭"},{"annotation":"snow-capped mountain","group":5,"hexcode":"1F3D4","order":3366,"tags":["cold","mountain","snow"],"unicode":"🏔️"},{"annotation":"mountain","group":5,"hexcode":"26F0","order":3368,"tags":["mountain"],"unicode":"⛰️"},{"annotation":"volcano","group":5,"hexcode":"1F30B","order":3369,"tags":["eruption","mountain"],"unicode":"🌋"},{"annotation":"mount fuji","group":5,"hexcode":"1F5FB","order":3370,"tags":["fuji","mountain"],"unicode":"🗻"},{"annotation":"camping","group":5,"hexcode":"1F3D5","order":3372,"tags":["camping"],"unicode":"🏕️"},{"annotation":"beach with umbrella","group":5,"hexcode":"1F3D6","order":3374,"tags":["beach","umbrella"],"unicode":"🏖️"},{"annotation":"desert","group":5,"hexcode":"1F3DC","order":3376,"tags":["desert"],"unicode":"🏜️"},{"annotation":"desert island","group":5,"hexcode":"1F3DD","order":3378,"tags":["desert","island"],"unicode":"🏝️"},{"annotation":"national park","group":5,"hexcode":"1F3DE","order":3380,"tags":["park"],"unicode":"🏞️"},{"annotation":"stadium","group":5,"hexcode":"1F3DF","order":3382,"tags":["stadium"],"unicode":"🏟️"},{"annotation":"classical building","group":5,"hexcode":"1F3DB","order":3384,"tags":["classical"],"unicode":"🏛️"},{"annotation":"building construction","group":5,"hexcode":"1F3D7","order":3386,"tags":["construction"],"unicode":"🏗️"},{"annotation":"brick","group":5,"hexcode":"1F9F1","order":3387,"tags":["bricks","clay","mortar","wall"],"unicode":"🧱"},{"annotation":"rock","group":5,"hexcode":"1FAA8","order":3388,"tags":["boulder","heavy","solid","stone"],"unicode":"🪨"},{"annotation":"wood","group":5,"hexcode":"1FAB5","order":3389,"tags":["log","lumber","timber"],"unicode":"🪵"},{"annotation":"hut","group":5,"hexcode":"1F6D6","order":3390,"tags":["house","roundhouse","yurt"],"unicode":"🛖"},{"annotation":"houses","group":5,"hexcode":"1F3D8","order":3392,"tags":["houses"],"unicode":"🏘️"},{"annotation":"derelict house","group":5,"hexcode":"1F3DA","order":3394,"tags":["derelict","house"],"unicode":"🏚️"},{"annotation":"house","group":5,"hexcode":"1F3E0","order":3395,"tags":["home"],"unicode":"🏠️"},{"annotation":"house with garden","group":5,"hexcode":"1F3E1","order":3396,"tags":["garden","home","house"],"unicode":"🏡"},{"annotation":"office building","group":5,"hexcode":"1F3E2","order":3397,"tags":["building"],"unicode":"🏢"},{"annotation":"Japanese post office","group":5,"hexcode":"1F3E3","order":3398,"tags":["japanese","japanese post office","post"],"unicode":"🏣"},{"annotation":"post office","group":5,"hexcode":"1F3E4","order":3399,"tags":["european","post"],"unicode":"🏤"},{"annotation":"hospital","group":5,"hexcode":"1F3E5","order":3400,"tags":["doctor","medicine"],"unicode":"🏥"},{"annotation":"bank","group":5,"hexcode":"1F3E6","order":3401,"tags":["building"],"unicode":"🏦"},{"annotation":"hotel","group":5,"hexcode":"1F3E8","order":3402,"tags":["building"],"unicode":"🏨"},{"annotation":"love hotel","group":5,"hexcode":"1F3E9","order":3403,"tags":["hotel","love"],"unicode":"🏩"},{"annotation":"convenience store","group":5,"hexcode":"1F3EA","order":3404,"tags":["convenience","store"],"unicode":"🏪"},{"annotation":"school","group":5,"hexcode":"1F3EB","order":3405,"tags":["building"],"unicode":"🏫"},{"annotation":"department store","group":5,"hexcode":"1F3EC","order":3406,"tags":["department","store"],"unicode":"🏬"},{"annotation":"factory","group":5,"hexcode":"1F3ED","order":3407,"tags":["building"],"unicode":"🏭️"},{"annotation":"Japanese castle","group":5,"hexcode":"1F3EF","order":3408,"tags":["castle","japanese"],"unicode":"🏯"},{"annotation":"castle","group":5,"hexcode":"1F3F0","order":3409,"tags":["european"],"unicode":"🏰"},{"annotation":"wedding","group":5,"hexcode":"1F492","order":3410,"tags":["chapel","romance"],"unicode":"💒"},{"annotation":"Tokyo tower","group":5,"hexcode":"1F5FC","order":3411,"tags":["tokyo","tower"],"unicode":"🗼"},{"annotation":"Statue of Liberty","group":5,"hexcode":"1F5FD","order":3412,"tags":["liberty","statue","statue of liberty"],"unicode":"🗽"},{"annotation":"church","group":5,"hexcode":"26EA","order":3413,"tags":["christian","cross","religion"],"unicode":"⛪️"},{"annotation":"mosque","group":5,"hexcode":"1F54C","order":3414,"tags":["islam","muslim","religion"],"unicode":"🕌"},{"annotation":"hindu temple","group":5,"hexcode":"1F6D5","order":3415,"tags":["hindu","temple"],"unicode":"🛕"},{"annotation":"synagogue","group":5,"hexcode":"1F54D","order":3416,"tags":["jew","jewish","religion","temple"],"unicode":"🕍"},{"annotation":"shinto shrine","group":5,"hexcode":"26E9","order":3418,"tags":["religion","shinto","shrine"],"unicode":"⛩️"},{"annotation":"kaaba","group":5,"hexcode":"1F54B","order":3419,"tags":["islam","muslim","religion"],"unicode":"🕋"},{"annotation":"fountain","group":5,"hexcode":"26F2","order":3420,"tags":["fountain"],"unicode":"⛲️"},{"annotation":"tent","group":5,"hexcode":"26FA","order":3421,"tags":["camping"],"unicode":"⛺️"},{"annotation":"foggy","group":5,"hexcode":"1F301","order":3422,"tags":["fog"],"unicode":"🌁"},{"annotation":"night with stars","group":5,"hexcode":"1F303","order":3423,"tags":["night","star"],"unicode":"🌃"},{"annotation":"cityscape","group":5,"hexcode":"1F3D9","order":3425,"tags":["city"],"unicode":"🏙️"},{"annotation":"sunrise over mountains","group":5,"hexcode":"1F304","order":3426,"tags":["morning","mountain","sun","sunrise"],"unicode":"🌄"},{"annotation":"sunrise","group":5,"hexcode":"1F305","order":3427,"tags":["morning","sun"],"unicode":"🌅"},{"annotation":"cityscape at dusk","group":5,"hexcode":"1F306","order":3428,"tags":["city","dusk","evening","landscape","sunset"],"unicode":"🌆"},{"annotation":"sunset","group":5,"hexcode":"1F307","order":3429,"tags":["dusk","sun"],"unicode":"🌇"},{"annotation":"bridge at night","group":5,"hexcode":"1F309","order":3430,"tags":["bridge","night"],"unicode":"🌉"},{"annotation":"hot springs","group":5,"hexcode":"2668","order":3432,"tags":["hot","hotsprings","springs","steaming"],"unicode":"♨️"},{"annotation":"carousel horse","group":5,"hexcode":"1F3A0","order":3433,"tags":["carousel","horse"],"unicode":"🎠"},{"annotation":"ferris wheel","group":5,"hexcode":"1F3A1","order":3434,"tags":["amusement park","ferris","wheel"],"unicode":"🎡"},{"annotation":"roller coaster","group":5,"hexcode":"1F3A2","order":3435,"tags":["amusement park","coaster","roller"],"unicode":"🎢"},{"annotation":"barber pole","group":5,"hexcode":"1F488","order":3436,"tags":["barber","haircut","pole"],"unicode":"💈"},{"annotation":"circus tent","group":5,"hexcode":"1F3AA","order":3437,"tags":["circus","tent"],"unicode":"🎪"},{"annotation":"locomotive","group":5,"hexcode":"1F682","order":3438,"tags":["engine","railway","steam","train"],"unicode":"🚂"},{"annotation":"railway car","group":5,"hexcode":"1F683","order":3439,"tags":["car","electric","railway","train","tram","trolleybus"],"unicode":"🚃"},{"annotation":"high-speed train","group":5,"hexcode":"1F684","order":3440,"tags":["railway","shinkansen","speed","train"],"unicode":"🚄"},{"annotation":"bullet train","group":5,"hexcode":"1F685","order":3441,"tags":["bullet","railway","shinkansen","speed","train"],"unicode":"🚅"},{"annotation":"train","group":5,"hexcode":"1F686","order":3442,"tags":["railway"],"unicode":"🚆"},{"annotation":"metro","group":5,"hexcode":"1F687","order":3443,"tags":["subway"],"unicode":"🚇️"},{"annotation":"light rail","group":5,"hexcode":"1F688","order":3444,"tags":["railway"],"unicode":"🚈"},{"annotation":"station","group":5,"hexcode":"1F689","order":3445,"tags":["railway","train"],"unicode":"🚉"},{"annotation":"tram","group":5,"hexcode":"1F68A","order":3446,"tags":["trolleybus"],"unicode":"🚊"},{"annotation":"monorail","group":5,"hexcode":"1F69D","order":3447,"tags":["vehicle"],"unicode":"🚝"},{"annotation":"mountain railway","group":5,"hexcode":"1F69E","order":3448,"tags":["car","mountain","railway"],"unicode":"🚞"},{"annotation":"tram car","group":5,"hexcode":"1F68B","order":3449,"tags":["car","tram","trolleybus"],"unicode":"🚋"},{"annotation":"bus","group":5,"hexcode":"1F68C","order":3450,"tags":["vehicle"],"unicode":"🚌"},{"annotation":"oncoming bus","group":5,"hexcode":"1F68D","order":3451,"tags":["bus","oncoming"],"unicode":"🚍️"},{"annotation":"trolleybus","group":5,"hexcode":"1F68E","order":3452,"tags":["bus","tram","trolley"],"unicode":"🚎"},{"annotation":"minibus","group":5,"hexcode":"1F690","order":3453,"tags":["bus"],"unicode":"🚐"},{"annotation":"ambulance","group":5,"hexcode":"1F691","order":3454,"tags":["vehicle"],"unicode":"🚑️"},{"annotation":"fire engine","group":5,"hexcode":"1F692","order":3455,"tags":["engine","fire","truck"],"unicode":"🚒"},{"annotation":"police car","group":5,"hexcode":"1F693","order":3456,"tags":["car","patrol","police"],"unicode":"🚓"},{"annotation":"oncoming police car","group":5,"hexcode":"1F694","order":3457,"tags":["car","oncoming","police"],"unicode":"🚔️"},{"annotation":"taxi","group":5,"hexcode":"1F695","order":3458,"tags":["vehicle"],"unicode":"🚕"},{"annotation":"oncoming taxi","group":5,"hexcode":"1F696","order":3459,"tags":["oncoming","taxi"],"unicode":"🚖"},{"annotation":"automobile","group":5,"hexcode":"1F697","order":3460,"tags":["car"],"unicode":"🚗"},{"annotation":"oncoming automobile","group":5,"hexcode":"1F698","order":3461,"tags":["automobile","car","oncoming"],"unicode":"🚘️"},{"annotation":"sport utility vehicle","group":5,"hexcode":"1F699","order":3462,"tags":["recreational","sport utility"],"unicode":"🚙"},{"annotation":"pickup truck","group":5,"hexcode":"1F6FB","order":3463,"tags":["pick-up","pickup","truck"],"unicode":"🛻"},{"annotation":"delivery truck","group":5,"hexcode":"1F69A","order":3464,"tags":["delivery","truck"],"unicode":"🚚"},{"annotation":"articulated lorry","group":5,"hexcode":"1F69B","order":3465,"tags":["lorry","semi","truck"],"unicode":"🚛"},{"annotation":"tractor","group":5,"hexcode":"1F69C","order":3466,"tags":["vehicle"],"unicode":"🚜"},{"annotation":"racing car","group":5,"hexcode":"1F3CE","order":3468,"tags":["car","racing"],"unicode":"🏎️"},{"annotation":"motorcycle","group":5,"hexcode":"1F3CD","order":3470,"tags":["racing"],"unicode":"🏍️"},{"annotation":"motor scooter","group":5,"hexcode":"1F6F5","order":3471,"tags":["motor","scooter"],"unicode":"🛵"},{"annotation":"manual wheelchair","group":5,"hexcode":"1F9BD","order":3472,"tags":["accessibility"],"unicode":"🦽"},{"annotation":"motorized wheelchair","group":5,"hexcode":"1F9BC","order":3473,"tags":["accessibility"],"unicode":"🦼"},{"annotation":"auto rickshaw","group":5,"hexcode":"1F6FA","order":3474,"tags":["tuk tuk"],"unicode":"🛺"},{"annotation":"bicycle","group":5,"hexcode":"1F6B2","order":3475,"tags":["bike"],"unicode":"🚲️"},{"annotation":"kick scooter","group":5,"hexcode":"1F6F4","order":3476,"tags":["kick","scooter"],"unicode":"🛴"},{"annotation":"skateboard","group":5,"hexcode":"1F6F9","order":3477,"tags":["board"],"unicode":"🛹"},{"annotation":"roller skate","group":5,"hexcode":"1F6FC","order":3478,"tags":["roller","skate"],"unicode":"🛼"},{"annotation":"bus stop","group":5,"hexcode":"1F68F","order":3479,"tags":["bus","busstop","stop"],"unicode":"🚏"},{"annotation":"motorway","group":5,"hexcode":"1F6E3","order":3481,"tags":["highway","road"],"unicode":"🛣️"},{"annotation":"railway track","group":5,"hexcode":"1F6E4","order":3483,"tags":["railway","train"],"unicode":"🛤️"},{"annotation":"oil drum","group":5,"hexcode":"1F6E2","order":3485,"tags":["drum","oil"],"unicode":"🛢️"},{"annotation":"fuel pump","group":5,"hexcode":"26FD","order":3486,"tags":["diesel","fuel","fuelpump","gas","pump","station"],"unicode":"⛽️"},{"annotation":"police car light","group":5,"hexcode":"1F6A8","order":3487,"tags":["beacon","car","light","police","revolving"],"unicode":"🚨"},{"annotation":"horizontal traffic light","group":5,"hexcode":"1F6A5","order":3488,"tags":["light","signal","traffic"],"unicode":"🚥"},{"annotation":"vertical traffic light","group":5,"hexcode":"1F6A6","order":3489,"tags":["light","signal","traffic"],"unicode":"🚦"},{"annotation":"stop sign","group":5,"hexcode":"1F6D1","order":3490,"tags":["octagonal","sign","stop"],"unicode":"🛑"},{"annotation":"construction","group":5,"hexcode":"1F6A7","order":3491,"tags":["barrier"],"unicode":"🚧"},{"annotation":"anchor","group":5,"hexcode":"2693","order":3492,"tags":["ship","tool"],"unicode":"⚓️"},{"annotation":"sailboat","group":5,"hexcode":"26F5","order":3493,"tags":["boat","resort","sea","yacht"],"unicode":"⛵️"},{"annotation":"canoe","group":5,"hexcode":"1F6F6","order":3494,"tags":["boat"],"unicode":"🛶"},{"annotation":"speedboat","group":5,"hexcode":"1F6A4","order":3495,"tags":["boat"],"unicode":"🚤"},{"annotation":"passenger ship","group":5,"hexcode":"1F6F3","order":3497,"tags":["passenger","ship"],"unicode":"🛳️"},{"annotation":"ferry","group":5,"hexcode":"26F4","order":3499,"tags":["boat","passenger"],"unicode":"⛴️"},{"annotation":"motor boat","group":5,"hexcode":"1F6E5","order":3501,"tags":["boat","motorboat"],"unicode":"🛥️"},{"annotation":"ship","group":5,"hexcode":"1F6A2","order":3502,"tags":["boat","passenger"],"unicode":"🚢"},{"annotation":"airplane","group":5,"hexcode":"2708","order":3504,"tags":["aeroplane"],"unicode":"✈️"},{"annotation":"small airplane","group":5,"hexcode":"1F6E9","order":3506,"tags":["aeroplane","airplane"],"unicode":"🛩️"},{"annotation":"airplane departure","group":5,"hexcode":"1F6EB","order":3507,"tags":["aeroplane","airplane","check-in","departure","departures"],"unicode":"🛫"},{"annotation":"airplane arrival","group":5,"hexcode":"1F6EC","order":3508,"tags":["aeroplane","airplane","arrivals","arriving","landing"],"unicode":"🛬"},{"annotation":"parachute","group":5,"hexcode":"1FA82","order":3509,"tags":["hang-glide","parasail","skydive"],"unicode":"🪂"},{"annotation":"seat","group":5,"hexcode":"1F4BA","order":3510,"tags":["chair"],"unicode":"💺"},{"annotation":"helicopter","group":5,"hexcode":"1F681","order":3511,"tags":["vehicle"],"unicode":"🚁"},{"annotation":"suspension railway","group":5,"hexcode":"1F69F","order":3512,"tags":["railway","suspension"],"unicode":"🚟"},{"annotation":"mountain cableway","group":5,"hexcode":"1F6A0","order":3513,"tags":["cable","gondola","mountain"],"unicode":"🚠"},{"annotation":"aerial tramway","group":5,"hexcode":"1F6A1","order":3514,"tags":["aerial","cable","car","gondola","tramway"],"unicode":"🚡"},{"annotation":"satellite","group":5,"hexcode":"1F6F0","order":3516,"tags":["space"],"unicode":"🛰️"},{"annotation":"rocket","group":5,"hexcode":"1F680","order":3517,"tags":["space"],"unicode":"🚀"},{"annotation":"flying saucer","group":5,"hexcode":"1F6F8","order":3518,"tags":["ufo"],"unicode":"🛸"},{"annotation":"bellhop bell","group":5,"hexcode":"1F6CE","order":3520,"tags":["bell","bellhop","hotel"],"unicode":"🛎️"},{"annotation":"luggage","group":5,"hexcode":"1F9F3","order":3521,"tags":["packing","travel"],"unicode":"🧳"},{"annotation":"hourglass done","group":5,"hexcode":"231B","order":3522,"tags":["sand","timer"],"unicode":"⌛️"},{"annotation":"hourglass not done","group":5,"hexcode":"23F3","order":3523,"tags":["hourglass","sand","timer"],"unicode":"⏳️"},{"annotation":"watch","group":5,"hexcode":"231A","order":3524,"tags":["clock"],"unicode":"⌚️"},{"annotation":"alarm clock","group":5,"hexcode":"23F0","order":3525,"tags":["alarm","clock"],"unicode":"⏰"},{"annotation":"stopwatch","group":5,"hexcode":"23F1","order":3527,"tags":["clock"],"unicode":"⏱️"},{"annotation":"timer clock","group":5,"hexcode":"23F2","order":3529,"tags":["clock","timer"],"unicode":"⏲️"},{"annotation":"mantelpiece clock","group":5,"hexcode":"1F570","order":3531,"tags":["clock"],"unicode":"🕰️"},{"annotation":"twelve o’clock","group":5,"hexcode":"1F55B","order":3532,"tags":["00","12","12:00","clock","o’clock","twelve"],"unicode":"🕛️"},{"annotation":"twelve-thirty","group":5,"hexcode":"1F567","order":3533,"tags":["12","12:30","clock","thirty","twelve"],"unicode":"🕧️"},{"annotation":"one o’clock","group":5,"hexcode":"1F550","order":3534,"tags":["00","1","1:00","clock","one","o’clock"],"unicode":"🕐️"},{"annotation":"one-thirty","group":5,"hexcode":"1F55C","order":3535,"tags":["1","1:30","clock","one","thirty"],"unicode":"🕜️"},{"annotation":"two o’clock","group":5,"hexcode":"1F551","order":3536,"tags":["00","2","2:00","clock","o’clock","two"],"unicode":"🕑️"},{"annotation":"two-thirty","group":5,"hexcode":"1F55D","order":3537,"tags":["2","2:30","clock","thirty","two"],"unicode":"🕝️"},{"annotation":"three o’clock","group":5,"hexcode":"1F552","order":3538,"tags":["00","3","3:00","clock","o’clock","three"],"unicode":"🕒️"},{"annotation":"three-thirty","group":5,"hexcode":"1F55E","order":3539,"tags":["3","3:30","clock","thirty","three"],"unicode":"🕞️"},{"annotation":"four o’clock","group":5,"hexcode":"1F553","order":3540,"tags":["00","4","4:00","clock","four","o’clock"],"unicode":"🕓️"},{"annotation":"four-thirty","group":5,"hexcode":"1F55F","order":3541,"tags":["4","4:30","clock","four","thirty"],"unicode":"🕟️"},{"annotation":"five o’clock","group":5,"hexcode":"1F554","order":3542,"tags":["00","5","5:00","clock","five","o’clock"],"unicode":"🕔️"},{"annotation":"five-thirty","group":5,"hexcode":"1F560","order":3543,"tags":["5","5:30","clock","five","thirty"],"unicode":"🕠️"},{"annotation":"six o’clock","group":5,"hexcode":"1F555","order":3544,"tags":["00","6","6:00","clock","o’clock","six"],"unicode":"🕕️"},{"annotation":"six-thirty","group":5,"hexcode":"1F561","order":3545,"tags":["6","6:30","clock","six","thirty"],"unicode":"🕡️"},{"annotation":"seven o’clock","group":5,"hexcode":"1F556","order":3546,"tags":["00","7","7:00","clock","o’clock","seven"],"unicode":"🕖️"},{"annotation":"seven-thirty","group":5,"hexcode":"1F562","order":3547,"tags":["7","7:30","clock","seven","thirty"],"unicode":"🕢️"},{"annotation":"eight o’clock","group":5,"hexcode":"1F557","order":3548,"tags":["00","8","8:00","clock","eight","o’clock"],"unicode":"🕗️"},{"annotation":"eight-thirty","group":5,"hexcode":"1F563","order":3549,"tags":["8","8:30","clock","eight","thirty"],"unicode":"🕣️"},{"annotation":"nine o’clock","group":5,"hexcode":"1F558","order":3550,"tags":["00","9","9:00","clock","nine","o’clock"],"unicode":"🕘️"},{"annotation":"nine-thirty","group":5,"hexcode":"1F564","order":3551,"tags":["9","9:30","clock","nine","thirty"],"unicode":"🕤️"},{"annotation":"ten o’clock","group":5,"hexcode":"1F559","order":3552,"tags":["00","10","10:00","clock","o’clock","ten"],"unicode":"🕙️"},{"annotation":"ten-thirty","group":5,"hexcode":"1F565","order":3553,"tags":["10","10:30","clock","ten","thirty"],"unicode":"🕥️"},{"annotation":"eleven o’clock","group":5,"hexcode":"1F55A","order":3554,"tags":["00","11","11:00","clock","eleven","o’clock"],"unicode":"🕚️"},{"annotation":"eleven-thirty","group":5,"hexcode":"1F566","order":3555,"tags":["11","11:30","clock","eleven","thirty"],"unicode":"🕦️"},{"annotation":"new moon","group":5,"hexcode":"1F311","order":3556,"tags":["dark","moon"],"unicode":"🌑"},{"annotation":"waxing crescent moon","group":5,"hexcode":"1F312","order":3557,"tags":["crescent","moon","waxing"],"unicode":"🌒"},{"annotation":"first quarter moon","group":5,"hexcode":"1F313","order":3558,"tags":["moon","quarter"],"unicode":"🌓"},{"annotation":"waxing gibbous moon","group":5,"hexcode":"1F314","order":3559,"tags":["gibbous","moon","waxing"],"unicode":"🌔"},{"annotation":"full moon","group":5,"hexcode":"1F315","order":3560,"tags":["full","moon"],"unicode":"🌕️"},{"annotation":"waning gibbous moon","group":5,"hexcode":"1F316","order":3561,"tags":["gibbous","moon","waning"],"unicode":"🌖"},{"annotation":"last quarter moon","group":5,"hexcode":"1F317","order":3562,"tags":["moon","quarter"],"unicode":"🌗"},{"annotation":"waning crescent moon","group":5,"hexcode":"1F318","order":3563,"tags":["crescent","moon","waning"],"unicode":"🌘"},{"annotation":"crescent moon","group":5,"hexcode":"1F319","order":3564,"tags":["crescent","moon"],"unicode":"🌙"},{"annotation":"new moon face","group":5,"hexcode":"1F31A","order":3565,"tags":["face","moon"],"unicode":"🌚"},{"annotation":"first quarter moon face","group":5,"hexcode":"1F31B","order":3566,"tags":["face","moon","quarter"],"unicode":"🌛"},{"annotation":"last quarter moon face","group":5,"hexcode":"1F31C","order":3567,"tags":["face","moon","quarter"],"unicode":"🌜️"},{"annotation":"thermometer","group":5,"hexcode":"1F321","order":3569,"tags":["weather"],"unicode":"🌡️"},{"annotation":"sun","group":5,"hexcode":"2600","order":3571,"tags":["bright","rays","sunny"],"unicode":"☀️"},{"annotation":"full moon face","group":5,"hexcode":"1F31D","order":3572,"tags":["bright","face","full","moon"],"unicode":"🌝"},{"annotation":"sun with face","group":5,"hexcode":"1F31E","order":3573,"tags":["bright","face","sun"],"unicode":"🌞"},{"annotation":"ringed planet","group":5,"hexcode":"1FA90","order":3574,"tags":["saturn","saturnine"],"unicode":"🪐"},{"annotation":"star","group":5,"hexcode":"2B50","order":3575,"tags":["star"],"unicode":"⭐️"},{"annotation":"glowing star","group":5,"hexcode":"1F31F","order":3576,"tags":["glittery","glow","shining","sparkle","star"],"unicode":"🌟"},{"annotation":"shooting star","group":5,"hexcode":"1F320","order":3577,"tags":["falling","shooting","star"],"unicode":"🌠"},{"annotation":"milky way","group":5,"hexcode":"1F30C","order":3578,"tags":["space"],"unicode":"🌌"},{"annotation":"cloud","group":5,"hexcode":"2601","order":3580,"tags":["weather"],"unicode":"☁️"},{"annotation":"sun behind cloud","group":5,"hexcode":"26C5","order":3581,"tags":["cloud","sun"],"unicode":"⛅️"},{"annotation":"cloud with lightning and rain","group":5,"hexcode":"26C8","order":3583,"tags":["cloud","rain","thunder"],"unicode":"⛈️"},{"annotation":"sun behind small cloud","group":5,"hexcode":"1F324","order":3585,"tags":["cloud","sun"],"unicode":"🌤️"},{"annotation":"sun behind large cloud","group":5,"hexcode":"1F325","order":3587,"tags":["cloud","sun"],"unicode":"🌥️"},{"annotation":"sun behind rain cloud","group":5,"hexcode":"1F326","order":3589,"tags":["cloud","rain","sun"],"unicode":"🌦️"},{"annotation":"cloud with rain","group":5,"hexcode":"1F327","order":3591,"tags":["cloud","rain"],"unicode":"🌧️"},{"annotation":"cloud with snow","group":5,"hexcode":"1F328","order":3593,"tags":["cloud","cold","snow"],"unicode":"🌨️"},{"annotation":"cloud with lightning","group":5,"hexcode":"1F329","order":3595,"tags":["cloud","lightning"],"unicode":"🌩️"},{"annotation":"tornado","group":5,"hexcode":"1F32A","order":3597,"tags":["cloud","whirlwind"],"unicode":"🌪️"},{"annotation":"fog","group":5,"hexcode":"1F32B","order":3599,"tags":["cloud"],"unicode":"🌫️"},{"annotation":"wind face","group":5,"hexcode":"1F32C","order":3601,"tags":["blow","cloud","face","wind"],"unicode":"🌬️"},{"annotation":"cyclone","group":5,"hexcode":"1F300","order":3602,"tags":["dizzy","hurricane","twister","typhoon"],"unicode":"🌀"},{"annotation":"rainbow","group":5,"hexcode":"1F308","order":3603,"tags":["rain"],"unicode":"🌈"},{"annotation":"closed umbrella","group":5,"hexcode":"1F302","order":3604,"tags":["clothing","rain","umbrella"],"unicode":"🌂"},{"annotation":"umbrella","group":5,"hexcode":"2602","order":3606,"tags":["clothing","rain"],"unicode":"☂️"},{"annotation":"umbrella with rain drops","group":5,"hexcode":"2614","order":3607,"tags":["clothing","drop","rain","umbrella"],"unicode":"☔️"},{"annotation":"umbrella on ground","group":5,"hexcode":"26F1","order":3609,"tags":["rain","sun","umbrella"],"unicode":"⛱️"},{"annotation":"high voltage","group":5,"hexcode":"26A1","order":3610,"tags":["danger","electric","lightning","voltage","zap"],"unicode":"⚡️"},{"annotation":"snowflake","group":5,"hexcode":"2744","order":3612,"tags":["cold","snow"],"unicode":"❄️"},{"annotation":"snowman","group":5,"hexcode":"2603","order":3614,"tags":["cold","snow"],"unicode":"☃️"},{"annotation":"snowman without snow","group":5,"hexcode":"26C4","order":3615,"tags":["cold","snow","snowman"],"unicode":"⛄️"},{"annotation":"comet","group":5,"hexcode":"2604","order":3617,"tags":["space"],"unicode":"☄️"},{"annotation":"fire","group":5,"hexcode":"1F525","order":3618,"tags":["flame","tool"],"unicode":"🔥"},{"annotation":"droplet","group":5,"hexcode":"1F4A7","order":3619,"tags":["cold","comic","drop","sweat"],"unicode":"💧"},{"annotation":"water wave","group":5,"hexcode":"1F30A","order":3620,"tags":["ocean","water","wave"],"unicode":"🌊"},{"annotation":"jack-o-lantern","group":6,"hexcode":"1F383","order":3621,"tags":["celebration","halloween","jack","lantern"],"unicode":"🎃"},{"annotation":"Christmas tree","group":6,"hexcode":"1F384","order":3622,"tags":["celebration","christmas","tree"],"unicode":"🎄"},{"annotation":"fireworks","group":6,"hexcode":"1F386","order":3623,"tags":["celebration"],"unicode":"🎆"},{"annotation":"sparkler","group":6,"hexcode":"1F387","order":3624,"tags":["celebration","fireworks","sparkle"],"unicode":"🎇"},{"annotation":"firecracker","group":6,"hexcode":"1F9E8","order":3625,"tags":["dynamite","explosive","fireworks"],"unicode":"🧨"},{"annotation":"sparkles","group":6,"hexcode":"2728","order":3626,"tags":["*","sparkle","star"],"unicode":"✨"},{"annotation":"balloon","group":6,"hexcode":"1F388","order":3627,"tags":["celebration"],"unicode":"🎈"},{"annotation":"party popper","group":6,"hexcode":"1F389","order":3628,"tags":["celebration","party","popper","tada"],"unicode":"🎉"},{"annotation":"confetti ball","group":6,"hexcode":"1F38A","order":3629,"tags":["ball","celebration","confetti"],"unicode":"🎊"},{"annotation":"tanabata tree","group":6,"hexcode":"1F38B","order":3630,"tags":["banner","celebration","japanese","tree"],"unicode":"🎋"},{"annotation":"pine decoration","group":6,"hexcode":"1F38D","order":3631,"tags":["bamboo","celebration","japanese","pine"],"unicode":"🎍"},{"annotation":"Japanese dolls","group":6,"hexcode":"1F38E","order":3632,"tags":["celebration","doll","festival","japanese","japanese dolls"],"unicode":"🎎"},{"annotation":"carp streamer","group":6,"hexcode":"1F38F","order":3633,"tags":["carp","celebration","streamer"],"unicode":"🎏"},{"annotation":"wind chime","group":6,"hexcode":"1F390","order":3634,"tags":["bell","celebration","chime","wind"],"unicode":"🎐"},{"annotation":"moon viewing ceremony","group":6,"hexcode":"1F391","order":3635,"tags":["celebration","ceremony","moon"],"unicode":"🎑"},{"annotation":"red envelope","group":6,"hexcode":"1F9E7","order":3636,"tags":["gift","good luck","hóngbāo","lai see","money"],"unicode":"🧧"},{"annotation":"ribbon","group":6,"hexcode":"1F380","order":3637,"tags":["celebration"],"unicode":"🎀"},{"annotation":"wrapped gift","group":6,"hexcode":"1F381","order":3638,"tags":["box","celebration","gift","present","wrapped"],"unicode":"🎁"},{"annotation":"reminder ribbon","group":6,"hexcode":"1F397","order":3640,"tags":["celebration","reminder","ribbon"],"unicode":"🎗️"},{"annotation":"admission tickets","group":6,"hexcode":"1F39F","order":3642,"tags":["admission","ticket"],"unicode":"🎟️"},{"annotation":"ticket","group":6,"hexcode":"1F3AB","order":3643,"tags":["admission"],"unicode":"🎫"},{"annotation":"military medal","group":6,"hexcode":"1F396","order":3645,"tags":["celebration","medal","military"],"unicode":"🎖️"},{"annotation":"trophy","group":6,"hexcode":"1F3C6","order":3646,"tags":["prize"],"unicode":"🏆️"},{"annotation":"sports medal","group":6,"hexcode":"1F3C5","order":3647,"tags":["medal"],"unicode":"🏅"},{"annotation":"1st place medal","group":6,"hexcode":"1F947","order":3648,"tags":["first","gold","medal"],"unicode":"🥇"},{"annotation":"2nd place medal","group":6,"hexcode":"1F948","order":3649,"tags":["medal","second","silver"],"unicode":"🥈"},{"annotation":"3rd place medal","group":6,"hexcode":"1F949","order":3650,"tags":["bronze","medal","third"],"unicode":"🥉"},{"annotation":"soccer ball","group":6,"hexcode":"26BD","order":3651,"tags":["ball","football","soccer"],"unicode":"⚽️"},{"annotation":"baseball","group":6,"hexcode":"26BE","order":3652,"tags":["ball"],"unicode":"⚾️"},{"annotation":"softball","group":6,"hexcode":"1F94E","order":3653,"tags":["ball","glove","underarm"],"unicode":"🥎"},{"annotation":"basketball","group":6,"hexcode":"1F3C0","order":3654,"tags":["ball","hoop"],"unicode":"🏀"},{"annotation":"volleyball","group":6,"hexcode":"1F3D0","order":3655,"tags":["ball","game"],"unicode":"🏐"},{"annotation":"american football","group":6,"hexcode":"1F3C8","order":3656,"tags":["american","ball","football"],"unicode":"🏈"},{"annotation":"rugby football","group":6,"hexcode":"1F3C9","order":3657,"tags":["ball","football","rugby"],"unicode":"🏉"},{"annotation":"tennis","group":6,"hexcode":"1F3BE","order":3658,"tags":["ball","racquet"],"unicode":"🎾"},{"annotation":"flying disc","group":6,"hexcode":"1F94F","order":3659,"tags":["ultimate"],"unicode":"🥏"},{"annotation":"bowling","group":6,"hexcode":"1F3B3","order":3660,"tags":["ball","game"],"unicode":"🎳"},{"annotation":"cricket game","group":6,"hexcode":"1F3CF","order":3661,"tags":["ball","bat","game"],"unicode":"🏏"},{"annotation":"field hockey","group":6,"hexcode":"1F3D1","order":3662,"tags":["ball","field","game","hockey","stick"],"unicode":"🏑"},{"annotation":"ice hockey","group":6,"hexcode":"1F3D2","order":3663,"tags":["game","hockey","ice","puck","stick"],"unicode":"🏒"},{"annotation":"lacrosse","group":6,"hexcode":"1F94D","order":3664,"tags":["ball","goal","stick"],"unicode":"🥍"},{"annotation":"ping pong","group":6,"hexcode":"1F3D3","order":3665,"tags":["ball","bat","game","paddle","table tennis"],"unicode":"🏓"},{"annotation":"badminton","group":6,"hexcode":"1F3F8","order":3666,"tags":["birdie","game","racquet","shuttlecock"],"unicode":"🏸"},{"annotation":"boxing glove","group":6,"hexcode":"1F94A","order":3667,"tags":["boxing","glove"],"unicode":"🥊"},{"annotation":"martial arts uniform","group":6,"hexcode":"1F94B","order":3668,"tags":["judo","karate","martial arts","taekwondo","uniform"],"unicode":"🥋"},{"annotation":"goal net","group":6,"hexcode":"1F945","order":3669,"tags":["goal","net"],"unicode":"🥅"},{"annotation":"flag in hole","group":6,"hexcode":"26F3","order":3670,"tags":["golf","hole"],"unicode":"⛳️"},{"annotation":"ice skate","group":6,"hexcode":"26F8","order":3672,"tags":["ice","skate"],"unicode":"⛸️"},{"annotation":"fishing pole","group":6,"hexcode":"1F3A3","order":3673,"tags":["fish","pole"],"unicode":"🎣"},{"annotation":"diving mask","group":6,"hexcode":"1F93F","order":3674,"tags":["diving","scuba","snorkeling"],"unicode":"🤿"},{"annotation":"running shirt","group":6,"hexcode":"1F3BD","order":3675,"tags":["athletics","running","sash","shirt"],"unicode":"🎽"},{"annotation":"skis","group":6,"hexcode":"1F3BF","order":3676,"tags":["ski","snow"],"unicode":"🎿"},{"annotation":"sled","group":6,"hexcode":"1F6F7","order":3677,"tags":["sledge","sleigh"],"unicode":"🛷"},{"annotation":"curling stone","group":6,"hexcode":"1F94C","order":3678,"tags":["game","rock"],"unicode":"🥌"},{"annotation":"bullseye","group":6,"hexcode":"1F3AF","order":3679,"tags":["dart","direct hit","game","hit","target"],"unicode":"🎯"},{"annotation":"yo-yo","group":6,"hexcode":"1FA80","order":3680,"tags":["fluctuate","toy"],"unicode":"🪀"},{"annotation":"kite","group":6,"hexcode":"1FA81","order":3681,"tags":["fly","soar"],"unicode":"🪁"},{"annotation":"pool 8 ball","group":6,"hexcode":"1F3B1","order":3682,"tags":["8","ball","billiard","eight","game"],"unicode":"🎱"},{"annotation":"crystal ball","group":6,"hexcode":"1F52E","order":3683,"tags":["ball","crystal","fairy tale","fantasy","fortune","tool"],"unicode":"🔮"},{"annotation":"magic wand","group":6,"hexcode":"1FA84","order":3684,"tags":["magic","witch","wizard"],"unicode":"🪄"},{"annotation":"nazar amulet","group":6,"hexcode":"1F9FF","order":3685,"tags":["bead","charm","evil-eye","nazar","talisman"],"unicode":"🧿"},{"annotation":"video game","group":6,"hexcode":"1F3AE","order":3686,"tags":["controller","game"],"unicode":"🎮️"},{"annotation":"joystick","group":6,"hexcode":"1F579","order":3688,"tags":["game","video game"],"unicode":"🕹️"},{"annotation":"slot machine","group":6,"hexcode":"1F3B0","order":3689,"tags":["game","slot"],"unicode":"🎰"},{"annotation":"game die","group":6,"hexcode":"1F3B2","order":3690,"tags":["dice","die","game"],"unicode":"🎲"},{"annotation":"puzzle piece","group":6,"hexcode":"1F9E9","order":3691,"tags":["clue","interlocking","jigsaw","piece","puzzle"],"unicode":"🧩"},{"annotation":"teddy bear","group":6,"hexcode":"1F9F8","order":3692,"tags":["plaything","plush","stuffed","toy"],"unicode":"🧸"},{"annotation":"piñata","group":6,"hexcode":"1FA85","order":3693,"tags":["celebration","party"],"unicode":"🪅"},{"annotation":"nesting dolls","group":6,"hexcode":"1FA86","order":3694,"tags":["doll","nesting","russia"],"unicode":"🪆"},{"annotation":"spade suit","group":6,"hexcode":"2660","order":3696,"tags":["card","game"],"unicode":"♠️"},{"annotation":"heart suit","group":6,"hexcode":"2665","order":3698,"tags":["card","game"],"unicode":"♥️"},{"annotation":"diamond suit","group":6,"hexcode":"2666","order":3700,"tags":["card","game"],"unicode":"♦️"},{"annotation":"club suit","group":6,"hexcode":"2663","order":3702,"tags":["card","game"],"unicode":"♣️"},{"annotation":"chess pawn","group":6,"hexcode":"265F","order":3704,"tags":["chess","dupe","expendable"],"unicode":"♟️"},{"annotation":"joker","group":6,"hexcode":"1F0CF","order":3705,"tags":["card","game","wildcard"],"unicode":"🃏"},{"annotation":"mahjong red dragon","group":6,"hexcode":"1F004","order":3706,"tags":["game","mahjong","red"],"unicode":"🀄️"},{"annotation":"flower playing cards","group":6,"hexcode":"1F3B4","order":3707,"tags":["card","flower","game","japanese","playing"],"unicode":"🎴"},{"annotation":"performing arts","group":6,"hexcode":"1F3AD","order":3708,"tags":["art","mask","performing","theater","theatre"],"unicode":"🎭️"},{"annotation":"framed picture","group":6,"hexcode":"1F5BC","order":3710,"tags":["art","frame","museum","painting","picture"],"unicode":"🖼️"},{"annotation":"artist palette","group":6,"hexcode":"1F3A8","order":3711,"tags":["art","museum","painting","palette"],"unicode":"🎨"},{"annotation":"thread","group":6,"hexcode":"1F9F5","order":3712,"tags":["needle","sewing","spool","string"],"unicode":"🧵"},{"annotation":"sewing needle","group":6,"hexcode":"1FAA1","order":3713,"tags":["embroidery","needle","sewing","stitches","sutures","tailoring"],"unicode":"🪡"},{"annotation":"yarn","group":6,"hexcode":"1F9F6","order":3714,"tags":["ball","crochet","knit"],"unicode":"🧶"},{"annotation":"knot","group":6,"hexcode":"1FAA2","order":3715,"tags":["rope","tangled","tie","twine","twist"],"unicode":"🪢"},{"annotation":"glasses","group":7,"hexcode":"1F453","order":3716,"tags":["clothing","eye","eyeglasses","eyewear"],"unicode":"👓️"},{"annotation":"sunglasses","group":7,"hexcode":"1F576","order":3718,"tags":["dark","eye","eyewear","glasses"],"unicode":"🕶️"},{"annotation":"goggles","group":7,"hexcode":"1F97D","order":3719,"tags":["eye protection","swimming","welding"],"unicode":"🥽"},{"annotation":"lab coat","group":7,"hexcode":"1F97C","order":3720,"tags":["doctor","experiment","scientist"],"unicode":"🥼"},{"annotation":"safety vest","group":7,"hexcode":"1F9BA","order":3721,"tags":["emergency","safety","vest"],"unicode":"🦺"},{"annotation":"necktie","group":7,"hexcode":"1F454","order":3722,"tags":["clothing","tie"],"unicode":"👔"},{"annotation":"t-shirt","group":7,"hexcode":"1F455","order":3723,"tags":["clothing","shirt","tshirt"],"unicode":"👕"},{"annotation":"jeans","group":7,"hexcode":"1F456","order":3724,"tags":["clothing","pants","trousers"],"unicode":"👖"},{"annotation":"scarf","group":7,"hexcode":"1F9E3","order":3725,"tags":["neck"],"unicode":"🧣"},{"annotation":"gloves","group":7,"hexcode":"1F9E4","order":3726,"tags":["hand"],"unicode":"🧤"},{"annotation":"coat","group":7,"hexcode":"1F9E5","order":3727,"tags":["jacket"],"unicode":"🧥"},{"annotation":"socks","group":7,"hexcode":"1F9E6","order":3728,"tags":["stocking"],"unicode":"🧦"},{"annotation":"dress","group":7,"hexcode":"1F457","order":3729,"tags":["clothing"],"unicode":"👗"},{"annotation":"kimono","group":7,"hexcode":"1F458","order":3730,"tags":["clothing"],"unicode":"👘"},{"annotation":"sari","group":7,"hexcode":"1F97B","order":3731,"tags":["clothing","dress"],"unicode":"🥻"},{"annotation":"one-piece swimsuit","group":7,"hexcode":"1FA71","order":3732,"tags":["bathing suit"],"unicode":"🩱"},{"annotation":"briefs","group":7,"hexcode":"1FA72","order":3733,"tags":["bathing suit","one-piece","swimsuit","underwear"],"unicode":"🩲"},{"annotation":"shorts","group":7,"hexcode":"1FA73","order":3734,"tags":["bathing suit","pants","underwear"],"unicode":"🩳"},{"annotation":"bikini","group":7,"hexcode":"1F459","order":3735,"tags":["clothing","swim"],"unicode":"👙"},{"annotation":"woman’s clothes","group":7,"hexcode":"1F45A","order":3736,"tags":["clothing","woman"],"unicode":"👚"},{"annotation":"purse","group":7,"hexcode":"1F45B","order":3737,"tags":["clothing","coin"],"unicode":"👛"},{"annotation":"handbag","group":7,"hexcode":"1F45C","order":3738,"tags":["bag","clothing","purse"],"unicode":"👜"},{"annotation":"clutch bag","group":7,"hexcode":"1F45D","order":3739,"tags":["bag","clothing","pouch"],"unicode":"👝"},{"annotation":"shopping bags","group":7,"hexcode":"1F6CD","order":3741,"tags":["bag","hotel","shopping"],"unicode":"🛍️"},{"annotation":"backpack","group":7,"hexcode":"1F392","order":3742,"tags":["bag","rucksack","satchel","school"],"unicode":"🎒"},{"annotation":"thong sandal","group":7,"hexcode":"1FA74","order":3743,"tags":["beach sandals","sandals","thong sandals","thongs","zōri"],"unicode":"🩴"},{"annotation":"man’s shoe","group":7,"hexcode":"1F45E","order":3744,"tags":["clothing","man","shoe"],"unicode":"👞"},{"annotation":"running shoe","group":7,"hexcode":"1F45F","order":3745,"tags":["athletic","clothing","shoe","sneaker"],"unicode":"👟"},{"annotation":"hiking boot","group":7,"hexcode":"1F97E","order":3746,"tags":["backpacking","boot","camping","hiking"],"unicode":"🥾"},{"annotation":"flat shoe","group":7,"hexcode":"1F97F","order":3747,"tags":["ballet flat","slip-on","slipper"],"unicode":"🥿"},{"annotation":"high-heeled shoe","group":7,"hexcode":"1F460","order":3748,"tags":["clothing","heel","shoe","woman"],"unicode":"👠"},{"annotation":"woman’s sandal","group":7,"hexcode":"1F461","order":3749,"tags":["clothing","sandal","shoe","woman"],"unicode":"👡"},{"annotation":"ballet shoes","group":7,"hexcode":"1FA70","order":3750,"tags":["ballet","dance"],"unicode":"🩰"},{"annotation":"woman’s boot","group":7,"hexcode":"1F462","order":3751,"tags":["boot","clothing","shoe","woman"],"unicode":"👢"},{"annotation":"crown","group":7,"hexcode":"1F451","order":3752,"tags":["clothing","king","queen"],"unicode":"👑"},{"annotation":"woman’s hat","group":7,"hexcode":"1F452","order":3753,"tags":["clothing","hat","woman"],"unicode":"👒"},{"annotation":"top hat","group":7,"hexcode":"1F3A9","order":3754,"tags":["clothing","hat","top","tophat"],"unicode":"🎩"},{"annotation":"graduation cap","group":7,"hexcode":"1F393","order":3755,"tags":["cap","celebration","clothing","graduation","hat"],"unicode":"🎓️"},{"annotation":"billed cap","group":7,"hexcode":"1F9E2","order":3756,"tags":["baseball cap"],"unicode":"🧢"},{"annotation":"military helmet","group":7,"hexcode":"1FA96","order":3757,"tags":["army","helmet","military","soldier","warrior"],"unicode":"🪖"},{"annotation":"rescue worker’s helmet","group":7,"hexcode":"26D1","order":3759,"tags":["aid","cross","face","hat","helmet"],"unicode":"⛑️"},{"annotation":"prayer beads","group":7,"hexcode":"1F4FF","order":3760,"tags":["beads","clothing","necklace","prayer","religion"],"unicode":"📿"},{"annotation":"lipstick","group":7,"hexcode":"1F484","order":3761,"tags":["cosmetics","makeup"],"unicode":"💄"},{"annotation":"ring","group":7,"hexcode":"1F48D","order":3762,"tags":["diamond"],"unicode":"💍"},{"annotation":"gem stone","group":7,"hexcode":"1F48E","order":3763,"tags":["diamond","gem","jewel"],"unicode":"💎"},{"annotation":"muted speaker","group":7,"hexcode":"1F507","order":3764,"tags":["mute","quiet","silent","speaker"],"unicode":"🔇"},{"annotation":"speaker low volume","group":7,"hexcode":"1F508","order":3765,"tags":["soft"],"unicode":"🔈️"},{"annotation":"speaker medium volume","group":7,"hexcode":"1F509","order":3766,"tags":["medium"],"unicode":"🔉"},{"annotation":"speaker high volume","group":7,"hexcode":"1F50A","order":3767,"tags":["loud"],"unicode":"🔊"},{"annotation":"loudspeaker","group":7,"hexcode":"1F4E2","order":3768,"tags":["loud","public address"],"unicode":"📢"},{"annotation":"megaphone","group":7,"hexcode":"1F4E3","order":3769,"tags":["cheering"],"unicode":"📣"},{"annotation":"postal horn","group":7,"hexcode":"1F4EF","order":3770,"tags":["horn","post","postal"],"unicode":"📯"},{"annotation":"bell","group":7,"hexcode":"1F514","order":3771,"tags":["bell"],"unicode":"🔔"},{"annotation":"bell with slash","group":7,"hexcode":"1F515","order":3772,"tags":["bell","forbidden","mute","quiet","silent"],"unicode":"🔕"},{"annotation":"musical score","group":7,"hexcode":"1F3BC","order":3773,"tags":["music","score"],"unicode":"🎼"},{"annotation":"musical note","group":7,"hexcode":"1F3B5","order":3774,"tags":["music","note"],"unicode":"🎵"},{"annotation":"musical notes","group":7,"hexcode":"1F3B6","order":3775,"tags":["music","note","notes"],"unicode":"🎶"},{"annotation":"studio microphone","group":7,"hexcode":"1F399","order":3777,"tags":["mic","microphone","music","studio"],"unicode":"🎙️"},{"annotation":"level slider","group":7,"hexcode":"1F39A","order":3779,"tags":["level","music","slider"],"unicode":"🎚️"},{"annotation":"control knobs","group":7,"hexcode":"1F39B","order":3781,"tags":["control","knobs","music"],"unicode":"🎛️"},{"annotation":"microphone","group":7,"hexcode":"1F3A4","order":3782,"tags":["karaoke","mic"],"unicode":"🎤"},{"annotation":"headphone","group":7,"hexcode":"1F3A7","order":3783,"tags":["earbud"],"unicode":"🎧️"},{"annotation":"radio","group":7,"hexcode":"1F4FB","order":3784,"tags":["video"],"unicode":"📻️"},{"annotation":"saxophone","group":7,"hexcode":"1F3B7","order":3785,"tags":["instrument","music","sax"],"unicode":"🎷"},{"annotation":"accordion","group":7,"hexcode":"1FA97","order":3786,"tags":["concertina","squeeze box"],"unicode":"🪗"},{"annotation":"guitar","group":7,"hexcode":"1F3B8","order":3787,"tags":["instrument","music"],"unicode":"🎸"},{"annotation":"musical keyboard","group":7,"hexcode":"1F3B9","order":3788,"tags":["instrument","keyboard","music","piano"],"unicode":"🎹"},{"annotation":"trumpet","group":7,"hexcode":"1F3BA","order":3789,"tags":["instrument","music"],"unicode":"🎺"},{"annotation":"violin","group":7,"hexcode":"1F3BB","order":3790,"tags":["instrument","music"],"unicode":"🎻"},{"annotation":"banjo","group":7,"hexcode":"1FA95","order":3791,"tags":["music","stringed"],"unicode":"🪕"},{"annotation":"drum","group":7,"hexcode":"1F941","order":3792,"tags":["drumsticks","music"],"unicode":"🥁"},{"annotation":"long drum","group":7,"hexcode":"1FA98","order":3793,"tags":["beat","conga","drum","rhythm"],"unicode":"🪘"},{"annotation":"mobile phone","group":7,"hexcode":"1F4F1","order":3794,"tags":["cell","mobile","phone","telephone"],"unicode":"📱"},{"annotation":"mobile phone with arrow","group":7,"hexcode":"1F4F2","order":3795,"tags":["arrow","cell","mobile","phone","receive"],"unicode":"📲"},{"annotation":"telephone","group":7,"hexcode":"260E","order":3797,"tags":["phone"],"unicode":"☎️"},{"annotation":"telephone receiver","group":7,"hexcode":"1F4DE","order":3798,"tags":["phone","receiver","telephone"],"unicode":"📞"},{"annotation":"pager","group":7,"hexcode":"1F4DF","order":3799,"tags":["pager"],"unicode":"📟️"},{"annotation":"fax machine","group":7,"hexcode":"1F4E0","order":3800,"tags":["fax"],"unicode":"📠"},{"annotation":"battery","group":7,"hexcode":"1F50B","order":3801,"tags":["battery"],"unicode":"🔋"},{"annotation":"electric plug","group":7,"hexcode":"1F50C","order":3802,"tags":["electric","electricity","plug"],"unicode":"🔌"},{"annotation":"laptop","group":7,"hexcode":"1F4BB","order":3803,"tags":["computer","pc","personal"],"unicode":"💻️"},{"annotation":"desktop computer","group":7,"hexcode":"1F5A5","order":3805,"tags":["computer","desktop"],"unicode":"🖥️"},{"annotation":"printer","group":7,"hexcode":"1F5A8","order":3807,"tags":["computer"],"unicode":"🖨️"},{"annotation":"keyboard","group":7,"hexcode":"2328","order":3809,"tags":["computer"],"unicode":"⌨️"},{"annotation":"computer mouse","group":7,"hexcode":"1F5B1","order":3811,"tags":["computer"],"unicode":"🖱️"},{"annotation":"trackball","group":7,"hexcode":"1F5B2","order":3813,"tags":["computer"],"unicode":"🖲️"},{"annotation":"computer disk","group":7,"hexcode":"1F4BD","order":3814,"tags":["computer","disk","minidisk","optical"],"unicode":"💽"},{"annotation":"floppy disk","group":7,"hexcode":"1F4BE","order":3815,"tags":["computer","disk","floppy"],"unicode":"💾"},{"annotation":"optical disk","group":7,"hexcode":"1F4BF","order":3816,"tags":["cd","computer","disk","optical"],"unicode":"💿️"},{"annotation":"dvd","group":7,"hexcode":"1F4C0","order":3817,"tags":["blu-ray","computer","disk","optical"],"unicode":"📀"},{"annotation":"abacus","group":7,"hexcode":"1F9EE","order":3818,"tags":["calculation"],"unicode":"🧮"},{"annotation":"movie camera","group":7,"hexcode":"1F3A5","order":3819,"tags":["camera","cinema","movie"],"unicode":"🎥"},{"annotation":"film frames","group":7,"hexcode":"1F39E","order":3821,"tags":["cinema","film","frames","movie"],"unicode":"🎞️"},{"annotation":"film projector","group":7,"hexcode":"1F4FD","order":3823,"tags":["cinema","film","movie","projector","video"],"unicode":"📽️"},{"annotation":"clapper board","group":7,"hexcode":"1F3AC","order":3824,"tags":["clapper","movie"],"unicode":"🎬️"},{"annotation":"television","group":7,"hexcode":"1F4FA","order":3825,"tags":["tv","video"],"unicode":"📺️"},{"annotation":"camera","group":7,"hexcode":"1F4F7","order":3826,"tags":["video"],"unicode":"📷️"},{"annotation":"camera with flash","group":7,"hexcode":"1F4F8","order":3827,"tags":["camera","flash","video"],"unicode":"📸"},{"annotation":"video camera","group":7,"hexcode":"1F4F9","order":3828,"tags":["camera","video"],"unicode":"📹️"},{"annotation":"videocassette","group":7,"hexcode":"1F4FC","order":3829,"tags":["tape","vhs","video"],"unicode":"📼"},{"annotation":"magnifying glass tilted left","group":7,"hexcode":"1F50D","order":3830,"tags":["glass","magnifying","search","tool"],"unicode":"🔍️"},{"annotation":"magnifying glass tilted right","group":7,"hexcode":"1F50E","order":3831,"tags":["glass","magnifying","search","tool"],"unicode":"🔎"},{"annotation":"candle","group":7,"hexcode":"1F56F","order":3833,"tags":["light"],"unicode":"🕯️"},{"annotation":"light bulb","group":7,"hexcode":"1F4A1","order":3834,"tags":["bulb","comic","electric","idea","light"],"unicode":"💡"},{"annotation":"flashlight","group":7,"hexcode":"1F526","order":3835,"tags":["electric","light","tool","torch"],"unicode":"🔦"},{"annotation":"red paper lantern","group":7,"hexcode":"1F3EE","order":3836,"tags":["bar","lantern","light","red"],"unicode":"🏮"},{"annotation":"diya lamp","group":7,"hexcode":"1FA94","order":3837,"tags":["diya","lamp","oil"],"unicode":"🪔"},{"annotation":"notebook with decorative cover","group":7,"hexcode":"1F4D4","order":3838,"tags":["book","cover","decorated","notebook"],"unicode":"📔"},{"annotation":"closed book","group":7,"hexcode":"1F4D5","order":3839,"tags":["book","closed"],"unicode":"📕"},{"annotation":"open book","group":7,"hexcode":"1F4D6","order":3840,"tags":["book","open"],"unicode":"📖"},{"annotation":"green book","group":7,"hexcode":"1F4D7","order":3841,"tags":["book","green"],"unicode":"📗"},{"annotation":"blue book","group":7,"hexcode":"1F4D8","order":3842,"tags":["blue","book"],"unicode":"📘"},{"annotation":"orange book","group":7,"hexcode":"1F4D9","order":3843,"tags":["book","orange"],"unicode":"📙"},{"annotation":"books","group":7,"hexcode":"1F4DA","order":3844,"tags":["book"],"unicode":"📚️"},{"annotation":"notebook","group":7,"hexcode":"1F4D3","order":3845,"tags":["notebook"],"unicode":"📓"},{"annotation":"ledger","group":7,"hexcode":"1F4D2","order":3846,"tags":["notebook"],"unicode":"📒"},{"annotation":"page with curl","group":7,"hexcode":"1F4C3","order":3847,"tags":["curl","document","page"],"unicode":"📃"},{"annotation":"scroll","group":7,"hexcode":"1F4DC","order":3848,"tags":["paper"],"unicode":"📜"},{"annotation":"page facing up","group":7,"hexcode":"1F4C4","order":3849,"tags":["document","page"],"unicode":"📄"},{"annotation":"newspaper","group":7,"hexcode":"1F4F0","order":3850,"tags":["news","paper"],"unicode":"📰"},{"annotation":"rolled-up newspaper","group":7,"hexcode":"1F5DE","order":3852,"tags":["news","newspaper","paper","rolled"],"unicode":"🗞️"},{"annotation":"bookmark tabs","group":7,"hexcode":"1F4D1","order":3853,"tags":["bookmark","mark","marker","tabs"],"unicode":"📑"},{"annotation":"bookmark","group":7,"hexcode":"1F516","order":3854,"tags":["mark"],"unicode":"🔖"},{"annotation":"label","group":7,"hexcode":"1F3F7","order":3856,"tags":["label"],"unicode":"🏷️"},{"annotation":"money bag","group":7,"hexcode":"1F4B0","order":3857,"tags":["bag","dollar","money","moneybag"],"unicode":"💰️"},{"annotation":"coin","group":7,"hexcode":"1FA99","order":3858,"tags":["gold","metal","money","silver","treasure"],"unicode":"🪙"},{"annotation":"yen banknote","group":7,"hexcode":"1F4B4","order":3859,"tags":["banknote","bill","currency","money","note","yen"],"unicode":"💴"},{"annotation":"dollar banknote","group":7,"hexcode":"1F4B5","order":3860,"tags":["banknote","bill","currency","dollar","money","note"],"unicode":"💵"},{"annotation":"euro banknote","group":7,"hexcode":"1F4B6","order":3861,"tags":["banknote","bill","currency","euro","money","note"],"unicode":"💶"},{"annotation":"pound banknote","group":7,"hexcode":"1F4B7","order":3862,"tags":["banknote","bill","currency","money","note","pound"],"unicode":"💷"},{"annotation":"money with wings","group":7,"hexcode":"1F4B8","order":3863,"tags":["banknote","bill","fly","money","wings"],"unicode":"💸"},{"annotation":"credit card","group":7,"hexcode":"1F4B3","order":3864,"tags":["card","credit","money"],"unicode":"💳️"},{"annotation":"receipt","group":7,"hexcode":"1F9FE","order":3865,"tags":["accounting","bookkeeping","evidence","proof"],"unicode":"🧾"},{"annotation":"chart increasing with yen","group":7,"hexcode":"1F4B9","order":3866,"tags":["chart","graph","growth","money","yen"],"unicode":"💹"},{"annotation":"envelope","group":7,"hexcode":"2709","order":3868,"tags":["email","letter"],"unicode":"✉️"},{"annotation":"e-mail","group":7,"hexcode":"1F4E7","order":3869,"tags":["email","letter","mail"],"unicode":"📧"},{"annotation":"incoming envelope","group":7,"hexcode":"1F4E8","order":3870,"tags":["e-mail","email","envelope","incoming","letter","receive"],"unicode":"📨"},{"annotation":"envelope with arrow","group":7,"hexcode":"1F4E9","order":3871,"tags":["arrow","e-mail","email","envelope","outgoing"],"unicode":"📩"},{"annotation":"outbox tray","group":7,"hexcode":"1F4E4","order":3872,"tags":["box","letter","mail","outbox","sent","tray"],"unicode":"📤️"},{"annotation":"inbox tray","group":7,"hexcode":"1F4E5","order":3873,"tags":["box","inbox","letter","mail","receive","tray"],"unicode":"📥️"},{"annotation":"package","group":7,"hexcode":"1F4E6","order":3874,"tags":["box","parcel"],"unicode":"📦️"},{"annotation":"closed mailbox with raised flag","group":7,"hexcode":"1F4EB","order":3875,"tags":["closed","mail","mailbox","postbox"],"unicode":"📫️"},{"annotation":"closed mailbox with lowered flag","group":7,"hexcode":"1F4EA","order":3876,"tags":["closed","lowered","mail","mailbox","postbox"],"unicode":"📪️"},{"annotation":"open mailbox with raised flag","group":7,"hexcode":"1F4EC","order":3877,"tags":["mail","mailbox","open","postbox"],"unicode":"📬️"},{"annotation":"open mailbox with lowered flag","group":7,"hexcode":"1F4ED","order":3878,"tags":["lowered","mail","mailbox","open","postbox"],"unicode":"📭️"},{"annotation":"postbox","group":7,"hexcode":"1F4EE","order":3879,"tags":["mail","mailbox"],"unicode":"📮"},{"annotation":"ballot box with ballot","group":7,"hexcode":"1F5F3","order":3881,"tags":["ballot","box"],"unicode":"🗳️"},{"annotation":"pencil","group":7,"hexcode":"270F","order":3883,"tags":["pencil"],"unicode":"✏️"},{"annotation":"black nib","group":7,"hexcode":"2712","order":3885,"tags":["nib","pen"],"unicode":"✒️"},{"annotation":"fountain pen","group":7,"hexcode":"1F58B","order":3887,"tags":["fountain","pen"],"unicode":"🖋️"},{"annotation":"pen","group":7,"hexcode":"1F58A","order":3889,"tags":["ballpoint"],"unicode":"🖊️"},{"annotation":"paintbrush","group":7,"hexcode":"1F58C","order":3891,"tags":["painting"],"unicode":"🖌️"},{"annotation":"crayon","group":7,"hexcode":"1F58D","order":3893,"tags":["crayon"],"unicode":"🖍️"},{"annotation":"memo","group":7,"hexcode":"1F4DD","order":3894,"tags":["pencil"],"unicode":"📝"},{"annotation":"briefcase","group":7,"hexcode":"1F4BC","order":3895,"tags":["briefcase"],"unicode":"💼"},{"annotation":"file folder","group":7,"hexcode":"1F4C1","order":3896,"tags":["file","folder"],"unicode":"📁"},{"annotation":"open file folder","group":7,"hexcode":"1F4C2","order":3897,"tags":["file","folder","open"],"unicode":"📂"},{"annotation":"card index dividers","group":7,"hexcode":"1F5C2","order":3899,"tags":["card","dividers","index"],"unicode":"🗂️"},{"annotation":"calendar","group":7,"hexcode":"1F4C5","order":3900,"tags":["date"],"unicode":"📅"},{"annotation":"tear-off calendar","group":7,"hexcode":"1F4C6","order":3901,"tags":["calendar"],"unicode":"📆"},{"annotation":"spiral notepad","group":7,"hexcode":"1F5D2","order":3903,"tags":["note","pad","spiral"],"unicode":"🗒️"},{"annotation":"spiral calendar","group":7,"hexcode":"1F5D3","order":3905,"tags":["calendar","pad","spiral"],"unicode":"🗓️"},{"annotation":"card index","group":7,"hexcode":"1F4C7","order":3906,"tags":["card","index","rolodex"],"unicode":"📇"},{"annotation":"chart increasing","group":7,"hexcode":"1F4C8","order":3907,"tags":["chart","graph","growth","trend","upward"],"unicode":"📈"},{"annotation":"chart decreasing","group":7,"hexcode":"1F4C9","order":3908,"tags":["chart","down","graph","trend"],"unicode":"📉"},{"annotation":"bar chart","group":7,"hexcode":"1F4CA","order":3909,"tags":["bar","chart","graph"],"unicode":"📊"},{"annotation":"clipboard","group":7,"hexcode":"1F4CB","order":3910,"tags":["clipboard"],"unicode":"📋️"},{"annotation":"pushpin","group":7,"hexcode":"1F4CC","order":3911,"tags":["pin"],"unicode":"📌"},{"annotation":"round pushpin","group":7,"hexcode":"1F4CD","order":3912,"tags":["pin","pushpin"],"unicode":"📍"},{"annotation":"paperclip","group":7,"hexcode":"1F4CE","order":3913,"tags":["paperclip"],"unicode":"📎"},{"annotation":"linked paperclips","group":7,"hexcode":"1F587","order":3915,"tags":["link","paperclip"],"unicode":"🖇️"},{"annotation":"straight ruler","group":7,"hexcode":"1F4CF","order":3916,"tags":["ruler","straight edge"],"unicode":"📏"},{"annotation":"triangular ruler","group":7,"hexcode":"1F4D0","order":3917,"tags":["ruler","set","triangle"],"unicode":"📐"},{"annotation":"scissors","group":7,"hexcode":"2702","order":3919,"tags":["cutting","tool"],"unicode":"✂️"},{"annotation":"card file box","group":7,"hexcode":"1F5C3","order":3921,"tags":["box","card","file"],"unicode":"🗃️"},{"annotation":"file cabinet","group":7,"hexcode":"1F5C4","order":3923,"tags":["cabinet","file","filing"],"unicode":"🗄️"},{"annotation":"wastebasket","group":7,"hexcode":"1F5D1","order":3925,"tags":["wastebasket"],"unicode":"🗑️"},{"annotation":"locked","group":7,"hexcode":"1F512","order":3926,"tags":["closed"],"unicode":"🔒️"},{"annotation":"unlocked","group":7,"hexcode":"1F513","order":3927,"tags":["lock","open","unlock"],"unicode":"🔓️"},{"annotation":"locked with pen","group":7,"hexcode":"1F50F","order":3928,"tags":["ink","lock","nib","pen","privacy"],"unicode":"🔏"},{"annotation":"locked with key","group":7,"hexcode":"1F510","order":3929,"tags":["closed","key","lock","secure"],"unicode":"🔐"},{"annotation":"key","group":7,"hexcode":"1F511","order":3930,"tags":["lock","password"],"unicode":"🔑"},{"annotation":"old key","group":7,"hexcode":"1F5DD","order":3932,"tags":["clue","key","lock","old"],"unicode":"🗝️"},{"annotation":"hammer","group":7,"hexcode":"1F528","order":3933,"tags":["tool"],"unicode":"🔨"},{"annotation":"axe","group":7,"hexcode":"1FA93","order":3934,"tags":["chop","hatchet","split","wood"],"unicode":"🪓"},{"annotation":"pick","group":7,"hexcode":"26CF","order":3936,"tags":["mining","tool"],"unicode":"⛏️"},{"annotation":"hammer and pick","group":7,"hexcode":"2692","order":3938,"tags":["hammer","pick","tool"],"unicode":"⚒️"},{"annotation":"hammer and wrench","group":7,"hexcode":"1F6E0","order":3940,"tags":["hammer","spanner","tool","wrench"],"unicode":"🛠️"},{"annotation":"dagger","group":7,"hexcode":"1F5E1","order":3942,"tags":["knife","weapon"],"unicode":"🗡️"},{"annotation":"crossed swords","group":7,"hexcode":"2694","order":3944,"tags":["crossed","swords","weapon"],"unicode":"⚔️"},{"annotation":"water pistol","group":7,"hexcode":"1F52B","order":3945,"tags":["gun","handgun","pistol","revolver","tool","water","weapon"],"unicode":"🔫"},{"annotation":"boomerang","group":7,"hexcode":"1FA83","order":3946,"tags":["australia","rebound","repercussion"],"unicode":"🪃"},{"annotation":"bow and arrow","group":7,"hexcode":"1F3F9","order":3947,"tags":["archer","arrow","bow","sagittarius","zodiac"],"unicode":"🏹"},{"annotation":"shield","group":7,"hexcode":"1F6E1","order":3949,"tags":["weapon"],"unicode":"🛡️"},{"annotation":"carpentry saw","group":7,"hexcode":"1FA9A","order":3950,"tags":["carpenter","lumber","saw","tool"],"unicode":"🪚"},{"annotation":"wrench","group":7,"hexcode":"1F527","order":3951,"tags":["spanner","tool"],"unicode":"🔧"},{"annotation":"screwdriver","group":7,"hexcode":"1FA9B","order":3952,"tags":["screw","tool"],"unicode":"🪛"},{"annotation":"nut and bolt","group":7,"hexcode":"1F529","order":3953,"tags":["bolt","nut","tool"],"unicode":"🔩"},{"annotation":"gear","group":7,"hexcode":"2699","order":3955,"tags":["cog","cogwheel","tool"],"unicode":"⚙️"},{"annotation":"clamp","group":7,"hexcode":"1F5DC","order":3957,"tags":["compress","tool","vice"],"unicode":"🗜️"},{"annotation":"balance scale","group":7,"hexcode":"2696","order":3959,"tags":["balance","justice","libra","scale","zodiac"],"unicode":"⚖️"},{"annotation":"white cane","group":7,"hexcode":"1F9AF","order":3960,"tags":["accessibility","blind"],"unicode":"🦯"},{"annotation":"link","group":7,"hexcode":"1F517","order":3961,"tags":["link"],"unicode":"🔗"},{"annotation":"chains","group":7,"hexcode":"26D3","order":3963,"tags":["chain"],"unicode":"⛓️"},{"annotation":"hook","group":7,"hexcode":"1FA9D","order":3964,"tags":["catch","crook","curve","ensnare","selling point"],"unicode":"🪝"},{"annotation":"toolbox","group":7,"hexcode":"1F9F0","order":3965,"tags":["chest","mechanic","tool"],"unicode":"🧰"},{"annotation":"magnet","group":7,"hexcode":"1F9F2","order":3966,"tags":["attraction","horseshoe","magnetic"],"unicode":"🧲"},{"annotation":"ladder","group":7,"hexcode":"1FA9C","order":3967,"tags":["climb","rung","step"],"unicode":"🪜"},{"annotation":"alembic","group":7,"hexcode":"2697","order":3969,"tags":["chemistry","tool"],"unicode":"⚗️"},{"annotation":"test tube","group":7,"hexcode":"1F9EA","order":3970,"tags":["chemist","chemistry","experiment","lab","science"],"unicode":"🧪"},{"annotation":"petri dish","group":7,"hexcode":"1F9EB","order":3971,"tags":["bacteria","biologist","biology","culture","lab"],"unicode":"🧫"},{"annotation":"dna","group":7,"hexcode":"1F9EC","order":3972,"tags":["biologist","evolution","gene","genetics","life"],"unicode":"🧬"},{"annotation":"microscope","group":7,"hexcode":"1F52C","order":3973,"tags":["science","tool"],"unicode":"🔬"},{"annotation":"telescope","group":7,"hexcode":"1F52D","order":3974,"tags":["science","tool"],"unicode":"🔭"},{"annotation":"satellite antenna","group":7,"hexcode":"1F4E1","order":3975,"tags":["antenna","dish","satellite"],"unicode":"📡"},{"annotation":"syringe","group":7,"hexcode":"1F489","order":3976,"tags":["medicine","needle","shot","sick"],"unicode":"💉"},{"annotation":"drop of blood","group":7,"hexcode":"1FA78","order":3977,"tags":["bleed","blood donation","injury","medicine","menstruation"],"unicode":"🩸"},{"annotation":"pill","group":7,"hexcode":"1F48A","order":3978,"tags":["doctor","medicine","sick"],"unicode":"💊"},{"annotation":"adhesive bandage","group":7,"hexcode":"1FA79","order":3979,"tags":["bandage"],"unicode":"🩹"},{"annotation":"stethoscope","group":7,"hexcode":"1FA7A","order":3980,"tags":["doctor","heart","medicine"],"unicode":"🩺"},{"annotation":"door","group":7,"hexcode":"1F6AA","order":3981,"tags":["door"],"unicode":"🚪"},{"annotation":"elevator","group":7,"hexcode":"1F6D7","order":3982,"tags":["accessibility","hoist","lift"],"unicode":"🛗"},{"annotation":"mirror","group":7,"hexcode":"1FA9E","order":3983,"tags":["reflection","reflector","speculum"],"unicode":"🪞"},{"annotation":"window","group":7,"hexcode":"1FA9F","order":3984,"tags":["frame","fresh air","opening","transparent","view"],"unicode":"🪟"},{"annotation":"bed","group":7,"hexcode":"1F6CF","order":3986,"tags":["hotel","sleep"],"unicode":"🛏️"},{"annotation":"couch and lamp","group":7,"hexcode":"1F6CB","order":3988,"tags":["couch","hotel","lamp"],"unicode":"🛋️"},{"annotation":"chair","group":7,"hexcode":"1FA91","order":3989,"tags":["seat","sit"],"unicode":"🪑"},{"annotation":"toilet","group":7,"hexcode":"1F6BD","order":3990,"tags":["toilet"],"unicode":"🚽"},{"annotation":"plunger","group":7,"hexcode":"1FAA0","order":3991,"tags":["force cup","plumber","suction","toilet"],"unicode":"🪠"},{"annotation":"shower","group":7,"hexcode":"1F6BF","order":3992,"tags":["water"],"unicode":"🚿"},{"annotation":"bathtub","group":7,"hexcode":"1F6C1","order":3993,"tags":["bath"],"unicode":"🛁"},{"annotation":"mouse trap","group":7,"hexcode":"1FAA4","order":3994,"tags":["bait","mousetrap","snare","trap"],"unicode":"🪤"},{"annotation":"razor","group":7,"hexcode":"1FA92","order":3995,"tags":["sharp","shave"],"unicode":"🪒"},{"annotation":"lotion bottle","group":7,"hexcode":"1F9F4","order":3996,"tags":["lotion","moisturizer","shampoo","sunscreen"],"unicode":"🧴"},{"annotation":"safety pin","group":7,"hexcode":"1F9F7","order":3997,"tags":["diaper","punk rock"],"unicode":"🧷"},{"annotation":"broom","group":7,"hexcode":"1F9F9","order":3998,"tags":["cleaning","sweeping","witch"],"unicode":"🧹"},{"annotation":"basket","group":7,"hexcode":"1F9FA","order":3999,"tags":["farming","laundry","picnic"],"unicode":"🧺"},{"annotation":"roll of paper","group":7,"hexcode":"1F9FB","order":4000,"tags":["paper towels","toilet paper"],"unicode":"🧻"},{"annotation":"bucket","group":7,"hexcode":"1FAA3","order":4001,"tags":["cask","pail","vat"],"unicode":"🪣"},{"annotation":"soap","group":7,"hexcode":"1F9FC","order":4002,"tags":["bar","bathing","cleaning","lather","soapdish"],"unicode":"🧼"},{"annotation":"toothbrush","group":7,"hexcode":"1FAA5","order":4003,"tags":["bathroom","brush","clean","dental","hygiene","teeth"],"unicode":"🪥"},{"annotation":"sponge","group":7,"hexcode":"1F9FD","order":4004,"tags":["absorbing","cleaning","porous"],"unicode":"🧽"},{"annotation":"fire extinguisher","group":7,"hexcode":"1F9EF","order":4005,"tags":["extinguish","fire","quench"],"unicode":"🧯"},{"annotation":"shopping cart","group":7,"hexcode":"1F6D2","order":4006,"tags":["cart","shopping","trolley"],"unicode":"🛒"},{"annotation":"cigarette","group":7,"hexcode":"1F6AC","order":4007,"tags":["smoking"],"unicode":"🚬"},{"annotation":"coffin","group":7,"hexcode":"26B0","order":4009,"tags":["death"],"unicode":"⚰️"},{"annotation":"headstone","group":7,"hexcode":"1FAA6","order":4010,"tags":["cemetery","grave","graveyard","tombstone"],"unicode":"🪦"},{"annotation":"funeral urn","group":7,"hexcode":"26B1","order":4012,"tags":["ashes","death","funeral","urn"],"unicode":"⚱️"},{"annotation":"moai","group":7,"hexcode":"1F5FF","order":4013,"tags":["face","moyai","statue"],"unicode":"🗿"},{"annotation":"placard","group":7,"hexcode":"1FAA7","order":4014,"tags":["demonstration","picket","protest","sign"],"unicode":"🪧"},{"annotation":"ATM sign","group":8,"hexcode":"1F3E7","order":4015,"tags":["atm","atm sign","automated","bank","teller"],"unicode":"🏧"},{"annotation":"litter in bin sign","group":8,"hexcode":"1F6AE","order":4016,"tags":["litter","litter bin"],"unicode":"🚮"},{"annotation":"potable water","group":8,"hexcode":"1F6B0","order":4017,"tags":["drinking","potable","water"],"unicode":"🚰"},{"annotation":"wheelchair symbol","group":8,"hexcode":"267F","order":4018,"tags":["access"],"unicode":"♿️"},{"annotation":"men’s room","group":8,"hexcode":"1F6B9","order":4019,"tags":["lavatory","man","restroom","wc"],"unicode":"🚹️"},{"annotation":"women’s room","group":8,"hexcode":"1F6BA","order":4020,"tags":["lavatory","restroom","wc","woman"],"unicode":"🚺️"},{"annotation":"restroom","group":8,"hexcode":"1F6BB","order":4021,"tags":["lavatory","wc"],"unicode":"🚻"},{"annotation":"baby symbol","group":8,"hexcode":"1F6BC","order":4022,"tags":["baby","changing"],"unicode":"🚼️"},{"annotation":"water closet","group":8,"hexcode":"1F6BE","order":4023,"tags":["closet","lavatory","restroom","water","wc"],"unicode":"🚾"},{"annotation":"passport control","group":8,"hexcode":"1F6C2","order":4024,"tags":["control","passport"],"unicode":"🛂"},{"annotation":"customs","group":8,"hexcode":"1F6C3","order":4025,"tags":["customs"],"unicode":"🛃"},{"annotation":"baggage claim","group":8,"hexcode":"1F6C4","order":4026,"tags":["baggage","claim"],"unicode":"🛄"},{"annotation":"left luggage","group":8,"hexcode":"1F6C5","order":4027,"tags":["baggage","locker","luggage"],"unicode":"🛅"},{"annotation":"warning","group":8,"hexcode":"26A0","order":4029,"tags":["warning"],"unicode":"⚠️"},{"annotation":"children crossing","group":8,"hexcode":"1F6B8","order":4030,"tags":["child","crossing","pedestrian","traffic"],"unicode":"🚸"},{"annotation":"no entry","group":8,"hexcode":"26D4","order":4031,"tags":["entry","forbidden","no","not","prohibited","traffic"],"unicode":"⛔️"},{"annotation":"prohibited","group":8,"hexcode":"1F6AB","order":4032,"tags":["entry","forbidden","no","not"],"unicode":"🚫"},{"annotation":"no bicycles","group":8,"hexcode":"1F6B3","order":4033,"tags":["bicycle","bike","forbidden","no","prohibited"],"unicode":"🚳"},{"annotation":"no smoking","group":8,"hexcode":"1F6AD","order":4034,"tags":["forbidden","no","not","prohibited","smoking"],"unicode":"🚭️"},{"annotation":"no littering","group":8,"hexcode":"1F6AF","order":4035,"tags":["forbidden","litter","no","not","prohibited"],"unicode":"🚯"},{"annotation":"non-potable water","group":8,"hexcode":"1F6B1","order":4036,"tags":["non-drinking","non-potable","water"],"unicode":"🚱"},{"annotation":"no pedestrians","group":8,"hexcode":"1F6B7","order":4037,"tags":["forbidden","no","not","pedestrian","prohibited"],"unicode":"🚷"},{"annotation":"no mobile phones","group":8,"hexcode":"1F4F5","order":4038,"tags":["cell","forbidden","mobile","no","phone"],"unicode":"📵"},{"annotation":"no one under eighteen","group":8,"hexcode":"1F51E","order":4039,"tags":["18","age restriction","eighteen","prohibited","underage"],"unicode":"🔞"},{"annotation":"radioactive","group":8,"hexcode":"2622","order":4041,"tags":["sign"],"unicode":"☢️"},{"annotation":"biohazard","group":8,"hexcode":"2623","order":4043,"tags":["sign"],"unicode":"☣️"},{"annotation":"up arrow","group":8,"hexcode":"2B06","order":4045,"tags":["arrow","cardinal","direction","north"],"unicode":"⬆️"},{"annotation":"up-right arrow","group":8,"hexcode":"2197","order":4047,"tags":["arrow","direction","intercardinal","northeast"],"unicode":"↗️"},{"annotation":"right arrow","group":8,"hexcode":"27A1","order":4049,"tags":["arrow","cardinal","direction","east"],"unicode":"➡️"},{"annotation":"down-right arrow","group":8,"hexcode":"2198","order":4051,"tags":["arrow","direction","intercardinal","southeast"],"unicode":"↘️"},{"annotation":"down arrow","group":8,"hexcode":"2B07","order":4053,"tags":["arrow","cardinal","direction","down","south"],"unicode":"⬇️"},{"annotation":"down-left arrow","group":8,"hexcode":"2199","order":4055,"tags":["arrow","direction","intercardinal","southwest"],"unicode":"↙️"},{"annotation":"left arrow","group":8,"hexcode":"2B05","order":4057,"tags":["arrow","cardinal","direction","west"],"unicode":"⬅️"},{"annotation":"up-left arrow","group":8,"hexcode":"2196","order":4059,"tags":["arrow","direction","intercardinal","northwest"],"unicode":"↖️"},{"annotation":"up-down arrow","group":8,"hexcode":"2195","order":4061,"tags":["arrow"],"unicode":"↕️"},{"annotation":"left-right arrow","group":8,"hexcode":"2194","order":4063,"tags":["arrow"],"unicode":"↔️"},{"annotation":"right arrow curving left","group":8,"hexcode":"21A9","order":4065,"tags":["arrow"],"unicode":"↩️"},{"annotation":"left arrow curving right","group":8,"hexcode":"21AA","order":4067,"tags":["arrow"],"unicode":"↪️"},{"annotation":"right arrow curving up","group":8,"hexcode":"2934","order":4069,"tags":["arrow"],"unicode":"⤴️"},{"annotation":"right arrow curving down","group":8,"hexcode":"2935","order":4071,"tags":["arrow","down"],"unicode":"⤵️"},{"annotation":"clockwise vertical arrows","group":8,"hexcode":"1F503","order":4072,"tags":["arrow","clockwise","reload"],"unicode":"🔃"},{"annotation":"counterclockwise arrows button","group":8,"hexcode":"1F504","order":4073,"tags":["anticlockwise","arrow","counterclockwise","withershins"],"unicode":"🔄"},{"annotation":"BACK arrow","group":8,"hexcode":"1F519","order":4074,"tags":["arrow","back","back arrow"],"unicode":"🔙"},{"annotation":"END arrow","group":8,"hexcode":"1F51A","order":4075,"tags":["arrow","end","end arrow"],"unicode":"🔚"},{"annotation":"ON! arrow","group":8,"hexcode":"1F51B","order":4076,"tags":["arrow","mark","on","on! arrow"],"unicode":"🔛"},{"annotation":"SOON arrow","group":8,"hexcode":"1F51C","order":4077,"tags":["arrow","soon","soon arrow"],"unicode":"🔜"},{"annotation":"TOP arrow","group":8,"hexcode":"1F51D","order":4078,"tags":["arrow","top","top arrow","up"],"unicode":"🔝"},{"annotation":"place of worship","group":8,"hexcode":"1F6D0","order":4079,"tags":["religion","worship"],"unicode":"🛐"},{"annotation":"atom symbol","group":8,"hexcode":"269B","order":4081,"tags":["atheist","atom"],"unicode":"⚛️"},{"annotation":"om","group":8,"hexcode":"1F549","order":4083,"tags":["hindu","religion"],"unicode":"🕉️"},{"annotation":"star of David","group":8,"hexcode":"2721","order":4085,"tags":["david","jew","jewish","religion","star","star of david"],"unicode":"✡️"},{"annotation":"wheel of dharma","group":8,"hexcode":"2638","order":4087,"tags":["buddhist","dharma","religion","wheel"],"unicode":"☸️"},{"annotation":"yin yang","group":8,"hexcode":"262F","order":4089,"tags":["religion","tao","taoist","yang","yin"],"unicode":"☯️"},{"annotation":"latin cross","group":8,"hexcode":"271D","order":4091,"tags":["christian","cross","religion"],"unicode":"✝️"},{"annotation":"orthodox cross","group":8,"hexcode":"2626","order":4093,"tags":["christian","cross","religion"],"unicode":"☦️"},{"annotation":"star and crescent","group":8,"hexcode":"262A","order":4095,"tags":["islam","muslim","religion"],"unicode":"☪️"},{"annotation":"peace symbol","group":8,"hexcode":"262E","order":4097,"tags":["peace"],"unicode":"☮️"},{"annotation":"menorah","group":8,"hexcode":"1F54E","order":4098,"tags":["candelabrum","candlestick","religion"],"unicode":"🕎"},{"annotation":"dotted six-pointed star","group":8,"hexcode":"1F52F","order":4099,"tags":["fortune","star"],"unicode":"🔯"},{"annotation":"Aries","group":8,"hexcode":"2648","order":4100,"tags":["aries","ram","zodiac"],"unicode":"♈️"},{"annotation":"Taurus","group":8,"hexcode":"2649","order":4101,"tags":["bull","ox","taurus","zodiac"],"unicode":"♉️"},{"annotation":"Gemini","group":8,"hexcode":"264A","order":4102,"tags":["gemini","twins","zodiac"],"unicode":"♊️"},{"annotation":"Cancer","group":8,"hexcode":"264B","order":4103,"tags":["cancer","crab","zodiac"],"unicode":"♋️"},{"annotation":"Leo","group":8,"hexcode":"264C","order":4104,"tags":["leo","lion","zodiac"],"unicode":"♌️"},{"annotation":"Virgo","group":8,"hexcode":"264D","order":4105,"tags":["virgo","zodiac"],"unicode":"♍️"},{"annotation":"Libra","group":8,"hexcode":"264E","order":4106,"tags":["balance","justice","libra","scales","zodiac"],"unicode":"♎️"},{"annotation":"Scorpio","group":8,"hexcode":"264F","order":4107,"tags":["scorpio","scorpion","scorpius","zodiac"],"unicode":"♏️"},{"annotation":"Sagittarius","group":8,"hexcode":"2650","order":4108,"tags":["archer","sagittarius","zodiac"],"unicode":"♐️"},{"annotation":"Capricorn","group":8,"hexcode":"2651","order":4109,"tags":["capricorn","goat","zodiac"],"unicode":"♑️"},{"annotation":"Aquarius","group":8,"hexcode":"2652","order":4110,"tags":["aquarius","bearer","water","zodiac"],"unicode":"♒️"},{"annotation":"Pisces","group":8,"hexcode":"2653","order":4111,"tags":["fish","pisces","zodiac"],"unicode":"♓️"},{"annotation":"Ophiuchus","group":8,"hexcode":"26CE","order":4112,"tags":["bearer","ophiuchus","serpent","snake","zodiac"],"unicode":"⛎"},{"annotation":"shuffle tracks button","group":8,"hexcode":"1F500","order":4113,"tags":["arrow","crossed"],"unicode":"🔀"},{"annotation":"repeat button","group":8,"hexcode":"1F501","order":4114,"tags":["arrow","clockwise","repeat"],"unicode":"🔁"},{"annotation":"repeat single button","group":8,"hexcode":"1F502","order":4115,"tags":["arrow","clockwise","once"],"unicode":"🔂"},{"annotation":"play button","group":8,"hexcode":"25B6","order":4117,"tags":["arrow","play","right","triangle"],"unicode":"▶️"},{"annotation":"fast-forward button","group":8,"hexcode":"23E9","order":4118,"tags":["arrow","double","fast","forward"],"unicode":"⏩️"},{"annotation":"next track button","group":8,"hexcode":"23ED","order":4120,"tags":["arrow","next scene","next track","triangle"],"unicode":"⏭️"},{"annotation":"play or pause button","group":8,"hexcode":"23EF","order":4122,"tags":["arrow","pause","play","right","triangle"],"unicode":"⏯️"},{"annotation":"reverse button","group":8,"hexcode":"25C0","order":4124,"tags":["arrow","left","reverse","triangle"],"unicode":"◀️"},{"annotation":"fast reverse button","group":8,"hexcode":"23EA","order":4125,"tags":["arrow","double","rewind"],"unicode":"⏪️"},{"annotation":"last track button","group":8,"hexcode":"23EE","order":4127,"tags":["arrow","previous scene","previous track","triangle"],"unicode":"⏮️"},{"annotation":"upwards button","group":8,"hexcode":"1F53C","order":4128,"tags":["arrow","button","red"],"unicode":"🔼"},{"annotation":"fast up button","group":8,"hexcode":"23EB","order":4129,"tags":["arrow","double"],"unicode":"⏫"},{"annotation":"downwards button","group":8,"hexcode":"1F53D","order":4130,"tags":["arrow","button","down","red"],"unicode":"🔽"},{"annotation":"fast down button","group":8,"hexcode":"23EC","order":4131,"tags":["arrow","double","down"],"unicode":"⏬"},{"annotation":"pause button","group":8,"hexcode":"23F8","order":4133,"tags":["bar","double","pause","vertical"],"unicode":"⏸️"},{"annotation":"stop button","group":8,"hexcode":"23F9","order":4135,"tags":["square","stop"],"unicode":"⏹️"},{"annotation":"record button","group":8,"hexcode":"23FA","order":4137,"tags":["circle","record"],"unicode":"⏺️"},{"annotation":"eject button","group":8,"hexcode":"23CF","order":4139,"tags":["eject"],"unicode":"⏏️"},{"annotation":"cinema","group":8,"hexcode":"1F3A6","order":4140,"tags":["camera","film","movie"],"unicode":"🎦"},{"annotation":"dim button","group":8,"hexcode":"1F505","order":4141,"tags":["brightness","dim","low"],"unicode":"🔅"},{"annotation":"bright button","group":8,"hexcode":"1F506","order":4142,"tags":["bright","brightness"],"unicode":"🔆"},{"annotation":"antenna bars","group":8,"hexcode":"1F4F6","order":4143,"tags":["antenna","bar","cell","mobile","phone"],"unicode":"📶"},{"annotation":"vibration mode","group":8,"hexcode":"1F4F3","order":4144,"tags":["cell","mobile","mode","phone","telephone","vibration"],"unicode":"📳"},{"annotation":"mobile phone off","group":8,"hexcode":"1F4F4","order":4145,"tags":["cell","mobile","off","phone","telephone"],"unicode":"📴"},{"annotation":"female sign","group":8,"hexcode":"2640","order":4147,"tags":["woman"],"unicode":"♀️"},{"annotation":"male sign","group":8,"hexcode":"2642","order":4149,"tags":["man"],"unicode":"♂️"},{"annotation":"transgender symbol","group":8,"hexcode":"26A7","order":4151,"tags":["transgender"],"unicode":"⚧️"},{"annotation":"multiply","group":8,"hexcode":"2716","order":4153,"tags":["cancel","multiplication","sign","x","×"],"unicode":"✖️"},{"annotation":"plus","group":8,"hexcode":"2795","order":4154,"tags":["+","math","sign"],"unicode":"➕"},{"annotation":"minus","group":8,"hexcode":"2796","order":4155,"tags":["-","math","sign","−"],"unicode":"➖"},{"annotation":"divide","group":8,"hexcode":"2797","order":4156,"tags":["division","math","sign","÷"],"unicode":"➗"},{"annotation":"infinity","group":8,"hexcode":"267E","order":4158,"tags":["forever","unbounded","universal"],"unicode":"♾️"},{"annotation":"double exclamation mark","group":8,"hexcode":"203C","order":4160,"tags":["!","!!","bangbang","exclamation","mark"],"unicode":"‼️"},{"annotation":"exclamation question mark","group":8,"hexcode":"2049","order":4162,"tags":["!","!?","?","exclamation","interrobang","mark","punctuation","question"],"unicode":"⁉️"},{"annotation":"red question mark","group":8,"hexcode":"2753","order":4163,"tags":["?","mark","punctuation","question"],"unicode":"❓️"},{"annotation":"white question mark","group":8,"hexcode":"2754","order":4164,"tags":["?","mark","outlined","punctuation","question"],"unicode":"❔"},{"annotation":"white exclamation mark","group":8,"hexcode":"2755","order":4165,"tags":["!","exclamation","mark","outlined","punctuation"],"unicode":"❕"},{"annotation":"red exclamation mark","group":8,"hexcode":"2757","order":4166,"tags":["!","exclamation","mark","punctuation"],"unicode":"❗️"},{"annotation":"wavy dash","group":8,"hexcode":"3030","order":4168,"tags":["dash","punctuation","wavy"],"unicode":"〰️"},{"annotation":"currency exchange","group":8,"hexcode":"1F4B1","order":4169,"tags":["bank","currency","exchange","money"],"unicode":"💱"},{"annotation":"heavy dollar sign","group":8,"hexcode":"1F4B2","order":4170,"tags":["currency","dollar","money"],"unicode":"💲"},{"annotation":"medical symbol","group":8,"hexcode":"2695","order":4172,"tags":["aesculapius","medicine","staff"],"unicode":"⚕️"},{"annotation":"recycling symbol","group":8,"hexcode":"267B","order":4174,"tags":["recycle"],"unicode":"♻️"},{"annotation":"fleur-de-lis","group":8,"hexcode":"269C","order":4176,"tags":["fleur-de-lis"],"unicode":"⚜️"},{"annotation":"trident emblem","group":8,"hexcode":"1F531","order":4177,"tags":["anchor","emblem","ship","tool","trident"],"unicode":"🔱"},{"annotation":"name badge","group":8,"hexcode":"1F4DB","order":4178,"tags":["badge","name"],"unicode":"📛"},{"annotation":"Japanese symbol for beginner","group":8,"hexcode":"1F530","order":4179,"tags":["beginner","chevron","japanese","japanese symbol for beginner","leaf"],"unicode":"🔰"},{"annotation":"hollow red circle","group":8,"hexcode":"2B55","order":4180,"tags":["circle","large","o","red"],"unicode":"⭕️"},{"annotation":"check mark button","group":8,"hexcode":"2705","order":4181,"tags":["button","check","mark","✓"],"unicode":"✅"},{"annotation":"check box with check","group":8,"hexcode":"2611","order":4183,"tags":["box","check","✓"],"unicode":"☑️"},{"annotation":"check mark","group":8,"hexcode":"2714","order":4185,"tags":["check","mark","✓"],"unicode":"✔️"},{"annotation":"cross mark","group":8,"hexcode":"274C","order":4186,"tags":["cancel","cross","mark","multiplication","multiply","x","×"],"unicode":"❌"},{"annotation":"cross mark button","group":8,"hexcode":"274E","order":4187,"tags":["mark","square","x","×"],"unicode":"❎"},{"annotation":"curly loop","group":8,"hexcode":"27B0","order":4188,"tags":["curl","loop"],"unicode":"➰"},{"annotation":"double curly loop","group":8,"hexcode":"27BF","order":4189,"tags":["curl","double","loop"],"unicode":"➿"},{"annotation":"part alternation mark","group":8,"hexcode":"303D","order":4191,"tags":["mark","part"],"unicode":"〽️"},{"annotation":"eight-spoked asterisk","group":8,"hexcode":"2733","order":4193,"tags":["*","asterisk"],"unicode":"✳️"},{"annotation":"eight-pointed star","group":8,"hexcode":"2734","order":4195,"tags":["*","star"],"unicode":"✴️"},{"annotation":"sparkle","group":8,"hexcode":"2747","order":4197,"tags":["*"],"unicode":"❇️"},{"annotation":"copyright","group":8,"hexcode":"00A9","order":4199,"tags":["c"],"unicode":"©️"},{"annotation":"registered","group":8,"hexcode":"00AE","order":4201,"tags":["r"],"unicode":"®️"},{"annotation":"trade mark","group":8,"hexcode":"2122","order":4203,"tags":["mark","tm","trademark"],"unicode":"™️"},{"annotation":"keycap: #","group":8,"hexcode":"0023-FE0F-20E3","order":4204,"tags":["keycap"],"unicode":"#️⃣"},{"annotation":"keycap: *","group":8,"hexcode":"002A-FE0F-20E3","order":4206,"tags":["keycap"],"unicode":"*️⃣"},{"annotation":"keycap: 0","group":8,"hexcode":"0030-FE0F-20E3","order":4208,"tags":["keycap"],"unicode":"0️⃣"},{"annotation":"keycap: 1","group":8,"hexcode":"0031-FE0F-20E3","order":4210,"tags":["keycap"],"unicode":"1️⃣"},{"annotation":"keycap: 2","group":8,"hexcode":"0032-FE0F-20E3","order":4212,"tags":["keycap"],"unicode":"2️⃣"},{"annotation":"keycap: 3","group":8,"hexcode":"0033-FE0F-20E3","order":4214,"tags":["keycap"],"unicode":"3️⃣"},{"annotation":"keycap: 4","group":8,"hexcode":"0034-FE0F-20E3","order":4216,"tags":["keycap"],"unicode":"4️⃣"},{"annotation":"keycap: 5","group":8,"hexcode":"0035-FE0F-20E3","order":4218,"tags":["keycap"],"unicode":"5️⃣"},{"annotation":"keycap: 6","group":8,"hexcode":"0036-FE0F-20E3","order":4220,"tags":["keycap"],"unicode":"6️⃣"},{"annotation":"keycap: 7","group":8,"hexcode":"0037-FE0F-20E3","order":4222,"tags":["keycap"],"unicode":"7️⃣"},{"annotation":"keycap: 8","group":8,"hexcode":"0038-FE0F-20E3","order":4224,"tags":["keycap"],"unicode":"8️⃣"},{"annotation":"keycap: 9","group":8,"hexcode":"0039-FE0F-20E3","order":4226,"tags":["keycap"],"unicode":"9️⃣"},{"annotation":"keycap: 10","group":8,"hexcode":"1F51F","order":4228,"tags":["keycap"],"unicode":"🔟"},{"annotation":"input latin uppercase","group":8,"hexcode":"1F520","order":4229,"tags":["abcd","input","latin","letters","uppercase"],"unicode":"🔠"},{"annotation":"input latin lowercase","group":8,"hexcode":"1F521","order":4230,"tags":["abcd","input","latin","letters","lowercase"],"unicode":"🔡"},{"annotation":"input numbers","group":8,"hexcode":"1F522","order":4231,"tags":["1234","input","numbers"],"unicode":"🔢"},{"annotation":"input symbols","group":8,"hexcode":"1F523","order":4232,"tags":["input","〒♪&%"],"unicode":"🔣"},{"annotation":"input latin letters","group":8,"hexcode":"1F524","order":4233,"tags":["abc","alphabet","input","latin","letters"],"unicode":"🔤"},{"annotation":"A button (blood type)","group":8,"hexcode":"1F170","order":4235,"tags":["a","a button (blood type)","blood type"],"unicode":"🅰️"},{"annotation":"AB button (blood type)","group":8,"hexcode":"1F18E","order":4236,"tags":["ab","ab button (blood type)","blood type"],"unicode":"🆎"},{"annotation":"B button (blood type)","group":8,"hexcode":"1F171","order":4238,"tags":["b","b button (blood type)","blood type"],"unicode":"🅱️"},{"annotation":"CL button","group":8,"hexcode":"1F191","order":4239,"tags":["cl","cl button"],"unicode":"🆑"},{"annotation":"COOL button","group":8,"hexcode":"1F192","order":4240,"tags":["cool","cool button"],"unicode":"🆒"},{"annotation":"FREE button","group":8,"hexcode":"1F193","order":4241,"tags":["free","free button"],"unicode":"🆓"},{"annotation":"information","group":8,"hexcode":"2139","order":4243,"tags":["i"],"unicode":"ℹ️"},{"annotation":"ID button","group":8,"hexcode":"1F194","order":4244,"tags":["id","id button","identity"],"unicode":"🆔"},{"annotation":"circled M","group":8,"hexcode":"24C2","order":4246,"tags":["circle","circled m","m"],"unicode":"Ⓜ️"},{"annotation":"NEW button","group":8,"hexcode":"1F195","order":4247,"tags":["new","new button"],"unicode":"🆕"},{"annotation":"NG button","group":8,"hexcode":"1F196","order":4248,"tags":["ng","ng button"],"unicode":"🆖"},{"annotation":"O button (blood type)","group":8,"hexcode":"1F17E","order":4250,"tags":["blood type","o","o button (blood type)"],"unicode":"🅾️"},{"annotation":"OK button","group":8,"hexcode":"1F197","order":4251,"tags":["ok","ok button"],"unicode":"🆗"},{"annotation":"P button","group":8,"hexcode":"1F17F","order":4253,"tags":["p button","parking"],"unicode":"🅿️"},{"annotation":"SOS button","group":8,"hexcode":"1F198","order":4254,"tags":["help","sos","sos button"],"unicode":"🆘"},{"annotation":"UP! button","group":8,"hexcode":"1F199","order":4255,"tags":["mark","up","up! button"],"unicode":"🆙"},{"annotation":"VS button","group":8,"hexcode":"1F19A","order":4256,"tags":["versus","vs","vs button"],"unicode":"🆚"},{"annotation":"Japanese “here” button","group":8,"hexcode":"1F201","order":4257,"tags":["japanese","japanese “here” button","katakana","“here”","ココ"],"unicode":"🈁"},{"annotation":"Japanese “service charge” button","group":8,"hexcode":"1F202","order":4259,"tags":["japanese","japanese “service charge” button","katakana","“service charge”","サ"],"unicode":"🈂️"},{"annotation":"Japanese “monthly amount” button","group":8,"hexcode":"1F237","order":4261,"tags":["ideograph","japanese","japanese “monthly amount” button","“monthly amount”","月"],"unicode":"🈷️"},{"annotation":"Japanese “not free of charge” button","group":8,"hexcode":"1F236","order":4262,"tags":["ideograph","japanese","japanese “not free of charge” button","“not free of charge”","有"],"unicode":"🈶"},{"annotation":"Japanese “reserved” button","group":8,"hexcode":"1F22F","order":4263,"tags":["ideograph","japanese","japanese “reserved” button","“reserved”","指"],"unicode":"🈯️"},{"annotation":"Japanese “bargain” button","group":8,"hexcode":"1F250","order":4264,"tags":["ideograph","japanese","japanese “bargain” button","“bargain”","得"],"unicode":"🉐"},{"annotation":"Japanese “discount” button","group":8,"hexcode":"1F239","order":4265,"tags":["ideograph","japanese","japanese “discount” button","“discount”","割"],"unicode":"🈹"},{"annotation":"Japanese “free of charge” button","group":8,"hexcode":"1F21A","order":4266,"tags":["ideograph","japanese","japanese “free of charge” button","“free of charge”","無"],"unicode":"🈚️"},{"annotation":"Japanese “prohibited” button","group":8,"hexcode":"1F232","order":4267,"tags":["ideograph","japanese","japanese “prohibited” button","“prohibited”","禁"],"unicode":"🈲"},{"annotation":"Japanese “acceptable” button","group":8,"hexcode":"1F251","order":4268,"tags":["ideograph","japanese","japanese “acceptable” button","“acceptable”","可"],"unicode":"🉑"},{"annotation":"Japanese “application” button","group":8,"hexcode":"1F238","order":4269,"tags":["ideograph","japanese","japanese “application” button","“application”","申"],"unicode":"🈸"},{"annotation":"Japanese “passing grade” button","group":8,"hexcode":"1F234","order":4270,"tags":["ideograph","japanese","japanese “passing grade” button","“passing grade”","合"],"unicode":"🈴"},{"annotation":"Japanese “vacancy” button","group":8,"hexcode":"1F233","order":4271,"tags":["ideograph","japanese","japanese “vacancy” button","“vacancy”","空"],"unicode":"🈳"},{"annotation":"Japanese “congratulations” button","group":8,"hexcode":"3297","order":4273,"tags":["ideograph","japanese","japanese “congratulations” button","“congratulations”","祝"],"unicode":"㊗️"},{"annotation":"Japanese “secret” button","group":8,"hexcode":"3299","order":4275,"tags":["ideograph","japanese","japanese “secret” button","“secret”","秘"],"unicode":"㊙️"},{"annotation":"Japanese “open for business” button","group":8,"hexcode":"1F23A","order":4276,"tags":["ideograph","japanese","japanese “open for business” button","“open for business”","営"],"unicode":"🈺"},{"annotation":"Japanese “no vacancy” button","group":8,"hexcode":"1F235","order":4277,"tags":["ideograph","japanese","japanese “no vacancy” button","“no vacancy”","満"],"unicode":"🈵"},{"annotation":"red circle","group":8,"hexcode":"1F534","order":4278,"tags":["circle","geometric","red"],"unicode":"🔴"},{"annotation":"orange circle","group":8,"hexcode":"1F7E0","order":4279,"tags":["circle","orange"],"unicode":"🟠"},{"annotation":"yellow circle","group":8,"hexcode":"1F7E1","order":4280,"tags":["circle","yellow"],"unicode":"🟡"},{"annotation":"green circle","group":8,"hexcode":"1F7E2","order":4281,"tags":["circle","green"],"unicode":"🟢"},{"annotation":"blue circle","group":8,"hexcode":"1F535","order":4282,"tags":["blue","circle","geometric"],"unicode":"🔵"},{"annotation":"purple circle","group":8,"hexcode":"1F7E3","order":4283,"tags":["circle","purple"],"unicode":"🟣"},{"annotation":"brown circle","group":8,"hexcode":"1F7E4","order":4284,"tags":["brown","circle"],"unicode":"🟤"},{"annotation":"black circle","group":8,"hexcode":"26AB","order":4285,"tags":["circle","geometric"],"unicode":"⚫️"},{"annotation":"white circle","group":8,"hexcode":"26AA","order":4286,"tags":["circle","geometric"],"unicode":"⚪️"},{"annotation":"red square","group":8,"hexcode":"1F7E5","order":4287,"tags":["red","square"],"unicode":"🟥"},{"annotation":"orange square","group":8,"hexcode":"1F7E7","order":4288,"tags":["orange","square"],"unicode":"🟧"},{"annotation":"yellow square","group":8,"hexcode":"1F7E8","order":4289,"tags":["square","yellow"],"unicode":"🟨"},{"annotation":"green square","group":8,"hexcode":"1F7E9","order":4290,"tags":["green","square"],"unicode":"🟩"},{"annotation":"blue square","group":8,"hexcode":"1F7E6","order":4291,"tags":["blue","square"],"unicode":"🟦"},{"annotation":"purple square","group":8,"hexcode":"1F7EA","order":4292,"tags":["purple","square"],"unicode":"🟪"},{"annotation":"brown square","group":8,"hexcode":"1F7EB","order":4293,"tags":["brown","square"],"unicode":"🟫"},{"annotation":"black large square","group":8,"hexcode":"2B1B","order":4294,"tags":["geometric","square"],"unicode":"⬛️"},{"annotation":"white large square","group":8,"hexcode":"2B1C","order":4295,"tags":["geometric","square"],"unicode":"⬜️"},{"annotation":"black medium square","group":8,"hexcode":"25FC","order":4297,"tags":["geometric","square"],"unicode":"◼️"},{"annotation":"white medium square","group":8,"hexcode":"25FB","order":4299,"tags":["geometric","square"],"unicode":"◻️"},{"annotation":"black medium-small square","group":8,"hexcode":"25FE","order":4300,"tags":["geometric","square"],"unicode":"◾️"},{"annotation":"white medium-small square","group":8,"hexcode":"25FD","order":4301,"tags":["geometric","square"],"unicode":"◽️"},{"annotation":"black small square","group":8,"hexcode":"25AA","order":4303,"tags":["geometric","square"],"unicode":"▪️"},{"annotation":"white small square","group":8,"hexcode":"25AB","order":4305,"tags":["geometric","square"],"unicode":"▫️"},{"annotation":"large orange diamond","group":8,"hexcode":"1F536","order":4306,"tags":["diamond","geometric","orange"],"unicode":"🔶"},{"annotation":"large blue diamond","group":8,"hexcode":"1F537","order":4307,"tags":["blue","diamond","geometric"],"unicode":"🔷"},{"annotation":"small orange diamond","group":8,"hexcode":"1F538","order":4308,"tags":["diamond","geometric","orange"],"unicode":"🔸"},{"annotation":"small blue diamond","group":8,"hexcode":"1F539","order":4309,"tags":["blue","diamond","geometric"],"unicode":"🔹"},{"annotation":"red triangle pointed up","group":8,"hexcode":"1F53A","order":4310,"tags":["geometric","red"],"unicode":"🔺"},{"annotation":"red triangle pointed down","group":8,"hexcode":"1F53B","order":4311,"tags":["down","geometric","red"],"unicode":"🔻"},{"annotation":"diamond with a dot","group":8,"hexcode":"1F4A0","order":4312,"tags":["comic","diamond","geometric","inside"],"unicode":"💠"},{"annotation":"radio button","group":8,"hexcode":"1F518","order":4313,"tags":["button","geometric","radio"],"unicode":"🔘"},{"annotation":"white square button","group":8,"hexcode":"1F533","order":4314,"tags":["button","geometric","outlined","square"],"unicode":"🔳"},{"annotation":"black square button","group":8,"hexcode":"1F532","order":4315,"tags":["button","geometric","square"],"unicode":"🔲"},{"annotation":"chequered flag","group":9,"hexcode":"1F3C1","order":4316,"tags":["checkered","chequered","racing"],"unicode":"🏁"},{"annotation":"triangular flag","group":9,"hexcode":"1F6A9","order":4317,"tags":["post"],"unicode":"🚩"},{"annotation":"crossed flags","group":9,"hexcode":"1F38C","order":4318,"tags":["celebration","cross","crossed","japanese"],"unicode":"🎌"},{"annotation":"black flag","group":9,"hexcode":"1F3F4","order":4319,"tags":["waving"],"unicode":"🏴"},{"annotation":"white flag","group":9,"hexcode":"1F3F3","order":4321,"tags":["waving"],"unicode":"🏳️"},{"annotation":"rainbow flag","group":9,"hexcode":"1F3F3-FE0F-200D-1F308","order":4322,"tags":["pride","rainbow"],"unicode":"🏳️‍🌈"},{"annotation":"transgender flag","group":9,"hexcode":"1F3F3-FE0F-200D-26A7-FE0F","order":4324,"tags":["flag","light blue","pink","transgender","white"],"unicode":"🏳️‍⚧️"},{"annotation":"pirate flag","group":9,"hexcode":"1F3F4-200D-2620-FE0F","order":4328,"tags":["jolly roger","pirate","plunder","treasure"],"unicode":"🏴‍☠️"},{"annotation":"flag: Ascension Island","group":9,"hexcode":"1F1E6-1F1E8","order":4330,"tags":["AC","flag"],"unicode":"🇦🇨"},{"annotation":"flag: Andorra","group":9,"hexcode":"1F1E6-1F1E9","order":4331,"tags":["AD","flag"],"unicode":"🇦🇩"},{"annotation":"flag: United Arab Emirates","group":9,"hexcode":"1F1E6-1F1EA","order":4332,"tags":["AE","flag"],"unicode":"🇦🇪"},{"annotation":"flag: Afghanistan","group":9,"hexcode":"1F1E6-1F1EB","order":4333,"tags":["AF","flag"],"unicode":"🇦🇫"},{"annotation":"flag: Antigua & Barbuda","group":9,"hexcode":"1F1E6-1F1EC","order":4334,"tags":["AG","flag"],"unicode":"🇦🇬"},{"annotation":"flag: Anguilla","group":9,"hexcode":"1F1E6-1F1EE","order":4335,"tags":["AI","flag"],"unicode":"🇦🇮"},{"annotation":"flag: Albania","group":9,"hexcode":"1F1E6-1F1F1","order":4336,"tags":["AL","flag"],"unicode":"🇦🇱"},{"annotation":"flag: Armenia","group":9,"hexcode":"1F1E6-1F1F2","order":4337,"tags":["AM","flag"],"unicode":"🇦🇲"},{"annotation":"flag: Angola","group":9,"hexcode":"1F1E6-1F1F4","order":4338,"tags":["AO","flag"],"unicode":"🇦🇴"},{"annotation":"flag: Antarctica","group":9,"hexcode":"1F1E6-1F1F6","order":4339,"tags":["AQ","flag"],"unicode":"🇦🇶"},{"annotation":"flag: Argentina","group":9,"hexcode":"1F1E6-1F1F7","order":4340,"tags":["AR","flag"],"unicode":"🇦🇷"},{"annotation":"flag: American Samoa","group":9,"hexcode":"1F1E6-1F1F8","order":4341,"tags":["AS","flag"],"unicode":"🇦🇸"},{"annotation":"flag: Austria","group":9,"hexcode":"1F1E6-1F1F9","order":4342,"tags":["AT","flag"],"unicode":"🇦🇹"},{"annotation":"flag: Australia","group":9,"hexcode":"1F1E6-1F1FA","order":4343,"tags":["AU","flag"],"unicode":"🇦🇺"},{"annotation":"flag: Aruba","group":9,"hexcode":"1F1E6-1F1FC","order":4344,"tags":["AW","flag"],"unicode":"🇦🇼"},{"annotation":"flag: Åland Islands","group":9,"hexcode":"1F1E6-1F1FD","order":4345,"tags":["AX","flag"],"unicode":"🇦🇽"},{"annotation":"flag: Azerbaijan","group":9,"hexcode":"1F1E6-1F1FF","order":4346,"tags":["AZ","flag"],"unicode":"🇦🇿"},{"annotation":"flag: Bosnia & Herzegovina","group":9,"hexcode":"1F1E7-1F1E6","order":4347,"tags":["BA","flag"],"unicode":"🇧🇦"},{"annotation":"flag: Barbados","group":9,"hexcode":"1F1E7-1F1E7","order":4348,"tags":["BB","flag"],"unicode":"🇧🇧"},{"annotation":"flag: Bangladesh","group":9,"hexcode":"1F1E7-1F1E9","order":4349,"tags":["BD","flag"],"unicode":"🇧🇩"},{"annotation":"flag: Belgium","group":9,"hexcode":"1F1E7-1F1EA","order":4350,"tags":["BE","flag"],"unicode":"🇧🇪"},{"annotation":"flag: Burkina Faso","group":9,"hexcode":"1F1E7-1F1EB","order":4351,"tags":["BF","flag"],"unicode":"🇧🇫"},{"annotation":"flag: Bulgaria","group":9,"hexcode":"1F1E7-1F1EC","order":4352,"tags":["BG","flag"],"unicode":"🇧🇬"},{"annotation":"flag: Bahrain","group":9,"hexcode":"1F1E7-1F1ED","order":4353,"tags":["BH","flag"],"unicode":"🇧🇭"},{"annotation":"flag: Burundi","group":9,"hexcode":"1F1E7-1F1EE","order":4354,"tags":["BI","flag"],"unicode":"🇧🇮"},{"annotation":"flag: Benin","group":9,"hexcode":"1F1E7-1F1EF","order":4355,"tags":["BJ","flag"],"unicode":"🇧🇯"},{"annotation":"flag: St. Barthélemy","group":9,"hexcode":"1F1E7-1F1F1","order":4356,"tags":["BL","flag"],"unicode":"🇧🇱"},{"annotation":"flag: Bermuda","group":9,"hexcode":"1F1E7-1F1F2","order":4357,"tags":["BM","flag"],"unicode":"🇧🇲"},{"annotation":"flag: Brunei","group":9,"hexcode":"1F1E7-1F1F3","order":4358,"tags":["BN","flag"],"unicode":"🇧🇳"},{"annotation":"flag: Bolivia","group":9,"hexcode":"1F1E7-1F1F4","order":4359,"tags":["BO","flag"],"unicode":"🇧🇴"},{"annotation":"flag: Caribbean Netherlands","group":9,"hexcode":"1F1E7-1F1F6","order":4360,"tags":["BQ","flag"],"unicode":"🇧🇶"},{"annotation":"flag: Brazil","group":9,"hexcode":"1F1E7-1F1F7","order":4361,"tags":["BR","flag"],"unicode":"🇧🇷"},{"annotation":"flag: Bahamas","group":9,"hexcode":"1F1E7-1F1F8","order":4362,"tags":["BS","flag"],"unicode":"🇧🇸"},{"annotation":"flag: Bhutan","group":9,"hexcode":"1F1E7-1F1F9","order":4363,"tags":["BT","flag"],"unicode":"🇧🇹"},{"annotation":"flag: Bouvet Island","group":9,"hexcode":"1F1E7-1F1FB","order":4364,"tags":["BV","flag"],"unicode":"🇧🇻"},{"annotation":"flag: Botswana","group":9,"hexcode":"1F1E7-1F1FC","order":4365,"tags":["BW","flag"],"unicode":"🇧🇼"},{"annotation":"flag: Belarus","group":9,"hexcode":"1F1E7-1F1FE","order":4366,"tags":["BY","flag"],"unicode":"🇧🇾"},{"annotation":"flag: Belize","group":9,"hexcode":"1F1E7-1F1FF","order":4367,"tags":["BZ","flag"],"unicode":"🇧🇿"},{"annotation":"flag: Canada","group":9,"hexcode":"1F1E8-1F1E6","order":4368,"tags":["CA","flag"],"unicode":"🇨🇦"},{"annotation":"flag: Cocos (Keeling) Islands","group":9,"hexcode":"1F1E8-1F1E8","order":4369,"tags":["CC","flag"],"unicode":"🇨🇨"},{"annotation":"flag: Congo - Kinshasa","group":9,"hexcode":"1F1E8-1F1E9","order":4370,"tags":["CD","flag"],"unicode":"🇨🇩"},{"annotation":"flag: Central African Republic","group":9,"hexcode":"1F1E8-1F1EB","order":4371,"tags":["CF","flag"],"unicode":"🇨🇫"},{"annotation":"flag: Congo - Brazzaville","group":9,"hexcode":"1F1E8-1F1EC","order":4372,"tags":["CG","flag"],"unicode":"🇨🇬"},{"annotation":"flag: Switzerland","group":9,"hexcode":"1F1E8-1F1ED","order":4373,"tags":["CH","flag"],"unicode":"🇨🇭"},{"annotation":"flag: Côte d’Ivoire","group":9,"hexcode":"1F1E8-1F1EE","order":4374,"tags":["CI","flag"],"unicode":"🇨🇮"},{"annotation":"flag: Cook Islands","group":9,"hexcode":"1F1E8-1F1F0","order":4375,"tags":["CK","flag"],"unicode":"🇨🇰"},{"annotation":"flag: Chile","group":9,"hexcode":"1F1E8-1F1F1","order":4376,"tags":["CL","flag"],"unicode":"🇨🇱"},{"annotation":"flag: Cameroon","group":9,"hexcode":"1F1E8-1F1F2","order":4377,"tags":["CM","flag"],"unicode":"🇨🇲"},{"annotation":"flag: China","group":9,"hexcode":"1F1E8-1F1F3","order":4378,"tags":["CN","flag"],"unicode":"🇨🇳"},{"annotation":"flag: Colombia","group":9,"hexcode":"1F1E8-1F1F4","order":4379,"tags":["CO","flag"],"unicode":"🇨🇴"},{"annotation":"flag: Clipperton Island","group":9,"hexcode":"1F1E8-1F1F5","order":4380,"tags":["CP","flag"],"unicode":"🇨🇵"},{"annotation":"flag: Costa Rica","group":9,"hexcode":"1F1E8-1F1F7","order":4381,"tags":["CR","flag"],"unicode":"🇨🇷"},{"annotation":"flag: Cuba","group":9,"hexcode":"1F1E8-1F1FA","order":4382,"tags":["CU","flag"],"unicode":"🇨🇺"},{"annotation":"flag: Cape Verde","group":9,"hexcode":"1F1E8-1F1FB","order":4383,"tags":["CV","flag"],"unicode":"🇨🇻"},{"annotation":"flag: Curaçao","group":9,"hexcode":"1F1E8-1F1FC","order":4384,"tags":["CW","flag"],"unicode":"🇨🇼"},{"annotation":"flag: Christmas Island","group":9,"hexcode":"1F1E8-1F1FD","order":4385,"tags":["CX","flag"],"unicode":"🇨🇽"},{"annotation":"flag: Cyprus","group":9,"hexcode":"1F1E8-1F1FE","order":4386,"tags":["CY","flag"],"unicode":"🇨🇾"},{"annotation":"flag: Czechia","group":9,"hexcode":"1F1E8-1F1FF","order":4387,"tags":["CZ","flag"],"unicode":"🇨🇿"},{"annotation":"flag: Germany","group":9,"hexcode":"1F1E9-1F1EA","order":4388,"tags":["DE","flag"],"unicode":"🇩🇪"},{"annotation":"flag: Diego Garcia","group":9,"hexcode":"1F1E9-1F1EC","order":4389,"tags":["DG","flag"],"unicode":"🇩🇬"},{"annotation":"flag: Djibouti","group":9,"hexcode":"1F1E9-1F1EF","order":4390,"tags":["DJ","flag"],"unicode":"🇩🇯"},{"annotation":"flag: Denmark","group":9,"hexcode":"1F1E9-1F1F0","order":4391,"tags":["DK","flag"],"unicode":"🇩🇰"},{"annotation":"flag: Dominica","group":9,"hexcode":"1F1E9-1F1F2","order":4392,"tags":["DM","flag"],"unicode":"🇩🇲"},{"annotation":"flag: Dominican Republic","group":9,"hexcode":"1F1E9-1F1F4","order":4393,"tags":["DO","flag"],"unicode":"🇩🇴"},{"annotation":"flag: Algeria","group":9,"hexcode":"1F1E9-1F1FF","order":4394,"tags":["DZ","flag"],"unicode":"🇩🇿"},{"annotation":"flag: Ceuta & Melilla","group":9,"hexcode":"1F1EA-1F1E6","order":4395,"tags":["EA","flag"],"unicode":"🇪🇦"},{"annotation":"flag: Ecuador","group":9,"hexcode":"1F1EA-1F1E8","order":4396,"tags":["EC","flag"],"unicode":"🇪🇨"},{"annotation":"flag: Estonia","group":9,"hexcode":"1F1EA-1F1EA","order":4397,"tags":["EE","flag"],"unicode":"🇪🇪"},{"annotation":"flag: Egypt","group":9,"hexcode":"1F1EA-1F1EC","order":4398,"tags":["EG","flag"],"unicode":"🇪🇬"},{"annotation":"flag: Western Sahara","group":9,"hexcode":"1F1EA-1F1ED","order":4399,"tags":["EH","flag"],"unicode":"🇪🇭"},{"annotation":"flag: Eritrea","group":9,"hexcode":"1F1EA-1F1F7","order":4400,"tags":["ER","flag"],"unicode":"🇪🇷"},{"annotation":"flag: Spain","group":9,"hexcode":"1F1EA-1F1F8","order":4401,"tags":["ES","flag"],"unicode":"🇪🇸"},{"annotation":"flag: Ethiopia","group":9,"hexcode":"1F1EA-1F1F9","order":4402,"tags":["ET","flag"],"unicode":"🇪🇹"},{"annotation":"flag: European Union","group":9,"hexcode":"1F1EA-1F1FA","order":4403,"tags":["EU","flag"],"unicode":"🇪🇺"},{"annotation":"flag: Finland","group":9,"hexcode":"1F1EB-1F1EE","order":4404,"tags":["FI","flag"],"unicode":"🇫🇮"},{"annotation":"flag: Fiji","group":9,"hexcode":"1F1EB-1F1EF","order":4405,"tags":["FJ","flag"],"unicode":"🇫🇯"},{"annotation":"flag: Falkland Islands","group":9,"hexcode":"1F1EB-1F1F0","order":4406,"tags":["FK","flag"],"unicode":"🇫🇰"},{"annotation":"flag: Micronesia","group":9,"hexcode":"1F1EB-1F1F2","order":4407,"tags":["FM","flag"],"unicode":"🇫🇲"},{"annotation":"flag: Faroe Islands","group":9,"hexcode":"1F1EB-1F1F4","order":4408,"tags":["FO","flag"],"unicode":"🇫🇴"},{"annotation":"flag: France","group":9,"hexcode":"1F1EB-1F1F7","order":4409,"tags":["FR","flag"],"unicode":"🇫🇷"},{"annotation":"flag: Gabon","group":9,"hexcode":"1F1EC-1F1E6","order":4410,"tags":["GA","flag"],"unicode":"🇬🇦"},{"annotation":"flag: United Kingdom","group":9,"hexcode":"1F1EC-1F1E7","order":4411,"tags":["GB","flag"],"unicode":"🇬🇧"},{"annotation":"flag: Grenada","group":9,"hexcode":"1F1EC-1F1E9","order":4412,"tags":["GD","flag"],"unicode":"🇬🇩"},{"annotation":"flag: Georgia","group":9,"hexcode":"1F1EC-1F1EA","order":4413,"tags":["GE","flag"],"unicode":"🇬🇪"},{"annotation":"flag: French Guiana","group":9,"hexcode":"1F1EC-1F1EB","order":4414,"tags":["GF","flag"],"unicode":"🇬🇫"},{"annotation":"flag: Guernsey","group":9,"hexcode":"1F1EC-1F1EC","order":4415,"tags":["GG","flag"],"unicode":"🇬🇬"},{"annotation":"flag: Ghana","group":9,"hexcode":"1F1EC-1F1ED","order":4416,"tags":["GH","flag"],"unicode":"🇬🇭"},{"annotation":"flag: Gibraltar","group":9,"hexcode":"1F1EC-1F1EE","order":4417,"tags":["GI","flag"],"unicode":"🇬🇮"},{"annotation":"flag: Greenland","group":9,"hexcode":"1F1EC-1F1F1","order":4418,"tags":["GL","flag"],"unicode":"🇬🇱"},{"annotation":"flag: Gambia","group":9,"hexcode":"1F1EC-1F1F2","order":4419,"tags":["GM","flag"],"unicode":"🇬🇲"},{"annotation":"flag: Guinea","group":9,"hexcode":"1F1EC-1F1F3","order":4420,"tags":["GN","flag"],"unicode":"🇬🇳"},{"annotation":"flag: Guadeloupe","group":9,"hexcode":"1F1EC-1F1F5","order":4421,"tags":["GP","flag"],"unicode":"🇬🇵"},{"annotation":"flag: Equatorial Guinea","group":9,"hexcode":"1F1EC-1F1F6","order":4422,"tags":["GQ","flag"],"unicode":"🇬🇶"},{"annotation":"flag: Greece","group":9,"hexcode":"1F1EC-1F1F7","order":4423,"tags":["GR","flag"],"unicode":"🇬🇷"},{"annotation":"flag: South Georgia & South Sandwich Islands","group":9,"hexcode":"1F1EC-1F1F8","order":4424,"tags":["GS","flag"],"unicode":"🇬🇸"},{"annotation":"flag: Guatemala","group":9,"hexcode":"1F1EC-1F1F9","order":4425,"tags":["GT","flag"],"unicode":"🇬🇹"},{"annotation":"flag: Guam","group":9,"hexcode":"1F1EC-1F1FA","order":4426,"tags":["GU","flag"],"unicode":"🇬🇺"},{"annotation":"flag: Guinea-Bissau","group":9,"hexcode":"1F1EC-1F1FC","order":4427,"tags":["GW","flag"],"unicode":"🇬🇼"},{"annotation":"flag: Guyana","group":9,"hexcode":"1F1EC-1F1FE","order":4428,"tags":["GY","flag"],"unicode":"🇬🇾"},{"annotation":"flag: Hong Kong SAR China","group":9,"hexcode":"1F1ED-1F1F0","order":4429,"tags":["HK","flag"],"unicode":"🇭🇰"},{"annotation":"flag: Heard & McDonald Islands","group":9,"hexcode":"1F1ED-1F1F2","order":4430,"tags":["HM","flag"],"unicode":"🇭🇲"},{"annotation":"flag: Honduras","group":9,"hexcode":"1F1ED-1F1F3","order":4431,"tags":["HN","flag"],"unicode":"🇭🇳"},{"annotation":"flag: Croatia","group":9,"hexcode":"1F1ED-1F1F7","order":4432,"tags":["HR","flag"],"unicode":"🇭🇷"},{"annotation":"flag: Haiti","group":9,"hexcode":"1F1ED-1F1F9","order":4433,"tags":["HT","flag"],"unicode":"🇭🇹"},{"annotation":"flag: Hungary","group":9,"hexcode":"1F1ED-1F1FA","order":4434,"tags":["HU","flag"],"unicode":"🇭🇺"},{"annotation":"flag: Canary Islands","group":9,"hexcode":"1F1EE-1F1E8","order":4435,"tags":["IC","flag"],"unicode":"🇮🇨"},{"annotation":"flag: Indonesia","group":9,"hexcode":"1F1EE-1F1E9","order":4436,"tags":["ID","flag"],"unicode":"🇮🇩"},{"annotation":"flag: Ireland","group":9,"hexcode":"1F1EE-1F1EA","order":4437,"tags":["IE","flag"],"unicode":"🇮🇪"},{"annotation":"flag: Israel","group":9,"hexcode":"1F1EE-1F1F1","order":4438,"tags":["IL","flag"],"unicode":"🇮🇱"},{"annotation":"flag: Isle of Man","group":9,"hexcode":"1F1EE-1F1F2","order":4439,"tags":["IM","flag"],"unicode":"🇮🇲"},{"annotation":"flag: India","group":9,"hexcode":"1F1EE-1F1F3","order":4440,"tags":["IN","flag"],"unicode":"🇮🇳"},{"annotation":"flag: British Indian Ocean Territory","group":9,"hexcode":"1F1EE-1F1F4","order":4441,"tags":["IO","flag"],"unicode":"🇮🇴"},{"annotation":"flag: Iraq","group":9,"hexcode":"1F1EE-1F1F6","order":4442,"tags":["IQ","flag"],"unicode":"🇮🇶"},{"annotation":"flag: Iran","group":9,"hexcode":"1F1EE-1F1F7","order":4443,"tags":["IR","flag"],"unicode":"🇮🇷"},{"annotation":"flag: Iceland","group":9,"hexcode":"1F1EE-1F1F8","order":4444,"tags":["IS","flag"],"unicode":"🇮🇸"},{"annotation":"flag: Italy","group":9,"hexcode":"1F1EE-1F1F9","order":4445,"tags":["IT","flag"],"unicode":"🇮🇹"},{"annotation":"flag: Jersey","group":9,"hexcode":"1F1EF-1F1EA","order":4446,"tags":["JE","flag"],"unicode":"🇯🇪"},{"annotation":"flag: Jamaica","group":9,"hexcode":"1F1EF-1F1F2","order":4447,"tags":["JM","flag"],"unicode":"🇯🇲"},{"annotation":"flag: Jordan","group":9,"hexcode":"1F1EF-1F1F4","order":4448,"tags":["JO","flag"],"unicode":"🇯🇴"},{"annotation":"flag: Japan","group":9,"hexcode":"1F1EF-1F1F5","order":4449,"tags":["JP","flag"],"unicode":"🇯🇵"},{"annotation":"flag: Kenya","group":9,"hexcode":"1F1F0-1F1EA","order":4450,"tags":["KE","flag"],"unicode":"🇰🇪"},{"annotation":"flag: Kyrgyzstan","group":9,"hexcode":"1F1F0-1F1EC","order":4451,"tags":["KG","flag"],"unicode":"🇰🇬"},{"annotation":"flag: Cambodia","group":9,"hexcode":"1F1F0-1F1ED","order":4452,"tags":["KH","flag"],"unicode":"🇰🇭"},{"annotation":"flag: Kiribati","group":9,"hexcode":"1F1F0-1F1EE","order":4453,"tags":["KI","flag"],"unicode":"🇰🇮"},{"annotation":"flag: Comoros","group":9,"hexcode":"1F1F0-1F1F2","order":4454,"tags":["KM","flag"],"unicode":"🇰🇲"},{"annotation":"flag: St. Kitts & Nevis","group":9,"hexcode":"1F1F0-1F1F3","order":4455,"tags":["KN","flag"],"unicode":"🇰🇳"},{"annotation":"flag: North Korea","group":9,"hexcode":"1F1F0-1F1F5","order":4456,"tags":["KP","flag"],"unicode":"🇰🇵"},{"annotation":"flag: South Korea","group":9,"hexcode":"1F1F0-1F1F7","order":4457,"tags":["KR","flag"],"unicode":"🇰🇷"},{"annotation":"flag: Kuwait","group":9,"hexcode":"1F1F0-1F1FC","order":4458,"tags":["KW","flag"],"unicode":"🇰🇼"},{"annotation":"flag: Cayman Islands","group":9,"hexcode":"1F1F0-1F1FE","order":4459,"tags":["KY","flag"],"unicode":"🇰🇾"},{"annotation":"flag: Kazakhstan","group":9,"hexcode":"1F1F0-1F1FF","order":4460,"tags":["KZ","flag"],"unicode":"🇰🇿"},{"annotation":"flag: Laos","group":9,"hexcode":"1F1F1-1F1E6","order":4461,"tags":["LA","flag"],"unicode":"🇱🇦"},{"annotation":"flag: Lebanon","group":9,"hexcode":"1F1F1-1F1E7","order":4462,"tags":["LB","flag"],"unicode":"🇱🇧"},{"annotation":"flag: St. Lucia","group":9,"hexcode":"1F1F1-1F1E8","order":4463,"tags":["LC","flag"],"unicode":"🇱🇨"},{"annotation":"flag: Liechtenstein","group":9,"hexcode":"1F1F1-1F1EE","order":4464,"tags":["LI","flag"],"unicode":"🇱🇮"},{"annotation":"flag: Sri Lanka","group":9,"hexcode":"1F1F1-1F1F0","order":4465,"tags":["LK","flag"],"unicode":"🇱🇰"},{"annotation":"flag: Liberia","group":9,"hexcode":"1F1F1-1F1F7","order":4466,"tags":["LR","flag"],"unicode":"🇱🇷"},{"annotation":"flag: Lesotho","group":9,"hexcode":"1F1F1-1F1F8","order":4467,"tags":["LS","flag"],"unicode":"🇱🇸"},{"annotation":"flag: Lithuania","group":9,"hexcode":"1F1F1-1F1F9","order":4468,"tags":["LT","flag"],"unicode":"🇱🇹"},{"annotation":"flag: Luxembourg","group":9,"hexcode":"1F1F1-1F1FA","order":4469,"tags":["LU","flag"],"unicode":"🇱🇺"},{"annotation":"flag: Latvia","group":9,"hexcode":"1F1F1-1F1FB","order":4470,"tags":["LV","flag"],"unicode":"🇱🇻"},{"annotation":"flag: Libya","group":9,"hexcode":"1F1F1-1F1FE","order":4471,"tags":["LY","flag"],"unicode":"🇱🇾"},{"annotation":"flag: Morocco","group":9,"hexcode":"1F1F2-1F1E6","order":4472,"tags":["MA","flag"],"unicode":"🇲🇦"},{"annotation":"flag: Monaco","group":9,"hexcode":"1F1F2-1F1E8","order":4473,"tags":["MC","flag"],"unicode":"🇲🇨"},{"annotation":"flag: Moldova","group":9,"hexcode":"1F1F2-1F1E9","order":4474,"tags":["MD","flag"],"unicode":"🇲🇩"},{"annotation":"flag: Montenegro","group":9,"hexcode":"1F1F2-1F1EA","order":4475,"tags":["ME","flag"],"unicode":"🇲🇪"},{"annotation":"flag: St. Martin","group":9,"hexcode":"1F1F2-1F1EB","order":4476,"tags":["MF","flag"],"unicode":"🇲🇫"},{"annotation":"flag: Madagascar","group":9,"hexcode":"1F1F2-1F1EC","order":4477,"tags":["MG","flag"],"unicode":"🇲🇬"},{"annotation":"flag: Marshall Islands","group":9,"hexcode":"1F1F2-1F1ED","order":4478,"tags":["MH","flag"],"unicode":"🇲🇭"},{"annotation":"flag: North Macedonia","group":9,"hexcode":"1F1F2-1F1F0","order":4479,"tags":["MK","flag"],"unicode":"🇲🇰"},{"annotation":"flag: Mali","group":9,"hexcode":"1F1F2-1F1F1","order":4480,"tags":["ML","flag"],"unicode":"🇲🇱"},{"annotation":"flag: Myanmar (Burma)","group":9,"hexcode":"1F1F2-1F1F2","order":4481,"tags":["MM","flag"],"unicode":"🇲🇲"},{"annotation":"flag: Mongolia","group":9,"hexcode":"1F1F2-1F1F3","order":4482,"tags":["MN","flag"],"unicode":"🇲🇳"},{"annotation":"flag: Macao SAR China","group":9,"hexcode":"1F1F2-1F1F4","order":4483,"tags":["MO","flag"],"unicode":"🇲🇴"},{"annotation":"flag: Northern Mariana Islands","group":9,"hexcode":"1F1F2-1F1F5","order":4484,"tags":["MP","flag"],"unicode":"🇲🇵"},{"annotation":"flag: Martinique","group":9,"hexcode":"1F1F2-1F1F6","order":4485,"tags":["MQ","flag"],"unicode":"🇲🇶"},{"annotation":"flag: Mauritania","group":9,"hexcode":"1F1F2-1F1F7","order":4486,"tags":["MR","flag"],"unicode":"🇲🇷"},{"annotation":"flag: Montserrat","group":9,"hexcode":"1F1F2-1F1F8","order":4487,"tags":["MS","flag"],"unicode":"🇲🇸"},{"annotation":"flag: Malta","group":9,"hexcode":"1F1F2-1F1F9","order":4488,"tags":["MT","flag"],"unicode":"🇲🇹"},{"annotation":"flag: Mauritius","group":9,"hexcode":"1F1F2-1F1FA","order":4489,"tags":["MU","flag"],"unicode":"🇲🇺"},{"annotation":"flag: Maldives","group":9,"hexcode":"1F1F2-1F1FB","order":4490,"tags":["MV","flag"],"unicode":"🇲🇻"},{"annotation":"flag: Malawi","group":9,"hexcode":"1F1F2-1F1FC","order":4491,"tags":["MW","flag"],"unicode":"🇲🇼"},{"annotation":"flag: Mexico","group":9,"hexcode":"1F1F2-1F1FD","order":4492,"tags":["MX","flag"],"unicode":"🇲🇽"},{"annotation":"flag: Malaysia","group":9,"hexcode":"1F1F2-1F1FE","order":4493,"tags":["MY","flag"],"unicode":"🇲🇾"},{"annotation":"flag: Mozambique","group":9,"hexcode":"1F1F2-1F1FF","order":4494,"tags":["MZ","flag"],"unicode":"🇲🇿"},{"annotation":"flag: Namibia","group":9,"hexcode":"1F1F3-1F1E6","order":4495,"tags":["NA","flag"],"unicode":"🇳🇦"},{"annotation":"flag: New Caledonia","group":9,"hexcode":"1F1F3-1F1E8","order":4496,"tags":["NC","flag"],"unicode":"🇳🇨"},{"annotation":"flag: Niger","group":9,"hexcode":"1F1F3-1F1EA","order":4497,"tags":["NE","flag"],"unicode":"🇳🇪"},{"annotation":"flag: Norfolk Island","group":9,"hexcode":"1F1F3-1F1EB","order":4498,"tags":["NF","flag"],"unicode":"🇳🇫"},{"annotation":"flag: Nigeria","group":9,"hexcode":"1F1F3-1F1EC","order":4499,"tags":["NG","flag"],"unicode":"🇳🇬"},{"annotation":"flag: Nicaragua","group":9,"hexcode":"1F1F3-1F1EE","order":4500,"tags":["NI","flag"],"unicode":"🇳🇮"},{"annotation":"flag: Netherlands","group":9,"hexcode":"1F1F3-1F1F1","order":4501,"tags":["NL","flag"],"unicode":"🇳🇱"},{"annotation":"flag: Norway","group":9,"hexcode":"1F1F3-1F1F4","order":4502,"tags":["NO","flag"],"unicode":"🇳🇴"},{"annotation":"flag: Nepal","group":9,"hexcode":"1F1F3-1F1F5","order":4503,"tags":["NP","flag"],"unicode":"🇳🇵"},{"annotation":"flag: Nauru","group":9,"hexcode":"1F1F3-1F1F7","order":4504,"tags":["NR","flag"],"unicode":"🇳🇷"},{"annotation":"flag: Niue","group":9,"hexcode":"1F1F3-1F1FA","order":4505,"tags":["NU","flag"],"unicode":"🇳🇺"},{"annotation":"flag: New Zealand","group":9,"hexcode":"1F1F3-1F1FF","order":4506,"tags":["NZ","flag"],"unicode":"🇳🇿"},{"annotation":"flag: Oman","group":9,"hexcode":"1F1F4-1F1F2","order":4507,"tags":["OM","flag"],"unicode":"🇴🇲"},{"annotation":"flag: Panama","group":9,"hexcode":"1F1F5-1F1E6","order":4508,"tags":["PA","flag"],"unicode":"🇵🇦"},{"annotation":"flag: Peru","group":9,"hexcode":"1F1F5-1F1EA","order":4509,"tags":["PE","flag"],"unicode":"🇵🇪"},{"annotation":"flag: French Polynesia","group":9,"hexcode":"1F1F5-1F1EB","order":4510,"tags":["PF","flag"],"unicode":"🇵🇫"},{"annotation":"flag: Papua New Guinea","group":9,"hexcode":"1F1F5-1F1EC","order":4511,"tags":["PG","flag"],"unicode":"🇵🇬"},{"annotation":"flag: Philippines","group":9,"hexcode":"1F1F5-1F1ED","order":4512,"tags":["PH","flag"],"unicode":"🇵🇭"},{"annotation":"flag: Pakistan","group":9,"hexcode":"1F1F5-1F1F0","order":4513,"tags":["PK","flag"],"unicode":"🇵🇰"},{"annotation":"flag: Poland","group":9,"hexcode":"1F1F5-1F1F1","order":4514,"tags":["PL","flag"],"unicode":"🇵🇱"},{"annotation":"flag: St. Pierre & Miquelon","group":9,"hexcode":"1F1F5-1F1F2","order":4515,"tags":["PM","flag"],"unicode":"🇵🇲"},{"annotation":"flag: Pitcairn Islands","group":9,"hexcode":"1F1F5-1F1F3","order":4516,"tags":["PN","flag"],"unicode":"🇵🇳"},{"annotation":"flag: Puerto Rico","group":9,"hexcode":"1F1F5-1F1F7","order":4517,"tags":["PR","flag"],"unicode":"🇵🇷"},{"annotation":"flag: Palestinian Territories","group":9,"hexcode":"1F1F5-1F1F8","order":4518,"tags":["PS","flag"],"unicode":"🇵🇸"},{"annotation":"flag: Portugal","group":9,"hexcode":"1F1F5-1F1F9","order":4519,"tags":["PT","flag"],"unicode":"🇵🇹"},{"annotation":"flag: Palau","group":9,"hexcode":"1F1F5-1F1FC","order":4520,"tags":["PW","flag"],"unicode":"🇵🇼"},{"annotation":"flag: Paraguay","group":9,"hexcode":"1F1F5-1F1FE","order":4521,"tags":["PY","flag"],"unicode":"🇵🇾"},{"annotation":"flag: Qatar","group":9,"hexcode":"1F1F6-1F1E6","order":4522,"tags":["QA","flag"],"unicode":"🇶🇦"},{"annotation":"flag: Réunion","group":9,"hexcode":"1F1F7-1F1EA","order":4523,"tags":["RE","flag"],"unicode":"🇷🇪"},{"annotation":"flag: Romania","group":9,"hexcode":"1F1F7-1F1F4","order":4524,"tags":["RO","flag"],"unicode":"🇷🇴"},{"annotation":"flag: Serbia","group":9,"hexcode":"1F1F7-1F1F8","order":4525,"tags":["RS","flag"],"unicode":"🇷🇸"},{"annotation":"flag: Russia","group":9,"hexcode":"1F1F7-1F1FA","order":4526,"tags":["RU","flag"],"unicode":"🇷🇺"},{"annotation":"flag: Rwanda","group":9,"hexcode":"1F1F7-1F1FC","order":4527,"tags":["RW","flag"],"unicode":"🇷🇼"},{"annotation":"flag: Saudi Arabia","group":9,"hexcode":"1F1F8-1F1E6","order":4528,"tags":["SA","flag"],"unicode":"🇸🇦"},{"annotation":"flag: Solomon Islands","group":9,"hexcode":"1F1F8-1F1E7","order":4529,"tags":["SB","flag"],"unicode":"🇸🇧"},{"annotation":"flag: Seychelles","group":9,"hexcode":"1F1F8-1F1E8","order":4530,"tags":["SC","flag"],"unicode":"🇸🇨"},{"annotation":"flag: Sudan","group":9,"hexcode":"1F1F8-1F1E9","order":4531,"tags":["SD","flag"],"unicode":"🇸🇩"},{"annotation":"flag: Sweden","group":9,"hexcode":"1F1F8-1F1EA","order":4532,"tags":["SE","flag"],"unicode":"🇸🇪"},{"annotation":"flag: Singapore","group":9,"hexcode":"1F1F8-1F1EC","order":4533,"tags":["SG","flag"],"unicode":"🇸🇬"},{"annotation":"flag: St. Helena","group":9,"hexcode":"1F1F8-1F1ED","order":4534,"tags":["SH","flag"],"unicode":"🇸🇭"},{"annotation":"flag: Slovenia","group":9,"hexcode":"1F1F8-1F1EE","order":4535,"tags":["SI","flag"],"unicode":"🇸🇮"},{"annotation":"flag: Svalbard & Jan Mayen","group":9,"hexcode":"1F1F8-1F1EF","order":4536,"tags":["SJ","flag"],"unicode":"🇸🇯"},{"annotation":"flag: Slovakia","group":9,"hexcode":"1F1F8-1F1F0","order":4537,"tags":["SK","flag"],"unicode":"🇸🇰"},{"annotation":"flag: Sierra Leone","group":9,"hexcode":"1F1F8-1F1F1","order":4538,"tags":["SL","flag"],"unicode":"🇸🇱"},{"annotation":"flag: San Marino","group":9,"hexcode":"1F1F8-1F1F2","order":4539,"tags":["SM","flag"],"unicode":"🇸🇲"},{"annotation":"flag: Senegal","group":9,"hexcode":"1F1F8-1F1F3","order":4540,"tags":["SN","flag"],"unicode":"🇸🇳"},{"annotation":"flag: Somalia","group":9,"hexcode":"1F1F8-1F1F4","order":4541,"tags":["SO","flag"],"unicode":"🇸🇴"},{"annotation":"flag: Suriname","group":9,"hexcode":"1F1F8-1F1F7","order":4542,"tags":["SR","flag"],"unicode":"🇸🇷"},{"annotation":"flag: South Sudan","group":9,"hexcode":"1F1F8-1F1F8","order":4543,"tags":["SS","flag"],"unicode":"🇸🇸"},{"annotation":"flag: São Tomé & Príncipe","group":9,"hexcode":"1F1F8-1F1F9","order":4544,"tags":["ST","flag"],"unicode":"🇸🇹"},{"annotation":"flag: El Salvador","group":9,"hexcode":"1F1F8-1F1FB","order":4545,"tags":["SV","flag"],"unicode":"🇸🇻"},{"annotation":"flag: Sint Maarten","group":9,"hexcode":"1F1F8-1F1FD","order":4546,"tags":["SX","flag"],"unicode":"🇸🇽"},{"annotation":"flag: Syria","group":9,"hexcode":"1F1F8-1F1FE","order":4547,"tags":["SY","flag"],"unicode":"🇸🇾"},{"annotation":"flag: Eswatini","group":9,"hexcode":"1F1F8-1F1FF","order":4548,"tags":["SZ","flag"],"unicode":"🇸🇿"},{"annotation":"flag: Tristan da Cunha","group":9,"hexcode":"1F1F9-1F1E6","order":4549,"tags":["TA","flag"],"unicode":"🇹🇦"},{"annotation":"flag: Turks & Caicos Islands","group":9,"hexcode":"1F1F9-1F1E8","order":4550,"tags":["TC","flag"],"unicode":"🇹🇨"},{"annotation":"flag: Chad","group":9,"hexcode":"1F1F9-1F1E9","order":4551,"tags":["TD","flag"],"unicode":"🇹🇩"},{"annotation":"flag: French Southern Territories","group":9,"hexcode":"1F1F9-1F1EB","order":4552,"tags":["TF","flag"],"unicode":"🇹🇫"},{"annotation":"flag: Togo","group":9,"hexcode":"1F1F9-1F1EC","order":4553,"tags":["TG","flag"],"unicode":"🇹🇬"},{"annotation":"flag: Thailand","group":9,"hexcode":"1F1F9-1F1ED","order":4554,"tags":["TH","flag"],"unicode":"🇹🇭"},{"annotation":"flag: Tajikistan","group":9,"hexcode":"1F1F9-1F1EF","order":4555,"tags":["TJ","flag"],"unicode":"🇹🇯"},{"annotation":"flag: Tokelau","group":9,"hexcode":"1F1F9-1F1F0","order":4556,"tags":["TK","flag"],"unicode":"🇹🇰"},{"annotation":"flag: Timor-Leste","group":9,"hexcode":"1F1F9-1F1F1","order":4557,"tags":["TL","flag"],"unicode":"🇹🇱"},{"annotation":"flag: Turkmenistan","group":9,"hexcode":"1F1F9-1F1F2","order":4558,"tags":["TM","flag"],"unicode":"🇹🇲"},{"annotation":"flag: Tunisia","group":9,"hexcode":"1F1F9-1F1F3","order":4559,"tags":["TN","flag"],"unicode":"🇹🇳"},{"annotation":"flag: Tonga","group":9,"hexcode":"1F1F9-1F1F4","order":4560,"tags":["TO","flag"],"unicode":"🇹🇴"},{"annotation":"flag: Turkey","group":9,"hexcode":"1F1F9-1F1F7","order":4561,"tags":["TR","flag"],"unicode":"🇹🇷"},{"annotation":"flag: Trinidad & Tobago","group":9,"hexcode":"1F1F9-1F1F9","order":4562,"tags":["TT","flag"],"unicode":"🇹🇹"},{"annotation":"flag: Tuvalu","group":9,"hexcode":"1F1F9-1F1FB","order":4563,"tags":["TV","flag"],"unicode":"🇹🇻"},{"annotation":"flag: Taiwan","group":9,"hexcode":"1F1F9-1F1FC","order":4564,"tags":["TW","flag"],"unicode":"🇹🇼"},{"annotation":"flag: Tanzania","group":9,"hexcode":"1F1F9-1F1FF","order":4565,"tags":["TZ","flag"],"unicode":"🇹🇿"},{"annotation":"flag: Ukraine","group":9,"hexcode":"1F1FA-1F1E6","order":4566,"tags":["UA","flag"],"unicode":"🇺🇦"},{"annotation":"flag: Uganda","group":9,"hexcode":"1F1FA-1F1EC","order":4567,"tags":["UG","flag"],"unicode":"🇺🇬"},{"annotation":"flag: U.S. Outlying Islands","group":9,"hexcode":"1F1FA-1F1F2","order":4568,"tags":["UM","flag"],"unicode":"🇺🇲"},{"annotation":"flag: United Nations","group":9,"hexcode":"1F1FA-1F1F3","order":4569,"tags":["UN","flag"],"unicode":"🇺🇳"},{"annotation":"flag: United States","group":9,"hexcode":"1F1FA-1F1F8","order":4570,"tags":["US","flag"],"unicode":"🇺🇸"},{"annotation":"flag: Uruguay","group":9,"hexcode":"1F1FA-1F1FE","order":4571,"tags":["UY","flag"],"unicode":"🇺🇾"},{"annotation":"flag: Uzbekistan","group":9,"hexcode":"1F1FA-1F1FF","order":4572,"tags":["UZ","flag"],"unicode":"🇺🇿"},{"annotation":"flag: Vatican City","group":9,"hexcode":"1F1FB-1F1E6","order":4573,"tags":["VA","flag"],"unicode":"🇻🇦"},{"annotation":"flag: St. Vincent & Grenadines","group":9,"hexcode":"1F1FB-1F1E8","order":4574,"tags":["VC","flag"],"unicode":"🇻🇨"},{"annotation":"flag: Venezuela","group":9,"hexcode":"1F1FB-1F1EA","order":4575,"tags":["VE","flag"],"unicode":"🇻🇪"},{"annotation":"flag: British Virgin Islands","group":9,"hexcode":"1F1FB-1F1EC","order":4576,"tags":["VG","flag"],"unicode":"🇻🇬"},{"annotation":"flag: U.S. Virgin Islands","group":9,"hexcode":"1F1FB-1F1EE","order":4577,"tags":["VI","flag"],"unicode":"🇻🇮"},{"annotation":"flag: Vietnam","group":9,"hexcode":"1F1FB-1F1F3","order":4578,"tags":["VN","flag"],"unicode":"🇻🇳"},{"annotation":"flag: Vanuatu","group":9,"hexcode":"1F1FB-1F1FA","order":4579,"tags":["VU","flag"],"unicode":"🇻🇺"},{"annotation":"flag: Wallis & Futuna","group":9,"hexcode":"1F1FC-1F1EB","order":4580,"tags":["WF","flag"],"unicode":"🇼🇫"},{"annotation":"flag: Samoa","group":9,"hexcode":"1F1FC-1F1F8","order":4581,"tags":["WS","flag"],"unicode":"🇼🇸"},{"annotation":"flag: Kosovo","group":9,"hexcode":"1F1FD-1F1F0","order":4582,"tags":["XK","flag"],"unicode":"🇽🇰"},{"annotation":"flag: Yemen","group":9,"hexcode":"1F1FE-1F1EA","order":4583,"tags":["YE","flag"],"unicode":"🇾🇪"},{"annotation":"flag: Mayotte","group":9,"hexcode":"1F1FE-1F1F9","order":4584,"tags":["YT","flag"],"unicode":"🇾🇹"},{"annotation":"flag: South Africa","group":9,"hexcode":"1F1FF-1F1E6","order":4585,"tags":["ZA","flag"],"unicode":"🇿🇦"},{"annotation":"flag: Zambia","group":9,"hexcode":"1F1FF-1F1F2","order":4586,"tags":["ZM","flag"],"unicode":"🇿🇲"},{"annotation":"flag: Zimbabwe","group":9,"hexcode":"1F1FF-1F1FC","order":4587,"tags":["ZW","flag"],"unicode":"🇿🇼"},{"annotation":"flag: England","group":9,"hexcode":"1F3F4-E0067-E0062-E0065-E006E-E0067-E007F","order":4588,"tags":["flag","gbeng"],"unicode":"🏴󠁧󠁢󠁥󠁮󠁧󠁿"},{"annotation":"flag: Scotland","group":9,"hexcode":"1F3F4-E0067-E0062-E0073-E0063-E0074-E007F","order":4589,"tags":["flag","gbsct"],"unicode":"🏴󠁧󠁢󠁳󠁣󠁴󠁿"},{"annotation":"flag: Wales","group":9,"hexcode":"1F3F4-E0067-E0062-E0077-E006C-E0073-E007F","order":4590,"tags":["flag","gbwls"],"unicode":"🏴󠁧󠁢󠁷󠁬󠁳󠁿"}]'),ns=JSON.parse('{"2049":"interrobang","2122":"tm","2139":"information_source","2194":"left_right_arrow","2195":"arrow_up_down","2196":"arrow_upper_left","2197":"arrow_upper_right","2198":"arrow_lower_right","2199":"arrow_lower_left","2328":"keyboard","2600":"sunny","2601":"cloud","2602":"umbrella2","2603":"snowman2","2604":"comet","2611":"ballot_box_with_check","2614":"umbrella","2615":"coffee","2618":"shamrock","2620":["skull_crossbones","skull_and_crossbones"],"2622":["radioactive","radioactive_sign"],"2623":["biohazard","biohazard_sign"],"2626":"orthodox_cross","2638":"wheel_of_dharma","2639":["frowning2","white_frowning_face"],"2640":"female_sign","2642":"male_sign","2648":"aries","2649":"taurus","2650":"sagittarius","2651":"capricorn","2652":"aquarius","2653":"pisces","2660":"spades","2663":"clubs","2665":"hearts","2666":"diamonds","2668":"hotsprings","2692":["hammer_pick","hammer_and_pick"],"2693":"anchor","2694":"crossed_swords","2695":"medical_symbol","2696":"scales","2697":"alembic","2699":"gear","2702":"scissors","2705":"white_check_mark","2708":"airplane","2709":"envelope","2712":"black_nib","2714":"heavy_check_mark","2716":"heavy_multiplication_x","2721":"star_of_david","2728":"sparkles","2733":"eight_spoked_asterisk","2734":"eight_pointed_black_star","2744":"snowflake","2747":"sparkle","2753":"question","2754":"grey_question","2755":"grey_exclamation","2757":"exclamation","2763":["heart_exclamation","heavy_heart_exclamation_mark_ornament"],"2764":"heart","2795":"heavy_plus_sign","2796":"heavy_minus_sign","2797":"heavy_division_sign","2934":"arrow_heading_up","2935":"arrow_heading_down","3030":"wavy_dash","3297":"congratulations","3299":"secret","1F600":"grinning","1F603":"smiley","1F604":"smile","1F601":"grin","1F606":["laughing","satisfied"],"1F605":"sweat_smile","1F602":"joy","1F923":["rofl","rolling_on_the_floor_laughing"],"263A":"relaxed","1F60A":"blush","1F607":"innocent","1F642":["slight_smile","slightly_smiling_face"],"1F643":["upside_down","upside_down_face"],"1F609":"wink","1F60C":"relieved","1F972":"smiling_face_with_tear","1F60D":"heart_eyes","1F970":"smiling_face_with_3_hearts","1F618":"kissing_heart","1F617":"kissing","1F619":"kissing_smiling_eyes","1F61A":"kissing_closed_eyes","1F60B":"yum","1F61B":"stuck_out_tongue","1F61D":"stuck_out_tongue_closed_eyes","1F61C":"stuck_out_tongue_winking_eye","1F92A":"zany_face","1F928":"face_with_raised_eyebrow","1F9D0":"face_with_monocle","1F913":["nerd","nerd_face"],"1F60E":"sunglasses","1F929":"star_struck","1F973":"partying_face","1F60F":"smirk","1F612":"unamused","1F61E":"disappointed","1F614":"pensive","1F61F":"worried","1F615":"confused","1F641":["slight_frown","slightly_frowning_face"],"1F623":"persevere","1F616":"confounded","1F62B":"tired_face","1F629":"weary","1F97A":"pleading_face","1F622":"cry","1F62D":"sob","1F624":"triumph","1F62E-200D-1F4A8":"face_exhaling","1F620":"angry","1F621":"rage","1F92C":"face_with_symbols_over_mouth","1F92F":"exploding_head","1F633":"flushed","1F636-200D-1F32B-FE0F":"face_in_clouds","1F975":"hot_face","1F976":"cold_face","1F631":"scream","1F628":"fearful","1F630":"cold_sweat","1F625":"disappointed_relieved","1F613":"sweat","1F917":["hugging","hugging_face"],"1F914":["thinking","thinking_face"],"1F92D":"face_with_hand_over_mouth","1F971":"yawning_face","1F92B":"shushing_face","1F925":["lying_face","liar"],"1F636":"no_mouth","1F610":"neutral_face","1F611":"expressionless","1F62C":"grimacing","1F644":["rolling_eyes","face_with_rolling_eyes"],"1F62F":"hushed","1F626":"frowning","1F627":"anguished","1F62E":"open_mouth","1F632":"astonished","1F634":"sleeping","1F924":["drooling_face","drool"],"1F62A":"sleepy","1F635":"dizzy_face","1F635-200D-1F4AB":"face_with_spiral_eyes","1F910":["zipper_mouth","zipper_mouth_face"],"1F974":"woozy_face","1F922":["nauseated_face","sick"],"1F92E":"face_vomiting","1F927":["sneezing_face","sneeze"],"1F637":"mask","1F912":["thermometer_face","face_with_thermometer"],"1F915":["head_bandage","face_with_head_bandage"],"1F911":["money_mouth","money_mouth_face"],"1F920":["cowboy","face_with_cowboy_hat"],"1F978":"disguised_face","1F608":"smiling_imp","1F47F":"imp","1F479":"japanese_ogre","1F47A":"japanese_goblin","1F921":["clown","clown_face"],"1F4A9":["poop","shit","hankey","poo"],"1F47B":"ghost","1F480":["skull","skeleton"],"1F47D":"alien","1F47E":"space_invader","1F916":["robot","robot_face"],"1F383":"jack_o_lantern","1F63A":"smiley_cat","1F638":"smile_cat","1F639":"joy_cat","1F63B":"heart_eyes_cat","1F63C":"smirk_cat","1F63D":"kissing_cat","1F640":"scream_cat","1F63F":"crying_cat_face","1F63E":"pouting_cat","1F932":"palms_up_together","1F932-1F3FB":["palms_up_together_tone1","palms_up_together_light_skin_tone"],"1F932-1F3FC":["palms_up_together_tone2","palms_up_together_medium_light_skin_tone"],"1F932-1F3FD":["palms_up_together_tone3","palms_up_together_medium_skin_tone"],"1F932-1F3FE":["palms_up_together_tone4","palms_up_together_medium_dark_skin_tone"],"1F932-1F3FF":["palms_up_together_tone5","palms_up_together_dark_skin_tone"],"1F450":"open_hands","1F450-1F3FB":"open_hands_tone1","1F450-1F3FC":"open_hands_tone2","1F450-1F3FD":"open_hands_tone3","1F450-1F3FE":"open_hands_tone4","1F450-1F3FF":"open_hands_tone5","1F64C":"raised_hands","1F64C-1F3FB":"raised_hands_tone1","1F64C-1F3FC":"raised_hands_tone2","1F64C-1F3FD":"raised_hands_tone3","1F64C-1F3FE":"raised_hands_tone4","1F64C-1F3FF":"raised_hands_tone5","1F44F":"clap","1F44F-1F3FB":"clap_tone1","1F44F-1F3FC":"clap_tone2","1F44F-1F3FD":"clap_tone3","1F44F-1F3FE":"clap_tone4","1F44F-1F3FF":"clap_tone5","1F91D":["handshake","shaking_hands"],"1F44D":["thumbsup","+1","thumbup"],"1F44D-1F3FB":["thumbsup_tone1","+1_tone1","thumbup_tone1"],"1F44D-1F3FC":["thumbsup_tone2","+1_tone2","thumbup_tone2"],"1F44D-1F3FD":["thumbsup_tone3","+1_tone3","thumbup_tone3"],"1F44D-1F3FE":["thumbsup_tone4","+1_tone4","thumbup_tone4"],"1F44D-1F3FF":["thumbsup_tone5","+1_tone5","thumbup_tone5"],"1F44E":["thumbsdown","-1","thumbdown"],"1F44E-1F3FB":["thumbsdown_tone1","-1_tone1","thumbdown_tone1"],"1F44E-1F3FC":["thumbsdown_tone2","-1_tone2","thumbdown_tone2"],"1F44E-1F3FD":["thumbsdown_tone3","-1_tone3","thumbdown_tone3"],"1F44E-1F3FE":["thumbsdown_tone4","-1_tone4","thumbdown_tone4"],"1F44E-1F3FF":["thumbsdown_tone5","-1_tone5","thumbdown_tone5"],"1F44A":"punch","1F44A-1F3FB":"punch_tone1","1F44A-1F3FC":"punch_tone2","1F44A-1F3FD":"punch_tone3","1F44A-1F3FE":"punch_tone4","1F44A-1F3FF":"punch_tone5","270A":"fist","270A-1F3FB":"fist_tone1","270A-1F3FC":"fist_tone2","270A-1F3FD":"fist_tone3","270A-1F3FE":"fist_tone4","270A-1F3FF":"fist_tone5","1F91B":["left_facing_fist","left_fist"],"1F91B-1F3FB":["left_facing_fist_tone1","left_fist_tone1"],"1F91B-1F3FC":["left_facing_fist_tone2","left_fist_tone2"],"1F91B-1F3FD":["left_facing_fist_tone3","left_fist_tone3"],"1F91B-1F3FE":["left_facing_fist_tone4","left_fist_tone4"],"1F91B-1F3FF":["left_facing_fist_tone5","left_fist_tone5"],"1F91C":["right_facing_fist","right_fist"],"1F91C-1F3FB":["right_facing_fist_tone1","right_fist_tone1"],"1F91C-1F3FC":["right_facing_fist_tone2","right_fist_tone2"],"1F91C-1F3FD":["right_facing_fist_tone3","right_fist_tone3"],"1F91C-1F3FE":["right_facing_fist_tone4","right_fist_tone4"],"1F91C-1F3FF":["right_facing_fist_tone5","right_fist_tone5"],"1F91E":["fingers_crossed","hand_with_index_and_middle_finger_crossed"],"1F91E-1F3FB":["fingers_crossed_tone1","hand_with_index_and_middle_fingers_crossed_tone1"],"1F91E-1F3FC":["fingers_crossed_tone2","hand_with_index_and_middle_fingers_crossed_tone2"],"1F91E-1F3FD":["fingers_crossed_tone3","hand_with_index_and_middle_fingers_crossed_tone3"],"1F91E-1F3FE":["fingers_crossed_tone4","hand_with_index_and_middle_fingers_crossed_tone4"],"1F91E-1F3FF":["fingers_crossed_tone5","hand_with_index_and_middle_fingers_crossed_tone5"],"270C":"v","270C-1F3FB":"v_tone1","270C-1F3FC":"v_tone2","270C-1F3FD":"v_tone3","270C-1F3FE":"v_tone4","270C-1F3FF":"v_tone5","1F91F":"love_you_gesture","1F91F-1F3FB":["love_you_gesture_tone1","love_you_gesture_light_skin_tone"],"1F91F-1F3FC":["love_you_gesture_tone2","love_you_gesture_medium_light_skin_tone"],"1F91F-1F3FD":["love_you_gesture_tone3","love_you_gesture_medium_skin_tone"],"1F91F-1F3FE":["love_you_gesture_tone4","love_you_gesture_medium_dark_skin_tone"],"1F91F-1F3FF":["love_you_gesture_tone5","love_you_gesture_dark_skin_tone"],"1F918":["metal","sign_of_the_horns"],"1F918-1F3FB":["metal_tone1","sign_of_the_horns_tone1"],"1F918-1F3FC":["metal_tone2","sign_of_the_horns_tone2"],"1F918-1F3FD":["metal_tone3","sign_of_the_horns_tone3"],"1F918-1F3FE":["metal_tone4","sign_of_the_horns_tone4"],"1F918-1F3FF":["metal_tone5","sign_of_the_horns_tone5"],"1F44C":"ok_hand","1F44C-1F3FB":"ok_hand_tone1","1F44C-1F3FC":"ok_hand_tone2","1F44C-1F3FD":"ok_hand_tone3","1F44C-1F3FE":"ok_hand_tone4","1F44C-1F3FF":"ok_hand_tone5","1F90F":"pinching_hand","1F90F-1F3FB":["pinching_hand_tone1","pinching_hand_light_skin_tone"],"1F90F-1F3FC":["pinching_hand_tone2","pinching_hand_medium_light_skin_tone"],"1F90F-1F3FD":["pinching_hand_tone3","pinching_hand_medium_skin_tone"],"1F90F-1F3FE":["pinching_hand_tone4","pinching_hand_medium_dark_skin_tone"],"1F90F-1F3FF":["pinching_hand_tone5","pinching_hand_dark_skin_tone"],"1F90C":"pinched_fingers","1F90C-1F3FC":["pinched_fingers_tone2","pinched_fingers_medium_light_skin_tone"],"1F90C-1F3FB":["pinched_fingers_tone1","pinched_fingers_light_skin_tone"],"1F90C-1F3FD":["pinched_fingers_tone3","pinched_fingers_medium_skin_tone"],"1F90C-1F3FE":["pinched_fingers_tone4","pinched_fingers_medium_dark_skin_tone"],"1F90C-1F3FF":["pinched_fingers_tone5","pinched_fingers_dark_skin_tone"],"1F448":"point_left","1F448-1F3FB":"point_left_tone1","1F448-1F3FC":"point_left_tone2","1F448-1F3FD":"point_left_tone3","1F448-1F3FE":"point_left_tone4","1F448-1F3FF":"point_left_tone5","1F449":"point_right","1F449-1F3FB":"point_right_tone1","1F449-1F3FC":"point_right_tone2","1F449-1F3FD":"point_right_tone3","1F449-1F3FE":"point_right_tone4","1F449-1F3FF":"point_right_tone5","1F446":"point_up_2","1F446-1F3FB":"point_up_2_tone1","1F446-1F3FC":"point_up_2_tone2","1F446-1F3FD":"point_up_2_tone3","1F446-1F3FE":"point_up_2_tone4","1F446-1F3FF":"point_up_2_tone5","1F447":"point_down","1F447-1F3FB":"point_down_tone1","1F447-1F3FC":"point_down_tone2","1F447-1F3FD":"point_down_tone3","1F447-1F3FE":"point_down_tone4","1F447-1F3FF":"point_down_tone5","261D":"point_up","261D-1F3FB":"point_up_tone1","261D-1F3FC":"point_up_tone2","261D-1F3FD":"point_up_tone3","261D-1F3FE":"point_up_tone4","261D-1F3FF":"point_up_tone5","270B":"raised_hand","270B-1F3FB":"raised_hand_tone1","270B-1F3FC":"raised_hand_tone2","270B-1F3FD":"raised_hand_tone3","270B-1F3FE":"raised_hand_tone4","270B-1F3FF":"raised_hand_tone5","1F91A":["raised_back_of_hand","back_of_hand"],"1F91A-1F3FB":["raised_back_of_hand_tone1","back_of_hand_tone1"],"1F91A-1F3FC":["raised_back_of_hand_tone2","back_of_hand_tone2"],"1F91A-1F3FD":["raised_back_of_hand_tone3","back_of_hand_tone3"],"1F91A-1F3FE":["raised_back_of_hand_tone4","back_of_hand_tone4"],"1F91A-1F3FF":["raised_back_of_hand_tone5","back_of_hand_tone5"],"1F590":["hand_splayed","raised_hand_with_fingers_splayed"],"1F590-1F3FB":["hand_splayed_tone1","raised_hand_with_fingers_splayed_tone1"],"1F590-1F3FC":["hand_splayed_tone2","raised_hand_with_fingers_splayed_tone2"],"1F590-1F3FD":["hand_splayed_tone3","raised_hand_with_fingers_splayed_tone3"],"1F590-1F3FE":["hand_splayed_tone4","raised_hand_with_fingers_splayed_tone4"],"1F590-1F3FF":["hand_splayed_tone5","raised_hand_with_fingers_splayed_tone5"],"1F596":["vulcan","raised_hand_with_part_between_middle_and_ring_fingers"],"1F596-1F3FB":["vulcan_tone1","raised_hand_with_part_between_middle_and_ring_fingers_tone1"],"1F596-1F3FC":["vulcan_tone2","raised_hand_with_part_between_middle_and_ring_fingers_tone2"],"1F596-1F3FD":["vulcan_tone3","raised_hand_with_part_between_middle_and_ring_fingers_tone3"],"1F596-1F3FE":["vulcan_tone4","raised_hand_with_part_between_middle_and_ring_fingers_tone4"],"1F596-1F3FF":["vulcan_tone5","raised_hand_with_part_between_middle_and_ring_fingers_tone5"],"1F44B":"wave","1F44B-1F3FB":"wave_tone1","1F44B-1F3FC":"wave_tone2","1F44B-1F3FD":"wave_tone3","1F44B-1F3FE":"wave_tone4","1F44B-1F3FF":"wave_tone5","1F919":["call_me","call_me_hand"],"1F919-1F3FB":["call_me_tone1","call_me_hand_tone1"],"1F919-1F3FC":["call_me_tone2","call_me_hand_tone2"],"1F919-1F3FD":["call_me_tone3","call_me_hand_tone3"],"1F919-1F3FE":["call_me_tone4","call_me_hand_tone4"],"1F919-1F3FF":["call_me_tone5","call_me_hand_tone5"],"1F4AA":"muscle","1F4AA-1F3FB":"muscle_tone1","1F4AA-1F3FC":"muscle_tone2","1F4AA-1F3FD":"muscle_tone3","1F4AA-1F3FE":"muscle_tone4","1F4AA-1F3FF":"muscle_tone5","1F9BE":"mechanical_arm","1F595":["middle_finger","reversed_hand_with_middle_finger_extended"],"1F595-1F3FB":["middle_finger_tone1","reversed_hand_with_middle_finger_extended_tone1"],"1F595-1F3FC":["middle_finger_tone2","reversed_hand_with_middle_finger_extended_tone2"],"1F595-1F3FD":["middle_finger_tone3","reversed_hand_with_middle_finger_extended_tone3"],"1F595-1F3FE":["middle_finger_tone4","reversed_hand_with_middle_finger_extended_tone4"],"1F595-1F3FF":["middle_finger_tone5","reversed_hand_with_middle_finger_extended_tone5"],"270D":"writing_hand","270D-1F3FB":"writing_hand_tone1","270D-1F3FC":"writing_hand_tone2","270D-1F3FD":"writing_hand_tone3","270D-1F3FE":"writing_hand_tone4","270D-1F3FF":"writing_hand_tone5","1F64F":"pray","1F64F-1F3FB":"pray_tone1","1F64F-1F3FC":"pray_tone2","1F64F-1F3FD":"pray_tone3","1F64F-1F3FE":"pray_tone4","1F64F-1F3FF":"pray_tone5","1F9B6":"foot","1F9B6-1F3FB":["foot_tone1","foot_light_skin_tone"],"1F9B6-1F3FC":["foot_tone2","foot_medium_light_skin_tone"],"1F9B6-1F3FD":["foot_tone3","foot_medium_skin_tone"],"1F9B6-1F3FE":["foot_tone4","foot_medium_dark_skin_tone"],"1F9B6-1F3FF":["foot_tone5","foot_dark_skin_tone"],"1F9B5":"leg","1F9B5-1F3FB":["leg_tone1","leg_light_skin_tone"],"1F9B5-1F3FC":["leg_tone2","leg_medium_light_skin_tone"],"1F9B5-1F3FD":["leg_tone3","leg_medium_skin_tone"],"1F9B5-1F3FE":["leg_tone4","leg_medium_dark_skin_tone"],"1F9B5-1F3FF":["leg_tone5","leg_dark_skin_tone"],"1F9BF":"mechanical_leg","1F484":"lipstick","1F48B":"kiss","1F444":"lips","1F9B7":"tooth","1F445":"tongue","1F442":"ear","1F442-1F3FB":"ear_tone1","1F442-1F3FC":"ear_tone2","1F9D1-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FE":["kiss_person_person_tone5_tone4","kiss_person_person_dark_skin_tone_medium_dark_skin_tone"],"1F442-1F3FD":"ear_tone3","1F442-1F3FE":"ear_tone4","1F442-1F3FF":"ear_tone5","1F9BB":"ear_with_hearing_aid","1F9BB-1F3FB":["ear_with_hearing_aid_tone1","ear_with_hearing_aid_light_skin_tone"],"1F9BB-1F3FC":["ear_with_hearing_aid_tone2","ear_with_hearing_aid_medium_light_skin_tone"],"1F9BB-1F3FD":["ear_with_hearing_aid_tone3","ear_with_hearing_aid_medium_skin_tone"],"1F9BB-1F3FE":["ear_with_hearing_aid_tone4","ear_with_hearing_aid_medium_dark_skin_tone"],"1F9BB-1F3FF":["ear_with_hearing_aid_tone5","ear_with_hearing_aid_dark_skin_tone"],"1F443":"nose","1F443-1F3FB":"nose_tone1","1F443-1F3FC":"nose_tone2","1F443-1F3FD":"nose_tone3","1F443-1F3FE":"nose_tone4","1F443-1F3FF":"nose_tone5","1F463":"footprints","1F441":"eye","1F440":"eyes","1F9E0":"brain","1FAC0":"anatomical_heart","1FAC1":"lungs","1F9B4":"bone","1F5E3":["speaking_head","speaking_head_in_silhouette"],"1F464":"bust_in_silhouette","1F465":"busts_in_silhouette","1FAC2":"people_hugging","1F476":"baby","1F476-1F3FB":"baby_tone1","1F476-1F3FC":"baby_tone2","1F476-1F3FD":"baby_tone3","1F476-1F3FE":"baby_tone4","1F476-1F3FF":"baby_tone5","1F467":"girl","1F467-1F3FB":"girl_tone1","1F467-1F3FC":"girl_tone2","1F467-1F3FD":"girl_tone3","1F467-1F3FE":"girl_tone4","1F467-1F3FF":"girl_tone5","1F9D2":"child","1F9D2-1F3FB":["child_tone1","child_light_skin_tone"],"1F9D2-1F3FC":["child_tone2","child_medium_light_skin_tone"],"1F9D2-1F3FD":["child_tone3","child_medium_skin_tone"],"1F9D2-1F3FE":["child_tone4","child_medium_dark_skin_tone"],"1F9D2-1F3FF":["child_tone5","child_dark_skin_tone"],"1F466":"boy","1F466-1F3FB":"boy_tone1","1F466-1F3FC":"boy_tone2","1F466-1F3FD":"boy_tone3","1F466-1F3FE":"boy_tone4","1F466-1F3FF":"boy_tone5","1F469":"woman","1F469-1F3FB":"woman_tone1","1F469-1F3FC":"woman_tone2","1F469-1F3FD":"woman_tone3","1F469-1F3FE":"woman_tone4","1F469-1F3FF":"woman_tone5","1F9D1":"adult","1F9D1-1F3FB":["adult_tone1","adult_light_skin_tone"],"1F9D1-1F3FC":["adult_tone2","adult_medium_light_skin_tone"],"1F9D1-1F3FD":["adult_tone3","adult_medium_skin_tone"],"1F9D1-1F3FE":["adult_tone4","adult_medium_dark_skin_tone"],"1F9D1-1F3FF":["adult_tone5","adult_dark_skin_tone"],"1F468":"man","1F468-1F3FB":"man_tone1","1F468-1F3FC":"man_tone2","1F468-1F3FD":"man_tone3","1F468-1F3FE":"man_tone4","1F468-1F3FF":"man_tone5","1F9D1-200D-1F9B1":"person_curly_hair","1F9D1-1F3FB-200D-1F9B1":["person_tone1_curly_hair","person_light_skin_tone_curly_hair"],"1F9D1-1F3FC-200D-1F9B1":["person_tone2_curly_hair","person_medium_light_skin_tone_curly_hair"],"1F9D1-1F3FD-200D-1F9B1":["person_tone3_curly_hair","person_medium_skin_tone_curly_hair"],"1F9D1-1F3FE-200D-1F9B1":["person_tone4_curly_hair","person_medium_dark_skin_tone_curly_hair"],"1F9D1-1F3FF-200D-1F9B1":["person_tone5_curly_hair","person_dark_skin_tone_curly_hair"],"1F469-200D-1F9B1":"woman_curly_haired","1F469-1F3FB-200D-1F9B1":["woman_curly_haired_tone1","woman_curly_haired_light_skin_tone"],"1F469-1F3FC-200D-1F9B1":["woman_curly_haired_tone2","woman_curly_haired_medium_light_skin_tone"],"1F469-1F3FD-200D-1F9B1":["woman_curly_haired_tone3","woman_curly_haired_medium_skin_tone"],"1F469-1F3FE-200D-1F9B1":["woman_curly_haired_tone4","woman_curly_haired_medium_dark_skin_tone"],"1F469-1F3FF-200D-1F9B1":["woman_curly_haired_tone5","woman_curly_haired_dark_skin_tone"],"1F468-200D-1F9B1":"man_curly_haired","1F468-1F3FB-200D-1F9B1":["man_curly_haired_tone1","man_curly_haired_light_skin_tone"],"1F468-1F3FC-200D-1F9B1":["man_curly_haired_tone2","man_curly_haired_medium_light_skin_tone"],"1F468-1F3FD-200D-1F9B1":["man_curly_haired_tone3","man_curly_haired_medium_skin_tone"],"1F468-1F3FE-200D-1F9B1":["man_curly_haired_tone4","man_curly_haired_medium_dark_skin_tone"],"1F468-1F3FF-200D-1F9B1":["man_curly_haired_tone5","man_curly_haired_dark_skin_tone"],"1F9D1-200D-1F9B0":"person_red_hair","1F9D1-1F3FB-200D-1F9B0":["person_tone1_red_hair","person_light_skin_tone_red_hair"],"1F9D1-1F3FC-200D-1F9B0":["person_tone2_red_hair","person_medium_light_skin_tone_red_hair"],"1F9D1-1F3FD-200D-1F9B0":["person_tone3_red_hair","person_medium_skin_tone_red_hair"],"1F9D1-1F3FE-200D-1F9B0":["person_tone4_red_hair","person_medium_dark_skin_tone_red_hair"],"1F9D1-1F3FF-200D-1F9B0":["person_tone5_red_hair","person_dark_skin_tone_red_hair"],"1F469-200D-1F9B0":"woman_red_haired","1F469-1F3FB-200D-1F9B0":["woman_red_haired_tone1","woman_red_haired_light_skin_tone"],"1F469-1F3FC-200D-1F9B0":["woman_red_haired_tone2","woman_red_haired_medium_light_skin_tone"],"1F469-1F3FD-200D-1F9B0":["woman_red_haired_tone3","woman_red_haired_medium_skin_tone"],"1F469-1F3FE-200D-1F9B0":["woman_red_haired_tone4","woman_red_haired_medium_dark_skin_tone"],"1F469-1F3FF-200D-1F9B0":["woman_red_haired_tone5","woman_red_haired_dark_skin_tone"],"1F468-200D-1F9B0":"man_red_haired","1F468-1F3FB-200D-1F9B0":["man_red_haired_tone1","man_red_haired_light_skin_tone"],"1F468-1F3FC-200D-1F9B0":["man_red_haired_tone2","man_red_haired_medium_light_skin_tone"],"1F468-1F3FD-200D-1F9B0":["man_red_haired_tone3","man_red_haired_medium_skin_tone"],"1F468-1F3FE-200D-1F9B0":["man_red_haired_tone4","man_red_haired_medium_dark_skin_tone"],"1F468-1F3FF-200D-1F9B0":["man_red_haired_tone5","man_red_haired_dark_skin_tone"],"1F471-200D-2640-FE0F":"blond-haired_woman","1F471-1F3FB-200D-2640-FE0F":["blond-haired_woman_tone1","blond-haired_woman_light_skin_tone"],"1F471-1F3FC-200D-2640-FE0F":["blond-haired_woman_tone2","blond-haired_woman_medium_light_skin_tone"],"1F471-1F3FD-200D-2640-FE0F":["blond-haired_woman_tone3","blond-haired_woman_medium_skin_tone"],"1F471-1F3FE-200D-2640-FE0F":["blond-haired_woman_tone4","blond-haired_woman_medium_dark_skin_tone"],"1F471-1F3FF-200D-2640-FE0F":["blond-haired_woman_tone5","blond-haired_woman_dark_skin_tone"],"1F471":["blond_haired_person","person_with_blond_hair"],"1F471-1F3FB":["blond_haired_person_tone1","person_with_blond_hair_tone1"],"1F471-1F3FC":["blond_haired_person_tone2","person_with_blond_hair_tone2"],"1F471-1F3FD":["blond_haired_person_tone3","person_with_blond_hair_tone3"],"1F471-1F3FE":["blond_haired_person_tone4","person_with_blond_hair_tone4"],"1F471-1F3FF":["blond_haired_person_tone5","person_with_blond_hair_tone5"],"1F471-200D-2642-FE0F":"blond-haired_man","1F471-1F3FB-200D-2642-FE0F":["blond-haired_man_tone1","blond-haired_man_light_skin_tone"],"1F471-1F3FC-200D-2642-FE0F":["blond-haired_man_tone2","blond-haired_man_medium_light_skin_tone"],"1F471-1F3FD-200D-2642-FE0F":["blond-haired_man_tone3","blond-haired_man_medium_skin_tone"],"1F471-1F3FE-200D-2642-FE0F":["blond-haired_man_tone4","blond-haired_man_medium_dark_skin_tone"],"1F471-1F3FF-200D-2642-FE0F":["blond-haired_man_tone5","blond-haired_man_dark_skin_tone"],"1F9D1-200D-1F9B3":"person_white_hair","1F9D1-1F3FB-200D-1F9B3":["person_tone1_white_hair","person_light_skin_tone_white_hair"],"1F9D1-1F3FC-200D-1F9B3":["person_tone2_white_hair","person_medium_light_skin_tone_white_hair"],"1F9D1-1F3FD-200D-1F9B3":["person_tone3_white_hair","person_medium_skin_tone_white_hair"],"1F9D1-1F3FE-200D-1F9B3":["person_tone4_white_hair","person_medium_dark_skin_tone_white_hair"],"1F9D1-1F3FF-200D-1F9B3":["person_tone5_white_hair","person_dark_skin_tone_white_hair"],"1F469-200D-1F9B3":"woman_white_haired","1F469-1F3FB-200D-1F9B3":["woman_white_haired_tone1","woman_white_haired_light_skin_tone"],"1F469-1F3FC-200D-1F9B3":["woman_white_haired_tone2","woman_white_haired_medium_light_skin_tone"],"1F469-1F3FD-200D-1F9B3":["woman_white_haired_tone3","woman_white_haired_medium_skin_tone"],"1F469-1F3FE-200D-1F9B3":["woman_white_haired_tone4","woman_white_haired_medium_dark_skin_tone"],"1F469-1F3FF-200D-1F9B3":["woman_white_haired_tone5","woman_white_haired_dark_skin_tone"],"1F468-200D-1F9B3":"man_white_haired","1F468-1F3FB-200D-1F9B3":["man_white_haired_tone1","man_white_haired_light_skin_tone"],"1F468-1F3FC-200D-1F9B3":["man_white_haired_tone2","man_white_haired_medium_light_skin_tone"],"1F468-1F3FD-200D-1F9B3":["man_white_haired_tone3","man_white_haired_medium_skin_tone"],"1F468-1F3FE-200D-1F9B3":["man_white_haired_tone4","man_white_haired_medium_dark_skin_tone"],"1F468-1F3FF-200D-1F9B3":["man_white_haired_tone5","man_white_haired_dark_skin_tone"],"1F9D1-200D-1F9B2":"person_bald","1F9D1-1F3FB-200D-1F9B2":["person_tone1_bald","person_light_skin_tone_bald"],"1F9D1-1F3FC-200D-1F9B2":["person_tone2_bald","person_medium_light_skin_tone_bald"],"1F9D1-1F3FD-200D-1F9B2":["person_tone3_bald","person_medium_skin_tone_bald"],"1F9D1-1F3FE-200D-1F9B2":["person_tone4_bald","person_medium_dark_skin_tone_bald"],"1F9D1-1F3FF-200D-1F9B2":["person_tone5_bald","person_dark_skin_tone_bald"],"1F469-200D-1F9B2":"woman_bald","1F469-1F3FB-200D-1F9B2":["woman_bald_tone1","woman_bald_light_skin_tone"],"1F469-1F3FC-200D-1F9B2":["woman_bald_tone2","woman_bald_medium_light_skin_tone"],"1F469-1F3FD-200D-1F9B2":["woman_bald_tone3","woman_bald_medium_skin_tone"],"1F469-1F3FE-200D-1F9B2":["woman_bald_tone4","woman_bald_medium_dark_skin_tone"],"1F469-1F3FF-200D-1F9B2":["woman_bald_tone5","woman_bald_dark_skin_tone"],"1F468-200D-1F9B2":"man_bald","1F468-1F3FB-200D-1F9B2":["man_bald_tone1","man_bald_light_skin_tone"],"1F468-1F3FC-200D-1F9B2":["man_bald_tone2","man_bald_medium_light_skin_tone"],"1F468-1F3FD-200D-1F9B2":["man_bald_tone3","man_bald_medium_skin_tone"],"1F468-1F3FE-200D-1F9B2":["man_bald_tone4","man_bald_medium_dark_skin_tone"],"1F468-1F3FF-200D-1F9B2":["man_bald_tone5","man_bald_dark_skin_tone"],"1F9D4":"bearded_person","1F9D4-1F3FB":["bearded_person_tone1","bearded_person_light_skin_tone"],"1F9D4-1F3FC":["bearded_person_tone2","bearded_person_medium_light_skin_tone"],"1F9D4-1F3FD":["bearded_person_tone3","bearded_person_medium_skin_tone"],"1F9D4-1F3FE":["bearded_person_tone4","bearded_person_medium_dark_skin_tone"],"1F9D4-1F3FF":["bearded_person_tone5","bearded_person_dark_skin_tone"],"1F9D4-200D-2642-FE0F":"man_beard","1F9D4-1F3FB-200D-2642-FE0F":["man_tone1_beard","man_light_skin_tone_beard"],"1F9D4-1F3FC-200D-2642-FE0F":["man_tone2_beard","man_medium_light_skin_tone_beard"],"1F9D4-1F3FD-200D-2642-FE0F":["man_tone3_beard","man_medium_skin_tone_beard"],"1F9D4-1F3FE-200D-2642-FE0F":["man_tone4_beard","man_medium_dark_skin_tone_beard"],"1F9D4-1F3FF-200D-2642-FE0F":["man_tone5_beard","man_dark_skin_tone_beard"],"1F9D4-200D-2640-FE0F":"woman_beard","1F9D4-1F3FB-200D-2640-FE0F":["woman_tone1_beard","woman_light_skin_tone_beard"],"1F9D4-1F3FC-200D-2640-FE0F":["woman_tone2_beard","woman_medium_light_skin_tone_beard"],"1F9D4-1F3FD-200D-2640-FE0F":["woman_tone3_beard","woman_medium_skin_tone_beard"],"1F9D4-1F3FE-200D-2640-FE0F":["woman_tone4_beard","woman_medium_dark_skin_tone_beard"],"1F9D4-1F3FF-200D-2640-FE0F":["woman_tone5_beard","woman_dark_skin_tone_beard"],"1F475":["older_woman","grandma"],"1F475-1F3FB":["older_woman_tone1","grandma_tone1"],"1F475-1F3FC":["older_woman_tone2","grandma_tone2"],"1F475-1F3FD":["older_woman_tone3","grandma_tone3"],"1F475-1F3FE":["older_woman_tone4","grandma_tone4"],"1F475-1F3FF":["older_woman_tone5","grandma_tone5"],"1F9D3":"older_adult","1F9D3-1F3FB":["older_adult_tone1","older_adult_light_skin_tone"],"1F9D3-1F3FC":["older_adult_tone2","older_adult_medium_light_skin_tone"],"1F9D3-1F3FD":["older_adult_tone3","older_adult_medium_skin_tone"],"1F9D3-1F3FE":["older_adult_tone4","older_adult_medium_dark_skin_tone"],"1F9D3-1F3FF":["older_adult_tone5","older_adult_dark_skin_tone"],"1F474":"older_man","1F474-1F3FB":"older_man_tone1","1F474-1F3FC":"older_man_tone2","1F474-1F3FD":"older_man_tone3","1F474-1F3FE":"older_man_tone4","1F474-1F3FF":"older_man_tone5","1F472":["man_with_chinese_cap","man_with_gua_pi_mao"],"1F472-1F3FB":["man_with_chinese_cap_tone1","man_with_gua_pi_mao_tone1"],"1F472-1F3FC":["man_with_chinese_cap_tone2","man_with_gua_pi_mao_tone2"],"1F472-1F3FD":["man_with_chinese_cap_tone3","man_with_gua_pi_mao_tone3"],"1F472-1F3FE":["man_with_chinese_cap_tone4","man_with_gua_pi_mao_tone4"],"1F472-1F3FF":["man_with_chinese_cap_tone5","man_with_gua_pi_mao_tone5"],"1F473":["person_wearing_turban","man_with_turban"],"1F473-1F3FB":["person_wearing_turban_tone1","man_with_turban_tone1"],"1F473-1F3FC":["person_wearing_turban_tone2","man_with_turban_tone2"],"1F473-1F3FD":["person_wearing_turban_tone3","man_with_turban_tone3"],"1F473-1F3FE":["person_wearing_turban_tone4","man_with_turban_tone4"],"1F473-1F3FF":["person_wearing_turban_tone5","man_with_turban_tone5"],"1F473-200D-2640-FE0F":"woman_wearing_turban","1F473-1F3FB-200D-2640-FE0F":["woman_wearing_turban_tone1","woman_wearing_turban_light_skin_tone"],"1F473-1F3FC-200D-2640-FE0F":["woman_wearing_turban_tone2","woman_wearing_turban_medium_light_skin_tone"],"1F473-1F3FD-200D-2640-FE0F":["woman_wearing_turban_tone3","woman_wearing_turban_medium_skin_tone"],"1F473-1F3FE-200D-2640-FE0F":["woman_wearing_turban_tone4","woman_wearing_turban_medium_dark_skin_tone"],"1F473-1F3FF-200D-2640-FE0F":["woman_wearing_turban_tone5","woman_wearing_turban_dark_skin_tone"],"1F473-200D-2642-FE0F":"man_wearing_turban","1F473-1F3FB-200D-2642-FE0F":["man_wearing_turban_tone1","man_wearing_turban_light_skin_tone"],"1F473-1F3FC-200D-2642-FE0F":["man_wearing_turban_tone2","man_wearing_turban_medium_light_skin_tone"],"1F473-1F3FD-200D-2642-FE0F":["man_wearing_turban_tone3","man_wearing_turban_medium_skin_tone"],"1F473-1F3FE-200D-2642-FE0F":["man_wearing_turban_tone4","man_wearing_turban_medium_dark_skin_tone"],"1F473-1F3FF-200D-2642-FE0F":["man_wearing_turban_tone5","man_wearing_turban_dark_skin_tone"],"1F9D5":"woman_with_headscarf","1F9D5-1F3FB":["woman_with_headscarf_tone1","woman_with_headscarf_light_skin_tone"],"1F9D5-1F3FC":["woman_with_headscarf_tone2","woman_with_headscarf_medium_light_skin_tone"],"1F9D5-1F3FD":["woman_with_headscarf_tone3","woman_with_headscarf_medium_skin_tone"],"1F9D5-1F3FE":["woman_with_headscarf_tone4","woman_with_headscarf_medium_dark_skin_tone"],"1F9D5-1F3FF":["woman_with_headscarf_tone5","woman_with_headscarf_dark_skin_tone"],"1F46E":["police_officer","cop"],"1F46E-1F3FB":["police_officer_tone1","cop_tone1"],"1F46E-1F3FC":["police_officer_tone2","cop_tone2"],"1F46E-1F3FD":["police_officer_tone3","cop_tone3"],"1F46E-1F3FE":["police_officer_tone4","cop_tone4"],"1F46E-1F3FF":["police_officer_tone5","cop_tone5"],"1F46E-200D-2640-FE0F":"woman_police_officer","1F46E-1F3FB-200D-2640-FE0F":["woman_police_officer_tone1","woman_police_officer_light_skin_tone"],"1F46E-1F3FC-200D-2640-FE0F":["woman_police_officer_tone2","woman_police_officer_medium_light_skin_tone"],"1F46E-1F3FD-200D-2640-FE0F":["woman_police_officer_tone3","woman_police_officer_medium_skin_tone"],"1F46E-1F3FE-200D-2640-FE0F":["woman_police_officer_tone4","woman_police_officer_medium_dark_skin_tone"],"1F46E-1F3FF-200D-2640-FE0F":["woman_police_officer_tone5","woman_police_officer_dark_skin_tone"],"1F46E-200D-2642-FE0F":"man_police_officer","1F46E-1F3FB-200D-2642-FE0F":["man_police_officer_tone1","man_police_officer_light_skin_tone"],"1F46E-1F3FC-200D-2642-FE0F":["man_police_officer_tone2","man_police_officer_medium_light_skin_tone"],"1F46E-1F3FD-200D-2642-FE0F":["man_police_officer_tone3","man_police_officer_medium_skin_tone"],"1F46E-1F3FE-200D-2642-FE0F":["man_police_officer_tone4","man_police_officer_medium_dark_skin_tone"],"1F46E-1F3FF-200D-2642-FE0F":["man_police_officer_tone5","man_police_officer_dark_skin_tone"],"1F477":"construction_worker","1F477-1F3FB":"construction_worker_tone1","1F477-1F3FC":"construction_worker_tone2","1F477-1F3FD":"construction_worker_tone3","1F477-1F3FE":"construction_worker_tone4","1F477-1F3FF":"construction_worker_tone5","1F477-200D-2640-FE0F":"woman_construction_worker","1F477-1F3FB-200D-2640-FE0F":["woman_construction_worker_tone1","woman_construction_worker_light_skin_tone"],"1F477-1F3FC-200D-2640-FE0F":["woman_construction_worker_tone2","woman_construction_worker_medium_light_skin_tone"],"1F477-1F3FD-200D-2640-FE0F":["woman_construction_worker_tone3","woman_construction_worker_medium_skin_tone"],"1F477-1F3FE-200D-2640-FE0F":["woman_construction_worker_tone4","woman_construction_worker_medium_dark_skin_tone"],"1F477-1F3FF-200D-2640-FE0F":["woman_construction_worker_tone5","woman_construction_worker_dark_skin_tone"],"1F477-200D-2642-FE0F":"man_construction_worker","1F477-1F3FB-200D-2642-FE0F":["man_construction_worker_tone1","man_construction_worker_light_skin_tone"],"1F477-1F3FC-200D-2642-FE0F":["man_construction_worker_tone2","man_construction_worker_medium_light_skin_tone"],"1F477-1F3FD-200D-2642-FE0F":["man_construction_worker_tone3","man_construction_worker_medium_skin_tone"],"1F477-1F3FE-200D-2642-FE0F":["man_construction_worker_tone4","man_construction_worker_medium_dark_skin_tone"],"1F477-1F3FF-200D-2642-FE0F":["man_construction_worker_tone5","man_construction_worker_dark_skin_tone"],"1F482":["guard","guardsman"],"1F482-1F3FB":["guard_tone1","guardsman_tone1"],"1F482-1F3FC":["guard_tone2","guardsman_tone2"],"1F482-1F3FD":["guard_tone3","guardsman_tone3"],"1F482-1F3FE":["guard_tone4","guardsman_tone4"],"1F482-1F3FF":["guard_tone5","guardsman_tone5"],"1F482-200D-2640-FE0F":"woman_guard","1F482-1F3FB-200D-2640-FE0F":["woman_guard_tone1","woman_guard_light_skin_tone"],"1F482-1F3FC-200D-2640-FE0F":["woman_guard_tone2","woman_guard_medium_light_skin_tone"],"1F482-1F3FD-200D-2640-FE0F":["woman_guard_tone3","woman_guard_medium_skin_tone"],"1F482-1F3FE-200D-2640-FE0F":["woman_guard_tone4","woman_guard_medium_dark_skin_tone"],"1F482-1F3FF-200D-2640-FE0F":["woman_guard_tone5","woman_guard_dark_skin_tone"],"1F482-200D-2642-FE0F":"man_guard","1F482-1F3FB-200D-2642-FE0F":["man_guard_tone1","man_guard_light_skin_tone"],"1F482-1F3FC-200D-2642-FE0F":["man_guard_tone2","man_guard_medium_light_skin_tone"],"1F482-1F3FD-200D-2642-FE0F":["man_guard_tone3","man_guard_medium_skin_tone"],"1F482-1F3FE-200D-2642-FE0F":["man_guard_tone4","man_guard_medium_dark_skin_tone"],"1F482-1F3FF-200D-2642-FE0F":["man_guard_tone5","man_guard_dark_skin_tone"],"1F575":["detective","spy","sleuth_or_spy"],"1F575-1F3FB":["detective_tone1","spy_tone1","sleuth_or_spy_tone1"],"1F575-1F3FC":["detective_tone2","spy_tone2","sleuth_or_spy_tone2"],"1F575-1F3FD":["detective_tone3","spy_tone3","sleuth_or_spy_tone3"],"1F575-1F3FE":["detective_tone4","spy_tone4","sleuth_or_spy_tone4"],"1F575-1F3FF":["detective_tone5","spy_tone5","sleuth_or_spy_tone5"],"1F575-FE0F-200D-2640-FE0F":"woman_detective","1F575-1F3FB-200D-2640-FE0F":["woman_detective_tone1","woman_detective_light_skin_tone"],"1F575-1F3FC-200D-2640-FE0F":["woman_detective_tone2","woman_detective_medium_light_skin_tone"],"1F575-1F3FD-200D-2640-FE0F":["woman_detective_tone3","woman_detective_medium_skin_tone"],"1F575-1F3FE-200D-2640-FE0F":["woman_detective_tone4","woman_detective_medium_dark_skin_tone"],"1F575-1F3FF-200D-2640-FE0F":["woman_detective_tone5","woman_detective_dark_skin_tone"],"1F575-FE0F-200D-2642-FE0F":"man_detective","1F575-1F3FB-200D-2642-FE0F":["man_detective_tone1","man_detective_light_skin_tone"],"1F575-1F3FC-200D-2642-FE0F":["man_detective_tone2","man_detective_medium_light_skin_tone"],"1F575-1F3FD-200D-2642-FE0F":["man_detective_tone3","man_detective_medium_skin_tone"],"1F575-1F3FE-200D-2642-FE0F":["man_detective_tone4","man_detective_medium_dark_skin_tone"],"1F575-1F3FF-200D-2642-FE0F":["man_detective_tone5","man_detective_dark_skin_tone"],"1F9D1-200D-2695-FE0F":"health_worker","1F9D1-1F3FB-200D-2695-FE0F":["health_worker_tone1","health_worker_light_skin_tone"],"1F9D1-1F3FC-200D-2695-FE0F":["health_worker_tone2","health_worker_medium_light_skin_tone"],"1F9D1-1F3FD-200D-2695-FE0F":["health_worker_tone3","health_worker_medium_skin_tone"],"1F9D1-1F3FE-200D-2695-FE0F":["health_worker_tone4","health_worker_medium_dark_skin_tone"],"1F9D1-1F3FF-200D-2695-FE0F":["health_worker_tone5","health_worker_dark_skin_tone"],"1F469-200D-2695-FE0F":"woman_health_worker","1F469-1F3FB-200D-2695-FE0F":["woman_health_worker_tone1","woman_health_worker_light_skin_tone"],"1F469-1F3FC-200D-2695-FE0F":["woman_health_worker_tone2","woman_health_worker_medium_light_skin_tone"],"1F469-1F3FD-200D-2695-FE0F":["woman_health_worker_tone3","woman_health_worker_medium_skin_tone"],"1F469-1F3FE-200D-2695-FE0F":["woman_health_worker_tone4","woman_health_worker_medium_dark_skin_tone"],"1F469-1F3FF-200D-2695-FE0F":["woman_health_worker_tone5","woman_health_worker_dark_skin_tone"],"1F468-200D-2695-FE0F":"man_health_worker","1F468-1F3FB-200D-2695-FE0F":["man_health_worker_tone1","man_health_worker_light_skin_tone"],"1F468-1F3FC-200D-2695-FE0F":["man_health_worker_tone2","man_health_worker_medium_light_skin_tone"],"1F468-1F3FD-200D-2695-FE0F":["man_health_worker_tone3","man_health_worker_medium_skin_tone"],"1F468-1F3FE-200D-2695-FE0F":["man_health_worker_tone4","man_health_worker_medium_dark_skin_tone"],"1F468-1F3FF-200D-2695-FE0F":["man_health_worker_tone5","man_health_worker_dark_skin_tone"],"1F9D1-200D-1F33E":"farmer","1F9D1-1F3FB-200D-1F33E":["farmer_tone1","farmer_light_skin_tone"],"1F9D1-1F3FC-200D-1F33E":["farmer_tone2","farmer_medium_light_skin_tone"],"1F9D1-1F3FD-200D-1F33E":["farmer_tone3","farmer_medium_skin_tone"],"1F9D1-1F3FE-200D-1F33E":["farmer_tone4","farmer_medium_dark_skin_tone"],"1F9D1-1F3FF-200D-1F33E":["farmer_tone5","farmer_dark_skin_tone"],"1F469-200D-1F33E":"woman_farmer","1F469-1F3FB-200D-1F33E":["woman_farmer_tone1","woman_farmer_light_skin_tone"],"1F469-1F3FC-200D-1F33E":["woman_farmer_tone2","woman_farmer_medium_light_skin_tone"],"1F469-1F3FD-200D-1F33E":["woman_farmer_tone3","woman_farmer_medium_skin_tone"],"1F469-1F3FE-200D-1F33E":["woman_farmer_tone4","woman_farmer_medium_dark_skin_tone"],"1F469-1F3FF-200D-1F33E":["woman_farmer_tone5","woman_farmer_dark_skin_tone"],"1F468-200D-1F33E":"man_farmer","1F468-1F3FB-200D-1F33E":["man_farmer_tone1","man_farmer_light_skin_tone"],"1F468-1F3FC-200D-1F33E":["man_farmer_tone2","man_farmer_medium_light_skin_tone"],"1F468-1F3FD-200D-1F33E":["man_farmer_tone3","man_farmer_medium_skin_tone"],"1F468-1F3FE-200D-1F33E":["man_farmer_tone4","man_farmer_medium_dark_skin_tone"],"1F468-1F3FF-200D-1F33E":["man_farmer_tone5","man_farmer_dark_skin_tone"],"1F9D1-200D-1F373":"cook","1F9D1-1F3FB-200D-1F373":["cook_tone1","cook_light_skin_tone"],"1F9D1-1F3FC-200D-1F373":["cook_tone2","cook_medium_light_skin_tone"],"1F9D1-1F3FD-200D-1F373":["cook_tone3","cook_medium_skin_tone"],"1F9D1-1F3FE-200D-1F373":["cook_tone4","cook_medium_dark_skin_tone"],"1F9D1-1F3FF-200D-1F373":["cook_tone5","cook_dark_skin_tone"],"1F469-200D-1F373":"woman_cook","1F469-1F3FB-200D-1F373":["woman_cook_tone1","woman_cook_light_skin_tone"],"1F469-1F3FC-200D-1F373":["woman_cook_tone2","woman_cook_medium_light_skin_tone"],"1F469-1F3FD-200D-1F373":["woman_cook_tone3","woman_cook_medium_skin_tone"],"1F469-1F3FE-200D-1F373":["woman_cook_tone4","woman_cook_medium_dark_skin_tone"],"1F469-1F3FF-200D-1F373":["woman_cook_tone5","woman_cook_dark_skin_tone"],"1F468-200D-1F373":"man_cook","1F468-1F3FB-200D-1F373":["man_cook_tone1","man_cook_light_skin_tone"],"1F468-1F3FC-200D-1F373":["man_cook_tone2","man_cook_medium_light_skin_tone"],"1F468-1F3FD-200D-1F373":["man_cook_tone3","man_cook_medium_skin_tone"],"1F468-1F3FE-200D-1F373":["man_cook_tone4","man_cook_medium_dark_skin_tone"],"1F468-1F3FF-200D-1F373":["man_cook_tone5","man_cook_dark_skin_tone"],"1F9D1-200D-1F393":"student","1F9D1-1F3FB-200D-1F393":["student_tone1","student_light_skin_tone"],"1F9D1-1F3FC-200D-1F393":["student_tone2","student_medium_light_skin_tone"],"1F9D1-1F3FD-200D-1F393":["student_tone3","student_medium_skin_tone"],"1F9D1-1F3FE-200D-1F393":["student_tone4","student_medium_dark_skin_tone"],"1F9D1-1F3FF-200D-1F393":["student_tone5","student_dark_skin_tone"],"1F469-200D-1F393":"woman_student","1F469-1F3FB-200D-1F393":["woman_student_tone1","woman_student_light_skin_tone"],"1F469-1F3FC-200D-1F393":["woman_student_tone2","woman_student_medium_light_skin_tone"],"1F469-1F3FD-200D-1F393":["woman_student_tone3","woman_student_medium_skin_tone"],"1F469-1F3FE-200D-1F393":["woman_student_tone4","woman_student_medium_dark_skin_tone"],"1F469-1F3FF-200D-1F393":["woman_student_tone5","woman_student_dark_skin_tone"],"1F468-200D-1F393":"man_student","1F468-1F3FB-200D-1F393":["man_student_tone1","man_student_light_skin_tone"],"1F468-1F3FC-200D-1F393":["man_student_tone2","man_student_medium_light_skin_tone"],"1F468-1F3FD-200D-1F393":["man_student_tone3","man_student_medium_skin_tone"],"1F468-1F3FE-200D-1F393":["man_student_tone4","man_student_medium_dark_skin_tone"],"1F468-1F3FF-200D-1F393":["man_student_tone5","man_student_dark_skin_tone"],"1F9D1-200D-1F3A4":"singer","1F9D1-1F3FB-200D-1F3A4":["singer_tone1","singer_light_skin_tone"],"1F9D1-1F3FC-200D-1F3A4":["singer_tone2","singer_medium_light_skin_tone"],"1F9D1-1F3FD-200D-1F3A4":["singer_tone3","singer_medium_skin_tone"],"1F9D1-1F3FE-200D-1F3A4":["singer_tone4","singer_medium_dark_skin_tone"],"1F9D1-1F3FF-200D-1F3A4":["singer_tone5","singer_dark_skin_tone"],"1F469-200D-1F3A4":"woman_singer","1F469-1F3FB-200D-1F3A4":["woman_singer_tone1","woman_singer_light_skin_tone"],"1F469-1F3FC-200D-1F3A4":["woman_singer_tone2","woman_singer_medium_light_skin_tone"],"1F469-1F3FD-200D-1F3A4":["woman_singer_tone3","woman_singer_medium_skin_tone"],"1F469-1F3FE-200D-1F3A4":["woman_singer_tone4","woman_singer_medium_dark_skin_tone"],"1F469-1F3FF-200D-1F3A4":["woman_singer_tone5","woman_singer_dark_skin_tone"],"1F468-200D-1F3A4":"man_singer","1F468-1F3FB-200D-1F3A4":["man_singer_tone1","man_singer_light_skin_tone"],"1F468-1F3FC-200D-1F3A4":["man_singer_tone2","man_singer_medium_light_skin_tone"],"1F468-1F3FD-200D-1F3A4":["man_singer_tone3","man_singer_medium_skin_tone"],"1F468-1F3FE-200D-1F3A4":["man_singer_tone4","man_singer_medium_dark_skin_tone"],"1F468-1F3FF-200D-1F3A4":["man_singer_tone5","man_singer_dark_skin_tone"],"1F9D1-200D-1F3EB":"teacher","1F9D1-1F3FB-200D-1F3EB":["teacher_tone1","teacher_light_skin_tone"],"1F9D1-1F3FC-200D-1F3EB":["teacher_tone2","teacher_medium_light_skin_tone"],"1F9D1-1F3FD-200D-1F3EB":["teacher_tone3","teacher_medium_skin_tone"],"1F9D1-1F3FE-200D-1F3EB":["teacher_tone4","teacher_medium_dark_skin_tone"],"1F9D1-1F3FF-200D-1F3EB":["teacher_tone5","teacher_dark_skin_tone"],"1F469-200D-1F3EB":"woman_teacher","1F469-1F3FB-200D-1F3EB":["woman_teacher_tone1","woman_teacher_light_skin_tone"],"1F469-1F3FC-200D-1F3EB":["woman_teacher_tone2","woman_teacher_medium_light_skin_tone"],"1F469-1F3FD-200D-1F3EB":["woman_teacher_tone3","woman_teacher_medium_skin_tone"],"1F469-1F3FE-200D-1F3EB":["woman_teacher_tone4","woman_teacher_medium_dark_skin_tone"],"1F469-1F3FF-200D-1F3EB":["woman_teacher_tone5","woman_teacher_dark_skin_tone"],"1F468-200D-1F3EB":"man_teacher","1F468-1F3FB-200D-1F3EB":["man_teacher_tone1","man_teacher_light_skin_tone"],"1F468-1F3FC-200D-1F3EB":["man_teacher_tone2","man_teacher_medium_light_skin_tone"],"1F468-1F3FD-200D-1F3EB":["man_teacher_tone3","man_teacher_medium_skin_tone"],"1F468-1F3FE-200D-1F3EB":["man_teacher_tone4","man_teacher_medium_dark_skin_tone"],"1F468-1F3FF-200D-1F3EB":["man_teacher_tone5","man_teacher_dark_skin_tone"],"1F9D1-200D-1F3ED":"factory_worker","1F9D1-1F3FB-200D-1F3ED":["factory_worker_tone1","factory_worker_light_skin_tone"],"1F9D1-1F3FC-200D-1F3ED":["factory_worker_tone2","factory_worker_medium_light_skin_tone"],"1F9D1-1F3FD-200D-1F3ED":["factory_worker_tone3","factory_worker_medium_skin_tone"],"1F9D1-1F3FE-200D-1F3ED":["factory_worker_tone4","factory_worker_medium_dark_skin_tone"],"1F9D1-1F3FF-200D-1F3ED":["factory_worker_tone5","factory_worker_dark_skin_tone"],"1F469-200D-1F3ED":"woman_factory_worker","1F469-1F3FB-200D-1F3ED":["woman_factory_worker_tone1","woman_factory_worker_light_skin_tone"],"1F469-1F3FC-200D-1F3ED":["woman_factory_worker_tone2","woman_factory_worker_medium_light_skin_tone"],"1F469-1F3FD-200D-1F3ED":["woman_factory_worker_tone3","woman_factory_worker_medium_skin_tone"],"1F469-1F3FE-200D-1F3ED":["woman_factory_worker_tone4","woman_factory_worker_medium_dark_skin_tone"],"1F469-1F3FF-200D-1F3ED":["woman_factory_worker_tone5","woman_factory_worker_dark_skin_tone"],"1F468-200D-1F3ED":"man_factory_worker","1F468-1F3FB-200D-1F3ED":["man_factory_worker_tone1","man_factory_worker_light_skin_tone"],"1F468-1F3FC-200D-1F3ED":["man_factory_worker_tone2","man_factory_worker_medium_light_skin_tone"],"1F468-1F3FD-200D-1F3ED":["man_factory_worker_tone3","man_factory_worker_medium_skin_tone"],"1F468-1F3FE-200D-1F3ED":["man_factory_worker_tone4","man_factory_worker_medium_dark_skin_tone"],"1F468-1F3FF-200D-1F3ED":["man_factory_worker_tone5","man_factory_worker_dark_skin_tone"],"1F9D1-200D-1F4BB":"technologist","1F9D1-1F3FB-200D-1F4BB":["technologist_tone1","technologist_light_skin_tone"],"1F9D1-1F3FC-200D-1F4BB":["technologist_tone2","technologist_medium_light_skin_tone"],"1F9D1-1F3FD-200D-1F4BB":["technologist_tone3","technologist_medium_skin_tone"],"1F9D1-1F3FE-200D-1F4BB":["technologist_tone4","technologist_medium_dark_skin_tone"],"1F9D1-1F3FF-200D-1F4BB":["technologist_tone5","technologist_dark_skin_tone"],"1F469-200D-1F4BB":"woman_technologist","1F469-1F3FB-200D-1F4BB":["woman_technologist_tone1","woman_technologist_light_skin_tone"],"1F469-1F3FC-200D-1F4BB":["woman_technologist_tone2","woman_technologist_medium_light_skin_tone"],"1F469-1F3FD-200D-1F4BB":["woman_technologist_tone3","woman_technologist_medium_skin_tone"],"1F469-1F3FE-200D-1F4BB":["woman_technologist_tone4","woman_technologist_medium_dark_skin_tone"],"1F469-1F3FF-200D-1F4BB":["woman_technologist_tone5","woman_technologist_dark_skin_tone"],"1F468-200D-1F4BB":"man_technologist","1F468-1F3FB-200D-1F4BB":["man_technologist_tone1","man_technologist_light_skin_tone"],"1F468-1F3FC-200D-1F4BB":["man_technologist_tone2","man_technologist_medium_light_skin_tone"],"1F468-1F3FD-200D-1F4BB":["man_technologist_tone3","man_technologist_medium_skin_tone"],"1F468-1F3FE-200D-1F4BB":["man_technologist_tone4","man_technologist_medium_dark_skin_tone"],"1F468-1F3FF-200D-1F4BB":["man_technologist_tone5","man_technologist_dark_skin_tone"],"1F9D1-200D-1F4BC":"office_worker","1F9D1-1F3FB-200D-1F4BC":["office_worker_tone1","office_worker_light_skin_tone"],"1F9D1-1F3FC-200D-1F4BC":["office_worker_tone2","office_worker_medium_light_skin_tone"],"1F9D1-1F3FD-200D-1F4BC":["office_worker_tone3","office_worker_medium_skin_tone"],"1F9D1-1F3FE-200D-1F4BC":["office_worker_tone4","office_worker_medium_dark_skin_tone"],"1F9D1-1F3FF-200D-1F4BC":["office_worker_tone5","office_worker_dark_skin_tone"],"1F469-200D-1F4BC":"woman_office_worker","1F469-1F3FB-200D-1F4BC":["woman_office_worker_tone1","woman_office_worker_light_skin_tone"],"1F469-1F3FC-200D-1F4BC":["woman_office_worker_tone2","woman_office_worker_medium_light_skin_tone"],"1F469-1F3FD-200D-1F4BC":["woman_office_worker_tone3","woman_office_worker_medium_skin_tone"],"1F469-1F3FE-200D-1F4BC":["woman_office_worker_tone4","woman_office_worker_medium_dark_skin_tone"],"1F469-1F3FF-200D-1F4BC":["woman_office_worker_tone5","woman_office_worker_dark_skin_tone"],"1F468-200D-1F4BC":"man_office_worker","1F468-1F3FB-200D-1F4BC":["man_office_worker_tone1","man_office_worker_light_skin_tone"],"1F468-1F3FC-200D-1F4BC":["man_office_worker_tone2","man_office_worker_medium_light_skin_tone"],"1F468-1F3FD-200D-1F4BC":["man_office_worker_tone3","man_office_worker_medium_skin_tone"],"1F468-1F3FE-200D-1F4BC":["man_office_worker_tone4","man_office_worker_medium_dark_skin_tone"],"1F468-1F3FF-200D-1F4BC":["man_office_worker_tone5","man_office_worker_dark_skin_tone"],"1F9D1-200D-1F527":"mechanic","1F9D1-1F3FB-200D-1F527":["mechanic_tone1","mechanic_light_skin_tone"],"1F9D1-1F3FC-200D-1F527":["mechanic_tone2","mechanic_medium_light_skin_tone"],"1F9D1-1F3FD-200D-1F527":["mechanic_tone3","mechanic_medium_skin_tone"],"1F9D1-1F3FE-200D-1F527":["mechanic_tone4","mechanic_medium_dark_skin_tone"],"1F9D1-1F3FF-200D-1F527":["mechanic_tone5","mechanic_dark_skin_tone"],"1F469-200D-1F527":"woman_mechanic","1F469-1F3FB-200D-1F527":["woman_mechanic_tone1","woman_mechanic_light_skin_tone"],"1F469-1F3FC-200D-1F527":["woman_mechanic_tone2","woman_mechanic_medium_light_skin_tone"],"1F469-1F3FD-200D-1F527":["woman_mechanic_tone3","woman_mechanic_medium_skin_tone"],"1F469-1F3FE-200D-1F527":["woman_mechanic_tone4","woman_mechanic_medium_dark_skin_tone"],"1F469-1F3FF-200D-1F527":["woman_mechanic_tone5","woman_mechanic_dark_skin_tone"],"1F468-200D-1F527":"man_mechanic","1F468-1F3FB-200D-1F527":["man_mechanic_tone1","man_mechanic_light_skin_tone"],"1F468-1F3FC-200D-1F527":["man_mechanic_tone2","man_mechanic_medium_light_skin_tone"],"1F468-1F3FD-200D-1F527":["man_mechanic_tone3","man_mechanic_medium_skin_tone"],"1F468-1F3FE-200D-1F527":["man_mechanic_tone4","man_mechanic_medium_dark_skin_tone"],"1F468-1F3FF-200D-1F527":["man_mechanic_tone5","man_mechanic_dark_skin_tone"],"1F9D1-200D-1F52C":"scientist","1F9D1-1F3FB-200D-1F52C":["scientist_tone1","scientist_light_skin_tone"],"1F9D1-1F3FC-200D-1F52C":["scientist_tone2","scientist_medium_light_skin_tone"],"1F9D1-1F3FD-200D-1F52C":["scientist_tone3","scientist_medium_skin_tone"],"1F9D1-1F3FE-200D-1F52C":["scientist_tone4","scientist_medium_dark_skin_tone"],"1F9D1-1F3FF-200D-1F52C":["scientist_tone5","scientist_dark_skin_tone"],"1F469-200D-1F52C":"woman_scientist","1F469-1F3FB-200D-1F52C":["woman_scientist_tone1","woman_scientist_light_skin_tone"],"1F469-1F3FC-200D-1F52C":["woman_scientist_tone2","woman_scientist_medium_light_skin_tone"],"1F469-1F3FD-200D-1F52C":["woman_scientist_tone3","woman_scientist_medium_skin_tone"],"1F469-1F3FE-200D-1F52C":["woman_scientist_tone4","woman_scientist_medium_dark_skin_tone"],"1F469-1F3FF-200D-1F52C":["woman_scientist_tone5","woman_scientist_dark_skin_tone"],"1F468-200D-1F52C":"man_scientist","1F468-1F3FB-200D-1F52C":["man_scientist_tone1","man_scientist_light_skin_tone"],"1F468-1F3FC-200D-1F52C":["man_scientist_tone2","man_scientist_medium_light_skin_tone"],"1F468-1F3FD-200D-1F52C":["man_scientist_tone3","man_scientist_medium_skin_tone"],"1F468-1F3FE-200D-1F52C":["man_scientist_tone4","man_scientist_medium_dark_skin_tone"],"1F468-1F3FF-200D-1F52C":["man_scientist_tone5","man_scientist_dark_skin_tone"],"1F9D1-200D-1F3A8":"artist","1F9D1-1F3FB-200D-1F3A8":["artist_tone1","artist_light_skin_tone"],"1F9D1-1F3FC-200D-1F3A8":["artist_tone2","artist_medium_light_skin_tone"],"1F9D1-1F3FD-200D-1F3A8":["artist_tone3","artist_medium_skin_tone"],"1F9D1-1F3FE-200D-1F3A8":["artist_tone4","artist_medium_dark_skin_tone"],"1F9D1-1F3FF-200D-1F3A8":["artist_tone5","artist_dark_skin_tone"],"1F469-200D-1F3A8":"woman_artist","1F469-1F3FB-200D-1F3A8":["woman_artist_tone1","woman_artist_light_skin_tone"],"1F469-1F3FC-200D-1F3A8":["woman_artist_tone2","woman_artist_medium_light_skin_tone"],"1F469-1F3FD-200D-1F3A8":["woman_artist_tone3","woman_artist_medium_skin_tone"],"1F469-1F3FE-200D-1F3A8":["woman_artist_tone4","woman_artist_medium_dark_skin_tone"],"1F469-1F3FF-200D-1F3A8":["woman_artist_tone5","woman_artist_dark_skin_tone"],"1F468-200D-1F3A8":"man_artist","1F468-1F3FB-200D-1F3A8":["man_artist_tone1","man_artist_light_skin_tone"],"1F468-1F3FC-200D-1F3A8":["man_artist_tone2","man_artist_medium_light_skin_tone"],"1F468-1F3FD-200D-1F3A8":["man_artist_tone3","man_artist_medium_skin_tone"],"1F468-1F3FE-200D-1F3A8":["man_artist_tone4","man_artist_medium_dark_skin_tone"],"1F468-1F3FF-200D-1F3A8":["man_artist_tone5","man_artist_dark_skin_tone"],"1F9D1-200D-1F692":"firefighter","1F9D1-1F3FB-200D-1F692":["firefighter_tone1","firefighter_light_skin_tone"],"1F9D1-1F3FC-200D-1F692":["firefighter_tone2","firefighter_medium_light_skin_tone"],"1F9D1-1F3FD-200D-1F692":["firefighter_tone3","firefighter_medium_skin_tone"],"1F9D1-1F3FE-200D-1F692":["firefighter_tone4","firefighter_medium_dark_skin_tone"],"1F9D1-1F3FF-200D-1F692":["firefighter_tone5","firefighter_dark_skin_tone"],"1F469-200D-1F692":"woman_firefighter","1F469-1F3FB-200D-1F692":["woman_firefighter_tone1","woman_firefighter_light_skin_tone"],"1F469-1F3FC-200D-1F692":["woman_firefighter_tone2","woman_firefighter_medium_light_skin_tone"],"1F469-1F3FD-200D-1F692":["woman_firefighter_tone3","woman_firefighter_medium_skin_tone"],"1F469-1F3FE-200D-1F692":["woman_firefighter_tone4","woman_firefighter_medium_dark_skin_tone"],"1F469-1F3FF-200D-1F692":["woman_firefighter_tone5","woman_firefighter_dark_skin_tone"],"1F468-200D-1F692":"man_firefighter","1F468-1F3FB-200D-1F692":["man_firefighter_tone1","man_firefighter_light_skin_tone"],"1F468-1F3FC-200D-1F692":["man_firefighter_tone2","man_firefighter_medium_light_skin_tone"],"1F468-1F3FD-200D-1F692":["man_firefighter_tone3","man_firefighter_medium_skin_tone"],"1F468-1F3FE-200D-1F692":["man_firefighter_tone4","man_firefighter_medium_dark_skin_tone"],"1F468-1F3FF-200D-1F692":["man_firefighter_tone5","man_firefighter_dark_skin_tone"],"1F9D1-200D-2708-FE0F":"pilot","1F9D1-1F3FB-200D-2708-FE0F":["pilot_tone1","pilot_light_skin_tone"],"1F9D1-1F3FC-200D-2708-FE0F":["pilot_tone2","pilot_medium_light_skin_tone"],"1F9D1-1F3FD-200D-2708-FE0F":["pilot_tone3","pilot_medium_skin_tone"],"1F9D1-1F3FE-200D-2708-FE0F":["pilot_tone4","pilot_medium_dark_skin_tone"],"1F9D1-1F3FF-200D-2708-FE0F":["pilot_tone5","pilot_dark_skin_tone"],"1F469-200D-2708-FE0F":"woman_pilot","1F469-1F3FB-200D-2708-FE0F":["woman_pilot_tone1","woman_pilot_light_skin_tone"],"1F469-1F3FC-200D-2708-FE0F":["woman_pilot_tone2","woman_pilot_medium_light_skin_tone"],"1F469-1F3FD-200D-2708-FE0F":["woman_pilot_tone3","woman_pilot_medium_skin_tone"],"1F469-1F3FE-200D-2708-FE0F":["woman_pilot_tone4","woman_pilot_medium_dark_skin_tone"],"1F469-1F3FF-200D-2708-FE0F":["woman_pilot_tone5","woman_pilot_dark_skin_tone"],"1F468-200D-2708-FE0F":"man_pilot","1F468-1F3FB-200D-2708-FE0F":["man_pilot_tone1","man_pilot_light_skin_tone"],"1F468-1F3FC-200D-2708-FE0F":["man_pilot_tone2","man_pilot_medium_light_skin_tone"],"1F468-1F3FD-200D-2708-FE0F":["man_pilot_tone3","man_pilot_medium_skin_tone"],"1F468-1F3FE-200D-2708-FE0F":["man_pilot_tone4","man_pilot_medium_dark_skin_tone"],"1F468-1F3FF-200D-2708-FE0F":["man_pilot_tone5","man_pilot_dark_skin_tone"],"1F9D1-200D-1F680":"astronaut","1F9D1-1F3FB-200D-1F680":["astronaut_tone1","astronaut_light_skin_tone"],"1F9D1-1F3FC-200D-1F680":["astronaut_tone2","astronaut_medium_light_skin_tone"],"1F9D1-1F3FD-200D-1F680":["astronaut_tone3","astronaut_medium_skin_tone"],"1F9D1-1F3FE-200D-1F680":["astronaut_tone4","astronaut_medium_dark_skin_tone"],"1F9D1-1F3FF-200D-1F680":["astronaut_tone5","astronaut_dark_skin_tone"],"1F469-200D-1F680":"woman_astronaut","1F469-1F3FB-200D-1F680":["woman_astronaut_tone1","woman_astronaut_light_skin_tone"],"1F469-1F3FC-200D-1F680":["woman_astronaut_tone2","woman_astronaut_medium_light_skin_tone"],"1F469-1F3FD-200D-1F680":["woman_astronaut_tone3","woman_astronaut_medium_skin_tone"],"1F469-1F3FE-200D-1F680":["woman_astronaut_tone4","woman_astronaut_medium_dark_skin_tone"],"1F469-1F3FF-200D-1F680":["woman_astronaut_tone5","woman_astronaut_dark_skin_tone"],"1F468-200D-1F680":"man_astronaut","1F468-1F3FB-200D-1F680":["man_astronaut_tone1","man_astronaut_light_skin_tone"],"1F468-1F3FC-200D-1F680":["man_astronaut_tone2","man_astronaut_medium_light_skin_tone"],"1F468-1F3FD-200D-1F680":["man_astronaut_tone3","man_astronaut_medium_skin_tone"],"1F468-1F3FE-200D-1F680":["man_astronaut_tone4","man_astronaut_medium_dark_skin_tone"],"1F468-1F3FF-200D-1F680":["man_astronaut_tone5","man_astronaut_dark_skin_tone"],"1F9D1-200D-2696-FE0F":"judge","1F9D1-1F3FB-200D-2696-FE0F":["judge_tone1","judge_light_skin_tone"],"1F9D1-1F3FC-200D-2696-FE0F":["judge_tone2","judge_medium_light_skin_tone"],"1F9D1-1F3FD-200D-2696-FE0F":["judge_tone3","judge_medium_skin_tone"],"1F9D1-1F3FE-200D-2696-FE0F":["judge_tone4","judge_medium_dark_skin_tone"],"1F9D1-1F3FF-200D-2696-FE0F":["judge_tone5","judge_dark_skin_tone"],"1F469-200D-2696-FE0F":"woman_judge","1F469-1F3FB-200D-2696-FE0F":["woman_judge_tone1","woman_judge_light_skin_tone"],"1F469-1F3FC-200D-2696-FE0F":["woman_judge_tone2","woman_judge_medium_light_skin_tone"],"1F469-1F3FD-200D-2696-FE0F":["woman_judge_tone3","woman_judge_medium_skin_tone"],"1F469-1F3FE-200D-2696-FE0F":["woman_judge_tone4","woman_judge_medium_dark_skin_tone"],"1F469-1F3FF-200D-2696-FE0F":["woman_judge_tone5","woman_judge_dark_skin_tone"],"1F468-200D-2696-FE0F":"man_judge","1F468-1F3FB-200D-2696-FE0F":["man_judge_tone1","man_judge_light_skin_tone"],"1F468-1F3FC-200D-2696-FE0F":["man_judge_tone2","man_judge_medium_light_skin_tone"],"1F468-1F3FD-200D-2696-FE0F":["man_judge_tone3","man_judge_medium_skin_tone"],"1F468-1F3FE-200D-2696-FE0F":["man_judge_tone4","man_judge_medium_dark_skin_tone"],"1F468-1F3FF-200D-2696-FE0F":["man_judge_tone5","man_judge_dark_skin_tone"],"1F470":"person_with_veil","1F470-1F3FB":"person_with_veil_tone1","1F470-1F3FC":"person_with_veil_tone2","1F470-1F3FD":"person_with_veil_tone3","1F470-1F3FE":"person_with_veil_tone4","1F470-1F3FF":"person_with_veil_tone5","1F470-200D-2640-FE0F":"woman_with_veil","1F470-1F3FB-200D-2640-FE0F":["woman_with_veil_tone1","woman_with_veil_light_skin_tone"],"1F470-1F3FC-200D-2640-FE0F":["woman_with_veil_tone2","woman_with_veil_medium_light_skin_tone"],"1F470-1F3FD-200D-2640-FE0F":["woman_with_veil_tone3","woman_with_veil_medium_skin_tone"],"1F470-1F3FE-200D-2640-FE0F":["woman_with_veil_tone4","woman_with_veil_medium_dark_skin_tone"],"1F470-1F3FF-200D-2640-FE0F":["woman_with_veil_tone5","woman_with_veil_dark_skin_tone"],"1F470-200D-2642-FE0F":"man_with_veil","1F470-1F3FB-200D-2642-FE0F":["man_with_veil_tone1","man_with_veil_light_skin_tone"],"1F470-1F3FC-200D-2642-FE0F":["man_with_veil_tone2","man_with_veil_medium_light_skin_tone"],"1F470-1F3FD-200D-2642-FE0F":["man_with_veil_tone3","man_with_veil_medium_skin_tone"],"1F470-1F3FE-200D-2642-FE0F":["man_with_veil_tone4","man_with_veil_medium_dark_skin_tone"],"1F470-1F3FF-200D-2642-FE0F":["man_with_veil_tone5","man_with_veil_dark_skin_tone"],"1F935":"person_in_tuxedo","1F935-1F3FB":["person_in_tuxedo_tone1","tuxedo_tone1"],"1F935-1F3FC":["person_in_tuxedo_tone2","tuxedo_tone2"],"1F935-1F3FD":["person_in_tuxedo_tone3","tuxedo_tone3"],"1F935-1F3FE":["person_in_tuxedo_tone4","tuxedo_tone4"],"1F935-1F3FF":["person_in_tuxedo_tone5","tuxedo_tone5"],"1F935-200D-2640-FE0F":"woman_in_tuxedo","1F935-1F3FB-200D-2640-FE0F":["woman_in_tuxedo_tone1","woman_in_tuxedo_light_skin_tone"],"1F935-1F3FC-200D-2640-FE0F":["woman_in_tuxedo_tone2","woman_in_tuxedo_medium_light_skin_tone"],"1F935-1F3FD-200D-2640-FE0F":["woman_in_tuxedo_tone3","woman_in_tuxedo_medium_skin_tone"],"1F935-1F3FE-200D-2640-FE0F":["woman_in_tuxedo_tone4","woman_in_tuxedo_medium_dark_skin_tone"],"1F935-1F3FF-200D-2640-FE0F":["woman_in_tuxedo_tone5","woman_in_tuxedo_dark_skin_tone"],"1F935-200D-2642-FE0F":"man_in_tuxedo","1F935-1F3FB-200D-2642-FE0F":["man_in_tuxedo_tone1","man_in_tuxedo_light_skin_tone"],"1F935-1F3FC-200D-2642-FE0F":["man_in_tuxedo_tone2","man_in_tuxedo_medium_light_skin_tone"],"1F935-1F3FD-200D-2642-FE0F":["man_in_tuxedo_tone3","man_in_tuxedo_medium_skin_tone"],"1F935-1F3FE-200D-2642-FE0F":["man_in_tuxedo_tone4","man_in_tuxedo_medium_dark_skin_tone"],"1F935-1F3FF-200D-2642-FE0F":["man_in_tuxedo_tone5","man_in_tuxedo_dark_skin_tone"],"1F478":"princess","1F478-1F3FB":"princess_tone1","1F478-1F3FC":"princess_tone2","1F478-1F3FD":"princess_tone3","1F478-1F3FE":"princess_tone4","1F478-1F3FF":"princess_tone5","1F934":"prince","1F934-1F3FB":"prince_tone1","1F934-1F3FC":"prince_tone2","1F934-1F3FD":"prince_tone3","1F934-1F3FE":"prince_tone4","1F934-1F3FF":"prince_tone5","1F9B8":"superhero","1F9B8-1F3FB":["superhero_tone1","superhero_light_skin_tone"],"1F9B8-1F3FC":["superhero_tone2","superhero_medium_light_skin_tone"],"1F9B8-1F3FD":["superhero_tone3","superhero_medium_skin_tone"],"1F9B8-1F3FE":["superhero_tone4","superhero_medium_dark_skin_tone"],"1F9B8-1F3FF":["superhero_tone5","superhero_dark_skin_tone"],"1F9B8-200D-2640-FE0F":"woman_superhero","1F9B8-1F3FB-200D-2640-FE0F":["woman_superhero_tone1","woman_superhero_light_skin_tone"],"1F9B8-1F3FC-200D-2640-FE0F":["woman_superhero_tone2","woman_superhero_medium_light_skin_tone"],"1F9B8-1F3FD-200D-2640-FE0F":["woman_superhero_tone3","woman_superhero_medium_skin_tone"],"1F9B8-1F3FE-200D-2640-FE0F":["woman_superhero_tone4","woman_superhero_medium_dark_skin_tone"],"1F9B8-1F3FF-200D-2640-FE0F":["woman_superhero_tone5","woman_superhero_dark_skin_tone"],"1F9B8-200D-2642-FE0F":"man_superhero","1F9B8-1F3FB-200D-2642-FE0F":["man_superhero_tone1","man_superhero_light_skin_tone"],"1F9B8-1F3FC-200D-2642-FE0F":["man_superhero_tone2","man_superhero_medium_light_skin_tone"],"1F9B8-1F3FD-200D-2642-FE0F":["man_superhero_tone3","man_superhero_medium_skin_tone"],"1F9B8-1F3FE-200D-2642-FE0F":["man_superhero_tone4","man_superhero_medium_dark_skin_tone"],"1F9B8-1F3FF-200D-2642-FE0F":["man_superhero_tone5","man_superhero_dark_skin_tone"],"1F9B9":"supervillain","1F9B9-1F3FB":["supervillain_tone1","supervillain_light_skin_tone"],"1F9B9-1F3FC":["supervillain_tone2","supervillain_medium_light_skin_tone"],"1F9B9-1F3FD":["supervillain_tone3","supervillain_medium_skin_tone"],"1F9B9-1F3FE":["supervillain_tone4","supervillain_medium_dark_skin_tone"],"1F9B9-1F3FF":["supervillain_tone5","supervillain_dark_skin_tone"],"1F9B9-200D-2640-FE0F":"woman_supervillain","1F9B9-1F3FB-200D-2640-FE0F":["woman_supervillain_tone1","woman_supervillain_light_skin_tone"],"1F9B9-1F3FC-200D-2640-FE0F":["woman_supervillain_tone2","woman_supervillain_medium_light_skin_tone"],"1F9B9-1F3FD-200D-2640-FE0F":["woman_supervillain_tone3","woman_supervillain_medium_skin_tone"],"1F9B9-1F3FE-200D-2640-FE0F":["woman_supervillain_tone4","woman_supervillain_medium_dark_skin_tone"],"1F9B9-1F3FF-200D-2640-FE0F":["woman_supervillain_tone5","woman_supervillain_dark_skin_tone"],"1F9B9-200D-2642-FE0F":"man_supervillain","1F9B9-1F3FB-200D-2642-FE0F":["man_supervillain_tone1","man_supervillain_light_skin_tone"],"1F9B9-1F3FC-200D-2642-FE0F":["man_supervillain_tone2","man_supervillain_medium_light_skin_tone"],"1F9B9-1F3FD-200D-2642-FE0F":["man_supervillain_tone3","man_supervillain_medium_skin_tone"],"1F9B9-1F3FE-200D-2642-FE0F":["man_supervillain_tone4","man_supervillain_medium_dark_skin_tone"],"1F9B9-1F3FF-200D-2642-FE0F":["man_supervillain_tone5","man_supervillain_dark_skin_tone"],"1F977":"ninja","1F977-1F3FB":["ninja_tone1","ninja_light_skin_tone"],"1F977-1F3FC":["ninja_tone2","ninja_medium_light_skin_tone"],"1F977-1F3FD":["ninja_tone3","ninja_medium_skin_tone"],"1F977-1F3FE":["ninja_tone4","ninja_medium_dark_skin_tone"],"1F977-1F3FF":["ninja_tone5","ninja_dark_skin_tone"],"1F9D1-200D-1F384":"mx_claus","1F9D1-1F3FB-200D-1F384":["mx_claus_tone1","mx_claus_light_skin_tone"],"1F9D1-1F3FC-200D-1F384":["mx_claus_tone2","mx_claus_medium_light_skin_tone"],"1F9D1-1F3FD-200D-1F384":["mx_claus_tone3","mx_claus_medium_skin_tone"],"1F9D1-1F3FE-200D-1F384":["mx_claus_tone4","mx_claus_medium_dark_skin_tone"],"1F9D1-1F3FF-200D-1F384":["mx_claus_tone5","mx_claus_dark_skin_tone"],"1F936":["mrs_claus","mother_christmas"],"1F936-1F3FB":["mrs_claus_tone1","mother_christmas_tone1"],"1F936-1F3FC":["mrs_claus_tone2","mother_christmas_tone2"],"1F936-1F3FD":["mrs_claus_tone3","mother_christmas_tone3"],"1F936-1F3FE":["mrs_claus_tone4","mother_christmas_tone4"],"1F936-1F3FF":["mrs_claus_tone5","mother_christmas_tone5"],"1F385":"santa","1F385-1F3FB":"santa_tone1","1F385-1F3FC":"santa_tone2","1F385-1F3FD":"santa_tone3","1F385-1F3FE":"santa_tone4","1F385-1F3FF":"santa_tone5","1F9D9":"mage","1F9D9-1F3FB":["mage_tone1","mage_light_skin_tone"],"1F9D9-1F3FC":["mage_tone2","mage_medium_light_skin_tone"],"1F9D9-1F3FD":["mage_tone3","mage_medium_skin_tone"],"1F9D9-1F3FE":["mage_tone4","mage_medium_dark_skin_tone"],"1F9D9-1F3FF":["mage_tone5","mage_dark_skin_tone"],"1F9D9-200D-2640-FE0F":"woman_mage","1F9D9-1F3FB-200D-2640-FE0F":["woman_mage_tone1","woman_mage_light_skin_tone"],"1F9D9-1F3FC-200D-2640-FE0F":["woman_mage_tone2","woman_mage_medium_light_skin_tone"],"1F9D9-1F3FD-200D-2640-FE0F":["woman_mage_tone3","woman_mage_medium_skin_tone"],"1F9D9-1F3FE-200D-2640-FE0F":["woman_mage_tone4","woman_mage_medium_dark_skin_tone"],"1F9D9-1F3FF-200D-2640-FE0F":["woman_mage_tone5","woman_mage_dark_skin_tone"],"1F9D9-200D-2642-FE0F":"man_mage","1F9D9-1F3FB-200D-2642-FE0F":["man_mage_tone1","man_mage_light_skin_tone"],"1F9D9-1F3FC-200D-2642-FE0F":["man_mage_tone2","man_mage_medium_light_skin_tone"],"1F9D9-1F3FD-200D-2642-FE0F":["man_mage_tone3","man_mage_medium_skin_tone"],"1F9D9-1F3FE-200D-2642-FE0F":["man_mage_tone4","man_mage_medium_dark_skin_tone"],"1F9D9-1F3FF-200D-2642-FE0F":["man_mage_tone5","man_mage_dark_skin_tone"],"1F9DD":"elf","1F9DD-1F3FB":["elf_tone1","elf_light_skin_tone"],"1F9DD-1F3FC":["elf_tone2","elf_medium_light_skin_tone"],"1F9DD-1F3FD":["elf_tone3","elf_medium_skin_tone"],"1F9DD-1F3FE":["elf_tone4","elf_medium_dark_skin_tone"],"1F9DD-1F3FF":["elf_tone5","elf_dark_skin_tone"],"1F9DD-200D-2640-FE0F":"woman_elf","1F9DD-1F3FB-200D-2640-FE0F":["woman_elf_tone1","woman_elf_light_skin_tone"],"1F9DD-1F3FC-200D-2640-FE0F":["woman_elf_tone2","woman_elf_medium_light_skin_tone"],"1F9DD-1F3FD-200D-2640-FE0F":["woman_elf_tone3","woman_elf_medium_skin_tone"],"1F9DD-1F3FE-200D-2640-FE0F":["woman_elf_tone4","woman_elf_medium_dark_skin_tone"],"1F9DD-1F3FF-200D-2640-FE0F":["woman_elf_tone5","woman_elf_dark_skin_tone"],"1F9DD-200D-2642-FE0F":"man_elf","1F9DD-1F3FB-200D-2642-FE0F":["man_elf_tone1","man_elf_light_skin_tone"],"1F9DD-1F3FC-200D-2642-FE0F":["man_elf_tone2","man_elf_medium_light_skin_tone"],"1F9DD-1F3FD-200D-2642-FE0F":["man_elf_tone3","man_elf_medium_skin_tone"],"1F9DD-1F3FE-200D-2642-FE0F":["man_elf_tone4","man_elf_medium_dark_skin_tone"],"1F9DD-1F3FF-200D-2642-FE0F":["man_elf_tone5","man_elf_dark_skin_tone"],"1F9DB":"vampire","1F9DB-1F3FB":["vampire_tone1","vampire_light_skin_tone"],"1F9DB-1F3FC":["vampire_tone2","vampire_medium_light_skin_tone"],"1F9DB-1F3FD":["vampire_tone3","vampire_medium_skin_tone"],"1F9DB-1F3FE":["vampire_tone4","vampire_medium_dark_skin_tone"],"1F9DB-1F3FF":["vampire_tone5","vampire_dark_skin_tone"],"1F9DB-200D-2640-FE0F":"woman_vampire","1F9DB-1F3FB-200D-2640-FE0F":["woman_vampire_tone1","woman_vampire_light_skin_tone"],"1F9DB-1F3FC-200D-2640-FE0F":["woman_vampire_tone2","woman_vampire_medium_light_skin_tone"],"1F9DB-1F3FD-200D-2640-FE0F":["woman_vampire_tone3","woman_vampire_medium_skin_tone"],"1F9DB-1F3FE-200D-2640-FE0F":["woman_vampire_tone4","woman_vampire_medium_dark_skin_tone"],"1F9DB-1F3FF-200D-2640-FE0F":["woman_vampire_tone5","woman_vampire_dark_skin_tone"],"1F9DB-200D-2642-FE0F":"man_vampire","1F9DB-1F3FB-200D-2642-FE0F":["man_vampire_tone1","man_vampire_light_skin_tone"],"1F9DB-1F3FC-200D-2642-FE0F":["man_vampire_tone2","man_vampire_medium_light_skin_tone"],"1F9DB-1F3FD-200D-2642-FE0F":["man_vampire_tone3","man_vampire_medium_skin_tone"],"1F9DB-1F3FE-200D-2642-FE0F":["man_vampire_tone4","man_vampire_medium_dark_skin_tone"],"1F9DB-1F3FF-200D-2642-FE0F":["man_vampire_tone5","man_vampire_dark_skin_tone"],"1F9DF":"zombie","1F9DF-200D-2640-FE0F":"woman_zombie","1F9DF-200D-2642-FE0F":"man_zombie","1F9DE":"genie","1F9DE-200D-2640-FE0F":"woman_genie","1F9DE-200D-2642-FE0F":"man_genie","1F9DC":"merperson","1F9DC-1F3FB":["merperson_tone1","merperson_light_skin_tone"],"1F9DC-1F3FC":["merperson_tone2","merperson_medium_light_skin_tone"],"1F9DC-1F3FD":["merperson_tone3","merperson_medium_skin_tone"],"1F9DC-1F3FE":["merperson_tone4","merperson_medium_dark_skin_tone"],"1F9DC-1F3FF":["merperson_tone5","merperson_dark_skin_tone"],"1F9DC-200D-2640-FE0F":"mermaid","1F9DC-1F3FB-200D-2640-FE0F":["mermaid_tone1","mermaid_light_skin_tone"],"1F9DC-1F3FC-200D-2640-FE0F":["mermaid_tone2","mermaid_medium_light_skin_tone"],"1F9DC-1F3FD-200D-2640-FE0F":["mermaid_tone3","mermaid_medium_skin_tone"],"1F9DC-1F3FE-200D-2640-FE0F":["mermaid_tone4","mermaid_medium_dark_skin_tone"],"1F9DC-1F3FF-200D-2640-FE0F":["mermaid_tone5","mermaid_dark_skin_tone"],"1F9DC-200D-2642-FE0F":"merman","1F9DC-1F3FB-200D-2642-FE0F":["merman_tone1","merman_light_skin_tone"],"1F9DC-1F3FC-200D-2642-FE0F":["merman_tone2","merman_medium_light_skin_tone"],"1F9DC-1F3FD-200D-2642-FE0F":["merman_tone3","merman_medium_skin_tone"],"1F9DC-1F3FE-200D-2642-FE0F":["merman_tone4","merman_medium_dark_skin_tone"],"1F9DC-1F3FF-200D-2642-FE0F":["merman_tone5","merman_dark_skin_tone"],"1F9DA":"fairy","1F9DA-1F3FB":["fairy_tone1","fairy_light_skin_tone"],"1F9DA-1F3FC":["fairy_tone2","fairy_medium_light_skin_tone"],"1F9DA-1F3FD":["fairy_tone3","fairy_medium_skin_tone"],"1F9DA-1F3FE":["fairy_tone4","fairy_medium_dark_skin_tone"],"1F9DA-1F3FF":["fairy_tone5","fairy_dark_skin_tone"],"1F9DA-200D-2640-FE0F":"woman_fairy","1F9DA-1F3FB-200D-2640-FE0F":["woman_fairy_tone1","woman_fairy_light_skin_tone"],"1F9DA-1F3FC-200D-2640-FE0F":["woman_fairy_tone2","woman_fairy_medium_light_skin_tone"],"1F9DA-1F3FD-200D-2640-FE0F":["woman_fairy_tone3","woman_fairy_medium_skin_tone"],"1F9DA-1F3FE-200D-2640-FE0F":["woman_fairy_tone4","woman_fairy_medium_dark_skin_tone"],"1F9DA-1F3FF-200D-2640-FE0F":["woman_fairy_tone5","woman_fairy_dark_skin_tone"],"1F9DA-200D-2642-FE0F":"man_fairy","1F9DA-1F3FB-200D-2642-FE0F":["man_fairy_tone1","man_fairy_light_skin_tone"],"1F9DA-1F3FC-200D-2642-FE0F":["man_fairy_tone2","man_fairy_medium_light_skin_tone"],"1F9DA-1F3FD-200D-2642-FE0F":["man_fairy_tone3","man_fairy_medium_skin_tone"],"1F9DA-1F3FE-200D-2642-FE0F":["man_fairy_tone4","man_fairy_medium_dark_skin_tone"],"1F9DA-1F3FF-200D-2642-FE0F":["man_fairy_tone5","man_fairy_dark_skin_tone"],"1F47C":"angel","1F47C-1F3FB":"angel_tone1","1F47C-1F3FC":"angel_tone2","1F47C-1F3FD":"angel_tone3","1F47C-1F3FE":"angel_tone4","1F47C-1F3FF":"angel_tone5","1F930":["pregnant_woman","expecting_woman"],"1F930-1F3FB":["pregnant_woman_tone1","expecting_woman_tone1"],"1F930-1F3FC":["pregnant_woman_tone2","expecting_woman_tone2"],"1F930-1F3FD":["pregnant_woman_tone3","expecting_woman_tone3"],"1F930-1F3FE":["pregnant_woman_tone4","expecting_woman_tone4"],"1F930-1F3FF":["pregnant_woman_tone5","expecting_woman_tone5"],"1F931":"breast_feeding","1F931-1F3FB":["breast_feeding_tone1","breast_feeding_light_skin_tone"],"1F931-1F3FC":["breast_feeding_tone2","breast_feeding_medium_light_skin_tone"],"1F931-1F3FD":["breast_feeding_tone3","breast_feeding_medium_skin_tone"],"1F931-1F3FE":["breast_feeding_tone4","breast_feeding_medium_dark_skin_tone"],"1F931-1F3FF":["breast_feeding_tone5","breast_feeding_dark_skin_tone"],"1F9D1-200D-1F37C":"person_feeding_baby","1F9D1-1F3FB-200D-1F37C":["person_feeding_baby_tone1","person_feeding_baby_light_skin_tone"],"1F9D1-1F3FC-200D-1F37C":["person_feeding_baby_tone2","person_feeding_baby_medium_light_skin_tone"],"1F9D1-1F3FD-200D-1F37C":["person_feeding_baby_tone3","person_feeding_baby_medium_skin_tone"],"1F9D1-1F3FE-200D-1F37C":["person_feeding_baby_tone4","person_feeding_baby_medium_dark_skin_tone"],"1F9D1-1F3FF-200D-1F37C":["person_feeding_baby_tone5","person_feeding_baby_dark_skin_tone"],"1F469-200D-1F37C":"woman_feeding_baby","1F469-1F3FB-200D-1F37C":["woman_feeding_baby_tone1","woman_feeding_baby_light_skin_tone"],"1F469-1F3FC-200D-1F37C":["woman_feeding_baby_tone2","woman_feeding_baby_medium_light_skin_tone"],"1F469-1F3FD-200D-1F37C":["woman_feeding_baby_tone3","woman_feeding_baby_medium_skin_tone"],"1F469-1F3FE-200D-1F37C":["woman_feeding_baby_tone4","woman_feeding_baby_medium_dark_skin_tone"],"1F469-1F3FF-200D-1F37C":["woman_feeding_baby_tone5","woman_feeding_baby_dark_skin_tone"],"1F468-200D-1F37C":"man_feeding_baby","1F468-1F3FB-200D-1F37C":["man_feeding_baby_tone1","man_feeding_baby_light_skin_tone"],"1F468-1F3FC-200D-1F37C":["man_feeding_baby_tone2","man_feeding_baby_medium_light_skin_tone"],"1F468-1F3FD-200D-1F37C":["man_feeding_baby_tone3","man_feeding_baby_medium_skin_tone"],"1F468-1F3FE-200D-1F37C":["man_feeding_baby_tone4","man_feeding_baby_medium_dark_skin_tone"],"1F468-1F3FF-200D-1F37C":["man_feeding_baby_tone5","man_feeding_baby_dark_skin_tone"],"1F647":["person_bowing","bow"],"1F647-1F3FB":["person_bowing_tone1","bow_tone1"],"1F647-1F3FC":["person_bowing_tone2","bow_tone2"],"1F647-1F3FD":["person_bowing_tone3","bow_tone3"],"1F647-1F3FE":["person_bowing_tone4","bow_tone4"],"1F647-1F3FF":["person_bowing_tone5","bow_tone5"],"1F647-200D-2640-FE0F":"woman_bowing","1F647-1F3FB-200D-2640-FE0F":["woman_bowing_tone1","woman_bowing_light_skin_tone"],"1F647-1F3FC-200D-2640-FE0F":["woman_bowing_tone2","woman_bowing_medium_light_skin_tone"],"1F647-1F3FD-200D-2640-FE0F":["woman_bowing_tone3","woman_bowing_medium_skin_tone"],"1F647-1F3FE-200D-2640-FE0F":["woman_bowing_tone4","woman_bowing_medium_dark_skin_tone"],"1F647-1F3FF-200D-2640-FE0F":["woman_bowing_tone5","woman_bowing_dark_skin_tone"],"1F647-200D-2642-FE0F":"man_bowing","1F647-1F3FB-200D-2642-FE0F":["man_bowing_tone1","man_bowing_light_skin_tone"],"1F647-1F3FC-200D-2642-FE0F":["man_bowing_tone2","man_bowing_medium_light_skin_tone"],"1F647-1F3FD-200D-2642-FE0F":["man_bowing_tone3","man_bowing_medium_skin_tone"],"1F647-1F3FE-200D-2642-FE0F":["man_bowing_tone4","man_bowing_medium_dark_skin_tone"],"1F647-1F3FF-200D-2642-FE0F":["man_bowing_tone5","man_bowing_dark_skin_tone"],"1F481":["person_tipping_hand","information_desk_person"],"1F481-1F3FB":["person_tipping_hand_tone1","information_desk_person_tone1"],"1F481-1F3FC":["person_tipping_hand_tone2","information_desk_person_tone2"],"1F481-1F3FD":["person_tipping_hand_tone3","information_desk_person_tone3"],"1F481-1F3FE":["person_tipping_hand_tone4","information_desk_person_tone4"],"1F481-1F3FF":["person_tipping_hand_tone5","information_desk_person_tone5"],"1F481-200D-2640-FE0F":"woman_tipping_hand","1F481-1F3FB-200D-2640-FE0F":["woman_tipping_hand_tone1","woman_tipping_hand_light_skin_tone"],"1F481-1F3FC-200D-2640-FE0F":["woman_tipping_hand_tone2","woman_tipping_hand_medium_light_skin_tone"],"1F481-1F3FD-200D-2640-FE0F":["woman_tipping_hand_tone3","woman_tipping_hand_medium_skin_tone"],"1F481-1F3FE-200D-2640-FE0F":["woman_tipping_hand_tone4","woman_tipping_hand_medium_dark_skin_tone"],"1F481-1F3FF-200D-2640-FE0F":["woman_tipping_hand_tone5","woman_tipping_hand_dark_skin_tone"],"1F481-200D-2642-FE0F":"man_tipping_hand","1F481-1F3FB-200D-2642-FE0F":["man_tipping_hand_tone1","man_tipping_hand_light_skin_tone"],"1F481-1F3FC-200D-2642-FE0F":["man_tipping_hand_tone2","man_tipping_hand_medium_light_skin_tone"],"1F481-1F3FD-200D-2642-FE0F":["man_tipping_hand_tone3","man_tipping_hand_medium_skin_tone"],"1F481-1F3FE-200D-2642-FE0F":["man_tipping_hand_tone4","man_tipping_hand_medium_dark_skin_tone"],"1F481-1F3FF-200D-2642-FE0F":["man_tipping_hand_tone5","man_tipping_hand_dark_skin_tone"],"1F645":["person_gesturing_no","no_good"],"1F645-1F3FB":["person_gesturing_no_tone1","no_good_tone1"],"1F645-1F3FC":["person_gesturing_no_tone2","no_good_tone2"],"1F645-1F3FD":["person_gesturing_no_tone3","no_good_tone3"],"1F645-1F3FE":["person_gesturing_no_tone4","no_good_tone4"],"1F645-1F3FF":["person_gesturing_no_tone5","no_good_tone5"],"1F645-200D-2640-FE0F":"woman_gesturing_no","1F645-1F3FB-200D-2640-FE0F":["woman_gesturing_no_tone1","woman_gesturing_no_light_skin_tone"],"1F645-1F3FC-200D-2640-FE0F":["woman_gesturing_no_tone2","woman_gesturing_no_medium_light_skin_tone"],"1F645-1F3FD-200D-2640-FE0F":["woman_gesturing_no_tone3","woman_gesturing_no_medium_skin_tone"],"1F645-1F3FE-200D-2640-FE0F":["woman_gesturing_no_tone4","woman_gesturing_no_medium_dark_skin_tone"],"1F645-1F3FF-200D-2640-FE0F":["woman_gesturing_no_tone5","woman_gesturing_no_dark_skin_tone"],"1F645-200D-2642-FE0F":"man_gesturing_no","1F645-1F3FB-200D-2642-FE0F":["man_gesturing_no_tone1","man_gesturing_no_light_skin_tone"],"1F645-1F3FC-200D-2642-FE0F":["man_gesturing_no_tone2","man_gesturing_no_medium_light_skin_tone"],"1F645-1F3FD-200D-2642-FE0F":["man_gesturing_no_tone3","man_gesturing_no_medium_skin_tone"],"1F645-1F3FE-200D-2642-FE0F":["man_gesturing_no_tone4","man_gesturing_no_medium_dark_skin_tone"],"1F645-1F3FF-200D-2642-FE0F":["man_gesturing_no_tone5","man_gesturing_no_dark_skin_tone"],"1F646":["person_gesturing_ok","ok_woman"],"1F646-1F3FB":["person_gesturing_ok_tone1","ok_woman_tone1"],"1F646-1F3FC":["person_gesturing_ok_tone2","ok_woman_tone2"],"1F646-1F3FD":["person_gesturing_ok_tone3","ok_woman_tone3"],"1F646-1F3FE":["person_gesturing_ok_tone4","ok_woman_tone4"],"1F646-1F3FF":["person_gesturing_ok_tone5","ok_woman_tone5"],"1F646-200D-2640-FE0F":"woman_gesturing_ok","1F646-1F3FB-200D-2640-FE0F":["woman_gesturing_ok_tone1","woman_gesturing_ok_light_skin_tone"],"1F646-1F3FC-200D-2640-FE0F":["woman_gesturing_ok_tone2","woman_gesturing_ok_medium_light_skin_tone"],"1F646-1F3FD-200D-2640-FE0F":["woman_gesturing_ok_tone3","woman_gesturing_ok_medium_skin_tone"],"1F646-1F3FE-200D-2640-FE0F":["woman_gesturing_ok_tone4","woman_gesturing_ok_medium_dark_skin_tone"],"1F646-1F3FF-200D-2640-FE0F":["woman_gesturing_ok_tone5","woman_gesturing_ok_dark_skin_tone"],"1F646-200D-2642-FE0F":"man_gesturing_ok","1F646-1F3FB-200D-2642-FE0F":["man_gesturing_ok_tone1","man_gesturing_ok_light_skin_tone"],"1F646-1F3FC-200D-2642-FE0F":["man_gesturing_ok_tone2","man_gesturing_ok_medium_light_skin_tone"],"1F646-1F3FD-200D-2642-FE0F":["man_gesturing_ok_tone3","man_gesturing_ok_medium_skin_tone"],"1F646-1F3FE-200D-2642-FE0F":["man_gesturing_ok_tone4","man_gesturing_ok_medium_dark_skin_tone"],"1F646-1F3FF-200D-2642-FE0F":["man_gesturing_ok_tone5","man_gesturing_ok_dark_skin_tone"],"1F64B":["person_raising_hand","raising_hand"],"1F64B-1F3FB":["person_raising_hand_tone1","raising_hand_tone1"],"1F64B-1F3FC":["person_raising_hand_tone2","raising_hand_tone2"],"1F64B-1F3FD":["person_raising_hand_tone3","raising_hand_tone3"],"1F64B-1F3FE":["person_raising_hand_tone4","raising_hand_tone4"],"1F64B-1F3FF":["person_raising_hand_tone5","raising_hand_tone5"],"1F64B-200D-2640-FE0F":"woman_raising_hand","1F64B-1F3FB-200D-2640-FE0F":["woman_raising_hand_tone1","woman_raising_hand_light_skin_tone"],"1F64B-1F3FC-200D-2640-FE0F":["woman_raising_hand_tone2","woman_raising_hand_medium_light_skin_tone"],"1F64B-1F3FD-200D-2640-FE0F":["woman_raising_hand_tone3","woman_raising_hand_medium_skin_tone"],"1F64B-1F3FE-200D-2640-FE0F":["woman_raising_hand_tone4","woman_raising_hand_medium_dark_skin_tone"],"1F64B-1F3FF-200D-2640-FE0F":["woman_raising_hand_tone5","woman_raising_hand_dark_skin_tone"],"1F64B-200D-2642-FE0F":"man_raising_hand","1F64B-1F3FB-200D-2642-FE0F":["man_raising_hand_tone1","man_raising_hand_light_skin_tone"],"1F64B-1F3FC-200D-2642-FE0F":["man_raising_hand_tone2","man_raising_hand_medium_light_skin_tone"],"1F64B-1F3FD-200D-2642-FE0F":["man_raising_hand_tone3","man_raising_hand_medium_skin_tone"],"1F64B-1F3FE-200D-2642-FE0F":["man_raising_hand_tone4","man_raising_hand_medium_dark_skin_tone"],"1F64B-1F3FF-200D-2642-FE0F":["man_raising_hand_tone5","man_raising_hand_dark_skin_tone"],"1F9CF":"deaf_person","1F9CF-1F3FB":["deaf_person_tone1","deaf_person_light_skin_tone"],"1F9CF-1F3FC":["deaf_person_tone2","deaf_person_medium_light_skin_tone"],"1F9CF-1F3FD":["deaf_person_tone3","deaf_person_medium_skin_tone"],"1F9CF-1F3FE":["deaf_person_tone4","deaf_person_medium_dark_skin_tone"],"1F9CF-1F3FF":["deaf_person_tone5","deaf_person_dark_skin_tone"],"1F9CF-200D-2640-FE0F":"deaf_woman","1F9CF-1F3FB-200D-2640-FE0F":["deaf_woman_tone1","deaf_woman_light_skin_tone"],"1F9CF-1F3FC-200D-2640-FE0F":["deaf_woman_tone2","deaf_woman_medium_light_skin_tone"],"1F9CF-1F3FD-200D-2640-FE0F":["deaf_woman_tone3","deaf_woman_medium_skin_tone"],"1F9CF-1F3FE-200D-2640-FE0F":["deaf_woman_tone4","deaf_woman_medium_dark_skin_tone"],"1F9CF-1F3FF-200D-2640-FE0F":["deaf_woman_tone5","deaf_woman_dark_skin_tone"],"1F9CF-200D-2642-FE0F":"deaf_man","1F9CF-1F3FB-200D-2642-FE0F":["deaf_man_tone1","deaf_man_light_skin_tone"],"1F9CF-1F3FC-200D-2642-FE0F":["deaf_man_tone2","deaf_man_medium_light_skin_tone"],"1F9CF-1F3FD-200D-2642-FE0F":["deaf_man_tone3","deaf_man_medium_skin_tone"],"1F9CF-1F3FE-200D-2642-FE0F":["deaf_man_tone4","deaf_man_medium_dark_skin_tone"],"1F9CF-1F3FF-200D-2642-FE0F":["deaf_man_tone5","deaf_man_dark_skin_tone"],"1F926":["person_facepalming","face_palm","facepalm"],"1F926-1F3FB":["person_facepalming_tone1","face_palm_tone1","facepalm_tone1"],"1F926-1F3FC":["person_facepalming_tone2","face_palm_tone2","facepalm_tone2"],"1F926-1F3FD":["person_facepalming_tone3","face_palm_tone3","facepalm_tone3"],"1F926-1F3FE":["person_facepalming_tone4","face_palm_tone4","facepalm_tone4"],"1F926-1F3FF":["person_facepalming_tone5","face_palm_tone5","facepalm_tone5"],"1F926-200D-2640-FE0F":"woman_facepalming","1F926-1F3FB-200D-2640-FE0F":["woman_facepalming_tone1","woman_facepalming_light_skin_tone"],"1F926-1F3FC-200D-2640-FE0F":["woman_facepalming_tone2","woman_facepalming_medium_light_skin_tone"],"1F926-1F3FD-200D-2640-FE0F":["woman_facepalming_tone3","woman_facepalming_medium_skin_tone"],"1F926-1F3FE-200D-2640-FE0F":["woman_facepalming_tone4","woman_facepalming_medium_dark_skin_tone"],"1F926-1F3FF-200D-2640-FE0F":["woman_facepalming_tone5","woman_facepalming_dark_skin_tone"],"1F926-200D-2642-FE0F":"man_facepalming","1F926-1F3FB-200D-2642-FE0F":["man_facepalming_tone1","man_facepalming_light_skin_tone"],"1F926-1F3FC-200D-2642-FE0F":["man_facepalming_tone2","man_facepalming_medium_light_skin_tone"],"1F926-1F3FD-200D-2642-FE0F":["man_facepalming_tone3","man_facepalming_medium_skin_tone"],"1F926-1F3FE-200D-2642-FE0F":["man_facepalming_tone4","man_facepalming_medium_dark_skin_tone"],"1F926-1F3FF-200D-2642-FE0F":["man_facepalming_tone5","man_facepalming_dark_skin_tone"],"1F937":["person_shrugging","shrug"],"1F937-1F3FB":["person_shrugging_tone1","shrug_tone1"],"1F937-1F3FC":["person_shrugging_tone2","shrug_tone2"],"1F937-1F3FD":["person_shrugging_tone3","shrug_tone3"],"1F937-1F3FE":["person_shrugging_tone4","shrug_tone4"],"1F937-1F3FF":["person_shrugging_tone5","shrug_tone5"],"1F937-200D-2640-FE0F":"woman_shrugging","1F937-1F3FB-200D-2640-FE0F":["woman_shrugging_tone1","woman_shrugging_light_skin_tone"],"1F937-1F3FC-200D-2640-FE0F":["woman_shrugging_tone2","woman_shrugging_medium_light_skin_tone"],"1F937-1F3FD-200D-2640-FE0F":["woman_shrugging_tone3","woman_shrugging_medium_skin_tone"],"1F937-1F3FE-200D-2640-FE0F":["woman_shrugging_tone4","woman_shrugging_medium_dark_skin_tone"],"1F937-1F3FF-200D-2640-FE0F":["woman_shrugging_tone5","woman_shrugging_dark_skin_tone"],"1F937-200D-2642-FE0F":"man_shrugging","1F937-1F3FB-200D-2642-FE0F":["man_shrugging_tone1","man_shrugging_light_skin_tone"],"1F937-1F3FC-200D-2642-FE0F":["man_shrugging_tone2","man_shrugging_medium_light_skin_tone"],"1F937-1F3FD-200D-2642-FE0F":["man_shrugging_tone3","man_shrugging_medium_skin_tone"],"1F937-1F3FE-200D-2642-FE0F":["man_shrugging_tone4","man_shrugging_medium_dark_skin_tone"],"1F937-1F3FF-200D-2642-FE0F":["man_shrugging_tone5","man_shrugging_dark_skin_tone"],"1F64E":["person_pouting","person_with_pouting_face"],"1F64E-1F3FB":["person_pouting_tone1","person_with_pouting_face_tone1"],"1F64E-1F3FC":["person_pouting_tone2","person_with_pouting_face_tone2"],"1F64E-1F3FD":["person_pouting_tone3","person_with_pouting_face_tone3"],"1F64E-1F3FE":["person_pouting_tone4","person_with_pouting_face_tone4"],"1F64E-1F3FF":["person_pouting_tone5","person_with_pouting_face_tone5"],"1F64E-200D-2640-FE0F":"woman_pouting","1F64E-1F3FB-200D-2640-FE0F":["woman_pouting_tone1","woman_pouting_light_skin_tone"],"1F64E-1F3FC-200D-2640-FE0F":["woman_pouting_tone2","woman_pouting_medium_light_skin_tone"],"1F64E-1F3FD-200D-2640-FE0F":["woman_pouting_tone3","woman_pouting_medium_skin_tone"],"1F64E-1F3FE-200D-2640-FE0F":["woman_pouting_tone4","woman_pouting_medium_dark_skin_tone"],"1F64E-1F3FF-200D-2640-FE0F":["woman_pouting_tone5","woman_pouting_dark_skin_tone"],"1F64E-200D-2642-FE0F":"man_pouting","1F64E-1F3FB-200D-2642-FE0F":["man_pouting_tone1","man_pouting_light_skin_tone"],"1F64E-1F3FC-200D-2642-FE0F":["man_pouting_tone2","man_pouting_medium_light_skin_tone"],"1F64E-1F3FD-200D-2642-FE0F":["man_pouting_tone3","man_pouting_medium_skin_tone"],"1F64E-1F3FE-200D-2642-FE0F":["man_pouting_tone4","man_pouting_medium_dark_skin_tone"],"1F64E-1F3FF-200D-2642-FE0F":["man_pouting_tone5","man_pouting_dark_skin_tone"],"1F64D":"person_frowning","1F64D-1F3FB":"person_frowning_tone1","1F64D-1F3FC":"person_frowning_tone2","1F64D-1F3FD":"person_frowning_tone3","1F64D-1F3FE":"person_frowning_tone4","1F64D-1F3FF":"person_frowning_tone5","1F64D-200D-2640-FE0F":"woman_frowning","1F64D-1F3FB-200D-2640-FE0F":["woman_frowning_tone1","woman_frowning_light_skin_tone"],"1F64D-1F3FC-200D-2640-FE0F":["woman_frowning_tone2","woman_frowning_medium_light_skin_tone"],"1F64D-1F3FD-200D-2640-FE0F":["woman_frowning_tone3","woman_frowning_medium_skin_tone"],"1F64D-1F3FE-200D-2640-FE0F":["woman_frowning_tone4","woman_frowning_medium_dark_skin_tone"],"1F64D-1F3FF-200D-2640-FE0F":["woman_frowning_tone5","woman_frowning_dark_skin_tone"],"1F64D-200D-2642-FE0F":"man_frowning","1F64D-1F3FB-200D-2642-FE0F":["man_frowning_tone1","man_frowning_light_skin_tone"],"1F64D-1F3FC-200D-2642-FE0F":["man_frowning_tone2","man_frowning_medium_light_skin_tone"],"1F64D-1F3FD-200D-2642-FE0F":["man_frowning_tone3","man_frowning_medium_skin_tone"],"1F64D-1F3FE-200D-2642-FE0F":["man_frowning_tone4","man_frowning_medium_dark_skin_tone"],"1F64D-1F3FF-200D-2642-FE0F":["man_frowning_tone5","man_frowning_dark_skin_tone"],"1F487":["person_getting_haircut","haircut"],"1F487-1F3FB":["person_getting_haircut_tone1","haircut_tone1"],"1F487-1F3FC":["person_getting_haircut_tone2","haircut_tone2"],"1F487-1F3FD":["person_getting_haircut_tone3","haircut_tone3"],"1F487-1F3FE":["person_getting_haircut_tone4","haircut_tone4"],"1F487-1F3FF":["person_getting_haircut_tone5","haircut_tone5"],"1F487-200D-2640-FE0F":"woman_getting_haircut","1F487-1F3FB-200D-2640-FE0F":["woman_getting_haircut_tone1","woman_getting_haircut_light_skin_tone"],"1F487-1F3FC-200D-2640-FE0F":["woman_getting_haircut_tone2","woman_getting_haircut_medium_light_skin_tone"],"1F487-1F3FD-200D-2640-FE0F":["woman_getting_haircut_tone3","woman_getting_haircut_medium_skin_tone"],"1F487-1F3FE-200D-2640-FE0F":["woman_getting_haircut_tone4","woman_getting_haircut_medium_dark_skin_tone"],"1F487-1F3FF-200D-2640-FE0F":["woman_getting_haircut_tone5","woman_getting_haircut_dark_skin_tone"],"1F487-200D-2642-FE0F":"man_getting_haircut","1F487-1F3FB-200D-2642-FE0F":["man_getting_haircut_tone1","man_getting_haircut_light_skin_tone"],"1F487-1F3FC-200D-2642-FE0F":["man_getting_haircut_tone2","man_getting_haircut_medium_light_skin_tone"],"1F487-1F3FD-200D-2642-FE0F":["man_getting_haircut_tone3","man_getting_haircut_medium_skin_tone"],"1F487-1F3FE-200D-2642-FE0F":["man_getting_haircut_tone4","man_getting_haircut_medium_dark_skin_tone"],"1F487-1F3FF-200D-2642-FE0F":["man_getting_haircut_tone5","man_getting_haircut_dark_skin_tone"],"1F486":["person_getting_massage","massage"],"1F486-1F3FB":["person_getting_massage_tone1","massage_tone1"],"1F486-1F3FC":["person_getting_massage_tone2","massage_tone2"],"1F486-1F3FD":["person_getting_massage_tone3","massage_tone3"],"1F486-1F3FE":["person_getting_massage_tone4","massage_tone4"],"1F486-1F3FF":["person_getting_massage_tone5","massage_tone5"],"1F486-200D-2640-FE0F":"woman_getting_face_massage","1F486-1F3FB-200D-2640-FE0F":["woman_getting_face_massage_tone1","woman_getting_face_massage_light_skin_tone"],"1F486-1F3FC-200D-2640-FE0F":["woman_getting_face_massage_tone2","woman_getting_face_massage_medium_light_skin_tone"],"1F486-1F3FD-200D-2640-FE0F":["woman_getting_face_massage_tone3","woman_getting_face_massage_medium_skin_tone"],"1F486-1F3FE-200D-2640-FE0F":["woman_getting_face_massage_tone4","woman_getting_face_massage_medium_dark_skin_tone"],"1F486-1F3FF-200D-2640-FE0F":["woman_getting_face_massage_tone5","woman_getting_face_massage_dark_skin_tone"],"1F486-200D-2642-FE0F":"man_getting_face_massage","1F486-1F3FB-200D-2642-FE0F":["man_getting_face_massage_tone1","man_getting_face_massage_light_skin_tone"],"1F486-1F3FC-200D-2642-FE0F":["man_getting_face_massage_tone2","man_getting_face_massage_medium_light_skin_tone"],"1F486-1F3FD-200D-2642-FE0F":["man_getting_face_massage_tone3","man_getting_face_massage_medium_skin_tone"],"1F486-1F3FE-200D-2642-FE0F":["man_getting_face_massage_tone4","man_getting_face_massage_medium_dark_skin_tone"],"1F486-1F3FF-200D-2642-FE0F":["man_getting_face_massage_tone5","man_getting_face_massage_dark_skin_tone"],"1F9D6":"person_in_steamy_room","1F9D6-1F3FB":["person_in_steamy_room_tone1","person_in_steamy_room_light_skin_tone"],"1F9D6-1F3FC":["person_in_steamy_room_tone2","person_in_steamy_room_medium_light_skin_tone"],"1F9D6-1F3FD":["person_in_steamy_room_tone3","person_in_steamy_room_medium_skin_tone"],"1F9D6-1F3FE":["person_in_steamy_room_tone4","person_in_steamy_room_medium_dark_skin_tone"],"1F9D6-1F3FF":["person_in_steamy_room_tone5","person_in_steamy_room_dark_skin_tone"],"1F9D6-200D-2640-FE0F":"woman_in_steamy_room","1F9D6-1F3FB-200D-2640-FE0F":["woman_in_steamy_room_tone1","woman_in_steamy_room_light_skin_tone"],"1F9D6-1F3FC-200D-2640-FE0F":["woman_in_steamy_room_tone2","woman_in_steamy_room_medium_light_skin_tone"],"1F9D6-1F3FD-200D-2640-FE0F":["woman_in_steamy_room_tone3","woman_in_steamy_room_medium_skin_tone"],"1F9D6-1F3FE-200D-2640-FE0F":["woman_in_steamy_room_tone4","woman_in_steamy_room_medium_dark_skin_tone"],"1F9D6-1F3FF-200D-2640-FE0F":["woman_in_steamy_room_tone5","woman_in_steamy_room_dark_skin_tone"],"1F9D6-200D-2642-FE0F":"man_in_steamy_room","1F9D6-1F3FB-200D-2642-FE0F":["man_in_steamy_room_tone1","man_in_steamy_room_light_skin_tone"],"1F9D6-1F3FC-200D-2642-FE0F":["man_in_steamy_room_tone2","man_in_steamy_room_medium_light_skin_tone"],"1F9D6-1F3FD-200D-2642-FE0F":["man_in_steamy_room_tone3","man_in_steamy_room_medium_skin_tone"],"1F9D6-1F3FE-200D-2642-FE0F":["man_in_steamy_room_tone4","man_in_steamy_room_medium_dark_skin_tone"],"1F9D6-1F3FF-200D-2642-FE0F":["man_in_steamy_room_tone5","man_in_steamy_room_dark_skin_tone"],"1F485":"nail_care","1F485-1F3FB":"nail_care_tone1","1F485-1F3FC":"nail_care_tone2","1F485-1F3FD":"nail_care_tone3","1F485-1F3FE":"nail_care_tone4","1F485-1F3FF":"nail_care_tone5","1F933":"selfie","1F933-1F3FB":"selfie_tone1","1F933-1F3FC":"selfie_tone2","1F933-1F3FD":"selfie_tone3","1F933-1F3FE":"selfie_tone4","1F933-1F3FF":"selfie_tone5","1F483":"dancer","1F483-1F3FB":"dancer_tone1","1F483-1F3FC":"dancer_tone2","1F483-1F3FD":"dancer_tone3","1F483-1F3FE":"dancer_tone4","1F483-1F3FF":"dancer_tone5","1F57A":["man_dancing","male_dancer"],"1F57A-1F3FB":["man_dancing_tone1","male_dancer_tone1"],"1F57A-1F3FC":["man_dancing_tone2","male_dancer_tone2"],"1F57A-1F3FD":["man_dancing_tone3","male_dancer_tone3"],"1F57A-1F3FF":["man_dancing_tone5","male_dancer_tone5"],"1F57A-1F3FE":["man_dancing_tone4","male_dancer_tone4"],"1F46F":["people_with_bunny_ears_partying","dancers"],"1F46F-200D-2640-FE0F":"women_with_bunny_ears_partying","1F46F-200D-2642-FE0F":"men_with_bunny_ears_partying","1F574":["levitate","man_in_business_suit_levitating"],"1F574-1F3FB":["levitate_tone1","man_in_business_suit_levitating_tone1","man_in_business_suit_levitating_light_skin_tone"],"1F574-1F3FC":["levitate_tone2","man_in_business_suit_levitating_tone2","man_in_business_suit_levitating_medium_light_skin_tone"],"1F574-1F3FD":["levitate_tone3","man_in_business_suit_levitating_tone3","man_in_business_suit_levitating_medium_skin_tone"],"1F574-1F3FE":["levitate_tone4","man_in_business_suit_levitating_tone4","man_in_business_suit_levitating_medium_dark_skin_tone"],"1F574-1F3FF":["levitate_tone5","man_in_business_suit_levitating_tone5","man_in_business_suit_levitating_dark_skin_tone"],"1F9D1-200D-1F9BD":"person_in_manual_wheelchair","1F9D1-1F3FB-200D-1F9BD":["person_in_manual_wheelchair_tone1","person_in_manual_wheelchair_light_skin_tone"],"1F9D1-1F3FC-200D-1F9BD":["person_in_manual_wheelchair_tone2","person_in_manual_wheelchair_medium_light_skin_tone"],"1F9D1-1F3FD-200D-1F9BD":["person_in_manual_wheelchair_tone3","person_in_manual_wheelchair_medium_skin_tone"],"1F9D1-1F3FE-200D-1F9BD":["person_in_manual_wheelchair_tone4","person_in_manual_wheelchair_medium_dark_skin_tone"],"1F9D1-1F3FF-200D-1F9BD":["person_in_manual_wheelchair_tone5","person_in_manual_wheelchair_dark_skin_tone"],"1F469-200D-1F9BD":"woman_in_manual_wheelchair","1F469-1F3FB-200D-1F9BD":["woman_in_manual_wheelchair_tone1","woman_in_manual_wheelchair_light_skin_tone"],"1F469-1F3FC-200D-1F9BD":["woman_in_manual_wheelchair_tone2","woman_in_manual_wheelchair_medium_light_skin_tone"],"1F469-1F3FD-200D-1F9BD":["woman_in_manual_wheelchair_tone3","woman_in_manual_wheelchair_medium_skin_tone"],"1F469-1F3FE-200D-1F9BD":["woman_in_manual_wheelchair_tone4","woman_in_manual_wheelchair_medium_dark_skin_tone"],"1F469-1F3FF-200D-1F9BD":["woman_in_manual_wheelchair_tone5","woman_in_manual_wheelchair_dark_skin_tone"],"1F468-200D-1F9BD":"man_in_manual_wheelchair","1F468-1F3FB-200D-1F9BD":["man_in_manual_wheelchair_tone1","man_in_manual_wheelchair_light_skin_tone"],"1F468-1F3FC-200D-1F9BD":["man_in_manual_wheelchair_tone2","man_in_manual_wheelchair_medium_light_skin_tone"],"1F468-1F3FD-200D-1F9BD":["man_in_manual_wheelchair_tone3","man_in_manual_wheelchair_medium_skin_tone"],"1F468-1F3FE-200D-1F9BD":["man_in_manual_wheelchair_tone4","man_in_manual_wheelchair_medium_dark_skin_tone"],"1F468-1F3FF-200D-1F9BD":["man_in_manual_wheelchair_tone5","man_in_manual_wheelchair_dark_skin_tone"],"1F9D1-200D-1F9BC":"person_in_motorized_wheelchair","1F9D1-1F3FB-200D-1F9BC":["person_in_motorized_wheelchair_tone1","person_in_motorized_wheelchair_light_skin_tone"],"1F9D1-1F3FC-200D-1F9BC":["person_in_motorized_wheelchair_tone2","person_in_motorized_wheelchair_medium_light_skin_tone"],"1F9D1-1F3FD-200D-1F9BC":["person_in_motorized_wheelchair_tone3","person_in_motorized_wheelchair_medium_skin_tone"],"1F9D1-1F3FE-200D-1F9BC":["person_in_motorized_wheelchair_tone4","person_in_motorized_wheelchair_medium_dark_skin_tone"],"1F9D1-1F3FF-200D-1F9BC":["person_in_motorized_wheelchair_tone5","person_in_motorized_wheelchair_dark_skin_tone"],"1F469-200D-1F9BC":"woman_in_motorized_wheelchair","1F469-1F3FB-200D-1F9BC":["woman_in_motorized_wheelchair_tone1","woman_in_motorized_wheelchair_light_skin_tone"],"1F469-1F3FC-200D-1F9BC":["woman_in_motorized_wheelchair_tone2","woman_in_motorized_wheelchair_medium_light_skin_tone"],"1F469-1F3FD-200D-1F9BC":["woman_in_motorized_wheelchair_tone3","woman_in_motorized_wheelchair_medium_skin_tone"],"1F469-1F3FE-200D-1F9BC":["woman_in_motorized_wheelchair_tone4","woman_in_motorized_wheelchair_medium_dark_skin_tone"],"1F469-1F3FF-200D-1F9BC":["woman_in_motorized_wheelchair_tone5","woman_in_motorized_wheelchair_dark_skin_tone"],"1F468-200D-1F9BC":"man_in_motorized_wheelchair","1F468-1F3FB-200D-1F9BC":["man_in_motorized_wheelchair_tone1","man_in_motorized_wheelchair_light_skin_tone"],"1F468-1F3FC-200D-1F9BC":["man_in_motorized_wheelchair_tone2","man_in_motorized_wheelchair_medium_light_skin_tone"],"1F468-1F3FD-200D-1F9BC":["man_in_motorized_wheelchair_tone3","man_in_motorized_wheelchair_medium_skin_tone"],"1F468-1F3FE-200D-1F9BC":["man_in_motorized_wheelchair_tone4","man_in_motorized_wheelchair_medium_dark_skin_tone"],"1F468-1F3FF-200D-1F9BC":["man_in_motorized_wheelchair_tone5","man_in_motorized_wheelchair_dark_skin_tone"],"1F6B6":["person_walking","walking"],"1F6B6-1F3FB":["person_walking_tone1","walking_tone1"],"1F6B6-1F3FC":["person_walking_tone2","walking_tone2"],"1F6B6-1F3FD":["person_walking_tone3","walking_tone3"],"1F6B6-1F3FE":["person_walking_tone4","walking_tone4"],"1F6B6-1F3FF":["person_walking_tone5","walking_tone5"],"1F6B6-200D-2640-FE0F":"woman_walking","1F6B6-1F3FB-200D-2640-FE0F":["woman_walking_tone1","woman_walking_light_skin_tone"],"1F6B6-1F3FC-200D-2640-FE0F":["woman_walking_tone2","woman_walking_medium_light_skin_tone"],"1F6B6-1F3FD-200D-2640-FE0F":["woman_walking_tone3","woman_walking_medium_skin_tone"],"1F6B6-1F3FE-200D-2640-FE0F":["woman_walking_tone4","woman_walking_medium_dark_skin_tone"],"1F6B6-1F3FF-200D-2640-FE0F":["woman_walking_tone5","woman_walking_dark_skin_tone"],"1F6B6-200D-2642-FE0F":"man_walking","1F6B6-1F3FB-200D-2642-FE0F":["man_walking_tone1","man_walking_light_skin_tone"],"1F6B6-1F3FC-200D-2642-FE0F":["man_walking_tone2","man_walking_medium_light_skin_tone"],"1F6B6-1F3FD-200D-2642-FE0F":["man_walking_tone3","man_walking_medium_skin_tone"],"1F6B6-1F3FE-200D-2642-FE0F":["man_walking_tone4","man_walking_medium_dark_skin_tone"],"1F6B6-1F3FF-200D-2642-FE0F":["man_walking_tone5","man_walking_dark_skin_tone"],"1F9D1-200D-1F9AF":"person_with_probing_cane","1F9D1-1F3FB-200D-1F9AF":["person_with_probing_cane_tone1","person_with_probing_cane_light_skin_tone"],"1F9D1-1F3FC-200D-1F9AF":["person_with_probing_cane_tone2","person_with_probing_cane_medium_light_skin_tone"],"1F9D1-1F3FD-200D-1F9AF":["person_with_probing_cane_tone3","person_with_probing_cane_medium_skin_tone"],"1F9D1-1F3FE-200D-1F9AF":["person_with_probing_cane_tone4","person_with_probing_cane_medium_dark_skin_tone"],"1F9D1-1F3FF-200D-1F9AF":["person_with_probing_cane_tone5","person_with_probing_cane_dark_skin_tone"],"1F469-200D-1F9AF":"woman_with_probing_cane","1F469-1F3FB-200D-1F9AF":["woman_with_probing_cane_tone1","woman_with_probing_cane_light_skin_tone"],"1F469-1F3FC-200D-1F9AF":["woman_with_probing_cane_tone2","woman_with_probing_cane_medium_light_skin_tone"],"1F469-1F3FD-200D-1F9AF":["woman_with_probing_cane_tone3","woman_with_probing_cane_medium_skin_tone"],"1F469-1F3FE-200D-1F9AF":["woman_with_probing_cane_tone4","woman_with_probing_cane_medium_dark_skin_tone"],"1F469-1F3FF-200D-1F9AF":["woman_with_probing_cane_tone5","woman_with_probing_cane_dark_skin_tone"],"1F468-200D-1F9AF":"man_with_probing_cane","1F468-1F3FB-200D-1F9AF":["man_with_probing_cane_tone1","man_with_probing_cane_light_skin_tone"],"1F468-1F3FD-200D-1F9AF":["man_with_probing_cane_tone3","man_with_probing_cane_medium_skin_tone"],"1F468-1F3FC-200D-1F9AF":["man_with_probing_cane_tone2","man_with_probing_cane_medium_light_skin_tone"],"1F468-1F3FE-200D-1F9AF":["man_with_probing_cane_tone4","man_with_probing_cane_medium_dark_skin_tone"],"1F468-1F3FF-200D-1F9AF":["man_with_probing_cane_tone5","man_with_probing_cane_dark_skin_tone"],"1F9CE":"person_kneeling","1F9CE-1F3FB":["person_kneeling_tone1","person_kneeling_light_skin_tone"],"1F9CE-1F3FC":["person_kneeling_tone2","person_kneeling_medium_light_skin_tone"],"1F9CE-1F3FD":["person_kneeling_tone3","person_kneeling_medium_skin_tone"],"1F9CE-1F3FE":["person_kneeling_tone4","person_kneeling_medium_dark_skin_tone"],"1F9CE-1F3FF":["person_kneeling_tone5","person_kneeling_dark_skin_tone"],"1F9CE-200D-2640-FE0F":"woman_kneeling","1F9CE-1F3FB-200D-2640-FE0F":["woman_kneeling_tone1","woman_kneeling_light_skin_tone"],"1F9CE-1F3FC-200D-2640-FE0F":["woman_kneeling_tone2","woman_kneeling_medium_light_skin_tone"],"1F9CE-1F3FD-200D-2640-FE0F":["woman_kneeling_tone3","woman_kneeling_medium_skin_tone"],"1F9CE-1F3FE-200D-2640-FE0F":["woman_kneeling_tone4","woman_kneeling_medium_dark_skin_tone"],"1F9CE-1F3FF-200D-2640-FE0F":["woman_kneeling_tone5","woman_kneeling_dark_skin_tone"],"1F9CE-200D-2642-FE0F":"man_kneeling","1F9CE-1F3FB-200D-2642-FE0F":["man_kneeling_tone1","man_kneeling_light_skin_tone"],"1F9CE-1F3FC-200D-2642-FE0F":["man_kneeling_tone2","man_kneeling_medium_light_skin_tone"],"1F9CE-1F3FD-200D-2642-FE0F":["man_kneeling_tone3","man_kneeling_medium_skin_tone"],"1F9CE-1F3FE-200D-2642-FE0F":["man_kneeling_tone4","man_kneeling_medium_dark_skin_tone"],"1F9CE-1F3FF-200D-2642-FE0F":["man_kneeling_tone5","man_kneeling_dark_skin_tone"],"1F3C3":["person_running","runner"],"1F3C3-1F3FB":["person_running_tone1","runner_tone1"],"1F3C3-1F3FC":["person_running_tone2","runner_tone2"],"1F3C3-1F3FD":["person_running_tone3","runner_tone3"],"1F3C3-1F3FE":["person_running_tone4","runner_tone4"],"1F3C3-1F3FF":["person_running_tone5","runner_tone5"],"1F3C3-200D-2640-FE0F":"woman_running","1F3C3-1F3FB-200D-2640-FE0F":["woman_running_tone1","woman_running_light_skin_tone"],"1F3C3-1F3FC-200D-2640-FE0F":["woman_running_tone2","woman_running_medium_light_skin_tone"],"1F3C3-1F3FD-200D-2640-FE0F":["woman_running_tone3","woman_running_medium_skin_tone"],"1F3C3-1F3FE-200D-2640-FE0F":["woman_running_tone4","woman_running_medium_dark_skin_tone"],"1F3C3-1F3FF-200D-2640-FE0F":["woman_running_tone5","woman_running_dark_skin_tone"],"1F3C3-200D-2642-FE0F":"man_running","1F3C3-1F3FB-200D-2642-FE0F":["man_running_tone1","man_running_light_skin_tone"],"1F3C3-1F3FC-200D-2642-FE0F":["man_running_tone2","man_running_medium_light_skin_tone"],"1F3C3-1F3FD-200D-2642-FE0F":["man_running_tone3","man_running_medium_skin_tone"],"1F3C3-1F3FE-200D-2642-FE0F":["man_running_tone4","man_running_medium_dark_skin_tone"],"1F3C3-1F3FF-200D-2642-FE0F":["man_running_tone5","man_running_dark_skin_tone"],"1F9CD":"person_standing","1F9CD-1F3FB":["person_standing_tone1","person_standing_light_skin_tone"],"1F9CD-1F3FC":["person_standing_tone2","person_standing_medium_light_skin_tone"],"1F9CD-1F3FD":["person_standing_tone3","person_standing_medium_skin_tone"],"1F9CD-1F3FE":["person_standing_tone4","person_standing_medium_dark_skin_tone"],"1F9CD-1F3FF":["person_standing_tone5","person_standing_dark_skin_tone"],"1F9CD-200D-2640-FE0F":"woman_standing","1F9CD-1F3FB-200D-2640-FE0F":["woman_standing_tone1","woman_standing_light_skin_tone"],"1F9CD-1F3FC-200D-2640-FE0F":["woman_standing_tone2","woman_standing_medium_light_skin_tone"],"1F9CD-1F3FD-200D-2640-FE0F":["woman_standing_tone3","woman_standing_medium_skin_tone"],"1F9CD-1F3FE-200D-2640-FE0F":["woman_standing_tone4","woman_standing_medium_dark_skin_tone"],"1F9CD-1F3FF-200D-2640-FE0F":["woman_standing_tone5","woman_standing_dark_skin_tone"],"1F9CD-200D-2642-FE0F":"man_standing","1F9CD-1F3FB-200D-2642-FE0F":["man_standing_tone1","man_standing_light_skin_tone"],"1F9CD-1F3FC-200D-2642-FE0F":["man_standing_tone2","man_standing_medium_light_skin_tone"],"1F9CD-1F3FD-200D-2642-FE0F":["man_standing_tone3","man_standing_medium_skin_tone"],"1F9CD-1F3FE-200D-2642-FE0F":["man_standing_tone4","man_standing_medium_dark_skin_tone"],"1F9CD-1F3FF-200D-2642-FE0F":["man_standing_tone5","man_standing_dark_skin_tone"],"1F9D1-200D-1F91D-200D-1F9D1":"people_holding_hands","1F9D1-1F3FB-200D-1F91D-200D-1F9D1-1F3FB":["people_holding_hands_tone1","people_holding_hands_light_skin_tone"],"1F9D1-1F3FB-200D-1F91D-200D-1F9D1-1F3FC":["people_holding_hands_tone1_tone2","people_holding_hands_light_skin_tone_medium_light_skin_tone"],"1F9D1-1F3FB-200D-1F91D-200D-1F9D1-1F3FD":["people_holding_hands_tone1_tone3","people_holding_hands_light_skin_tone_medium_skin_tone"],"1F9D1-1F3FB-200D-1F91D-200D-1F9D1-1F3FE":["people_holding_hands_tone1_tone4","people_holding_hands_light_skin_tone_medium_dark_skin_tone"],"1F9D1-1F3FB-200D-1F91D-200D-1F9D1-1F3FF":["people_holding_hands_tone1_tone5","people_holding_hands_light_skin_tone_dark_skin_tone"],"1F9D1-1F3FC-200D-1F91D-200D-1F9D1-1F3FB":["people_holding_hands_tone2_tone1","people_holding_hands_medium_light_skin_tone_light_skin_tone"],"1F9D1-1F3FC-200D-1F91D-200D-1F9D1-1F3FC":["people_holding_hands_tone2","people_holding_hands_medium_light_skin_tone"],"1F9D1-1F3FC-200D-1F91D-200D-1F9D1-1F3FD":["people_holding_hands_tone2_tone3","people_holding_hands_medium_light_skin_tone_medium_skin_tone"],"1F9D1-1F3FC-200D-1F91D-200D-1F9D1-1F3FE":["people_holding_hands_tone2_tone4","people_holding_hands_medium_light_skin_tone_medium_dark_skin_tone"],"1F9D1-1F3FC-200D-1F91D-200D-1F9D1-1F3FF":["people_holding_hands_tone2_tone5","people_holding_hands_medium_light_skin_tone_dark_skin_tone"],"1F9D1-1F3FD-200D-1F91D-200D-1F9D1-1F3FB":["people_holding_hands_tone3_tone1","people_holding_hands_medium_skin_tone_light_skin_tone"],"1F9D1-1F3FD-200D-1F91D-200D-1F9D1-1F3FC":["people_holding_hands_tone3_tone2","people_holding_hands_medium_skin_tone_medium_light_skin_tone"],"1F9D1-1F3FD-200D-1F91D-200D-1F9D1-1F3FD":["people_holding_hands_tone3","people_holding_hands_medium_skin_tone"],"1F9D1-1F3FD-200D-1F91D-200D-1F9D1-1F3FE":["people_holding_hands_tone3_tone4","people_holding_hands_medium_skin_tone_medium_dark_skin_tone"],"1F9D1-1F3FD-200D-1F91D-200D-1F9D1-1F3FF":["people_holding_hands_tone3_tone5","people_holding_hands_medium_skin_tone_dark_skin_tone"],"1F9D1-1F3FE-200D-1F91D-200D-1F9D1-1F3FB":["people_holding_hands_tone4_tone1","people_holding_hands_medium_dark_skin_tone_light_skin_tone"],"1F9D1-1F3FE-200D-1F91D-200D-1F9D1-1F3FC":["people_holding_hands_tone4_tone2","people_holding_hands_medium_dark_skin_tone_medium_light_skin_tone"],"1F9D1-1F3FE-200D-1F91D-200D-1F9D1-1F3FD":["people_holding_hands_tone4_tone3","people_holding_hands_medium_dark_skin_tone_medium_skin_tone"],"1F9D1-1F3FE-200D-1F91D-200D-1F9D1-1F3FE":["people_holding_hands_tone4","people_holding_hands_medium_dark_skin_tone"],"1F9D1-1F3FE-200D-1F91D-200D-1F9D1-1F3FF":["people_holding_hands_tone4_tone5","people_holding_hands_medium_dark_skin_tone_dark_skin_tone"],"1F9D1-1F3FF-200D-1F91D-200D-1F9D1-1F3FB":["people_holding_hands_tone5_tone1","people_holding_hands_dark_skin_tone_light_skin_tone"],"1F9D1-1F3FF-200D-1F91D-200D-1F9D1-1F3FC":["people_holding_hands_tone5_tone2","people_holding_hands_dark_skin_tone_medium_light_skin_tone"],"1F9D1-1F3FF-200D-1F91D-200D-1F9D1-1F3FD":["people_holding_hands_tone5_tone3","people_holding_hands_dark_skin_tone_medium_skin_tone"],"1F9D1-1F3FF-200D-1F91D-200D-1F9D1-1F3FE":["people_holding_hands_tone5_tone4","people_holding_hands_dark_skin_tone_medium_dark_skin_tone"],"1F9D1-1F3FF-200D-1F91D-200D-1F9D1-1F3FF":["people_holding_hands_tone5","people_holding_hands_dark_skin_tone"],"1F46B":"couple","1F46B-1F3FB":["woman_and_man_holding_hands_tone1","woman_and_man_holding_hands_light_skin_tone"],"1F469-1F3FB-200D-1F91D-200D-1F468-1F3FC":["woman_and_man_holding_hands_tone1_tone2","woman_and_man_holding_hands_light_skin_tone_medium_light_skin_tone"],"1F469-1F3FB-200D-1F91D-200D-1F468-1F3FD":["woman_and_man_holding_hands_tone1_tone3","woman_and_man_holding_hands_light_skin_tone_medium_skin_tone"],"1F469-1F3FB-200D-1F91D-200D-1F468-1F3FE":["woman_and_man_holding_hands_tone1_tone4","woman_and_man_holding_hands_light_skin_tone_medium_dark_skin_tone"],"1F469-1F3FB-200D-1F91D-200D-1F468-1F3FF":["woman_and_man_holding_hands_tone1_tone5","woman_and_man_holding_hands_light_skin_tone_dark_skin_tone"],"1F469-1F3FC-200D-1F91D-200D-1F468-1F3FB":["woman_and_man_holding_hands_tone2_tone1","woman_and_man_holding_hands_medium_light_skin_tone_light_skin_tone"],"1F46B-1F3FC":["woman_and_man_holding_hands_tone2","woman_and_man_holding_hands_medium_light_skin_tone"],"1F469-1F3FC-200D-1F91D-200D-1F468-1F3FD":["woman_and_man_holding_hands_tone2_tone3","woman_and_man_holding_hands_medium_light_skin_tone_medium_skin_tone"],"1F469-1F3FC-200D-1F91D-200D-1F468-1F3FE":["woman_and_man_holding_hands_tone2_tone4","woman_and_man_holding_hands_medium_light_skin_tone_medium_dark_skin_tone"],"1F469-1F3FC-200D-1F91D-200D-1F468-1F3FF":["woman_and_man_holding_hands_tone2_tone5","woman_and_man_holding_hands_medium_light_skin_tone_dark_skin_tone"],"1F469-1F3FD-200D-1F91D-200D-1F468-1F3FB":["woman_and_man_holding_hands_tone3_tone1","woman_and_man_holding_hands_medium_skin_tone_light_skin_tone"],"1F469-1F3FD-200D-1F91D-200D-1F468-1F3FC":["woman_and_man_holding_hands_tone3_tone2","woman_and_man_holding_hands_medium_skin_tone_medium_light_skin_tone"],"1F46B-1F3FD":["woman_and_man_holding_hands_tone3","woman_and_man_holding_hands_medium_skin_tone"],"1F469-1F3FD-200D-1F91D-200D-1F468-1F3FE":["woman_and_man_holding_hands_tone3_tone4","woman_and_man_holding_hands_medium_skin_tone_medium_dark_skin_tone"],"1F469-1F3FD-200D-1F91D-200D-1F468-1F3FF":["woman_and_man_holding_hands_tone3_tone5","woman_and_man_holding_hands_medium_skin_tone_dark_skin_tone"],"1F469-1F3FE-200D-1F91D-200D-1F468-1F3FB":["woman_and_man_holding_hands_tone4_tone1","woman_and_man_holding_hands_medium_dark_skin_tone_light_skin_tone"],"1F469-1F3FE-200D-1F91D-200D-1F468-1F3FC":["woman_and_man_holding_hands_tone4_tone2","woman_and_man_holding_hands_medium_dark_skin_tone_medium_light_skin_tone"],"1F469-1F3FE-200D-1F91D-200D-1F468-1F3FD":["woman_and_man_holding_hands_tone4_tone3","woman_and_man_holding_hands_medium_dark_skin_tone_medium_skin_tone"],"1F46B-1F3FE":["woman_and_man_holding_hands_tone4","woman_and_man_holding_hands_medium_dark_skin_tone"],"1F469-1F3FE-200D-1F91D-200D-1F468-1F3FF":["woman_and_man_holding_hands_tone4_tone5","woman_and_man_holding_hands_medium_dark_skin_tone_dark_skin_tone"],"1F469-1F3FF-200D-1F91D-200D-1F468-1F3FB":["woman_and_man_holding_hands_tone5_tone1","woman_and_man_holding_hands_dark_skin_tone_light_skin_tone"],"1F469-1F3FF-200D-1F91D-200D-1F468-1F3FC":["woman_and_man_holding_hands_tone5_tone2","woman_and_man_holding_hands_dark_skin_tone_medium_light_skin_tone"],"1F469-1F3FF-200D-1F91D-200D-1F468-1F3FD":["woman_and_man_holding_hands_tone5_tone3","woman_and_man_holding_hands_dark_skin_tone_medium_skin_tone"],"1F469-1F3FF-200D-1F91D-200D-1F468-1F3FE":["woman_and_man_holding_hands_tone5_tone4","woman_and_man_holding_hands_dark_skin_tone_medium_dark_skin_tone"],"1F46B-1F3FF":["woman_and_man_holding_hands_tone5","woman_and_man_holding_hands_dark_skin_tone"],"1F46D":"two_women_holding_hands","1F46D-1F3FB":["women_holding_hands_tone1","women_holding_hands_light_skin_tone"],"1F469-1F3FB-200D-1F91D-200D-1F469-1F3FC":["women_holding_hands_tone1_tone2","women_holding_hands_light_skin_tone_medium_light_skin_tone"],"1F469-1F3FB-200D-1F91D-200D-1F469-1F3FD":["women_holding_hands_tone1_tone3","women_holding_hands_light_skin_tone_medium_skin_tone"],"1F469-1F3FB-200D-1F91D-200D-1F469-1F3FE":["women_holding_hands_tone1_tone4","women_holding_hands_light_skin_tone_medium_dark_skin_tone"],"1F469-1F3FB-200D-1F91D-200D-1F469-1F3FF":["women_holding_hands_tone1_tone5","women_holding_hands_light_skin_tone_dark_skin_tone"],"1F469-1F3FC-200D-1F91D-200D-1F469-1F3FB":["women_holding_hands_tone2_tone1","women_holding_hands_medium_light_skin_tone_light_skin_tone"],"1F46D-1F3FC":["women_holding_hands_tone2","women_holding_hands_medium_light_skin_tone"],"1F469-1F3FC-200D-1F91D-200D-1F469-1F3FD":["women_holding_hands_tone2_tone3","women_holding_hands_medium_light_skin_tone_medium_skin_tone"],"1F469-1F3FC-200D-1F91D-200D-1F469-1F3FE":["women_holding_hands_tone2_tone4","women_holding_hands_medium_light_skin_tone_medium_dark_skin_tone"],"1F469-1F3FC-200D-1F91D-200D-1F469-1F3FF":["women_holding_hands_tone2_tone5","women_holding_hands_medium_light_skin_tone_dark_skin_tone"],"1F469-1F3FD-200D-1F91D-200D-1F469-1F3FB":["women_holding_hands_tone3_tone1","women_holding_hands_medium_skin_tone_light_skin_tone"],"1F469-1F3FD-200D-1F91D-200D-1F469-1F3FC":["women_holding_hands_tone3_tone2","women_holding_hands_medium_skin_tone_medium_light_skin_tone"],"1F46D-1F3FD":["women_holding_hands_tone3","women_holding_hands_medium_skin_tone"],"1F469-1F3FD-200D-1F91D-200D-1F469-1F3FE":["women_holding_hands_tone3_tone4","women_holding_hands_medium_skin_tone_medium_dark_skin_tone"],"1F469-1F3FD-200D-1F91D-200D-1F469-1F3FF":["women_holding_hands_tone3_tone5","women_holding_hands_medium_skin_tone_dark_skin_tone"],"1F469-1F3FE-200D-1F91D-200D-1F469-1F3FB":["women_holding_hands_tone4_tone1","women_holding_hands_medium_dark_skin_tone_light_skin_tone"],"1F469-1F3FE-200D-1F91D-200D-1F469-1F3FC":["women_holding_hands_tone4_tone2","women_holding_hands_medium_dark_skin_tone_medium_light_skin_tone"],"1F469-1F3FE-200D-1F91D-200D-1F469-1F3FD":["women_holding_hands_tone4_tone3","women_holding_hands_medium_dark_skin_tone_medium_skin_tone"],"1F46D-1F3FE":["women_holding_hands_tone4","women_holding_hands_medium_dark_skin_tone"],"1F469-1F3FE-200D-1F91D-200D-1F469-1F3FF":["women_holding_hands_tone4_tone5","women_holding_hands_medium_dark_skin_tone_dark_skin_tone"],"1F469-1F3FF-200D-1F91D-200D-1F469-1F3FB":["women_holding_hands_tone5_tone1","women_holding_hands_dark_skin_tone_light_skin_tone"],"1F469-1F3FF-200D-1F91D-200D-1F469-1F3FC":["women_holding_hands_tone5_tone2","women_holding_hands_dark_skin_tone_medium_light_skin_tone"],"1F469-1F3FF-200D-1F91D-200D-1F469-1F3FD":["women_holding_hands_tone5_tone3","women_holding_hands_dark_skin_tone_medium_skin_tone"],"1F469-1F3FF-200D-1F91D-200D-1F469-1F3FE":["women_holding_hands_tone5_tone4","women_holding_hands_dark_skin_tone_medium_dark_skin_tone"],"1F46D-1F3FF":["women_holding_hands_tone5","women_holding_hands_dark_skin_tone"],"1F46C":"two_men_holding_hands","1F46C-1F3FB":["men_holding_hands_tone1","men_holding_hands_light_skin_tone"],"1F468-1F3FB-200D-1F91D-200D-1F468-1F3FC":["men_holding_hands_tone1_tone2","men_holding_hands_light_skin_tone_medium_light_skin_tone"],"1F468-1F3FB-200D-1F91D-200D-1F468-1F3FD":["men_holding_hands_tone1_tone3","men_holding_hands_light_skin_tone_medium_skin_tone"],"1F468-1F3FB-200D-1F91D-200D-1F468-1F3FE":["men_holding_hands_tone1_tone4","men_holding_hands_light_skin_tone_medium_dark_skin_tone"],"1F468-1F3FB-200D-1F91D-200D-1F468-1F3FF":["men_holding_hands_tone1_tone5","men_holding_hands_light_skin_tone_dark_skin_tone"],"1F468-1F3FC-200D-1F91D-200D-1F468-1F3FB":["men_holding_hands_tone2_tone1","men_holding_hands_medium_light_skin_tone_light_skin_tone"],"1F46C-1F3FC":["men_holding_hands_tone2","men_holding_hands_medium_light_skin_tone"],"1F468-1F3FC-200D-1F91D-200D-1F468-1F3FD":["men_holding_hands_tone2_tone3","men_holding_hands_medium_light_skin_tone_medium_skin_tone"],"1F468-1F3FC-200D-1F91D-200D-1F468-1F3FE":["men_holding_hands_tone2_tone4","men_holding_hands_medium_light_skin_tone_medium_dark_skin_tone"],"1F468-1F3FC-200D-1F91D-200D-1F468-1F3FF":["men_holding_hands_tone2_tone5","men_holding_hands_medium_light_skin_tone_dark_skin_tone"],"1F468-1F3FD-200D-1F91D-200D-1F468-1F3FB":["men_holding_hands_tone3_tone1","men_holding_hands_medium_skin_tone_light_skin_tone"],"1F468-1F3FD-200D-1F91D-200D-1F468-1F3FC":["men_holding_hands_tone3_tone2","men_holding_hands_medium_skin_tone_medium_light_skin_tone"],"1F46C-1F3FD":["men_holding_hands_tone3","men_holding_hands_medium_skin_tone"],"1F468-1F3FD-200D-1F91D-200D-1F468-1F3FE":["men_holding_hands_tone3_tone4","men_holding_hands_medium_skin_tone_medium_dark_skin_tone"],"1F468-1F3FD-200D-1F91D-200D-1F468-1F3FF":["men_holding_hands_tone3_tone5","men_holding_hands_medium_skin_tone_dark_skin_tone"],"1F468-1F3FE-200D-1F91D-200D-1F468-1F3FB":["men_holding_hands_tone4_tone1","men_holding_hands_medium_dark_skin_tone_light_skin_tone"],"1F468-1F3FE-200D-1F91D-200D-1F468-1F3FC":["men_holding_hands_tone4_tone2","men_holding_hands_medium_dark_skin_tone_medium_light_skin_tone"],"1F468-1F3FE-200D-1F91D-200D-1F468-1F3FD":["men_holding_hands_tone4_tone3","men_holding_hands_medium_dark_skin_tone_medium_skin_tone"],"1F46C-1F3FE":["men_holding_hands_tone4","men_holding_hands_medium_dark_skin_tone"],"1F468-1F3FE-200D-1F91D-200D-1F468-1F3FF":["men_holding_hands_tone4_tone5","men_holding_hands_medium_dark_skin_tone_dark_skin_tone"],"1F468-1F3FF-200D-1F91D-200D-1F468-1F3FB":["men_holding_hands_tone5_tone1","men_holding_hands_dark_skin_tone_light_skin_tone"],"1F468-1F3FF-200D-1F91D-200D-1F468-1F3FC":["men_holding_hands_tone5_tone2","men_holding_hands_dark_skin_tone_medium_light_skin_tone"],"1F468-1F3FF-200D-1F91D-200D-1F468-1F3FD":["men_holding_hands_tone5_tone3","men_holding_hands_dark_skin_tone_medium_skin_tone"],"1F468-1F3FF-200D-1F91D-200D-1F468-1F3FE":["men_holding_hands_tone5_tone4","men_holding_hands_dark_skin_tone_medium_dark_skin_tone"],"1F46C-1F3FF":["men_holding_hands_tone5","men_holding_hands_dark_skin_tone"],"1F491":"couple_with_heart","1F491-1F3FB":["couple_with_heart_tone1","couple_with_heart_light_skin_tone"],"1F9D1-1F3FB-200D-2764-FE0F-200D-1F9D1-1F3FC":["couple_with_heart_person_person_tone1_tone2","couple_with_heart_person_person_light_skin_tone_medium_light_skin_tone"],"1F9D1-1F3FB-200D-2764-FE0F-200D-1F9D1-1F3FD":["couple_with_heart_person_person_tone1_tone3","couple_with_heart_person_person_light_skin_tone_medium_skin_tone"],"1F9D1-1F3FB-200D-2764-FE0F-200D-1F9D1-1F3FE":["couple_with_heart_person_person_tone1_tone4","couple_with_heart_person_person_light_skin_tone_medium_dark_skin_tone"],"1F9D1-1F3FB-200D-2764-FE0F-200D-1F9D1-1F3FF":["couple_with_heart_person_person_tone1_tone5","couple_with_heart_person_person_light_skin_tone_dark_skin_tone"],"1F9D1-1F3FC-200D-2764-FE0F-200D-1F9D1-1F3FB":["couple_with_heart_person_person_tone2_tone1","couple_with_heart_person_person_medium_light_skin_tone_light_skin_tone"],"1F491-1F3FC":["couple_with_heart_tone2","couple_with_heart_medium_light_skin_tone"],"1F9D1-1F3FC-200D-2764-FE0F-200D-1F9D1-1F3FD":["couple_with_heart_person_person_tone2_tone3","couple_with_heart_person_person_medium_light_skin_tone_medium_skin_tone"],"1F9D1-1F3FC-200D-2764-FE0F-200D-1F9D1-1F3FE":["couple_with_heart_person_person_tone2_tone4","couple_with_heart_person_person_medium_light_skin_tone_medium_dark_skin_tone"],"1F9D1-1F3FC-200D-2764-FE0F-200D-1F9D1-1F3FF":["couple_with_heart_person_person_tone2_tone5","couple_with_heart_person_person_medium_light_skin_tone_dark_skin_tone"],"1F9D1-1F3FD-200D-2764-FE0F-200D-1F9D1-1F3FB":["couple_with_heart_person_person_tone3_tone1","couple_with_heart_person_person_medium_skin_tone_light_skin_tone"],"1F9D1-1F3FD-200D-2764-FE0F-200D-1F9D1-1F3FC":["couple_with_heart_person_person_tone3_tone2","couple_with_heart_person_person_medium_skin_tone_medium_light_skin_tone"],"1F491-1F3FD":["couple_with_heart_tone3","couple_with_heart_medium_skin_tone"],"1F9D1-1F3FD-200D-2764-FE0F-200D-1F9D1-1F3FE":["couple_with_heart_person_person_tone3_tone4","couple_with_heart_person_person_medium_skin_tone_medium_dark_skin_tone"],"1F9D1-1F3FD-200D-2764-FE0F-200D-1F9D1-1F3FF":["couple_with_heart_person_person_tone3_tone5","couple_with_heart_person_person_medium_skin_tone_dark_skin_tone"],"1F9D1-1F3FE-200D-2764-FE0F-200D-1F9D1-1F3FB":["couple_with_heart_person_person_tone4_tone1","couple_with_heart_person_person_medium_dark_skin_tone_light_skin_tone"],"1F9D1-1F3FE-200D-2764-FE0F-200D-1F9D1-1F3FC":["couple_with_heart_person_person_tone4_tone2","couple_with_heart_person_person_medium_dark_skin_tone_medium_light_skin_tone"],"1F9D1-1F3FE-200D-2764-FE0F-200D-1F9D1-1F3FD":["couple_with_heart_person_person_tone4_tone3","couple_with_heart_person_person_medium_dark_skin_tone_medium_skin_tone"],"1F491-1F3FE":["couple_with_heart_tone4","couple_with_heart_medium_dark_skin_tone"],"1F9D1-1F3FE-200D-2764-FE0F-200D-1F9D1-1F3FF":["couple_with_heart_person_person_tone4_tone5","couple_with_heart_person_person_medium_dark_skin_tone_dark_skin_tone"],"1F9D1-1F3FF-200D-2764-FE0F-200D-1F9D1-1F3FB":["couple_with_heart_person_person_tone5_tone1","couple_with_heart_person_person_dark_skin_tone_light_skin_tone"],"1F9D1-1F3FF-200D-2764-FE0F-200D-1F9D1-1F3FC":["couple_with_heart_person_person_tone5_tone2","couple_with_heart_person_person_dark_skin_tone_medium_light_skin_tone"],"1F9D1-1F3FF-200D-2764-FE0F-200D-1F9D1-1F3FD":["couple_with_heart_person_person_tone5_tone3","couple_with_heart_person_person_dark_skin_tone_medium_skin_tone"],"1F9D1-1F3FF-200D-2764-FE0F-200D-1F9D1-1F3FE":["couple_with_heart_person_person_tone5_tone4","couple_with_heart_person_person_dark_skin_tone_medium_dark_skin_tone"],"1F491-1F3FF":["couple_with_heart_tone5","couple_with_heart_dark_skin_tone"],"1F469-200D-2764-FE0F-200D-1F468":"couple_with_heart_woman_man","1F469-1F3FB-200D-2764-FE0F-200D-1F468-1F3FB":["couple_with_heart_woman_man_tone1","couple_with_heart_woman_man_light_skin_tone"],"1F469-1F3FB-200D-2764-FE0F-200D-1F468-1F3FC":["couple_with_heart_woman_man_tone1_tone2","couple_with_heart_woman_man_light_skin_tone_medium_light_skin_tone"],"1F469-1F3FB-200D-2764-FE0F-200D-1F468-1F3FD":["couple_with_heart_woman_man_tone1_tone3","couple_with_heart_woman_man_light_skin_tone_medium_skin_tone"],"1F469-1F3FB-200D-2764-FE0F-200D-1F468-1F3FE":["couple_with_heart_woman_man_tone1_tone4","couple_with_heart_woman_man_light_skin_tone_medium_dark_skin_tone"],"1F469-1F3FB-200D-2764-FE0F-200D-1F468-1F3FF":["couple_with_heart_woman_man_tone1_tone5","couple_with_heart_woman_man_light_skin_tone_dark_skin_tone"],"1F469-1F3FC-200D-2764-FE0F-200D-1F468-1F3FB":["couple_with_heart_woman_man_tone2_tone1","couple_with_heart_woman_man_medium_light_skin_tone_light_skin_tone"],"1F469-1F3FC-200D-2764-FE0F-200D-1F468-1F3FC":["couple_with_heart_woman_man_tone2","couple_with_heart_woman_man_medium_light_skin_tone"],"1F469-1F3FC-200D-2764-FE0F-200D-1F468-1F3FD":["couple_with_heart_woman_man_tone2_tone3","couple_with_heart_woman_man_medium_light_skin_tone_medium_skin_tone"],"1F469-1F3FC-200D-2764-FE0F-200D-1F468-1F3FE":["couple_with_heart_woman_man_tone2_tone4","couple_with_heart_woman_man_medium_light_skin_tone_medium_dark_skin_tone"],"1F469-1F3FC-200D-2764-FE0F-200D-1F468-1F3FF":["couple_with_heart_woman_man_tone2_tone5","couple_with_heart_woman_man_medium_light_skin_tone_dark_skin_tone"],"1F469-1F3FD-200D-2764-FE0F-200D-1F468-1F3FB":["couple_with_heart_woman_man_tone3_tone1","couple_with_heart_woman_man_medium_skin_tone_light_skin_tone"],"1F469-1F3FD-200D-2764-FE0F-200D-1F468-1F3FC":["couple_with_heart_woman_man_tone3_tone2","couple_with_heart_woman_man_medium_skin_tone_medium_light_skin_tone"],"1F469-1F3FD-200D-2764-FE0F-200D-1F468-1F3FD":["couple_with_heart_woman_man_tone3","couple_with_heart_woman_man_medium_skin_tone"],"1F469-1F3FD-200D-2764-FE0F-200D-1F468-1F3FE":["couple_with_heart_woman_man_tone3_tone4","couple_with_heart_woman_man_medium_skin_tone_medium_dark_skin_tone"],"1F469-1F3FD-200D-2764-FE0F-200D-1F468-1F3FF":["couple_with_heart_woman_man_tone3_tone5","couple_with_heart_woman_man_medium_skin_tone_dark_skin_tone"],"1F469-1F3FE-200D-2764-FE0F-200D-1F468-1F3FB":["couple_with_heart_woman_man_tone4_tone1","couple_with_heart_woman_man_medium_dark_skin_tone_light_skin_tone"],"1F469-1F3FE-200D-2764-FE0F-200D-1F468-1F3FC":["couple_with_heart_woman_man_tone4_tone2","couple_with_heart_woman_man_medium_dark_skin_tone_medium_light_skin_tone"],"1F469-1F3FE-200D-2764-FE0F-200D-1F468-1F3FD":["couple_with_heart_woman_man_tone4_tone3","couple_with_heart_woman_man_medium_dark_skin_tone_medium_skin_tone"],"1F469-1F3FE-200D-2764-FE0F-200D-1F468-1F3FE":["couple_with_heart_woman_man_tone4","couple_with_heart_woman_man_medium_dark_skin_tone"],"1F469-1F3FE-200D-2764-FE0F-200D-1F468-1F3FF":["couple_with_heart_woman_man_tone4_tone5","couple_with_heart_woman_man_medium_dark_skin_tone_dark_skin_tone"],"1F469-1F3FF-200D-2764-FE0F-200D-1F468-1F3FB":["couple_with_heart_woman_man_tone5_tone1","couple_with_heart_woman_man_dark_skin_tone_light_skin_tone"],"1F469-1F3FF-200D-2764-FE0F-200D-1F468-1F3FC":["couple_with_heart_woman_man_tone5_tone2","couple_with_heart_woman_man_dark_skin_tone_medium_light_skin_tone"],"1F469-1F3FF-200D-2764-FE0F-200D-1F468-1F3FD":["couple_with_heart_woman_man_tone5_tone3","couple_with_heart_woman_man_dark_skin_tone_medium_skin_tone"],"1F469-1F3FF-200D-2764-FE0F-200D-1F468-1F3FE":["couple_with_heart_woman_man_tone5_tone4","couple_with_heart_woman_man_dark_skin_tone_medium_dark_skin_tone"],"1F469-1F3FF-200D-2764-FE0F-200D-1F468-1F3FF":["couple_with_heart_woman_man_tone5","couple_with_heart_woman_man_dark_skin_tone"],"1F469-200D-2764-FE0F-200D-1F469":["couple_ww","couple_with_heart_ww"],"1F469-1F3FB-200D-2764-FE0F-200D-1F469-1F3FB":["couple_with_heart_woman_woman_tone1","couple_with_heart_woman_woman_light_skin_tone"],"1F469-1F3FB-200D-2764-FE0F-200D-1F469-1F3FC":["couple_with_heart_woman_woman_tone1_tone2","couple_with_heart_woman_woman_light_skin_tone_medium_light_skin_tone"],"1F469-1F3FB-200D-2764-FE0F-200D-1F469-1F3FD":["couple_with_heart_woman_woman_tone1_tone3","couple_with_heart_woman_woman_light_skin_tone_medium_skin_tone"],"1F469-1F3FB-200D-2764-FE0F-200D-1F469-1F3FE":["couple_with_heart_woman_woman_tone1_tone4","couple_with_heart_woman_woman_light_skin_tone_medium_dark_skin_tone"],"1F469-1F3FB-200D-2764-FE0F-200D-1F469-1F3FF":["couple_with_heart_woman_woman_tone1_tone5","couple_with_heart_woman_woman_light_skin_tone_dark_skin_tone"],"1F469-1F3FC-200D-2764-FE0F-200D-1F469-1F3FB":["couple_with_heart_woman_woman_tone2_tone1","couple_with_heart_woman_woman_medium_light_skin_tone_light_skin_tone"],"1F469-1F3FC-200D-2764-FE0F-200D-1F469-1F3FC":["couple_with_heart_woman_woman_tone2","couple_with_heart_woman_woman_medium_light_skin_tone"],"1F469-1F3FC-200D-2764-FE0F-200D-1F469-1F3FD":["couple_with_heart_woman_woman_tone2_tone3","couple_with_heart_woman_woman_medium_light_skin_tone_medium_skin_tone"],"1F469-1F3FC-200D-2764-FE0F-200D-1F469-1F3FE":["couple_with_heart_woman_woman_tone2_tone4","couple_with_heart_woman_woman_medium_light_skin_tone_medium_dark_skin_tone"],"1F469-1F3FC-200D-2764-FE0F-200D-1F469-1F3FF":["couple_with_heart_woman_woman_tone2_tone5","couple_with_heart_woman_woman_medium_light_skin_tone_dark_skin_tone"],"1F469-1F3FD-200D-2764-FE0F-200D-1F469-1F3FB":["couple_with_heart_woman_woman_tone3_tone1","couple_with_heart_woman_woman_medium_skin_tone_light_skin_tone"],"1F469-1F3FD-200D-2764-FE0F-200D-1F469-1F3FC":["couple_with_heart_woman_woman_tone3_tone2","couple_with_heart_woman_woman_medium_skin_tone_medium_light_skin_tone"],"1F469-1F3FD-200D-2764-FE0F-200D-1F469-1F3FD":["couple_with_heart_woman_woman_tone3","couple_with_heart_woman_woman_medium_skin_tone"],"1F469-1F3FD-200D-2764-FE0F-200D-1F469-1F3FE":["couple_with_heart_woman_woman_tone3_tone4","couple_with_heart_woman_woman_medium_skin_tone_medium_dark_skin_tone"],"1F469-1F3FD-200D-2764-FE0F-200D-1F469-1F3FF":["couple_with_heart_woman_woman_tone3_tone5","couple_with_heart_woman_woman_medium_skin_tone_dark_skin_tone"],"1F469-1F3FE-200D-2764-FE0F-200D-1F469-1F3FB":["couple_with_heart_woman_woman_tone4_tone1","couple_with_heart_woman_woman_medium_dark_skin_tone_light_skin_tone"],"1F469-1F3FE-200D-2764-FE0F-200D-1F469-1F3FC":["couple_with_heart_woman_woman_tone4_tone2","couple_with_heart_woman_woman_medium_dark_skin_tone_medium_light_skin_tone"],"1F469-1F3FE-200D-2764-FE0F-200D-1F469-1F3FD":["couple_with_heart_woman_woman_tone4_tone3","couple_with_heart_woman_woman_medium_dark_skin_tone_medium_skin_tone"],"1F469-1F3FE-200D-2764-FE0F-200D-1F469-1F3FE":["couple_with_heart_woman_woman_tone4","couple_with_heart_woman_woman_medium_dark_skin_tone"],"1F469-1F3FE-200D-2764-FE0F-200D-1F469-1F3FF":["couple_with_heart_woman_woman_tone4_tone5","couple_with_heart_woman_woman_medium_dark_skin_tone_dark_skin_tone"],"1F469-1F3FF-200D-2764-FE0F-200D-1F469-1F3FB":["couple_with_heart_woman_woman_tone5_tone1","couple_with_heart_woman_woman_dark_skin_tone_light_skin_tone"],"1F469-1F3FF-200D-2764-FE0F-200D-1F469-1F3FC":["couple_with_heart_woman_woman_tone5_tone2","couple_with_heart_woman_woman_dark_skin_tone_medium_light_skin_tone"],"1F469-1F3FF-200D-2764-FE0F-200D-1F469-1F3FD":["couple_with_heart_woman_woman_tone5_tone3","couple_with_heart_woman_woman_dark_skin_tone_medium_skin_tone"],"1F469-1F3FF-200D-2764-FE0F-200D-1F469-1F3FE":["couple_with_heart_woman_woman_tone5_tone4","couple_with_heart_woman_woman_dark_skin_tone_medium_dark_skin_tone"],"1F469-1F3FF-200D-2764-FE0F-200D-1F469-1F3FF":["couple_with_heart_woman_woman_tone5","couple_with_heart_woman_woman_dark_skin_tone"],"1F468-200D-2764-FE0F-200D-1F468":["couple_mm","couple_with_heart_mm"],"1F468-1F3FB-200D-2764-FE0F-200D-1F468-1F3FB":["couple_with_heart_man_man_tone1","couple_with_heart_man_man_light_skin_tone"],"1F468-1F3FB-200D-2764-FE0F-200D-1F468-1F3FC":["couple_with_heart_man_man_tone1_tone2","couple_with_heart_man_man_light_skin_tone_medium_light_skin_tone"],"1F468-1F3FB-200D-2764-FE0F-200D-1F468-1F3FD":["couple_with_heart_man_man_tone1_tone3","couple_with_heart_man_man_light_skin_tone_medium_skin_tone"],"1F468-1F3FB-200D-2764-FE0F-200D-1F468-1F3FE":["couple_with_heart_man_man_tone1_tone4","couple_with_heart_man_man_light_skin_tone_medium_dark_skin_tone"],"1F468-1F3FB-200D-2764-FE0F-200D-1F468-1F3FF":["couple_with_heart_man_man_tone1_tone5","couple_with_heart_man_man_light_skin_tone_dark_skin_tone"],"1F468-1F3FC-200D-2764-FE0F-200D-1F468-1F3FB":["couple_with_heart_man_man_tone2_tone1","couple_with_heart_man_man_medium_light_skin_tone_light_skin_tone"],"1F468-1F3FC-200D-2764-FE0F-200D-1F468-1F3FC":["couple_with_heart_man_man_tone2","couple_with_heart_man_man_medium_light_skin_tone"],"1F468-1F3FC-200D-2764-FE0F-200D-1F468-1F3FD":["couple_with_heart_man_man_tone2_tone3","couple_with_heart_man_man_medium_light_skin_tone_medium_skin_tone"],"1F468-1F3FC-200D-2764-FE0F-200D-1F468-1F3FE":["couple_with_heart_man_man_tone2_tone4","couple_with_heart_man_man_medium_light_skin_tone_medium_dark_skin_tone"],"1F468-1F3FC-200D-2764-FE0F-200D-1F468-1F3FF":["couple_with_heart_man_man_tone2_tone5","couple_with_heart_man_man_medium_light_skin_tone_dark_skin_tone"],"1F468-1F3FD-200D-2764-FE0F-200D-1F468-1F3FB":["couple_with_heart_man_man_tone3_tone1","couple_with_heart_man_man_medium_skin_tone_light_skin_tone"],"1F468-1F3FD-200D-2764-FE0F-200D-1F468-1F3FC":["couple_with_heart_man_man_tone3_tone2","couple_with_heart_man_man_medium_skin_tone_medium_light_skin_tone"],"1F468-1F3FD-200D-2764-FE0F-200D-1F468-1F3FD":["couple_with_heart_man_man_tone3","couple_with_heart_man_man_medium_skin_tone"],"1F468-1F3FD-200D-2764-FE0F-200D-1F468-1F3FE":["couple_with_heart_man_man_tone3_tone4","couple_with_heart_man_man_medium_skin_tone_medium_dark_skin_tone"],"1F468-1F3FD-200D-2764-FE0F-200D-1F468-1F3FF":["couple_with_heart_man_man_tone3_tone5","couple_with_heart_man_man_medium_skin_tone_dark_skin_tone"],"1F468-1F3FE-200D-2764-FE0F-200D-1F468-1F3FB":["couple_with_heart_man_man_tone4_tone1","couple_with_heart_man_man_medium_dark_skin_tone_light_skin_tone"],"1F468-1F3FE-200D-2764-FE0F-200D-1F468-1F3FC":["couple_with_heart_man_man_tone4_tone2","couple_with_heart_man_man_medium_dark_skin_tone_medium_light_skin_tone"],"1F468-1F3FE-200D-2764-FE0F-200D-1F468-1F3FD":["couple_with_heart_man_man_tone4_tone3","couple_with_heart_man_man_medium_dark_skin_tone_medium_skin_tone"],"1F468-1F3FE-200D-2764-FE0F-200D-1F468-1F3FE":["couple_with_heart_man_man_tone4","couple_with_heart_man_man_medium_dark_skin_tone"],"1F468-1F3FE-200D-2764-FE0F-200D-1F468-1F3FF":["couple_with_heart_man_man_tone4_tone5","couple_with_heart_man_man_medium_dark_skin_tone_dark_skin_tone"],"1F468-1F3FF-200D-2764-FE0F-200D-1F468-1F3FB":["couple_with_heart_man_man_tone5_tone1","couple_with_heart_man_man_dark_skin_tone_light_skin_tone"],"1F468-1F3FF-200D-2764-FE0F-200D-1F468-1F3FC":["couple_with_heart_man_man_tone5_tone2","couple_with_heart_man_man_dark_skin_tone_medium_light_skin_tone"],"1F468-1F3FF-200D-2764-FE0F-200D-1F468-1F3FD":["couple_with_heart_man_man_tone5_tone3","couple_with_heart_man_man_dark_skin_tone_medium_skin_tone"],"1F468-1F3FF-200D-2764-FE0F-200D-1F468-1F3FE":["couple_with_heart_man_man_tone5_tone4","couple_with_heart_man_man_dark_skin_tone_medium_dark_skin_tone"],"1F468-1F3FF-200D-2764-FE0F-200D-1F468-1F3FF":["couple_with_heart_man_man_tone5","couple_with_heart_man_man_dark_skin_tone"],"1F48F":"couplekiss","1F48F-1F3FB":["kiss_tone1","kiss_light_skin_tone"],"1F9D1-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FC":["kiss_person_person_tone1_tone2","kiss_person_person_light_skin_tone_medium_light_skin_tone"],"1F9D1-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FD":["kiss_person_person_tone1_tone3","kiss_person_person_light_skin_tone_medium_skin_tone"],"1F9D1-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FE":["kiss_person_person_tone1_tone4","kiss_person_person_light_skin_tone_medium_dark_skin_tone"],"1F9D1-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FF":["kiss_person_person_tone1_tone5","kiss_person_person_light_skin_tone_dark_skin_tone"],"1F9D1-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FB":["kiss_person_person_tone2_tone1","kiss_person_person_medium_light_skin_tone_light_skin_tone"],"1F48F-1F3FC":["kiss_tone2","kiss_medium_light_skin_tone"],"1F9D1-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FD":["kiss_person_person_tone2_tone3","kiss_person_person_medium_light_skin_tone_medium_skin_tone"],"1F9D1-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FE":["kiss_person_person_tone2_tone4","kiss_person_person_medium_light_skin_tone_medium_dark_skin_tone"],"1F9D1-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FF":["kiss_person_person_tone2_tone5","kiss_person_person_medium_light_skin_tone_dark_skin_tone"],"1F9D1-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FB":["kiss_person_person_tone3_tone1","kiss_person_person_medium_skin_tone_light_skin_tone"],"1F9D1-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FC":["kiss_person_person_tone3_tone2","kiss_person_person_medium_skin_tone_medium_light_skin_tone"],"1F48F-1F3FD":["kiss_tone3","kiss_medium_skin_tone"],"1F9D1-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FE":["kiss_person_person_tone3_tone4","kiss_person_person_medium_skin_tone_medium_dark_skin_tone"],"1F9D1-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FF":["kiss_person_person_tone3_tone5","kiss_person_person_medium_skin_tone_dark_skin_tone"],"1F9D1-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FB":["kiss_person_person_tone4_tone1","kiss_person_person_medium_dark_skin_tone_light_skin_tone"],"1F9D1-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FC":["kiss_person_person_tone4_tone2","kiss_person_person_medium_dark_skin_tone_medium_light_skin_tone"],"1F9D1-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FD":["kiss_person_person_tone4_tone3","kiss_person_person_medium_dark_skin_tone_medium_skin_tone"],"1F48F-1F3FE":["kiss_tone4","kiss_medium_dark_skin_tone"],"1F9D1-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FF":["kiss_person_person_tone4_tone5","kiss_person_person_medium_dark_skin_tone_dark_skin_tone"],"1F9D1-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FB":["kiss_person_person_tone5_tone1","kiss_person_person_dark_skin_tone_light_skin_tone"],"1F9D1-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FC":["kiss_person_person_tone5_tone2","kiss_person_person_dark_skin_tone_medium_light_skin_tone"],"1F9D1-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FD":["kiss_person_person_tone5_tone3","kiss_person_person_dark_skin_tone_medium_skin_tone"],"1F48F-1F3FF":["kiss_tone5","kiss_dark_skin_tone"],"1F469-200D-2764-FE0F-200D-1F48B-200D-1F468":"kiss_woman_man","1F469-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FB":["kiss_woman_man_tone1","kiss_woman_man_light_skin_tone"],"1F469-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FC":["kiss_woman_man_tone1_tone2","kiss_woman_man_light_skin_tone_medium_light_skin_tone"],"1F469-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FD":["kiss_woman_man_tone1_tone3","kiss_woman_man_light_skin_tone_medium_skin_tone"],"1F469-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FE":["kiss_woman_man_tone1_tone4","kiss_woman_man_light_skin_tone_medium_dark_skin_tone"],"1F469-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FF":["kiss_woman_man_tone1_tone5","kiss_woman_man_light_skin_tone_dark_skin_tone"],"1F469-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FB":["kiss_woman_man_tone2_tone1","kiss_woman_man_medium_light_skin_tone_light_skin_tone"],"1F469-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FC":["kiss_woman_man_tone2","kiss_woman_man_medium_light_skin_tone"],"1F469-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FD":["kiss_woman_man_tone2_tone3","kiss_woman_man_medium_light_skin_tone_medium_skin_tone"],"1F469-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FE":["kiss_woman_man_tone2_tone4","kiss_woman_man_medium_light_skin_tone_medium_dark_skin_tone"],"1F469-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FF":["kiss_woman_man_tone2_tone5","kiss_woman_man_medium_light_skin_tone_dark_skin_tone"],"1F469-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FB":["kiss_woman_man_tone3_tone1","kiss_woman_man_medium_skin_tone_light_skin_tone"],"1F469-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FC":["kiss_woman_man_tone3_tone2","kiss_woman_man_medium_skin_tone_medium_light_skin_tone"],"1F469-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FD":["kiss_woman_man_tone3","kiss_woman_man_medium_skin_tone"],"1F469-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FE":["kiss_woman_man_tone3_tone4","kiss_woman_man_medium_skin_tone_medium_dark_skin_tone"],"1F469-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FF":["kiss_woman_man_tone3_tone5","kiss_woman_man_medium_skin_tone_dark_skin_tone"],"1F469-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FB":["kiss_woman_man_tone4_tone1","kiss_woman_man_medium_dark_skin_tone_light_skin_tone"],"1F469-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FC":["kiss_woman_man_tone4_tone2","kiss_woman_man_medium_dark_skin_tone_medium_light_skin_tone"],"1F469-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FD":["kiss_woman_man_tone4_tone3","kiss_woman_man_medium_dark_skin_tone_medium_skin_tone"],"1F469-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FE":["kiss_woman_man_tone4","kiss_woman_man_medium_dark_skin_tone"],"1F469-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FF":["kiss_woman_man_tone4_tone5","kiss_woman_man_medium_dark_skin_tone_dark_skin_tone"],"1F469-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FB":["kiss_woman_man_tone5_tone1","kiss_woman_man_dark_skin_tone_light_skin_tone"],"1F469-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FC":["kiss_woman_man_tone5_tone2","kiss_woman_man_dark_skin_tone_medium_light_skin_tone"],"1F469-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FD":["kiss_woman_man_tone5_tone3","kiss_woman_man_dark_skin_tone_medium_skin_tone"],"1F469-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FE":["kiss_woman_man_tone5_tone4","kiss_woman_man_dark_skin_tone_medium_dark_skin_tone"],"1F469-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FF":["kiss_woman_man_tone5","kiss_woman_man_dark_skin_tone"],"1F469-200D-2764-FE0F-200D-1F48B-200D-1F469":["kiss_ww","couplekiss_ww"],"1F469-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FB":["kiss_woman_woman_tone1","kiss_woman_woman_light_skin_tone"],"1F469-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FC":["kiss_woman_woman_tone1_tone2","kiss_woman_woman_light_skin_tone_medium_light_skin_tone"],"1F469-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FD":["kiss_woman_woman_tone1_tone3","kiss_woman_woman_light_skin_tone_medium_skin_tone"],"1F469-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FE":["kiss_woman_woman_tone1_tone4","kiss_woman_woman_light_skin_tone_medium_dark_skin_tone"],"1F469-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FF":["kiss_woman_woman_tone1_tone5","kiss_woman_woman_light_skin_tone_dark_skin_tone"],"1F469-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FB":["kiss_woman_woman_tone2_tone1","kiss_woman_woman_medium_light_skin_tone_light_skin_tone"],"1F469-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FC":["kiss_woman_woman_tone2","kiss_woman_woman_medium_light_skin_tone"],"1F469-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FD":["kiss_woman_woman_tone2_tone3","kiss_woman_woman_medium_light_skin_tone_medium_skin_tone"],"1F469-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FE":["kiss_woman_woman_tone2_tone4","kiss_woman_woman_medium_light_skin_tone_medium_dark_skin_tone"],"1F469-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FF":["kiss_woman_woman_tone2_tone5","kiss_woman_woman_medium_light_skin_tone_dark_skin_tone"],"1F469-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FB":["kiss_woman_woman_tone3_tone1","kiss_woman_woman_medium_skin_tone_light_skin_tone"],"1F469-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FC":["kiss_woman_woman_tone3_tone2","kiss_woman_woman_medium_skin_tone_medium_light_skin_tone"],"1F469-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FD":["kiss_woman_woman_tone3","kiss_woman_woman_medium_skin_tone"],"1F469-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FE":["kiss_woman_woman_tone3_tone4","kiss_woman_woman_medium_skin_tone_medium_dark_skin_tone"],"1F469-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FF":["kiss_woman_woman_tone3_tone5","kiss_woman_woman_medium_skin_tone_dark_skin_tone"],"1F469-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FB":["kiss_woman_woman_tone4_tone1","kiss_woman_woman_medium_dark_skin_tone_light_skin_tone"],"1F469-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FC":["kiss_woman_woman_tone4_tone2","kiss_woman_woman_medium_dark_skin_tone_medium_light_skin_tone"],"1F469-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FD":["kiss_woman_woman_tone4_tone3","kiss_woman_woman_medium_dark_skin_tone_medium_skin_tone"],"1F469-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FE":["kiss_woman_woman_tone4","kiss_woman_woman_medium_dark_skin_tone"],"1F469-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FF":["kiss_woman_woman_tone4_tone5","kiss_woman_woman_medium_dark_skin_tone_dark_skin_tone"],"1F469-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FB":["kiss_woman_woman_tone5_tone1","kiss_woman_woman_dark_skin_tone_light_skin_tone"],"1F469-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FC":["kiss_woman_woman_tone5_tone2","kiss_woman_woman_dark_skin_tone_medium_light_skin_tone"],"1F469-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FD":["kiss_woman_woman_tone5_tone3","kiss_woman_woman_dark_skin_tone_medium_skin_tone"],"1F469-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FE":["kiss_woman_woman_tone5_tone4","kiss_woman_woman_dark_skin_tone_medium_dark_skin_tone"],"1F469-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FF":["kiss_woman_woman_tone5","kiss_woman_woman_dark_skin_tone"],"1F468-200D-2764-FE0F-200D-1F48B-200D-1F468":["kiss_mm","couplekiss_mm"],"1F468-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FB":["kiss_man_man_tone1","kiss_man_man_light_skin_tone"],"1F468-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FC":["kiss_man_man_tone1_tone2","kiss_man_man_light_skin_tone_medium_light_skin_tone"],"1F468-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FD":["kiss_man_man_tone1_tone3","kiss_man_man_light_skin_tone_medium_skin_tone"],"1F468-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FE":["kiss_man_man_tone1_tone4","kiss_man_man_light_skin_tone_medium_dark_skin_tone"],"1F468-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FF":["kiss_man_man_tone1_tone5","kiss_man_man_light_skin_tone_dark_skin_tone"],"1F468-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FB":["kiss_man_man_tone2_tone1","kiss_man_man_medium_light_skin_tone_light_skin_tone"],"1F468-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FC":["kiss_man_man_tone2","kiss_man_man_medium_light_skin_tone"],"1F468-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FD":["kiss_man_man_tone2_tone3","kiss_man_man_medium_light_skin_tone_medium_skin_tone"],"1F468-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FE":["kiss_man_man_tone2_tone4","kiss_man_man_medium_light_skin_tone_medium_dark_skin_tone"],"1F468-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FF":["kiss_man_man_tone2_tone5","kiss_man_man_medium_light_skin_tone_dark_skin_tone"],"1F468-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FB":["kiss_man_man_tone3_tone1","kiss_man_man_medium_skin_tone_light_skin_tone"],"1F468-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FC":["kiss_man_man_tone3_tone2","kiss_man_man_medium_skin_tone_medium_light_skin_tone"],"1F468-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FD":["kiss_man_man_tone3","kiss_man_man_medium_skin_tone"],"1F468-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FE":["kiss_man_man_tone3_tone4","kiss_man_man_medium_skin_tone_medium_dark_skin_tone"],"1F468-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FF":["kiss_man_man_tone3_tone5","kiss_man_man_medium_skin_tone_dark_skin_tone"],"1F468-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FB":["kiss_man_man_tone4_tone1","kiss_man_man_medium_dark_skin_tone_light_skin_tone"],"1F468-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FC":["kiss_man_man_tone4_tone2","kiss_man_man_medium_dark_skin_tone_medium_light_skin_tone"],"1F468-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FD":["kiss_man_man_tone4_tone3","kiss_man_man_medium_dark_skin_tone_medium_skin_tone"],"1F468-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FE":["kiss_man_man_tone4","kiss_man_man_medium_dark_skin_tone"],"1F468-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FF":["kiss_man_man_tone4_tone5","kiss_man_man_medium_dark_skin_tone_dark_skin_tone"],"1F468-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FB":["kiss_man_man_tone5_tone1","kiss_man_man_dark_skin_tone_light_skin_tone"],"1F468-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FC":["kiss_man_man_tone5_tone2","kiss_man_man_dark_skin_tone_medium_light_skin_tone"],"1F468-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FD":["kiss_man_man_tone5_tone3","kiss_man_man_dark_skin_tone_medium_skin_tone"],"1F468-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FE":["kiss_man_man_tone5_tone4","kiss_man_man_dark_skin_tone_medium_dark_skin_tone"],"1F468-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FF":["kiss_man_man_tone5","kiss_man_man_dark_skin_tone"],"1F46A":"family","1F468-200D-1F469-200D-1F466":"family_man_woman_boy","1F468-200D-1F469-200D-1F467":"family_mwg","1F468-200D-1F469-200D-1F467-200D-1F466":"family_mwgb","1F468-200D-1F469-200D-1F466-200D-1F466":"family_mwbb","1F468-200D-1F469-200D-1F467-200D-1F467":"family_mwgg","1F469-200D-1F469-200D-1F466":"family_wwb","1F469-200D-1F469-200D-1F467":"family_wwg","1F469-200D-1F469-200D-1F467-200D-1F466":"family_wwgb","1F469-200D-1F469-200D-1F466-200D-1F466":"family_wwbb","1F469-200D-1F469-200D-1F467-200D-1F467":"family_wwgg","1F468-200D-1F468-200D-1F466":"family_mmb","1F468-200D-1F468-200D-1F467":"family_mmg","1F468-200D-1F468-200D-1F467-200D-1F466":"family_mmgb","1F468-200D-1F468-200D-1F466-200D-1F466":"family_mmbb","1F468-200D-1F468-200D-1F467-200D-1F467":"family_mmgg","1F469-200D-1F466":"family_woman_boy","1F469-200D-1F467":"family_woman_girl","1F469-200D-1F467-200D-1F466":"family_woman_girl_boy","1F469-200D-1F466-200D-1F466":"family_woman_boy_boy","1F469-200D-1F467-200D-1F467":"family_woman_girl_girl","1F468-200D-1F466":"family_man_boy","1F468-200D-1F467":"family_man_girl","1F468-200D-1F467-200D-1F466":"family_man_girl_boy","1F468-200D-1F466-200D-1F466":"family_man_boy_boy","1F468-200D-1F467-200D-1F467":"family_man_girl_girl","1F9F6":"yarn","1F9F5":"thread","1F9E5":"coat","1F97C":"lab_coat","1F9BA":"safety_vest","1F45A":"womans_clothes","1F455":"shirt","1F456":"jeans","1FA72":"briefs","1FA73":"shorts","1F454":"necktie","1F457":"dress","1F459":"bikini","1FA71":"one_piece_swimsuit","1F458":"kimono","1F97B":"sari","1F97F":"womans_flat_shoe","1F460":"high_heel","1F461":"sandal","1F462":"boot","1F45E":"mans_shoe","1F45F":"athletic_shoe","1F97E":"hiking_boot","1FA74":"thong_sandal","1F9E6":"socks","1F9E4":"gloves","1F9E3":"scarf","1F3A9":"tophat","1F9E2":"billed_cap","1F452":"womans_hat","1F393":"mortar_board","26D1":["helmet_with_cross","helmet_with_white_cross"],"1FA96":"military_helmet","1F451":"crown","1F48D":"ring","1F45D":"pouch","1F45B":"purse","1F45C":"handbag","1F4BC":"briefcase","1F392":"school_satchel","1F9F3":"luggage","1F453":"eyeglasses","1F576":"dark_sunglasses","1F97D":"goggles","1F302":"closed_umbrella","1F9B1":"curly_haired","1F9B0":"red_haired","1F9B3":"white_haired","1F9B2":"bald","1F436":"dog","1F431":"cat","1F42D":"mouse","1F439":"hamster","1F430":"rabbit","1F98A":["fox","fox_face"],"1F43B":"bear","1F43C":"panda_face","1F43B-200D-2744-FE0F":"polar_bear","1F428":"koala","1F42F":"tiger","1F981":["lion_face","lion"],"1F42E":"cow","1F437":"pig","1F43D":"pig_nose","1F438":"frog","1F435":"monkey_face","1F648":"see_no_evil","1F649":"hear_no_evil","1F64A":"speak_no_evil","1F412":"monkey","1F414":"chicken","1F427":"penguin","1F426":"bird","1F424":"baby_chick","1F423":"hatching_chick","1F425":"hatched_chick","1F986":"duck","1F9A4":"dodo","1F985":"eagle","1F989":"owl","1F987":"bat","1F43A":"wolf","1F417":"boar","1F434":"horse","1F984":["unicorn","unicorn_face"],"1F41D":"bee","1F41B":"bug","1F98B":"butterfly","1F40C":"snail","1FAB1":"worm","1F41E":"lady_beetle","1F41C":"ant","1FAB0":"fly","1F99F":"mosquito","1FAB3":"cockroach","1FAB2":"beetle","1F997":"cricket","1F577":"spider","1F578":"spider_web","1F982":"scorpion","1F422":"turtle","1F40D":"snake","1F98E":"lizard","1F996":"t_rex","1F995":"sauropod","1F419":"octopus","1F991":"squid","1F990":"shrimp","1F99E":"lobster","1F980":"crab","1F421":"blowfish","1F420":"tropical_fish","1F41F":"fish","1F9AD":"seal","1F42C":"dolphin","1F433":"whale","1F40B":"whale2","1F988":"shark","1F40A":"crocodile","1F405":"tiger2","1F406":"leopard","1F993":"zebra","1F98D":"gorilla","1F9A7":"orangutan","1F418":"elephant","1F9A3":"mammoth","1F9AC":"bison","1F99B":"hippopotamus","1F98F":["rhino","rhinoceros"],"1F42A":"dromedary_camel","1F42B":"camel","1F992":"giraffe","1F998":"kangaroo","1F403":"water_buffalo","1F402":"ox","1F404":"cow2","1F40E":"racehorse","1F416":"pig2","1F40F":"ram","1F411":"sheep","1F999":"llama","1F410":"goat","1F98C":"deer","1F415":"dog2","1F429":"poodle","1F9AE":"guide_dog","1F415-200D-1F9BA":"service_dog","1F408":"cat2","1F408-200D-2B1B":"black_cat","1F413":"rooster","1F983":"turkey","1F99A":"peacock","1F99C":"parrot","1F9A2":"swan","1F9A9":"flamingo","1F54A":["dove","dove_of_peace"],"1F407":"rabbit2","1F99D":"raccoon","1F9A8":"skunk","1F9A1":"badger","1F9AB":"beaver","1F9A6":"otter","1F9A5":"sloth","1F401":"mouse2","1F400":"rat","1F43F":"chipmunk","1F994":"hedgehog","1F43E":["feet","paw_prints"],"1F409":"dragon","1F432":"dragon_face","1F335":"cactus","1F384":"christmas_tree","1F332":"evergreen_tree","1F333":"deciduous_tree","1F334":"palm_tree","1F331":"seedling","1F33F":"herb","1F340":"four_leaf_clover","1F38D":"bamboo","1F38B":"tanabata_tree","1F343":"leaves","1F342":"fallen_leaf","1F341":"maple_leaf","1FAB6":"feather","1F344":"mushroom","1F41A":"shell","1FAA8":"rock","1FAB5":"wood","1F33E":"ear_of_rice","1FAB4":"potted_plant","1F490":"bouquet","1F337":"tulip","1F339":"rose","1F940":["wilted_rose","wilted_flower"],"1F33A":"hibiscus","1F338":"cherry_blossom","1F33C":"blossom","1F33B":"sunflower","1F31E":"sun_with_face","1F31D":"full_moon_with_face","1F31B":"first_quarter_moon_with_face","1F31C":"last_quarter_moon_with_face","1F31A":"new_moon_with_face","1F315":"full_moon","1F316":"waning_gibbous_moon","1F317":"last_quarter_moon","1F318":"waning_crescent_moon","1F311":"new_moon","1F312":"waxing_crescent_moon","1F313":"first_quarter_moon","1F314":"waxing_gibbous_moon","1F319":"crescent_moon","1F30E":"earth_americas","1F30D":"earth_africa","1F30F":"earth_asia","1FA90":"ringed_planet","1F4AB":"dizzy","2B50":"star","1F31F":"star2","26A1":"zap","1F4A5":"boom","1F525":["fire","flame"],"1F32A":["cloud_tornado","cloud_with_tornado"],"1F308":"rainbow","1F324":["white_sun_small_cloud","white_sun_with_small_cloud"],"26C5":"partly_sunny","1F325":["white_sun_cloud","white_sun_behind_cloud"],"1F326":["white_sun_rain_cloud","white_sun_behind_cloud_with_rain"],"1F327":["cloud_rain","cloud_with_rain"],"26C8":["thunder_cloud_rain","thunder_cloud_and_rain"],"1F329":["cloud_lightning","cloud_with_lightning"],"1F328":["cloud_snow","cloud_with_snow"],"26C4":"snowman","1F32C":"wind_blowing_face","1F4A8":"dash","1F4A7":"droplet","1F4A6":"sweat_drops","1F30A":"ocean","1F32B":"fog","1F34F":"green_apple","1F34E":"apple","1F350":"pear","1F34A":"tangerine","1F34B":"lemon","1F34C":"banana","1F349":"watermelon","1F347":"grapes","1FAD0":"blueberries","1F353":"strawberry","1F348":"melon","1F352":"cherries","1F351":"peach","1F96D":"mango","1F34D":"pineapple","1F965":"coconut","1F95D":["kiwi","kiwifruit"],"1F345":"tomato","1F346":"eggplant","1F951":"avocado","1FAD2":"olive","1F966":"broccoli","1F96C":"leafy_green","1FAD1":"bell_pepper","1F952":"cucumber","1F336":"hot_pepper","1F33D":"corn","1F955":"carrot","1F9C4":"garlic","1F9C5":"onion","1F954":"potato","1F360":"sweet_potato","1F950":"croissant","1F96F":"bagel","1F35E":"bread","1F956":["french_bread","baguette_bread"],"1FAD3":"flatbread","1F968":"pretzel","1F9C0":["cheese","cheese_wedge"],"1F95A":"egg","1F373":"cooking","1F9C8":"butter","1F95E":"pancakes","1F9C7":"waffle","1F953":"bacon","1F969":"cut_of_meat","1F357":"poultry_leg","1F356":"meat_on_bone","1F32D":["hotdog","hot_dog"],"1F354":"hamburger","1F35F":"fries","1F355":"pizza","1F96A":"sandwich","1F959":["stuffed_flatbread","stuffed_pita"],"1F9C6":"falafel","1F32E":"taco","1F32F":"burrito","1FAD4":"tamale","1F957":["salad","green_salad"],"1F958":["shallow_pan_of_food","paella"],"1FAD5":"fondue","1F96B":"canned_food","1F35D":"spaghetti","1F35C":"ramen","1F372":"stew","1F35B":"curry","1F363":"sushi","1F371":"bento","1F95F":"dumpling","1F9AA":"oyster","1F364":"fried_shrimp","1F359":"rice_ball","1F35A":"rice","1F358":"rice_cracker","1F365":"fish_cake","1F960":"fortune_cookie","1F96E":"moon_cake","1F362":"oden","1F361":"dango","1F367":"shaved_ice","1F368":"ice_cream","1F366":"icecream","1F967":"pie","1F9C1":"cupcake","1F370":"cake","1F382":"birthday","1F36E":["custard","pudding","flan"],"1F36D":"lollipop","1F36C":"candy","1F36B":"chocolate_bar","1F37F":"popcorn","1F369":"doughnut","1F36A":"cookie","1F330":"chestnut","1F95C":["peanuts","shelled_peanut"],"1F36F":"honey_pot","1F95B":["milk","glass_of_milk"],"1F37C":"baby_bottle","1F375":"tea","1FAD6":"teapot","1F9C9":"mate","1F9CB":"bubble_tea","1F9C3":"beverage_box","1F964":"cup_with_straw","1F376":"sake","1F37A":"beer","1F37B":"beers","1F942":["champagne_glass","clinking_glass"],"1F377":"wine_glass","1F943":["tumbler_glass","whisky"],"1F378":"cocktail","1F379":"tropical_drink","1F37E":["champagne","bottle_with_popping_cork"],"1F9CA":"ice_cube","1F944":"spoon","1F374":"fork_and_knife","1F37D":["fork_knife_plate","fork_and_knife_with_plate"],"1F963":"bowl_with_spoon","1F961":"takeout_box","1F962":"chopsticks","1F9C2":"salt","26BD":"soccer","1F3C0":"basketball","1F3C8":"football","26BE":"baseball","1F94E":"softball","1F3BE":"tennis","1F3D0":"volleyball","1F3C9":"rugby_football","1F94F":"flying_disc","1FA83":"boomerang","1F3B1":"8ball","1FA80":"yo_yo","1F3D3":["ping_pong","table_tennis"],"1F3F8":"badminton","1F3D2":"hockey","1F3D1":"field_hockey","1F94D":"lacrosse","1F3CF":["cricket_game","cricket_bat_ball"],"1F945":["goal","goal_net"],"26F3":"golf","1FA81":"kite","1F3F9":["bow_and_arrow","archery"],"1F3A3":"fishing_pole_and_fish","1F93F":"diving_mask","1F94A":["boxing_glove","boxing_gloves"],"1F94B":["martial_arts_uniform","karate_uniform"],"1F3BD":"running_shirt_with_sash","1F6F9":"skateboard","1F6FC":"roller_skate","1F6F7":"sled","26F8":"ice_skate","1F94C":"curling_stone","1F3BF":"ski","26F7":"skier","1F3C2":"snowboarder","1F3C2-1F3FB":["snowboarder_tone1","snowboarder_light_skin_tone"],"1F3C2-1F3FC":["snowboarder_tone2","snowboarder_medium_light_skin_tone"],"1F3C2-1F3FD":["snowboarder_tone3","snowboarder_medium_skin_tone"],"1F3C2-1F3FE":["snowboarder_tone4","snowboarder_medium_dark_skin_tone"],"1F3C2-1F3FF":["snowboarder_tone5","snowboarder_dark_skin_tone"],"1FA82":"parachute","1F3CB":["person_lifting_weights","lifter","weight_lifter"],"1F3CB-1F3FB":["person_lifting_weights_tone1","lifter_tone1","weight_lifter_tone1"],"1F3CB-1F3FC":["person_lifting_weights_tone2","lifter_tone2","weight_lifter_tone2"],"1F3CB-1F3FD":["person_lifting_weights_tone3","lifter_tone3","weight_lifter_tone3"],"1F3CB-1F3FE":["person_lifting_weights_tone4","lifter_tone4","weight_lifter_tone4"],"1F3CB-1F3FF":["person_lifting_weights_tone5","lifter_tone5","weight_lifter_tone5"],"1F3CB-FE0F-200D-2640-FE0F":"woman_lifting_weights","1F3CB-1F3FB-200D-2640-FE0F":["woman_lifting_weights_tone1","woman_lifting_weights_light_skin_tone"],"1F3CB-1F3FC-200D-2640-FE0F":["woman_lifting_weights_tone2","woman_lifting_weights_medium_light_skin_tone"],"1F3CB-1F3FD-200D-2640-FE0F":["woman_lifting_weights_tone3","woman_lifting_weights_medium_skin_tone"],"1F3CB-1F3FE-200D-2640-FE0F":["woman_lifting_weights_tone4","woman_lifting_weights_medium_dark_skin_tone"],"1F3CB-1F3FF-200D-2640-FE0F":["woman_lifting_weights_tone5","woman_lifting_weights_dark_skin_tone"],"1F3CB-FE0F-200D-2642-FE0F":"man_lifting_weights","1F3CB-1F3FB-200D-2642-FE0F":["man_lifting_weights_tone1","man_lifting_weights_light_skin_tone"],"1F3CB-1F3FC-200D-2642-FE0F":["man_lifting_weights_tone2","man_lifting_weights_medium_light_skin_tone"],"1F3CB-1F3FD-200D-2642-FE0F":["man_lifting_weights_tone3","man_lifting_weights_medium_skin_tone"],"1F3CB-1F3FE-200D-2642-FE0F":["man_lifting_weights_tone4","man_lifting_weights_medium_dark_skin_tone"],"1F3CB-1F3FF-200D-2642-FE0F":["man_lifting_weights_tone5","man_lifting_weights_dark_skin_tone"],"1F93C":["people_wrestling","wrestlers","wrestling"],"1F93C-200D-2640-FE0F":"women_wrestling","1F93C-200D-2642-FE0F":"men_wrestling","1F938":["person_doing_cartwheel","cartwheel"],"1F938-1F3FB":["person_doing_cartwheel_tone1","cartwheel_tone1"],"1F938-1F3FC":["person_doing_cartwheel_tone2","cartwheel_tone2"],"1F938-1F3FD":["person_doing_cartwheel_tone3","cartwheel_tone3"],"1F938-1F3FE":["person_doing_cartwheel_tone4","cartwheel_tone4"],"1F938-1F3FF":["person_doing_cartwheel_tone5","cartwheel_tone5"],"1F938-200D-2640-FE0F":"woman_cartwheeling","1F938-1F3FB-200D-2640-FE0F":["woman_cartwheeling_tone1","woman_cartwheeling_light_skin_tone"],"1F938-1F3FC-200D-2640-FE0F":["woman_cartwheeling_tone2","woman_cartwheeling_medium_light_skin_tone"],"1F938-1F3FD-200D-2640-FE0F":["woman_cartwheeling_tone3","woman_cartwheeling_medium_skin_tone"],"1F938-1F3FE-200D-2640-FE0F":["woman_cartwheeling_tone4","woman_cartwheeling_medium_dark_skin_tone"],"1F938-1F3FF-200D-2640-FE0F":["woman_cartwheeling_tone5","woman_cartwheeling_dark_skin_tone"],"1F938-200D-2642-FE0F":"man_cartwheeling","1F938-1F3FB-200D-2642-FE0F":["man_cartwheeling_tone1","man_cartwheeling_light_skin_tone"],"1F938-1F3FC-200D-2642-FE0F":["man_cartwheeling_tone2","man_cartwheeling_medium_light_skin_tone"],"1F938-1F3FD-200D-2642-FE0F":["man_cartwheeling_tone3","man_cartwheeling_medium_skin_tone"],"1F938-1F3FE-200D-2642-FE0F":["man_cartwheeling_tone4","man_cartwheeling_medium_dark_skin_tone"],"1F938-1F3FF-200D-2642-FE0F":["man_cartwheeling_tone5","man_cartwheeling_dark_skin_tone"],"26F9":["person_bouncing_ball","basketball_player","person_with_ball"],"26F9-1F3FB":["person_bouncing_ball_tone1","basketball_player_tone1","person_with_ball_tone1"],"26F9-1F3FC":["person_bouncing_ball_tone2","basketball_player_tone2","person_with_ball_tone2"],"26F9-1F3FD":["person_bouncing_ball_tone3","basketball_player_tone3","person_with_ball_tone3"],"26F9-1F3FE":["person_bouncing_ball_tone4","basketball_player_tone4","person_with_ball_tone4"],"26F9-1F3FF":["person_bouncing_ball_tone5","basketball_player_tone5","person_with_ball_tone5"],"26F9-FE0F-200D-2640-FE0F":"woman_bouncing_ball","26F9-1F3FB-200D-2640-FE0F":["woman_bouncing_ball_tone1","woman_bouncing_ball_light_skin_tone"],"26F9-1F3FC-200D-2640-FE0F":["woman_bouncing_ball_tone2","woman_bouncing_ball_medium_light_skin_tone"],"26F9-1F3FD-200D-2640-FE0F":["woman_bouncing_ball_tone3","woman_bouncing_ball_medium_skin_tone"],"26F9-1F3FE-200D-2640-FE0F":["woman_bouncing_ball_tone4","woman_bouncing_ball_medium_dark_skin_tone"],"26F9-1F3FF-200D-2640-FE0F":["woman_bouncing_ball_tone5","woman_bouncing_ball_dark_skin_tone"],"26F9-FE0F-200D-2642-FE0F":"man_bouncing_ball","26F9-1F3FB-200D-2642-FE0F":["man_bouncing_ball_tone1","man_bouncing_ball_light_skin_tone"],"26F9-1F3FC-200D-2642-FE0F":["man_bouncing_ball_tone2","man_bouncing_ball_medium_light_skin_tone"],"26F9-1F3FD-200D-2642-FE0F":["man_bouncing_ball_tone3","man_bouncing_ball_medium_skin_tone"],"26F9-1F3FE-200D-2642-FE0F":["man_bouncing_ball_tone4","man_bouncing_ball_medium_dark_skin_tone"],"26F9-1F3FF-200D-2642-FE0F":["man_bouncing_ball_tone5","man_bouncing_ball_dark_skin_tone"],"1F93A":["person_fencing","fencer","fencing"],"1F93E":["person_playing_handball","handball"],"1F93E-1F3FB":["person_playing_handball_tone1","handball_tone1"],"1F93E-1F3FC":["person_playing_handball_tone2","handball_tone2"],"1F93E-1F3FD":["person_playing_handball_tone3","handball_tone3"],"1F93E-1F3FE":["person_playing_handball_tone4","handball_tone4"],"1F93E-1F3FF":["person_playing_handball_tone5","handball_tone5"],"1F93E-200D-2640-FE0F":"woman_playing_handball","1F93E-1F3FB-200D-2640-FE0F":["woman_playing_handball_tone1","woman_playing_handball_light_skin_tone"],"1F93E-1F3FC-200D-2640-FE0F":["woman_playing_handball_tone2","woman_playing_handball_medium_light_skin_tone"],"1F93E-1F3FD-200D-2640-FE0F":["woman_playing_handball_tone3","woman_playing_handball_medium_skin_tone"],"1F93E-1F3FE-200D-2640-FE0F":["woman_playing_handball_tone4","woman_playing_handball_medium_dark_skin_tone"],"1F93E-1F3FF-200D-2640-FE0F":["woman_playing_handball_tone5","woman_playing_handball_dark_skin_tone"],"1F93E-200D-2642-FE0F":"man_playing_handball","1F93E-1F3FB-200D-2642-FE0F":["man_playing_handball_tone1","man_playing_handball_light_skin_tone"],"1F93E-1F3FC-200D-2642-FE0F":["man_playing_handball_tone2","man_playing_handball_medium_light_skin_tone"],"1F93E-1F3FD-200D-2642-FE0F":["man_playing_handball_tone3","man_playing_handball_medium_skin_tone"],"1F93E-1F3FE-200D-2642-FE0F":["man_playing_handball_tone4","man_playing_handball_medium_dark_skin_tone"],"1F93E-1F3FF-200D-2642-FE0F":["man_playing_handball_tone5","man_playing_handball_dark_skin_tone"],"1F3CC":["person_golfing","golfer"],"1F3CC-1F3FB":["person_golfing_tone1","person_golfing_light_skin_tone"],"1F3CC-1F3FC":["person_golfing_tone2","person_golfing_medium_light_skin_tone"],"1F3CC-1F3FD":["person_golfing_tone3","person_golfing_medium_skin_tone"],"1F3CC-1F3FE":["person_golfing_tone4","person_golfing_medium_dark_skin_tone"],"1F3CC-1F3FF":["person_golfing_tone5","person_golfing_dark_skin_tone"],"1F3CC-FE0F-200D-2640-FE0F":"woman_golfing","1F3CC-1F3FB-200D-2640-FE0F":["woman_golfing_tone1","woman_golfing_light_skin_tone"],"1F3CC-1F3FC-200D-2640-FE0F":["woman_golfing_tone2","woman_golfing_medium_light_skin_tone"],"1F3CC-1F3FD-200D-2640-FE0F":["woman_golfing_tone3","woman_golfing_medium_skin_tone"],"1F3CC-1F3FE-200D-2640-FE0F":["woman_golfing_tone4","woman_golfing_medium_dark_skin_tone"],"1F3CC-1F3FF-200D-2640-FE0F":["woman_golfing_tone5","woman_golfing_dark_skin_tone"],"1F3CC-FE0F-200D-2642-FE0F":"man_golfing","1F3CC-1F3FB-200D-2642-FE0F":["man_golfing_tone1","man_golfing_light_skin_tone"],"1F3CC-1F3FC-200D-2642-FE0F":["man_golfing_tone2","man_golfing_medium_light_skin_tone"],"1F3CC-1F3FD-200D-2642-FE0F":["man_golfing_tone3","man_golfing_medium_skin_tone"],"1F3CC-1F3FE-200D-2642-FE0F":["man_golfing_tone4","man_golfing_medium_dark_skin_tone"],"1F3CC-1F3FF-200D-2642-FE0F":["man_golfing_tone5","man_golfing_dark_skin_tone"],"1F3C7":"horse_racing","1F3C7-1F3FB":"horse_racing_tone1","1F3C7-1F3FC":"horse_racing_tone2","1F3C7-1F3FD":"horse_racing_tone3","1F3C7-1F3FE":"horse_racing_tone4","1F3C7-1F3FF":"horse_racing_tone5","1F9D8":"person_in_lotus_position","1F9D8-1F3FB":["person_in_lotus_position_tone1","person_in_lotus_position_light_skin_tone"],"1F9D8-1F3FC":["person_in_lotus_position_tone2","person_in_lotus_position_medium_light_skin_tone"],"1F9D8-1F3FD":["person_in_lotus_position_tone3","person_in_lotus_position_medium_skin_tone"],"1F9D8-1F3FE":["person_in_lotus_position_tone4","person_in_lotus_position_medium_dark_skin_tone"],"1F9D8-1F3FF":["person_in_lotus_position_tone5","person_in_lotus_position_dark_skin_tone"],"1F9D8-200D-2640-FE0F":"woman_in_lotus_position","1F9D8-1F3FB-200D-2640-FE0F":["woman_in_lotus_position_tone1","woman_in_lotus_position_light_skin_tone"],"1F9D8-1F3FC-200D-2640-FE0F":["woman_in_lotus_position_tone2","woman_in_lotus_position_medium_light_skin_tone"],"1F9D8-1F3FD-200D-2640-FE0F":["woman_in_lotus_position_tone3","woman_in_lotus_position_medium_skin_tone"],"1F9D8-1F3FE-200D-2640-FE0F":["woman_in_lotus_position_tone4","woman_in_lotus_position_medium_dark_skin_tone"],"1F9D8-1F3FF-200D-2640-FE0F":["woman_in_lotus_position_tone5","woman_in_lotus_position_dark_skin_tone"],"1F9D8-200D-2642-FE0F":"man_in_lotus_position","1F9D8-1F3FB-200D-2642-FE0F":["man_in_lotus_position_tone1","man_in_lotus_position_light_skin_tone"],"1F9D8-1F3FC-200D-2642-FE0F":["man_in_lotus_position_tone2","man_in_lotus_position_medium_light_skin_tone"],"1F9D8-1F3FD-200D-2642-FE0F":["man_in_lotus_position_tone3","man_in_lotus_position_medium_skin_tone"],"1F9D8-1F3FE-200D-2642-FE0F":["man_in_lotus_position_tone4","man_in_lotus_position_medium_dark_skin_tone"],"1F9D8-1F3FF-200D-2642-FE0F":["man_in_lotus_position_tone5","man_in_lotus_position_dark_skin_tone"],"1F3C4":["person_surfing","surfer"],"1F3C4-1F3FB":["person_surfing_tone1","surfer_tone1"],"1F3C4-1F3FC":["person_surfing_tone2","surfer_tone2"],"1F3C4-1F3FD":["person_surfing_tone3","surfer_tone3"],"1F3C4-1F3FE":["person_surfing_tone4","surfer_tone4"],"1F3C4-1F3FF":["person_surfing_tone5","surfer_tone5"],"1F3C4-200D-2640-FE0F":"woman_surfing","1F3C4-1F3FB-200D-2640-FE0F":["woman_surfing_tone1","woman_surfing_light_skin_tone"],"1F3C4-1F3FC-200D-2640-FE0F":["woman_surfing_tone2","woman_surfing_medium_light_skin_tone"],"1F3C4-1F3FD-200D-2640-FE0F":["woman_surfing_tone3","woman_surfing_medium_skin_tone"],"1F3C4-1F3FE-200D-2640-FE0F":["woman_surfing_tone4","woman_surfing_medium_dark_skin_tone"],"1F3C4-1F3FF-200D-2640-FE0F":["woman_surfing_tone5","woman_surfing_dark_skin_tone"],"1F3C4-200D-2642-FE0F":"man_surfing","1F3C4-1F3FB-200D-2642-FE0F":["man_surfing_tone1","man_surfing_light_skin_tone"],"1F3C4-1F3FC-200D-2642-FE0F":["man_surfing_tone2","man_surfing_medium_light_skin_tone"],"1F3C4-1F3FD-200D-2642-FE0F":["man_surfing_tone3","man_surfing_medium_skin_tone"],"1F3C4-1F3FE-200D-2642-FE0F":["man_surfing_tone4","man_surfing_medium_dark_skin_tone"],"1F3C4-1F3FF-200D-2642-FE0F":["man_surfing_tone5","man_surfing_dark_skin_tone"],"1F3CA":["person_swimming","swimmer"],"1F3CA-1F3FB":["person_swimming_tone1","swimmer_tone1"],"1F3CA-1F3FC":["person_swimming_tone2","swimmer_tone2"],"1F3CA-1F3FD":["person_swimming_tone3","swimmer_tone3"],"1F3CA-1F3FE":["person_swimming_tone4","swimmer_tone4"],"1F3CA-1F3FF":["person_swimming_tone5","swimmer_tone5"],"1F3CA-200D-2640-FE0F":"woman_swimming","1F3CA-1F3FB-200D-2640-FE0F":["woman_swimming_tone1","woman_swimming_light_skin_tone"],"1F3CA-1F3FC-200D-2640-FE0F":["woman_swimming_tone2","woman_swimming_medium_light_skin_tone"],"1F3CA-1F3FD-200D-2640-FE0F":["woman_swimming_tone3","woman_swimming_medium_skin_tone"],"1F3CA-1F3FE-200D-2640-FE0F":["woman_swimming_tone4","woman_swimming_medium_dark_skin_tone"],"1F3CA-1F3FF-200D-2640-FE0F":["woman_swimming_tone5","woman_swimming_dark_skin_tone"],"1F3CA-200D-2642-FE0F":"man_swimming","1F3CA-1F3FB-200D-2642-FE0F":["man_swimming_tone1","man_swimming_light_skin_tone"],"1F3CA-1F3FC-200D-2642-FE0F":["man_swimming_tone2","man_swimming_medium_light_skin_tone"],"1F3CA-1F3FD-200D-2642-FE0F":["man_swimming_tone3","man_swimming_medium_skin_tone"],"1F3CA-1F3FE-200D-2642-FE0F":["man_swimming_tone4","man_swimming_medium_dark_skin_tone"],"1F3CA-1F3FF-200D-2642-FE0F":["man_swimming_tone5","man_swimming_dark_skin_tone"],"1F93D":["person_playing_water_polo","water_polo"],"1F93D-1F3FB":["person_playing_water_polo_tone1","water_polo_tone1"],"1F93D-1F3FC":["person_playing_water_polo_tone2","water_polo_tone2"],"1F93D-1F3FD":["person_playing_water_polo_tone3","water_polo_tone3"],"1F93D-1F3FE":["person_playing_water_polo_tone4","water_polo_tone4"],"1F93D-1F3FF":["person_playing_water_polo_tone5","water_polo_tone5"],"1F93D-200D-2640-FE0F":"woman_playing_water_polo","1F93D-1F3FB-200D-2640-FE0F":["woman_playing_water_polo_tone1","woman_playing_water_polo_light_skin_tone"],"1F93D-1F3FC-200D-2640-FE0F":["woman_playing_water_polo_tone2","woman_playing_water_polo_medium_light_skin_tone"],"1F93D-1F3FD-200D-2640-FE0F":["woman_playing_water_polo_tone3","woman_playing_water_polo_medium_skin_tone"],"1F93D-1F3FE-200D-2640-FE0F":["woman_playing_water_polo_tone4","woman_playing_water_polo_medium_dark_skin_tone"],"1F93D-1F3FF-200D-2640-FE0F":["woman_playing_water_polo_tone5","woman_playing_water_polo_dark_skin_tone"],"1F93D-200D-2642-FE0F":"man_playing_water_polo","1F93D-1F3FB-200D-2642-FE0F":["man_playing_water_polo_tone1","man_playing_water_polo_light_skin_tone"],"1F93D-1F3FC-200D-2642-FE0F":["man_playing_water_polo_tone2","man_playing_water_polo_medium_light_skin_tone"],"1F93D-1F3FD-200D-2642-FE0F":["man_playing_water_polo_tone3","man_playing_water_polo_medium_skin_tone"],"1F93D-1F3FE-200D-2642-FE0F":["man_playing_water_polo_tone4","man_playing_water_polo_medium_dark_skin_tone"],"1F93D-1F3FF-200D-2642-FE0F":["man_playing_water_polo_tone5","man_playing_water_polo_dark_skin_tone"],"1F6A3":["person_rowing_boat","rowboat"],"1F6A3-1F3FB":["person_rowing_boat_tone1","rowboat_tone1"],"1F6A3-1F3FC":["person_rowing_boat_tone2","rowboat_tone2"],"1F6A3-1F3FD":["person_rowing_boat_tone3","rowboat_tone3"],"1F6A3-1F3FE":["person_rowing_boat_tone4","rowboat_tone4"],"1F6A3-1F3FF":["person_rowing_boat_tone5","rowboat_tone5"],"1F6A3-200D-2640-FE0F":"woman_rowing_boat","1F6A3-1F3FB-200D-2640-FE0F":["woman_rowing_boat_tone1","woman_rowing_boat_light_skin_tone"],"1F6A3-1F3FC-200D-2640-FE0F":["woman_rowing_boat_tone2","woman_rowing_boat_medium_light_skin_tone"],"1F6A3-1F3FD-200D-2640-FE0F":["woman_rowing_boat_tone3","woman_rowing_boat_medium_skin_tone"],"1F6A3-1F3FE-200D-2640-FE0F":["woman_rowing_boat_tone4","woman_rowing_boat_medium_dark_skin_tone"],"1F6A3-1F3FF-200D-2640-FE0F":["woman_rowing_boat_tone5","woman_rowing_boat_dark_skin_tone"],"1F6A3-200D-2642-FE0F":"man_rowing_boat","1F6A3-1F3FB-200D-2642-FE0F":["man_rowing_boat_tone1","man_rowing_boat_light_skin_tone"],"1F6A3-1F3FC-200D-2642-FE0F":["man_rowing_boat_tone2","man_rowing_boat_medium_light_skin_tone"],"1F6A3-1F3FD-200D-2642-FE0F":["man_rowing_boat_tone3","man_rowing_boat_medium_skin_tone"],"1F6A3-1F3FE-200D-2642-FE0F":["man_rowing_boat_tone4","man_rowing_boat_medium_dark_skin_tone"],"1F6A3-1F3FF-200D-2642-FE0F":["man_rowing_boat_tone5","man_rowing_boat_dark_skin_tone"],"1F9D7":"person_climbing","1F9D7-1F3FB":["person_climbing_tone1","person_climbing_light_skin_tone"],"1F9D7-1F3FC":["person_climbing_tone2","person_climbing_medium_light_skin_tone"],"1F9D7-1F3FD":["person_climbing_tone3","person_climbing_medium_skin_tone"],"1F9D7-1F3FE":["person_climbing_tone4","person_climbing_medium_dark_skin_tone"],"1F9D7-1F3FF":["person_climbing_tone5","person_climbing_dark_skin_tone"],"1F9D7-200D-2640-FE0F":"woman_climbing","1F9D7-1F3FB-200D-2640-FE0F":["woman_climbing_tone1","woman_climbing_light_skin_tone"],"1F9D7-1F3FC-200D-2640-FE0F":["woman_climbing_tone2","woman_climbing_medium_light_skin_tone"],"1F9D7-1F3FD-200D-2640-FE0F":["woman_climbing_tone3","woman_climbing_medium_skin_tone"],"1F9D7-1F3FE-200D-2640-FE0F":["woman_climbing_tone4","woman_climbing_medium_dark_skin_tone"],"1F9D7-1F3FF-200D-2640-FE0F":["woman_climbing_tone5","woman_climbing_dark_skin_tone"],"1F9D7-200D-2642-FE0F":"man_climbing","1F9D7-1F3FB-200D-2642-FE0F":["man_climbing_tone1","man_climbing_light_skin_tone"],"1F9D7-1F3FC-200D-2642-FE0F":["man_climbing_tone2","man_climbing_medium_light_skin_tone"],"1F9D7-1F3FD-200D-2642-FE0F":["man_climbing_tone3","man_climbing_medium_skin_tone"],"1F9D7-1F3FE-200D-2642-FE0F":["man_climbing_tone4","man_climbing_medium_dark_skin_tone"],"1F9D7-1F3FF-200D-2642-FE0F":["man_climbing_tone5","man_climbing_dark_skin_tone"],"1F6B5":["person_mountain_biking","mountain_bicyclist"],"1F6B5-1F3FB":["person_mountain_biking_tone1","mountain_bicyclist_tone1"],"1F6B5-1F3FC":["person_mountain_biking_tone2","mountain_bicyclist_tone2"],"1F6B5-1F3FD":["person_mountain_biking_tone3","mountain_bicyclist_tone3"],"1F6B5-1F3FE":["person_mountain_biking_tone4","mountain_bicyclist_tone4"],"1F6B5-1F3FF":["person_mountain_biking_tone5","mountain_bicyclist_tone5"],"1F6B5-200D-2640-FE0F":"woman_mountain_biking","1F6B5-1F3FB-200D-2640-FE0F":["woman_mountain_biking_tone1","woman_mountain_biking_light_skin_tone"],"1F6B5-1F3FC-200D-2640-FE0F":["woman_mountain_biking_tone2","woman_mountain_biking_medium_light_skin_tone"],"1F6B5-1F3FD-200D-2640-FE0F":["woman_mountain_biking_tone3","woman_mountain_biking_medium_skin_tone"],"1F6B5-1F3FE-200D-2640-FE0F":["woman_mountain_biking_tone4","woman_mountain_biking_medium_dark_skin_tone"],"1F6B5-1F3FF-200D-2640-FE0F":["woman_mountain_biking_tone5","woman_mountain_biking_dark_skin_tone"],"1F6B5-200D-2642-FE0F":"man_mountain_biking","1F6B5-1F3FB-200D-2642-FE0F":["man_mountain_biking_tone1","man_mountain_biking_light_skin_tone"],"1F6B5-1F3FC-200D-2642-FE0F":["man_mountain_biking_tone2","man_mountain_biking_medium_light_skin_tone"],"1F6B5-1F3FD-200D-2642-FE0F":["man_mountain_biking_tone3","man_mountain_biking_medium_skin_tone"],"1F6B5-1F3FE-200D-2642-FE0F":["man_mountain_biking_tone4","man_mountain_biking_medium_dark_skin_tone"],"1F6B5-1F3FF-200D-2642-FE0F":["man_mountain_biking_tone5","man_mountain_biking_dark_skin_tone"],"1F6B4":["person_biking","bicyclist"],"1F6B4-1F3FB":["person_biking_tone1","bicyclist_tone1"],"1F6B4-1F3FC":["person_biking_tone2","bicyclist_tone2"],"1F6B4-1F3FD":["person_biking_tone3","bicyclist_tone3"],"1F6B4-1F3FE":["person_biking_tone4","bicyclist_tone4"],"1F6B4-1F3FF":["person_biking_tone5","bicyclist_tone5"],"1F6B4-200D-2640-FE0F":"woman_biking","1F6B4-1F3FB-200D-2640-FE0F":["woman_biking_tone1","woman_biking_light_skin_tone"],"1F6B4-1F3FC-200D-2640-FE0F":["woman_biking_tone2","woman_biking_medium_light_skin_tone"],"1F6B4-1F3FD-200D-2640-FE0F":["woman_biking_tone3","woman_biking_medium_skin_tone"],"1F6B4-1F3FE-200D-2640-FE0F":["woman_biking_tone4","woman_biking_medium_dark_skin_tone"],"1F6B4-1F3FF-200D-2640-FE0F":["woman_biking_tone5","woman_biking_dark_skin_tone"],"1F6B4-200D-2642-FE0F":"man_biking","1F6B4-1F3FB-200D-2642-FE0F":["man_biking_tone1","man_biking_light_skin_tone"],"1F6B4-1F3FC-200D-2642-FE0F":["man_biking_tone2","man_biking_medium_light_skin_tone"],"1F6B4-1F3FD-200D-2642-FE0F":["man_biking_tone3","man_biking_medium_skin_tone"],"1F6B4-1F3FE-200D-2642-FE0F":["man_biking_tone4","man_biking_medium_dark_skin_tone"],"1F6B4-1F3FF-200D-2642-FE0F":["man_biking_tone5","man_biking_dark_skin_tone"],"1F3C6":"trophy","1F947":["first_place","first_place_medal"],"1F948":["second_place","second_place_medal"],"1F949":["third_place","third_place_medal"],"1F3C5":["medal","sports_medal"],"1F396":"military_medal","1F3F5":"rosette","1F397":"reminder_ribbon","1F3AB":"ticket","1F39F":["tickets","admission_tickets"],"1F3AA":"circus_tent","1F939":["person_juggling","juggling","juggler"],"1F939-1F3FB":["person_juggling_tone1","juggling_tone1","juggler_tone1"],"1F939-1F3FC":["person_juggling_tone2","juggling_tone2","juggler_tone2"],"1F939-1F3FD":["person_juggling_tone3","juggling_tone3","juggler_tone3"],"1F939-1F3FE":["person_juggling_tone4","juggling_tone4","juggler_tone4"],"1F939-1F3FF":["person_juggling_tone5","juggling_tone5","juggler_tone5"],"1F939-200D-2640-FE0F":"woman_juggling","1F939-1F3FB-200D-2640-FE0F":["woman_juggling_tone1","woman_juggling_light_skin_tone"],"1F939-1F3FC-200D-2640-FE0F":["woman_juggling_tone2","woman_juggling_medium_light_skin_tone"],"1F939-1F3FD-200D-2640-FE0F":["woman_juggling_tone3","woman_juggling_medium_skin_tone"],"1F939-1F3FE-200D-2640-FE0F":["woman_juggling_tone4","woman_juggling_medium_dark_skin_tone"],"1F939-1F3FF-200D-2640-FE0F":["woman_juggling_tone5","woman_juggling_dark_skin_tone"],"1F939-200D-2642-FE0F":"man_juggling","1F939-1F3FB-200D-2642-FE0F":["man_juggling_tone1","man_juggling_light_skin_tone"],"1F939-1F3FC-200D-2642-FE0F":["man_juggling_tone2","man_juggling_medium_light_skin_tone"],"1F939-1F3FD-200D-2642-FE0F":["man_juggling_tone3","man_juggling_medium_skin_tone"],"1F939-1F3FE-200D-2642-FE0F":["man_juggling_tone4","man_juggling_medium_dark_skin_tone"],"1F939-1F3FF-200D-2642-FE0F":["man_juggling_tone5","man_juggling_dark_skin_tone"],"1F3AD":"performing_arts","1FA70":"ballet_shoes","1F3A8":"art","1F3AC":"clapper","1F3A4":"microphone","1F3A7":"headphones","1F3BC":"musical_score","1F3B9":"musical_keyboard","1F941":["drum","drum_with_drumsticks"],"1FA98":"long_drum","1F3B7":"saxophone","1F3BA":"trumpet","1F3B8":"guitar","1FA95":"banjo","1F3BB":"violin","1FA97":"accordion","1F3B2":"game_die","265F":"chess_pawn","1F3AF":"dart","1F3B3":"bowling","1F3AE":"video_game","1F3B0":"slot_machine","1F9E9":"jigsaw","1F697":"red_car","1F695":"taxi","1F699":"blue_car","1F6FB":"pickup_truck","1F68C":"bus","1F68E":"trolleybus","1F3CE":["race_car","racing_car"],"1F693":"police_car","1F691":"ambulance","1F692":"fire_engine","1F690":"minibus","1F69A":"truck","1F69B":"articulated_lorry","1F69C":"tractor","1F9AF":"probing_cane","1F9BD":"manual_wheelchair","1F9BC":"motorized_wheelchair","1F6F4":"scooter","1F6B2":"bike","1F6F5":["motor_scooter","motorbike"],"1F3CD":["motorcycle","racing_motorcycle"],"1F6FA":"auto_rickshaw","1F6A8":"rotating_light","1F694":"oncoming_police_car","1F68D":"oncoming_bus","1F698":"oncoming_automobile","1F696":"oncoming_taxi","1F6A1":"aerial_tramway","1F6A0":"mountain_cableway","1F69F":"suspension_railway","1F683":"railway_car","1F68B":"train","1F69E":"mountain_railway","1F69D":"monorail","1F684":"bullettrain_side","1F685":"bullettrain_front","1F688":"light_rail","1F682":"steam_locomotive","1F686":"train2","1F687":"metro","1F68A":"tram","1F689":"station","1F6EB":"airplane_departure","1F6EC":"airplane_arriving","1F6E9":["airplane_small","small_airplane"],"1F4BA":"seat","1F6F0":"satellite_orbital","1F680":"rocket","1F6F8":"flying_saucer","1F681":"helicopter","1F6F6":["canoe","kayak"],"26F5":"sailboat","1F6A4":"speedboat","1F6E5":"motorboat","1F6F3":["cruise_ship","passenger_ship"],"26F4":"ferry","1F6A2":"ship","26FD":"fuelpump","1F6A7":"construction","1F6A6":"vertical_traffic_light","1F6A5":"traffic_light","1F68F":"busstop","1F5FA":["map","world_map"],"1F5FF":"moyai","1F5FD":"statue_of_liberty","1F5FC":"tokyo_tower","1F3F0":"european_castle","1F3EF":"japanese_castle","1F3DF":"stadium","1F3A1":"ferris_wheel","1F3A2":"roller_coaster","1F3A0":"carousel_horse","26F2":"fountain","26F1":["beach_umbrella","umbrella_on_ground"],"1F3D6":["beach","beach_with_umbrella"],"1F3DD":["island","desert_island"],"1F3DC":"desert","1F30B":"volcano","26F0":"mountain","1F3D4":["mountain_snow","snow_capped_mountain"],"1F5FB":"mount_fuji","1F3D5":"camping","26FA":"tent","1F3E0":"house","1F3E1":"house_with_garden","1F3D8":["homes","house_buildings"],"1F3DA":["house_abandoned","derelict_house_building"],"1F6D6":"hut","1F3D7":["construction_site","building_construction"],"1F3ED":"factory","1F3E2":"office","1F3EC":"department_store","1F3E3":"post_office","1F3E4":"european_post_office","1F3E5":"hospital","1F3E6":"bank","1F3E8":"hotel","1F3EA":"convenience_store","1F3EB":"school","1F3E9":"love_hotel","1F492":"wedding","1F3DB":"classical_building","26EA":"church","1F54C":"mosque","1F54D":"synagogue","1F6D5":"hindu_temple","1F54B":"kaaba","26E9":"shinto_shrine","1F6E4":["railway_track","railroad_track"],"1F6E3":"motorway","1F5FE":"japan","1F391":"rice_scene","1F3DE":["park","national_park"],"1F305":"sunrise","1F304":"sunrise_over_mountains","1F320":"stars","1F387":"sparkler","1F386":"fireworks","1F307":["city_sunset","city_sunrise"],"1F306":"city_dusk","1F3D9":"cityscape","1F303":"night_with_stars","1F30C":"milky_way","1F309":"bridge_at_night","1F301":"foggy","231A":"watch","1F4F1":"mobile_phone","1F4F2":"calling","1F4BB":"computer","1F5A5":["desktop","desktop_computer"],"1F5A8":"printer","1F5B1":["mouse_three_button","three_button_mouse"],"1F5B2":"trackball","1F579":"joystick","1F5DC":"compression","1F4BD":"minidisc","1F4BE":"floppy_disk","1F4BF":"cd","1F4C0":"dvd","1F4FC":"vhs","1F4F7":"camera","1F4F8":"camera_with_flash","1F4F9":"video_camera","1F3A5":"movie_camera","1F4FD":["projector","film_projector"],"1F39E":"film_frames","1F4DE":"telephone_receiver","260E":"telephone","1F4DF":"pager","1F4E0":"fax","1F4FA":"tv","1F4FB":"radio","1F399":["microphone2","studio_microphone"],"1F39A":"level_slider","1F39B":"control_knobs","1F9ED":"compass","23F1":"stopwatch","23F2":["timer","timer_clock"],"23F0":"alarm_clock","1F570":["clock","mantlepiece_clock"],"231B":"hourglass","23F3":"hourglass_flowing_sand","1F4E1":"satellite","1F50B":"battery","1F50C":"electric_plug","1F4A1":"bulb","1F526":"flashlight","1F56F":"candle","1FA94":"diya_lamp","1F9EF":"fire_extinguisher","1F6E2":["oil","oil_drum"],"1F4B8":"money_with_wings","1F4B5":"dollar","1F4B4":"yen","1F4B6":"euro","1F4B7":"pound","1FA99":"coin","1F4B0":"moneybag","1F4B3":"credit_card","1F48E":"gem","1FA9C":"ladder","1F9F0":"toolbox","1FA9B":"screwdriver","1F527":"wrench","1F528":"hammer","1F6E0":["tools","hammer_and_wrench"],"26CF":"pick","1F529":"nut_and_bolt","1F9F1":"bricks","26D3":"chains","1FA9D":"hook","1FAA2":"knot","1F9F2":"magnet","1F52B":"gun","1F4A3":"bomb","1F9E8":"firecracker","1FA93":"axe","1FA9A":"carpentry_saw","1F52A":"knife","1F5E1":["dagger","dagger_knife"],"1F6E1":"shield","1F6AC":"smoking","26B0":"coffin","1FAA6":"headstone","26B1":["urn","funeral_urn"],"1F3FA":"amphora","1FA84":"magic_wand","1F52E":"crystal_ball","1F4FF":"prayer_beads","1F9FF":"nazar_amulet","1F488":"barber","1F52D":"telescope","1F52C":"microscope","1F573":"hole","1FA9F":"window","1FA79":"adhesive_bandage","1FA7A":"stethoscope","1F48A":"pill","1F489":"syringe","1FA78":"drop_of_blood","1F9EC":"dna","1F9A0":"microbe","1F9EB":"petri_dish","1F9EA":"test_tube","1F321":"thermometer","1FAA4":"mouse_trap","1F9F9":"broom","1F9FA":"basket","1FAA1":"sewing_needle","1F9FB":"roll_of_paper","1F6BD":"toilet","1FAA0":"plunger","1FAA3":"bucket","1F6B0":"potable_water","1F6BF":"shower","1F6C1":"bathtub","1F6C0":"bath","1F6C0-1F3FB":"bath_tone1","1F6C0-1F3FC":"bath_tone2","1F6C0-1F3FD":"bath_tone3","1F6C0-1F3FE":"bath_tone4","1F6C0-1F3FF":"bath_tone5","1FAA5":"toothbrush","1F9FC":"soap","1FA92":"razor","1F9FD":"sponge","1F9F4":"squeeze_bottle","1F6CE":["bellhop","bellhop_bell"],"1F511":"key","1F5DD":["key2","old_key"],"1F6AA":"door","1FA91":"chair","1FA9E":"mirror","1F6CB":["couch","couch_and_lamp"],"1F6CF":"bed","1F6CC":"sleeping_accommodation","1F6CC-1F3FB":["person_in_bed_tone1","person_in_bed_light_skin_tone"],"1F6CC-1F3FC":["person_in_bed_tone2","person_in_bed_medium_light_skin_tone"],"1F6CC-1F3FD":["person_in_bed_tone3","person_in_bed_medium_skin_tone"],"1F6CC-1F3FE":["person_in_bed_tone4","person_in_bed_medium_dark_skin_tone"],"1F6CC-1F3FF":["person_in_bed_tone5","person_in_bed_dark_skin_tone"],"1F9F8":"teddy_bear","1F5BC":["frame_photo","frame_with_picture"],"1F6CD":"shopping_bags","1F6D2":["shopping_cart","shopping_trolley"],"1F381":"gift","1F388":"balloon","1F38F":"flags","1F380":"ribbon","1F38A":"confetti_ball","1F389":"tada","1FA85":"pinata","1FA86":"nesting_dolls","1F38E":"dolls","1F3EE":"izakaya_lantern","1F390":"wind_chime","1F9E7":"red_envelope","1F4E9":"envelope_with_arrow","1F4E8":"incoming_envelope","1F4E7":["e-mail","email"],"1F48C":"love_letter","1F4E5":"inbox_tray","1F4E4":"outbox_tray","1F4E6":"package","1F3F7":"label","1F4EA":"mailbox_closed","1F4EB":"mailbox","1F4EC":"mailbox_with_mail","1F4ED":"mailbox_with_no_mail","1F4EE":"postbox","1F4EF":"postal_horn","1FAA7":"placard","1F4DC":"scroll","1F4C3":"page_with_curl","1F4C4":"page_facing_up","1F4D1":"bookmark_tabs","1F9FE":"receipt","1F4CA":"bar_chart","1F4C8":"chart_with_upwards_trend","1F4C9":"chart_with_downwards_trend","1F5D2":["notepad_spiral","spiral_note_pad"],"1F5D3":["calendar_spiral","spiral_calendar_pad"],"1F4C6":"calendar","1F4C5":"date","1F5D1":"wastebasket","1F4C7":"card_index","1F5C3":["card_box","card_file_box"],"1F5F3":["ballot_box","ballot_box_with_ballot"],"1F5C4":"file_cabinet","1F4CB":"clipboard","1F4C1":"file_folder","1F4C2":"open_file_folder","1F5C2":["dividers","card_index_dividers"],"1F5DE":["newspaper2","rolled_up_newspaper"],"1F4F0":"newspaper","1F4D3":"notebook","1F4D4":"notebook_with_decorative_cover","1F4D2":"ledger","1F4D5":"closed_book","1F4D7":"green_book","1F4D8":"blue_book","1F4D9":"orange_book","1F4DA":"books","1F4D6":"book","1F516":"bookmark","1F9F7":"safety_pin","1F517":"link","1F4CE":"paperclip","1F587":["paperclips","linked_paperclips"],"1F4D0":"triangular_ruler","1F4CF":"straight_ruler","1F9EE":"abacus","1F4CC":"pushpin","1F4CD":"round_pushpin","1F58A":["pen_ballpoint","lower_left_ballpoint_pen"],"1F58B":["pen_fountain","lower_left_fountain_pen"],"1F58C":["paintbrush","lower_left_paintbrush"],"1F58D":["crayon","lower_left_crayon"],"1F4DD":["pencil","memo"],"270F":"pencil2","1F50D":"mag","1F50E":"mag_right","1F50F":"lock_with_ink_pen","1F510":"closed_lock_with_key","1F512":"lock","1F513":"unlock","1F9E1":"orange_heart","1F49B":"yellow_heart","1F49A":"green_heart","1F499":"blue_heart","1F49C":"purple_heart","1F5A4":"black_heart","1F90E":"brown_heart","1F90D":"white_heart","1F494":"broken_heart","1F495":"two_hearts","1F49E":"revolving_hearts","1F493":"heartbeat","1F497":"heartpulse","1F496":"sparkling_heart","1F498":"cupid","1F49D":"gift_heart","2764-FE0F-200D-1FA79":"mending_heart","2764-FE0F-200D-1F525":"heart_on_fire","1F49F":"heart_decoration","262E":["peace","peace_symbol"],"271D":["cross","latin_cross"],"262A":"star_and_crescent","1F549":"om_symbol","1F52F":"six_pointed_star","1F54E":"menorah","262F":"yin_yang","1F6D0":["place_of_worship","worship_symbol"],"26CE":"ophiuchus","264A":"gemini","264B":"cancer","264C":"leo","264D":"virgo","264E":"libra","264F":"scorpius","1F194":"id","269B":["atom","atom_symbol"],"1F251":"accept","1F4F4":"mobile_phone_off","1F4F3":"vibration_mode","1F236":"u6709","1F21A":"u7121","1F238":"u7533","1F23A":"u55b6","1F237":"u6708","1F19A":"vs","1F4AE":"white_flower","1F250":"ideograph_advantage","1F234":"u5408","1F235":"u6e80","1F239":"u5272","1F232":"u7981","1F170":"a","1F171":"b","1F18E":"ab","1F191":"cl","1F17E":"o2","1F198":"sos","274C":"x","2B55":"o","1F6D1":["octagonal_sign","stop_sign"],"26D4":"no_entry","1F4DB":"name_badge","1F6AB":"no_entry_sign","1F4AF":"100","1F4A2":"anger","1F6B7":"no_pedestrians","1F6AF":"do_not_litter","1F6B3":"no_bicycles","1F6B1":"non-potable_water","1F51E":"underage","1F4F5":"no_mobile_phones","1F6AD":"no_smoking","203C":"bangbang","1F505":"low_brightness","1F506":"high_brightness","303D":"part_alternation_mark","26A0":"warning","1F6B8":"children_crossing","1F531":"trident","269C":"fleur-de-lis","1F530":"beginner","267B":"recycle","1F22F":"u6307","1F4B9":"chart","274E":"negative_squared_cross_mark","1F310":"globe_with_meridians","1F4A0":"diamond_shape_with_a_dot_inside","24C2":"m","1F300":"cyclone","1F4A4":"zzz","1F3E7":"atm","1F6BE":"wc","267F":"wheelchair","1F17F":"parking","1F233":"u7a7a","1F202":"sa","1F6C2":"passport_control","1F6C3":"customs","1F6C4":"baggage_claim","1F6C5":"left_luggage","1F6D7":"elevator","1F6B9":"mens","1F6BA":"womens","1F6BC":"baby_symbol","1F6BB":"restroom","1F6AE":"put_litter_in_its_place","1F3A6":"cinema","1F4F6":"signal_strength","1F201":"koko","1F523":"symbols","1F524":"abc","1F521":"abcd","1F520":"capital_abcd","1F196":"ng","1F197":"ok","1F199":"up","1F192":"cool","1F195":"new","1F193":"free","0030-FE0F-20E3":"zero","0031-FE0F-20E3":"one","0032-FE0F-20E3":"two","0033-FE0F-20E3":"three","0034-FE0F-20E3":"four","0035-FE0F-20E3":"five","0036-FE0F-20E3":"six","0037-FE0F-20E3":"seven","0038-FE0F-20E3":"eight","0039-FE0F-20E3":"nine","1F51F":"keycap_ten","1F522":"1234","0023-FE0F-20E3":"hash","002A-FE0F-20E3":["asterisk","keycap_asterisk"],"23CF":["eject","eject_symbol"],"25B6":"arrow_forward","23F8":["pause_button","double_vertical_bar"],"23EF":"play_pause","23F9":"stop_button","23FA":"record_button","23ED":["track_next","next_track"],"23EE":["track_previous","previous_track"],"23E9":"fast_forward","23EA":"rewind","23EB":"arrow_double_up","23EC":"arrow_double_down","25C0":"arrow_backward","1F53C":"arrow_up_small","1F53D":"arrow_down_small","27A1":"arrow_right","2B05":"arrow_left","2B06":"arrow_up","2B07":"arrow_down","21AA":"arrow_right_hook","21A9":"leftwards_arrow_with_hook","1F500":"twisted_rightwards_arrows","1F501":"repeat","1F502":"repeat_one","1F504":"arrows_counterclockwise","1F503":"arrows_clockwise","1F3B5":"musical_note","1F3B6":"notes","267E":"infinity","1F4B2":"heavy_dollar_sign","1F4B1":"currency_exchange","00A9":"copyright","00AE":"registered","27B0":"curly_loop","27BF":"loop","1F51A":"end","1F519":"back","1F51B":"on","1F51D":"top","1F51C":"soon","1F518":"radio_button","26AA":"white_circle","26AB":"black_circle","1F534":"red_circle","1F535":"blue_circle","1F7E4":"brown_circle","1F7E3":"purple_circle","1F7E2":"green_circle","1F7E1":"yellow_circle","1F7E0":"orange_circle","1F53A":"small_red_triangle","1F53B":"small_red_triangle_down","1F538":"small_orange_diamond","1F539":"small_blue_diamond","1F536":"large_orange_diamond","1F537":"large_blue_diamond","1F533":"white_square_button","1F532":"black_square_button","25AA":"black_small_square","25AB":"white_small_square","25FE":"black_medium_small_square","25FD":"white_medium_small_square","25FC":"black_medium_square","25FB":"white_medium_square","2B1B":"black_large_square","2B1C":"white_large_square","1F7E7":"orange_square","1F7E6":"blue_square","1F7E5":"red_square","1F7EB":"brown_square","1F7EA":"purple_square","1F7E9":"green_square","1F7E8":"yellow_square","1F508":"speaker","1F507":"mute","1F509":"sound","1F50A":"loud_sound","1F514":"bell","1F515":"no_bell","1F4E3":"mega","1F4E2":"loudspeaker","1F5E8":["speech_left","left_speech_bubble"],"1F441-FE0F-200D-1F5E8-FE0F":"eye_in_speech_bubble","1F4AC":"speech_balloon","1F4AD":"thought_balloon","1F5EF":["anger_right","right_anger_bubble"],"1F0CF":"black_joker","1F3B4":"flower_playing_cards","1F004":"mahjong","1F550":"clock1","1F551":"clock2","1F552":"clock3","1F553":"clock4","1F554":"clock5","1F555":"clock6","1F556":"clock7","1F557":"clock8","1F558":"clock9","1F559":"clock10","1F55A":"clock11","1F55B":"clock12","1F55C":"clock130","1F55D":"clock230","1F55E":"clock330","1F55F":"clock430","1F560":"clock530","1F561":"clock630","1F562":"clock730","1F563":"clock830","1F564":"clock930","1F565":"clock1030","1F566":"clock1130","1F567":"clock1230","26A7":"transgender_symbol","1F3F3":["flag_white","waving_white_flag"],"1F3F4":["flag_black","waving_black_flag"],"1F3C1":"checkered_flag","1F6A9":"triangular_flag_on_post","1F3F3-FE0F-200D-1F308":["rainbow_flag","gay_pride_flag"],"1F3F3-FE0F-200D-26A7-FE0F":"transgender_flag","1F3F4-200D-2620-FE0F":"pirate_flag","1F1E6-1F1EB":["flag_af","af"],"1F1E6-1F1FD":["flag_ax","ax"],"1F1E6-1F1F1":["flag_al","al"],"1F1E9-1F1FF":["flag_dz","dz"],"1F1E6-1F1F8":["flag_as","as"],"1F1E6-1F1E9":["flag_ad","ad"],"1F1E6-1F1F4":["flag_ao","ao"],"1F1E6-1F1EE":["flag_ai","ai"],"1F1E6-1F1F6":["flag_aq","aq"],"1F1E6-1F1EC":["flag_ag","ag"],"1F1E6-1F1F7":["flag_ar","ar"],"1F1E6-1F1F2":["flag_am","am"],"1F1E6-1F1FC":["flag_aw","aw"],"1F1E6-1F1FA":["flag_au","au"],"1F1E6-1F1F9":["flag_at","at"],"1F1E6-1F1FF":["flag_az","az"],"1F1E7-1F1F8":["flag_bs","bs"],"1F1E7-1F1ED":["flag_bh","bh"],"1F1E7-1F1E9":["flag_bd","bd"],"1F1E7-1F1E7":["flag_bb","bb"],"1F1E7-1F1FE":["flag_by","by"],"1F1E7-1F1EA":["flag_be","be"],"1F1E7-1F1FF":["flag_bz","bz"],"1F1E7-1F1EF":["flag_bj","bj"],"1F1E7-1F1F2":["flag_bm","bm"],"1F1E7-1F1F9":["flag_bt","bt"],"1F1E7-1F1F4":["flag_bo","bo"],"1F1E7-1F1E6":["flag_ba","ba"],"1F1E7-1F1FC":["flag_bw","bw"],"1F1E7-1F1F7":["flag_br","br"],"1F1EE-1F1F4":["flag_io","io"],"1F1FB-1F1EC":["flag_vg","vg"],"1F1E7-1F1F3":["flag_bn","bn"],"1F1E7-1F1EC":["flag_bg","bg"],"1F1E7-1F1EB":["flag_bf","bf"],"1F1E7-1F1EE":["flag_bi","bi"],"1F1F0-1F1ED":["flag_kh","kh"],"1F1E8-1F1F2":["flag_cm","cm"],"1F1E8-1F1E6":["flag_ca","ca"],"1F1EE-1F1E8":["flag_ic","ic"],"1F1E8-1F1FB":["flag_cv","cv"],"1F1E7-1F1F6":["flag_bq","bq"],"1F1F0-1F1FE":["flag_ky","ky"],"1F1E8-1F1EB":["flag_cf","cf"],"1F1F9-1F1E9":["flag_td","td"],"1F1E8-1F1F1":["flag_cl","chile"],"1F1E8-1F1F3":["flag_cn","cn"],"1F1E8-1F1FD":["flag_cx","cx"],"1F1E8-1F1E8":["flag_cc","cc"],"1F1E8-1F1F4":["flag_co","co"],"1F1F0-1F1F2":["flag_km","km"],"1F1E8-1F1EC":["flag_cg","cg"],"1F1E8-1F1E9":["flag_cd","congo"],"1F1E8-1F1F0":["flag_ck","ck"],"1F1E8-1F1F7":["flag_cr","cr"],"1F1E8-1F1EE":["flag_ci","ci"],"1F1ED-1F1F7":["flag_hr","hr"],"1F1E8-1F1FA":["flag_cu","cu"],"1F1E8-1F1FC":["flag_cw","cw"],"1F1E8-1F1FE":["flag_cy","cy"],"1F1E8-1F1FF":["flag_cz","cz"],"1F1E9-1F1F0":["flag_dk","dk"],"1F1E9-1F1EF":["flag_dj","dj"],"1F1E9-1F1F2":["flag_dm","dm"],"1F1E9-1F1F4":["flag_do","do"],"1F1EA-1F1E8":["flag_ec","ec"],"1F1EA-1F1EC":["flag_eg","eg"],"1F1F8-1F1FB":["flag_sv","sv"],"1F1EC-1F1F6":["flag_gq","gq"],"1F1EA-1F1F7":["flag_er","er"],"1F1EA-1F1EA":["flag_ee","ee"],"1F1EA-1F1F9":["flag_et","et"],"1F1EA-1F1FA":["flag_eu","eu"],"1F1EB-1F1F0":["flag_fk","fk"],"1F1EB-1F1F4":["flag_fo","fo"],"1F1EB-1F1EF":["flag_fj","fj"],"1F1EB-1F1EE":["flag_fi","fi"],"1F1EB-1F1F7":["flag_fr","fr"],"1F1EC-1F1EB":["flag_gf","gf"],"1F1F5-1F1EB":["flag_pf","pf"],"1F1F9-1F1EB":["flag_tf","tf"],"1F1EC-1F1E6":["flag_ga","ga"],"1F1EC-1F1F2":["flag_gm","gm"],"1F1EC-1F1EA":["flag_ge","ge"],"1F1E9-1F1EA":["flag_de","de"],"1F1EC-1F1ED":["flag_gh","gh"],"1F1EC-1F1EE":["flag_gi","gi"],"1F1EC-1F1F7":["flag_gr","gr"],"1F1EC-1F1F1":["flag_gl","gl"],"1F1EC-1F1E9":["flag_gd","gd"],"1F1EC-1F1F5":["flag_gp","gp"],"1F1EC-1F1FA":["flag_gu","gu"],"1F1EC-1F1F9":["flag_gt","gt"],"1F1EC-1F1EC":["flag_gg","gg"],"1F1EC-1F1F3":["flag_gn","gn"],"1F1EC-1F1FC":["flag_gw","gw"],"1F1EC-1F1FE":["flag_gy","gy"],"1F1ED-1F1F9":["flag_ht","ht"],"1F1ED-1F1F3":["flag_hn","hn"],"1F1ED-1F1F0":["flag_hk","hk"],"1F1ED-1F1FA":["flag_hu","hu"],"1F1EE-1F1F8":["flag_is","is"],"1F1EE-1F1F3":["flag_in","in"],"1F1EE-1F1E9":["flag_id","indonesia"],"1F1EE-1F1F7":["flag_ir","ir"],"1F1EE-1F1F6":["flag_iq","iq"],"1F1EE-1F1EA":["flag_ie","ie"],"1F1EE-1F1F2":["flag_im","im"],"1F1EE-1F1F1":["flag_il","il"],"1F1EE-1F1F9":["flag_it","it"],"1F1EF-1F1F2":["flag_jm","jm"],"1F1EF-1F1F5":["flag_jp","jp"],"1F38C":"crossed_flags","1F1EF-1F1EA":["flag_je","je"],"1F1EF-1F1F4":["flag_jo","jo"],"1F1F0-1F1FF":["flag_kz","kz"],"1F1F0-1F1EA":["flag_ke","ke"],"1F1F0-1F1EE":["flag_ki","ki"],"1F1FD-1F1F0":["flag_xk","xk"],"1F1F0-1F1FC":["flag_kw","kw"],"1F1F0-1F1EC":["flag_kg","kg"],"1F1F1-1F1E6":["flag_la","la"],"1F1F1-1F1FB":["flag_lv","lv"],"1F1F1-1F1E7":["flag_lb","lb"],"1F1F1-1F1F8":["flag_ls","ls"],"1F1F1-1F1F7":["flag_lr","lr"],"1F1F1-1F1FE":["flag_ly","ly"],"1F1F1-1F1EE":["flag_li","li"],"1F1F1-1F1F9":["flag_lt","lt"],"1F1F1-1F1FA":["flag_lu","lu"],"1F1F2-1F1F4":["flag_mo","mo"],"1F1F2-1F1F0":["flag_mk","mk"],"1F1F2-1F1EC":["flag_mg","mg"],"1F1F2-1F1FC":["flag_mw","mw"],"1F1F2-1F1FE":["flag_my","my"],"1F1F2-1F1FB":["flag_mv","mv"],"1F1F2-1F1F1":["flag_ml","ml"],"1F1F2-1F1F9":["flag_mt","mt"],"1F1F2-1F1ED":["flag_mh","mh"],"1F1F2-1F1F6":["flag_mq","mq"],"1F1F2-1F1F7":["flag_mr","mr"],"1F1F2-1F1FA":["flag_mu","mu"],"1F1FE-1F1F9":["flag_yt","yt"],"1F1F2-1F1FD":["flag_mx","mx"],"1F1EB-1F1F2":["flag_fm","fm"],"1F1F2-1F1E9":["flag_md","md"],"1F1F2-1F1E8":["flag_mc","mc"],"1F1F2-1F1F3":["flag_mn","mn"],"1F1F2-1F1EA":["flag_me","me"],"1F1F2-1F1F8":["flag_ms","ms"],"1F1F2-1F1E6":["flag_ma","ma"],"1F1F2-1F1FF":["flag_mz","mz"],"1F1F2-1F1F2":["flag_mm","mm"],"1F1F3-1F1E6":["flag_na","na"],"1F1F3-1F1F7":["flag_nr","nr"],"1F1F3-1F1F5":["flag_np","np"],"1F1F3-1F1F1":["flag_nl","nl"],"1F1F3-1F1E8":["flag_nc","nc"],"1F1F3-1F1FF":["flag_nz","nz"],"1F1F3-1F1EE":["flag_ni","ni"],"1F1F3-1F1EA":["flag_ne","ne"],"1F1F3-1F1EC":["flag_ng","nigeria"],"1F1F3-1F1FA":["flag_nu","nu"],"1F1F3-1F1EB":["flag_nf","nf"],"1F1F0-1F1F5":["flag_kp","kp"],"1F1F2-1F1F5":["flag_mp","mp"],"1F1F3-1F1F4":["flag_no","no"],"1F1F4-1F1F2":["flag_om","om"],"1F1F5-1F1F0":["flag_pk","pk"],"1F1F5-1F1FC":["flag_pw","pw"],"1F1F5-1F1F8":["flag_ps","ps"],"1F1F5-1F1E6":["flag_pa","pa"],"1F1F5-1F1EC":["flag_pg","pg"],"1F1F5-1F1FE":["flag_py","py"],"1F1F5-1F1EA":["flag_pe","pe"],"1F1F5-1F1ED":["flag_ph","ph"],"1F1F5-1F1F3":["flag_pn","pn"],"1F1F5-1F1F1":["flag_pl","pl"],"1F1F5-1F1F9":["flag_pt","pt"],"1F1F5-1F1F7":["flag_pr","pr"],"1F1F6-1F1E6":["flag_qa","qa"],"1F1F7-1F1EA":["flag_re","re"],"1F1F7-1F1F4":["flag_ro","ro"],"1F1F7-1F1FA":["flag_ru","ru"],"1F1F7-1F1FC":["flag_rw","rw"],"1F1FC-1F1F8":["flag_ws","ws"],"1F1F8-1F1F2":["flag_sm","sm"],"1F1F8-1F1F9":["flag_st","st"],"1F1F8-1F1E6":["flag_sa","saudiarabia","saudi"],"1F1F8-1F1F3":["flag_sn","sn"],"1F1F7-1F1F8":["flag_rs","rs"],"1F1F8-1F1E8":["flag_sc","sc"],"1F1F8-1F1F1":["flag_sl","sl"],"1F1F8-1F1EC":["flag_sg","sg"],"1F1F8-1F1FD":["flag_sx","sx"],"1F1F8-1F1F0":["flag_sk","sk"],"1F1F8-1F1EE":["flag_si","si"],"1F1EC-1F1F8":["flag_gs","gs"],"1F1F8-1F1E7":["flag_sb","sb"],"1F1F8-1F1F4":["flag_so","so"],"1F1FF-1F1E6":["flag_za","za"],"1F1F0-1F1F7":["flag_kr","kr"],"1F1F8-1F1F8":["flag_ss","ss"],"1F1EA-1F1F8":["flag_es","es"],"1F1F1-1F1F0":["flag_lk","lk"],"1F1E7-1F1F1":["flag_bl","bl"],"1F1F8-1F1ED":["flag_sh","sh"],"1F1F0-1F1F3":["flag_kn","kn"],"1F1F1-1F1E8":["flag_lc","lc"],"1F1F5-1F1F2":["flag_pm","pm"],"1F1FB-1F1E8":["flag_vc","vc"],"1F1F8-1F1E9":["flag_sd","sd"],"1F1F8-1F1F7":["flag_sr","sr"],"1F1F8-1F1FF":["flag_sz","sz"],"1F1F8-1F1EA":["flag_se","se"],"1F1E8-1F1ED":["flag_ch","ch"],"1F1F8-1F1FE":["flag_sy","sy"],"1F1F9-1F1FC":["flag_tw","tw"],"1F1F9-1F1EF":["flag_tj","tj"],"1F1F9-1F1FF":["flag_tz","tz"],"1F1F9-1F1ED":["flag_th","th"],"1F1F9-1F1F1":["flag_tl","tl"],"1F1F9-1F1EC":["flag_tg","tg"],"1F1F9-1F1F0":["flag_tk","tk"],"1F1F9-1F1F4":["flag_to","to"],"1F1F9-1F1F9":["flag_tt","tt"],"1F1F9-1F1F3":["flag_tn","tn"],"1F1F9-1F1F7":["flag_tr","tr"],"1F1F9-1F1F2":["flag_tm","turkmenistan"],"1F1F9-1F1E8":["flag_tc","tc"],"1F1FB-1F1EE":["flag_vi","vi"],"1F1F9-1F1FB":["flag_tv","tuvalu"],"1F1FA-1F1EC":["flag_ug","ug"],"1F1FA-1F1E6":["flag_ua","ua"],"1F1E6-1F1EA":["flag_ae","ae"],"1F1EC-1F1E7":["flag_gb","gb"],"1F3F4-E0067-E0062-E0065-E006E-E0067-E007F":"england","1F3F4-E0067-E0062-E0073-E0063-E0074-E007F":"scotland","1F3F4-E0067-E0062-E0077-E006C-E0073-E007F":"wales","1F1FA-1F1F8":["flag_us","us"],"1F1FA-1F1FE":["flag_uy","uy"],"1F1FA-1F1FF":["flag_uz","uz"],"1F1FB-1F1FA":["flag_vu","vu"],"1F1FB-1F1E6":["flag_va","va"],"1F1FB-1F1EA":["flag_ve","ve"],"1F1FB-1F1F3":["flag_vn","vn"],"1F1FC-1F1EB":["flag_wf","wf"],"1F1EA-1F1ED":["flag_eh","eh"],"1F1FE-1F1EA":["flag_ye","ye"],"1F1FF-1F1F2":["flag_zm","zm"],"1F1FF-1F1FC":["flag_zw","zw"],"1F1E6-1F1E8":["flag_ac","ac"],"1F1E7-1F1FB":["flag_bv","bv"],"1F1E8-1F1F5":["flag_cp","cp"],"1F1EA-1F1E6":["flag_ea","ea"],"1F1E9-1F1EC":["flag_dg","dg"],"1F1ED-1F1F2":["flag_hm","hm"],"1F1F2-1F1EB":["flag_mf","mf"],"1F1F8-1F1EF":["flag_sj","sj"],"1F1F9-1F1E6":["flag_ta","ta"],"1F1FA-1F1F2":["flag_um","um"],"1F1FA-1F1F3":"united_nations","1F3FB":"tone1","1F3FC":"tone2","1F3FD":"tone3","1F3FE":"tone4","1F3FF":"tone5","1F1FF":"regional_indicator_z","1F1FE":"regional_indicator_y","1F1FD":"regional_indicator_x","1F1FC":"regional_indicator_w","1F1FB":"regional_indicator_v","1F1FA":"regional_indicator_u","1F1F9":"regional_indicator_t","1F1F8":"regional_indicator_s","1F1F7":"regional_indicator_r","1F1F6":"regional_indicator_q","1F1F5":"regional_indicator_p","1F1F4":"regional_indicator_o","1F1F3":"regional_indicator_n","1F1F2":"regional_indicator_m","1F1F1":"regional_indicator_l","1F1F0":"regional_indicator_k","1F1EF":"regional_indicator_j","1F1EE":"regional_indicator_i","1F1ED":"regional_indicator_h","1F1EC":"regional_indicator_g","1F1EB":"regional_indicator_f","1F1EA":"regional_indicator_e","1F1E9":"regional_indicator_d","1F1E8":"regional_indicator_c","1F1E7":"regional_indicator_b","1F1E6":"regional_indicator_a"}');function os(e){return Array.isArray?Array.isArray(e):"[object Array]"===cs(e)}function rs(e){return"string"==typeof e}function is(e){return"number"==typeof e}function as(e){return"object"==typeof e}function ss(e){return null!=e}function us(e){return!e.trim().length}function cs(e){return null==e?void 0===e?"[object Undefined]":"[object Null]":Object.prototype.toString.call(e)}const ls=Object.prototype.hasOwnProperty;class ds{constructor(e){this._keys=[],this._keyMap={};let t=0;e.forEach((e=>{let n=hs(e);t+=n.weight,this._keys.push(n),this._keyMap[n.id]=n,t+=n.weight})),this._keys.forEach((e=>{e.weight/=t}))}get(e){return this._keyMap[e]}keys(){return this._keys}toJSON(){return JSON.stringify(this._keys)}}function hs(e){let t=null,n=null,o=null,r=1;if(rs(e)||os(e))o=e,t=ps(e),n=fs(e);else{if(!ls.call(e,"name"))throw new Error("Missing name property in key");const i=e.name;if(o=i,ls.call(e,"weight")&&(r=e.weight,r<=0))throw new Error((e=>`Property 'weight' in key '${e}' must be a positive integer`)(i));t=ps(i),n=fs(i)}return{path:t,id:n,weight:r,src:o}}function ps(e){return os(e)?e:e.split(".")}function fs(e){return os(e)?e.join("."):e}var gs={isCaseSensitive:!1,includeScore:!1,keys:[],shouldSort:!0,sortFn:(e,t)=>e.score===t.score?e.idx{if(ss(e))if(t[i]){const a=e[t[i]];if(!ss(a))return;if(i===t.length-1&&(rs(a)||is(a)||function(e){return!0===e||!1===e||function(e){return as(e)&&null!==e}(e)&&"[object Boolean]"==cs(e)}(a)))n.push(function(e){return null==e?"":function(e){if("string"==typeof e)return e;let t=e+"";return"0"==t&&1/e==-1/0?"-0":t}(e)}(a));else if(os(a)){o=!0;for(let e=0,n=a.length;e{this._keysMap[e.id]=t}))}create(){!this.isCreated&&this.docs.length&&(this.isCreated=!0,rs(this.docs[0])?this.docs.forEach(((e,t)=>{this._addString(e,t)})):this.docs.forEach(((e,t)=>{this._addObject(e,t)})),this.norm.clear())}add(e){const t=this.size();rs(e)?this._addString(e,t):this._addObject(e,t)}removeAt(e){this.records.splice(e,1);for(let t=e,n=this.size();t{let r=this.getFn(e,t.path);if(ss(r))if(os(r)){let e=[];const t=[{nestedArrIndex:-1,value:r}];for(;t.length;){const{nestedArrIndex:n,value:o}=t.pop();if(ss(o))if(rs(o)&&!us(o)){let t={v:o,i:n,n:this.norm.get(o)};e.push(t)}else os(o)&&o.forEach(((e,n)=>{t.push({nestedArrIndex:n,value:e})}))}n.$[o]=e}else if(!us(r)){let e={v:r,n:this.norm.get(r)};n.$[o]=e}})),this.records.push(n)}toJSON(){return{keys:this.keys,records:this.records}}}function Fs(e,t,{getFn:n=gs.getFn}={}){const o=new _s({getFn:n});return o.setKeys(e.map(hs)),o.setSources(t),o.create(),o}function ys(e,{errors:t=0,currentLocation:n=0,expectedLocation:o=0,distance:r=gs.distance,ignoreLocation:i=gs.ignoreLocation}={}){const a=t/e.length;if(i)return a;const s=Math.abs(o-n);return r?a+s/r:s?1:a}const bs=32;function vs(e){let t={};for(let n=0,o=e.length;n{this.chunks.push({pattern:e,alphabet:vs(e),startIndex:t})},l=this.pattern.length;if(l>bs){let e=0;const t=l%bs,n=l-t;for(;e{const{isMatch:f,score:g,indices:m}=function(e,t,n,{location:o=gs.location,distance:r=gs.distance,threshold:i=gs.threshold,findAllMatches:a=gs.findAllMatches,minMatchCharLength:s=gs.minMatchCharLength,includeMatches:u=gs.includeMatches,ignoreLocation:c=gs.ignoreLocation}={}){if(t.length>bs)throw new Error("Pattern length exceeds max of 32.");const l=t.length,d=e.length,h=Math.max(0,Math.min(o,d));let p=i,f=h;const g=s>1||u,m=g?Array(d):[];let _;for(;(_=e.indexOf(t,f))>-1;){let e=ys(t,{currentLocation:_,expectedLocation:h,distance:r,ignoreLocation:c});if(p=Math.min(e,p),f=_+l,g){let e=0;for(;e=u;i-=1){let a=i-1,s=n[e.charAt(a)];if(g&&(m[a]=+!!s),w[i]=(w[i+1]<<1|1)&s,o&&(w[i]|=(F[i+1]|F[i])<<1|1|F[i+1]),w[i]&v&&(y=ys(t,{errors:o,currentLocation:a,expectedLocation:h,distance:r,ignoreLocation:c}),y<=p)){if(p=y,f=a,f<=h)break;u=Math.max(1,2*h-f)}}if(ys(t,{errors:o+1,currentLocation:h,expectedLocation:h,distance:r,ignoreLocation:c})>p)break;F=w}const w={isMatch:f>=0,score:Math.max(.001,y)};if(g){const e=function(e=[],t=gs.minMatchCharLength){let n=[],o=-1,r=-1,i=0;for(let a=e.length;i=t&&n.push([o,r]),o=-1)}return e[i-1]&&i-o>=t&&n.push([o,i-1]),n}(m,s);e.length?u&&(w.indices=e):w.isMatch=!1}return w}(e,t,h,{location:o+p,distance:r,threshold:i,findAllMatches:a,minMatchCharLength:s,includeMatches:n,ignoreLocation:u});f&&(d=!0),l+=g,f&&m&&(c=[...c,...m])}));let h={isMatch:d,score:d?l/this.chunks.length:1};return d&&n&&(h.indices=c),h}}class Es{constructor(e){this.pattern=e}static isMultiMatch(e){return ks(e,this.multiRegex)}static isSingleMatch(e){return ks(e,this.singleRegex)}search(){}}function ks(e,t){const n=e.match(t);return n?n[1]:null}class Ds extends Es{constructor(e,{location:t=gs.location,threshold:n=gs.threshold,distance:o=gs.distance,includeMatches:r=gs.includeMatches,findAllMatches:i=gs.findAllMatches,minMatchCharLength:a=gs.minMatchCharLength,isCaseSensitive:s=gs.isCaseSensitive,ignoreLocation:u=gs.ignoreLocation}={}){super(e),this._bitapSearch=new ws(e,{location:t,threshold:n,distance:o,includeMatches:r,findAllMatches:i,minMatchCharLength:a,isCaseSensitive:s,ignoreLocation:u})}static get type(){return"fuzzy"}static get multiRegex(){return/^"(.*)"$/}static get singleRegex(){return/^(.*)$/}search(e){return this._bitapSearch.searchIn(e)}}class Ss extends Es{constructor(e){super(e)}static get type(){return"include"}static get multiRegex(){return/^'"(.*)"$/}static get singleRegex(){return/^'(.*)$/}search(e){let t,n=0;const o=[],r=this.pattern.length;for(;(t=e.indexOf(this.pattern,n))>-1;)n=t+r,o.push([t,n-1]);const i=!!o.length;return{isMatch:i,score:i?0:1,indices:o}}}const xs=[class extends Es{constructor(e){super(e)}static get type(){return"exact"}static get multiRegex(){return/^="(.*)"$/}static get singleRegex(){return/^=(.*)$/}search(e){const t=e===this.pattern;return{isMatch:t,score:t?0:1,indices:[0,this.pattern.length-1]}}},Ss,class extends Es{constructor(e){super(e)}static get type(){return"prefix-exact"}static get multiRegex(){return/^\^"(.*)"$/}static get singleRegex(){return/^\^(.*)$/}search(e){const t=e.startsWith(this.pattern);return{isMatch:t,score:t?0:1,indices:[0,this.pattern.length-1]}}},class extends Es{constructor(e){super(e)}static get type(){return"inverse-prefix-exact"}static get multiRegex(){return/^!\^"(.*)"$/}static get singleRegex(){return/^!\^(.*)$/}search(e){const t=!e.startsWith(this.pattern);return{isMatch:t,score:t?0:1,indices:[0,e.length-1]}}},class extends Es{constructor(e){super(e)}static get type(){return"inverse-suffix-exact"}static get multiRegex(){return/^!"(.*)"\$$/}static get singleRegex(){return/^!(.*)\$$/}search(e){const t=!e.endsWith(this.pattern);return{isMatch:t,score:t?0:1,indices:[0,e.length-1]}}},class extends Es{constructor(e){super(e)}static get type(){return"suffix-exact"}static get multiRegex(){return/^"(.*)"\$$/}static get singleRegex(){return/^(.*)\$$/}search(e){const t=e.endsWith(this.pattern);return{isMatch:t,score:t?0:1,indices:[e.length-this.pattern.length,e.length-1]}}},class extends Es{constructor(e){super(e)}static get type(){return"inverse-exact"}static get multiRegex(){return/^!"(.*)"$/}static get singleRegex(){return/^!(.*)$/}search(e){const t=-1===e.indexOf(this.pattern);return{isMatch:t,score:t?0:1,indices:[0,e.length-1]}}},Ds],Cs=xs.length,As=/ +(?=([^\"]*\"[^\"]*\")*[^\"]*$)/,Ts=new Set([Ds.type,Ss.type]);const Rs=[];function Is(e,t){for(let n=0,o=Rs.length;n!(!e.$and&&!e.$or),Bs=e=>({[Ms]:Object.keys(e).map((t=>({[t]:e[t]})))});function Ns(e,t,{auto:n=!0}={}){const o=e=>{let r=Object.keys(e);const i=(e=>!!e.$path)(e);if(!i&&r.length>1&&!Os(e))return o(Bs(e));if((e=>!os(e)&&as(e)&&!Os(e))(e)){const o=i?e.$path:r[0],a=i?e.$val:e[o];if(!rs(a))throw new Error((e=>`Invalid value for key ${e}`)(o));const s={keyId:fs(o),pattern:a};return n&&(s.searcher=Is(a,t)),s}let a={children:[],operator:r[0]};return r.forEach((t=>{const n=e[t];os(n)&&n.forEach((e=>{a.children.push(o(e))}))})),a};return Os(e)||(e=Bs(e)),o(e)}function Ls(e,t){const n=e.matches;t.matches=[],ss(n)&&n.forEach((e=>{if(!ss(e.indices)||!e.indices.length)return;const{indices:n,value:o}=e;let r={indices:n,value:o};e.key&&(r.key=e.key.src),e.idx>-1&&(r.refIndex=e.idx),t.matches.push(r)}))}function Ps(e,t){t.score=e.score}class Us{constructor(e,t={},n){this.options={...gs,...t},this.options.useExtendedSearch,this._keyStore=new ds(this.options.keys),this.setCollection(e,n)}setCollection(e,t){if(this._docs=e,t&&!(t instanceof _s))throw new Error("Incorrect 'index' type");this._myIndex=t||Fs(this.options.keys,this._docs,{getFn:this.options.getFn})}add(e){ss(e)&&(this._docs.push(e),this._myIndex.add(e))}remove(e=(()=>!1)){const t=[];for(let n=0,o=this._docs.length;n{let n=1;e.matches.forEach((({key:e,norm:o,score:r})=>{const i=e?e.weight:null;n*=Math.pow(0===r&&i?Number.EPSILON:r,(i||1)*(t?1:o))})),e.score=n}))}(s,{ignoreFieldNorm:a}),r&&s.sort(i),is(t)&&t>-1&&(s=s.slice(0,t)),function(e,t,{includeMatches:n=gs.includeMatches,includeScore:o=gs.includeScore}={}){const r=[];return n&&r.push(Ls),o&&r.push(Ps),e.map((e=>{const{idx:n}=e,o={item:t[n],refIndex:n};return r.length&&r.forEach((t=>{t(e,o)})),o}))}(s,this._docs,{includeMatches:n,includeScore:o})}_searchStringList(e){const t=Is(e,this.options),{records:n}=this._myIndex,o=[];return n.forEach((({v:e,i:n,n:r})=>{if(!ss(e))return;const{isMatch:i,score:a,indices:s}=t.searchIn(e);i&&o.push({item:e,idx:n,matches:[{score:a,value:e,norm:r,indices:s}]})})),o}_searchLogical(e){const t=Ns(e,this.options),n=(e,t,o)=>{if(!e.children){const{keyId:n,searcher:r}=e,i=this._findMatches({key:this._keyStore.get(n),value:this._myIndex.getValueForItemAtKeyId(t,n),searcher:r});return i&&i.length?[{idx:o,item:t,matches:i}]:[]}switch(e.operator){case Ms:{const r=[];for(let i=0,a=e.children.length;i{if(ss(e)){let a=n(t,e,o);a.length&&(r[o]||(r[o]={idx:o,item:e,matches:[]},i.push(r[o])),a.forEach((({matches:e})=>{r[o].matches.push(...e)})))}})),i}_searchObjectList(e){const t=Is(e,this.options),{keys:n,records:o}=this._myIndex,r=[];return o.forEach((({$:e,i:o})=>{if(!ss(e))return;let i=[];n.forEach(((n,o)=>{i.push(...this._findMatches({key:n,value:e[o],searcher:t}))})),i.length&&r.push({idx:o,item:e,matches:i})})),r}_findMatches({key:e,value:t,searcher:n}){if(!ss(t))return[];let o=[];if(os(t))t.forEach((({v:t,i:r,n:i})=>{if(!ss(t))return;const{isMatch:a,score:s,indices:u}=n.searchIn(t);a&&o.push({score:s,key:e,value:t,idx:r,norm:i,indices:u})}));else{const{v:r,n:i}=t,{isMatch:a,score:s,indices:u}=n.searchIn(r);a&&o.push({score:s,key:e,value:r,norm:i,indices:u})}return o}}Us.version="6.4.6",Us.createIndex=Fs,Us.parseIndex=function(e,{getFn:t=gs.getFn}={}){const{keys:n,records:o}=e,r=new _s({getFn:t});return r.setKeys(n),r.setIndexRecords(o),r},Us.config=gs,Us.parseQuery=Ns,function(...e){Rs.push(...e)}(class{constructor(e,{isCaseSensitive:t=gs.isCaseSensitive,includeMatches:n=gs.includeMatches,minMatchCharLength:o=gs.minMatchCharLength,ignoreLocation:r=gs.ignoreLocation,findAllMatches:i=gs.findAllMatches,location:a=gs.location,threshold:s=gs.threshold,distance:u=gs.distance}={}){this.query=null,this.options={isCaseSensitive:t,includeMatches:n,minMatchCharLength:o,findAllMatches:i,ignoreLocation:r,location:a,threshold:s,distance:u},this.pattern=t?e:e.toLowerCase(),this.query=function(e,t={}){return e.split("|").map((e=>{let n=e.trim().split(As).filter((e=>e&&!!e.trim())),o=[];for(let e=0,r=n.length;ee.length)&&(t=e.length);for(var n=0,o=new Array(t);n=t)return"break";var s=n[a];i.push(o.createElement("span",{key:a},Qa(es.parse(s.unicode,{attributes:function(){var e;return{unicode:s.unicode,shortcodes:null===(e=s.shortcodes)||void 0===e?void 0:e.toString()}}}))))},s=r;s20&&(t=t.slice(0,20)),t.map((function(e){return e.item}))}(e)):i([])}return(0,o.useEffect)((function(){return ou.on("search-emoji",a),function(){ou.removeListener("search-emoji",a)}}),[]),0!==r.length&&o.createElement(ru,{key:"-1",name:"Search results",emojis:r})}function au(e){var t=e.onSelect,n=(0,o.useRef)(null),r=(0,o.useRef)(null);function i(e){return!1===e.classList.contains("emoji")}function a(e){var t=e.getAttribute("unicode"),n=e.getAttribute("shortcodes");return{unicode:t,shortcodes:n=void 0===n?void 0:n.split(",")}}function s(e){var t=e,n=r.current.firstElementChild,o=n.childElementCount;o>Gs.length&&(t+=o-Gs.length),n.children[t].scrollIntoView()}return o.createElement("div",{id:"emoji-board",className:"emoji-board"},o.createElement("div",{className:"emoji-board__content"},o.createElement("div",{className:"emoji-board__emojis"},o.createElement(Fn,{ref:r,autoHide:!0},o.createElement("div",{onMouseMove:function(e){if(!i(e.target)){var t=a(e.target).shortcodes;void 0!==t?n.current.placeholder!==t[0]&&n.current.setAttribute("placeholder",":".concat(t[0],":")):n.current.placeholder="Search"}},onClick:function(e){if(!i(e.target)){var n=e.target;t(a(n))}}},o.createElement(iu,null),Gs.map((function(e){return o.createElement(ru,{key:e.name,name:e.name,emojis:e.emojis})}))))),o.createElement("div",{className:"emoji-board__search"},o.createElement(Et,{size:"small",src:Vs}),o.createElement(Tt,{onChange:function(e){var t=e.target.value;setTimeout((function(){e.target.value===t&&(ou.emit("search-emoji",t),r.current.scrollTop=0)}),500)},forwardRef:n,placeholder:"Search"}))),o.createElement("div",{className:"emoji-board__nav"},o.createElement(Yr,{onClick:function(){return s(0)},src:Ws,tooltip:"Smileys",tooltipPlacement:"right"}),o.createElement(Yr,{onClick:function(){return s(1)},src:Ys,tooltip:"Animals",tooltipPlacement:"right"}),o.createElement(Yr,{onClick:function(){return s(2)},src:Zs,tooltip:"Food",tooltipPlacement:"right"}),o.createElement(Yr,{onClick:function(){return s(3)},src:Xs,tooltip:"Activity",tooltipPlacement:"right"}),o.createElement(Yr,{onClick:function(){return s(4)},src:Js,tooltip:"Travel",tooltipPlacement:"right"}),o.createElement(Yr,{onClick:function(){return s(5)},src:Qs,tooltip:"Objects",tooltipPlacement:"right"}),o.createElement(Yr,{onClick:function(){return s(6)},src:eu,tooltip:"Symbols",tooltipPlacement:"right"}),o.createElement(Yr,{onClick:function(){return s(7)},src:tu,tooltip:"Flags",tooltipPlacement:"right"})))}ru.propTypes={name:l().string.isRequired,emojis:l().arrayOf(l().shape({length:l().number,unicode:l().string,shortcodes:l().oneOfType([l().string,l().arrayOf(l().string)])})).isRequired},au.propTypes={onSelect:l().func.isRequired};const su=au,uu=n.p+"assets/vertical-menu.180cbca47512a24456ba0a74e64a5405.svg",cu=n.p+"assets/circle-plus.d6fd1e875f585a026f8196da8e1a7b64.svg",lu=n.p+"assets/send.507da28d5579add6eccc11cba4870a69.svg",du=n.p+"assets/add-user.d87fd7bdbcd69110487cade29b6cdab6.svg",hu=n.p+"assets/chevron-bottom.8fba8942b34b3f8d54820d2dfde94cc2.svg",pu=n.p+"assets/shield.498420bdf2ec5957adc2646fa892026d.svg",fu=n.p+"assets/vlc.12ce0b57b1b136a0150c3c5f147ef08f.svg",gu=n.p+"assets/volume-full.a74609ebaadf79cabc7fee7590f52793.svg",mu=n.p+"assets/file.71d04d960aa446d4672fc1f60cd462dc.svg";function _u(e,t,n,o,r,i,a){try{var s=e[i](a),u=s.value}catch(e){return void n(e)}s.done?t(u):Promise.resolve(u).then(o,r)}function Fu(e){return function(){var t=this,n=arguments;return new Promise((function(o,r){var i=e.apply(t,n);function a(e){_u(i,o,r,a,s,"next",e)}function s(e){_u(i,o,r,a,s,"throw",e)}a(void 0)}))}}function yu(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(e)){var n=[],o=!0,r=!1,i=void 0;try{for(var a,s=e[Symbol.iterator]();!(o=(a=s.next()).done)&&(n.push(a.value),!t||n.length!==t);o=!0);}catch(e){r=!0,i=e}finally{try{o||null==s.return||s.return()}finally{if(r)throw i}}return n}}(e,t)||bu(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function bu(e,t){if(e){if("string"==typeof e)return vu(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?vu(e,t):void 0}}function vu(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,o=new Array(t);n"))return null;var t=e.slice(e.indexOf("@")),n=t.slice(0,t.indexOf(">")),o=(t=t.slice(t.indexOf(">")+2)).slice(0,t.indexOf("\n\n"));return t=t.slice(t.indexOf("\n\n")+2),""===n?null:{userId:n,replyContent:o,content:t}}function Du(e){var t=e.current.scrollHeight-e.current.offsetHeight;e.current.scrollTop=t}function Su(e){var t=e.current;return t.scrollHeight-(t.scrollTop+t.offsetHeight)<=e.current.lastElementChild.lastElementChild.lastElementChild.offsetHeight+48}function xu(e){var t,n=e.roomId,r=Qe.matrixClient,i=r.getRoom(n).getAvatarUrl(r.baseUrl,36,36,"crop"),a=r.getRoom(n).name,s=Qe.roomList.directs.has(n),u=null===(t=r.getRoom(n).currentState.getStateEvents("m.room.topic")[0])||void 0===t?void 0:t.getContent().topic;return o.createElement(Hr,null,o.createElement(Sr,{imageSrc:i,text:a.slice(0,1),bgColor:gn(a),size:"small"}),o.createElement(Vr,null,o.createElement(vt,{variant:"h2"},a),void 0!==u&&o.createElement("p",{title:u,className:"text text-b3"},u)),o.createElement(Yr,{onClick:dn,tooltip:"People",src:Lr}),o.createElement(Ir,{placement:"bottom",content:function(e){return o.createElement(o.Fragment,null,o.createElement(Mr,null,"Options"),o.createElement(Or,{iconSrc:du,onClick:function(){pn(n),e()}},"Invite"),o.createElement(Or,{iconSrc:Ga,variant:"danger",onClick:function(){return Ni(n,s)}},"Leave"))},render:function(e){return o.createElement(Yr,{onClick:e,tooltip:"Options",src:uu})}}))}xu.propTypes={roomId:l().string.isRequired};var Cu=!0;function Au(e){var t,n=e.roomId,r=e.roomTimeline,i=e.timelineScroll,a=yu((0,o.useState)(!1),2),s=a[0],u=a[1],c=yu((0,o.useState)(null),2),l=c[0],d=c[1],h=yu((0,o.useState)(null),2),p=h[0],f=h[1],g=Qe.matrixClient;function m(){!0!==i.isScrollable()&&r.paginateBack()}function _(){var e=r.room,t=r.timeline;ut(e)&&0!==t.length&&g.sendReadReceipt(t[t.length-1])}function F(){r.isOngoingPagination||s||r.paginateBack()}function y(e){Cu=e,e&&_()}var b=function(e){e?(f({}),m()):u(!0)},v=function(){Cu&&_(),d({})};(0,o.useEffect)((function(){u(!1),Cu=!0}),[n]),(0,o.useEffect)((function(){return _()}),[r]),(0,o.useEffect)((function(){return r.on(se.events.roomTimeline.EVENT,v),r.on(se.events.roomTimeline.PAGINATED,b),wu.on("reached-top",F),wu.on("toggle-reached-bottom",y),function(){r.removeListener(se.events.roomTimeline.EVENT,v),r.removeListener(se.events.roomTimeline.PAGINATED,b),wu.removeListener("reached-top",F),wu.removeListener("toggle-reached-bottom",y)}}),[r,s,p]),(0,o.useLayoutEffect)((function(){i.reachBottom(),m()}),[r]),(0,o.useLayoutEffect)((function(){null!==p&&i.tryRestoringScroll()}),[p]),(0,o.useEffect)((function(){null!==l&&Cu&&i.reachBottom()}),[l]);var w=null,E=null===(t=r.room.currentState.getStateEvents("m.room.topic")[0])||void 0===t?void 0:t.getContent().topic;return o.createElement("div",{className:"channel-view__content"},o.createElement("div",{className:"timeline__wrapper"},"m.room.create"!==r.timeline[0].getType()&&!s&&o.createElement(o.Fragment,null,o.createElement(wa,{key:Math.random().toString(20).substr(2,6)}),o.createElement(wa,{key:Math.random().toString(20).substr(2,6)}),o.createElement(wa,{key:Math.random().toString(20).substr(2,6)})),"m.room.create"!==r.timeline[0].getType()&&s&&o.createElement(Xa,{key:Math.random().toString(20).substr(2,6),avatarSrc:r.room.getAvatarUrl(Qe.matrixClient.baseUrl,80,80,"crop"),name:r.room.name,heading:"Welcome to ".concat(r.room.name),desc:"This is the beginning of ".concat(r.room.name," channel.").concat(void 0!==E?" Topic: ".concat(E):"")}),r.timeline.map((function(e){var t;if("m.room.create"===e.getType()){var n,i=null===(n=r.room.currentState.getStateEvents("m.room.topic")[0])||void 0===n?void 0:n.getContent().topic;return o.createElement(Xa,{key:e.getId(),avatarSrc:r.room.getAvatarUrl(Qe.matrixClient.baseUrl,80,80,"crop"),name:r.room.name,heading:"Welcome to ".concat(r.room.name),desc:"This is the beginning of ".concat(r.room.name," channel.").concat(void 0!==i?" Topic: ".concat(i):""),time:"Created at ".concat(vi()(e.getDate(),"dd mmmm yyyy, hh:MM TT"))})}if("m.room.message"!==e.getType()&&"m.room.encrypted"!==e.getType()&&"m.room.member"!==e.getType())return!1;if("m.replace"===(null===(t=e.getRelation())||void 0===t?void 0:t.rel_type))return!1;if(e.isRedacted())return!1;var a,s,u,c,l,d,h,p=null;if(null!==w&&(a=e.getDate(),s=w.getDate(),a.getDay()!==s.getDay()||a.getMonth()!==s.getMonth()||a.getYear()!==s.getYear())&&(p=o.createElement(Ki,{key:"divider-".concat(e.getId()),text:"".concat(vi()(e.getDate(),"mmmm dd, yyyy"))})),"m.room.member"!==e.getType()){var f,m=null!==w&&"m.room.member"!==w.getType()&&function(e,t){var n=(e.getTime()-t.getTime())/1e3;return n/=60,Math.abs(Math.round(n))}(e.getDate(),w.getDate())<=5&&w.getSender()===e.getSender(),_=e.getContent().body;if(void 0===_)return null;var F=null,y=null,b="org.matrix.custom.html"===e.getContent().format,v=void 0!==(null===(f=e.getWireContent()["m.relates_to"])||void 0===f?void 0:f["m.in_reply_to"]),E=r.editedTimeline.has(e.getId()),k=r.reactionTimeline.has(e.getId());if(v){var D=ku(_);if(null!==D){var S=it(D.userId);F={color:gn(D.userId),to:S,content:D.replyContent},_=D.content}}if(E){var x=r.editedTimeline.get(e.getId()),C=x[x.length-1];if(void 0===C.getContent()["m.new_content"])return null;var A=C.getContent()["m.new_content"].body,T=ku(A);b="org.matrix.custom.html"===C.getContent()["m.new_content"].format,_=null===T?A:T.content}k&&(y=[],r.reactionTimeline.get(e.getId()).forEach((function(e){if(null!==e.getRelation())if(function(e){for(var t=0;te}};return o.createElement("div",{className:"channel-view"},o.createElement(xu,{roomId:t}),o.createElement("div",{className:"channel-view__content-wrapper"},o.createElement("div",{className:"channel-view__scrollable"},o.createElement(Fn,{onScroll:function(e){var t=e.target,n=t.scrollTop,o=t.scrollHeight;if(t.offsetHeight,Bu=n,Nu=o,!Lu&&Su(a)&&(Lu=!0,wu.emit("toggle-reached-bottom",!0)),Lu&&!Su(a)&&(Lu=!1,wu.emit("toggle-reached-bottom",!1)),n<288&&!1===Pu)return Pu=!0,void wu.emit("reached-top");Pu=!1},ref:a,autoHide:!0},null!==r&&o.createElement(Au,{roomId:t,roomTimeline:r,timelineScroll:s})),null!==r&&o.createElement(Tu,{roomId:t,roomTimeline:r,timelineScroll:s})),null!==r&&o.createElement(Ru,null,o.createElement(Mu,{roomId:t,roomTimeline:r,timelineScroll:s}),o.createElement(Ou,{roomId:t,roomTimeline:r}))))}Uu.propTypes={roomId:l().string.isRequired};const ju=Uu;function qu(e){var t=e.avatarSrc,n=e.name,r=e.color,i=e.peopleRole,a=e.onClick;return o.createElement("div",{className:"people-selector__container"},o.createElement("button",{className:"people-selector",onMouseUp:function(e){return Dt(e,".people-selector")},onClick:a,type:"button"},o.createElement(Sr,{imageSrc:t,text:n.slice(0,1),bgColor:r,size:"extra-small"}),o.createElement(vt,{className:"people-selector__name",variant:"b1"},n),null!==i&&o.createElement(vt,{className:"people-selector__role",variant:"b3"},i)))}qu.defaultProps={avatarSrc:null,peopleRole:null},qu.propTypes={avatarSrc:l().string,name:l().string.isRequired,color:l().string.isRequired,peopleRole:l().string,onClick:l().func.isRequired};const zu=qu;function Ku(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,o=new Array(t);no.toLowerCase()?1:0}function Hu(e,t){var n=String(e.powerLevel),o=String(t.powerLevel);return"100"===n&&(n="90.9"),"100"===o&&(o="90.9"),n.toLowerCase()>o.toLowerCase()?-1:n.toLowerCase()e.length)&&(t=e.length);for(var n=0,o=new Array(t);ne.length)&&(t=e.length);for(var n=0,o=new Array(t);ne.length)&&(t=e.length);for(var n=0,o=new Array(t);ne.length)&&(t=e.length);for(var n=0,o=new Array(t);ne.length)&&(t=e.length);for(var n=0,o=new Array(t);n1,c(!0),h({username:t}),!n){e.next=19;break}return e.prev=7,e.next=10,I.getProfileInfo(t);case 10:o=e.sent,g([{user_id:t,display_name:o.displayname,avatar_url:o.avatar_url}]),e.next=17;break;case 14:e.prev=14,e.t0=e.catch(7),h({error:"".concat(t," not found!")});case 17:e.next=33;break;case 19:return e.prev=19,e.next=22,I.searchUserDirectory({term:t,limit:20});case 22:if(0!==(r=e.sent).results.length){e.next=27;break}return h({error:'No matches found for "'.concat(t,'"!')}),c(!1),e.abrupt("return");case 27:g(r.results),e.next=33;break;case 30:e.prev=30,e.t1=e.catch(19),h({error:"Something went wrong!"});case 33:c(!1);case 34:case"end":return e.stop()}}),e,null,[[7,14],[19,30]])})))).apply(this,arguments)}function P(){return(P=Cc(regeneratorRuntime.mark((function e(t){var n;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(I.getUserId()!==t){e.next=2;break}return e.abrupt("return");case 2:return e.prev=2,O(t),b.delete(t),v(M(b)),e.next=8,Li({isPublic:!1,isEncrypted:!0,isDirect:!0,invite:[t]});case 8:n=e.sent,S.set(n.room_id,t),x(M(S)),e.next=18;break;case 13:e.prev=13,e.t0=e.catch(2),B(t),"string"==typeof e.t0.message?b.set(t,e.t0.message):b.set(t,"Something went wrong!"),v(M(b));case 18:case"end":return e.stop()}}),e,null,[[2,13]])})))).apply(this,arguments)}function U(){return(U=Cc(regeneratorRuntime.mark((function e(t){return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(void 0!==i){e.next=2;break}return e.abrupt("return");case 2:return e.prev=2,O(t),b.delete(t),v(M(b)),e.next=8,Ui(i,t);case 8:A.add(t),T(new Set(Array.from(A))),B(t),e.next=18;break;case 13:e.prev=13,e.t0=e.catch(2),B(t),"string"==typeof e.t0.message?b.set(t,e.t0.message):b.set(t,"Something went wrong!"),v(M(b));case 18:case"end":return e.stop()}}),e,null,[[2,13]])})))).apply(this,arguments)}return(0,o.useEffect)((function(){return function(){c(!1),h({}),g([]),F(new Set),v(new Map),k(new Map),x(new Map),T(new Set)}}),[r]),(0,o.useEffect)((function(){return Qe.roomList.on(se.events.roomList.ROOM_CREATED,N),function(){Qe.roomList.removeListener(se.events.roomList.ROOM_CREATED,N)}}),[r,_,E,S]),o.createElement(rc,{isOpen:r,title:"string"==typeof i?"Invite to ".concat(I.getRoom(i).name):"Direct message",contentOptions:o.createElement(Yr,{src:sc,onClick:a,tooltip:"Close"}),onRequestClose:a},o.createElement("div",{className:"invite-user"},o.createElement("form",{className:"invite-user__form",onSubmit:function(e){e.preventDefault(),function(){L.apply(this,arguments)}()}},o.createElement(Tt,{forwardRef:R,label:"Username or userId"}),o.createElement(xt,{disabled:u,iconSrc:Lr,variant:"primary",type:"submit"},"Search")),o.createElement("div",{className:"invite-user__search-status"},void 0!==d.username&&u&&o.createElement("div",{className:"flex--center"},o.createElement(It,{size:"small"}),o.createElement(vt,{variant:"b2"},'Searching for user "'.concat(d.username,'"...'))),void 0!==d.username&&!u&&o.createElement(vt,{variant:"b2"},'Search result for user "'.concat(d.username,'"')),d.error&&o.createElement(vt,{className:"invite-user__search-error",variant:"b2"},d.error)),0!==f.length&&o.createElement("div",{className:"invite-user__content"},(t=function(e){var t=function(e,t){return o.createElement(vt,{variant:"b2"},o.createElement("span",{style:{color:t?"var(--bg-positive)":"var(--bg-negative)"}},e))};if(I.getUserId()===e)return null;if(_.has(e))return o.createElement(It,{size:"small"});if(E.has(e))return o.createElement(xt,{onClick:function(){ln(E.get(e)),a()}},"Open");if(A.has(e))return t("Invited",!0);if("string"==typeof i){var n=I.getRoom(i).getMember(e);if(null!==n)switch(n.membership){case"join":return t("Already joined",!0);case"invite":return t("Already Invited",!0);case"ban":return t("Banned",!1)}}return"string"==typeof i?o.createElement(xt,{onClick:function(){return function(e){return U.apply(this,arguments)}(e)},variant:"primary"},"Invite"):o.createElement(xt,{onClick:function(){return function(e){return P.apply(this,arguments)}(e)},variant:"primary"},"Message")},n=function(e){return b.has(e)?o.createElement(vt,{variant:"b2"},o.createElement("span",{style:{color:"var(--bg-danger)"}},b.get(e))):null},f.map((function(e){var r=e.user_id,i="string"==typeof e.display_name?e.display_name:r;return o.createElement(ac,{key:r,avatarSrc:"string"==typeof e.avatar_url?I.mxcUrlToHttp(e.avatar_url,42,42,"crop"):null,name:i,id:r,options:t(r),desc:n(r)})}))))))}Rc.defaultProps={roomId:void 0},Rc.propTypes={isOpen:l().bool.isRequired,roomId:l().string,onRequestClose:l().func.isRequired};const Ic=Rc;function Mc(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,o=new Array(t);ne.length)&&(t=e.length);for(var n=0,o=new Array(t);ne.length)&&(t=e.length);for(var n=0,o=new Array(t);n{"use strict";e.exports=function(e){if(e)throw e}},58162:(e,t,n)=>{"use strict";var o=n(89509).Buffer;e.exports=function(e){if(e.length>=255)throw new TypeError("Alphabet too long");for(var t=new Uint8Array(256),n=0;n>>0,l=new Uint8Array(a);e[n];){var d=t[e.charCodeAt(n)];if(255===d)return;for(var h=0,p=a-1;(0!==d||h>>0,l[p]=d%256>>>0,d=d/256>>>0;if(0!==d)throw new Error("Non-zero carry");i=h,n++}if(" "!==e[n]){for(var f=a-i;f!==a&&0===l[f];)f++;var g=o.allocUnsafe(r+(a-f));g.fill(0,0,r);for(var m=r;f!==a;)g[m++]=l[f++];return g}}}return{encode:function(t){if((Array.isArray(t)||t instanceof Uint8Array)&&(t=o.from(t)),!o.isBuffer(t))throw new TypeError("Expected Buffer");if(0===t.length)return"";for(var n=0,r=0,i=0,a=t.length;i!==a&&0===t[i];)i++,n++;for(var c=(a-i)*l+1>>>0,d=new Uint8Array(c);i!==a;){for(var h=t[i],p=0,f=c-1;(0!==h||p>>0,d[f]=h%s>>>0,h=h/s>>>0;if(0!==h)throw new Error("Non-zero carry");r=p,i++}for(var g=c-r;g!==c&&0===d[g];)g++;for(var m=u.repeat(n);g{"use strict";t.byteLength=function(e){var t=u(e),n=t[0],o=t[1];return 3*(n+o)/4-o},t.toByteArray=function(e){var t,n,i=u(e),a=i[0],s=i[1],c=new r(function(e,t,n){return 3*(t+n)/4-n}(0,a,s)),l=0,d=s>0?a-4:a;for(n=0;n>16&255,c[l++]=t>>8&255,c[l++]=255&t;return 2===s&&(t=o[e.charCodeAt(n)]<<2|o[e.charCodeAt(n+1)]>>4,c[l++]=255&t),1===s&&(t=o[e.charCodeAt(n)]<<10|o[e.charCodeAt(n+1)]<<4|o[e.charCodeAt(n+2)]>>2,c[l++]=t>>8&255,c[l++]=255&t),c},t.fromByteArray=function(e){for(var t,o=e.length,r=o%3,i=[],a=16383,s=0,u=o-r;su?u:s+a));return 1===r?(t=e[o-1],i.push(n[t>>2]+n[t<<4&63]+"==")):2===r&&(t=(e[o-2]<<8)+e[o-1],i.push(n[t>>10]+n[t>>4&63]+n[t<<2&63]+"=")),i.join("")};for(var n=[],o=[],r="undefined"!=typeof Uint8Array?Uint8Array:Array,i="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",a=0,s=i.length;a0)throw new Error("Invalid string. Length must be a multiple of 4");var n=e.indexOf("=");return-1===n&&(n=t),[n,n===t?0:4-n%4]}function c(e,t,o){for(var r,i,a=[],s=t;s>18&63]+n[i>>12&63]+n[i>>6&63]+n[63&i]);return a.join("")}o["-".charCodeAt(0)]=62,o["_".charCodeAt(0)]=63},10022:(e,t,n)=>{var o=n(97631).Duplex;function r(e){if(!(this instanceof r))return new r(e);if(this._bufs=[],this.length=0,"function"==typeof e){this._callback=e;var t=function(e){this._callback&&(this._callback(e),this._callback=null)}.bind(this);this.on("pipe",(function(e){e.on("error",t)})),this.on("unpipe",(function(e){e.removeListener("error",t)}))}else Buffer.isBuffer(e)?this.append(e):Array.isArray(e)&&e.forEach(function(e){Buffer.isBuffer(e)&&this.append(e)}.bind(this));o.call(this)}n(89539).inherits(r,o),r.prototype._offset=function(e){for(var t,n=0,o=0;othis.length)&&(o=this.length),n>=this.length)return e||new Buffer(0);if(o<=0)return e||new Buffer(0);var r,i,a=!!e,s=this._offset(n),u=o-n,c=u,l=a&&t||0,d=s[1];if(0===n&&o==this.length){if(!a)return Buffer.concat(this._bufs);for(i=0;i(r=this._bufs[i].length-d))){this._bufs[i].copy(e,l,d,d+c);break}this._bufs[i].copy(e,l,d),l+=r,c-=r,d&&(d=0)}return e},r.prototype.toString=function(e,t,n){return this.slice(t,n).toString(e)},r.prototype.consume=function(e){for(;this._bufs.length;){if(!(e>this._bufs[0].length)){this._bufs[0]=this._bufs[0].slice(e),this.length-=e;break}e-=this._bufs[0].length,this.length-=this._bufs[0].length,this._bufs.shift()}return this},r.prototype.duplicate=function(){for(var e=0,t=new r;e{e.exports=Array.isArray||function(e){return"[object Array]"==Object.prototype.toString.call(e)}},6510:(e,t,n)=>{e.exports=s;var o=Object.keys||function(e){var t=[];for(var n in e)t.push(n);return t},r=n(16497);r.inherits=n(35717);var i=n(42813),a=n(79850);function s(e){if(!(this instanceof s))return new s(e);i.call(this,e),a.call(this,e),e&&!1===e.readable&&(this.readable=!1),e&&!1===e.writable&&(this.writable=!1),this.allowHalfOpen=!0,e&&!1===e.allowHalfOpen&&(this.allowHalfOpen=!1),this.once("end",u)}function u(){this.allowHalfOpen||this._writableState.ended||process.nextTick(this.end.bind(this))}r.inherits(s,i),function(e,t){for(var n=0,o=e.length;n{e.exports=i;var o=n(14059),r=n(16497);function i(e){if(!(this instanceof i))return new i(e);o.call(this,e)}r.inherits=n(35717),r.inherits(i,o),i.prototype._transform=function(e,t,n){n(null,e)}},42813:(e,t,n)=>{e.exports=l;var o=n(50430),r=n(48764).Buffer;l.ReadableState=c;var i=n(17187).EventEmitter;i.listenerCount||(i.listenerCount=function(e,t){return e.listeners(t).length});var a,s=n(42830),u=n(16497);function c(e,t){var o=(e=e||{}).highWaterMark;this.highWaterMark=o||0===o?o:16384,this.highWaterMark=~~this.highWaterMark,this.buffer=[],this.length=0,this.pipes=null,this.pipesCount=0,this.flowing=!1,this.ended=!1,this.endEmitted=!1,this.reading=!1,this.calledRead=!1,this.sync=!0,this.needReadable=!1,this.emittedReadable=!1,this.readableListening=!1,this.objectMode=!!e.objectMode,this.defaultEncoding=e.defaultEncoding||"utf8",this.ranOut=!1,this.awaitDrain=0,this.readingMore=!1,this.decoder=null,this.encoding=null,e.encoding&&(a||(a=n(75159).s),this.decoder=new a(e.encoding),this.encoding=e.encoding)}function l(e){if(!(this instanceof l))return new l(e);this._readableState=new c(e,this),this.readable=!0,s.call(this)}function d(e,t,n,o,i){var a=function(e,t){var n=null;return r.isBuffer(t)||"string"==typeof t||null==t||e.objectMode||(n=new TypeError("Invalid non-string/buffer chunk")),n}(t,n);if(a)e.emit("error",a);else if(null==n)t.reading=!1,t.ended||function(e,t){if(t.decoder&&!t.ended){var n=t.decoder.end();n&&n.length&&(t.buffer.push(n),t.length+=t.objectMode?1:n.length)}t.ended=!0,t.length>0?f(e):b(e)}(e,t);else if(t.objectMode||n&&n.length>0)if(t.ended&&!i){var s=new Error("stream.push() after EOF");e.emit("error",s)}else t.endEmitted&&i?(s=new Error("stream.unshift() after end event"),e.emit("error",s)):(!t.decoder||i||o||(n=t.decoder.write(n)),t.length+=t.objectMode?1:n.length,i?t.buffer.unshift(n):(t.reading=!1,t.buffer.push(n)),t.needReadable&&f(e),function(e,t){t.readingMore||(t.readingMore=!0,process.nextTick((function(){!function(e,t){for(var n=t.length;!t.reading&&!t.flowing&&!t.ended&&t.lengtht.highWaterMark&&(t.highWaterMark=function(e){if(e>=h)e=h;else{e--;for(var t=1;t<32;t<<=1)e|=e>>t;e++}return e}(e)),e>t.length?t.ended?t.length:(t.needReadable=!0,0):e)}function f(e){var t=e._readableState;t.needReadable=!1,t.emittedReadable||(t.emittedReadable=!0,t.sync?process.nextTick((function(){g(e)})):g(e))}function g(e){e.emit("readable")}function m(e){var t,n=e._readableState;function o(e,o,r){!1===e.write(t)&&n.awaitDrain++}for(n.awaitDrain=0;n.pipesCount&&null!==(t=e.read());)if(1===n.pipesCount?o(n.pipes):v(n.pipes,o),e.emit("data",t),n.awaitDrain>0)return;if(0===n.pipesCount)return n.flowing=!1,void(i.listenerCount(e,"data")>0&&F(e));n.ranOut=!0}function _(){this._readableState.ranOut&&(this._readableState.ranOut=!1,m(this))}function F(e,t){if(e._readableState.flowing)throw new Error("Cannot switch to old mode now.");var n=t||!1,o=!1;e.readable=!0,e.pipe=s.prototype.pipe,e.on=e.addListener=s.prototype.on,e.on("readable",(function(){var t;for(o=!0;!n&&null!==(t=e.read());)e.emit("data",t);null===t&&(o=!1,e._readableState.needReadable=!0)})),e.pause=function(){n=!0,this.emit("pause")},e.resume=function(){n=!1,o?process.nextTick((function(){e.emit("readable")})):this.read(0),this.emit("resume")},e.emit("readable")}function y(e,t){var n,o=t.buffer,i=t.length,a=!!t.decoder,s=!!t.objectMode;if(0===o.length)return null;if(0===i)n=null;else if(s)n=o.shift();else if(!e||e>=i)n=a?o.join(""):r.concat(o,i),o.length=0;else if(e0)throw new Error("endReadable called on non-empty stream");!t.endEmitted&&t.calledRead&&(t.ended=!0,process.nextTick((function(){t.endEmitted||0!==t.length||(t.endEmitted=!0,e.readable=!1,e.emit("end"))})))}function v(e,t){for(var n=0,o=e.length;n0)&&(t.emittedReadable=!1),0===e&&t.needReadable&&(t.length>=t.highWaterMark||t.ended))return f(this),null;if(0===(e=p(e,t))&&t.ended)return n=null,t.length>0&&t.decoder&&(n=y(e,t),t.length-=n.length),0===t.length&&b(this),n;var r=t.needReadable;return t.length-e<=t.highWaterMark&&(r=!0),(t.ended||t.reading)&&(r=!1),r&&(t.reading=!0,t.sync=!0,0===t.length&&(t.needReadable=!0),this._read(t.highWaterMark),t.sync=!1),r&&!t.reading&&(e=p(o,t)),null===(n=e>0?y(e,t):null)&&(t.needReadable=!0,e=0),t.length-=e,0!==t.length||t.ended||(t.needReadable=!0),t.ended&&!t.endEmitted&&0===t.length&&b(this),n},l.prototype._read=function(e){this.emit("error",new Error("not implemented"))},l.prototype.pipe=function(e,t){var n=this,r=this._readableState;switch(r.pipesCount){case 0:r.pipes=e;break;case 1:r.pipes=[r.pipes,e];break;default:r.pipes.push(e)}r.pipesCount+=1;var a=t&&!1===t.end||e===process.stdout||e===process.stderr?l:u;function s(e){e===n&&l()}function u(){e.end()}r.endEmitted?process.nextTick(a):n.once("end",a),e.on("unpipe",s);var c=function(e){return function(){var t=e._readableState;t.awaitDrain--,0===t.awaitDrain&&m(e)}}(n);function l(){e.removeListener("close",h),e.removeListener("finish",p),e.removeListener("drain",c),e.removeListener("error",d),e.removeListener("unpipe",s),n.removeListener("end",u),n.removeListener("end",l),e._writableState&&!e._writableState.needDrain||c()}function d(t){f(),e.removeListener("error",d),0===i.listenerCount(e,"error")&&e.emit("error",t)}function h(){e.removeListener("finish",p),f()}function p(){e.removeListener("close",h),f()}function f(){n.unpipe(e)}return e.on("drain",c),e._events&&e._events.error?o(e._events.error)?e._events.error.unshift(d):e._events.error=[d,e._events.error]:e.on("error",d),e.once("close",h),e.once("finish",p),e.emit("pipe",n),r.flowing||(this.on("readable",_),r.flowing=!0,process.nextTick((function(){m(n)}))),e},l.prototype.unpipe=function(e){var t=this._readableState;if(0===t.pipesCount)return this;if(1===t.pipesCount)return e&&e!==t.pipes||(e||(e=t.pipes),t.pipes=null,t.pipesCount=0,this.removeListener("readable",_),t.flowing=!1,e&&e.emit("unpipe",this)),this;if(!e){var n=t.pipes,o=t.pipesCount;t.pipes=null,t.pipesCount=0,this.removeListener("readable",_),t.flowing=!1;for(var r=0;r{e.exports=a;var o=n(6510),r=n(16497);function i(e,t){this.afterTransform=function(e,n){return function(e,t,n){var o=e._transformState;o.transforming=!1;var r=o.writecb;if(!r)return e.emit("error",new Error("no writecb in Transform class"));o.writechunk=null,o.writecb=null,null!=n&&e.push(n),r&&r(t);var i=e._readableState;i.reading=!1,(i.needReadable||i.length{e.exports=u;var o=n(48764).Buffer;u.WritableState=s;var r=n(16497);r.inherits=n(35717);var i=n(42830);function a(e,t,n){this.chunk=e,this.encoding=t,this.callback=n}function s(e,t){var n=(e=e||{}).highWaterMark;this.highWaterMark=n||0===n?n:16384,this.objectMode=!!e.objectMode,this.highWaterMark=~~this.highWaterMark,this.needDrain=!1,this.ending=!1,this.ended=!1,this.finished=!1;var o=!1===e.decodeStrings;this.decodeStrings=!o,this.defaultEncoding=e.defaultEncoding||"utf8",this.length=0,this.writing=!1,this.sync=!0,this.bufferProcessing=!1,this.onwrite=function(e){!function(e,t){var n=e._writableState,o=n.sync,r=n.writecb;if(function(e){e.writing=!1,e.writecb=null,e.length-=e.writelen,e.writelen=0}(n),t)!function(e,t,n,o,r){n?process.nextTick((function(){r(o)})):r(o),e._writableState.errorEmitted=!0,e.emit("error",o)}(e,0,o,t,r);else{var i=d(0,n);i||n.bufferProcessing||!n.buffer.length||function(e,t){t.bufferProcessing=!0;for(var n=0;n{var o=n(42830);(t=e.exports=n(42813)).Stream=o,t.Readable=t,t.Writable=n(79850),t.Duplex=n(6510),t.Transform=n(14059),t.PassThrough=n(4586),process.browser||"disable"!==process.env.READABLE_STREAM||(e.exports=n(42830))},75159:(e,t,n)=>{var o=n(48764).Buffer,r=o.isEncoding||function(e){switch(e&&e.toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":case"raw":return!0;default:return!1}},i=t.s=function(e){switch(this.encoding=(e||"utf8").toLowerCase().replace(/[-_]/,""),function(e){if(e&&!r(e))throw new Error("Unknown encoding: "+e)}(e),this.encoding){case"utf8":this.surrogateSize=3;break;case"ucs2":case"utf16le":this.surrogateSize=2,this.detectIncompleteChar=s;break;case"base64":this.surrogateSize=3,this.detectIncompleteChar=u;break;default:return void(this.write=a)}this.charBuffer=new o(6),this.charReceived=0,this.charLength=0};function a(e){return e.toString(this.encoding)}function s(e){this.charReceived=e.length%2,this.charLength=this.charReceived?2:0}function u(e){this.charReceived=e.length%3,this.charLength=this.charReceived?3:0}i.prototype.write=function(e){for(var t="";this.charLength;){var n=e.length>=this.charLength-this.charReceived?this.charLength-this.charReceived:e.length;if(e.copy(this.charBuffer,this.charReceived,0,n),this.charReceived+=n,this.charReceived=55296&&o<=56319)){if(this.charReceived=this.charLength=0,0===e.length)return t;break}this.charLength+=this.surrogateSize,t=""}this.detectIncompleteChar(e);var o,r=e.length;if(this.charLength&&(e.copy(this.charBuffer,0,e.length-this.charReceived,r),r-=this.charReceived),r=(t+=e.toString(this.encoding,0,r)).length-1,(o=t.charCodeAt(r))>=55296&&o<=56319){var i=this.surrogateSize;return this.charLength+=i,this.charReceived+=i,this.charBuffer.copy(this.charBuffer,i,0,i),e.copy(this.charBuffer,0,0,i),t.substring(0,r)}return t},i.prototype.detectIncompleteChar=function(e){for(var t=e.length>=3?3:e.length;t>0;t--){var n=e[e.length-t];if(1==t&&n>>5==6){this.charLength=2;break}if(t<=2&&n>>4==14){this.charLength=3;break}if(t<=3&&n>>3==30){this.charLength=4;break}}this.charReceived=t},i.prototype.end=function(e){var t="";if(e&&e.length&&(t=this.write(e)),this.charReceived){var n=this.charReceived,o=this.charBuffer,r=this.encoding;t+=o.slice(0,n).toString(r)}return t}},13550:function(e,t,n){!function(e,t){"use strict";function o(e,t){if(!e)throw new Error(t||"Assertion failed")}function r(e,t){e.super_=t;var n=function(){};n.prototype=t.prototype,e.prototype=new n,e.prototype.constructor=e}function i(e,t,n){if(i.isBN(e))return e;this.negative=0,this.words=null,this.length=0,this.red=null,null!==e&&("le"!==t&&"be"!==t||(n=t,t=10),this._init(e||0,t||10,n||"be"))}var a;"object"==typeof e?e.exports=i:t.BN=i,i.BN=i,i.wordSize=26;try{a="undefined"!=typeof window&&void 0!==window.Buffer?window.Buffer:n(46601).Buffer}catch(e){}function s(e,t){var n=e.charCodeAt(t);return n>=48&&n<=57?n-48:n>=65&&n<=70?n-55:n>=97&&n<=102?n-87:void o(!1,"Invalid character in "+e)}function u(e,t,n){var o=s(e,n);return n-1>=t&&(o|=s(e,n-1)<<4),o}function c(e,t,n,r){for(var i=0,a=0,s=Math.min(e.length,n),u=t;u=49?c-49+10:c>=17?c-17+10:c,o(c>=0&&a0?e:t},i.min=function(e,t){return e.cmp(t)<0?e:t},i.prototype._init=function(e,t,n){if("number"==typeof e)return this._initNumber(e,t,n);if("object"==typeof e)return this._initArray(e,t,n);"hex"===t&&(t=16),o(t===(0|t)&&t>=2&&t<=36);var r=0;"-"===(e=e.toString().replace(/\s+/g,""))[0]&&(r++,this.negative=1),r=0;r-=3)a=e[r]|e[r-1]<<8|e[r-2]<<16,this.words[i]|=a<>>26-s&67108863,(s+=24)>=26&&(s-=26,i++);else if("le"===n)for(r=0,i=0;r>>26-s&67108863,(s+=24)>=26&&(s-=26,i++);return this._strip()},i.prototype._parseHex=function(e,t,n){this.length=Math.ceil((e.length-t)/6),this.words=new Array(this.length);for(var o=0;o=t;o-=2)r=u(e,t,o)<=18?(i-=18,a+=1,this.words[a]|=r>>>26):i+=8;else for(o=(e.length-t)%2==0?t+1:t;o=18?(i-=18,a+=1,this.words[a]|=r>>>26):i+=8;this._strip()},i.prototype._parseBase=function(e,t,n){this.words=[0],this.length=1;for(var o=0,r=1;r<=67108863;r*=t)o++;o--,r=r/t|0;for(var i=e.length-n,a=i%o,s=Math.min(i,i-a)+n,u=0,l=n;l1&&0===this.words[this.length-1];)this.length--;return this._normSign()},i.prototype._normSign=function(){return 1===this.length&&0===this.words[0]&&(this.negative=0),this},"undefined"!=typeof Symbol&&"function"==typeof Symbol.for)try{i.prototype[Symbol.for("nodejs.util.inspect.custom")]=d}catch(e){i.prototype.inspect=d}else i.prototype.inspect=d;function d(){return(this.red?""}var h=["","0","00","000","0000","00000","000000","0000000","00000000","000000000","0000000000","00000000000","000000000000","0000000000000","00000000000000","000000000000000","0000000000000000","00000000000000000","000000000000000000","0000000000000000000","00000000000000000000","000000000000000000000","0000000000000000000000","00000000000000000000000","000000000000000000000000","0000000000000000000000000"],p=[0,0,25,16,12,11,10,9,8,8,7,7,7,7,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5],f=[0,0,33554432,43046721,16777216,48828125,60466176,40353607,16777216,43046721,1e7,19487171,35831808,62748517,7529536,11390625,16777216,24137569,34012224,47045881,64e6,4084101,5153632,6436343,7962624,9765625,11881376,14348907,17210368,20511149,243e5,28629151,33554432,39135393,45435424,52521875,60466176];function g(e,t,n){n.negative=t.negative^e.negative;var o=e.length+t.length|0;n.length=o,o=o-1|0;var r=0|e.words[0],i=0|t.words[0],a=r*i,s=67108863&a,u=a/67108864|0;n.words[0]=s;for(var c=1;c>>26,d=67108863&u,h=Math.min(c,t.length-1),p=Math.max(0,c-e.length+1);p<=h;p++){var f=c-p|0;l+=(a=(r=0|e.words[f])*(i=0|t.words[p])+d)/67108864|0,d=67108863&a}n.words[c]=0|d,u=0|l}return 0!==u?n.words[c]=0|u:n.length--,n._strip()}i.prototype.toString=function(e,t){var n;if(t=0|t||1,16===(e=e||10)||"hex"===e){n="";for(var r=0,i=0,a=0;a>>24-r&16777215)||a!==this.length-1?h[6-u.length]+u+n:u+n,(r+=2)>=26&&(r-=26,a--)}for(0!==i&&(n=i.toString(16)+n);n.length%t!=0;)n="0"+n;return 0!==this.negative&&(n="-"+n),n}if(e===(0|e)&&e>=2&&e<=36){var c=p[e],l=f[e];n="";var d=this.clone();for(d.negative=0;!d.isZero();){var g=d.modrn(l).toString(e);n=(d=d.idivn(l)).isZero()?g+n:h[c-g.length]+g+n}for(this.isZero()&&(n="0"+n);n.length%t!=0;)n="0"+n;return 0!==this.negative&&(n="-"+n),n}o(!1,"Base should be between 2 and 36")},i.prototype.toNumber=function(){var e=this.words[0];return 2===this.length?e+=67108864*this.words[1]:3===this.length&&1===this.words[2]?e+=4503599627370496+67108864*this.words[1]:this.length>2&&o(!1,"Number can only safely store up to 53 bits"),0!==this.negative?-e:e},i.prototype.toJSON=function(){return this.toString(16,2)},a&&(i.prototype.toBuffer=function(e,t){return this.toArrayLike(a,e,t)}),i.prototype.toArray=function(e,t){return this.toArrayLike(Array,e,t)},i.prototype.toArrayLike=function(e,t,n){this._strip();var r=this.byteLength(),i=n||Math.max(1,r);o(r<=i,"byte array longer than desired length"),o(i>0,"Requested array length <= 0");var a=function(e,t){return e.allocUnsafe?e.allocUnsafe(t):new e(t)}(e,i);return this["_toArrayLike"+("le"===t?"LE":"BE")](a,r),a},i.prototype._toArrayLikeLE=function(e,t){for(var n=0,o=0,r=0,i=0;r>8&255),n>16&255),6===i?(n>24&255),o=0,i=0):(o=a>>>24,i+=2)}if(n=0&&(e[n--]=a>>8&255),n>=0&&(e[n--]=a>>16&255),6===i?(n>=0&&(e[n--]=a>>24&255),o=0,i=0):(o=a>>>24,i+=2)}if(n>=0)for(e[n--]=o;n>=0;)e[n--]=0},Math.clz32?i.prototype._countBits=function(e){return 32-Math.clz32(e)}:i.prototype._countBits=function(e){var t=e,n=0;return t>=4096&&(n+=13,t>>>=13),t>=64&&(n+=7,t>>>=7),t>=8&&(n+=4,t>>>=4),t>=2&&(n+=2,t>>>=2),n+t},i.prototype._zeroBits=function(e){if(0===e)return 26;var t=e,n=0;return 0==(8191&t)&&(n+=13,t>>>=13),0==(127&t)&&(n+=7,t>>>=7),0==(15&t)&&(n+=4,t>>>=4),0==(3&t)&&(n+=2,t>>>=2),0==(1&t)&&n++,n},i.prototype.bitLength=function(){var e=this.words[this.length-1],t=this._countBits(e);return 26*(this.length-1)+t},i.prototype.zeroBits=function(){if(this.isZero())return 0;for(var e=0,t=0;te.length?this.clone().ior(e):e.clone().ior(this)},i.prototype.uor=function(e){return this.length>e.length?this.clone().iuor(e):e.clone().iuor(this)},i.prototype.iuand=function(e){var t;t=this.length>e.length?e:this;for(var n=0;ne.length?this.clone().iand(e):e.clone().iand(this)},i.prototype.uand=function(e){return this.length>e.length?this.clone().iuand(e):e.clone().iuand(this)},i.prototype.iuxor=function(e){var t,n;this.length>e.length?(t=this,n=e):(t=e,n=this);for(var o=0;oe.length?this.clone().ixor(e):e.clone().ixor(this)},i.prototype.uxor=function(e){return this.length>e.length?this.clone().iuxor(e):e.clone().iuxor(this)},i.prototype.inotn=function(e){o("number"==typeof e&&e>=0);var t=0|Math.ceil(e/26),n=e%26;this._expand(t),n>0&&t--;for(var r=0;r0&&(this.words[r]=~this.words[r]&67108863>>26-n),this._strip()},i.prototype.notn=function(e){return this.clone().inotn(e)},i.prototype.setn=function(e,t){o("number"==typeof e&&e>=0);var n=e/26|0,r=e%26;return this._expand(n+1),this.words[n]=t?this.words[n]|1<e.length?(n=this,o=e):(n=e,o=this);for(var r=0,i=0;i>>26;for(;0!==r&&i>>26;if(this.length=n.length,0!==r)this.words[this.length]=r,this.length++;else if(n!==this)for(;ie.length?this.clone().iadd(e):e.clone().iadd(this)},i.prototype.isub=function(e){if(0!==e.negative){e.negative=0;var t=this.iadd(e);return e.negative=1,t._normSign()}if(0!==this.negative)return this.negative=0,this.iadd(e),this.negative=1,this._normSign();var n,o,r=this.cmp(e);if(0===r)return this.negative=0,this.length=1,this.words[0]=0,this;r>0?(n=this,o=e):(n=e,o=this);for(var i=0,a=0;a>26,this.words[a]=67108863&t;for(;0!==i&&a>26,this.words[a]=67108863&t;if(0===i&&a>>13,p=0|a[1],f=8191&p,g=p>>>13,m=0|a[2],_=8191&m,F=m>>>13,y=0|a[3],b=8191&y,v=y>>>13,w=0|a[4],E=8191&w,k=w>>>13,D=0|a[5],S=8191&D,x=D>>>13,C=0|a[6],A=8191&C,T=C>>>13,R=0|a[7],I=8191&R,M=R>>>13,O=0|a[8],B=8191&O,N=O>>>13,L=0|a[9],P=8191&L,U=L>>>13,j=0|s[0],q=8191&j,z=j>>>13,K=0|s[1],G=8191&K,$=K>>>13,H=0|s[2],V=8191&H,W=H>>>13,Y=0|s[3],Z=8191&Y,X=Y>>>13,J=0|s[4],Q=8191&J,ee=J>>>13,te=0|s[5],ne=8191&te,oe=te>>>13,re=0|s[6],ie=8191&re,ae=re>>>13,se=0|s[7],ue=8191&se,ce=se>>>13,le=0|s[8],de=8191&le,he=le>>>13,pe=0|s[9],fe=8191&pe,ge=pe>>>13;n.negative=e.negative^t.negative,n.length=19;var me=(c+(o=Math.imul(d,q))|0)+((8191&(r=(r=Math.imul(d,z))+Math.imul(h,q)|0))<<13)|0;c=((i=Math.imul(h,z))+(r>>>13)|0)+(me>>>26)|0,me&=67108863,o=Math.imul(f,q),r=(r=Math.imul(f,z))+Math.imul(g,q)|0,i=Math.imul(g,z);var _e=(c+(o=o+Math.imul(d,G)|0)|0)+((8191&(r=(r=r+Math.imul(d,$)|0)+Math.imul(h,G)|0))<<13)|0;c=((i=i+Math.imul(h,$)|0)+(r>>>13)|0)+(_e>>>26)|0,_e&=67108863,o=Math.imul(_,q),r=(r=Math.imul(_,z))+Math.imul(F,q)|0,i=Math.imul(F,z),o=o+Math.imul(f,G)|0,r=(r=r+Math.imul(f,$)|0)+Math.imul(g,G)|0,i=i+Math.imul(g,$)|0;var Fe=(c+(o=o+Math.imul(d,V)|0)|0)+((8191&(r=(r=r+Math.imul(d,W)|0)+Math.imul(h,V)|0))<<13)|0;c=((i=i+Math.imul(h,W)|0)+(r>>>13)|0)+(Fe>>>26)|0,Fe&=67108863,o=Math.imul(b,q),r=(r=Math.imul(b,z))+Math.imul(v,q)|0,i=Math.imul(v,z),o=o+Math.imul(_,G)|0,r=(r=r+Math.imul(_,$)|0)+Math.imul(F,G)|0,i=i+Math.imul(F,$)|0,o=o+Math.imul(f,V)|0,r=(r=r+Math.imul(f,W)|0)+Math.imul(g,V)|0,i=i+Math.imul(g,W)|0;var ye=(c+(o=o+Math.imul(d,Z)|0)|0)+((8191&(r=(r=r+Math.imul(d,X)|0)+Math.imul(h,Z)|0))<<13)|0;c=((i=i+Math.imul(h,X)|0)+(r>>>13)|0)+(ye>>>26)|0,ye&=67108863,o=Math.imul(E,q),r=(r=Math.imul(E,z))+Math.imul(k,q)|0,i=Math.imul(k,z),o=o+Math.imul(b,G)|0,r=(r=r+Math.imul(b,$)|0)+Math.imul(v,G)|0,i=i+Math.imul(v,$)|0,o=o+Math.imul(_,V)|0,r=(r=r+Math.imul(_,W)|0)+Math.imul(F,V)|0,i=i+Math.imul(F,W)|0,o=o+Math.imul(f,Z)|0,r=(r=r+Math.imul(f,X)|0)+Math.imul(g,Z)|0,i=i+Math.imul(g,X)|0;var be=(c+(o=o+Math.imul(d,Q)|0)|0)+((8191&(r=(r=r+Math.imul(d,ee)|0)+Math.imul(h,Q)|0))<<13)|0;c=((i=i+Math.imul(h,ee)|0)+(r>>>13)|0)+(be>>>26)|0,be&=67108863,o=Math.imul(S,q),r=(r=Math.imul(S,z))+Math.imul(x,q)|0,i=Math.imul(x,z),o=o+Math.imul(E,G)|0,r=(r=r+Math.imul(E,$)|0)+Math.imul(k,G)|0,i=i+Math.imul(k,$)|0,o=o+Math.imul(b,V)|0,r=(r=r+Math.imul(b,W)|0)+Math.imul(v,V)|0,i=i+Math.imul(v,W)|0,o=o+Math.imul(_,Z)|0,r=(r=r+Math.imul(_,X)|0)+Math.imul(F,Z)|0,i=i+Math.imul(F,X)|0,o=o+Math.imul(f,Q)|0,r=(r=r+Math.imul(f,ee)|0)+Math.imul(g,Q)|0,i=i+Math.imul(g,ee)|0;var ve=(c+(o=o+Math.imul(d,ne)|0)|0)+((8191&(r=(r=r+Math.imul(d,oe)|0)+Math.imul(h,ne)|0))<<13)|0;c=((i=i+Math.imul(h,oe)|0)+(r>>>13)|0)+(ve>>>26)|0,ve&=67108863,o=Math.imul(A,q),r=(r=Math.imul(A,z))+Math.imul(T,q)|0,i=Math.imul(T,z),o=o+Math.imul(S,G)|0,r=(r=r+Math.imul(S,$)|0)+Math.imul(x,G)|0,i=i+Math.imul(x,$)|0,o=o+Math.imul(E,V)|0,r=(r=r+Math.imul(E,W)|0)+Math.imul(k,V)|0,i=i+Math.imul(k,W)|0,o=o+Math.imul(b,Z)|0,r=(r=r+Math.imul(b,X)|0)+Math.imul(v,Z)|0,i=i+Math.imul(v,X)|0,o=o+Math.imul(_,Q)|0,r=(r=r+Math.imul(_,ee)|0)+Math.imul(F,Q)|0,i=i+Math.imul(F,ee)|0,o=o+Math.imul(f,ne)|0,r=(r=r+Math.imul(f,oe)|0)+Math.imul(g,ne)|0,i=i+Math.imul(g,oe)|0;var we=(c+(o=o+Math.imul(d,ie)|0)|0)+((8191&(r=(r=r+Math.imul(d,ae)|0)+Math.imul(h,ie)|0))<<13)|0;c=((i=i+Math.imul(h,ae)|0)+(r>>>13)|0)+(we>>>26)|0,we&=67108863,o=Math.imul(I,q),r=(r=Math.imul(I,z))+Math.imul(M,q)|0,i=Math.imul(M,z),o=o+Math.imul(A,G)|0,r=(r=r+Math.imul(A,$)|0)+Math.imul(T,G)|0,i=i+Math.imul(T,$)|0,o=o+Math.imul(S,V)|0,r=(r=r+Math.imul(S,W)|0)+Math.imul(x,V)|0,i=i+Math.imul(x,W)|0,o=o+Math.imul(E,Z)|0,r=(r=r+Math.imul(E,X)|0)+Math.imul(k,Z)|0,i=i+Math.imul(k,X)|0,o=o+Math.imul(b,Q)|0,r=(r=r+Math.imul(b,ee)|0)+Math.imul(v,Q)|0,i=i+Math.imul(v,ee)|0,o=o+Math.imul(_,ne)|0,r=(r=r+Math.imul(_,oe)|0)+Math.imul(F,ne)|0,i=i+Math.imul(F,oe)|0,o=o+Math.imul(f,ie)|0,r=(r=r+Math.imul(f,ae)|0)+Math.imul(g,ie)|0,i=i+Math.imul(g,ae)|0;var Ee=(c+(o=o+Math.imul(d,ue)|0)|0)+((8191&(r=(r=r+Math.imul(d,ce)|0)+Math.imul(h,ue)|0))<<13)|0;c=((i=i+Math.imul(h,ce)|0)+(r>>>13)|0)+(Ee>>>26)|0,Ee&=67108863,o=Math.imul(B,q),r=(r=Math.imul(B,z))+Math.imul(N,q)|0,i=Math.imul(N,z),o=o+Math.imul(I,G)|0,r=(r=r+Math.imul(I,$)|0)+Math.imul(M,G)|0,i=i+Math.imul(M,$)|0,o=o+Math.imul(A,V)|0,r=(r=r+Math.imul(A,W)|0)+Math.imul(T,V)|0,i=i+Math.imul(T,W)|0,o=o+Math.imul(S,Z)|0,r=(r=r+Math.imul(S,X)|0)+Math.imul(x,Z)|0,i=i+Math.imul(x,X)|0,o=o+Math.imul(E,Q)|0,r=(r=r+Math.imul(E,ee)|0)+Math.imul(k,Q)|0,i=i+Math.imul(k,ee)|0,o=o+Math.imul(b,ne)|0,r=(r=r+Math.imul(b,oe)|0)+Math.imul(v,ne)|0,i=i+Math.imul(v,oe)|0,o=o+Math.imul(_,ie)|0,r=(r=r+Math.imul(_,ae)|0)+Math.imul(F,ie)|0,i=i+Math.imul(F,ae)|0,o=o+Math.imul(f,ue)|0,r=(r=r+Math.imul(f,ce)|0)+Math.imul(g,ue)|0,i=i+Math.imul(g,ce)|0;var ke=(c+(o=o+Math.imul(d,de)|0)|0)+((8191&(r=(r=r+Math.imul(d,he)|0)+Math.imul(h,de)|0))<<13)|0;c=((i=i+Math.imul(h,he)|0)+(r>>>13)|0)+(ke>>>26)|0,ke&=67108863,o=Math.imul(P,q),r=(r=Math.imul(P,z))+Math.imul(U,q)|0,i=Math.imul(U,z),o=o+Math.imul(B,G)|0,r=(r=r+Math.imul(B,$)|0)+Math.imul(N,G)|0,i=i+Math.imul(N,$)|0,o=o+Math.imul(I,V)|0,r=(r=r+Math.imul(I,W)|0)+Math.imul(M,V)|0,i=i+Math.imul(M,W)|0,o=o+Math.imul(A,Z)|0,r=(r=r+Math.imul(A,X)|0)+Math.imul(T,Z)|0,i=i+Math.imul(T,X)|0,o=o+Math.imul(S,Q)|0,r=(r=r+Math.imul(S,ee)|0)+Math.imul(x,Q)|0,i=i+Math.imul(x,ee)|0,o=o+Math.imul(E,ne)|0,r=(r=r+Math.imul(E,oe)|0)+Math.imul(k,ne)|0,i=i+Math.imul(k,oe)|0,o=o+Math.imul(b,ie)|0,r=(r=r+Math.imul(b,ae)|0)+Math.imul(v,ie)|0,i=i+Math.imul(v,ae)|0,o=o+Math.imul(_,ue)|0,r=(r=r+Math.imul(_,ce)|0)+Math.imul(F,ue)|0,i=i+Math.imul(F,ce)|0,o=o+Math.imul(f,de)|0,r=(r=r+Math.imul(f,he)|0)+Math.imul(g,de)|0,i=i+Math.imul(g,he)|0;var De=(c+(o=o+Math.imul(d,fe)|0)|0)+((8191&(r=(r=r+Math.imul(d,ge)|0)+Math.imul(h,fe)|0))<<13)|0;c=((i=i+Math.imul(h,ge)|0)+(r>>>13)|0)+(De>>>26)|0,De&=67108863,o=Math.imul(P,G),r=(r=Math.imul(P,$))+Math.imul(U,G)|0,i=Math.imul(U,$),o=o+Math.imul(B,V)|0,r=(r=r+Math.imul(B,W)|0)+Math.imul(N,V)|0,i=i+Math.imul(N,W)|0,o=o+Math.imul(I,Z)|0,r=(r=r+Math.imul(I,X)|0)+Math.imul(M,Z)|0,i=i+Math.imul(M,X)|0,o=o+Math.imul(A,Q)|0,r=(r=r+Math.imul(A,ee)|0)+Math.imul(T,Q)|0,i=i+Math.imul(T,ee)|0,o=o+Math.imul(S,ne)|0,r=(r=r+Math.imul(S,oe)|0)+Math.imul(x,ne)|0,i=i+Math.imul(x,oe)|0,o=o+Math.imul(E,ie)|0,r=(r=r+Math.imul(E,ae)|0)+Math.imul(k,ie)|0,i=i+Math.imul(k,ae)|0,o=o+Math.imul(b,ue)|0,r=(r=r+Math.imul(b,ce)|0)+Math.imul(v,ue)|0,i=i+Math.imul(v,ce)|0,o=o+Math.imul(_,de)|0,r=(r=r+Math.imul(_,he)|0)+Math.imul(F,de)|0,i=i+Math.imul(F,he)|0;var Se=(c+(o=o+Math.imul(f,fe)|0)|0)+((8191&(r=(r=r+Math.imul(f,ge)|0)+Math.imul(g,fe)|0))<<13)|0;c=((i=i+Math.imul(g,ge)|0)+(r>>>13)|0)+(Se>>>26)|0,Se&=67108863,o=Math.imul(P,V),r=(r=Math.imul(P,W))+Math.imul(U,V)|0,i=Math.imul(U,W),o=o+Math.imul(B,Z)|0,r=(r=r+Math.imul(B,X)|0)+Math.imul(N,Z)|0,i=i+Math.imul(N,X)|0,o=o+Math.imul(I,Q)|0,r=(r=r+Math.imul(I,ee)|0)+Math.imul(M,Q)|0,i=i+Math.imul(M,ee)|0,o=o+Math.imul(A,ne)|0,r=(r=r+Math.imul(A,oe)|0)+Math.imul(T,ne)|0,i=i+Math.imul(T,oe)|0,o=o+Math.imul(S,ie)|0,r=(r=r+Math.imul(S,ae)|0)+Math.imul(x,ie)|0,i=i+Math.imul(x,ae)|0,o=o+Math.imul(E,ue)|0,r=(r=r+Math.imul(E,ce)|0)+Math.imul(k,ue)|0,i=i+Math.imul(k,ce)|0,o=o+Math.imul(b,de)|0,r=(r=r+Math.imul(b,he)|0)+Math.imul(v,de)|0,i=i+Math.imul(v,he)|0;var xe=(c+(o=o+Math.imul(_,fe)|0)|0)+((8191&(r=(r=r+Math.imul(_,ge)|0)+Math.imul(F,fe)|0))<<13)|0;c=((i=i+Math.imul(F,ge)|0)+(r>>>13)|0)+(xe>>>26)|0,xe&=67108863,o=Math.imul(P,Z),r=(r=Math.imul(P,X))+Math.imul(U,Z)|0,i=Math.imul(U,X),o=o+Math.imul(B,Q)|0,r=(r=r+Math.imul(B,ee)|0)+Math.imul(N,Q)|0,i=i+Math.imul(N,ee)|0,o=o+Math.imul(I,ne)|0,r=(r=r+Math.imul(I,oe)|0)+Math.imul(M,ne)|0,i=i+Math.imul(M,oe)|0,o=o+Math.imul(A,ie)|0,r=(r=r+Math.imul(A,ae)|0)+Math.imul(T,ie)|0,i=i+Math.imul(T,ae)|0,o=o+Math.imul(S,ue)|0,r=(r=r+Math.imul(S,ce)|0)+Math.imul(x,ue)|0,i=i+Math.imul(x,ce)|0,o=o+Math.imul(E,de)|0,r=(r=r+Math.imul(E,he)|0)+Math.imul(k,de)|0,i=i+Math.imul(k,he)|0;var Ce=(c+(o=o+Math.imul(b,fe)|0)|0)+((8191&(r=(r=r+Math.imul(b,ge)|0)+Math.imul(v,fe)|0))<<13)|0;c=((i=i+Math.imul(v,ge)|0)+(r>>>13)|0)+(Ce>>>26)|0,Ce&=67108863,o=Math.imul(P,Q),r=(r=Math.imul(P,ee))+Math.imul(U,Q)|0,i=Math.imul(U,ee),o=o+Math.imul(B,ne)|0,r=(r=r+Math.imul(B,oe)|0)+Math.imul(N,ne)|0,i=i+Math.imul(N,oe)|0,o=o+Math.imul(I,ie)|0,r=(r=r+Math.imul(I,ae)|0)+Math.imul(M,ie)|0,i=i+Math.imul(M,ae)|0,o=o+Math.imul(A,ue)|0,r=(r=r+Math.imul(A,ce)|0)+Math.imul(T,ue)|0,i=i+Math.imul(T,ce)|0,o=o+Math.imul(S,de)|0,r=(r=r+Math.imul(S,he)|0)+Math.imul(x,de)|0,i=i+Math.imul(x,he)|0;var Ae=(c+(o=o+Math.imul(E,fe)|0)|0)+((8191&(r=(r=r+Math.imul(E,ge)|0)+Math.imul(k,fe)|0))<<13)|0;c=((i=i+Math.imul(k,ge)|0)+(r>>>13)|0)+(Ae>>>26)|0,Ae&=67108863,o=Math.imul(P,ne),r=(r=Math.imul(P,oe))+Math.imul(U,ne)|0,i=Math.imul(U,oe),o=o+Math.imul(B,ie)|0,r=(r=r+Math.imul(B,ae)|0)+Math.imul(N,ie)|0,i=i+Math.imul(N,ae)|0,o=o+Math.imul(I,ue)|0,r=(r=r+Math.imul(I,ce)|0)+Math.imul(M,ue)|0,i=i+Math.imul(M,ce)|0,o=o+Math.imul(A,de)|0,r=(r=r+Math.imul(A,he)|0)+Math.imul(T,de)|0,i=i+Math.imul(T,he)|0;var Te=(c+(o=o+Math.imul(S,fe)|0)|0)+((8191&(r=(r=r+Math.imul(S,ge)|0)+Math.imul(x,fe)|0))<<13)|0;c=((i=i+Math.imul(x,ge)|0)+(r>>>13)|0)+(Te>>>26)|0,Te&=67108863,o=Math.imul(P,ie),r=(r=Math.imul(P,ae))+Math.imul(U,ie)|0,i=Math.imul(U,ae),o=o+Math.imul(B,ue)|0,r=(r=r+Math.imul(B,ce)|0)+Math.imul(N,ue)|0,i=i+Math.imul(N,ce)|0,o=o+Math.imul(I,de)|0,r=(r=r+Math.imul(I,he)|0)+Math.imul(M,de)|0,i=i+Math.imul(M,he)|0;var Re=(c+(o=o+Math.imul(A,fe)|0)|0)+((8191&(r=(r=r+Math.imul(A,ge)|0)+Math.imul(T,fe)|0))<<13)|0;c=((i=i+Math.imul(T,ge)|0)+(r>>>13)|0)+(Re>>>26)|0,Re&=67108863,o=Math.imul(P,ue),r=(r=Math.imul(P,ce))+Math.imul(U,ue)|0,i=Math.imul(U,ce),o=o+Math.imul(B,de)|0,r=(r=r+Math.imul(B,he)|0)+Math.imul(N,de)|0,i=i+Math.imul(N,he)|0;var Ie=(c+(o=o+Math.imul(I,fe)|0)|0)+((8191&(r=(r=r+Math.imul(I,ge)|0)+Math.imul(M,fe)|0))<<13)|0;c=((i=i+Math.imul(M,ge)|0)+(r>>>13)|0)+(Ie>>>26)|0,Ie&=67108863,o=Math.imul(P,de),r=(r=Math.imul(P,he))+Math.imul(U,de)|0,i=Math.imul(U,he);var Me=(c+(o=o+Math.imul(B,fe)|0)|0)+((8191&(r=(r=r+Math.imul(B,ge)|0)+Math.imul(N,fe)|0))<<13)|0;c=((i=i+Math.imul(N,ge)|0)+(r>>>13)|0)+(Me>>>26)|0,Me&=67108863;var Oe=(c+(o=Math.imul(P,fe))|0)+((8191&(r=(r=Math.imul(P,ge))+Math.imul(U,fe)|0))<<13)|0;return c=((i=Math.imul(U,ge))+(r>>>13)|0)+(Oe>>>26)|0,Oe&=67108863,u[0]=me,u[1]=_e,u[2]=Fe,u[3]=ye,u[4]=be,u[5]=ve,u[6]=we,u[7]=Ee,u[8]=ke,u[9]=De,u[10]=Se,u[11]=xe,u[12]=Ce,u[13]=Ae,u[14]=Te,u[15]=Re,u[16]=Ie,u[17]=Me,u[18]=Oe,0!==c&&(u[19]=c,n.length++),n};function _(e,t,n){n.negative=t.negative^e.negative,n.length=e.length+t.length;for(var o=0,r=0,i=0;i>>26)|0)>>>26,a&=67108863}n.words[i]=s,o=a,a=r}return 0!==o?n.words[i]=o:n.length--,n._strip()}function F(e,t,n){return _(e,t,n)}function y(e,t){this.x=e,this.y=t}Math.imul||(m=g),i.prototype.mulTo=function(e,t){var n=this.length+e.length;return 10===this.length&&10===e.length?m(this,e,t):n<63?g(this,e,t):n<1024?_(this,e,t):F(this,e,t)},y.prototype.makeRBT=function(e){for(var t=new Array(e),n=i.prototype._countBits(e)-1,o=0;o>=1;return o},y.prototype.permute=function(e,t,n,o,r,i){for(var a=0;a>>=1)r++;return 1<>>=13,n[2*a+1]=8191&i,i>>>=13;for(a=2*t;a>=26,n+=i/67108864|0,n+=a>>>26,this.words[r]=67108863&a}return 0!==n&&(this.words[r]=n,this.length++),t?this.ineg():this},i.prototype.muln=function(e){return this.clone().imuln(e)},i.prototype.sqr=function(){return this.mul(this)},i.prototype.isqr=function(){return this.imul(this.clone())},i.prototype.pow=function(e){var t=function(e){for(var t=new Array(e.bitLength()),n=0;n>>r&1}return t}(e);if(0===t.length)return new i(1);for(var n=this,o=0;o=0);var t,n=e%26,r=(e-n)/26,i=67108863>>>26-n<<26-n;if(0!==n){var a=0;for(t=0;t>>26-n}a&&(this.words[t]=a,this.length++)}if(0!==r){for(t=this.length-1;t>=0;t--)this.words[t+r]=this.words[t];for(t=0;t=0),r=t?(t-t%26)/26:0;var i=e%26,a=Math.min((e-i)/26,this.length),s=67108863^67108863>>>i<a)for(this.length-=a,c=0;c=0&&(0!==l||c>=r);c--){var d=0|this.words[c];this.words[c]=l<<26-i|d>>>i,l=d&s}return u&&0!==l&&(u.words[u.length++]=l),0===this.length&&(this.words[0]=0,this.length=1),this._strip()},i.prototype.ishrn=function(e,t,n){return o(0===this.negative),this.iushrn(e,t,n)},i.prototype.shln=function(e){return this.clone().ishln(e)},i.prototype.ushln=function(e){return this.clone().iushln(e)},i.prototype.shrn=function(e){return this.clone().ishrn(e)},i.prototype.ushrn=function(e){return this.clone().iushrn(e)},i.prototype.testn=function(e){o("number"==typeof e&&e>=0);var t=e%26,n=(e-t)/26,r=1<=0);var t=e%26,n=(e-t)/26;if(o(0===this.negative,"imaskn works only with positive numbers"),this.length<=n)return this;if(0!==t&&n++,this.length=Math.min(n,this.length),0!==t){var r=67108863^67108863>>>t<=67108864;t++)this.words[t]-=67108864,t===this.length-1?this.words[t+1]=1:this.words[t+1]++;return this.length=Math.max(this.length,t+1),this},i.prototype.isubn=function(e){if(o("number"==typeof e),o(e<67108864),e<0)return this.iaddn(-e);if(0!==this.negative)return this.negative=0,this.iaddn(e),this.negative=1,this;if(this.words[0]-=e,1===this.length&&this.words[0]<0)this.words[0]=-this.words[0],this.negative=1;else for(var t=0;t>26)-(u/67108864|0),this.words[r+n]=67108863&i}for(;r>26,this.words[r+n]=67108863&i;if(0===s)return this._strip();for(o(-1===s),s=0,r=0;r>26,this.words[r]=67108863&i;return this.negative=1,this._strip()},i.prototype._wordDiv=function(e,t){var n=(this.length,e.length),o=this.clone(),r=e,a=0|r.words[r.length-1];0!=(n=26-this._countBits(a))&&(r=r.ushln(n),o.iushln(n),a=0|r.words[r.length-1]);var s,u=o.length-r.length;if("mod"!==t){(s=new i(null)).length=u+1,s.words=new Array(s.length);for(var c=0;c=0;d--){var h=67108864*(0|o.words[r.length+d])+(0|o.words[r.length+d-1]);for(h=Math.min(h/a|0,67108863),o._ishlnsubmul(r,h,d);0!==o.negative;)h--,o.negative=0,o._ishlnsubmul(r,1,d),o.isZero()||(o.negative^=1);s&&(s.words[d]=h)}return s&&s._strip(),o._strip(),"div"!==t&&0!==n&&o.iushrn(n),{div:s||null,mod:o}},i.prototype.divmod=function(e,t,n){return o(!e.isZero()),this.isZero()?{div:new i(0),mod:new i(0)}:0!==this.negative&&0===e.negative?(s=this.neg().divmod(e,t),"mod"!==t&&(r=s.div.neg()),"div"!==t&&(a=s.mod.neg(),n&&0!==a.negative&&a.iadd(e)),{div:r,mod:a}):0===this.negative&&0!==e.negative?(s=this.divmod(e.neg(),t),"mod"!==t&&(r=s.div.neg()),{div:r,mod:s.mod}):0!=(this.negative&e.negative)?(s=this.neg().divmod(e.neg(),t),"div"!==t&&(a=s.mod.neg(),n&&0!==a.negative&&a.isub(e)),{div:s.div,mod:a}):e.length>this.length||this.cmp(e)<0?{div:new i(0),mod:this}:1===e.length?"div"===t?{div:this.divn(e.words[0]),mod:null}:"mod"===t?{div:null,mod:new i(this.modrn(e.words[0]))}:{div:this.divn(e.words[0]),mod:new i(this.modrn(e.words[0]))}:this._wordDiv(e,t);var r,a,s},i.prototype.div=function(e){return this.divmod(e,"div",!1).div},i.prototype.mod=function(e){return this.divmod(e,"mod",!1).mod},i.prototype.umod=function(e){return this.divmod(e,"mod",!0).mod},i.prototype.divRound=function(e){var t=this.divmod(e);if(t.mod.isZero())return t.div;var n=0!==t.div.negative?t.mod.isub(e):t.mod,o=e.ushrn(1),r=e.andln(1),i=n.cmp(o);return i<0||1===r&&0===i?t.div:0!==t.div.negative?t.div.isubn(1):t.div.iaddn(1)},i.prototype.modrn=function(e){var t=e<0;t&&(e=-e),o(e<=67108863);for(var n=(1<<26)%e,r=0,i=this.length-1;i>=0;i--)r=(n*r+(0|this.words[i]))%e;return t?-r:r},i.prototype.modn=function(e){return this.modrn(e)},i.prototype.idivn=function(e){var t=e<0;t&&(e=-e),o(e<=67108863);for(var n=0,r=this.length-1;r>=0;r--){var i=(0|this.words[r])+67108864*n;this.words[r]=i/e|0,n=i%e}return this._strip(),t?this.ineg():this},i.prototype.divn=function(e){return this.clone().idivn(e)},i.prototype.egcd=function(e){o(0===e.negative),o(!e.isZero());var t=this,n=e.clone();t=0!==t.negative?t.umod(e):t.clone();for(var r=new i(1),a=new i(0),s=new i(0),u=new i(1),c=0;t.isEven()&&n.isEven();)t.iushrn(1),n.iushrn(1),++c;for(var l=n.clone(),d=t.clone();!t.isZero();){for(var h=0,p=1;0==(t.words[0]&p)&&h<26;++h,p<<=1);if(h>0)for(t.iushrn(h);h-- >0;)(r.isOdd()||a.isOdd())&&(r.iadd(l),a.isub(d)),r.iushrn(1),a.iushrn(1);for(var f=0,g=1;0==(n.words[0]&g)&&f<26;++f,g<<=1);if(f>0)for(n.iushrn(f);f-- >0;)(s.isOdd()||u.isOdd())&&(s.iadd(l),u.isub(d)),s.iushrn(1),u.iushrn(1);t.cmp(n)>=0?(t.isub(n),r.isub(s),a.isub(u)):(n.isub(t),s.isub(r),u.isub(a))}return{a:s,b:u,gcd:n.iushln(c)}},i.prototype._invmp=function(e){o(0===e.negative),o(!e.isZero());var t=this,n=e.clone();t=0!==t.negative?t.umod(e):t.clone();for(var r,a=new i(1),s=new i(0),u=n.clone();t.cmpn(1)>0&&n.cmpn(1)>0;){for(var c=0,l=1;0==(t.words[0]&l)&&c<26;++c,l<<=1);if(c>0)for(t.iushrn(c);c-- >0;)a.isOdd()&&a.iadd(u),a.iushrn(1);for(var d=0,h=1;0==(n.words[0]&h)&&d<26;++d,h<<=1);if(d>0)for(n.iushrn(d);d-- >0;)s.isOdd()&&s.iadd(u),s.iushrn(1);t.cmp(n)>=0?(t.isub(n),a.isub(s)):(n.isub(t),s.isub(a))}return(r=0===t.cmpn(1)?a:s).cmpn(0)<0&&r.iadd(e),r},i.prototype.gcd=function(e){if(this.isZero())return e.abs();if(e.isZero())return this.abs();var t=this.clone(),n=e.clone();t.negative=0,n.negative=0;for(var o=0;t.isEven()&&n.isEven();o++)t.iushrn(1),n.iushrn(1);for(;;){for(;t.isEven();)t.iushrn(1);for(;n.isEven();)n.iushrn(1);var r=t.cmp(n);if(r<0){var i=t;t=n,n=i}else if(0===r||0===n.cmpn(1))break;t.isub(n)}return n.iushln(o)},i.prototype.invm=function(e){return this.egcd(e).a.umod(e)},i.prototype.isEven=function(){return 0==(1&this.words[0])},i.prototype.isOdd=function(){return 1==(1&this.words[0])},i.prototype.andln=function(e){return this.words[0]&e},i.prototype.bincn=function(e){o("number"==typeof e);var t=e%26,n=(e-t)/26,r=1<>>26,s&=67108863,this.words[a]=s}return 0!==i&&(this.words[a]=i,this.length++),this},i.prototype.isZero=function(){return 1===this.length&&0===this.words[0]},i.prototype.cmpn=function(e){var t,n=e<0;if(0!==this.negative&&!n)return-1;if(0===this.negative&&n)return 1;if(this._strip(),this.length>1)t=1;else{n&&(e=-e),o(e<=67108863,"Number is too big");var r=0|this.words[0];t=r===e?0:re.length)return 1;if(this.length=0;n--){var o=0|this.words[n],r=0|e.words[n];if(o!==r){or&&(t=1);break}}return t},i.prototype.gtn=function(e){return 1===this.cmpn(e)},i.prototype.gt=function(e){return 1===this.cmp(e)},i.prototype.gten=function(e){return this.cmpn(e)>=0},i.prototype.gte=function(e){return this.cmp(e)>=0},i.prototype.ltn=function(e){return-1===this.cmpn(e)},i.prototype.lt=function(e){return-1===this.cmp(e)},i.prototype.lten=function(e){return this.cmpn(e)<=0},i.prototype.lte=function(e){return this.cmp(e)<=0},i.prototype.eqn=function(e){return 0===this.cmpn(e)},i.prototype.eq=function(e){return 0===this.cmp(e)},i.red=function(e){return new S(e)},i.prototype.toRed=function(e){return o(!this.red,"Already a number in reduction context"),o(0===this.negative,"red works only with positives"),e.convertTo(this)._forceRed(e)},i.prototype.fromRed=function(){return o(this.red,"fromRed works only with numbers in reduction context"),this.red.convertFrom(this)},i.prototype._forceRed=function(e){return this.red=e,this},i.prototype.forceRed=function(e){return o(!this.red,"Already a number in reduction context"),this._forceRed(e)},i.prototype.redAdd=function(e){return o(this.red,"redAdd works only with red numbers"),this.red.add(this,e)},i.prototype.redIAdd=function(e){return o(this.red,"redIAdd works only with red numbers"),this.red.iadd(this,e)},i.prototype.redSub=function(e){return o(this.red,"redSub works only with red numbers"),this.red.sub(this,e)},i.prototype.redISub=function(e){return o(this.red,"redISub works only with red numbers"),this.red.isub(this,e)},i.prototype.redShl=function(e){return o(this.red,"redShl works only with red numbers"),this.red.shl(this,e)},i.prototype.redMul=function(e){return o(this.red,"redMul works only with red numbers"),this.red._verify2(this,e),this.red.mul(this,e)},i.prototype.redIMul=function(e){return o(this.red,"redMul works only with red numbers"),this.red._verify2(this,e),this.red.imul(this,e)},i.prototype.redSqr=function(){return o(this.red,"redSqr works only with red numbers"),this.red._verify1(this),this.red.sqr(this)},i.prototype.redISqr=function(){return o(this.red,"redISqr works only with red numbers"),this.red._verify1(this),this.red.isqr(this)},i.prototype.redSqrt=function(){return o(this.red,"redSqrt works only with red numbers"),this.red._verify1(this),this.red.sqrt(this)},i.prototype.redInvm=function(){return o(this.red,"redInvm works only with red numbers"),this.red._verify1(this),this.red.invm(this)},i.prototype.redNeg=function(){return o(this.red,"redNeg works only with red numbers"),this.red._verify1(this),this.red.neg(this)},i.prototype.redPow=function(e){return o(this.red&&!e.red,"redPow(normalNum)"),this.red._verify1(this),this.red.pow(this,e)};var b={k256:null,p224:null,p192:null,p25519:null};function v(e,t){this.name=e,this.p=new i(t,16),this.n=this.p.bitLength(),this.k=new i(1).iushln(this.n).isub(this.p),this.tmp=this._tmp()}function w(){v.call(this,"k256","ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f")}function E(){v.call(this,"p224","ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001")}function k(){v.call(this,"p192","ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff")}function D(){v.call(this,"25519","7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed")}function S(e){if("string"==typeof e){var t=i._prime(e);this.m=t.p,this.prime=t}else o(e.gtn(1),"modulus must be greater than 1"),this.m=e,this.prime=null}function x(e){S.call(this,e),this.shift=this.m.bitLength(),this.shift%26!=0&&(this.shift+=26-this.shift%26),this.r=new i(1).iushln(this.shift),this.r2=this.imod(this.r.sqr()),this.rinv=this.r._invmp(this.m),this.minv=this.rinv.mul(this.r).isubn(1).div(this.m),this.minv=this.minv.umod(this.r),this.minv=this.r.sub(this.minv)}v.prototype._tmp=function(){var e=new i(null);return e.words=new Array(Math.ceil(this.n/13)),e},v.prototype.ireduce=function(e){var t,n=e;do{this.split(n,this.tmp),t=(n=(n=this.imulK(n)).iadd(this.tmp)).bitLength()}while(t>this.n);var o=t0?n.isub(this.p):void 0!==n.strip?n.strip():n._strip(),n},v.prototype.split=function(e,t){e.iushrn(this.n,0,t)},v.prototype.imulK=function(e){return e.imul(this.k)},r(w,v),w.prototype.split=function(e,t){for(var n=4194303,o=Math.min(e.length,9),r=0;r>>22,i=a}i>>>=22,e.words[r-10]=i,0===i&&e.length>10?e.length-=10:e.length-=9},w.prototype.imulK=function(e){e.words[e.length]=0,e.words[e.length+1]=0,e.length+=2;for(var t=0,n=0;n>>=26,e.words[n]=r,t=o}return 0!==t&&(e.words[e.length++]=t),e},i._prime=function(e){if(b[e])return b[e];var t;if("k256"===e)t=new w;else if("p224"===e)t=new E;else if("p192"===e)t=new k;else{if("p25519"!==e)throw new Error("Unknown prime "+e);t=new D}return b[e]=t,t},S.prototype._verify1=function(e){o(0===e.negative,"red works only with positives"),o(e.red,"red works only with red numbers")},S.prototype._verify2=function(e,t){o(0==(e.negative|t.negative),"red works only with positives"),o(e.red&&e.red===t.red,"red works only with red numbers")},S.prototype.imod=function(e){return this.prime?this.prime.ireduce(e)._forceRed(this):(l(e,e.umod(this.m)._forceRed(this)),e)},S.prototype.neg=function(e){return e.isZero()?e.clone():this.m.sub(e)._forceRed(this)},S.prototype.add=function(e,t){this._verify2(e,t);var n=e.add(t);return n.cmp(this.m)>=0&&n.isub(this.m),n._forceRed(this)},S.prototype.iadd=function(e,t){this._verify2(e,t);var n=e.iadd(t);return n.cmp(this.m)>=0&&n.isub(this.m),n},S.prototype.sub=function(e,t){this._verify2(e,t);var n=e.sub(t);return n.cmpn(0)<0&&n.iadd(this.m),n._forceRed(this)},S.prototype.isub=function(e,t){this._verify2(e,t);var n=e.isub(t);return n.cmpn(0)<0&&n.iadd(this.m),n},S.prototype.shl=function(e,t){return this._verify1(e),this.imod(e.ushln(t))},S.prototype.imul=function(e,t){return this._verify2(e,t),this.imod(e.imul(t))},S.prototype.mul=function(e,t){return this._verify2(e,t),this.imod(e.mul(t))},S.prototype.isqr=function(e){return this.imul(e,e.clone())},S.prototype.sqr=function(e){return this.mul(e,e)},S.prototype.sqrt=function(e){if(e.isZero())return e.clone();var t=this.m.andln(3);if(o(t%2==1),3===t){var n=this.m.add(new i(1)).iushrn(2);return this.pow(e,n)}for(var r=this.m.subn(1),a=0;!r.isZero()&&0===r.andln(1);)a++,r.iushrn(1);o(!r.isZero());var s=new i(1).toRed(this),u=s.redNeg(),c=this.m.subn(1).iushrn(1),l=this.m.bitLength();for(l=new i(2*l*l).toRed(this);0!==this.pow(l,c).cmp(u);)l.redIAdd(u);for(var d=this.pow(l,r),h=this.pow(e,r.addn(1).iushrn(1)),p=this.pow(e,r),f=a;0!==p.cmp(s);){for(var g=p,m=0;0!==g.cmp(s);m++)g=g.redSqr();o(m=0;o--){for(var c=t.words[o],l=u-1;l>=0;l--){var d=c>>l&1;r!==n[0]&&(r=this.sqr(r)),0!==d||0!==a?(a<<=1,a|=d,(4==++s||0===o&&0===l)&&(r=this.mul(r,n[a]),s=0,a=0)):s=0}u=26}return r},S.prototype.convertTo=function(e){var t=e.umod(this.m);return t===e?t.clone():t},S.prototype.convertFrom=function(e){var t=e.clone();return t.red=null,t},i.mont=function(e){return new x(e)},r(x,S),x.prototype.convertTo=function(e){return this.imod(e.ushln(this.shift))},x.prototype.convertFrom=function(e){var t=this.imod(e.mul(this.rinv));return t.red=null,t},x.prototype.imul=function(e,t){if(e.isZero()||t.isZero())return e.words[0]=0,e.length=1,e;var n=e.imul(t),o=n.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m),r=n.isub(o).iushrn(this.shift),i=r;return r.cmp(this.m)>=0?i=r.isub(this.m):r.cmpn(0)<0&&(i=r.iadd(this.m)),i._forceRed(this)},x.prototype.mul=function(e,t){if(e.isZero()||t.isZero())return new i(0)._forceRed(this);var n=e.mul(t),o=n.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m),r=n.isub(o).iushrn(this.shift),a=r;return r.cmp(this.m)>=0?a=r.isub(this.m):r.cmpn(0)<0&&(a=r.iadd(this.m)),a._forceRed(this)},x.prototype.invm=function(e){return this.imod(e._invmp(this.m).mul(this.r2))._forceRed(this)}}(e=n.nmd(e),this)},29931:(e,t,n)=>{var o;function r(e){this.rand=e}if(e.exports=function(e){return o||(o=new r(null)),o.generate(e)},e.exports.Rand=r,r.prototype.generate=function(e){return this._rand(e)},r.prototype._rand=function(e){if(this.rand.getBytes)return this.rand.getBytes(e);for(var t=new Uint8Array(e),n=0;n{function n(e){var t=String.fromCharCode.apply(null,e),n=window.btoa(t),o=e.length,r=4*Math.floor((o+2)/3)+(o+2)%3-2;return n.slice(0,r)}try{t.encryptAttachment=function(e){var t,o,r,i,a;return a=new Uint8Array(16),window.crypto.getRandomValues(a.subarray(0,8)),window.crypto.subtle.generateKey({name:"AES-CTR",length:256},!0,["encrypt","decrypt"]).then((function(e){return t=e,window.crypto.subtle.exportKey("jwk",t)})).then((function(n){return o=n,window.crypto.subtle.encrypt({name:"AES-CTR",counter:a,length:64},t,e)})).then((function(e){return r=e,window.crypto.subtle.digest("SHA-256",r)})).then((function(e){return i=e,{data:r,info:{v:"v2",key:o,iv:n(a),hashes:{sha256:n(new Uint8Array(i))}}}}))},t.decryptAttachment=function(e,t){if(void 0===t||void 0===t.key||void 0===t.iv||void 0===t.hashes||void 0===t.hashes.sha256)throw new Error("Invalid info. Missing info.key, info.iv or info.hashes.sha256 key");var o,r=function(e){for(var t=e+"===".slice(0,(4-e.length%4)%4),n=window.atob(t),o=new Uint8Array(n.length),r=0;r>18&63,n=i>>12&63,o=i>>6&63,r=63&i,l[u++]=a.charAt(t)+a.charAt(n)+a.charAt(o)+a.charAt(r)}while(s299)&&o.error){for(var r in e=new Error("CouchDB error: "+(o.error.reason||o.error.error)),o)e[r]=o[r];return n(e,t,o)}return n(e,t,o)}))},t})?n.apply(t,[]):n)||(e.exports=o)},74497:(e,t,n)=>{var o=n(89509).Buffer;function r(e){o.isBuffer(e)||(e=o.from(e));for(var t=e.length/4|0,n=new Array(t),r=0;r>>24]^l[f>>>16&255]^d[g>>>8&255]^h[255&m]^t[_++],a=c[f>>>24]^l[g>>>16&255]^d[m>>>8&255]^h[255&p]^t[_++],s=c[g>>>24]^l[m>>>16&255]^d[p>>>8&255]^h[255&f]^t[_++],u=c[m>>>24]^l[p>>>16&255]^d[f>>>8&255]^h[255&g]^t[_++],p=i,f=a,g=s,m=u;return i=(o[p>>>24]<<24|o[f>>>16&255]<<16|o[g>>>8&255]<<8|o[255&m])^t[_++],a=(o[f>>>24]<<24|o[g>>>16&255]<<16|o[m>>>8&255]<<8|o[255&p])^t[_++],s=(o[g>>>24]<<24|o[m>>>16&255]<<16|o[p>>>8&255]<<8|o[255&f])^t[_++],u=(o[m>>>24]<<24|o[p>>>16&255]<<16|o[f>>>8&255]<<8|o[255&g])^t[_++],[i>>>=0,a>>>=0,s>>>=0,u>>>=0]}var s=[0,1,2,4,8,16,32,64,128,27,54],u=function(){for(var e=new Array(256),t=0;t<256;t++)e[t]=t<128?t<<1:t<<1^283;for(var n=[],o=[],r=[[],[],[],[]],i=[[],[],[],[]],a=0,s=0,u=0;u<256;++u){var c=s^s<<1^s<<2^s<<3^s<<4;c=c>>>8^255&c^99,n[a]=c,o[c]=a;var l=e[a],d=e[l],h=e[d],p=257*e[c]^16843008*c;r[0][a]=p<<24|p>>>8,r[1][a]=p<<16|p>>>16,r[2][a]=p<<8|p>>>24,r[3][a]=p,p=16843009*h^65537*d^257*l^16843008*a,i[0][c]=p<<24|p>>>8,i[1][c]=p<<16|p>>>16,i[2][c]=p<<8|p>>>24,i[3][c]=p,0===a?a=s=1:(a=l^e[e[e[h^l]]],s^=e[e[s]])}return{SBOX:n,INV_SBOX:o,SUB_MIX:r,INV_SUB_MIX:i}}();function c(e){this._key=r(e),this._reset()}c.blockSize=16,c.keySize=32,c.prototype.blockSize=c.blockSize,c.prototype.keySize=c.keySize,c.prototype._reset=function(){for(var e=this._key,t=e.length,n=t+6,o=4*(n+1),r=[],i=0;i>>24,a=u.SBOX[a>>>24]<<24|u.SBOX[a>>>16&255]<<16|u.SBOX[a>>>8&255]<<8|u.SBOX[255&a],a^=s[i/t|0]<<24):t>6&&i%t==4&&(a=u.SBOX[a>>>24]<<24|u.SBOX[a>>>16&255]<<16|u.SBOX[a>>>8&255]<<8|u.SBOX[255&a]),r[i]=r[i-t]^a}for(var c=[],l=0;l>>24]]^u.INV_SUB_MIX[1][u.SBOX[h>>>16&255]]^u.INV_SUB_MIX[2][u.SBOX[h>>>8&255]]^u.INV_SUB_MIX[3][u.SBOX[255&h]]}this._nRounds=n,this._keySchedule=r,this._invKeySchedule=c},c.prototype.encryptBlockRaw=function(e){return a(e=r(e),this._keySchedule,u.SUB_MIX,u.SBOX,this._nRounds)},c.prototype.encryptBlock=function(e){var t=this.encryptBlockRaw(e),n=o.allocUnsafe(16);return n.writeUInt32BE(t[0],0),n.writeUInt32BE(t[1],4),n.writeUInt32BE(t[2],8),n.writeUInt32BE(t[3],12),n},c.prototype.decryptBlock=function(e){var t=(e=r(e))[1];e[1]=e[3],e[3]=t;var n=a(e,this._invKeySchedule,u.INV_SUB_MIX,u.INV_SBOX,this._nRounds),i=o.allocUnsafe(16);return i.writeUInt32BE(n[0],0),i.writeUInt32BE(n[3],4),i.writeUInt32BE(n[2],8),i.writeUInt32BE(n[1],12),i},c.prototype.scrub=function(){i(this._keySchedule),i(this._invKeySchedule),i(this._key)},e.exports.AES=c},62422:(e,t,n)=>{var o=n(74497),r=n(89509).Buffer,i=n(71027),a=n(35717),s=n(83288),u=n(67295),c=n(20685);function l(e,t,n,a){i.call(this);var u=r.alloc(4,0);this._cipher=new o.AES(t);var l=this._cipher.encryptBlock(u);this._ghash=new s(l),n=function(e,t,n){if(12===t.length)return e._finID=r.concat([t,r.from([0,0,0,1])]),r.concat([t,r.from([0,0,0,2])]);var o=new s(n),i=t.length,a=i%16;o.update(t),a&&(a=16-a,o.update(r.alloc(a,0))),o.update(r.alloc(8,0));var u=8*i,l=r.alloc(8);l.writeUIntBE(u,0,8),o.update(l),e._finID=o.state;var d=r.from(e._finID);return c(d),d}(this,n,l),this._prev=r.from(n),this._cache=r.allocUnsafe(0),this._secCache=r.allocUnsafe(0),this._decrypt=a,this._alen=0,this._len=0,this._mode=e,this._authTag=null,this._called=!1}a(l,i),l.prototype._update=function(e){if(!this._called&&this._alen){var t=16-this._alen%16;t<16&&(t=r.alloc(t,0),this._ghash.update(t))}this._called=!0;var n=this._mode.encrypt(this,e);return this._decrypt?this._ghash.update(e):this._ghash.update(n),this._len+=e.length,n},l.prototype._final=function(){if(this._decrypt&&!this._authTag)throw new Error("Unsupported state or unable to authenticate data");var e=u(this._ghash.final(8*this._alen,8*this._len),this._cipher.encryptBlock(this._finID));if(this._decrypt&&function(e,t){var n=0;e.length!==t.length&&n++;for(var o=Math.min(e.length,t.length),r=0;r{var o=n(71494),r=n(66193),i=n(55415);t.createCipher=t.Cipher=o.createCipher,t.createCipheriv=t.Cipheriv=o.createCipheriv,t.createDecipher=t.Decipher=r.createDecipher,t.createDecipheriv=t.Decipheriv=r.createDecipheriv,t.listCiphers=t.getCiphers=function(){return Object.keys(i)}},66193:(e,t,n)=>{var o=n(62422),r=n(89509).Buffer,i=n(45),a=n(25969),s=n(71027),u=n(74497),c=n(13048);function l(e,t,n){s.call(this),this._cache=new d,this._last=void 0,this._cipher=new u.AES(t),this._prev=r.from(n),this._mode=e,this._autopadding=!0}function d(){this.cache=r.allocUnsafe(0)}function h(e,t,n){var s=i[e.toLowerCase()];if(!s)throw new TypeError("invalid suite type");if("string"==typeof n&&(n=r.from(n)),"GCM"!==s.mode&&n.length!==s.iv)throw new TypeError("invalid iv length "+n.length);if("string"==typeof t&&(t=r.from(t)),t.length!==s.key/8)throw new TypeError("invalid key length "+t.length);return"stream"===s.type?new a(s.module,t,n,!0):"auth"===s.type?new o(s.module,t,n,!0):new l(s.module,t,n)}n(35717)(l,s),l.prototype._update=function(e){var t,n;this._cache.add(e);for(var o=[];t=this._cache.get(this._autopadding);)n=this._mode.decrypt(this,t),o.push(n);return r.concat(o)},l.prototype._final=function(){var e=this._cache.flush();if(this._autopadding)return function(e){var t=e[15];if(t<1||t>16)throw new Error("unable to decrypt data");for(var n=-1;++n16)return t=this.cache.slice(0,16),this.cache=this.cache.slice(16),t}else if(this.cache.length>=16)return t=this.cache.slice(0,16),this.cache=this.cache.slice(16),t;return null},d.prototype.flush=function(){if(this.cache.length)return this.cache},t.createDecipher=function(e,t){var n=i[e.toLowerCase()];if(!n)throw new TypeError("invalid suite type");var o=c(t,!1,n.key,n.iv);return h(e,o.key,o.iv)},t.createDecipheriv=h},71494:(e,t,n)=>{var o=n(45),r=n(62422),i=n(89509).Buffer,a=n(25969),s=n(71027),u=n(74497),c=n(13048);function l(e,t,n){s.call(this),this._cache=new h,this._cipher=new u.AES(t),this._prev=i.from(n),this._mode=e,this._autopadding=!0}n(35717)(l,s),l.prototype._update=function(e){var t,n;this._cache.add(e);for(var o=[];t=this._cache.get();)n=this._mode.encrypt(this,t),o.push(n);return i.concat(o)};var d=i.alloc(16,16);function h(){this.cache=i.allocUnsafe(0)}function p(e,t,n){var s=o[e.toLowerCase()];if(!s)throw new TypeError("invalid suite type");if("string"==typeof t&&(t=i.from(t)),t.length!==s.key/8)throw new TypeError("invalid key length "+t.length);if("string"==typeof n&&(n=i.from(n)),"GCM"!==s.mode&&n.length!==s.iv)throw new TypeError("invalid iv length "+n.length);return"stream"===s.type?new a(s.module,t,n):"auth"===s.type?new r(s.module,t,n):new l(s.module,t,n)}l.prototype._final=function(){var e=this._cache.flush();if(this._autopadding)return e=this._mode.encrypt(this,e),this._cipher.scrub(),e;if(!e.equals(d))throw this._cipher.scrub(),new Error("data not multiple of block length")},l.prototype.setAutoPadding=function(e){return this._autopadding=!!e,this},h.prototype.add=function(e){this.cache=i.concat([this.cache,e])},h.prototype.get=function(){if(this.cache.length>15){var e=this.cache.slice(0,16);return this.cache=this.cache.slice(16),e}return null},h.prototype.flush=function(){for(var e=16-this.cache.length,t=i.allocUnsafe(e),n=-1;++n{var o=n(89509).Buffer,r=o.alloc(16,0);function i(e){var t=o.allocUnsafe(16);return t.writeUInt32BE(e[0]>>>0,0),t.writeUInt32BE(e[1]>>>0,4),t.writeUInt32BE(e[2]>>>0,8),t.writeUInt32BE(e[3]>>>0,12),t}function a(e){this.h=e,this.state=o.alloc(16,0),this.cache=o.allocUnsafe(0)}a.prototype.ghash=function(e){for(var t=-1;++t0;t--)o[t]=o[t]>>>1|(1&o[t-1])<<31;o[0]=o[0]>>>1,n&&(o[0]=o[0]^225<<24)}this.state=i(r)},a.prototype.update=function(e){var t;for(this.cache=o.concat([this.cache,e]);this.cache.length>=16;)t=this.cache.slice(0,16),this.cache=this.cache.slice(16),this.ghash(t)},a.prototype.final=function(e,t){return this.cache.length&&this.ghash(o.concat([this.cache,r],16)),this.ghash(i([0,e,0,t])),this.state},e.exports=a},20685:e=>{e.exports=function(e){for(var t,n=e.length;n--;){if(255!==(t=e.readUInt8(n))){t++,e.writeUInt8(t,n);break}e.writeUInt8(0,n)}}},25292:(e,t,n)=>{var o=n(67295);t.encrypt=function(e,t){var n=o(t,e._prev);return e._prev=e._cipher.encryptBlock(n),e._prev},t.decrypt=function(e,t){var n=e._prev;e._prev=t;var r=e._cipher.decryptBlock(t);return o(r,n)}},86311:(e,t,n)=>{var o=n(89509).Buffer,r=n(67295);function i(e,t,n){var i=t.length,a=r(t,e._cache);return e._cache=e._cache.slice(i),e._prev=o.concat([e._prev,n?t:a]),a}t.encrypt=function(e,t,n){for(var r,a=o.allocUnsafe(0);t.length;){if(0===e._cache.length&&(e._cache=e._cipher.encryptBlock(e._prev),e._prev=o.allocUnsafe(0)),!(e._cache.length<=t.length)){a=o.concat([a,i(e,t,n)]);break}r=e._cache.length,a=o.concat([a,i(e,t.slice(0,r),n)]),t=t.slice(r)}return a}},21510:(e,t,n)=>{var o=n(89509).Buffer;function r(e,t,n){for(var o,r,a=-1,s=0;++a<8;)o=t&1<<7-a?128:0,s+=(128&(r=e._cipher.encryptBlock(e._prev)[0]^o))>>a%8,e._prev=i(e._prev,n?o:r);return s}function i(e,t){var n=e.length,r=-1,i=o.allocUnsafe(e.length);for(e=o.concat([e,o.from([t])]);++r>7;return i}t.encrypt=function(e,t,n){for(var i=t.length,a=o.allocUnsafe(i),s=-1;++s{var o=n(89509).Buffer;function r(e,t,n){var r=e._cipher.encryptBlock(e._prev)[0]^t;return e._prev=o.concat([e._prev.slice(1),o.from([n?t:r])]),r}t.encrypt=function(e,t,n){for(var i=t.length,a=o.allocUnsafe(i),s=-1;++s{var o=n(67295),r=n(89509).Buffer,i=n(20685);function a(e){var t=e._cipher.encryptBlockRaw(e._prev);return i(e._prev),t}t.encrypt=function(e,t){var n=Math.ceil(t.length/16),i=e._cache.length;e._cache=r.concat([e._cache,r.allocUnsafe(16*n)]);for(var s=0;s{t.encrypt=function(e,t){return e._cipher.encryptBlock(t)},t.decrypt=function(e,t){return e._cipher.decryptBlock(t)}},45:(e,t,n)=>{var o={ECB:n(11084),CBC:n(25292),CFB:n(86311),CFB8:n(71964),CFB1:n(21510),OFB:n(18861),CTR:n(96009),GCM:n(96009)},r=n(55415);for(var i in r)r[i].module=o[r[i].mode];e.exports=r},55415:e=>{"use strict";e.exports=JSON.parse('{"aes-128-ecb":{"cipher":"AES","key":128,"iv":0,"mode":"ECB","type":"block"},"aes-192-ecb":{"cipher":"AES","key":192,"iv":0,"mode":"ECB","type":"block"},"aes-256-ecb":{"cipher":"AES","key":256,"iv":0,"mode":"ECB","type":"block"},"aes-128-cbc":{"cipher":"AES","key":128,"iv":16,"mode":"CBC","type":"block"},"aes-192-cbc":{"cipher":"AES","key":192,"iv":16,"mode":"CBC","type":"block"},"aes-256-cbc":{"cipher":"AES","key":256,"iv":16,"mode":"CBC","type":"block"},"aes128":{"cipher":"AES","key":128,"iv":16,"mode":"CBC","type":"block"},"aes192":{"cipher":"AES","key":192,"iv":16,"mode":"CBC","type":"block"},"aes256":{"cipher":"AES","key":256,"iv":16,"mode":"CBC","type":"block"},"aes-128-cfb":{"cipher":"AES","key":128,"iv":16,"mode":"CFB","type":"stream"},"aes-192-cfb":{"cipher":"AES","key":192,"iv":16,"mode":"CFB","type":"stream"},"aes-256-cfb":{"cipher":"AES","key":256,"iv":16,"mode":"CFB","type":"stream"},"aes-128-cfb8":{"cipher":"AES","key":128,"iv":16,"mode":"CFB8","type":"stream"},"aes-192-cfb8":{"cipher":"AES","key":192,"iv":16,"mode":"CFB8","type":"stream"},"aes-256-cfb8":{"cipher":"AES","key":256,"iv":16,"mode":"CFB8","type":"stream"},"aes-128-cfb1":{"cipher":"AES","key":128,"iv":16,"mode":"CFB1","type":"stream"},"aes-192-cfb1":{"cipher":"AES","key":192,"iv":16,"mode":"CFB1","type":"stream"},"aes-256-cfb1":{"cipher":"AES","key":256,"iv":16,"mode":"CFB1","type":"stream"},"aes-128-ofb":{"cipher":"AES","key":128,"iv":16,"mode":"OFB","type":"stream"},"aes-192-ofb":{"cipher":"AES","key":192,"iv":16,"mode":"OFB","type":"stream"},"aes-256-ofb":{"cipher":"AES","key":256,"iv":16,"mode":"OFB","type":"stream"},"aes-128-ctr":{"cipher":"AES","key":128,"iv":16,"mode":"CTR","type":"stream"},"aes-192-ctr":{"cipher":"AES","key":192,"iv":16,"mode":"CTR","type":"stream"},"aes-256-ctr":{"cipher":"AES","key":256,"iv":16,"mode":"CTR","type":"stream"},"aes-128-gcm":{"cipher":"AES","key":128,"iv":12,"mode":"GCM","type":"auth"},"aes-192-gcm":{"cipher":"AES","key":192,"iv":12,"mode":"GCM","type":"auth"},"aes-256-gcm":{"cipher":"AES","key":256,"iv":12,"mode":"GCM","type":"auth"}}')},18861:(e,t,n)=>{var o=n(67295);function r(e){return e._prev=e._cipher.encryptBlock(e._prev),e._prev}t.encrypt=function(e,t){for(;e._cache.length{var o=n(74497),r=n(89509).Buffer,i=n(71027);function a(e,t,n,a){i.call(this),this._cipher=new o.AES(t),this._prev=r.from(n),this._cache=r.allocUnsafe(0),this._secCache=r.allocUnsafe(0),this._decrypt=a,this._mode=e}n(35717)(a,i),a.prototype._update=function(e){return this._mode.encrypt(this,e,this._decrypt)},a.prototype._final=function(){this._cipher.scrub()},e.exports=a},53614:(e,t,n)=>{var o=n(47667),r=n(44696),i=n(45),a=n(99715),s=n(13048);function u(e,t,n){if(e=e.toLowerCase(),i[e])return r.createCipheriv(e,t,n);if(a[e])return new o({key:t,iv:n,mode:e});throw new TypeError("invalid suite type")}function c(e,t,n){if(e=e.toLowerCase(),i[e])return r.createDecipheriv(e,t,n);if(a[e])return new o({key:t,iv:n,mode:e,decrypt:!0});throw new TypeError("invalid suite type")}t.createCipher=t.Cipher=function(e,t){var n,o;if(e=e.toLowerCase(),i[e])n=i[e].key,o=i[e].iv;else{if(!a[e])throw new TypeError("invalid suite type");n=8*a[e].key,o=a[e].iv}var r=s(t,!1,n,o);return u(e,r.key,r.iv)},t.createCipheriv=t.Cipheriv=u,t.createDecipher=t.Decipher=function(e,t){var n,o;if(e=e.toLowerCase(),i[e])n=i[e].key,o=i[e].iv;else{if(!a[e])throw new TypeError("invalid suite type");n=8*a[e].key,o=a[e].iv}var r=s(t,!1,n,o);return c(e,r.key,r.iv)},t.createDecipheriv=t.Decipheriv=c,t.listCiphers=t.getCiphers=function(){return Object.keys(a).concat(r.getCiphers())}},47667:(e,t,n)=>{var o=n(71027),r=n(15251),i=n(35717),a=n(89509).Buffer,s={"des-ede3-cbc":r.CBC.instantiate(r.EDE),"des-ede3":r.EDE,"des-ede-cbc":r.CBC.instantiate(r.EDE),"des-ede":r.EDE,"des-cbc":r.CBC.instantiate(r.DES),"des-ecb":r.DES};function u(e){o.call(this);var t,n=e.mode.toLowerCase(),r=s[n];t=e.decrypt?"decrypt":"encrypt";var i=e.key;a.isBuffer(i)||(i=a.from(i)),"des-ede"!==n&&"des-ede-cbc"!==n||(i=a.concat([i,i.slice(0,8)]));var u=e.iv;a.isBuffer(u)||(u=a.from(u)),this._des=r.create({key:i,iv:u,type:t})}s.des=s["des-cbc"],s.des3=s["des-ede3-cbc"],e.exports=u,i(u,o),u.prototype._update=function(e){return a.from(this._des.update(e))},u.prototype._final=function(){return a.from(this._des.final())}},99715:(e,t)=>{t["des-ecb"]={key:8,iv:0},t["des-cbc"]=t.des={key:8,iv:8},t["des-ede3-cbc"]=t.des3={key:24,iv:8},t["des-ede3"]={key:24,iv:0},t["des-ede-cbc"]={key:16,iv:8},t["des-ede"]={key:16,iv:0}},23384:(e,t,n)=>{var o=n(99558),r=n(34918),i=n(49942),a=r("level-filesystem",{db:o});e.exports=i(a)},23663:(e,t,n)=>{var o=n(13550),r=n(61798);function i(e){var t,n=e.modulus.byteLength();do{t=new o(r(n))}while(t.cmp(e.modulus)>=0||!t.umod(e.prime1)||!t.umod(e.prime2));return t}function a(e,t){var n=function(e){var t=i(e);return{blinder:t.toRed(o.mont(e.modulus)).redPow(new o(e.publicExponent)).fromRed(),unblinder:t.invm(e.modulus)}}(t),r=t.modulus.byteLength(),a=new o(e).mul(n.blinder).umod(t.modulus),s=a.toRed(o.mont(t.prime1)),u=a.toRed(o.mont(t.prime2)),c=t.coefficient,l=t.prime1,d=t.prime2,h=s.redPow(t.exponent1).fromRed(),p=u.redPow(t.exponent2).fromRed(),f=h.isub(p).imul(c).umod(l).imul(d);return p.iadd(f).imul(n.unblinder).umod(t.modulus).toArrayLike(Buffer,"be",r)}a.getr=i,e.exports=a},56042:(e,t,n)=>{e.exports=n(42063)},42063:e=>{"use strict";e.exports=JSON.parse('{"sha224WithRSAEncryption":{"sign":"rsa","hash":"sha224","id":"302d300d06096086480165030402040500041c"},"RSA-SHA224":{"sign":"ecdsa/rsa","hash":"sha224","id":"302d300d06096086480165030402040500041c"},"sha256WithRSAEncryption":{"sign":"rsa","hash":"sha256","id":"3031300d060960864801650304020105000420"},"RSA-SHA256":{"sign":"ecdsa/rsa","hash":"sha256","id":"3031300d060960864801650304020105000420"},"sha384WithRSAEncryption":{"sign":"rsa","hash":"sha384","id":"3041300d060960864801650304020205000430"},"RSA-SHA384":{"sign":"ecdsa/rsa","hash":"sha384","id":"3041300d060960864801650304020205000430"},"sha512WithRSAEncryption":{"sign":"rsa","hash":"sha512","id":"3051300d060960864801650304020305000440"},"RSA-SHA512":{"sign":"ecdsa/rsa","hash":"sha512","id":"3051300d060960864801650304020305000440"},"RSA-SHA1":{"sign":"rsa","hash":"sha1","id":"3021300906052b0e03021a05000414"},"ecdsa-with-SHA1":{"sign":"ecdsa","hash":"sha1","id":""},"sha256":{"sign":"ecdsa","hash":"sha256","id":""},"sha224":{"sign":"ecdsa","hash":"sha224","id":""},"sha384":{"sign":"ecdsa","hash":"sha384","id":""},"sha512":{"sign":"ecdsa","hash":"sha512","id":""},"DSA-SHA":{"sign":"dsa","hash":"sha1","id":""},"DSA-SHA1":{"sign":"dsa","hash":"sha1","id":""},"DSA":{"sign":"dsa","hash":"sha1","id":""},"DSA-WITH-SHA224":{"sign":"dsa","hash":"sha224","id":""},"DSA-SHA224":{"sign":"dsa","hash":"sha224","id":""},"DSA-WITH-SHA256":{"sign":"dsa","hash":"sha256","id":""},"DSA-SHA256":{"sign":"dsa","hash":"sha256","id":""},"DSA-WITH-SHA384":{"sign":"dsa","hash":"sha384","id":""},"DSA-SHA384":{"sign":"dsa","hash":"sha384","id":""},"DSA-WITH-SHA512":{"sign":"dsa","hash":"sha512","id":""},"DSA-SHA512":{"sign":"dsa","hash":"sha512","id":""},"DSA-RIPEMD160":{"sign":"dsa","hash":"rmd160","id":""},"ripemd160WithRSA":{"sign":"rsa","hash":"rmd160","id":"3021300906052b2403020105000414"},"RSA-RIPEMD160":{"sign":"rsa","hash":"rmd160","id":"3021300906052b2403020105000414"},"md5WithRSAEncryption":{"sign":"rsa","hash":"md5","id":"3020300c06082a864886f70d020505000410"},"RSA-MD5":{"sign":"rsa","hash":"md5","id":"3020300c06082a864886f70d020505000410"}}')},42236:e=>{"use strict";e.exports=JSON.parse('{"1.3.132.0.10":"secp256k1","1.3.132.0.33":"p224","1.2.840.10045.3.1.1":"p192","1.2.840.10045.3.1.7":"p256","1.3.132.0.34":"p384","1.3.132.0.35":"p521"}')},64743:(e,t,n)=>{var o=n(89509).Buffer,r=n(23482),i=n(23872),a=n(35717),s=n(82957),u=n(47753),c=n(42063);function l(e){i.Writable.call(this);var t=c[e];if(!t)throw new Error("Unknown message digest");this._hashType=t.hash,this._hash=r(t.hash),this._tag=t.id,this._signType=t.sign}function d(e){i.Writable.call(this);var t=c[e];if(!t)throw new Error("Unknown message digest");this._hash=r(t.hash),this._tag=t.id,this._signType=t.sign}function h(e){return new l(e)}function p(e){return new d(e)}Object.keys(c).forEach((function(e){c[e].id=o.from(c[e].id,"hex"),c[e.toLowerCase()]=c[e]})),a(l,i.Writable),l.prototype._write=function(e,t,n){this._hash.update(e),n()},l.prototype.update=function(e,t){return"string"==typeof e&&(e=o.from(e,t)),this._hash.update(e),this},l.prototype.sign=function(e,t){this.end();var n=this._hash.digest(),o=s(n,e,this._hashType,this._signType,this._tag);return t?o.toString(t):o},a(d,i.Writable),d.prototype._write=function(e,t,n){this._hash.update(e),n()},d.prototype.update=function(e,t){return"string"==typeof e&&(e=o.from(e,t)),this._hash.update(e),this},d.prototype.verify=function(e,t,n){"string"==typeof t&&(t=o.from(t,n)),this.end();var r=this._hash.digest();return u(t,r,e,this._signType,this._tag)},e.exports={Sign:h,Verify:p,createSign:h,createVerify:p}},82957:(e,t,n)=>{var o=n(89509).Buffer,r=n(58355),i=n(23663),a=n(86266).ec,s=n(13550),u=n(70980),c=n(42236);function l(e,t,n,i){if((e=o.from(e.toArray())).length0&&n.ishrn(o),n}function h(e,t,n){var i,a;do{for(i=o.alloc(0);8*i.length{var o=n(89509).Buffer,r=n(13550),i=n(86266).ec,a=n(70980),s=n(42236);function u(e,t){if(e.cmpn(0)<=0)throw new Error("invalid sig");if(e.cmp(t)>=t)throw new Error("invalid sig")}e.exports=function(e,t,n,c,l){var d=a(n);if("ec"===d.type){if("ecdsa"!==c&&"ecdsa/rsa"!==c)throw new Error("wrong public key type");return function(e,t,n){var o=s[n.data.algorithm.curve.join(".")];if(!o)throw new Error("unknown curve "+n.data.algorithm.curve.join("."));var r=new i(o),a=n.data.subjectPrivateKey.data;return r.verify(t,e,a)}(e,t,d)}if("dsa"===d.type){if("dsa"!==c)throw new Error("wrong public key type");return function(e,t,n){var o=n.data.p,i=n.data.q,s=n.data.g,c=n.data.pub_key,l=a.signature.decode(e,"der"),d=l.s,h=l.r;u(d,i),u(h,i);var p=r.mont(o),f=d.invm(i);return 0===s.toRed(p).redPow(new r(t).mul(f).mod(i)).fromRed().mul(c.toRed(p).redPow(h.mul(f).mod(i)).fromRed()).mod(o).mod(i).cmp(h)}(e,t,d)}if("rsa"!==c&&"ecdsa/rsa"!==c)throw new Error("wrong public key type");t=o.concat([l,t]);for(var h=d.modulus.byteLength(),p=[1],f=0;t.length+p.length+2{"use strict";var t={};function n(e,n,o){o||(o=Error);var r=function(e){var t,o;function r(t,o,r){return e.call(this,function(e,t,o){return"string"==typeof n?n:n(e,t,o)}(t,o,r))||this}return o=e,(t=r).prototype=Object.create(o.prototype),t.prototype.constructor=t,t.__proto__=o,r}(o);r.prototype.name=o.name,r.prototype.code=e,t[e]=r}function o(e,t){if(Array.isArray(e)){var n=e.length;return e=e.map((function(e){return String(e)})),n>2?"one of ".concat(t," ").concat(e.slice(0,n-1).join(", "),", or ")+e[n-1]:2===n?"one of ".concat(t," ").concat(e[0]," or ").concat(e[1]):"of ".concat(t," ").concat(e[0])}return"of ".concat(t," ").concat(String(e))}n("ERR_INVALID_OPT_VALUE",(function(e,t){return'The value "'+t+'" is invalid for option "'+e+'"'}),TypeError),n("ERR_INVALID_ARG_TYPE",(function(e,t,n){var r,i,a,s,u;if("string"==typeof t&&(i="not ",t.substr(0,i.length)===i)?(r="must not be",t=t.replace(/^not /,"")):r="must be",function(e,t,n){return(void 0===n||n>e.length)&&(n=e.length),e.substring(n-t.length,n)===t}(e," argument"))a="The ".concat(e," ").concat(r," ").concat(o(t,"type"));else{var c=("number"!=typeof u&&(u=0),u+".".length>(s=e).length||-1===s.indexOf(".",u)?"argument":"property");a='The "'.concat(e,'" ').concat(c," ").concat(r," ").concat(o(t,"type"))}return a+". Received type ".concat(typeof n)}),TypeError),n("ERR_STREAM_PUSH_AFTER_EOF","stream.push() after EOF"),n("ERR_METHOD_NOT_IMPLEMENTED",(function(e){return"The "+e+" method is not implemented"})),n("ERR_STREAM_PREMATURE_CLOSE","Premature close"),n("ERR_STREAM_DESTROYED",(function(e){return"Cannot call "+e+" after a stream was destroyed"})),n("ERR_MULTIPLE_CALLBACK","Callback called multiple times"),n("ERR_STREAM_CANNOT_PIPE","Cannot pipe, not readable"),n("ERR_STREAM_WRITE_AFTER_END","write after end"),n("ERR_STREAM_NULL_VALUES","May not write null values to stream",TypeError),n("ERR_UNKNOWN_ENCODING",(function(e){return"Unknown encoding: "+e}),TypeError),n("ERR_STREAM_UNSHIFT_AFTER_END_EVENT","stream.unshift() after end event"),e.exports.q=t},34390:(e,t,n)=>{"use strict";var o=Object.keys||function(e){var t=[];for(var n in e)t.push(n);return t};e.exports=c;var r=n(44960),i=n(92010);n(35717)(c,r);for(var a=o(i.prototype),s=0;s{"use strict";e.exports=r;var o=n(3912);function r(e){if(!(this instanceof r))return new r(e);o.call(this,e)}n(35717)(r,o),r.prototype._transform=function(e,t,n){n(null,e)}},44960:(e,t,n)=>{"use strict";var o;e.exports=k,k.ReadableState=E,n(17187).EventEmitter;var r,i=function(e,t){return e.listeners(t).length},a=n(59819),s=n(48764).Buffer,u=n.g.Uint8Array||function(){},c=n(56353);r=c&&c.debuglog?c.debuglog("stream"):function(){};var l,d,h,p=n(76633),f=n(75997),g=n(898).getHighWaterMark,m=n(84419).q,_=m.ERR_INVALID_ARG_TYPE,F=m.ERR_STREAM_PUSH_AFTER_EOF,y=m.ERR_METHOD_NOT_IMPLEMENTED,b=m.ERR_STREAM_UNSHIFT_AFTER_END_EVENT;n(35717)(k,a);var v=f.errorOrDestroy,w=["error","close","destroy","pause","resume"];function E(e,t,r){o=o||n(34390),e=e||{},"boolean"!=typeof r&&(r=t instanceof o),this.objectMode=!!e.objectMode,r&&(this.objectMode=this.objectMode||!!e.readableObjectMode),this.highWaterMark=g(this,e,"readableHighWaterMark",r),this.buffer=new p,this.length=0,this.pipes=null,this.pipesCount=0,this.flowing=null,this.ended=!1,this.endEmitted=!1,this.reading=!1,this.sync=!0,this.needReadable=!1,this.emittedReadable=!1,this.readableListening=!1,this.resumeScheduled=!1,this.paused=!0,this.emitClose=!1!==e.emitClose,this.autoDestroy=!!e.autoDestroy,this.destroyed=!1,this.defaultEncoding=e.defaultEncoding||"utf8",this.awaitDrain=0,this.readingMore=!1,this.decoder=null,this.encoding=null,e.encoding&&(l||(l=n(32553).s),this.decoder=new l(e.encoding),this.encoding=e.encoding)}function k(e){if(o=o||n(34390),!(this instanceof k))return new k(e);var t=this instanceof o;this._readableState=new E(e,this,t),this.readable=!0,e&&("function"==typeof e.read&&(this._read=e.read),"function"==typeof e.destroy&&(this._destroy=e.destroy)),a.call(this)}function D(e,t,n,o,i){r("readableAddChunk",t);var a,c=e._readableState;if(null===t)c.reading=!1,function(e,t){if(r("onEofChunk"),!t.ended){if(t.decoder){var n=t.decoder.end();n&&n.length&&(t.buffer.push(n),t.length+=t.objectMode?1:n.length)}t.ended=!0,t.sync?A(e):(t.needReadable=!1,t.emittedReadable||(t.emittedReadable=!0,T(e)))}}(e,c);else if(i||(a=function(e,t){var n,o;return o=t,s.isBuffer(o)||o instanceof u||"string"==typeof t||void 0===t||e.objectMode||(n=new _("chunk",["string","Buffer","Uint8Array"],t)),n}(c,t)),a)v(e,a);else if(c.objectMode||t&&t.length>0)if("string"==typeof t||c.objectMode||Object.getPrototypeOf(t)===s.prototype||(t=function(e){return s.from(e)}(t)),o)c.endEmitted?v(e,new b):S(e,c,t,!0);else if(c.ended)v(e,new F);else{if(c.destroyed)return!1;c.reading=!1,c.decoder&&!n?(t=c.decoder.write(t),c.objectMode||0!==t.length?S(e,c,t,!1):R(e,c)):S(e,c,t,!1)}else o||(c.reading=!1,R(e,c));return!c.ended&&(c.lengtht.highWaterMark&&(t.highWaterMark=function(e){return e>=x?e=x:(e--,e|=e>>>1,e|=e>>>2,e|=e>>>4,e|=e>>>8,e|=e>>>16,e++),e}(e)),e<=t.length?e:t.ended?t.length:(t.needReadable=!0,0))}function A(e){var t=e._readableState;r("emitReadable",t.needReadable,t.emittedReadable),t.needReadable=!1,t.emittedReadable||(r("emitReadable",t.flowing),t.emittedReadable=!0,process.nextTick(T,e))}function T(e){var t=e._readableState;r("emitReadable_",t.destroyed,t.length,t.ended),t.destroyed||!t.length&&!t.ended||(e.emit("readable"),t.emittedReadable=!1),t.needReadable=!t.flowing&&!t.ended&&t.length<=t.highWaterMark,N(e)}function R(e,t){t.readingMore||(t.readingMore=!0,process.nextTick(I,e,t))}function I(e,t){for(;!t.reading&&!t.ended&&(t.length0,t.resumeScheduled&&!t.paused?t.flowing=!0:e.listenerCount("data")>0&&e.resume()}function O(e){r("readable nexttick read 0"),e.read(0)}function B(e,t){r("resume",t.reading),t.reading||e.read(0),t.resumeScheduled=!1,e.emit("resume"),N(e),t.flowing&&!t.reading&&e.read(0)}function N(e){var t=e._readableState;for(r("flow",t.flowing);t.flowing&&null!==e.read(););}function L(e,t){return 0===t.length?null:(t.objectMode?n=t.buffer.shift():!e||e>=t.length?(n=t.decoder?t.buffer.join(""):1===t.buffer.length?t.buffer.first():t.buffer.concat(t.length),t.buffer.clear()):n=t.buffer.consume(e,t.decoder),n);var n}function P(e){var t=e._readableState;r("endReadable",t.endEmitted),t.endEmitted||(t.ended=!0,process.nextTick(U,t,e))}function U(e,t){if(r("endReadableNT",e.endEmitted,e.length),!e.endEmitted&&0===e.length&&(e.endEmitted=!0,t.readable=!1,t.emit("end"),e.autoDestroy)){var n=t._writableState;(!n||n.autoDestroy&&n.finished)&&t.destroy()}}function j(e,t){for(var n=0,o=e.length;n=t.highWaterMark:t.length>0)||t.ended))return r("read: emitReadable",t.length,t.ended),0===t.length&&t.ended?P(this):A(this),null;if(0===(e=C(e,t))&&t.ended)return 0===t.length&&P(this),null;var o,i=t.needReadable;return r("need readable",i),(0===t.length||t.length-e0?L(e,t):null)?(t.needReadable=t.length<=t.highWaterMark,e=0):(t.length-=e,t.awaitDrain=0),0===t.length&&(t.ended||(t.needReadable=!0),n!==e&&t.ended&&P(this)),null!==o&&this.emit("data",o),o},k.prototype._read=function(e){v(this,new y("_read()"))},k.prototype.pipe=function(e,t){var n=this,o=this._readableState;switch(o.pipesCount){case 0:o.pipes=e;break;case 1:o.pipes=[o.pipes,e];break;default:o.pipes.push(e)}o.pipesCount+=1,r("pipe count=%d opts=%j",o.pipesCount,t);var a=t&&!1===t.end||e===process.stdout||e===process.stderr?f:s;function s(){r("onend"),e.end()}o.endEmitted?process.nextTick(a):n.once("end",a),e.on("unpipe",(function t(i,a){r("onunpipe"),i===n&&a&&!1===a.hasUnpiped&&(a.hasUnpiped=!0,r("cleanup"),e.removeListener("close",h),e.removeListener("finish",p),e.removeListener("drain",u),e.removeListener("error",d),e.removeListener("unpipe",t),n.removeListener("end",s),n.removeListener("end",f),n.removeListener("data",l),c=!0,!o.awaitDrain||e._writableState&&!e._writableState.needDrain||u())}));var u=function(e){return function(){var t=e._readableState;r("pipeOnDrain",t.awaitDrain),t.awaitDrain&&t.awaitDrain--,0===t.awaitDrain&&i(e,"data")&&(t.flowing=!0,N(e))}}(n);e.on("drain",u);var c=!1;function l(t){r("ondata");var i=e.write(t);r("dest.write",i),!1===i&&((1===o.pipesCount&&o.pipes===e||o.pipesCount>1&&-1!==j(o.pipes,e))&&!c&&(r("false write response, pause",o.awaitDrain),o.awaitDrain++),n.pause())}function d(t){r("onerror",t),f(),e.removeListener("error",d),0===i(e,"error")&&v(e,t)}function h(){e.removeListener("finish",p),f()}function p(){r("onfinish"),e.removeListener("close",h),f()}function f(){r("unpipe"),n.unpipe(e)}return n.on("data",l),function(e,t,n){if("function"==typeof e.prependListener)return e.prependListener(t,n);e._events&&e._events.error?Array.isArray(e._events.error)?e._events.error.unshift(n):e._events.error=[n,e._events.error]:e.on(t,n)}(e,"error",d),e.once("close",h),e.once("finish",p),e.emit("pipe",n),o.flowing||(r("pipe resume"),n.resume()),e},k.prototype.unpipe=function(e){var t=this._readableState,n={hasUnpiped:!1};if(0===t.pipesCount)return this;if(1===t.pipesCount)return e&&e!==t.pipes||(e||(e=t.pipes),t.pipes=null,t.pipesCount=0,t.flowing=!1,e&&e.emit("unpipe",this,n)),this;if(!e){var o=t.pipes,r=t.pipesCount;t.pipes=null,t.pipesCount=0,t.flowing=!1;for(var i=0;i0,!1!==o.flowing&&this.resume()):"readable"===e&&(o.endEmitted||o.readableListening||(o.readableListening=o.needReadable=!0,o.flowing=!1,o.emittedReadable=!1,r("on readable",o.length,o.reading),o.length?A(this):o.reading||process.nextTick(O,this))),n},k.prototype.addListener=k.prototype.on,k.prototype.removeListener=function(e,t){var n=a.prototype.removeListener.call(this,e,t);return"readable"===e&&process.nextTick(M,this),n},k.prototype.removeAllListeners=function(e){var t=a.prototype.removeAllListeners.apply(this,arguments);return"readable"!==e&&void 0!==e||process.nextTick(M,this),t},k.prototype.resume=function(){var e=this._readableState;return e.flowing||(r("resume"),e.flowing=!e.readableListening,function(e,t){t.resumeScheduled||(t.resumeScheduled=!0,process.nextTick(B,e,t))}(this,e)),e.paused=!1,this},k.prototype.pause=function(){return r("call pause flowing=%j",this._readableState.flowing),!1!==this._readableState.flowing&&(r("pause"),this._readableState.flowing=!1,this.emit("pause")),this._readableState.paused=!0,this},k.prototype.wrap=function(e){var t=this,n=this._readableState,o=!1;for(var i in e.on("end",(function(){if(r("wrapped end"),n.decoder&&!n.ended){var e=n.decoder.end();e&&e.length&&t.push(e)}t.push(null)})),e.on("data",(function(i){r("wrapped data"),n.decoder&&(i=n.decoder.write(i)),n.objectMode&&null==i||(n.objectMode||i&&i.length)&&(t.push(i)||(o=!0,e.pause()))})),e)void 0===this[i]&&"function"==typeof e[i]&&(this[i]=function(t){return function(){return e[t].apply(e,arguments)}}(i));for(var a=0;a{"use strict";e.exports=l;var o=n(84419).q,r=o.ERR_METHOD_NOT_IMPLEMENTED,i=o.ERR_MULTIPLE_CALLBACK,a=o.ERR_TRANSFORM_ALREADY_TRANSFORMING,s=o.ERR_TRANSFORM_WITH_LENGTH_0,u=n(34390);function c(e,t){var n=this._transformState;n.transforming=!1;var o=n.writecb;if(null===o)return this.emit("error",new i);n.writechunk=null,n.writecb=null,null!=t&&this.push(t),o(e);var r=this._readableState;r.reading=!1,(r.needReadable||r.length{"use strict";function o(e){var t=this;this.next=null,this.entry=null,this.finish=function(){!function(e,t,n){var o=e.entry;for(e.entry=null;o;){var r=o.callback;t.pendingcb--,r(undefined),o=o.next}t.corkedRequestsFree.next=e}(t,e)}}var r;e.exports=k,k.WritableState=E;var i,a={deprecate:n(94927)},s=n(59819),u=n(48764).Buffer,c=n.g.Uint8Array||function(){},l=n(75997),d=n(898).getHighWaterMark,h=n(84419).q,p=h.ERR_INVALID_ARG_TYPE,f=h.ERR_METHOD_NOT_IMPLEMENTED,g=h.ERR_MULTIPLE_CALLBACK,m=h.ERR_STREAM_CANNOT_PIPE,_=h.ERR_STREAM_DESTROYED,F=h.ERR_STREAM_NULL_VALUES,y=h.ERR_STREAM_WRITE_AFTER_END,b=h.ERR_UNKNOWN_ENCODING,v=l.errorOrDestroy;function w(){}function E(e,t,i){r=r||n(34390),e=e||{},"boolean"!=typeof i&&(i=t instanceof r),this.objectMode=!!e.objectMode,i&&(this.objectMode=this.objectMode||!!e.writableObjectMode),this.highWaterMark=d(this,e,"writableHighWaterMark",i),this.finalCalled=!1,this.needDrain=!1,this.ending=!1,this.ended=!1,this.finished=!1,this.destroyed=!1;var a=!1===e.decodeStrings;this.decodeStrings=!a,this.defaultEncoding=e.defaultEncoding||"utf8",this.length=0,this.writing=!1,this.corked=0,this.sync=!0,this.bufferProcessing=!1,this.onwrite=function(e){!function(e,t){var n=e._writableState,o=n.sync,r=n.writecb;if("function"!=typeof r)throw new g;if(function(e){e.writing=!1,e.writecb=null,e.length-=e.writelen,e.writelen=0}(n),t)!function(e,t,n,o,r){--t.pendingcb,n?(process.nextTick(r,o),process.nextTick(T,e,t),e._writableState.errorEmitted=!0,v(e,o)):(r(o),e._writableState.errorEmitted=!0,v(e,o),T(e,t))}(e,n,o,t,r);else{var i=C(n)||e.destroyed;i||n.corked||n.bufferProcessing||!n.bufferedRequest||x(e,n),o?process.nextTick(S,e,n,i,r):S(e,n,i,r)}}(t,e)},this.writecb=null,this.writelen=0,this.bufferedRequest=null,this.lastBufferedRequest=null,this.pendingcb=0,this.prefinished=!1,this.errorEmitted=!1,this.emitClose=!1!==e.emitClose,this.autoDestroy=!!e.autoDestroy,this.bufferedRequestCount=0,this.corkedRequestsFree=new o(this)}function k(e){var t=this instanceof(r=r||n(34390));if(!t&&!i.call(k,this))return new k(e);this._writableState=new E(e,this,t),this.writable=!0,e&&("function"==typeof e.write&&(this._write=e.write),"function"==typeof e.writev&&(this._writev=e.writev),"function"==typeof e.destroy&&(this._destroy=e.destroy),"function"==typeof e.final&&(this._final=e.final)),s.call(this)}function D(e,t,n,o,r,i,a){t.writelen=o,t.writecb=a,t.writing=!0,t.sync=!0,t.destroyed?t.onwrite(new _("write")):n?e._writev(r,t.onwrite):e._write(r,i,t.onwrite),t.sync=!1}function S(e,t,n,o){n||function(e,t){0===t.length&&t.needDrain&&(t.needDrain=!1,e.emit("drain"))}(e,t),t.pendingcb--,o(),T(e,t)}function x(e,t){t.bufferProcessing=!0;var n=t.bufferedRequest;if(e._writev&&n&&n.next){var r=t.bufferedRequestCount,i=new Array(r),a=t.corkedRequestsFree;a.entry=n;for(var s=0,u=!0;n;)i[s]=n,n.isBuf||(u=!1),n=n.next,s+=1;i.allBuffers=u,D(e,t,!0,t.length,i,"",a.finish),t.pendingcb++,t.lastBufferedRequest=null,a.next?(t.corkedRequestsFree=a.next,a.next=null):t.corkedRequestsFree=new o(t),t.bufferedRequestCount=0}else{for(;n;){var c=n.chunk,l=n.encoding,d=n.callback;if(D(e,t,!1,t.objectMode?1:c.length,c,l,d),n=n.next,t.bufferedRequestCount--,t.writing)break}null===n&&(t.lastBufferedRequest=null)}t.bufferedRequest=n,t.bufferProcessing=!1}function C(e){return e.ending&&0===e.length&&null===e.bufferedRequest&&!e.finished&&!e.writing}function A(e,t){e._final((function(n){t.pendingcb--,n&&v(e,n),t.prefinished=!0,e.emit("prefinish"),T(e,t)}))}function T(e,t){var n=C(t);if(n&&(function(e,t){t.prefinished||t.finalCalled||("function"!=typeof e._final||t.destroyed?(t.prefinished=!0,e.emit("prefinish")):(t.pendingcb++,t.finalCalled=!0,process.nextTick(A,e,t)))}(e,t),0===t.pendingcb&&(t.finished=!0,e.emit("finish"),t.autoDestroy))){var o=e._readableState;(!o||o.autoDestroy&&o.endEmitted)&&e.destroy()}return n}n(35717)(k,s),E.prototype.getBuffer=function(){for(var e=this.bufferedRequest,t=[];e;)t.push(e),e=e.next;return t},function(){try{Object.defineProperty(E.prototype,"buffer",{get:a.deprecate((function(){return this.getBuffer()}),"_writableState.buffer is deprecated. Use _writableState.getBuffer instead.","DEP0003")})}catch(e){}}(),"function"==typeof Symbol&&Symbol.hasInstance&&"function"==typeof Function.prototype[Symbol.hasInstance]?(i=Function.prototype[Symbol.hasInstance],Object.defineProperty(k,Symbol.hasInstance,{value:function(e){return!!i.call(this,e)||this===k&&e&&e._writableState instanceof E}})):i=function(e){return e instanceof this},k.prototype.pipe=function(){v(this,new m)},k.prototype.write=function(e,t,n){var o,r=this._writableState,i=!1,a=!r.objectMode&&(o=e,u.isBuffer(o)||o instanceof c);return a&&!u.isBuffer(e)&&(e=function(e){return u.from(e)}(e)),"function"==typeof t&&(n=t,t=null),a?t="buffer":t||(t=r.defaultEncoding),"function"!=typeof n&&(n=w),r.ending?function(e,t){var n=new y;v(e,n),process.nextTick(t,n)}(this,n):(a||function(e,t,n,o){var r;return null===n?r=new F:"string"==typeof n||t.objectMode||(r=new p("chunk",["string","Buffer"],n)),!r||(v(e,r),process.nextTick(o,r),!1)}(this,r,e,n))&&(r.pendingcb++,i=function(e,t,n,o,r,i){if(!n){var a=function(e,t,n){return e.objectMode||!1===e.decodeStrings||"string"!=typeof t||(t=u.from(t,n)),t}(t,o,r);o!==a&&(n=!0,r="buffer",o=a)}var s=t.objectMode?1:o.length;t.length+=s;var c=t.length-1))throw new b(e);return this._writableState.defaultEncoding=e,this},Object.defineProperty(k.prototype,"writableBuffer",{enumerable:!1,get:function(){return this._writableState&&this._writableState.getBuffer()}}),Object.defineProperty(k.prototype,"writableHighWaterMark",{enumerable:!1,get:function(){return this._writableState.highWaterMark}}),k.prototype._write=function(e,t,n){n(new f("_write()"))},k.prototype._writev=null,k.prototype.end=function(e,t,n){var o=this._writableState;return"function"==typeof e?(n=e,e=null,t=null):"function"==typeof t&&(n=t,t=null),null!=e&&this.write(e,t),o.corked&&(o.corked=1,this.uncork()),o.ending||function(e,t,n){t.ending=!0,T(e,t),n&&(t.finished?process.nextTick(n):e.once("finish",n)),t.ended=!0,e.writable=!1}(this,o,n),this},Object.defineProperty(k.prototype,"writableLength",{enumerable:!1,get:function(){return this._writableState.length}}),Object.defineProperty(k.prototype,"destroyed",{enumerable:!1,get:function(){return void 0!==this._writableState&&this._writableState.destroyed},set:function(e){this._writableState&&(this._writableState.destroyed=e)}}),k.prototype.destroy=l.destroy,k.prototype._undestroy=l.undestroy,k.prototype._destroy=function(e,t){t(e)}},54887:(e,t,n)=>{"use strict";var o;function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var i=n(5800),a=Symbol("lastResolve"),s=Symbol("lastReject"),u=Symbol("error"),c=Symbol("ended"),l=Symbol("lastPromise"),d=Symbol("handlePromise"),h=Symbol("stream");function p(e,t){return{value:e,done:t}}function f(e){var t=e[a];if(null!==t){var n=e[h].read();null!==n&&(e[l]=null,e[a]=null,e[s]=null,t(p(n,!1)))}}function g(e){process.nextTick(f,e)}var m=Object.getPrototypeOf((function(){})),_=Object.setPrototypeOf((r(o={get stream(){return this[h]},next:function(){var e=this,t=this[u];if(null!==t)return Promise.reject(t);if(this[c])return Promise.resolve(p(void 0,!0));if(this[h].destroyed)return new Promise((function(t,n){process.nextTick((function(){e[u]?n(e[u]):t(p(void 0,!0))}))}));var n,o=this[l];if(o)n=new Promise(function(e,t){return function(n,o){e.then((function(){t[c]?n(p(void 0,!0)):t[d](n,o)}),o)}}(o,this));else{var r=this[h].read();if(null!==r)return Promise.resolve(p(r,!1));n=new Promise(this[d])}return this[l]=n,n}},Symbol.asyncIterator,(function(){return this})),r(o,"return",(function(){var e=this;return new Promise((function(t,n){e[h].destroy(null,(function(e){e?n(e):t(p(void 0,!0))}))}))})),o),m);e.exports=function(e){var t,n=Object.create(_,(r(t={},h,{value:e,writable:!0}),r(t,a,{value:null,writable:!0}),r(t,s,{value:null,writable:!0}),r(t,u,{value:null,writable:!0}),r(t,c,{value:e._readableState.endEmitted,writable:!0}),r(t,d,{value:function(e,t){var o=n[h].read();o?(n[l]=null,n[a]=null,n[s]=null,e(p(o,!1))):(n[a]=e,n[s]=t)},writable:!0}),t));return n[l]=null,i(e,(function(e){if(e&&"ERR_STREAM_PREMATURE_CLOSE"!==e.code){var t=n[s];return null!==t&&(n[l]=null,n[a]=null,n[s]=null,t(e)),void(n[u]=e)}var o=n[a];null!==o&&(n[l]=null,n[a]=null,n[s]=null,o(p(void 0,!0))),n[c]=!0})),e.on("readable",g.bind(null,n)),n}},76633:(e,t,n)=>{"use strict";function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){for(var n=0;n0?this.tail.next=t:this.head=t,this.tail=t,++this.length}},{key:"unshift",value:function(e){var t={data:e,next:this.head};0===this.length&&(this.tail=t),this.head=t,++this.length}},{key:"shift",value:function(){if(0!==this.length){var e=this.head.data;return 1===this.length?this.head=this.tail=null:this.head=this.head.next,--this.length,e}}},{key:"clear",value:function(){this.head=this.tail=null,this.length=0}},{key:"join",value:function(e){if(0===this.length)return"";for(var t=this.head,n=""+t.data;t=t.next;)n+=e+t.data;return n}},{key:"concat",value:function(e){if(0===this.length)return a.alloc(0);for(var t,n,o,r=a.allocUnsafe(e>>>0),i=this.head,s=0;i;)t=i.data,n=r,o=s,a.prototype.copy.call(t,n,o),s+=i.data.length,i=i.next;return r}},{key:"consume",value:function(e,t){var n;return er.length?r.length:e;if(i===r.length?o+=r:o+=r.slice(0,e),0==(e-=i)){i===r.length?(++n,t.next?this.head=t.next:this.head=this.tail=null):(this.head=t,t.data=r.slice(i));break}++n}return this.length-=n,o}},{key:"_getBuffer",value:function(e){var t=a.allocUnsafe(e),n=this.head,o=1;for(n.data.copy(t),e-=n.data.length;n=n.next;){var r=n.data,i=e>r.length?r.length:e;if(r.copy(t,t.length-e,0,i),0==(e-=i)){i===r.length?(++o,n.next?this.head=n.next:this.head=this.tail=null):(this.head=n,n.data=r.slice(i));break}++o}return this.length-=o,t}},{key:u,value:function(e,t){return s(this,function(e){for(var t=1;t{"use strict";function t(e,t){o(e,t),n(e)}function n(e){e._writableState&&!e._writableState.emitClose||e._readableState&&!e._readableState.emitClose||e.emit("close")}function o(e,t){e.emit("error",t)}e.exports={destroy:function(e,r){var i=this,a=this._readableState&&this._readableState.destroyed,s=this._writableState&&this._writableState.destroyed;return a||s?(r?r(e):e&&(this._writableState?this._writableState.errorEmitted||(this._writableState.errorEmitted=!0,process.nextTick(o,this,e)):process.nextTick(o,this,e)),this):(this._readableState&&(this._readableState.destroyed=!0),this._writableState&&(this._writableState.destroyed=!0),this._destroy(e||null,(function(e){!r&&e?i._writableState?i._writableState.errorEmitted?process.nextTick(n,i):(i._writableState.errorEmitted=!0,process.nextTick(t,i,e)):process.nextTick(t,i,e):r?(process.nextTick(n,i),r(e)):process.nextTick(n,i)})),this)},undestroy:function(){this._readableState&&(this._readableState.destroyed=!1,this._readableState.reading=!1,this._readableState.ended=!1,this._readableState.endEmitted=!1),this._writableState&&(this._writableState.destroyed=!1,this._writableState.ended=!1,this._writableState.ending=!1,this._writableState.finalCalled=!1,this._writableState.prefinished=!1,this._writableState.finished=!1,this._writableState.errorEmitted=!1)},errorOrDestroy:function(e,t){var n=e._readableState,o=e._writableState;n&&n.autoDestroy||o&&o.autoDestroy?e.destroy(t):e.emit("error",t)}}},5800:(e,t,n)=>{"use strict";var o=n(84419).q.ERR_STREAM_PREMATURE_CLOSE;function r(){}e.exports=function e(t,n,i){if("function"==typeof n)return e(t,null,n);n||(n={}),i=function(e){var t=!1;return function(){if(!t){t=!0;for(var n=arguments.length,o=new Array(n),r=0;r{e.exports=function(){throw new Error("Readable.from is not available in the browser")}},37065:(e,t,n)=>{"use strict";var o,r=n(84419).q,i=r.ERR_MISSING_ARGS,a=r.ERR_STREAM_DESTROYED;function s(e){if(e)throw e}function u(e,t,r,i){i=function(e){var t=!1;return function(){t||(t=!0,e.apply(void 0,arguments))}}(i);var s=!1;e.on("close",(function(){s=!0})),void 0===o&&(o=n(5800)),o(e,{readable:t,writable:r},(function(e){if(e)return i(e);s=!0,i()}));var u=!1;return function(t){if(!s&&!u)return u=!0,function(e){return e.setHeader&&"function"==typeof e.abort}(e)?e.abort():"function"==typeof e.destroy?e.destroy():void i(t||new a("pipe"))}}function c(e){e()}function l(e,t){return e.pipe(t)}function d(e){return e.length?"function"!=typeof e[e.length-1]?s:e.pop():s}e.exports=function(){for(var e=arguments.length,t=new Array(e),n=0;n0,(function(e){o||(o=e),e&&a.forEach(c),i||(a.forEach(c),r(o))}))}));return t.reduce(l)}},898:(e,t,n)=>{"use strict";var o=n(84419).q.ERR_INVALID_OPT_VALUE;e.exports={getHighWaterMark:function(e,t,n,r){var i=function(e,t,n){return null!=e.highWaterMark?e.highWaterMark:t?e[n]:null}(t,r,n);if(null!=i){if(!isFinite(i)||Math.floor(i)!==i||i<0)throw new o(r?n:"highWaterMark",i);return Math.floor(i)}return e.objectMode?16:16384}}},59819:(e,t,n)=>{e.exports=n(17187).EventEmitter},23872:(e,t,n)=>{(t=e.exports=n(44960)).Stream=t,t.Readable=t,t.Writable=n(92010),t.Duplex=n(34390),t.Transform=n(3912),t.PassThrough=n(41294),t.finished=n(5800),t.pipeline=n(37065)},77191:(e,t,n)=>{var o=n(58162);e.exports=o("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz")},55420:e=>{var t=Object.prototype.toString,n="function"==typeof Buffer.alloc&&"function"==typeof Buffer.allocUnsafe&&"function"==typeof Buffer.from;e.exports=function(e,o,r){if("number"==typeof e)throw new TypeError('"value" argument must not be a number');return i=e,"ArrayBuffer"===t.call(i).slice(8,-1)?function(e,t,o){t>>>=0;var r=e.byteLength-t;if(r<0)throw new RangeError("'offset' is out of bounds");if(void 0===o)o=r;else if((o>>>=0)>r)throw new RangeError("'length' is out of bounds");return n?Buffer.from(e.slice(t,t+o)):new Buffer(new Uint8Array(e.slice(t,t+o)))}(e,o,r):"string"==typeof e?function(e,t){if("string"==typeof t&&""!==t||(t="utf8"),!Buffer.isEncoding(t))throw new TypeError('"encoding" must be a valid string encoding');return n?Buffer.from(e,t):new Buffer(e,t)}(e,o):n?Buffer.from(e):new Buffer(e);var i}},67295:e=>{e.exports=function(e,t){for(var n=Math.min(e.length,t.length),o=new Buffer(n),r=0;r{"use strict";const o=n(79742),r=n(80645),i="function"==typeof Symbol&&"function"==typeof Symbol.for?Symbol.for("nodejs.util.inspect.custom"):null;t.Buffer=u,t.SlowBuffer=function(e){return+e!=e&&(e=0),u.alloc(+e)},t.INSPECT_MAX_BYTES=50;const a=2147483647;function s(e){if(e>a)throw new RangeError('The value "'+e+'" is invalid for option "size"');const t=new Uint8Array(e);return Object.setPrototypeOf(t,u.prototype),t}function u(e,t,n){if("number"==typeof e){if("string"==typeof t)throw new TypeError('The "string" argument must be of type string. Received type number');return d(e)}return c(e,t,n)}function c(e,t,n){if("string"==typeof e)return function(e,t){if("string"==typeof t&&""!==t||(t="utf8"),!u.isEncoding(t))throw new TypeError("Unknown encoding: "+t);const n=0|g(e,t);let o=s(n);const r=o.write(e,t);return r!==n&&(o=o.slice(0,r)),o}(e,t);if(ArrayBuffer.isView(e))return function(e){if(Y(e,Uint8Array)){const t=new Uint8Array(e);return p(t.buffer,t.byteOffset,t.byteLength)}return h(e)}(e);if(null==e)throw new TypeError("The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type "+typeof e);if(Y(e,ArrayBuffer)||e&&Y(e.buffer,ArrayBuffer))return p(e,t,n);if("undefined"!=typeof SharedArrayBuffer&&(Y(e,SharedArrayBuffer)||e&&Y(e.buffer,SharedArrayBuffer)))return p(e,t,n);if("number"==typeof e)throw new TypeError('The "value" argument must not be of type number. Received type number');const o=e.valueOf&&e.valueOf();if(null!=o&&o!==e)return u.from(o,t,n);const r=function(e){if(u.isBuffer(e)){const t=0|f(e.length),n=s(t);return 0===n.length||e.copy(n,0,0,t),n}return void 0!==e.length?"number"!=typeof e.length||Z(e.length)?s(0):h(e):"Buffer"===e.type&&Array.isArray(e.data)?h(e.data):void 0}(e);if(r)return r;if("undefined"!=typeof Symbol&&null!=Symbol.toPrimitive&&"function"==typeof e[Symbol.toPrimitive])return u.from(e[Symbol.toPrimitive]("string"),t,n);throw new TypeError("The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type "+typeof e)}function l(e){if("number"!=typeof e)throw new TypeError('"size" argument must be of type number');if(e<0)throw new RangeError('The value "'+e+'" is invalid for option "size"')}function d(e){return l(e),s(e<0?0:0|f(e))}function h(e){const t=e.length<0?0:0|f(e.length),n=s(t);for(let o=0;o=a)throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+a.toString(16)+" bytes");return 0|e}function g(e,t){if(u.isBuffer(e))return e.length;if(ArrayBuffer.isView(e)||Y(e,ArrayBuffer))return e.byteLength;if("string"!=typeof e)throw new TypeError('The "string" argument must be one of type string, Buffer, or ArrayBuffer. Received type '+typeof e);const n=e.length,o=arguments.length>2&&!0===arguments[2];if(!o&&0===n)return 0;let r=!1;for(;;)switch(t){case"ascii":case"latin1":case"binary":return n;case"utf8":case"utf-8":return H(e).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*n;case"hex":return n>>>1;case"base64":return V(e).length;default:if(r)return o?-1:H(e).length;t=(""+t).toLowerCase(),r=!0}}function m(e,t,n){let o=!1;if((void 0===t||t<0)&&(t=0),t>this.length)return"";if((void 0===n||n>this.length)&&(n=this.length),n<=0)return"";if((n>>>=0)<=(t>>>=0))return"";for(e||(e="utf8");;)switch(e){case"hex":return T(this,t,n);case"utf8":case"utf-8":return S(this,t,n);case"ascii":return C(this,t,n);case"latin1":case"binary":return A(this,t,n);case"base64":return D(this,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return R(this,t,n);default:if(o)throw new TypeError("Unknown encoding: "+e);e=(e+"").toLowerCase(),o=!0}}function _(e,t,n){const o=e[t];e[t]=e[n],e[n]=o}function F(e,t,n,o,r){if(0===e.length)return-1;if("string"==typeof n?(o=n,n=0):n>2147483647?n=2147483647:n<-2147483648&&(n=-2147483648),Z(n=+n)&&(n=r?0:e.length-1),n<0&&(n=e.length+n),n>=e.length){if(r)return-1;n=e.length-1}else if(n<0){if(!r)return-1;n=0}if("string"==typeof t&&(t=u.from(t,o)),u.isBuffer(t))return 0===t.length?-1:y(e,t,n,o,r);if("number"==typeof t)return t&=255,"function"==typeof Uint8Array.prototype.indexOf?r?Uint8Array.prototype.indexOf.call(e,t,n):Uint8Array.prototype.lastIndexOf.call(e,t,n):y(e,[t],n,o,r);throw new TypeError("val must be string, number or Buffer")}function y(e,t,n,o,r){let i,a=1,s=e.length,u=t.length;if(void 0!==o&&("ucs2"===(o=String(o).toLowerCase())||"ucs-2"===o||"utf16le"===o||"utf-16le"===o)){if(e.length<2||t.length<2)return-1;a=2,s/=2,u/=2,n/=2}function c(e,t){return 1===a?e[t]:e.readUInt16BE(t*a)}if(r){let o=-1;for(i=n;is&&(n=s-u),i=n;i>=0;i--){let n=!0;for(let o=0;or&&(o=r):o=r;const i=t.length;let a;for(o>i/2&&(o=i/2),a=0;a>8,r=n%256,i.push(r),i.push(o);return i}(t,e.length-n),e,n,o)}function D(e,t,n){return 0===t&&n===e.length?o.fromByteArray(e):o.fromByteArray(e.slice(t,n))}function S(e,t,n){n=Math.min(e.length,n);const o=[];let r=t;for(;r239?4:t>223?3:t>191?2:1;if(r+a<=n){let n,o,s,u;switch(a){case 1:t<128&&(i=t);break;case 2:n=e[r+1],128==(192&n)&&(u=(31&t)<<6|63&n,u>127&&(i=u));break;case 3:n=e[r+1],o=e[r+2],128==(192&n)&&128==(192&o)&&(u=(15&t)<<12|(63&n)<<6|63&o,u>2047&&(u<55296||u>57343)&&(i=u));break;case 4:n=e[r+1],o=e[r+2],s=e[r+3],128==(192&n)&&128==(192&o)&&128==(192&s)&&(u=(15&t)<<18|(63&n)<<12|(63&o)<<6|63&s,u>65535&&u<1114112&&(i=u))}}null===i?(i=65533,a=1):i>65535&&(i-=65536,o.push(i>>>10&1023|55296),i=56320|1023&i),o.push(i),r+=a}return function(e){const t=e.length;if(t<=x)return String.fromCharCode.apply(String,e);let n="",o=0;for(;oo.length?(u.isBuffer(t)||(t=u.from(t)),t.copy(o,r)):Uint8Array.prototype.set.call(o,t,r);else{if(!u.isBuffer(t))throw new TypeError('"list" argument must be an Array of Buffers');t.copy(o,r)}r+=t.length}return o},u.byteLength=g,u.prototype._isBuffer=!0,u.prototype.swap16=function(){const e=this.length;if(e%2!=0)throw new RangeError("Buffer size must be a multiple of 16-bits");for(let t=0;tn&&(e+=" ... "),""},i&&(u.prototype[i]=u.prototype.inspect),u.prototype.compare=function(e,t,n,o,r){if(Y(e,Uint8Array)&&(e=u.from(e,e.offset,e.byteLength)),!u.isBuffer(e))throw new TypeError('The "target" argument must be one of type Buffer or Uint8Array. Received type '+typeof e);if(void 0===t&&(t=0),void 0===n&&(n=e?e.length:0),void 0===o&&(o=0),void 0===r&&(r=this.length),t<0||n>e.length||o<0||r>this.length)throw new RangeError("out of range index");if(o>=r&&t>=n)return 0;if(o>=r)return-1;if(t>=n)return 1;if(this===e)return 0;let i=(r>>>=0)-(o>>>=0),a=(n>>>=0)-(t>>>=0);const s=Math.min(i,a),c=this.slice(o,r),l=e.slice(t,n);for(let e=0;e>>=0,isFinite(n)?(n>>>=0,void 0===o&&(o="utf8")):(o=n,n=void 0)}const r=this.length-t;if((void 0===n||n>r)&&(n=r),e.length>0&&(n<0||t<0)||t>this.length)throw new RangeError("Attempt to write outside buffer bounds");o||(o="utf8");let i=!1;for(;;)switch(o){case"hex":return b(this,e,t,n);case"utf8":case"utf-8":return v(this,e,t,n);case"ascii":case"latin1":case"binary":return w(this,e,t,n);case"base64":return E(this,e,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return k(this,e,t,n);default:if(i)throw new TypeError("Unknown encoding: "+o);o=(""+o).toLowerCase(),i=!0}},u.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};const x=4096;function C(e,t,n){let o="";n=Math.min(e.length,n);for(let r=t;ro)&&(n=o);let r="";for(let o=t;on)throw new RangeError("Trying to access beyond buffer length")}function M(e,t,n,o,r,i){if(!u.isBuffer(e))throw new TypeError('"buffer" argument must be a Buffer instance');if(t>r||te.length)throw new RangeError("Index out of range")}function O(e,t,n,o,r){z(t,o,r,e,n,7);let i=Number(t&BigInt(4294967295));e[n++]=i,i>>=8,e[n++]=i,i>>=8,e[n++]=i,i>>=8,e[n++]=i;let a=Number(t>>BigInt(32)&BigInt(4294967295));return e[n++]=a,a>>=8,e[n++]=a,a>>=8,e[n++]=a,a>>=8,e[n++]=a,n}function B(e,t,n,o,r){z(t,o,r,e,n,7);let i=Number(t&BigInt(4294967295));e[n+7]=i,i>>=8,e[n+6]=i,i>>=8,e[n+5]=i,i>>=8,e[n+4]=i;let a=Number(t>>BigInt(32)&BigInt(4294967295));return e[n+3]=a,a>>=8,e[n+2]=a,a>>=8,e[n+1]=a,a>>=8,e[n]=a,n+8}function N(e,t,n,o,r,i){if(n+o>e.length)throw new RangeError("Index out of range");if(n<0)throw new RangeError("Index out of range")}function L(e,t,n,o,i){return t=+t,n>>>=0,i||N(e,0,n,4),r.write(e,t,n,o,23,4),n+4}function P(e,t,n,o,i){return t=+t,n>>>=0,i||N(e,0,n,8),r.write(e,t,n,o,52,8),n+8}u.prototype.slice=function(e,t){const n=this.length;(e=~~e)<0?(e+=n)<0&&(e=0):e>n&&(e=n),(t=void 0===t?n:~~t)<0?(t+=n)<0&&(t=0):t>n&&(t=n),t>>=0,t>>>=0,n||I(e,t,this.length);let o=this[e],r=1,i=0;for(;++i>>=0,t>>>=0,n||I(e,t,this.length);let o=this[e+--t],r=1;for(;t>0&&(r*=256);)o+=this[e+--t]*r;return o},u.prototype.readUint8=u.prototype.readUInt8=function(e,t){return e>>>=0,t||I(e,1,this.length),this[e]},u.prototype.readUint16LE=u.prototype.readUInt16LE=function(e,t){return e>>>=0,t||I(e,2,this.length),this[e]|this[e+1]<<8},u.prototype.readUint16BE=u.prototype.readUInt16BE=function(e,t){return e>>>=0,t||I(e,2,this.length),this[e]<<8|this[e+1]},u.prototype.readUint32LE=u.prototype.readUInt32LE=function(e,t){return e>>>=0,t||I(e,4,this.length),(this[e]|this[e+1]<<8|this[e+2]<<16)+16777216*this[e+3]},u.prototype.readUint32BE=u.prototype.readUInt32BE=function(e,t){return e>>>=0,t||I(e,4,this.length),16777216*this[e]+(this[e+1]<<16|this[e+2]<<8|this[e+3])},u.prototype.readBigUInt64LE=J((function(e){K(e>>>=0,"offset");const t=this[e],n=this[e+7];void 0!==t&&void 0!==n||G(e,this.length-8);const o=t+256*this[++e]+65536*this[++e]+this[++e]*2**24,r=this[++e]+256*this[++e]+65536*this[++e]+n*2**24;return BigInt(o)+(BigInt(r)<>>=0,"offset");const t=this[e],n=this[e+7];void 0!==t&&void 0!==n||G(e,this.length-8);const o=t*2**24+65536*this[++e]+256*this[++e]+this[++e],r=this[++e]*2**24+65536*this[++e]+256*this[++e]+n;return(BigInt(o)<>>=0,t>>>=0,n||I(e,t,this.length);let o=this[e],r=1,i=0;for(;++i=r&&(o-=Math.pow(2,8*t)),o},u.prototype.readIntBE=function(e,t,n){e>>>=0,t>>>=0,n||I(e,t,this.length);let o=t,r=1,i=this[e+--o];for(;o>0&&(r*=256);)i+=this[e+--o]*r;return r*=128,i>=r&&(i-=Math.pow(2,8*t)),i},u.prototype.readInt8=function(e,t){return e>>>=0,t||I(e,1,this.length),128&this[e]?-1*(255-this[e]+1):this[e]},u.prototype.readInt16LE=function(e,t){e>>>=0,t||I(e,2,this.length);const n=this[e]|this[e+1]<<8;return 32768&n?4294901760|n:n},u.prototype.readInt16BE=function(e,t){e>>>=0,t||I(e,2,this.length);const n=this[e+1]|this[e]<<8;return 32768&n?4294901760|n:n},u.prototype.readInt32LE=function(e,t){return e>>>=0,t||I(e,4,this.length),this[e]|this[e+1]<<8|this[e+2]<<16|this[e+3]<<24},u.prototype.readInt32BE=function(e,t){return e>>>=0,t||I(e,4,this.length),this[e]<<24|this[e+1]<<16|this[e+2]<<8|this[e+3]},u.prototype.readBigInt64LE=J((function(e){K(e>>>=0,"offset");const t=this[e],n=this[e+7];void 0!==t&&void 0!==n||G(e,this.length-8);const o=this[e+4]+256*this[e+5]+65536*this[e+6]+(n<<24);return(BigInt(o)<>>=0,"offset");const t=this[e],n=this[e+7];void 0!==t&&void 0!==n||G(e,this.length-8);const o=(t<<24)+65536*this[++e]+256*this[++e]+this[++e];return(BigInt(o)<>>=0,t||I(e,4,this.length),r.read(this,e,!0,23,4)},u.prototype.readFloatBE=function(e,t){return e>>>=0,t||I(e,4,this.length),r.read(this,e,!1,23,4)},u.prototype.readDoubleLE=function(e,t){return e>>>=0,t||I(e,8,this.length),r.read(this,e,!0,52,8)},u.prototype.readDoubleBE=function(e,t){return e>>>=0,t||I(e,8,this.length),r.read(this,e,!1,52,8)},u.prototype.writeUintLE=u.prototype.writeUIntLE=function(e,t,n,o){e=+e,t>>>=0,n>>>=0,o||M(this,e,t,n,Math.pow(2,8*n)-1,0);let r=1,i=0;for(this[t]=255&e;++i>>=0,n>>>=0,o||M(this,e,t,n,Math.pow(2,8*n)-1,0);let r=n-1,i=1;for(this[t+r]=255&e;--r>=0&&(i*=256);)this[t+r]=e/i&255;return t+n},u.prototype.writeUint8=u.prototype.writeUInt8=function(e,t,n){return e=+e,t>>>=0,n||M(this,e,t,1,255,0),this[t]=255&e,t+1},u.prototype.writeUint16LE=u.prototype.writeUInt16LE=function(e,t,n){return e=+e,t>>>=0,n||M(this,e,t,2,65535,0),this[t]=255&e,this[t+1]=e>>>8,t+2},u.prototype.writeUint16BE=u.prototype.writeUInt16BE=function(e,t,n){return e=+e,t>>>=0,n||M(this,e,t,2,65535,0),this[t]=e>>>8,this[t+1]=255&e,t+2},u.prototype.writeUint32LE=u.prototype.writeUInt32LE=function(e,t,n){return e=+e,t>>>=0,n||M(this,e,t,4,4294967295,0),this[t+3]=e>>>24,this[t+2]=e>>>16,this[t+1]=e>>>8,this[t]=255&e,t+4},u.prototype.writeUint32BE=u.prototype.writeUInt32BE=function(e,t,n){return e=+e,t>>>=0,n||M(this,e,t,4,4294967295,0),this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e,t+4},u.prototype.writeBigUInt64LE=J((function(e,t=0){return O(this,e,t,BigInt(0),BigInt("0xffffffffffffffff"))})),u.prototype.writeBigUInt64BE=J((function(e,t=0){return B(this,e,t,BigInt(0),BigInt("0xffffffffffffffff"))})),u.prototype.writeIntLE=function(e,t,n,o){if(e=+e,t>>>=0,!o){const o=Math.pow(2,8*n-1);M(this,e,t,n,o-1,-o)}let r=0,i=1,a=0;for(this[t]=255&e;++r>0)-a&255;return t+n},u.prototype.writeIntBE=function(e,t,n,o){if(e=+e,t>>>=0,!o){const o=Math.pow(2,8*n-1);M(this,e,t,n,o-1,-o)}let r=n-1,i=1,a=0;for(this[t+r]=255&e;--r>=0&&(i*=256);)e<0&&0===a&&0!==this[t+r+1]&&(a=1),this[t+r]=(e/i>>0)-a&255;return t+n},u.prototype.writeInt8=function(e,t,n){return e=+e,t>>>=0,n||M(this,e,t,1,127,-128),e<0&&(e=255+e+1),this[t]=255&e,t+1},u.prototype.writeInt16LE=function(e,t,n){return e=+e,t>>>=0,n||M(this,e,t,2,32767,-32768),this[t]=255&e,this[t+1]=e>>>8,t+2},u.prototype.writeInt16BE=function(e,t,n){return e=+e,t>>>=0,n||M(this,e,t,2,32767,-32768),this[t]=e>>>8,this[t+1]=255&e,t+2},u.prototype.writeInt32LE=function(e,t,n){return e=+e,t>>>=0,n||M(this,e,t,4,2147483647,-2147483648),this[t]=255&e,this[t+1]=e>>>8,this[t+2]=e>>>16,this[t+3]=e>>>24,t+4},u.prototype.writeInt32BE=function(e,t,n){return e=+e,t>>>=0,n||M(this,e,t,4,2147483647,-2147483648),e<0&&(e=4294967295+e+1),this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e,t+4},u.prototype.writeBigInt64LE=J((function(e,t=0){return O(this,e,t,-BigInt("0x8000000000000000"),BigInt("0x7fffffffffffffff"))})),u.prototype.writeBigInt64BE=J((function(e,t=0){return B(this,e,t,-BigInt("0x8000000000000000"),BigInt("0x7fffffffffffffff"))})),u.prototype.writeFloatLE=function(e,t,n){return L(this,e,t,!0,n)},u.prototype.writeFloatBE=function(e,t,n){return L(this,e,t,!1,n)},u.prototype.writeDoubleLE=function(e,t,n){return P(this,e,t,!0,n)},u.prototype.writeDoubleBE=function(e,t,n){return P(this,e,t,!1,n)},u.prototype.copy=function(e,t,n,o){if(!u.isBuffer(e))throw new TypeError("argument should be a Buffer");if(n||(n=0),o||0===o||(o=this.length),t>=e.length&&(t=e.length),t||(t=0),o>0&&o=this.length)throw new RangeError("Index out of range");if(o<0)throw new RangeError("sourceEnd out of bounds");o>this.length&&(o=this.length),e.length-t>>=0,n=void 0===n?this.length:n>>>0,e||(e=0),"number"==typeof e)for(r=t;r=o+4;n-=3)t=`_${e.slice(n-3,n)}${t}`;return`${e.slice(0,n)}${t}`}function z(e,t,n,o,r,i){if(e>n||e3?0===t||t===BigInt(0)?`>= 0${o} and < 2${o} ** ${8*(i+1)}${o}`:`>= -(2${o} ** ${8*(i+1)-1}${o}) and < 2 ** ${8*(i+1)-1}${o}`:`>= ${t}${o} and <= ${n}${o}`,new U.ERR_OUT_OF_RANGE("value",r,e)}!function(e,t,n){K(t,"offset"),void 0!==e[t]&&void 0!==e[t+n]||G(t,e.length-(n+1))}(o,r,i)}function K(e,t){if("number"!=typeof e)throw new U.ERR_INVALID_ARG_TYPE(t,"number",e)}function G(e,t,n){if(Math.floor(e)!==e)throw K(e,n),new U.ERR_OUT_OF_RANGE(n||"offset","an integer",e);if(t<0)throw new U.ERR_BUFFER_OUT_OF_BOUNDS;throw new U.ERR_OUT_OF_RANGE(n||"offset",`>= ${n?1:0} and <= ${t}`,e)}j("ERR_BUFFER_OUT_OF_BOUNDS",(function(e){return e?`${e} is outside of buffer bounds`:"Attempt to access memory outside buffer bounds"}),RangeError),j("ERR_INVALID_ARG_TYPE",(function(e,t){return`The "${e}" argument must be of type number. Received type ${typeof t}`}),TypeError),j("ERR_OUT_OF_RANGE",(function(e,t,n){let o=`The value of "${e}" is out of range.`,r=n;return Number.isInteger(n)&&Math.abs(n)>2**32?r=q(String(n)):"bigint"==typeof n&&(r=String(n),(n>BigInt(2)**BigInt(32)||n<-(BigInt(2)**BigInt(32)))&&(r=q(r)),r+="n"),o+=` It must be ${t}. Received ${r}`,o}),RangeError);const $=/[^+/0-9A-Za-z-_]/g;function H(e,t){let n;t=t||1/0;const o=e.length;let r=null;const i=[];for(let a=0;a55295&&n<57344){if(!r){if(n>56319){(t-=3)>-1&&i.push(239,191,189);continue}if(a+1===o){(t-=3)>-1&&i.push(239,191,189);continue}r=n;continue}if(n<56320){(t-=3)>-1&&i.push(239,191,189),r=n;continue}n=65536+(r-55296<<10|n-56320)}else r&&(t-=3)>-1&&i.push(239,191,189);if(r=null,n<128){if((t-=1)<0)break;i.push(n)}else if(n<2048){if((t-=2)<0)break;i.push(n>>6|192,63&n|128)}else if(n<65536){if((t-=3)<0)break;i.push(n>>12|224,n>>6&63|128,63&n|128)}else{if(!(n<1114112))throw new Error("Invalid code point");if((t-=4)<0)break;i.push(n>>18|240,n>>12&63|128,n>>6&63|128,63&n|128)}}return i}function V(e){return o.toByteArray(function(e){if((e=(e=e.split("=")[0]).trim().replace($,"")).length<2)return"";for(;e.length%4!=0;)e+="=";return e}(e))}function W(e,t,n,o){let r;for(r=0;r=t.length||r>=e.length);++r)t[r+n]=e[r];return r}function Y(e,t){return e instanceof t||null!=e&&null!=e.constructor&&null!=e.constructor.name&&e.constructor.name===t.name}function Z(e){return e!=e}const X=function(){const e="0123456789abcdef",t=new Array(256);for(let n=0;n<16;++n){const o=16*n;for(let r=0;r<16;++r)t[o+r]=e[n]+e[r]}return t}();function J(e){return"undefined"==typeof BigInt?Q:e}function Q(){throw new Error("BigInt not supported")}},21924:(e,t,n)=>{"use strict";var o=n(40210),r=n(55559),i=r(o("String.prototype.indexOf"));e.exports=function(e,t){var n=o(e,!!t);return"function"==typeof n&&i(e,".prototype.")>-1?r(n):n}},55559:(e,t,n)=>{"use strict";var o=n(58612),r=n(40210),i=r("%Function.prototype.apply%"),a=r("%Function.prototype.call%"),s=r("%Reflect.apply%",!0)||o.call(a,i),u=r("%Object.getOwnPropertyDescriptor%",!0),c=r("%Object.defineProperty%",!0),l=r("%Math.max%");if(c)try{c({},"a",{value:1})}catch(e){c=null}e.exports=function(e){var t=s(o,a,arguments);if(u&&c){var n=u(t,"length");n.configurable&&c(t,"length",{value:1+l(0,e.length-(arguments.length-1))})}return t};var d=function(){return s(o,i,arguments)};c?c(e.exports,"apply",{value:d}):e.exports.apply=d},30932:e=>{"use strict";e.exports=function(e,t){var n,o=String(e),r=0;if("string"!=typeof t)throw new Error("Expected character");for(n=o.indexOf(t);-1!==n;)r++,n=o.indexOf(t,n+t.length);return r}},16588:e=>{"use strict";e.exports=JSON.parse('{"AElig":"Æ","AMP":"&","Aacute":"Á","Acirc":"Â","Agrave":"À","Aring":"Å","Atilde":"Ã","Auml":"Ä","COPY":"©","Ccedil":"Ç","ETH":"Ð","Eacute":"É","Ecirc":"Ê","Egrave":"È","Euml":"Ë","GT":">","Iacute":"Í","Icirc":"Î","Igrave":"Ì","Iuml":"Ï","LT":"<","Ntilde":"Ñ","Oacute":"Ó","Ocirc":"Ô","Ograve":"Ò","Oslash":"Ø","Otilde":"Õ","Ouml":"Ö","QUOT":"\\"","REG":"®","THORN":"Þ","Uacute":"Ú","Ucirc":"Û","Ugrave":"Ù","Uuml":"Ü","Yacute":"Ý","aacute":"á","acirc":"â","acute":"´","aelig":"æ","agrave":"à","amp":"&","aring":"å","atilde":"ã","auml":"ä","brvbar":"¦","ccedil":"ç","cedil":"¸","cent":"¢","copy":"©","curren":"¤","deg":"°","divide":"÷","eacute":"é","ecirc":"ê","egrave":"è","eth":"ð","euml":"ë","frac12":"½","frac14":"¼","frac34":"¾","gt":">","iacute":"í","icirc":"î","iexcl":"¡","igrave":"ì","iquest":"¿","iuml":"ï","laquo":"«","lt":"<","macr":"¯","micro":"µ","middot":"·","nbsp":" ","not":"¬","ntilde":"ñ","oacute":"ó","ocirc":"ô","ograve":"ò","ordf":"ª","ordm":"º","oslash":"ø","otilde":"õ","ouml":"ö","para":"¶","plusmn":"±","pound":"£","quot":"\\"","raquo":"»","reg":"®","sect":"§","shy":"­","sup1":"¹","sup2":"²","sup3":"³","szlig":"ß","thorn":"þ","times":"×","uacute":"ú","ucirc":"û","ugrave":"ù","uml":"¨","uuml":"ü","yacute":"ý","yen":"¥","yuml":"ÿ"}')},6852:e=>{"use strict";e.exports=JSON.parse('{"0":"�","128":"€","130":"‚","131":"ƒ","132":"„","133":"…","134":"†","135":"‡","136":"ˆ","137":"‰","138":"Š","139":"‹","140":"Œ","142":"Ž","145":"‘","146":"’","147":"“","148":"”","149":"•","150":"–","151":"—","152":"˜","153":"™","154":"š","155":"›","156":"œ","158":"ž","159":"Ÿ"}')},71027:(e,t,n)=>{var o=n(89509).Buffer,r=n(42830).Transform,i=n(32553).s;function a(e){r.call(this),this.hashMode="string"==typeof e,this.hashMode?this[e]=this._finalOrDigest:this.final=this._finalOrDigest,this._final&&(this.__final=this._final,this._final=null),this._decoder=null,this._encoding=null}n(35717)(a,r),a.prototype.update=function(e,t,n){"string"==typeof e&&(e=o.from(e,t));var r=this._update(e);return this.hashMode?this:(n&&(r=this._toString(r,n)),r)},a.prototype.setAutoPadding=function(){},a.prototype.getAuthTag=function(){throw new Error("trying to get auth tag in unsupported state")},a.prototype.setAuthTag=function(){throw new Error("trying to set auth tag in unsupported state")},a.prototype.setAAD=function(){throw new Error("trying to set aad in unsupported state")},a.prototype._transform=function(e,t,n){var o;try{this.hashMode?this._update(e):this.push(this._update(e))}catch(e){o=e}finally{n(o)}},a.prototype._flush=function(e){var t;try{this.push(this.__final())}catch(e){t=e}e(t)},a.prototype._finalOrDigest=function(e){var t=this.__final()||o.alloc(0);return e&&(t=this._toString(t,e,!0)),t},a.prototype._toString=function(e,t,n){if(this._decoder||(this._decoder=new i(t),this._encoding=t),this._encoding!==t)throw new Error("can't switch encodings");var o=this._decoder.write(e);return n&&(o+=this._decoder.end()),o},e.exports=a},16313:e=>{"use strict";function t(e){return Object.prototype.toString.call(e)}function n(e,n,o,r){var i=[],a=[],s="undefined"!=typeof Buffer;return void 0===n&&(n=!0),void 0===o&&(o=1/0),function e(o,u){if(null===o)return null;if(0==u)return o;var c,l,d,h,p;if("object"!=typeof o)return o;if(p=o,Array.isArray(p)||"object"==typeof p&&"[object Array]"===t(p))c=[];else if("object"==typeof(h=o)&&"[object RegExp]"===t(h))c=new RegExp(o.source,function(e){var t="";return e.global&&(t+="g"),e.ignoreCase&&(t+="i"),e.multiline&&(t+="m"),t}(o)),o.lastIndex&&(c.lastIndex=o.lastIndex);else if("object"==typeof(d=o)&&"[object Date]"===t(d))c=new Date(o.getTime());else{if(s&&Buffer.isBuffer(o))return c=new Buffer(o.length),o.copy(c),c;void 0===r?(l=Object.getPrototypeOf(o),c=Object.create(l)):(c=Object.create(r),l=r)}if(n){var f=i.indexOf(o);if(-1!=f)return a[f];i.push(o),a.push(c)}for(var g in o){var m;l&&(m=Object.getOwnPropertyDescriptor(l,g)),m&&null==m.set||(c[g]=e(o[g],u-1))}return c}(e,o)}e.exports=n,n.clonePrototype=function(e){if(null===e)return null;var t=function(){};return t.prototype=e,new t}},56851:(e,t)=>{"use strict";t.parse=function(e){for(var t,n=[],o=String(e||""),r=o.indexOf(","),i=0,a=!1;!a;)-1===r&&(r=o.length,a=!0),!(t=o.slice(i,r).trim())&&a||n.push(t),i=r+1,r=o.indexOf(",",i);return n},t.stringify=function(e,t){var n=t||{},o=!1===n.padLeft?"":" ",r=n.padRight?" ":"";return""===e[e.length-1]&&(e=e.concat("")),e.join(r+","+o).trim()}},31934:e=>{e.exports=function(e,t,n){return((n=window.getComputedStyle)?n(e):e.currentStyle)[t.replace(/-(\w)/gi,(function(e,t){return t.toUpperCase()}))]}},36890:(e,t,n)=>{var o=n(88473).Writable,r=n(35717),i=n(55420);if("undefined"==typeof Uint8Array)var a=n(61666).U2;else a=Uint8Array;function s(e,t){if(!(this instanceof s))return new s(e,t);"function"==typeof e&&(t=e,e={}),e||(e={});var n=e.encoding,r=!1;n?"u8"!==(n=String(n).toLowerCase())&&"uint8"!==n||(n="uint8array"):r=!0,o.call(this,{objectMode:!0}),this.encoding=n,this.shouldInferEncoding=r,t&&this.on("finish",(function(){t(this.getBody())})),this.body=[]}function u(e){return"string"==typeof e||(t=e,/Array\]$/.test(Object.prototype.toString.call(t)))||e&&"function"==typeof e.subarray;var t}e.exports=s,r(s,o),s.prototype._write=function(e,t,n){this.body.push(e),n()},s.prototype.inferEncoding=function(e){var t=void 0===e?this.body[0]:e;return Buffer.isBuffer(t)?"buffer":"undefined"!=typeof Uint8Array&&t instanceof Uint8Array?"uint8array":Array.isArray(t)?"array":"string"==typeof t?"string":"[object Object]"===Object.prototype.toString.call(t)?"object":"buffer"},s.prototype.getBody=function(){return this.encoding||0!==this.body.length?(this.shouldInferEncoding&&(this.encoding=this.inferEncoding()),"array"===this.encoding?function(e){for(var t=[],n=0;n{"use strict";var n=/; *([!#$%&'*+.^_`|~0-9A-Za-z-]+) *= *("(?:[\u000b\u0020\u0021\u0023-\u005b\u005d-\u007e\u0080-\u00ff]|\\[\u000b\u0020-\u00ff])*"|[!#$%&'*+.^_`|~0-9A-Za-z-]+) */g,o=/^[\u000b\u0020-\u007e\u0080-\u00ff]+$/,r=/^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/,i=/\\([\u000b\u0020-\u00ff])/g,a=/([\\"])/g,s=/^[!#$%&'*+.^_`|~0-9A-Za-z-]+\/[!#$%&'*+.^_`|~0-9A-Za-z-]+$/;function u(e){var t=String(e);if(r.test(t))return t;if(t.length>0&&!o.test(t))throw new TypeError("invalid parameter value");return'"'+t.replace(a,"\\$1")+'"'}function c(e){this.parameters=Object.create(null),this.type=e}t.format=function(e){if(!e||"object"!=typeof e)throw new TypeError("argument obj is required");var t=e.parameters,n=e.type;if(!n||!s.test(n))throw new TypeError("invalid type");var o=n;if(t&&"object"==typeof t)for(var i,a=Object.keys(t).sort(),c=0;c{function n(e){return Object.prototype.toString.call(e)}t.isArray=function(e){return Array.isArray?Array.isArray(e):"[object Array]"===n(e)},t.isBoolean=function(e){return"boolean"==typeof e},t.isNull=function(e){return null===e},t.isNullOrUndefined=function(e){return null==e},t.isNumber=function(e){return"number"==typeof e},t.isString=function(e){return"string"==typeof e},t.isSymbol=function(e){return"symbol"==typeof e},t.isUndefined=function(e){return void 0===e},t.isRegExp=function(e){return"[object RegExp]"===n(e)},t.isObject=function(e){return"object"==typeof e&&null!==e},t.isDate=function(e){return"[object Date]"===n(e)},t.isError=function(e){return"[object Error]"===n(e)||e instanceof Error},t.isFunction=function(e){return"function"==typeof e},t.isPrimitive=function(e){return null===e||"boolean"==typeof e||"number"==typeof e||"string"==typeof e||"symbol"==typeof e||void 0===e},t.isBuffer=Buffer.isBuffer},76393:(e,t,n)=>{var o=n(86266),r=n(16426);e.exports=function(e){return new a(e)};var i={secp256k1:{name:"secp256k1",byteLength:32},secp224r1:{name:"p224",byteLength:28},prime256v1:{name:"p256",byteLength:32},prime192v1:{name:"p192",byteLength:24},ed25519:{name:"ed25519",byteLength:32},secp384r1:{name:"p384",byteLength:48},secp521r1:{name:"p521",byteLength:66}};function a(e){this.curveType=i[e],this.curveType||(this.curveType={name:e}),this.curve=new o.ec(this.curveType.name),this.keys=void 0}function s(e,t,n){Array.isArray(e)||(e=e.toArray());var o=new Buffer(e);if(n&&o.length=65&&n<=70?n-55:n>=97&&n<=102?n-87:n-48&15}function u(e,t,n){var o=s(e,n);return n-1>=t&&(o|=s(e,n-1)<<4),o}function c(e,t,n,o){for(var r=0,i=Math.min(e.length,n),a=t;a=49?s-49+10:s>=17?s-17+10:s}return r}i.isBN=function(e){return e instanceof i||null!==e&&"object"==typeof e&&e.constructor.wordSize===i.wordSize&&Array.isArray(e.words)},i.max=function(e,t){return e.cmp(t)>0?e:t},i.min=function(e,t){return e.cmp(t)<0?e:t},i.prototype._init=function(e,t,n){if("number"==typeof e)return this._initNumber(e,t,n);if("object"==typeof e)return this._initArray(e,t,n);"hex"===t&&(t=16),o(t===(0|t)&&t>=2&&t<=36);var r=0;"-"===(e=e.toString().replace(/\s+/g,""))[0]&&(r++,this.negative=1),r=0;r-=3)a=e[r]|e[r-1]<<8|e[r-2]<<16,this.words[i]|=a<>>26-s&67108863,(s+=24)>=26&&(s-=26,i++);else if("le"===n)for(r=0,i=0;r>>26-s&67108863,(s+=24)>=26&&(s-=26,i++);return this.strip()},i.prototype._parseHex=function(e,t,n){this.length=Math.ceil((e.length-t)/6),this.words=new Array(this.length);for(var o=0;o=t;o-=2)r=u(e,t,o)<=18?(i-=18,a+=1,this.words[a]|=r>>>26):i+=8;else for(o=(e.length-t)%2==0?t+1:t;o=18?(i-=18,a+=1,this.words[a]|=r>>>26):i+=8;this.strip()},i.prototype._parseBase=function(e,t,n){this.words=[0],this.length=1;for(var o=0,r=1;r<=67108863;r*=t)o++;o--,r=r/t|0;for(var i=e.length-n,a=i%o,s=Math.min(i,i-a)+n,u=0,l=n;l1&&0===this.words[this.length-1];)this.length--;return this._normSign()},i.prototype._normSign=function(){return 1===this.length&&0===this.words[0]&&(this.negative=0),this},i.prototype.inspect=function(){return(this.red?""};var l=["","0","00","000","0000","00000","000000","0000000","00000000","000000000","0000000000","00000000000","000000000000","0000000000000","00000000000000","000000000000000","0000000000000000","00000000000000000","000000000000000000","0000000000000000000","00000000000000000000","000000000000000000000","0000000000000000000000","00000000000000000000000","000000000000000000000000","0000000000000000000000000"],d=[0,0,25,16,12,11,10,9,8,8,7,7,7,7,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5],h=[0,0,33554432,43046721,16777216,48828125,60466176,40353607,16777216,43046721,1e7,19487171,35831808,62748517,7529536,11390625,16777216,24137569,34012224,47045881,64e6,4084101,5153632,6436343,7962624,9765625,11881376,14348907,17210368,20511149,243e5,28629151,33554432,39135393,45435424,52521875,60466176];function p(e,t,n){n.negative=t.negative^e.negative;var o=e.length+t.length|0;n.length=o,o=o-1|0;var r=0|e.words[0],i=0|t.words[0],a=r*i,s=67108863&a,u=a/67108864|0;n.words[0]=s;for(var c=1;c>>26,d=67108863&u,h=Math.min(c,t.length-1),p=Math.max(0,c-e.length+1);p<=h;p++){var f=c-p|0;l+=(a=(r=0|e.words[f])*(i=0|t.words[p])+d)/67108864|0,d=67108863&a}n.words[c]=0|d,u=0|l}return 0!==u?n.words[c]=0|u:n.length--,n.strip()}i.prototype.toString=function(e,t){var n;if(t=0|t||1,16===(e=e||10)||"hex"===e){n="";for(var r=0,i=0,a=0;a>>24-r&16777215)||a!==this.length-1?l[6-u.length]+u+n:u+n,(r+=2)>=26&&(r-=26,a--)}for(0!==i&&(n=i.toString(16)+n);n.length%t!=0;)n="0"+n;return 0!==this.negative&&(n="-"+n),n}if(e===(0|e)&&e>=2&&e<=36){var c=d[e],p=h[e];n="";var f=this.clone();for(f.negative=0;!f.isZero();){var g=f.modn(p).toString(e);n=(f=f.idivn(p)).isZero()?g+n:l[c-g.length]+g+n}for(this.isZero()&&(n="0"+n);n.length%t!=0;)n="0"+n;return 0!==this.negative&&(n="-"+n),n}o(!1,"Base should be between 2 and 36")},i.prototype.toNumber=function(){var e=this.words[0];return 2===this.length?e+=67108864*this.words[1]:3===this.length&&1===this.words[2]?e+=4503599627370496+67108864*this.words[1]:this.length>2&&o(!1,"Number can only safely store up to 53 bits"),0!==this.negative?-e:e},i.prototype.toJSON=function(){return this.toString(16)},i.prototype.toBuffer=function(e,t){return o(void 0!==a),this.toArrayLike(a,e,t)},i.prototype.toArray=function(e,t){return this.toArrayLike(Array,e,t)},i.prototype.toArrayLike=function(e,t,n){var r=this.byteLength(),i=n||Math.max(1,r);o(r<=i,"byte array longer than desired length"),o(i>0,"Requested array length <= 0"),this.strip();var a,s,u="le"===t,c=new e(i),l=this.clone();if(u){for(s=0;!l.isZero();s++)a=l.andln(255),l.iushrn(8),c[s]=a;for(;s=4096&&(n+=13,t>>>=13),t>=64&&(n+=7,t>>>=7),t>=8&&(n+=4,t>>>=4),t>=2&&(n+=2,t>>>=2),n+t},i.prototype._zeroBits=function(e){if(0===e)return 26;var t=e,n=0;return 0==(8191&t)&&(n+=13,t>>>=13),0==(127&t)&&(n+=7,t>>>=7),0==(15&t)&&(n+=4,t>>>=4),0==(3&t)&&(n+=2,t>>>=2),0==(1&t)&&n++,n},i.prototype.bitLength=function(){var e=this.words[this.length-1],t=this._countBits(e);return 26*(this.length-1)+t},i.prototype.zeroBits=function(){if(this.isZero())return 0;for(var e=0,t=0;te.length?this.clone().ior(e):e.clone().ior(this)},i.prototype.uor=function(e){return this.length>e.length?this.clone().iuor(e):e.clone().iuor(this)},i.prototype.iuand=function(e){var t;t=this.length>e.length?e:this;for(var n=0;ne.length?this.clone().iand(e):e.clone().iand(this)},i.prototype.uand=function(e){return this.length>e.length?this.clone().iuand(e):e.clone().iuand(this)},i.prototype.iuxor=function(e){var t,n;this.length>e.length?(t=this,n=e):(t=e,n=this);for(var o=0;oe.length?this.clone().ixor(e):e.clone().ixor(this)},i.prototype.uxor=function(e){return this.length>e.length?this.clone().iuxor(e):e.clone().iuxor(this)},i.prototype.inotn=function(e){o("number"==typeof e&&e>=0);var t=0|Math.ceil(e/26),n=e%26;this._expand(t),n>0&&t--;for(var r=0;r0&&(this.words[r]=~this.words[r]&67108863>>26-n),this.strip()},i.prototype.notn=function(e){return this.clone().inotn(e)},i.prototype.setn=function(e,t){o("number"==typeof e&&e>=0);var n=e/26|0,r=e%26;return this._expand(n+1),this.words[n]=t?this.words[n]|1<e.length?(n=this,o=e):(n=e,o=this);for(var r=0,i=0;i>>26;for(;0!==r&&i>>26;if(this.length=n.length,0!==r)this.words[this.length]=r,this.length++;else if(n!==this)for(;ie.length?this.clone().iadd(e):e.clone().iadd(this)},i.prototype.isub=function(e){if(0!==e.negative){e.negative=0;var t=this.iadd(e);return e.negative=1,t._normSign()}if(0!==this.negative)return this.negative=0,this.iadd(e),this.negative=1,this._normSign();var n,o,r=this.cmp(e);if(0===r)return this.negative=0,this.length=1,this.words[0]=0,this;r>0?(n=this,o=e):(n=e,o=this);for(var i=0,a=0;a>26,this.words[a]=67108863&t;for(;0!==i&&a>26,this.words[a]=67108863&t;if(0===i&&a>>13,p=0|a[1],f=8191&p,g=p>>>13,m=0|a[2],_=8191&m,F=m>>>13,y=0|a[3],b=8191&y,v=y>>>13,w=0|a[4],E=8191&w,k=w>>>13,D=0|a[5],S=8191&D,x=D>>>13,C=0|a[6],A=8191&C,T=C>>>13,R=0|a[7],I=8191&R,M=R>>>13,O=0|a[8],B=8191&O,N=O>>>13,L=0|a[9],P=8191&L,U=L>>>13,j=0|s[0],q=8191&j,z=j>>>13,K=0|s[1],G=8191&K,$=K>>>13,H=0|s[2],V=8191&H,W=H>>>13,Y=0|s[3],Z=8191&Y,X=Y>>>13,J=0|s[4],Q=8191&J,ee=J>>>13,te=0|s[5],ne=8191&te,oe=te>>>13,re=0|s[6],ie=8191&re,ae=re>>>13,se=0|s[7],ue=8191&se,ce=se>>>13,le=0|s[8],de=8191&le,he=le>>>13,pe=0|s[9],fe=8191&pe,ge=pe>>>13;n.negative=e.negative^t.negative,n.length=19;var me=(c+(o=Math.imul(d,q))|0)+((8191&(r=(r=Math.imul(d,z))+Math.imul(h,q)|0))<<13)|0;c=((i=Math.imul(h,z))+(r>>>13)|0)+(me>>>26)|0,me&=67108863,o=Math.imul(f,q),r=(r=Math.imul(f,z))+Math.imul(g,q)|0,i=Math.imul(g,z);var _e=(c+(o=o+Math.imul(d,G)|0)|0)+((8191&(r=(r=r+Math.imul(d,$)|0)+Math.imul(h,G)|0))<<13)|0;c=((i=i+Math.imul(h,$)|0)+(r>>>13)|0)+(_e>>>26)|0,_e&=67108863,o=Math.imul(_,q),r=(r=Math.imul(_,z))+Math.imul(F,q)|0,i=Math.imul(F,z),o=o+Math.imul(f,G)|0,r=(r=r+Math.imul(f,$)|0)+Math.imul(g,G)|0,i=i+Math.imul(g,$)|0;var Fe=(c+(o=o+Math.imul(d,V)|0)|0)+((8191&(r=(r=r+Math.imul(d,W)|0)+Math.imul(h,V)|0))<<13)|0;c=((i=i+Math.imul(h,W)|0)+(r>>>13)|0)+(Fe>>>26)|0,Fe&=67108863,o=Math.imul(b,q),r=(r=Math.imul(b,z))+Math.imul(v,q)|0,i=Math.imul(v,z),o=o+Math.imul(_,G)|0,r=(r=r+Math.imul(_,$)|0)+Math.imul(F,G)|0,i=i+Math.imul(F,$)|0,o=o+Math.imul(f,V)|0,r=(r=r+Math.imul(f,W)|0)+Math.imul(g,V)|0,i=i+Math.imul(g,W)|0;var ye=(c+(o=o+Math.imul(d,Z)|0)|0)+((8191&(r=(r=r+Math.imul(d,X)|0)+Math.imul(h,Z)|0))<<13)|0;c=((i=i+Math.imul(h,X)|0)+(r>>>13)|0)+(ye>>>26)|0,ye&=67108863,o=Math.imul(E,q),r=(r=Math.imul(E,z))+Math.imul(k,q)|0,i=Math.imul(k,z),o=o+Math.imul(b,G)|0,r=(r=r+Math.imul(b,$)|0)+Math.imul(v,G)|0,i=i+Math.imul(v,$)|0,o=o+Math.imul(_,V)|0,r=(r=r+Math.imul(_,W)|0)+Math.imul(F,V)|0,i=i+Math.imul(F,W)|0,o=o+Math.imul(f,Z)|0,r=(r=r+Math.imul(f,X)|0)+Math.imul(g,Z)|0,i=i+Math.imul(g,X)|0;var be=(c+(o=o+Math.imul(d,Q)|0)|0)+((8191&(r=(r=r+Math.imul(d,ee)|0)+Math.imul(h,Q)|0))<<13)|0;c=((i=i+Math.imul(h,ee)|0)+(r>>>13)|0)+(be>>>26)|0,be&=67108863,o=Math.imul(S,q),r=(r=Math.imul(S,z))+Math.imul(x,q)|0,i=Math.imul(x,z),o=o+Math.imul(E,G)|0,r=(r=r+Math.imul(E,$)|0)+Math.imul(k,G)|0,i=i+Math.imul(k,$)|0,o=o+Math.imul(b,V)|0,r=(r=r+Math.imul(b,W)|0)+Math.imul(v,V)|0,i=i+Math.imul(v,W)|0,o=o+Math.imul(_,Z)|0,r=(r=r+Math.imul(_,X)|0)+Math.imul(F,Z)|0,i=i+Math.imul(F,X)|0,o=o+Math.imul(f,Q)|0,r=(r=r+Math.imul(f,ee)|0)+Math.imul(g,Q)|0,i=i+Math.imul(g,ee)|0;var ve=(c+(o=o+Math.imul(d,ne)|0)|0)+((8191&(r=(r=r+Math.imul(d,oe)|0)+Math.imul(h,ne)|0))<<13)|0;c=((i=i+Math.imul(h,oe)|0)+(r>>>13)|0)+(ve>>>26)|0,ve&=67108863,o=Math.imul(A,q),r=(r=Math.imul(A,z))+Math.imul(T,q)|0,i=Math.imul(T,z),o=o+Math.imul(S,G)|0,r=(r=r+Math.imul(S,$)|0)+Math.imul(x,G)|0,i=i+Math.imul(x,$)|0,o=o+Math.imul(E,V)|0,r=(r=r+Math.imul(E,W)|0)+Math.imul(k,V)|0,i=i+Math.imul(k,W)|0,o=o+Math.imul(b,Z)|0,r=(r=r+Math.imul(b,X)|0)+Math.imul(v,Z)|0,i=i+Math.imul(v,X)|0,o=o+Math.imul(_,Q)|0,r=(r=r+Math.imul(_,ee)|0)+Math.imul(F,Q)|0,i=i+Math.imul(F,ee)|0,o=o+Math.imul(f,ne)|0,r=(r=r+Math.imul(f,oe)|0)+Math.imul(g,ne)|0,i=i+Math.imul(g,oe)|0;var we=(c+(o=o+Math.imul(d,ie)|0)|0)+((8191&(r=(r=r+Math.imul(d,ae)|0)+Math.imul(h,ie)|0))<<13)|0;c=((i=i+Math.imul(h,ae)|0)+(r>>>13)|0)+(we>>>26)|0,we&=67108863,o=Math.imul(I,q),r=(r=Math.imul(I,z))+Math.imul(M,q)|0,i=Math.imul(M,z),o=o+Math.imul(A,G)|0,r=(r=r+Math.imul(A,$)|0)+Math.imul(T,G)|0,i=i+Math.imul(T,$)|0,o=o+Math.imul(S,V)|0,r=(r=r+Math.imul(S,W)|0)+Math.imul(x,V)|0,i=i+Math.imul(x,W)|0,o=o+Math.imul(E,Z)|0,r=(r=r+Math.imul(E,X)|0)+Math.imul(k,Z)|0,i=i+Math.imul(k,X)|0,o=o+Math.imul(b,Q)|0,r=(r=r+Math.imul(b,ee)|0)+Math.imul(v,Q)|0,i=i+Math.imul(v,ee)|0,o=o+Math.imul(_,ne)|0,r=(r=r+Math.imul(_,oe)|0)+Math.imul(F,ne)|0,i=i+Math.imul(F,oe)|0,o=o+Math.imul(f,ie)|0,r=(r=r+Math.imul(f,ae)|0)+Math.imul(g,ie)|0,i=i+Math.imul(g,ae)|0;var Ee=(c+(o=o+Math.imul(d,ue)|0)|0)+((8191&(r=(r=r+Math.imul(d,ce)|0)+Math.imul(h,ue)|0))<<13)|0;c=((i=i+Math.imul(h,ce)|0)+(r>>>13)|0)+(Ee>>>26)|0,Ee&=67108863,o=Math.imul(B,q),r=(r=Math.imul(B,z))+Math.imul(N,q)|0,i=Math.imul(N,z),o=o+Math.imul(I,G)|0,r=(r=r+Math.imul(I,$)|0)+Math.imul(M,G)|0,i=i+Math.imul(M,$)|0,o=o+Math.imul(A,V)|0,r=(r=r+Math.imul(A,W)|0)+Math.imul(T,V)|0,i=i+Math.imul(T,W)|0,o=o+Math.imul(S,Z)|0,r=(r=r+Math.imul(S,X)|0)+Math.imul(x,Z)|0,i=i+Math.imul(x,X)|0,o=o+Math.imul(E,Q)|0,r=(r=r+Math.imul(E,ee)|0)+Math.imul(k,Q)|0,i=i+Math.imul(k,ee)|0,o=o+Math.imul(b,ne)|0,r=(r=r+Math.imul(b,oe)|0)+Math.imul(v,ne)|0,i=i+Math.imul(v,oe)|0,o=o+Math.imul(_,ie)|0,r=(r=r+Math.imul(_,ae)|0)+Math.imul(F,ie)|0,i=i+Math.imul(F,ae)|0,o=o+Math.imul(f,ue)|0,r=(r=r+Math.imul(f,ce)|0)+Math.imul(g,ue)|0,i=i+Math.imul(g,ce)|0;var ke=(c+(o=o+Math.imul(d,de)|0)|0)+((8191&(r=(r=r+Math.imul(d,he)|0)+Math.imul(h,de)|0))<<13)|0;c=((i=i+Math.imul(h,he)|0)+(r>>>13)|0)+(ke>>>26)|0,ke&=67108863,o=Math.imul(P,q),r=(r=Math.imul(P,z))+Math.imul(U,q)|0,i=Math.imul(U,z),o=o+Math.imul(B,G)|0,r=(r=r+Math.imul(B,$)|0)+Math.imul(N,G)|0,i=i+Math.imul(N,$)|0,o=o+Math.imul(I,V)|0,r=(r=r+Math.imul(I,W)|0)+Math.imul(M,V)|0,i=i+Math.imul(M,W)|0,o=o+Math.imul(A,Z)|0,r=(r=r+Math.imul(A,X)|0)+Math.imul(T,Z)|0,i=i+Math.imul(T,X)|0,o=o+Math.imul(S,Q)|0,r=(r=r+Math.imul(S,ee)|0)+Math.imul(x,Q)|0,i=i+Math.imul(x,ee)|0,o=o+Math.imul(E,ne)|0,r=(r=r+Math.imul(E,oe)|0)+Math.imul(k,ne)|0,i=i+Math.imul(k,oe)|0,o=o+Math.imul(b,ie)|0,r=(r=r+Math.imul(b,ae)|0)+Math.imul(v,ie)|0,i=i+Math.imul(v,ae)|0,o=o+Math.imul(_,ue)|0,r=(r=r+Math.imul(_,ce)|0)+Math.imul(F,ue)|0,i=i+Math.imul(F,ce)|0,o=o+Math.imul(f,de)|0,r=(r=r+Math.imul(f,he)|0)+Math.imul(g,de)|0,i=i+Math.imul(g,he)|0;var De=(c+(o=o+Math.imul(d,fe)|0)|0)+((8191&(r=(r=r+Math.imul(d,ge)|0)+Math.imul(h,fe)|0))<<13)|0;c=((i=i+Math.imul(h,ge)|0)+(r>>>13)|0)+(De>>>26)|0,De&=67108863,o=Math.imul(P,G),r=(r=Math.imul(P,$))+Math.imul(U,G)|0,i=Math.imul(U,$),o=o+Math.imul(B,V)|0,r=(r=r+Math.imul(B,W)|0)+Math.imul(N,V)|0,i=i+Math.imul(N,W)|0,o=o+Math.imul(I,Z)|0,r=(r=r+Math.imul(I,X)|0)+Math.imul(M,Z)|0,i=i+Math.imul(M,X)|0,o=o+Math.imul(A,Q)|0,r=(r=r+Math.imul(A,ee)|0)+Math.imul(T,Q)|0,i=i+Math.imul(T,ee)|0,o=o+Math.imul(S,ne)|0,r=(r=r+Math.imul(S,oe)|0)+Math.imul(x,ne)|0,i=i+Math.imul(x,oe)|0,o=o+Math.imul(E,ie)|0,r=(r=r+Math.imul(E,ae)|0)+Math.imul(k,ie)|0,i=i+Math.imul(k,ae)|0,o=o+Math.imul(b,ue)|0,r=(r=r+Math.imul(b,ce)|0)+Math.imul(v,ue)|0,i=i+Math.imul(v,ce)|0,o=o+Math.imul(_,de)|0,r=(r=r+Math.imul(_,he)|0)+Math.imul(F,de)|0,i=i+Math.imul(F,he)|0;var Se=(c+(o=o+Math.imul(f,fe)|0)|0)+((8191&(r=(r=r+Math.imul(f,ge)|0)+Math.imul(g,fe)|0))<<13)|0;c=((i=i+Math.imul(g,ge)|0)+(r>>>13)|0)+(Se>>>26)|0,Se&=67108863,o=Math.imul(P,V),r=(r=Math.imul(P,W))+Math.imul(U,V)|0,i=Math.imul(U,W),o=o+Math.imul(B,Z)|0,r=(r=r+Math.imul(B,X)|0)+Math.imul(N,Z)|0,i=i+Math.imul(N,X)|0,o=o+Math.imul(I,Q)|0,r=(r=r+Math.imul(I,ee)|0)+Math.imul(M,Q)|0,i=i+Math.imul(M,ee)|0,o=o+Math.imul(A,ne)|0,r=(r=r+Math.imul(A,oe)|0)+Math.imul(T,ne)|0,i=i+Math.imul(T,oe)|0,o=o+Math.imul(S,ie)|0,r=(r=r+Math.imul(S,ae)|0)+Math.imul(x,ie)|0,i=i+Math.imul(x,ae)|0,o=o+Math.imul(E,ue)|0,r=(r=r+Math.imul(E,ce)|0)+Math.imul(k,ue)|0,i=i+Math.imul(k,ce)|0,o=o+Math.imul(b,de)|0,r=(r=r+Math.imul(b,he)|0)+Math.imul(v,de)|0,i=i+Math.imul(v,he)|0;var xe=(c+(o=o+Math.imul(_,fe)|0)|0)+((8191&(r=(r=r+Math.imul(_,ge)|0)+Math.imul(F,fe)|0))<<13)|0;c=((i=i+Math.imul(F,ge)|0)+(r>>>13)|0)+(xe>>>26)|0,xe&=67108863,o=Math.imul(P,Z),r=(r=Math.imul(P,X))+Math.imul(U,Z)|0,i=Math.imul(U,X),o=o+Math.imul(B,Q)|0,r=(r=r+Math.imul(B,ee)|0)+Math.imul(N,Q)|0,i=i+Math.imul(N,ee)|0,o=o+Math.imul(I,ne)|0,r=(r=r+Math.imul(I,oe)|0)+Math.imul(M,ne)|0,i=i+Math.imul(M,oe)|0,o=o+Math.imul(A,ie)|0,r=(r=r+Math.imul(A,ae)|0)+Math.imul(T,ie)|0,i=i+Math.imul(T,ae)|0,o=o+Math.imul(S,ue)|0,r=(r=r+Math.imul(S,ce)|0)+Math.imul(x,ue)|0,i=i+Math.imul(x,ce)|0,o=o+Math.imul(E,de)|0,r=(r=r+Math.imul(E,he)|0)+Math.imul(k,de)|0,i=i+Math.imul(k,he)|0;var Ce=(c+(o=o+Math.imul(b,fe)|0)|0)+((8191&(r=(r=r+Math.imul(b,ge)|0)+Math.imul(v,fe)|0))<<13)|0;c=((i=i+Math.imul(v,ge)|0)+(r>>>13)|0)+(Ce>>>26)|0,Ce&=67108863,o=Math.imul(P,Q),r=(r=Math.imul(P,ee))+Math.imul(U,Q)|0,i=Math.imul(U,ee),o=o+Math.imul(B,ne)|0,r=(r=r+Math.imul(B,oe)|0)+Math.imul(N,ne)|0,i=i+Math.imul(N,oe)|0,o=o+Math.imul(I,ie)|0,r=(r=r+Math.imul(I,ae)|0)+Math.imul(M,ie)|0,i=i+Math.imul(M,ae)|0,o=o+Math.imul(A,ue)|0,r=(r=r+Math.imul(A,ce)|0)+Math.imul(T,ue)|0,i=i+Math.imul(T,ce)|0,o=o+Math.imul(S,de)|0,r=(r=r+Math.imul(S,he)|0)+Math.imul(x,de)|0,i=i+Math.imul(x,he)|0;var Ae=(c+(o=o+Math.imul(E,fe)|0)|0)+((8191&(r=(r=r+Math.imul(E,ge)|0)+Math.imul(k,fe)|0))<<13)|0;c=((i=i+Math.imul(k,ge)|0)+(r>>>13)|0)+(Ae>>>26)|0,Ae&=67108863,o=Math.imul(P,ne),r=(r=Math.imul(P,oe))+Math.imul(U,ne)|0,i=Math.imul(U,oe),o=o+Math.imul(B,ie)|0,r=(r=r+Math.imul(B,ae)|0)+Math.imul(N,ie)|0,i=i+Math.imul(N,ae)|0,o=o+Math.imul(I,ue)|0,r=(r=r+Math.imul(I,ce)|0)+Math.imul(M,ue)|0,i=i+Math.imul(M,ce)|0,o=o+Math.imul(A,de)|0,r=(r=r+Math.imul(A,he)|0)+Math.imul(T,de)|0,i=i+Math.imul(T,he)|0;var Te=(c+(o=o+Math.imul(S,fe)|0)|0)+((8191&(r=(r=r+Math.imul(S,ge)|0)+Math.imul(x,fe)|0))<<13)|0;c=((i=i+Math.imul(x,ge)|0)+(r>>>13)|0)+(Te>>>26)|0,Te&=67108863,o=Math.imul(P,ie),r=(r=Math.imul(P,ae))+Math.imul(U,ie)|0,i=Math.imul(U,ae),o=o+Math.imul(B,ue)|0,r=(r=r+Math.imul(B,ce)|0)+Math.imul(N,ue)|0,i=i+Math.imul(N,ce)|0,o=o+Math.imul(I,de)|0,r=(r=r+Math.imul(I,he)|0)+Math.imul(M,de)|0,i=i+Math.imul(M,he)|0;var Re=(c+(o=o+Math.imul(A,fe)|0)|0)+((8191&(r=(r=r+Math.imul(A,ge)|0)+Math.imul(T,fe)|0))<<13)|0;c=((i=i+Math.imul(T,ge)|0)+(r>>>13)|0)+(Re>>>26)|0,Re&=67108863,o=Math.imul(P,ue),r=(r=Math.imul(P,ce))+Math.imul(U,ue)|0,i=Math.imul(U,ce),o=o+Math.imul(B,de)|0,r=(r=r+Math.imul(B,he)|0)+Math.imul(N,de)|0,i=i+Math.imul(N,he)|0;var Ie=(c+(o=o+Math.imul(I,fe)|0)|0)+((8191&(r=(r=r+Math.imul(I,ge)|0)+Math.imul(M,fe)|0))<<13)|0;c=((i=i+Math.imul(M,ge)|0)+(r>>>13)|0)+(Ie>>>26)|0,Ie&=67108863,o=Math.imul(P,de),r=(r=Math.imul(P,he))+Math.imul(U,de)|0,i=Math.imul(U,he);var Me=(c+(o=o+Math.imul(B,fe)|0)|0)+((8191&(r=(r=r+Math.imul(B,ge)|0)+Math.imul(N,fe)|0))<<13)|0;c=((i=i+Math.imul(N,ge)|0)+(r>>>13)|0)+(Me>>>26)|0,Me&=67108863;var Oe=(c+(o=Math.imul(P,fe))|0)+((8191&(r=(r=Math.imul(P,ge))+Math.imul(U,fe)|0))<<13)|0;return c=((i=Math.imul(U,ge))+(r>>>13)|0)+(Oe>>>26)|0,Oe&=67108863,u[0]=me,u[1]=_e,u[2]=Fe,u[3]=ye,u[4]=be,u[5]=ve,u[6]=we,u[7]=Ee,u[8]=ke,u[9]=De,u[10]=Se,u[11]=xe,u[12]=Ce,u[13]=Ae,u[14]=Te,u[15]=Re,u[16]=Ie,u[17]=Me,u[18]=Oe,0!==c&&(u[19]=c,n.length++),n};function g(e,t,n){return(new m).mulp(e,t,n)}function m(e,t){this.x=e,this.y=t}Math.imul||(f=p),i.prototype.mulTo=function(e,t){var n=this.length+e.length;return 10===this.length&&10===e.length?f(this,e,t):n<63?p(this,e,t):n<1024?function(e,t,n){n.negative=t.negative^e.negative,n.length=e.length+t.length;for(var o=0,r=0,i=0;i>>26)|0)>>>26,a&=67108863}n.words[i]=s,o=a,a=r}return 0!==o?n.words[i]=o:n.length--,n.strip()}(this,e,t):g(this,e,t)},m.prototype.makeRBT=function(e){for(var t=new Array(e),n=i.prototype._countBits(e)-1,o=0;o>=1;return o},m.prototype.permute=function(e,t,n,o,r,i){for(var a=0;a>>=1)r++;return 1<>>=13,n[2*a+1]=8191&i,i>>>=13;for(a=2*t;a>=26,t+=r/67108864|0,t+=i>>>26,this.words[n]=67108863&i}return 0!==t&&(this.words[n]=t,this.length++),this},i.prototype.muln=function(e){return this.clone().imuln(e)},i.prototype.sqr=function(){return this.mul(this)},i.prototype.isqr=function(){return this.imul(this.clone())},i.prototype.pow=function(e){var t=function(e){for(var t=new Array(e.bitLength()),n=0;n>>r}return t}(e);if(0===t.length)return new i(1);for(var n=this,o=0;o=0);var t,n=e%26,r=(e-n)/26,i=67108863>>>26-n<<26-n;if(0!==n){var a=0;for(t=0;t>>26-n}a&&(this.words[t]=a,this.length++)}if(0!==r){for(t=this.length-1;t>=0;t--)this.words[t+r]=this.words[t];for(t=0;t=0),r=t?(t-t%26)/26:0;var i=e%26,a=Math.min((e-i)/26,this.length),s=67108863^67108863>>>i<a)for(this.length-=a,c=0;c=0&&(0!==l||c>=r);c--){var d=0|this.words[c];this.words[c]=l<<26-i|d>>>i,l=d&s}return u&&0!==l&&(u.words[u.length++]=l),0===this.length&&(this.words[0]=0,this.length=1),this.strip()},i.prototype.ishrn=function(e,t,n){return o(0===this.negative),this.iushrn(e,t,n)},i.prototype.shln=function(e){return this.clone().ishln(e)},i.prototype.ushln=function(e){return this.clone().iushln(e)},i.prototype.shrn=function(e){return this.clone().ishrn(e)},i.prototype.ushrn=function(e){return this.clone().iushrn(e)},i.prototype.testn=function(e){o("number"==typeof e&&e>=0);var t=e%26,n=(e-t)/26,r=1<=0);var t=e%26,n=(e-t)/26;if(o(0===this.negative,"imaskn works only with positive numbers"),this.length<=n)return this;if(0!==t&&n++,this.length=Math.min(n,this.length),0!==t){var r=67108863^67108863>>>t<=67108864;t++)this.words[t]-=67108864,t===this.length-1?this.words[t+1]=1:this.words[t+1]++;return this.length=Math.max(this.length,t+1),this},i.prototype.isubn=function(e){if(o("number"==typeof e),o(e<67108864),e<0)return this.iaddn(-e);if(0!==this.negative)return this.negative=0,this.iaddn(e),this.negative=1,this;if(this.words[0]-=e,1===this.length&&this.words[0]<0)this.words[0]=-this.words[0],this.negative=1;else for(var t=0;t>26)-(u/67108864|0),this.words[r+n]=67108863&i}for(;r>26,this.words[r+n]=67108863&i;if(0===s)return this.strip();for(o(-1===s),s=0,r=0;r>26,this.words[r]=67108863&i;return this.negative=1,this.strip()},i.prototype._wordDiv=function(e,t){var n=(this.length,e.length),o=this.clone(),r=e,a=0|r.words[r.length-1];0!=(n=26-this._countBits(a))&&(r=r.ushln(n),o.iushln(n),a=0|r.words[r.length-1]);var s,u=o.length-r.length;if("mod"!==t){(s=new i(null)).length=u+1,s.words=new Array(s.length);for(var c=0;c=0;d--){var h=67108864*(0|o.words[r.length+d])+(0|o.words[r.length+d-1]);for(h=Math.min(h/a|0,67108863),o._ishlnsubmul(r,h,d);0!==o.negative;)h--,o.negative=0,o._ishlnsubmul(r,1,d),o.isZero()||(o.negative^=1);s&&(s.words[d]=h)}return s&&s.strip(),o.strip(),"div"!==t&&0!==n&&o.iushrn(n),{div:s||null,mod:o}},i.prototype.divmod=function(e,t,n){return o(!e.isZero()),this.isZero()?{div:new i(0),mod:new i(0)}:0!==this.negative&&0===e.negative?(s=this.neg().divmod(e,t),"mod"!==t&&(r=s.div.neg()),"div"!==t&&(a=s.mod.neg(),n&&0!==a.negative&&a.iadd(e)),{div:r,mod:a}):0===this.negative&&0!==e.negative?(s=this.divmod(e.neg(),t),"mod"!==t&&(r=s.div.neg()),{div:r,mod:s.mod}):0!=(this.negative&e.negative)?(s=this.neg().divmod(e.neg(),t),"div"!==t&&(a=s.mod.neg(),n&&0!==a.negative&&a.isub(e)),{div:s.div,mod:a}):e.length>this.length||this.cmp(e)<0?{div:new i(0),mod:this}:1===e.length?"div"===t?{div:this.divn(e.words[0]),mod:null}:"mod"===t?{div:null,mod:new i(this.modn(e.words[0]))}:{div:this.divn(e.words[0]),mod:new i(this.modn(e.words[0]))}:this._wordDiv(e,t);var r,a,s},i.prototype.div=function(e){return this.divmod(e,"div",!1).div},i.prototype.mod=function(e){return this.divmod(e,"mod",!1).mod},i.prototype.umod=function(e){return this.divmod(e,"mod",!0).mod},i.prototype.divRound=function(e){var t=this.divmod(e);if(t.mod.isZero())return t.div;var n=0!==t.div.negative?t.mod.isub(e):t.mod,o=e.ushrn(1),r=e.andln(1),i=n.cmp(o);return i<0||1===r&&0===i?t.div:0!==t.div.negative?t.div.isubn(1):t.div.iaddn(1)},i.prototype.modn=function(e){o(e<=67108863);for(var t=(1<<26)%e,n=0,r=this.length-1;r>=0;r--)n=(t*n+(0|this.words[r]))%e;return n},i.prototype.idivn=function(e){o(e<=67108863);for(var t=0,n=this.length-1;n>=0;n--){var r=(0|this.words[n])+67108864*t;this.words[n]=r/e|0,t=r%e}return this.strip()},i.prototype.divn=function(e){return this.clone().idivn(e)},i.prototype.egcd=function(e){o(0===e.negative),o(!e.isZero());var t=this,n=e.clone();t=0!==t.negative?t.umod(e):t.clone();for(var r=new i(1),a=new i(0),s=new i(0),u=new i(1),c=0;t.isEven()&&n.isEven();)t.iushrn(1),n.iushrn(1),++c;for(var l=n.clone(),d=t.clone();!t.isZero();){for(var h=0,p=1;0==(t.words[0]&p)&&h<26;++h,p<<=1);if(h>0)for(t.iushrn(h);h-- >0;)(r.isOdd()||a.isOdd())&&(r.iadd(l),a.isub(d)),r.iushrn(1),a.iushrn(1);for(var f=0,g=1;0==(n.words[0]&g)&&f<26;++f,g<<=1);if(f>0)for(n.iushrn(f);f-- >0;)(s.isOdd()||u.isOdd())&&(s.iadd(l),u.isub(d)),s.iushrn(1),u.iushrn(1);t.cmp(n)>=0?(t.isub(n),r.isub(s),a.isub(u)):(n.isub(t),s.isub(r),u.isub(a))}return{a:s,b:u,gcd:n.iushln(c)}},i.prototype._invmp=function(e){o(0===e.negative),o(!e.isZero());var t=this,n=e.clone();t=0!==t.negative?t.umod(e):t.clone();for(var r,a=new i(1),s=new i(0),u=n.clone();t.cmpn(1)>0&&n.cmpn(1)>0;){for(var c=0,l=1;0==(t.words[0]&l)&&c<26;++c,l<<=1);if(c>0)for(t.iushrn(c);c-- >0;)a.isOdd()&&a.iadd(u),a.iushrn(1);for(var d=0,h=1;0==(n.words[0]&h)&&d<26;++d,h<<=1);if(d>0)for(n.iushrn(d);d-- >0;)s.isOdd()&&s.iadd(u),s.iushrn(1);t.cmp(n)>=0?(t.isub(n),a.isub(s)):(n.isub(t),s.isub(a))}return(r=0===t.cmpn(1)?a:s).cmpn(0)<0&&r.iadd(e),r},i.prototype.gcd=function(e){if(this.isZero())return e.abs();if(e.isZero())return this.abs();var t=this.clone(),n=e.clone();t.negative=0,n.negative=0;for(var o=0;t.isEven()&&n.isEven();o++)t.iushrn(1),n.iushrn(1);for(;;){for(;t.isEven();)t.iushrn(1);for(;n.isEven();)n.iushrn(1);var r=t.cmp(n);if(r<0){var i=t;t=n,n=i}else if(0===r||0===n.cmpn(1))break;t.isub(n)}return n.iushln(o)},i.prototype.invm=function(e){return this.egcd(e).a.umod(e)},i.prototype.isEven=function(){return 0==(1&this.words[0])},i.prototype.isOdd=function(){return 1==(1&this.words[0])},i.prototype.andln=function(e){return this.words[0]&e},i.prototype.bincn=function(e){o("number"==typeof e);var t=e%26,n=(e-t)/26,r=1<>>26,s&=67108863,this.words[a]=s}return 0!==i&&(this.words[a]=i,this.length++),this},i.prototype.isZero=function(){return 1===this.length&&0===this.words[0]},i.prototype.cmpn=function(e){var t,n=e<0;if(0!==this.negative&&!n)return-1;if(0===this.negative&&n)return 1;if(this.strip(),this.length>1)t=1;else{n&&(e=-e),o(e<=67108863,"Number is too big");var r=0|this.words[0];t=r===e?0:re.length)return 1;if(this.length=0;n--){var o=0|this.words[n],r=0|e.words[n];if(o!==r){or&&(t=1);break}}return t},i.prototype.gtn=function(e){return 1===this.cmpn(e)},i.prototype.gt=function(e){return 1===this.cmp(e)},i.prototype.gten=function(e){return this.cmpn(e)>=0},i.prototype.gte=function(e){return this.cmp(e)>=0},i.prototype.ltn=function(e){return-1===this.cmpn(e)},i.prototype.lt=function(e){return-1===this.cmp(e)},i.prototype.lten=function(e){return this.cmpn(e)<=0},i.prototype.lte=function(e){return this.cmp(e)<=0},i.prototype.eqn=function(e){return 0===this.cmpn(e)},i.prototype.eq=function(e){return 0===this.cmp(e)},i.red=function(e){return new E(e)},i.prototype.toRed=function(e){return o(!this.red,"Already a number in reduction context"),o(0===this.negative,"red works only with positives"),e.convertTo(this)._forceRed(e)},i.prototype.fromRed=function(){return o(this.red,"fromRed works only with numbers in reduction context"),this.red.convertFrom(this)},i.prototype._forceRed=function(e){return this.red=e,this},i.prototype.forceRed=function(e){return o(!this.red,"Already a number in reduction context"),this._forceRed(e)},i.prototype.redAdd=function(e){return o(this.red,"redAdd works only with red numbers"),this.red.add(this,e)},i.prototype.redIAdd=function(e){return o(this.red,"redIAdd works only with red numbers"),this.red.iadd(this,e)},i.prototype.redSub=function(e){return o(this.red,"redSub works only with red numbers"),this.red.sub(this,e)},i.prototype.redISub=function(e){return o(this.red,"redISub works only with red numbers"),this.red.isub(this,e)},i.prototype.redShl=function(e){return o(this.red,"redShl works only with red numbers"),this.red.shl(this,e)},i.prototype.redMul=function(e){return o(this.red,"redMul works only with red numbers"),this.red._verify2(this,e),this.red.mul(this,e)},i.prototype.redIMul=function(e){return o(this.red,"redMul works only with red numbers"),this.red._verify2(this,e),this.red.imul(this,e)},i.prototype.redSqr=function(){return o(this.red,"redSqr works only with red numbers"),this.red._verify1(this),this.red.sqr(this)},i.prototype.redISqr=function(){return o(this.red,"redISqr works only with red numbers"),this.red._verify1(this),this.red.isqr(this)},i.prototype.redSqrt=function(){return o(this.red,"redSqrt works only with red numbers"),this.red._verify1(this),this.red.sqrt(this)},i.prototype.redInvm=function(){return o(this.red,"redInvm works only with red numbers"),this.red._verify1(this),this.red.invm(this)},i.prototype.redNeg=function(){return o(this.red,"redNeg works only with red numbers"),this.red._verify1(this),this.red.neg(this)},i.prototype.redPow=function(e){return o(this.red&&!e.red,"redPow(normalNum)"),this.red._verify1(this),this.red.pow(this,e)};var _={k256:null,p224:null,p192:null,p25519:null};function F(e,t){this.name=e,this.p=new i(t,16),this.n=this.p.bitLength(),this.k=new i(1).iushln(this.n).isub(this.p),this.tmp=this._tmp()}function y(){F.call(this,"k256","ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f")}function b(){F.call(this,"p224","ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001")}function v(){F.call(this,"p192","ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff")}function w(){F.call(this,"25519","7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed")}function E(e){if("string"==typeof e){var t=i._prime(e);this.m=t.p,this.prime=t}else o(e.gtn(1),"modulus must be greater than 1"),this.m=e,this.prime=null}function k(e){E.call(this,e),this.shift=this.m.bitLength(),this.shift%26!=0&&(this.shift+=26-this.shift%26),this.r=new i(1).iushln(this.shift),this.r2=this.imod(this.r.sqr()),this.rinv=this.r._invmp(this.m),this.minv=this.rinv.mul(this.r).isubn(1).div(this.m),this.minv=this.minv.umod(this.r),this.minv=this.r.sub(this.minv)}F.prototype._tmp=function(){var e=new i(null);return e.words=new Array(Math.ceil(this.n/13)),e},F.prototype.ireduce=function(e){var t,n=e;do{this.split(n,this.tmp),t=(n=(n=this.imulK(n)).iadd(this.tmp)).bitLength()}while(t>this.n);var o=t0?n.isub(this.p):void 0!==n.strip?n.strip():n._strip(),n},F.prototype.split=function(e,t){e.iushrn(this.n,0,t)},F.prototype.imulK=function(e){return e.imul(this.k)},r(y,F),y.prototype.split=function(e,t){for(var n=4194303,o=Math.min(e.length,9),r=0;r>>22,i=a}i>>>=22,e.words[r-10]=i,0===i&&e.length>10?e.length-=10:e.length-=9},y.prototype.imulK=function(e){e.words[e.length]=0,e.words[e.length+1]=0,e.length+=2;for(var t=0,n=0;n>>=26,e.words[n]=r,t=o}return 0!==t&&(e.words[e.length++]=t),e},i._prime=function(e){if(_[e])return _[e];var t;if("k256"===e)t=new y;else if("p224"===e)t=new b;else if("p192"===e)t=new v;else{if("p25519"!==e)throw new Error("Unknown prime "+e);t=new w}return _[e]=t,t},E.prototype._verify1=function(e){o(0===e.negative,"red works only with positives"),o(e.red,"red works only with red numbers")},E.prototype._verify2=function(e,t){o(0==(e.negative|t.negative),"red works only with positives"),o(e.red&&e.red===t.red,"red works only with red numbers")},E.prototype.imod=function(e){return this.prime?this.prime.ireduce(e)._forceRed(this):e.umod(this.m)._forceRed(this)},E.prototype.neg=function(e){return e.isZero()?e.clone():this.m.sub(e)._forceRed(this)},E.prototype.add=function(e,t){this._verify2(e,t);var n=e.add(t);return n.cmp(this.m)>=0&&n.isub(this.m),n._forceRed(this)},E.prototype.iadd=function(e,t){this._verify2(e,t);var n=e.iadd(t);return n.cmp(this.m)>=0&&n.isub(this.m),n},E.prototype.sub=function(e,t){this._verify2(e,t);var n=e.sub(t);return n.cmpn(0)<0&&n.iadd(this.m),n._forceRed(this)},E.prototype.isub=function(e,t){this._verify2(e,t);var n=e.isub(t);return n.cmpn(0)<0&&n.iadd(this.m),n},E.prototype.shl=function(e,t){return this._verify1(e),this.imod(e.ushln(t))},E.prototype.imul=function(e,t){return this._verify2(e,t),this.imod(e.imul(t))},E.prototype.mul=function(e,t){return this._verify2(e,t),this.imod(e.mul(t))},E.prototype.isqr=function(e){return this.imul(e,e.clone())},E.prototype.sqr=function(e){return this.mul(e,e)},E.prototype.sqrt=function(e){if(e.isZero())return e.clone();var t=this.m.andln(3);if(o(t%2==1),3===t){var n=this.m.add(new i(1)).iushrn(2);return this.pow(e,n)}for(var r=this.m.subn(1),a=0;!r.isZero()&&0===r.andln(1);)a++,r.iushrn(1);o(!r.isZero());var s=new i(1).toRed(this),u=s.redNeg(),c=this.m.subn(1).iushrn(1),l=this.m.bitLength();for(l=new i(2*l*l).toRed(this);0!==this.pow(l,c).cmp(u);)l.redIAdd(u);for(var d=this.pow(l,r),h=this.pow(e,r.addn(1).iushrn(1)),p=this.pow(e,r),f=a;0!==p.cmp(s);){for(var g=p,m=0;0!==g.cmp(s);m++)g=g.redSqr();o(m=0;o--){for(var c=t.words[o],l=u-1;l>=0;l--){var d=c>>l&1;r!==n[0]&&(r=this.sqr(r)),0!==d||0!==a?(a<<=1,a|=d,(4==++s||0===o&&0===l)&&(r=this.mul(r,n[a]),s=0,a=0)):s=0}u=26}return r},E.prototype.convertTo=function(e){var t=e.umod(this.m);return t===e?t.clone():t},E.prototype.convertFrom=function(e){var t=e.clone();return t.red=null,t},i.mont=function(e){return new k(e)},r(k,E),k.prototype.convertTo=function(e){return this.imod(e.ushln(this.shift))},k.prototype.convertFrom=function(e){var t=this.imod(e.mul(this.rinv));return t.red=null,t},k.prototype.imul=function(e,t){if(e.isZero()||t.isZero())return e.words[0]=0,e.length=1,e;var n=e.imul(t),o=n.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m),r=n.isub(o).iushrn(this.shift),i=r;return r.cmp(this.m)>=0?i=r.isub(this.m):r.cmpn(0)<0&&(i=r.iadd(this.m)),i._forceRed(this)},k.prototype.mul=function(e,t){if(e.isZero()||t.isZero())return new i(0)._forceRed(this);var n=e.mul(t),o=n.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m),r=n.isub(o).iushrn(this.shift),a=r;return r.cmp(this.m)>=0?a=r.isub(this.m):r.cmpn(0)<0&&(a=r.iadd(this.m)),a._forceRed(this)},k.prototype.invm=function(e){return this.imod(e._invmp(this.m).mul(this.r2))._forceRed(this)}}(e=n.nmd(e),this)},23482:(e,t,n)=>{"use strict";var o=n(35717),r=n(62318),i=n(79785),a=n(89072),s=n(71027);function u(e){s.call(this,"digest"),this._hash=e}o(u,s),u.prototype._update=function(e){this._hash.update(e)},u.prototype._final=function(){return this._hash.digest()},e.exports=function(e){return"md5"===(e=e.toLowerCase())?new r:"rmd160"===e||"ripemd160"===e?new i:new u(a(e))}},78028:(e,t,n)=>{var o=n(62318);e.exports=function(e){return(new o).update(e).digest()}},58355:(e,t,n)=>{"use strict";var o=n(35717),r=n(51031),i=n(71027),a=n(89509).Buffer,s=n(78028),u=n(79785),c=n(89072),l=a.alloc(128);function d(e,t){i.call(this,"digest"),"string"==typeof t&&(t=a.from(t));var n="sha512"===e||"sha384"===e?128:64;this._alg=e,this._key=t,t.length>n?t=("rmd160"===e?new u:c(e)).update(t).digest():t.length{"use strict";var o=n(35717),r=n(89509).Buffer,i=n(71027),a=r.alloc(128),s=64;function u(e,t){i.call(this,"digest"),"string"==typeof t&&(t=r.from(t)),this._alg=e,this._key=t,t.length>s?t=e(t):t.length{"use strict";t.randomBytes=t.rng=t.pseudoRandomBytes=t.prng=n(61798),t.createHash=t.Hash=n(23482),t.createHmac=t.Hmac=n(58355);var o=n(56042),r=Object.keys(o),i=["sha1","sha224","sha256","sha384","sha512","md5","rmd160"].concat(r);t.getHashes=function(){return i};var a=n(25632);t.pbkdf2=a.pbkdf2,t.pbkdf2Sync=a.pbkdf2Sync;var s=n(53614);t.Cipher=s.Cipher,t.createCipher=s.createCipher,t.Cipheriv=s.Cipheriv,t.createCipheriv=s.createCipheriv,t.Decipher=s.Decipher,t.createDecipher=s.createDecipher,t.Decipheriv=s.Decipheriv,t.createDecipheriv=s.createDecipheriv,t.getCiphers=s.getCiphers,t.listCiphers=s.listCiphers;var u=n(62607);t.DiffieHellmanGroup=u.DiffieHellmanGroup,t.createDiffieHellmanGroup=u.createDiffieHellmanGroup,t.getDiffieHellman=u.getDiffieHellman,t.createDiffieHellman=u.createDiffieHellman,t.DiffieHellman=u.DiffieHellman;var c=n(64743);t.createSign=c.createSign,t.Sign=c.Sign,t.createVerify=c.createVerify,t.Verify=c.Verify,t.createECDH=n(76393);var l=n(7900);t.publicEncrypt=l.publicEncrypt,t.privateEncrypt=l.privateEncrypt,t.publicDecrypt=l.publicDecrypt,t.privateDecrypt=l.privateDecrypt;var d=n(77963);t.randomFill=d.randomFill,t.randomFillSync=d.randomFillSync,t.createCredentials=function(){throw new Error(["sorry, createCredentials is not implemented yet","we accept pull requests","https://github.com/crypto-browserify/crypto-browserify"].join("\n"))},t.constants={DH_CHECK_P_NOT_SAFE_PRIME:2,DH_CHECK_P_NOT_PRIME:1,DH_UNABLE_TO_CHECK_GENERATOR:4,DH_NOT_SUITABLE_GENERATOR:8,NPN_ENABLED:1,ALPN_ENABLED:1,RSA_PKCS1_PADDING:1,RSA_SSLV23_PADDING:2,RSA_NO_PADDING:3,RSA_PKCS1_OAEP_PADDING:4,RSA_X931_PADDING:5,RSA_PKCS1_PSS_PADDING:6,POINT_CONVERSION_COMPRESSED:2,POINT_CONVERSION_UNCOMPRESSED:4,POINT_CONVERSION_HYBRID:6}},48116:(e,t,n)=>{"use strict";var o;function r(e){return(r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}!function(i){var a,s,u,c=arguments,l=(a=/d{1,4}|D{3,4}|m{1,4}|yy(?:yy)?|([HhMsTt])\1?|W{1,2}|[LlopSZN]|"[^"]*"|'[^']*'/g,s=/\b(?:[PMCEA][SDP]T|(?:Pacific|Mountain|Central|Eastern|Atlantic) (?:Standard|Daylight|Prevailing) Time|(?:GMT|UTC)(?:[-+]\d{4})?)\b/g,u=/[^-+\dA-Z]/g,function(e,t,n,o){if(1!==c.length||"string"!==g(e)||/\d/.test(e)||(t=e,e=void 0),(e=e||0===e?e:new Date)instanceof Date||(e=new Date(e)),isNaN(e))throw TypeError("Invalid date");var r=(t=String(l.masks[t]||t||l.masks.default)).slice(0,4);"UTC:"!==r&&"GMT:"!==r||(t=t.slice(4),n=!0,"GMT:"===r&&(o=!0));var i=function(){return n?"getUTC":"get"},m=function(){return e[i()+"Date"]()},_=function(){return e[i()+"Day"]()},F=function(){return e[i()+"Month"]()},y=function(){return e[i()+"FullYear"]()},b=function(){return e[i()+"Hours"]()},v=function(){return e[i()+"Minutes"]()},w=function(){return e[i()+"Seconds"]()},E=function(){return e[i()+"Milliseconds"]()},k=function(){return n?0:e.getTimezoneOffset()},D=function(){return p(e)},S={d:function(){return m()},dd:function(){return d(m())},ddd:function(){return l.i18n.dayNames[_()]},DDD:function(){return h({y:y(),m:F(),d:m(),_:i(),dayName:l.i18n.dayNames[_()],short:!0})},dddd:function(){return l.i18n.dayNames[_()+7]},DDDD:function(){return h({y:y(),m:F(),d:m(),_:i(),dayName:l.i18n.dayNames[_()+7]})},m:function(){return F()+1},mm:function(){return d(F()+1)},mmm:function(){return l.i18n.monthNames[F()]},mmmm:function(){return l.i18n.monthNames[F()+12]},yy:function(){return String(y()).slice(2)},yyyy:function(){return d(y(),4)},h:function(){return b()%12||12},hh:function(){return d(b()%12||12)},H:function(){return b()},HH:function(){return d(b())},M:function(){return v()},MM:function(){return d(v())},s:function(){return w()},ss:function(){return d(w())},l:function(){return d(E(),3)},L:function(){return d(Math.floor(E()/10))},t:function(){return b()<12?l.i18n.timeNames[0]:l.i18n.timeNames[1]},tt:function(){return b()<12?l.i18n.timeNames[2]:l.i18n.timeNames[3]},T:function(){return b()<12?l.i18n.timeNames[4]:l.i18n.timeNames[5]},TT:function(){return b()<12?l.i18n.timeNames[6]:l.i18n.timeNames[7]},Z:function(){return o?"GMT":n?"UTC":(String(e).match(s)||[""]).pop().replace(u,"").replace(/GMT\+0000/g,"UTC")},o:function(){return(k()>0?"-":"+")+d(100*Math.floor(Math.abs(k())/60)+Math.abs(k())%60,4)},p:function(){return(k()>0?"-":"+")+d(Math.floor(Math.abs(k())/60),2)+":"+d(Math.floor(Math.abs(k())%60),2)},S:function(){return["th","st","nd","rd"][m()%10>3?0:(m()%100-m()%10!=10)*m()%10]},W:function(){return D()},WW:function(){return d(D())},N:function(){return f(e)}};return t.replace(a,(function(e){return e in S?S[e]():e.slice(1,e.length-1)}))});l.masks={default:"ddd mmm dd yyyy HH:MM:ss",shortDate:"m/d/yy",paddedShortDate:"mm/dd/yyyy",mediumDate:"mmm d, yyyy",longDate:"mmmm d, yyyy",fullDate:"dddd, mmmm d, yyyy",shortTime:"h:MM TT",mediumTime:"h:MM:ss TT",longTime:"h:MM:ss TT Z",isoDate:"yyyy-mm-dd",isoTime:"HH:MM:ss",isoDateTime:"yyyy-mm-dd'T'HH:MM:sso",isoUtcDateTime:"UTC:yyyy-mm-dd'T'HH:MM:ss'Z'",expiresHeaderFormat:"ddd, dd mmm yyyy HH:MM:ss Z"},l.i18n={dayNames:["Sun","Mon","Tue","Wed","Thu","Fri","Sat","Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],monthNames:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec","January","February","March","April","May","June","July","August","September","October","November","December"],timeNames:["a","p","am","pm","A","P","AM","PM"]};var d=function(e,t){for(e=String(e),t=t||2;e.length{var o=n(89539),r=n(32554).NI;function i(e){r.call(this,"string"==typeof e?e:""),this._db=void 0,this._operations=[]}o.inherits(i,r),i.prototype.setDb=function(e){this._db=e,this._operations.forEach((function(t){e[t.method].apply(e,t.args)}))},i.prototype._open=function(e,t){return process.nextTick(t)},i.prototype._operation=function(e,t){if(this._db)return this._db[e].apply(this._db,t);this._operations.push({method:e,args:t})},"put get del batch approximateSize".split(" ").forEach((function(e){i.prototype["_"+e]=function(){this._operation(e,arguments)}})),i.prototype._isBuffer=function(e){return Buffer.isBuffer(e)},i.prototype._iterator=function(){throw new TypeError("not implemented")},e.exports=i},15251:(e,t,n)=>{"use strict";t.utils=n(11278),t.Cipher=n(55756),t.DES=n(70778),t.CBC=n(39051),t.EDE=n(50651)},39051:(e,t,n)=>{"use strict";var o=n(79746),r=n(35717),i={};function a(e){o.equal(e.length,8,"Invalid IV length"),this.iv=new Array(8);for(var t=0;t{"use strict";var o=n(79746);function r(e){this.options=e,this.type=this.options.type,this.blockSize=8,this._init(),this.buffer=new Array(this.blockSize),this.bufferOff=0}e.exports=r,r.prototype._init=function(){},r.prototype.update=function(e){return 0===e.length?[]:"decrypt"===this.type?this._updateDecrypt(e):this._updateEncrypt(e)},r.prototype._buffer=function(e,t){for(var n=Math.min(this.buffer.length-this.bufferOff,e.length-t),o=0;o0;o--)t+=this._buffer(e,t),n+=this._flushBuffer(r,n);return t+=this._buffer(e,t),r},r.prototype.final=function(e){var t,n;return e&&(t=this.update(e)),n="encrypt"===this.type?this._finalEncrypt():this._finalDecrypt(),t?t.concat(n):n},r.prototype._pad=function(e,t){if(0===t)return!1;for(;t{"use strict";var o=n(79746),r=n(35717),i=n(11278),a=n(55756);function s(){this.tmp=new Array(2),this.keys=null}function u(e){a.call(this,e);var t=new s;this._desState=t,this.deriveKeys(t,e.key)}r(u,a),e.exports=u,u.create=function(e){return new u(e)};var c=[1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1];u.prototype.deriveKeys=function(e,t){e.keys=new Array(32),o.equal(t.length,this.blockSize,"Invalid key length");var n=i.readUInt32BE(t,0),r=i.readUInt32BE(t,4);i.pc1(n,r,e.tmp,0),n=e.tmp[0],r=e.tmp[1];for(var a=0;a>>1];n=i.r28shl(n,s),r=i.r28shl(r,s),i.pc2(n,r,e.keys,a)}},u.prototype._update=function(e,t,n,o){var r=this._desState,a=i.readUInt32BE(e,t),s=i.readUInt32BE(e,t+4);i.ip(a,s,r.tmp,0),a=r.tmp[0],s=r.tmp[1],"encrypt"===this.type?this._encrypt(r,a,s,r.tmp,0):this._decrypt(r,a,s,r.tmp,0),a=r.tmp[0],s=r.tmp[1],i.writeUInt32BE(n,a,o),i.writeUInt32BE(n,s,o+4)},u.prototype._pad=function(e,t){for(var n=e.length-t,o=t;o>>0,a=h}i.rip(s,a,o,r)},u.prototype._decrypt=function(e,t,n,o,r){for(var a=n,s=t,u=e.keys.length-2;u>=0;u-=2){var c=e.keys[u],l=e.keys[u+1];i.expand(a,e.tmp,0),c^=e.tmp[0],l^=e.tmp[1];var d=i.substitute(c,l),h=a;a=(s^i.permute(d))>>>0,s=h}i.rip(a,s,o,r)}},50651:(e,t,n)=>{"use strict";var o=n(79746),r=n(35717),i=n(55756),a=n(70778);function s(e,t){o.equal(t.length,24,"Invalid key length");var n=t.slice(0,8),r=t.slice(8,16),i=t.slice(16,24);this.ciphers="encrypt"===e?[a.create({type:"encrypt",key:n}),a.create({type:"decrypt",key:r}),a.create({type:"encrypt",key:i})]:[a.create({type:"decrypt",key:i}),a.create({type:"encrypt",key:r}),a.create({type:"decrypt",key:n})]}function u(e){i.call(this,e);var t=new s(this.type,this.options.key);this._edeState=t}r(u,i),e.exports=u,u.create=function(e){return new u(e)},u.prototype._update=function(e,t,n,o){var r=this._edeState;r.ciphers[0]._update(e,t,n,o),r.ciphers[1]._update(n,o,n,o),r.ciphers[2]._update(n,o,n,o)},u.prototype._pad=a.prototype._pad,u.prototype._unpad=a.prototype._unpad},11278:(e,t)=>{"use strict";t.readUInt32BE=function(e,t){return(e[0+t]<<24|e[1+t]<<16|e[2+t]<<8|e[3+t])>>>0},t.writeUInt32BE=function(e,t,n){e[0+n]=t>>>24,e[1+n]=t>>>16&255,e[2+n]=t>>>8&255,e[3+n]=255&t},t.ip=function(e,t,n,o){for(var r=0,i=0,a=6;a>=0;a-=2){for(var s=0;s<=24;s+=8)r<<=1,r|=t>>>s+a&1;for(s=0;s<=24;s+=8)r<<=1,r|=e>>>s+a&1}for(a=6;a>=0;a-=2){for(s=1;s<=25;s+=8)i<<=1,i|=t>>>s+a&1;for(s=1;s<=25;s+=8)i<<=1,i|=e>>>s+a&1}n[o+0]=r>>>0,n[o+1]=i>>>0},t.rip=function(e,t,n,o){for(var r=0,i=0,a=0;a<4;a++)for(var s=24;s>=0;s-=8)r<<=1,r|=t>>>s+a&1,r<<=1,r|=e>>>s+a&1;for(a=4;a<8;a++)for(s=24;s>=0;s-=8)i<<=1,i|=t>>>s+a&1,i<<=1,i|=e>>>s+a&1;n[o+0]=r>>>0,n[o+1]=i>>>0},t.pc1=function(e,t,n,o){for(var r=0,i=0,a=7;a>=5;a--){for(var s=0;s<=24;s+=8)r<<=1,r|=t>>s+a&1;for(s=0;s<=24;s+=8)r<<=1,r|=e>>s+a&1}for(s=0;s<=24;s+=8)r<<=1,r|=t>>s+a&1;for(a=1;a<=3;a++){for(s=0;s<=24;s+=8)i<<=1,i|=t>>s+a&1;for(s=0;s<=24;s+=8)i<<=1,i|=e>>s+a&1}for(s=0;s<=24;s+=8)i<<=1,i|=e>>s+a&1;n[o+0]=r>>>0,n[o+1]=i>>>0},t.r28shl=function(e,t){return e<>>28-t};var n=[14,11,17,4,27,23,25,0,13,22,7,18,5,9,16,24,2,20,12,21,1,8,15,26,15,4,25,19,9,1,26,16,5,11,23,8,12,7,17,0,22,3,10,14,6,20,27,24];t.pc2=function(e,t,o,r){for(var i=0,a=0,s=n.length>>>1,u=0;u>>n[u]&1;for(u=s;u>>n[u]&1;o[r+0]=i>>>0,o[r+1]=a>>>0},t.expand=function(e,t,n){var o=0,r=0;o=(1&e)<<5|e>>>27;for(var i=23;i>=15;i-=4)o<<=6,o|=e>>>i&63;for(i=11;i>=3;i-=4)r|=e>>>i&63,r<<=6;r|=(31&e)<<1|e>>>31,t[n+0]=o>>>0,t[n+1]=r>>>0};var o=[14,0,4,15,13,7,1,4,2,14,15,2,11,13,8,1,3,10,10,6,6,12,12,11,5,9,9,5,0,3,7,8,4,15,1,12,14,8,8,2,13,4,6,9,2,1,11,7,15,5,12,11,9,3,7,14,3,10,10,0,5,6,0,13,15,3,1,13,8,4,14,7,6,15,11,2,3,8,4,14,9,12,7,0,2,1,13,10,12,6,0,9,5,11,10,5,0,13,14,8,7,10,11,1,10,3,4,15,13,4,1,2,5,11,8,6,12,7,6,12,9,0,3,5,2,14,15,9,10,13,0,7,9,0,14,9,6,3,3,4,15,6,5,10,1,2,13,8,12,5,7,14,11,12,4,11,2,15,8,1,13,1,6,10,4,13,9,0,8,6,15,9,3,8,0,7,11,4,1,15,2,14,12,3,5,11,10,5,14,2,7,12,7,13,13,8,14,11,3,5,0,6,6,15,9,0,10,3,1,4,2,7,8,2,5,12,11,1,12,10,4,14,15,9,10,3,6,15,9,0,0,6,12,10,11,1,7,13,13,8,15,9,1,4,3,5,14,11,5,12,2,7,8,2,4,14,2,14,12,11,4,2,1,12,7,4,10,7,11,13,6,1,8,5,5,0,3,15,15,10,13,3,0,9,14,8,9,6,4,11,2,8,1,12,11,7,10,1,13,14,7,2,8,13,15,6,9,15,12,0,5,9,6,10,3,4,0,5,14,3,12,10,1,15,10,4,15,2,9,7,2,12,6,9,8,5,0,6,13,1,3,13,4,14,14,0,7,11,5,3,11,8,9,4,14,3,15,2,5,12,2,9,8,5,12,15,3,10,7,11,0,14,4,1,10,7,1,6,13,0,11,8,6,13,4,13,11,0,2,11,14,7,15,4,0,9,8,1,13,10,3,14,12,3,9,5,7,12,5,2,10,15,6,8,1,6,1,6,4,11,11,13,13,8,12,1,3,4,7,10,14,7,10,9,15,5,6,0,8,15,0,14,5,2,9,3,2,12,13,1,2,15,8,13,4,8,6,10,15,3,11,7,1,4,10,12,9,5,3,6,14,11,5,0,0,14,12,9,7,2,7,2,11,1,4,14,1,7,9,4,12,10,14,8,2,13,0,15,6,12,10,9,13,0,15,3,3,5,5,6,8,11];t.substitute=function(e,t){for(var n=0,r=0;r<4;r++)n<<=4,n|=o[64*r+(e>>>18-6*r&63)];for(r=0;r<4;r++)n<<=4,n|=o[256+64*r+(t>>>18-6*r&63)];return n>>>0};var r=[16,25,12,11,3,20,4,15,31,17,9,6,27,14,1,22,30,24,8,18,0,5,29,23,13,19,2,26,10,21,28,7];t.permute=function(e){for(var t=0,n=0;n>>r[n]&1;return t>>>0},t.padSplit=function(e,t,n){for(var o=e.toString(2);o.length{var o=n(43590),r=n(61930),i=n(57426),a={binary:!0,hex:!0,base64:!0};t.DiffieHellmanGroup=t.createDiffieHellmanGroup=t.getDiffieHellman=function(e){var t=new Buffer(r[e].prime,"hex"),n=new Buffer(r[e].gen,"hex");return new i(t,n)},t.createDiffieHellman=t.DiffieHellman=function e(t,n,r,s){return Buffer.isBuffer(n)||void 0===a[n]?e(t,"binary",n,r):(n=n||"binary",s=s||"binary",r=r||new Buffer([2]),Buffer.isBuffer(r)||(r=new Buffer(r,s)),"number"==typeof t?new i(o(t,r),r,!0):(Buffer.isBuffer(t)||(t=new Buffer(t,n)),new i(t,r,!0)))}},57426:(e,t,n)=>{var o=n(83620),r=new(n(63047)),i=new o(24),a=new o(11),s=new o(10),u=new o(3),c=new o(7),l=n(43590),d=n(61798);function h(e,t){return t=t||"utf8",Buffer.isBuffer(e)||(e=new Buffer(e,t)),this._pub=new o(e),this}function p(e,t){return t=t||"utf8",Buffer.isBuffer(e)||(e=new Buffer(e,t)),this._priv=new o(e),this}e.exports=g;var f={};function g(e,t,n){this.setGenerator(t),this.__prime=new o(e),this._prime=o.mont(this.__prime),this._primeLen=e.length,this._pub=void 0,this._priv=void 0,this._primeCode=void 0,n?(this.setPublicKey=h,this.setPrivateKey=p):this._primeCode=8}function m(e,t){var n=new Buffer(e.toArray());return t?n.toString(t):n}Object.defineProperty(g.prototype,"verifyError",{enumerable:!0,get:function(){return"number"!=typeof this._primeCode&&(this._primeCode=function(e,t){var n=t.toString("hex"),o=[n,e.toString(16)].join("_");if(o in f)return f[o];var d,h=0;if(e.isEven()||!l.simpleSieve||!l.fermatTest(e)||!r.test(e))return h+=1,h+="02"===n||"05"===n?8:4,f[o]=h,h;switch(r.test(e.shrn(1))||(h+=2),n){case"02":e.mod(i).cmp(a)&&(h+=8);break;case"05":(d=e.mod(s)).cmp(u)&&d.cmp(c)&&(h+=8);break;default:h+=4}return f[o]=h,h}(this.__prime,this.__gen)),this._primeCode}}),g.prototype.generateKeys=function(){return this._priv||(this._priv=new o(d(this._primeLen))),this._pub=this._gen.toRed(this._prime).redPow(this._priv).fromRed(),this.getPublicKey()},g.prototype.computeSecret=function(e){var t=(e=(e=new o(e)).toRed(this._prime)).redPow(this._priv).fromRed(),n=new Buffer(t.toArray()),r=this.getPrime();if(n.length{var o=n(61798);e.exports=F,F.simpleSieve=m,F.fermatTest=_;var r=n(83620),i=new r(24),a=new(n(63047)),s=new r(1),u=new r(2),c=new r(5),l=(new r(16),new r(8),new r(10)),d=new r(3),h=(new r(7),new r(11)),p=new r(4),f=(new r(12),null);function g(){if(null!==f)return f;var e=[];e[0]=2;for(var t=1,n=3;n<1048576;n+=2){for(var o=Math.ceil(Math.sqrt(n)),r=0;re;)n.ishrn(1);if(n.isEven()&&n.iadd(s),n.testn(1)||n.iadd(u),t.cmp(u)){if(!t.cmp(c))for(;n.mod(l).cmp(d);)n.iadd(p)}else for(;n.mod(i).cmp(h);)n.iadd(p);if(m(f=n.shrn(1))&&m(n)&&_(f)&&_(n)&&a.test(f)&&a.test(n))return n}}},61930:e=>{"use strict";e.exports=JSON.parse('{"modp1":{"gen":"02","prime":"ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a63a3620ffffffffffffffff"},"modp2":{"gen":"02","prime":"ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece65381ffffffffffffffff"},"modp5":{"gen":"02","prime":"ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca237327ffffffffffffffff"},"modp14":{"gen":"02","prime":"ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aacaa68ffffffffffffffff"},"modp15":{"gen":"02","prime":"ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aaac42dad33170d04507a33a85521abdf1cba64ecfb850458dbef0a8aea71575d060c7db3970f85a6e1e4c7abf5ae8cdb0933d71e8c94e04a25619dcee3d2261ad2ee6bf12ffa06d98a0864d87602733ec86a64521f2b18177b200cbbe117577a615d6c770988c0bad946e208e24fa074e5ab3143db5bfce0fd108e4b82d120a93ad2caffffffffffffffff"},"modp16":{"gen":"02","prime":"ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aaac42dad33170d04507a33a85521abdf1cba64ecfb850458dbef0a8aea71575d060c7db3970f85a6e1e4c7abf5ae8cdb0933d71e8c94e04a25619dcee3d2261ad2ee6bf12ffa06d98a0864d87602733ec86a64521f2b18177b200cbbe117577a615d6c770988c0bad946e208e24fa074e5ab3143db5bfce0fd108e4b82d120a92108011a723c12a787e6d788719a10bdba5b2699c327186af4e23c1a946834b6150bda2583e9ca2ad44ce8dbbbc2db04de8ef92e8efc141fbecaa6287c59474e6bc05d99b2964fa090c3a2233ba186515be7ed1f612970cee2d7afb81bdd762170481cd0069127d5b05aa993b4ea988d8fddc186ffb7dc90a6c08f4df435c934063199ffffffffffffffff"},"modp17":{"gen":"02","prime":"ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aaac42dad33170d04507a33a85521abdf1cba64ecfb850458dbef0a8aea71575d060c7db3970f85a6e1e4c7abf5ae8cdb0933d71e8c94e04a25619dcee3d2261ad2ee6bf12ffa06d98a0864d87602733ec86a64521f2b18177b200cbbe117577a615d6c770988c0bad946e208e24fa074e5ab3143db5bfce0fd108e4b82d120a92108011a723c12a787e6d788719a10bdba5b2699c327186af4e23c1a946834b6150bda2583e9ca2ad44ce8dbbbc2db04de8ef92e8efc141fbecaa6287c59474e6bc05d99b2964fa090c3a2233ba186515be7ed1f612970cee2d7afb81bdd762170481cd0069127d5b05aa993b4ea988d8fddc186ffb7dc90a6c08f4df435c93402849236c3fab4d27c7026c1d4dcb2602646dec9751e763dba37bdf8ff9406ad9e530ee5db382f413001aeb06a53ed9027d831179727b0865a8918da3edbebcf9b14ed44ce6cbaced4bb1bdb7f1447e6cc254b332051512bd7af426fb8f401378cd2bf5983ca01c64b92ecf032ea15d1721d03f482d7ce6e74fef6d55e702f46980c82b5a84031900b1c9e59e7c97fbec7e8f323a97a7e36cc88be0f1d45b7ff585ac54bd407b22b4154aacc8f6d7ebf48e1d814cc5ed20f8037e0a79715eef29be32806a1d58bb7c5da76f550aa3d8a1fbff0eb19ccb1a313d55cda56c9ec2ef29632387fe8d76e3c0468043e8f663f4860ee12bf2d5b0b7474d6e694f91e6dcc4024ffffffffffffffff"},"modp18":{"gen":"02","prime":"ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aaac42dad33170d04507a33a85521abdf1cba64ecfb850458dbef0a8aea71575d060c7db3970f85a6e1e4c7abf5ae8cdb0933d71e8c94e04a25619dcee3d2261ad2ee6bf12ffa06d98a0864d87602733ec86a64521f2b18177b200cbbe117577a615d6c770988c0bad946e208e24fa074e5ab3143db5bfce0fd108e4b82d120a92108011a723c12a787e6d788719a10bdba5b2699c327186af4e23c1a946834b6150bda2583e9ca2ad44ce8dbbbc2db04de8ef92e8efc141fbecaa6287c59474e6bc05d99b2964fa090c3a2233ba186515be7ed1f612970cee2d7afb81bdd762170481cd0069127d5b05aa993b4ea988d8fddc186ffb7dc90a6c08f4df435c93402849236c3fab4d27c7026c1d4dcb2602646dec9751e763dba37bdf8ff9406ad9e530ee5db382f413001aeb06a53ed9027d831179727b0865a8918da3edbebcf9b14ed44ce6cbaced4bb1bdb7f1447e6cc254b332051512bd7af426fb8f401378cd2bf5983ca01c64b92ecf032ea15d1721d03f482d7ce6e74fef6d55e702f46980c82b5a84031900b1c9e59e7c97fbec7e8f323a97a7e36cc88be0f1d45b7ff585ac54bd407b22b4154aacc8f6d7ebf48e1d814cc5ed20f8037e0a79715eef29be32806a1d58bb7c5da76f550aa3d8a1fbff0eb19ccb1a313d55cda56c9ec2ef29632387fe8d76e3c0468043e8f663f4860ee12bf2d5b0b7474d6e694f91e6dbe115974a3926f12fee5e438777cb6a932df8cd8bec4d073b931ba3bc832b68d9dd300741fa7bf8afc47ed2576f6936ba424663aab639c5ae4f5683423b4742bf1c978238f16cbe39d652de3fdb8befc848ad922222e04a4037c0713eb57a81a23f0c73473fc646cea306b4bcbc8862f8385ddfa9d4b7fa2c087e879683303ed5bdd3a062b3cf5b3a278a66d2a13f83f44f82ddf310ee074ab6a364597e899a0255dc164f31cc50846851df9ab48195ded7ea1b1d510bd7ee74d73faf36bc31ecfa268359046f4eb879f924009438b481c6cd7889a002ed5ee382bc9190da6fc026e479558e4475677e9aa9e3050e2765694dfc81f56e880b96e7160c980dd98edd3dfffffffffffffffff"}}')},83620:function(e,t,n){!function(e,t){"use strict";function o(e,t){if(!e)throw new Error(t||"Assertion failed")}function r(e,t){e.super_=t;var n=function(){};n.prototype=t.prototype,e.prototype=new n,e.prototype.constructor=e}function i(e,t,n){if(i.isBN(e))return e;this.negative=0,this.words=null,this.length=0,this.red=null,null!==e&&("le"!==t&&"be"!==t||(n=t,t=10),this._init(e||0,t||10,n||"be"))}var a;"object"==typeof e?e.exports=i:t.BN=i,i.BN=i,i.wordSize=26;try{a="undefined"!=typeof window&&void 0!==window.Buffer?window.Buffer:n(7748).Buffer}catch(e){}function s(e,t){var n=e.charCodeAt(t);return n>=65&&n<=70?n-55:n>=97&&n<=102?n-87:n-48&15}function u(e,t,n){var o=s(e,n);return n-1>=t&&(o|=s(e,n-1)<<4),o}function c(e,t,n,o){for(var r=0,i=Math.min(e.length,n),a=t;a=49?s-49+10:s>=17?s-17+10:s}return r}i.isBN=function(e){return e instanceof i||null!==e&&"object"==typeof e&&e.constructor.wordSize===i.wordSize&&Array.isArray(e.words)},i.max=function(e,t){return e.cmp(t)>0?e:t},i.min=function(e,t){return e.cmp(t)<0?e:t},i.prototype._init=function(e,t,n){if("number"==typeof e)return this._initNumber(e,t,n);if("object"==typeof e)return this._initArray(e,t,n);"hex"===t&&(t=16),o(t===(0|t)&&t>=2&&t<=36);var r=0;"-"===(e=e.toString().replace(/\s+/g,""))[0]&&(r++,this.negative=1),r=0;r-=3)a=e[r]|e[r-1]<<8|e[r-2]<<16,this.words[i]|=a<>>26-s&67108863,(s+=24)>=26&&(s-=26,i++);else if("le"===n)for(r=0,i=0;r>>26-s&67108863,(s+=24)>=26&&(s-=26,i++);return this.strip()},i.prototype._parseHex=function(e,t,n){this.length=Math.ceil((e.length-t)/6),this.words=new Array(this.length);for(var o=0;o=t;o-=2)r=u(e,t,o)<=18?(i-=18,a+=1,this.words[a]|=r>>>26):i+=8;else for(o=(e.length-t)%2==0?t+1:t;o=18?(i-=18,a+=1,this.words[a]|=r>>>26):i+=8;this.strip()},i.prototype._parseBase=function(e,t,n){this.words=[0],this.length=1;for(var o=0,r=1;r<=67108863;r*=t)o++;o--,r=r/t|0;for(var i=e.length-n,a=i%o,s=Math.min(i,i-a)+n,u=0,l=n;l1&&0===this.words[this.length-1];)this.length--;return this._normSign()},i.prototype._normSign=function(){return 1===this.length&&0===this.words[0]&&(this.negative=0),this},i.prototype.inspect=function(){return(this.red?""};var l=["","0","00","000","0000","00000","000000","0000000","00000000","000000000","0000000000","00000000000","000000000000","0000000000000","00000000000000","000000000000000","0000000000000000","00000000000000000","000000000000000000","0000000000000000000","00000000000000000000","000000000000000000000","0000000000000000000000","00000000000000000000000","000000000000000000000000","0000000000000000000000000"],d=[0,0,25,16,12,11,10,9,8,8,7,7,7,7,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5],h=[0,0,33554432,43046721,16777216,48828125,60466176,40353607,16777216,43046721,1e7,19487171,35831808,62748517,7529536,11390625,16777216,24137569,34012224,47045881,64e6,4084101,5153632,6436343,7962624,9765625,11881376,14348907,17210368,20511149,243e5,28629151,33554432,39135393,45435424,52521875,60466176];function p(e,t,n){n.negative=t.negative^e.negative;var o=e.length+t.length|0;n.length=o,o=o-1|0;var r=0|e.words[0],i=0|t.words[0],a=r*i,s=67108863&a,u=a/67108864|0;n.words[0]=s;for(var c=1;c>>26,d=67108863&u,h=Math.min(c,t.length-1),p=Math.max(0,c-e.length+1);p<=h;p++){var f=c-p|0;l+=(a=(r=0|e.words[f])*(i=0|t.words[p])+d)/67108864|0,d=67108863&a}n.words[c]=0|d,u=0|l}return 0!==u?n.words[c]=0|u:n.length--,n.strip()}i.prototype.toString=function(e,t){var n;if(t=0|t||1,16===(e=e||10)||"hex"===e){n="";for(var r=0,i=0,a=0;a>>24-r&16777215)||a!==this.length-1?l[6-u.length]+u+n:u+n,(r+=2)>=26&&(r-=26,a--)}for(0!==i&&(n=i.toString(16)+n);n.length%t!=0;)n="0"+n;return 0!==this.negative&&(n="-"+n),n}if(e===(0|e)&&e>=2&&e<=36){var c=d[e],p=h[e];n="";var f=this.clone();for(f.negative=0;!f.isZero();){var g=f.modn(p).toString(e);n=(f=f.idivn(p)).isZero()?g+n:l[c-g.length]+g+n}for(this.isZero()&&(n="0"+n);n.length%t!=0;)n="0"+n;return 0!==this.negative&&(n="-"+n),n}o(!1,"Base should be between 2 and 36")},i.prototype.toNumber=function(){var e=this.words[0];return 2===this.length?e+=67108864*this.words[1]:3===this.length&&1===this.words[2]?e+=4503599627370496+67108864*this.words[1]:this.length>2&&o(!1,"Number can only safely store up to 53 bits"),0!==this.negative?-e:e},i.prototype.toJSON=function(){return this.toString(16)},i.prototype.toBuffer=function(e,t){return o(void 0!==a),this.toArrayLike(a,e,t)},i.prototype.toArray=function(e,t){return this.toArrayLike(Array,e,t)},i.prototype.toArrayLike=function(e,t,n){var r=this.byteLength(),i=n||Math.max(1,r);o(r<=i,"byte array longer than desired length"),o(i>0,"Requested array length <= 0"),this.strip();var a,s,u="le"===t,c=new e(i),l=this.clone();if(u){for(s=0;!l.isZero();s++)a=l.andln(255),l.iushrn(8),c[s]=a;for(;s=4096&&(n+=13,t>>>=13),t>=64&&(n+=7,t>>>=7),t>=8&&(n+=4,t>>>=4),t>=2&&(n+=2,t>>>=2),n+t},i.prototype._zeroBits=function(e){if(0===e)return 26;var t=e,n=0;return 0==(8191&t)&&(n+=13,t>>>=13),0==(127&t)&&(n+=7,t>>>=7),0==(15&t)&&(n+=4,t>>>=4),0==(3&t)&&(n+=2,t>>>=2),0==(1&t)&&n++,n},i.prototype.bitLength=function(){var e=this.words[this.length-1],t=this._countBits(e);return 26*(this.length-1)+t},i.prototype.zeroBits=function(){if(this.isZero())return 0;for(var e=0,t=0;te.length?this.clone().ior(e):e.clone().ior(this)},i.prototype.uor=function(e){return this.length>e.length?this.clone().iuor(e):e.clone().iuor(this)},i.prototype.iuand=function(e){var t;t=this.length>e.length?e:this;for(var n=0;ne.length?this.clone().iand(e):e.clone().iand(this)},i.prototype.uand=function(e){return this.length>e.length?this.clone().iuand(e):e.clone().iuand(this)},i.prototype.iuxor=function(e){var t,n;this.length>e.length?(t=this,n=e):(t=e,n=this);for(var o=0;oe.length?this.clone().ixor(e):e.clone().ixor(this)},i.prototype.uxor=function(e){return this.length>e.length?this.clone().iuxor(e):e.clone().iuxor(this)},i.prototype.inotn=function(e){o("number"==typeof e&&e>=0);var t=0|Math.ceil(e/26),n=e%26;this._expand(t),n>0&&t--;for(var r=0;r0&&(this.words[r]=~this.words[r]&67108863>>26-n),this.strip()},i.prototype.notn=function(e){return this.clone().inotn(e)},i.prototype.setn=function(e,t){o("number"==typeof e&&e>=0);var n=e/26|0,r=e%26;return this._expand(n+1),this.words[n]=t?this.words[n]|1<e.length?(n=this,o=e):(n=e,o=this);for(var r=0,i=0;i>>26;for(;0!==r&&i>>26;if(this.length=n.length,0!==r)this.words[this.length]=r,this.length++;else if(n!==this)for(;ie.length?this.clone().iadd(e):e.clone().iadd(this)},i.prototype.isub=function(e){if(0!==e.negative){e.negative=0;var t=this.iadd(e);return e.negative=1,t._normSign()}if(0!==this.negative)return this.negative=0,this.iadd(e),this.negative=1,this._normSign();var n,o,r=this.cmp(e);if(0===r)return this.negative=0,this.length=1,this.words[0]=0,this;r>0?(n=this,o=e):(n=e,o=this);for(var i=0,a=0;a>26,this.words[a]=67108863&t;for(;0!==i&&a>26,this.words[a]=67108863&t;if(0===i&&a>>13,p=0|a[1],f=8191&p,g=p>>>13,m=0|a[2],_=8191&m,F=m>>>13,y=0|a[3],b=8191&y,v=y>>>13,w=0|a[4],E=8191&w,k=w>>>13,D=0|a[5],S=8191&D,x=D>>>13,C=0|a[6],A=8191&C,T=C>>>13,R=0|a[7],I=8191&R,M=R>>>13,O=0|a[8],B=8191&O,N=O>>>13,L=0|a[9],P=8191&L,U=L>>>13,j=0|s[0],q=8191&j,z=j>>>13,K=0|s[1],G=8191&K,$=K>>>13,H=0|s[2],V=8191&H,W=H>>>13,Y=0|s[3],Z=8191&Y,X=Y>>>13,J=0|s[4],Q=8191&J,ee=J>>>13,te=0|s[5],ne=8191&te,oe=te>>>13,re=0|s[6],ie=8191&re,ae=re>>>13,se=0|s[7],ue=8191&se,ce=se>>>13,le=0|s[8],de=8191&le,he=le>>>13,pe=0|s[9],fe=8191&pe,ge=pe>>>13;n.negative=e.negative^t.negative,n.length=19;var me=(c+(o=Math.imul(d,q))|0)+((8191&(r=(r=Math.imul(d,z))+Math.imul(h,q)|0))<<13)|0;c=((i=Math.imul(h,z))+(r>>>13)|0)+(me>>>26)|0,me&=67108863,o=Math.imul(f,q),r=(r=Math.imul(f,z))+Math.imul(g,q)|0,i=Math.imul(g,z);var _e=(c+(o=o+Math.imul(d,G)|0)|0)+((8191&(r=(r=r+Math.imul(d,$)|0)+Math.imul(h,G)|0))<<13)|0;c=((i=i+Math.imul(h,$)|0)+(r>>>13)|0)+(_e>>>26)|0,_e&=67108863,o=Math.imul(_,q),r=(r=Math.imul(_,z))+Math.imul(F,q)|0,i=Math.imul(F,z),o=o+Math.imul(f,G)|0,r=(r=r+Math.imul(f,$)|0)+Math.imul(g,G)|0,i=i+Math.imul(g,$)|0;var Fe=(c+(o=o+Math.imul(d,V)|0)|0)+((8191&(r=(r=r+Math.imul(d,W)|0)+Math.imul(h,V)|0))<<13)|0;c=((i=i+Math.imul(h,W)|0)+(r>>>13)|0)+(Fe>>>26)|0,Fe&=67108863,o=Math.imul(b,q),r=(r=Math.imul(b,z))+Math.imul(v,q)|0,i=Math.imul(v,z),o=o+Math.imul(_,G)|0,r=(r=r+Math.imul(_,$)|0)+Math.imul(F,G)|0,i=i+Math.imul(F,$)|0,o=o+Math.imul(f,V)|0,r=(r=r+Math.imul(f,W)|0)+Math.imul(g,V)|0,i=i+Math.imul(g,W)|0;var ye=(c+(o=o+Math.imul(d,Z)|0)|0)+((8191&(r=(r=r+Math.imul(d,X)|0)+Math.imul(h,Z)|0))<<13)|0;c=((i=i+Math.imul(h,X)|0)+(r>>>13)|0)+(ye>>>26)|0,ye&=67108863,o=Math.imul(E,q),r=(r=Math.imul(E,z))+Math.imul(k,q)|0,i=Math.imul(k,z),o=o+Math.imul(b,G)|0,r=(r=r+Math.imul(b,$)|0)+Math.imul(v,G)|0,i=i+Math.imul(v,$)|0,o=o+Math.imul(_,V)|0,r=(r=r+Math.imul(_,W)|0)+Math.imul(F,V)|0,i=i+Math.imul(F,W)|0,o=o+Math.imul(f,Z)|0,r=(r=r+Math.imul(f,X)|0)+Math.imul(g,Z)|0,i=i+Math.imul(g,X)|0;var be=(c+(o=o+Math.imul(d,Q)|0)|0)+((8191&(r=(r=r+Math.imul(d,ee)|0)+Math.imul(h,Q)|0))<<13)|0;c=((i=i+Math.imul(h,ee)|0)+(r>>>13)|0)+(be>>>26)|0,be&=67108863,o=Math.imul(S,q),r=(r=Math.imul(S,z))+Math.imul(x,q)|0,i=Math.imul(x,z),o=o+Math.imul(E,G)|0,r=(r=r+Math.imul(E,$)|0)+Math.imul(k,G)|0,i=i+Math.imul(k,$)|0,o=o+Math.imul(b,V)|0,r=(r=r+Math.imul(b,W)|0)+Math.imul(v,V)|0,i=i+Math.imul(v,W)|0,o=o+Math.imul(_,Z)|0,r=(r=r+Math.imul(_,X)|0)+Math.imul(F,Z)|0,i=i+Math.imul(F,X)|0,o=o+Math.imul(f,Q)|0,r=(r=r+Math.imul(f,ee)|0)+Math.imul(g,Q)|0,i=i+Math.imul(g,ee)|0;var ve=(c+(o=o+Math.imul(d,ne)|0)|0)+((8191&(r=(r=r+Math.imul(d,oe)|0)+Math.imul(h,ne)|0))<<13)|0;c=((i=i+Math.imul(h,oe)|0)+(r>>>13)|0)+(ve>>>26)|0,ve&=67108863,o=Math.imul(A,q),r=(r=Math.imul(A,z))+Math.imul(T,q)|0,i=Math.imul(T,z),o=o+Math.imul(S,G)|0,r=(r=r+Math.imul(S,$)|0)+Math.imul(x,G)|0,i=i+Math.imul(x,$)|0,o=o+Math.imul(E,V)|0,r=(r=r+Math.imul(E,W)|0)+Math.imul(k,V)|0,i=i+Math.imul(k,W)|0,o=o+Math.imul(b,Z)|0,r=(r=r+Math.imul(b,X)|0)+Math.imul(v,Z)|0,i=i+Math.imul(v,X)|0,o=o+Math.imul(_,Q)|0,r=(r=r+Math.imul(_,ee)|0)+Math.imul(F,Q)|0,i=i+Math.imul(F,ee)|0,o=o+Math.imul(f,ne)|0,r=(r=r+Math.imul(f,oe)|0)+Math.imul(g,ne)|0,i=i+Math.imul(g,oe)|0;var we=(c+(o=o+Math.imul(d,ie)|0)|0)+((8191&(r=(r=r+Math.imul(d,ae)|0)+Math.imul(h,ie)|0))<<13)|0;c=((i=i+Math.imul(h,ae)|0)+(r>>>13)|0)+(we>>>26)|0,we&=67108863,o=Math.imul(I,q),r=(r=Math.imul(I,z))+Math.imul(M,q)|0,i=Math.imul(M,z),o=o+Math.imul(A,G)|0,r=(r=r+Math.imul(A,$)|0)+Math.imul(T,G)|0,i=i+Math.imul(T,$)|0,o=o+Math.imul(S,V)|0,r=(r=r+Math.imul(S,W)|0)+Math.imul(x,V)|0,i=i+Math.imul(x,W)|0,o=o+Math.imul(E,Z)|0,r=(r=r+Math.imul(E,X)|0)+Math.imul(k,Z)|0,i=i+Math.imul(k,X)|0,o=o+Math.imul(b,Q)|0,r=(r=r+Math.imul(b,ee)|0)+Math.imul(v,Q)|0,i=i+Math.imul(v,ee)|0,o=o+Math.imul(_,ne)|0,r=(r=r+Math.imul(_,oe)|0)+Math.imul(F,ne)|0,i=i+Math.imul(F,oe)|0,o=o+Math.imul(f,ie)|0,r=(r=r+Math.imul(f,ae)|0)+Math.imul(g,ie)|0,i=i+Math.imul(g,ae)|0;var Ee=(c+(o=o+Math.imul(d,ue)|0)|0)+((8191&(r=(r=r+Math.imul(d,ce)|0)+Math.imul(h,ue)|0))<<13)|0;c=((i=i+Math.imul(h,ce)|0)+(r>>>13)|0)+(Ee>>>26)|0,Ee&=67108863,o=Math.imul(B,q),r=(r=Math.imul(B,z))+Math.imul(N,q)|0,i=Math.imul(N,z),o=o+Math.imul(I,G)|0,r=(r=r+Math.imul(I,$)|0)+Math.imul(M,G)|0,i=i+Math.imul(M,$)|0,o=o+Math.imul(A,V)|0,r=(r=r+Math.imul(A,W)|0)+Math.imul(T,V)|0,i=i+Math.imul(T,W)|0,o=o+Math.imul(S,Z)|0,r=(r=r+Math.imul(S,X)|0)+Math.imul(x,Z)|0,i=i+Math.imul(x,X)|0,o=o+Math.imul(E,Q)|0,r=(r=r+Math.imul(E,ee)|0)+Math.imul(k,Q)|0,i=i+Math.imul(k,ee)|0,o=o+Math.imul(b,ne)|0,r=(r=r+Math.imul(b,oe)|0)+Math.imul(v,ne)|0,i=i+Math.imul(v,oe)|0,o=o+Math.imul(_,ie)|0,r=(r=r+Math.imul(_,ae)|0)+Math.imul(F,ie)|0,i=i+Math.imul(F,ae)|0,o=o+Math.imul(f,ue)|0,r=(r=r+Math.imul(f,ce)|0)+Math.imul(g,ue)|0,i=i+Math.imul(g,ce)|0;var ke=(c+(o=o+Math.imul(d,de)|0)|0)+((8191&(r=(r=r+Math.imul(d,he)|0)+Math.imul(h,de)|0))<<13)|0;c=((i=i+Math.imul(h,he)|0)+(r>>>13)|0)+(ke>>>26)|0,ke&=67108863,o=Math.imul(P,q),r=(r=Math.imul(P,z))+Math.imul(U,q)|0,i=Math.imul(U,z),o=o+Math.imul(B,G)|0,r=(r=r+Math.imul(B,$)|0)+Math.imul(N,G)|0,i=i+Math.imul(N,$)|0,o=o+Math.imul(I,V)|0,r=(r=r+Math.imul(I,W)|0)+Math.imul(M,V)|0,i=i+Math.imul(M,W)|0,o=o+Math.imul(A,Z)|0,r=(r=r+Math.imul(A,X)|0)+Math.imul(T,Z)|0,i=i+Math.imul(T,X)|0,o=o+Math.imul(S,Q)|0,r=(r=r+Math.imul(S,ee)|0)+Math.imul(x,Q)|0,i=i+Math.imul(x,ee)|0,o=o+Math.imul(E,ne)|0,r=(r=r+Math.imul(E,oe)|0)+Math.imul(k,ne)|0,i=i+Math.imul(k,oe)|0,o=o+Math.imul(b,ie)|0,r=(r=r+Math.imul(b,ae)|0)+Math.imul(v,ie)|0,i=i+Math.imul(v,ae)|0,o=o+Math.imul(_,ue)|0,r=(r=r+Math.imul(_,ce)|0)+Math.imul(F,ue)|0,i=i+Math.imul(F,ce)|0,o=o+Math.imul(f,de)|0,r=(r=r+Math.imul(f,he)|0)+Math.imul(g,de)|0,i=i+Math.imul(g,he)|0;var De=(c+(o=o+Math.imul(d,fe)|0)|0)+((8191&(r=(r=r+Math.imul(d,ge)|0)+Math.imul(h,fe)|0))<<13)|0;c=((i=i+Math.imul(h,ge)|0)+(r>>>13)|0)+(De>>>26)|0,De&=67108863,o=Math.imul(P,G),r=(r=Math.imul(P,$))+Math.imul(U,G)|0,i=Math.imul(U,$),o=o+Math.imul(B,V)|0,r=(r=r+Math.imul(B,W)|0)+Math.imul(N,V)|0,i=i+Math.imul(N,W)|0,o=o+Math.imul(I,Z)|0,r=(r=r+Math.imul(I,X)|0)+Math.imul(M,Z)|0,i=i+Math.imul(M,X)|0,o=o+Math.imul(A,Q)|0,r=(r=r+Math.imul(A,ee)|0)+Math.imul(T,Q)|0,i=i+Math.imul(T,ee)|0,o=o+Math.imul(S,ne)|0,r=(r=r+Math.imul(S,oe)|0)+Math.imul(x,ne)|0,i=i+Math.imul(x,oe)|0,o=o+Math.imul(E,ie)|0,r=(r=r+Math.imul(E,ae)|0)+Math.imul(k,ie)|0,i=i+Math.imul(k,ae)|0,o=o+Math.imul(b,ue)|0,r=(r=r+Math.imul(b,ce)|0)+Math.imul(v,ue)|0,i=i+Math.imul(v,ce)|0,o=o+Math.imul(_,de)|0,r=(r=r+Math.imul(_,he)|0)+Math.imul(F,de)|0,i=i+Math.imul(F,he)|0;var Se=(c+(o=o+Math.imul(f,fe)|0)|0)+((8191&(r=(r=r+Math.imul(f,ge)|0)+Math.imul(g,fe)|0))<<13)|0;c=((i=i+Math.imul(g,ge)|0)+(r>>>13)|0)+(Se>>>26)|0,Se&=67108863,o=Math.imul(P,V),r=(r=Math.imul(P,W))+Math.imul(U,V)|0,i=Math.imul(U,W),o=o+Math.imul(B,Z)|0,r=(r=r+Math.imul(B,X)|0)+Math.imul(N,Z)|0,i=i+Math.imul(N,X)|0,o=o+Math.imul(I,Q)|0,r=(r=r+Math.imul(I,ee)|0)+Math.imul(M,Q)|0,i=i+Math.imul(M,ee)|0,o=o+Math.imul(A,ne)|0,r=(r=r+Math.imul(A,oe)|0)+Math.imul(T,ne)|0,i=i+Math.imul(T,oe)|0,o=o+Math.imul(S,ie)|0,r=(r=r+Math.imul(S,ae)|0)+Math.imul(x,ie)|0,i=i+Math.imul(x,ae)|0,o=o+Math.imul(E,ue)|0,r=(r=r+Math.imul(E,ce)|0)+Math.imul(k,ue)|0,i=i+Math.imul(k,ce)|0,o=o+Math.imul(b,de)|0,r=(r=r+Math.imul(b,he)|0)+Math.imul(v,de)|0,i=i+Math.imul(v,he)|0;var xe=(c+(o=o+Math.imul(_,fe)|0)|0)+((8191&(r=(r=r+Math.imul(_,ge)|0)+Math.imul(F,fe)|0))<<13)|0;c=((i=i+Math.imul(F,ge)|0)+(r>>>13)|0)+(xe>>>26)|0,xe&=67108863,o=Math.imul(P,Z),r=(r=Math.imul(P,X))+Math.imul(U,Z)|0,i=Math.imul(U,X),o=o+Math.imul(B,Q)|0,r=(r=r+Math.imul(B,ee)|0)+Math.imul(N,Q)|0,i=i+Math.imul(N,ee)|0,o=o+Math.imul(I,ne)|0,r=(r=r+Math.imul(I,oe)|0)+Math.imul(M,ne)|0,i=i+Math.imul(M,oe)|0,o=o+Math.imul(A,ie)|0,r=(r=r+Math.imul(A,ae)|0)+Math.imul(T,ie)|0,i=i+Math.imul(T,ae)|0,o=o+Math.imul(S,ue)|0,r=(r=r+Math.imul(S,ce)|0)+Math.imul(x,ue)|0,i=i+Math.imul(x,ce)|0,o=o+Math.imul(E,de)|0,r=(r=r+Math.imul(E,he)|0)+Math.imul(k,de)|0,i=i+Math.imul(k,he)|0;var Ce=(c+(o=o+Math.imul(b,fe)|0)|0)+((8191&(r=(r=r+Math.imul(b,ge)|0)+Math.imul(v,fe)|0))<<13)|0;c=((i=i+Math.imul(v,ge)|0)+(r>>>13)|0)+(Ce>>>26)|0,Ce&=67108863,o=Math.imul(P,Q),r=(r=Math.imul(P,ee))+Math.imul(U,Q)|0,i=Math.imul(U,ee),o=o+Math.imul(B,ne)|0,r=(r=r+Math.imul(B,oe)|0)+Math.imul(N,ne)|0,i=i+Math.imul(N,oe)|0,o=o+Math.imul(I,ie)|0,r=(r=r+Math.imul(I,ae)|0)+Math.imul(M,ie)|0,i=i+Math.imul(M,ae)|0,o=o+Math.imul(A,ue)|0,r=(r=r+Math.imul(A,ce)|0)+Math.imul(T,ue)|0,i=i+Math.imul(T,ce)|0,o=o+Math.imul(S,de)|0,r=(r=r+Math.imul(S,he)|0)+Math.imul(x,de)|0,i=i+Math.imul(x,he)|0;var Ae=(c+(o=o+Math.imul(E,fe)|0)|0)+((8191&(r=(r=r+Math.imul(E,ge)|0)+Math.imul(k,fe)|0))<<13)|0;c=((i=i+Math.imul(k,ge)|0)+(r>>>13)|0)+(Ae>>>26)|0,Ae&=67108863,o=Math.imul(P,ne),r=(r=Math.imul(P,oe))+Math.imul(U,ne)|0,i=Math.imul(U,oe),o=o+Math.imul(B,ie)|0,r=(r=r+Math.imul(B,ae)|0)+Math.imul(N,ie)|0,i=i+Math.imul(N,ae)|0,o=o+Math.imul(I,ue)|0,r=(r=r+Math.imul(I,ce)|0)+Math.imul(M,ue)|0,i=i+Math.imul(M,ce)|0,o=o+Math.imul(A,de)|0,r=(r=r+Math.imul(A,he)|0)+Math.imul(T,de)|0,i=i+Math.imul(T,he)|0;var Te=(c+(o=o+Math.imul(S,fe)|0)|0)+((8191&(r=(r=r+Math.imul(S,ge)|0)+Math.imul(x,fe)|0))<<13)|0;c=((i=i+Math.imul(x,ge)|0)+(r>>>13)|0)+(Te>>>26)|0,Te&=67108863,o=Math.imul(P,ie),r=(r=Math.imul(P,ae))+Math.imul(U,ie)|0,i=Math.imul(U,ae),o=o+Math.imul(B,ue)|0,r=(r=r+Math.imul(B,ce)|0)+Math.imul(N,ue)|0,i=i+Math.imul(N,ce)|0,o=o+Math.imul(I,de)|0,r=(r=r+Math.imul(I,he)|0)+Math.imul(M,de)|0,i=i+Math.imul(M,he)|0;var Re=(c+(o=o+Math.imul(A,fe)|0)|0)+((8191&(r=(r=r+Math.imul(A,ge)|0)+Math.imul(T,fe)|0))<<13)|0;c=((i=i+Math.imul(T,ge)|0)+(r>>>13)|0)+(Re>>>26)|0,Re&=67108863,o=Math.imul(P,ue),r=(r=Math.imul(P,ce))+Math.imul(U,ue)|0,i=Math.imul(U,ce),o=o+Math.imul(B,de)|0,r=(r=r+Math.imul(B,he)|0)+Math.imul(N,de)|0,i=i+Math.imul(N,he)|0;var Ie=(c+(o=o+Math.imul(I,fe)|0)|0)+((8191&(r=(r=r+Math.imul(I,ge)|0)+Math.imul(M,fe)|0))<<13)|0;c=((i=i+Math.imul(M,ge)|0)+(r>>>13)|0)+(Ie>>>26)|0,Ie&=67108863,o=Math.imul(P,de),r=(r=Math.imul(P,he))+Math.imul(U,de)|0,i=Math.imul(U,he);var Me=(c+(o=o+Math.imul(B,fe)|0)|0)+((8191&(r=(r=r+Math.imul(B,ge)|0)+Math.imul(N,fe)|0))<<13)|0;c=((i=i+Math.imul(N,ge)|0)+(r>>>13)|0)+(Me>>>26)|0,Me&=67108863;var Oe=(c+(o=Math.imul(P,fe))|0)+((8191&(r=(r=Math.imul(P,ge))+Math.imul(U,fe)|0))<<13)|0;return c=((i=Math.imul(U,ge))+(r>>>13)|0)+(Oe>>>26)|0,Oe&=67108863,u[0]=me,u[1]=_e,u[2]=Fe,u[3]=ye,u[4]=be,u[5]=ve,u[6]=we,u[7]=Ee,u[8]=ke,u[9]=De,u[10]=Se,u[11]=xe,u[12]=Ce,u[13]=Ae,u[14]=Te,u[15]=Re,u[16]=Ie,u[17]=Me,u[18]=Oe,0!==c&&(u[19]=c,n.length++),n};function g(e,t,n){return(new m).mulp(e,t,n)}function m(e,t){this.x=e,this.y=t}Math.imul||(f=p),i.prototype.mulTo=function(e,t){var n=this.length+e.length;return 10===this.length&&10===e.length?f(this,e,t):n<63?p(this,e,t):n<1024?function(e,t,n){n.negative=t.negative^e.negative,n.length=e.length+t.length;for(var o=0,r=0,i=0;i>>26)|0)>>>26,a&=67108863}n.words[i]=s,o=a,a=r}return 0!==o?n.words[i]=o:n.length--,n.strip()}(this,e,t):g(this,e,t)},m.prototype.makeRBT=function(e){for(var t=new Array(e),n=i.prototype._countBits(e)-1,o=0;o>=1;return o},m.prototype.permute=function(e,t,n,o,r,i){for(var a=0;a>>=1)r++;return 1<>>=13,n[2*a+1]=8191&i,i>>>=13;for(a=2*t;a>=26,t+=r/67108864|0,t+=i>>>26,this.words[n]=67108863&i}return 0!==t&&(this.words[n]=t,this.length++),this},i.prototype.muln=function(e){return this.clone().imuln(e)},i.prototype.sqr=function(){return this.mul(this)},i.prototype.isqr=function(){return this.imul(this.clone())},i.prototype.pow=function(e){var t=function(e){for(var t=new Array(e.bitLength()),n=0;n>>r}return t}(e);if(0===t.length)return new i(1);for(var n=this,o=0;o=0);var t,n=e%26,r=(e-n)/26,i=67108863>>>26-n<<26-n;if(0!==n){var a=0;for(t=0;t>>26-n}a&&(this.words[t]=a,this.length++)}if(0!==r){for(t=this.length-1;t>=0;t--)this.words[t+r]=this.words[t];for(t=0;t=0),r=t?(t-t%26)/26:0;var i=e%26,a=Math.min((e-i)/26,this.length),s=67108863^67108863>>>i<a)for(this.length-=a,c=0;c=0&&(0!==l||c>=r);c--){var d=0|this.words[c];this.words[c]=l<<26-i|d>>>i,l=d&s}return u&&0!==l&&(u.words[u.length++]=l),0===this.length&&(this.words[0]=0,this.length=1),this.strip()},i.prototype.ishrn=function(e,t,n){return o(0===this.negative),this.iushrn(e,t,n)},i.prototype.shln=function(e){return this.clone().ishln(e)},i.prototype.ushln=function(e){return this.clone().iushln(e)},i.prototype.shrn=function(e){return this.clone().ishrn(e)},i.prototype.ushrn=function(e){return this.clone().iushrn(e)},i.prototype.testn=function(e){o("number"==typeof e&&e>=0);var t=e%26,n=(e-t)/26,r=1<=0);var t=e%26,n=(e-t)/26;if(o(0===this.negative,"imaskn works only with positive numbers"),this.length<=n)return this;if(0!==t&&n++,this.length=Math.min(n,this.length),0!==t){var r=67108863^67108863>>>t<=67108864;t++)this.words[t]-=67108864,t===this.length-1?this.words[t+1]=1:this.words[t+1]++;return this.length=Math.max(this.length,t+1),this},i.prototype.isubn=function(e){if(o("number"==typeof e),o(e<67108864),e<0)return this.iaddn(-e);if(0!==this.negative)return this.negative=0,this.iaddn(e),this.negative=1,this;if(this.words[0]-=e,1===this.length&&this.words[0]<0)this.words[0]=-this.words[0],this.negative=1;else for(var t=0;t>26)-(u/67108864|0),this.words[r+n]=67108863&i}for(;r>26,this.words[r+n]=67108863&i;if(0===s)return this.strip();for(o(-1===s),s=0,r=0;r>26,this.words[r]=67108863&i;return this.negative=1,this.strip()},i.prototype._wordDiv=function(e,t){var n=(this.length,e.length),o=this.clone(),r=e,a=0|r.words[r.length-1];0!=(n=26-this._countBits(a))&&(r=r.ushln(n),o.iushln(n),a=0|r.words[r.length-1]);var s,u=o.length-r.length;if("mod"!==t){(s=new i(null)).length=u+1,s.words=new Array(s.length);for(var c=0;c=0;d--){var h=67108864*(0|o.words[r.length+d])+(0|o.words[r.length+d-1]);for(h=Math.min(h/a|0,67108863),o._ishlnsubmul(r,h,d);0!==o.negative;)h--,o.negative=0,o._ishlnsubmul(r,1,d),o.isZero()||(o.negative^=1);s&&(s.words[d]=h)}return s&&s.strip(),o.strip(),"div"!==t&&0!==n&&o.iushrn(n),{div:s||null,mod:o}},i.prototype.divmod=function(e,t,n){return o(!e.isZero()),this.isZero()?{div:new i(0),mod:new i(0)}:0!==this.negative&&0===e.negative?(s=this.neg().divmod(e,t),"mod"!==t&&(r=s.div.neg()),"div"!==t&&(a=s.mod.neg(),n&&0!==a.negative&&a.iadd(e)),{div:r,mod:a}):0===this.negative&&0!==e.negative?(s=this.divmod(e.neg(),t),"mod"!==t&&(r=s.div.neg()),{div:r,mod:s.mod}):0!=(this.negative&e.negative)?(s=this.neg().divmod(e.neg(),t),"div"!==t&&(a=s.mod.neg(),n&&0!==a.negative&&a.isub(e)),{div:s.div,mod:a}):e.length>this.length||this.cmp(e)<0?{div:new i(0),mod:this}:1===e.length?"div"===t?{div:this.divn(e.words[0]),mod:null}:"mod"===t?{div:null,mod:new i(this.modn(e.words[0]))}:{div:this.divn(e.words[0]),mod:new i(this.modn(e.words[0]))}:this._wordDiv(e,t);var r,a,s},i.prototype.div=function(e){return this.divmod(e,"div",!1).div},i.prototype.mod=function(e){return this.divmod(e,"mod",!1).mod},i.prototype.umod=function(e){return this.divmod(e,"mod",!0).mod},i.prototype.divRound=function(e){var t=this.divmod(e);if(t.mod.isZero())return t.div;var n=0!==t.div.negative?t.mod.isub(e):t.mod,o=e.ushrn(1),r=e.andln(1),i=n.cmp(o);return i<0||1===r&&0===i?t.div:0!==t.div.negative?t.div.isubn(1):t.div.iaddn(1)},i.prototype.modn=function(e){o(e<=67108863);for(var t=(1<<26)%e,n=0,r=this.length-1;r>=0;r--)n=(t*n+(0|this.words[r]))%e;return n},i.prototype.idivn=function(e){o(e<=67108863);for(var t=0,n=this.length-1;n>=0;n--){var r=(0|this.words[n])+67108864*t;this.words[n]=r/e|0,t=r%e}return this.strip()},i.prototype.divn=function(e){return this.clone().idivn(e)},i.prototype.egcd=function(e){o(0===e.negative),o(!e.isZero());var t=this,n=e.clone();t=0!==t.negative?t.umod(e):t.clone();for(var r=new i(1),a=new i(0),s=new i(0),u=new i(1),c=0;t.isEven()&&n.isEven();)t.iushrn(1),n.iushrn(1),++c;for(var l=n.clone(),d=t.clone();!t.isZero();){for(var h=0,p=1;0==(t.words[0]&p)&&h<26;++h,p<<=1);if(h>0)for(t.iushrn(h);h-- >0;)(r.isOdd()||a.isOdd())&&(r.iadd(l),a.isub(d)),r.iushrn(1),a.iushrn(1);for(var f=0,g=1;0==(n.words[0]&g)&&f<26;++f,g<<=1);if(f>0)for(n.iushrn(f);f-- >0;)(s.isOdd()||u.isOdd())&&(s.iadd(l),u.isub(d)),s.iushrn(1),u.iushrn(1);t.cmp(n)>=0?(t.isub(n),r.isub(s),a.isub(u)):(n.isub(t),s.isub(r),u.isub(a))}return{a:s,b:u,gcd:n.iushln(c)}},i.prototype._invmp=function(e){o(0===e.negative),o(!e.isZero());var t=this,n=e.clone();t=0!==t.negative?t.umod(e):t.clone();for(var r,a=new i(1),s=new i(0),u=n.clone();t.cmpn(1)>0&&n.cmpn(1)>0;){for(var c=0,l=1;0==(t.words[0]&l)&&c<26;++c,l<<=1);if(c>0)for(t.iushrn(c);c-- >0;)a.isOdd()&&a.iadd(u),a.iushrn(1);for(var d=0,h=1;0==(n.words[0]&h)&&d<26;++d,h<<=1);if(d>0)for(n.iushrn(d);d-- >0;)s.isOdd()&&s.iadd(u),s.iushrn(1);t.cmp(n)>=0?(t.isub(n),a.isub(s)):(n.isub(t),s.isub(a))}return(r=0===t.cmpn(1)?a:s).cmpn(0)<0&&r.iadd(e),r},i.prototype.gcd=function(e){if(this.isZero())return e.abs();if(e.isZero())return this.abs();var t=this.clone(),n=e.clone();t.negative=0,n.negative=0;for(var o=0;t.isEven()&&n.isEven();o++)t.iushrn(1),n.iushrn(1);for(;;){for(;t.isEven();)t.iushrn(1);for(;n.isEven();)n.iushrn(1);var r=t.cmp(n);if(r<0){var i=t;t=n,n=i}else if(0===r||0===n.cmpn(1))break;t.isub(n)}return n.iushln(o)},i.prototype.invm=function(e){return this.egcd(e).a.umod(e)},i.prototype.isEven=function(){return 0==(1&this.words[0])},i.prototype.isOdd=function(){return 1==(1&this.words[0])},i.prototype.andln=function(e){return this.words[0]&e},i.prototype.bincn=function(e){o("number"==typeof e);var t=e%26,n=(e-t)/26,r=1<>>26,s&=67108863,this.words[a]=s}return 0!==i&&(this.words[a]=i,this.length++),this},i.prototype.isZero=function(){return 1===this.length&&0===this.words[0]},i.prototype.cmpn=function(e){var t,n=e<0;if(0!==this.negative&&!n)return-1;if(0===this.negative&&n)return 1;if(this.strip(),this.length>1)t=1;else{n&&(e=-e),o(e<=67108863,"Number is too big");var r=0|this.words[0];t=r===e?0:re.length)return 1;if(this.length=0;n--){var o=0|this.words[n],r=0|e.words[n];if(o!==r){or&&(t=1);break}}return t},i.prototype.gtn=function(e){return 1===this.cmpn(e)},i.prototype.gt=function(e){return 1===this.cmp(e)},i.prototype.gten=function(e){return this.cmpn(e)>=0},i.prototype.gte=function(e){return this.cmp(e)>=0},i.prototype.ltn=function(e){return-1===this.cmpn(e)},i.prototype.lt=function(e){return-1===this.cmp(e)},i.prototype.lten=function(e){return this.cmpn(e)<=0},i.prototype.lte=function(e){return this.cmp(e)<=0},i.prototype.eqn=function(e){return 0===this.cmpn(e)},i.prototype.eq=function(e){return 0===this.cmp(e)},i.red=function(e){return new E(e)},i.prototype.toRed=function(e){return o(!this.red,"Already a number in reduction context"),o(0===this.negative,"red works only with positives"),e.convertTo(this)._forceRed(e)},i.prototype.fromRed=function(){return o(this.red,"fromRed works only with numbers in reduction context"),this.red.convertFrom(this)},i.prototype._forceRed=function(e){return this.red=e,this},i.prototype.forceRed=function(e){return o(!this.red,"Already a number in reduction context"),this._forceRed(e)},i.prototype.redAdd=function(e){return o(this.red,"redAdd works only with red numbers"),this.red.add(this,e)},i.prototype.redIAdd=function(e){return o(this.red,"redIAdd works only with red numbers"),this.red.iadd(this,e)},i.prototype.redSub=function(e){return o(this.red,"redSub works only with red numbers"),this.red.sub(this,e)},i.prototype.redISub=function(e){return o(this.red,"redISub works only with red numbers"),this.red.isub(this,e)},i.prototype.redShl=function(e){return o(this.red,"redShl works only with red numbers"),this.red.shl(this,e)},i.prototype.redMul=function(e){return o(this.red,"redMul works only with red numbers"),this.red._verify2(this,e),this.red.mul(this,e)},i.prototype.redIMul=function(e){return o(this.red,"redMul works only with red numbers"),this.red._verify2(this,e),this.red.imul(this,e)},i.prototype.redSqr=function(){return o(this.red,"redSqr works only with red numbers"),this.red._verify1(this),this.red.sqr(this)},i.prototype.redISqr=function(){return o(this.red,"redISqr works only with red numbers"),this.red._verify1(this),this.red.isqr(this)},i.prototype.redSqrt=function(){return o(this.red,"redSqrt works only with red numbers"),this.red._verify1(this),this.red.sqrt(this)},i.prototype.redInvm=function(){return o(this.red,"redInvm works only with red numbers"),this.red._verify1(this),this.red.invm(this)},i.prototype.redNeg=function(){return o(this.red,"redNeg works only with red numbers"),this.red._verify1(this),this.red.neg(this)},i.prototype.redPow=function(e){return o(this.red&&!e.red,"redPow(normalNum)"),this.red._verify1(this),this.red.pow(this,e)};var _={k256:null,p224:null,p192:null,p25519:null};function F(e,t){this.name=e,this.p=new i(t,16),this.n=this.p.bitLength(),this.k=new i(1).iushln(this.n).isub(this.p),this.tmp=this._tmp()}function y(){F.call(this,"k256","ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f")}function b(){F.call(this,"p224","ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001")}function v(){F.call(this,"p192","ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff")}function w(){F.call(this,"25519","7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed")}function E(e){if("string"==typeof e){var t=i._prime(e);this.m=t.p,this.prime=t}else o(e.gtn(1),"modulus must be greater than 1"),this.m=e,this.prime=null}function k(e){E.call(this,e),this.shift=this.m.bitLength(),this.shift%26!=0&&(this.shift+=26-this.shift%26),this.r=new i(1).iushln(this.shift),this.r2=this.imod(this.r.sqr()),this.rinv=this.r._invmp(this.m),this.minv=this.rinv.mul(this.r).isubn(1).div(this.m),this.minv=this.minv.umod(this.r),this.minv=this.r.sub(this.minv)}F.prototype._tmp=function(){var e=new i(null);return e.words=new Array(Math.ceil(this.n/13)),e},F.prototype.ireduce=function(e){var t,n=e;do{this.split(n,this.tmp),t=(n=(n=this.imulK(n)).iadd(this.tmp)).bitLength()}while(t>this.n);var o=t0?n.isub(this.p):void 0!==n.strip?n.strip():n._strip(),n},F.prototype.split=function(e,t){e.iushrn(this.n,0,t)},F.prototype.imulK=function(e){return e.imul(this.k)},r(y,F),y.prototype.split=function(e,t){for(var n=4194303,o=Math.min(e.length,9),r=0;r>>22,i=a}i>>>=22,e.words[r-10]=i,0===i&&e.length>10?e.length-=10:e.length-=9},y.prototype.imulK=function(e){e.words[e.length]=0,e.words[e.length+1]=0,e.length+=2;for(var t=0,n=0;n>>=26,e.words[n]=r,t=o}return 0!==t&&(e.words[e.length++]=t),e},i._prime=function(e){if(_[e])return _[e];var t;if("k256"===e)t=new y;else if("p224"===e)t=new b;else if("p192"===e)t=new v;else{if("p25519"!==e)throw new Error("Unknown prime "+e);t=new w}return _[e]=t,t},E.prototype._verify1=function(e){o(0===e.negative,"red works only with positives"),o(e.red,"red works only with red numbers")},E.prototype._verify2=function(e,t){o(0==(e.negative|t.negative),"red works only with positives"),o(e.red&&e.red===t.red,"red works only with red numbers")},E.prototype.imod=function(e){return this.prime?this.prime.ireduce(e)._forceRed(this):e.umod(this.m)._forceRed(this)},E.prototype.neg=function(e){return e.isZero()?e.clone():this.m.sub(e)._forceRed(this)},E.prototype.add=function(e,t){this._verify2(e,t);var n=e.add(t);return n.cmp(this.m)>=0&&n.isub(this.m),n._forceRed(this)},E.prototype.iadd=function(e,t){this._verify2(e,t);var n=e.iadd(t);return n.cmp(this.m)>=0&&n.isub(this.m),n},E.prototype.sub=function(e,t){this._verify2(e,t);var n=e.sub(t);return n.cmpn(0)<0&&n.iadd(this.m),n._forceRed(this)},E.prototype.isub=function(e,t){this._verify2(e,t);var n=e.isub(t);return n.cmpn(0)<0&&n.iadd(this.m),n},E.prototype.shl=function(e,t){return this._verify1(e),this.imod(e.ushln(t))},E.prototype.imul=function(e,t){return this._verify2(e,t),this.imod(e.imul(t))},E.prototype.mul=function(e,t){return this._verify2(e,t),this.imod(e.mul(t))},E.prototype.isqr=function(e){return this.imul(e,e.clone())},E.prototype.sqr=function(e){return this.mul(e,e)},E.prototype.sqrt=function(e){if(e.isZero())return e.clone();var t=this.m.andln(3);if(o(t%2==1),3===t){var n=this.m.add(new i(1)).iushrn(2);return this.pow(e,n)}for(var r=this.m.subn(1),a=0;!r.isZero()&&0===r.andln(1);)a++,r.iushrn(1);o(!r.isZero());var s=new i(1).toRed(this),u=s.redNeg(),c=this.m.subn(1).iushrn(1),l=this.m.bitLength();for(l=new i(2*l*l).toRed(this);0!==this.pow(l,c).cmp(u);)l.redIAdd(u);for(var d=this.pow(l,r),h=this.pow(e,r.addn(1).iushrn(1)),p=this.pow(e,r),f=a;0!==p.cmp(s);){for(var g=p,m=0;0!==g.cmp(s);m++)g=g.redSqr();o(m=0;o--){for(var c=t.words[o],l=u-1;l>=0;l--){var d=c>>l&1;r!==n[0]&&(r=this.sqr(r)),0!==d||0!==a?(a<<=1,a|=d,(4==++s||0===o&&0===l)&&(r=this.mul(r,n[a]),s=0,a=0)):s=0}u=26}return r},E.prototype.convertTo=function(e){var t=e.umod(this.m);return t===e?t.clone():t},E.prototype.convertFrom=function(e){var t=e.clone();return t.red=null,t},i.mont=function(e){return new k(e)},r(k,E),k.prototype.convertTo=function(e){return this.imod(e.ushln(this.shift))},k.prototype.convertFrom=function(e){var t=this.imod(e.mul(this.rinv));return t.red=null,t},k.prototype.imul=function(e,t){if(e.isZero()||t.isZero())return e.words[0]=0,e.length=1,e;var n=e.imul(t),o=n.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m),r=n.isub(o).iushrn(this.shift),i=r;return r.cmp(this.m)>=0?i=r.isub(this.m):r.cmpn(0)<0&&(i=r.iadd(this.m)),i._forceRed(this)},k.prototype.mul=function(e,t){if(e.isZero()||t.isZero())return new i(0)._forceRed(this);var n=e.mul(t),o=n.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m),r=n.isub(o).iushrn(this.shift),a=r;return r.cmp(this.m)>=0?a=r.isub(this.m):r.cmpn(0)<0&&(a=r.iadd(this.m)),a._forceRed(this)},k.prototype.invm=function(e){return this.imod(e._invmp(this.m).mul(this.r2))._forceRed(this)}}(e=n.nmd(e),this)},86266:(e,t,n)=>{"use strict";var o=t;o.version=n(17519).i8,o.utils=n(80953),o.rand=n(29931),o.curve=n(88254),o.curves=n(45427),o.ec=n(57954),o.eddsa=n(65980)},4918:(e,t,n)=>{"use strict";var o=n(73785),r=n(80953),i=r.getNAF,a=r.getJSF,s=r.assert;function u(e,t){this.type=e,this.p=new o(t.p,16),this.red=t.prime?o.red(t.prime):o.mont(this.p),this.zero=new o(0).toRed(this.red),this.one=new o(1).toRed(this.red),this.two=new o(2).toRed(this.red),this.n=t.n&&new o(t.n,16),this.g=t.g&&this.pointFromJSON(t.g,t.gRed),this._wnafT1=new Array(4),this._wnafT2=new Array(4),this._wnafT3=new Array(4),this._wnafT4=new Array(4),this._bitLength=this.n?this.n.bitLength():0;var n=this.n&&this.p.div(this.n);!n||n.cmpn(100)>0?this.redN=null:(this._maxwellTrick=!0,this.redN=this.n.toRed(this.red))}function c(e,t){this.curve=e,this.type=t,this.precomputed=null}e.exports=u,u.prototype.point=function(){throw new Error("Not implemented")},u.prototype.validate=function(){throw new Error("Not implemented")},u.prototype._fixedNafMul=function(e,t){s(e.precomputed);var n=e._getDoubles(),o=i(t,1,this._bitLength),r=(1<=a;l--)u=(u<<1)+o[l];c.push(u)}for(var d=this.jpoint(null,null,null),h=this.jpoint(null,null,null),p=r;p>0;p--){for(a=0;a=0;c--){for(var l=0;c>=0&&0===a[c];c--)l++;if(c>=0&&l++,u=u.dblp(l),c<0)break;var d=a[c];s(0!==d),u="affine"===e.type?d>0?u.mixedAdd(r[d-1>>1]):u.mixedAdd(r[-d-1>>1].neg()):d>0?u.add(r[d-1>>1]):u.add(r[-d-1>>1].neg())}return"affine"===e.type?u.toP():u},u.prototype._wnafMulAdd=function(e,t,n,o,r){var s,u,c,l=this._wnafT1,d=this._wnafT2,h=this._wnafT3,p=0;for(s=0;s=1;s-=2){var g=s-1,m=s;if(1===l[g]&&1===l[m]){var _=[t[g],null,null,t[m]];0===t[g].y.cmp(t[m].y)?(_[1]=t[g].add(t[m]),_[2]=t[g].toJ().mixedAdd(t[m].neg())):0===t[g].y.cmp(t[m].y.redNeg())?(_[1]=t[g].toJ().mixedAdd(t[m]),_[2]=t[g].add(t[m].neg())):(_[1]=t[g].toJ().mixedAdd(t[m]),_[2]=t[g].toJ().mixedAdd(t[m].neg()));var F=[-3,-1,-5,-7,0,7,5,1,3],y=a(n[g],n[m]);for(p=Math.max(y[0].length,p),h[g]=new Array(p),h[m]=new Array(p),u=0;u=0;s--){for(var k=0;s>=0;){var D=!0;for(u=0;u=0&&k++,w=w.dblp(k),s<0)break;for(u=0;u0?c=d[u][S-1>>1]:S<0&&(c=d[u][-S-1>>1].neg()),w="affine"===c.type?w.mixedAdd(c):w.add(c))}}for(s=0;s=Math.ceil((e.bitLength()+1)/t.step)},c.prototype._getDoubles=function(e,t){if(this.precomputed&&this.precomputed.doubles)return this.precomputed.doubles;for(var n=[this],o=this,r=0;r{"use strict";var o=n(80953),r=n(73785),i=n(35717),a=n(4918),s=o.assert;function u(e){this.twisted=1!=(0|e.a),this.mOneA=this.twisted&&-1==(0|e.a),this.extended=this.mOneA,a.call(this,"edwards",e),this.a=new r(e.a,16).umod(this.red.m),this.a=this.a.toRed(this.red),this.c=new r(e.c,16).toRed(this.red),this.c2=this.c.redSqr(),this.d=new r(e.d,16).toRed(this.red),this.dd=this.d.redAdd(this.d),s(!this.twisted||0===this.c.fromRed().cmpn(1)),this.oneC=1==(0|e.c)}function c(e,t,n,o,i){a.BasePoint.call(this,e,"projective"),null===t&&null===n&&null===o?(this.x=this.curve.zero,this.y=this.curve.one,this.z=this.curve.one,this.t=this.curve.zero,this.zOne=!0):(this.x=new r(t,16),this.y=new r(n,16),this.z=o?new r(o,16):this.curve.one,this.t=i&&new r(i,16),this.x.red||(this.x=this.x.toRed(this.curve.red)),this.y.red||(this.y=this.y.toRed(this.curve.red)),this.z.red||(this.z=this.z.toRed(this.curve.red)),this.t&&!this.t.red&&(this.t=this.t.toRed(this.curve.red)),this.zOne=this.z===this.curve.one,this.curve.extended&&!this.t&&(this.t=this.x.redMul(this.y),this.zOne||(this.t=this.t.redMul(this.z.redInvm()))))}i(u,a),e.exports=u,u.prototype._mulA=function(e){return this.mOneA?e.redNeg():this.a.redMul(e)},u.prototype._mulC=function(e){return this.oneC?e:this.c.redMul(e)},u.prototype.jpoint=function(e,t,n,o){return this.point(e,t,n,o)},u.prototype.pointFromX=function(e,t){(e=new r(e,16)).red||(e=e.toRed(this.red));var n=e.redSqr(),o=this.c2.redSub(this.a.redMul(n)),i=this.one.redSub(this.c2.redMul(this.d).redMul(n)),a=o.redMul(i.redInvm()),s=a.redSqrt();if(0!==s.redSqr().redSub(a).cmp(this.zero))throw new Error("invalid point");var u=s.fromRed().isOdd();return(t&&!u||!t&&u)&&(s=s.redNeg()),this.point(e,s)},u.prototype.pointFromY=function(e,t){(e=new r(e,16)).red||(e=e.toRed(this.red));var n=e.redSqr(),o=n.redSub(this.c2),i=n.redMul(this.d).redMul(this.c2).redSub(this.a),a=o.redMul(i.redInvm());if(0===a.cmp(this.zero)){if(t)throw new Error("invalid point");return this.point(this.zero,e)}var s=a.redSqrt();if(0!==s.redSqr().redSub(a).cmp(this.zero))throw new Error("invalid point");return s.fromRed().isOdd()!==t&&(s=s.redNeg()),this.point(s,e)},u.prototype.validate=function(e){if(e.isInfinity())return!0;e.normalize();var t=e.x.redSqr(),n=e.y.redSqr(),o=t.redMul(this.a).redAdd(n),r=this.c2.redMul(this.one.redAdd(this.d.redMul(t).redMul(n)));return 0===o.cmp(r)},i(c,a.BasePoint),u.prototype.pointFromJSON=function(e){return c.fromJSON(this,e)},u.prototype.point=function(e,t,n,o){return new c(this,e,t,n,o)},c.fromJSON=function(e,t){return new c(e,t[0],t[1],t[2])},c.prototype.inspect=function(){return this.isInfinity()?"":""},c.prototype.isInfinity=function(){return 0===this.x.cmpn(0)&&(0===this.y.cmp(this.z)||this.zOne&&0===this.y.cmp(this.curve.c))},c.prototype._extDbl=function(){var e=this.x.redSqr(),t=this.y.redSqr(),n=this.z.redSqr();n=n.redIAdd(n);var o=this.curve._mulA(e),r=this.x.redAdd(this.y).redSqr().redISub(e).redISub(t),i=o.redAdd(t),a=i.redSub(n),s=o.redSub(t),u=r.redMul(a),c=i.redMul(s),l=r.redMul(s),d=a.redMul(i);return this.curve.point(u,c,d,l)},c.prototype._projDbl=function(){var e,t,n,o,r,i,a=this.x.redAdd(this.y).redSqr(),s=this.x.redSqr(),u=this.y.redSqr();if(this.curve.twisted){var c=(o=this.curve._mulA(s)).redAdd(u);this.zOne?(e=a.redSub(s).redSub(u).redMul(c.redSub(this.curve.two)),t=c.redMul(o.redSub(u)),n=c.redSqr().redSub(c).redSub(c)):(r=this.z.redSqr(),i=c.redSub(r).redISub(r),e=a.redSub(s).redISub(u).redMul(i),t=c.redMul(o.redSub(u)),n=c.redMul(i))}else o=s.redAdd(u),r=this.curve._mulC(this.z).redSqr(),i=o.redSub(r).redSub(r),e=this.curve._mulC(a.redISub(o)).redMul(i),t=this.curve._mulC(o).redMul(s.redISub(u)),n=o.redMul(i);return this.curve.point(e,t,n)},c.prototype.dbl=function(){return this.isInfinity()?this:this.curve.extended?this._extDbl():this._projDbl()},c.prototype._extAdd=function(e){var t=this.y.redSub(this.x).redMul(e.y.redSub(e.x)),n=this.y.redAdd(this.x).redMul(e.y.redAdd(e.x)),o=this.t.redMul(this.curve.dd).redMul(e.t),r=this.z.redMul(e.z.redAdd(e.z)),i=n.redSub(t),a=r.redSub(o),s=r.redAdd(o),u=n.redAdd(t),c=i.redMul(a),l=s.redMul(u),d=i.redMul(u),h=a.redMul(s);return this.curve.point(c,l,h,d)},c.prototype._projAdd=function(e){var t,n,o=this.z.redMul(e.z),r=o.redSqr(),i=this.x.redMul(e.x),a=this.y.redMul(e.y),s=this.curve.d.redMul(i).redMul(a),u=r.redSub(s),c=r.redAdd(s),l=this.x.redAdd(this.y).redMul(e.x.redAdd(e.y)).redISub(i).redISub(a),d=o.redMul(u).redMul(l);return this.curve.twisted?(t=o.redMul(c).redMul(a.redSub(this.curve._mulA(i))),n=u.redMul(c)):(t=o.redMul(c).redMul(a.redSub(i)),n=this.curve._mulC(u).redMul(c)),this.curve.point(d,t,n)},c.prototype.add=function(e){return this.isInfinity()?e:e.isInfinity()?this:this.curve.extended?this._extAdd(e):this._projAdd(e)},c.prototype.mul=function(e){return this._hasDoubles(e)?this.curve._fixedNafMul(this,e):this.curve._wnafMul(this,e)},c.prototype.mulAdd=function(e,t,n){return this.curve._wnafMulAdd(1,[this,t],[e,n],2,!1)},c.prototype.jmulAdd=function(e,t,n){return this.curve._wnafMulAdd(1,[this,t],[e,n],2,!0)},c.prototype.normalize=function(){if(this.zOne)return this;var e=this.z.redInvm();return this.x=this.x.redMul(e),this.y=this.y.redMul(e),this.t&&(this.t=this.t.redMul(e)),this.z=this.curve.one,this.zOne=!0,this},c.prototype.neg=function(){return this.curve.point(this.x.redNeg(),this.y,this.z,this.t&&this.t.redNeg())},c.prototype.getX=function(){return this.normalize(),this.x.fromRed()},c.prototype.getY=function(){return this.normalize(),this.y.fromRed()},c.prototype.eq=function(e){return this===e||0===this.getX().cmp(e.getX())&&0===this.getY().cmp(e.getY())},c.prototype.eqXToP=function(e){var t=e.toRed(this.curve.red).redMul(this.z);if(0===this.x.cmp(t))return!0;for(var n=e.clone(),o=this.curve.redN.redMul(this.z);;){if(n.iadd(this.curve.n),n.cmp(this.curve.p)>=0)return!1;if(t.redIAdd(o),0===this.x.cmp(t))return!0}},c.prototype.toP=c.prototype.normalize,c.prototype.mixedAdd=c.prototype.add},88254:(e,t,n)=>{"use strict";var o=t;o.base=n(4918),o.short=n(6673),o.mont=n(22881),o.edwards=n(31138)},22881:(e,t,n)=>{"use strict";var o=n(73785),r=n(35717),i=n(4918),a=n(80953);function s(e){i.call(this,"mont",e),this.a=new o(e.a,16).toRed(this.red),this.b=new o(e.b,16).toRed(this.red),this.i4=new o(4).toRed(this.red).redInvm(),this.two=new o(2).toRed(this.red),this.a24=this.i4.redMul(this.a.redAdd(this.two))}function u(e,t,n){i.BasePoint.call(this,e,"projective"),null===t&&null===n?(this.x=this.curve.one,this.z=this.curve.zero):(this.x=new o(t,16),this.z=new o(n,16),this.x.red||(this.x=this.x.toRed(this.curve.red)),this.z.red||(this.z=this.z.toRed(this.curve.red)))}r(s,i),e.exports=s,s.prototype.validate=function(e){var t=e.normalize().x,n=t.redSqr(),o=n.redMul(t).redAdd(n.redMul(this.a)).redAdd(t);return 0===o.redSqrt().redSqr().cmp(o)},r(u,i.BasePoint),s.prototype.decodePoint=function(e,t){return this.point(a.toArray(e,t),1)},s.prototype.point=function(e,t){return new u(this,e,t)},s.prototype.pointFromJSON=function(e){return u.fromJSON(this,e)},u.prototype.precompute=function(){},u.prototype._encode=function(){return this.getX().toArray("be",this.curve.p.byteLength())},u.fromJSON=function(e,t){return new u(e,t[0],t[1]||e.one)},u.prototype.inspect=function(){return this.isInfinity()?"":""},u.prototype.isInfinity=function(){return 0===this.z.cmpn(0)},u.prototype.dbl=function(){var e=this.x.redAdd(this.z).redSqr(),t=this.x.redSub(this.z).redSqr(),n=e.redSub(t),o=e.redMul(t),r=n.redMul(t.redAdd(this.curve.a24.redMul(n)));return this.curve.point(o,r)},u.prototype.add=function(){throw new Error("Not supported on Montgomery curve")},u.prototype.diffAdd=function(e,t){var n=this.x.redAdd(this.z),o=this.x.redSub(this.z),r=e.x.redAdd(e.z),i=e.x.redSub(e.z).redMul(n),a=r.redMul(o),s=t.z.redMul(i.redAdd(a).redSqr()),u=t.x.redMul(i.redISub(a).redSqr());return this.curve.point(s,u)},u.prototype.mul=function(e){for(var t=e.clone(),n=this,o=this.curve.point(null,null),r=[];0!==t.cmpn(0);t.iushrn(1))r.push(t.andln(1));for(var i=r.length-1;i>=0;i--)0===r[i]?(n=n.diffAdd(o,this),o=o.dbl()):(o=n.diffAdd(o,this),n=n.dbl());return o},u.prototype.mulAdd=function(){throw new Error("Not supported on Montgomery curve")},u.prototype.jumlAdd=function(){throw new Error("Not supported on Montgomery curve")},u.prototype.eq=function(e){return 0===this.getX().cmp(e.getX())},u.prototype.normalize=function(){return this.x=this.x.redMul(this.z.redInvm()),this.z=this.curve.one,this},u.prototype.getX=function(){return this.normalize(),this.x.fromRed()}},6673:(e,t,n)=>{"use strict";var o=n(80953),r=n(73785),i=n(35717),a=n(4918),s=o.assert;function u(e){a.call(this,"short",e),this.a=new r(e.a,16).toRed(this.red),this.b=new r(e.b,16).toRed(this.red),this.tinv=this.two.redInvm(),this.zeroA=0===this.a.fromRed().cmpn(0),this.threeA=0===this.a.fromRed().sub(this.p).cmpn(-3),this.endo=this._getEndomorphism(e),this._endoWnafT1=new Array(4),this._endoWnafT2=new Array(4)}function c(e,t,n,o){a.BasePoint.call(this,e,"affine"),null===t&&null===n?(this.x=null,this.y=null,this.inf=!0):(this.x=new r(t,16),this.y=new r(n,16),o&&(this.x.forceRed(this.curve.red),this.y.forceRed(this.curve.red)),this.x.red||(this.x=this.x.toRed(this.curve.red)),this.y.red||(this.y=this.y.toRed(this.curve.red)),this.inf=!1)}function l(e,t,n,o){a.BasePoint.call(this,e,"jacobian"),null===t&&null===n&&null===o?(this.x=this.curve.one,this.y=this.curve.one,this.z=new r(0)):(this.x=new r(t,16),this.y=new r(n,16),this.z=new r(o,16)),this.x.red||(this.x=this.x.toRed(this.curve.red)),this.y.red||(this.y=this.y.toRed(this.curve.red)),this.z.red||(this.z=this.z.toRed(this.curve.red)),this.zOne=this.z===this.curve.one}i(u,a),e.exports=u,u.prototype._getEndomorphism=function(e){if(this.zeroA&&this.g&&this.n&&1===this.p.modn(3)){var t,n;if(e.beta)t=new r(e.beta,16).toRed(this.red);else{var o=this._getEndoRoots(this.p);t=(t=o[0].cmp(o[1])<0?o[0]:o[1]).toRed(this.red)}if(e.lambda)n=new r(e.lambda,16);else{var i=this._getEndoRoots(this.n);0===this.g.mul(i[0]).x.cmp(this.g.x.redMul(t))?n=i[0]:(n=i[1],s(0===this.g.mul(n).x.cmp(this.g.x.redMul(t))))}return{beta:t,lambda:n,basis:e.basis?e.basis.map((function(e){return{a:new r(e.a,16),b:new r(e.b,16)}})):this._getEndoBasis(n)}}},u.prototype._getEndoRoots=function(e){var t=e===this.p?this.red:r.mont(e),n=new r(2).toRed(t).redInvm(),o=n.redNeg(),i=new r(3).toRed(t).redNeg().redSqrt().redMul(n);return[o.redAdd(i).fromRed(),o.redSub(i).fromRed()]},u.prototype._getEndoBasis=function(e){for(var t,n,o,i,a,s,u,c,l,d=this.n.ushrn(Math.floor(this.n.bitLength()/2)),h=e,p=this.n.clone(),f=new r(1),g=new r(0),m=new r(0),_=new r(1),F=0;0!==h.cmpn(0);){var y=p.div(h);c=p.sub(y.mul(h)),l=m.sub(y.mul(f));var b=_.sub(y.mul(g));if(!o&&c.cmp(d)<0)t=u.neg(),n=f,o=c.neg(),i=l;else if(o&&2==++F)break;u=c,p=h,h=c,m=f,f=l,_=g,g=b}a=c.neg(),s=l;var v=o.sqr().add(i.sqr());return a.sqr().add(s.sqr()).cmp(v)>=0&&(a=t,s=n),o.negative&&(o=o.neg(),i=i.neg()),a.negative&&(a=a.neg(),s=s.neg()),[{a:o,b:i},{a,b:s}]},u.prototype._endoSplit=function(e){var t=this.endo.basis,n=t[0],o=t[1],r=o.b.mul(e).divRound(this.n),i=n.b.neg().mul(e).divRound(this.n),a=r.mul(n.a),s=i.mul(o.a),u=r.mul(n.b),c=i.mul(o.b);return{k1:e.sub(a).sub(s),k2:u.add(c).neg()}},u.prototype.pointFromX=function(e,t){(e=new r(e,16)).red||(e=e.toRed(this.red));var n=e.redSqr().redMul(e).redIAdd(e.redMul(this.a)).redIAdd(this.b),o=n.redSqrt();if(0!==o.redSqr().redSub(n).cmp(this.zero))throw new Error("invalid point");var i=o.fromRed().isOdd();return(t&&!i||!t&&i)&&(o=o.redNeg()),this.point(e,o)},u.prototype.validate=function(e){if(e.inf)return!0;var t=e.x,n=e.y,o=this.a.redMul(t),r=t.redSqr().redMul(t).redIAdd(o).redIAdd(this.b);return 0===n.redSqr().redISub(r).cmpn(0)},u.prototype._endoWnafMulAdd=function(e,t,n){for(var o=this._endoWnafT1,r=this._endoWnafT2,i=0;i":""},c.prototype.isInfinity=function(){return this.inf},c.prototype.add=function(e){if(this.inf)return e;if(e.inf)return this;if(this.eq(e))return this.dbl();if(this.neg().eq(e))return this.curve.point(null,null);if(0===this.x.cmp(e.x))return this.curve.point(null,null);var t=this.y.redSub(e.y);0!==t.cmpn(0)&&(t=t.redMul(this.x.redSub(e.x).redInvm()));var n=t.redSqr().redISub(this.x).redISub(e.x),o=t.redMul(this.x.redSub(n)).redISub(this.y);return this.curve.point(n,o)},c.prototype.dbl=function(){if(this.inf)return this;var e=this.y.redAdd(this.y);if(0===e.cmpn(0))return this.curve.point(null,null);var t=this.curve.a,n=this.x.redSqr(),o=e.redInvm(),r=n.redAdd(n).redIAdd(n).redIAdd(t).redMul(o),i=r.redSqr().redISub(this.x.redAdd(this.x)),a=r.redMul(this.x.redSub(i)).redISub(this.y);return this.curve.point(i,a)},c.prototype.getX=function(){return this.x.fromRed()},c.prototype.getY=function(){return this.y.fromRed()},c.prototype.mul=function(e){return e=new r(e,16),this.isInfinity()?this:this._hasDoubles(e)?this.curve._fixedNafMul(this,e):this.curve.endo?this.curve._endoWnafMulAdd([this],[e]):this.curve._wnafMul(this,e)},c.prototype.mulAdd=function(e,t,n){var o=[this,t],r=[e,n];return this.curve.endo?this.curve._endoWnafMulAdd(o,r):this.curve._wnafMulAdd(1,o,r,2)},c.prototype.jmulAdd=function(e,t,n){var o=[this,t],r=[e,n];return this.curve.endo?this.curve._endoWnafMulAdd(o,r,!0):this.curve._wnafMulAdd(1,o,r,2,!0)},c.prototype.eq=function(e){return this===e||this.inf===e.inf&&(this.inf||0===this.x.cmp(e.x)&&0===this.y.cmp(e.y))},c.prototype.neg=function(e){if(this.inf)return this;var t=this.curve.point(this.x,this.y.redNeg());if(e&&this.precomputed){var n=this.precomputed,o=function(e){return e.neg()};t.precomputed={naf:n.naf&&{wnd:n.naf.wnd,points:n.naf.points.map(o)},doubles:n.doubles&&{step:n.doubles.step,points:n.doubles.points.map(o)}}}return t},c.prototype.toJ=function(){return this.inf?this.curve.jpoint(null,null,null):this.curve.jpoint(this.x,this.y,this.curve.one)},i(l,a.BasePoint),u.prototype.jpoint=function(e,t,n){return new l(this,e,t,n)},l.prototype.toP=function(){if(this.isInfinity())return this.curve.point(null,null);var e=this.z.redInvm(),t=e.redSqr(),n=this.x.redMul(t),o=this.y.redMul(t).redMul(e);return this.curve.point(n,o)},l.prototype.neg=function(){return this.curve.jpoint(this.x,this.y.redNeg(),this.z)},l.prototype.add=function(e){if(this.isInfinity())return e;if(e.isInfinity())return this;var t=e.z.redSqr(),n=this.z.redSqr(),o=this.x.redMul(t),r=e.x.redMul(n),i=this.y.redMul(t.redMul(e.z)),a=e.y.redMul(n.redMul(this.z)),s=o.redSub(r),u=i.redSub(a);if(0===s.cmpn(0))return 0!==u.cmpn(0)?this.curve.jpoint(null,null,null):this.dbl();var c=s.redSqr(),l=c.redMul(s),d=o.redMul(c),h=u.redSqr().redIAdd(l).redISub(d).redISub(d),p=u.redMul(d.redISub(h)).redISub(i.redMul(l)),f=this.z.redMul(e.z).redMul(s);return this.curve.jpoint(h,p,f)},l.prototype.mixedAdd=function(e){if(this.isInfinity())return e.toJ();if(e.isInfinity())return this;var t=this.z.redSqr(),n=this.x,o=e.x.redMul(t),r=this.y,i=e.y.redMul(t).redMul(this.z),a=n.redSub(o),s=r.redSub(i);if(0===a.cmpn(0))return 0!==s.cmpn(0)?this.curve.jpoint(null,null,null):this.dbl();var u=a.redSqr(),c=u.redMul(a),l=n.redMul(u),d=s.redSqr().redIAdd(c).redISub(l).redISub(l),h=s.redMul(l.redISub(d)).redISub(r.redMul(c)),p=this.z.redMul(a);return this.curve.jpoint(d,h,p)},l.prototype.dblp=function(e){if(0===e)return this;if(this.isInfinity())return this;if(!e)return this.dbl();var t;if(this.curve.zeroA||this.curve.threeA){var n=this;for(t=0;t=0)return!1;if(n.redIAdd(r),0===this.x.cmp(n))return!0}},l.prototype.inspect=function(){return this.isInfinity()?"":""},l.prototype.isInfinity=function(){return 0===this.z.cmpn(0)}},45427:(e,t,n)=>{"use strict";var o,r=t,i=n(33715),a=n(88254),s=n(80953).assert;function u(e){"short"===e.type?this.curve=new a.short(e):"edwards"===e.type?this.curve=new a.edwards(e):this.curve=new a.mont(e),this.g=this.curve.g,this.n=this.curve.n,this.hash=e.hash,s(this.g.validate(),"Invalid curve"),s(this.g.mul(this.n).isInfinity(),"Invalid curve, G*N != O")}function c(e,t){Object.defineProperty(r,e,{configurable:!0,enumerable:!0,get:function(){var n=new u(t);return Object.defineProperty(r,e,{configurable:!0,enumerable:!0,value:n}),n}})}r.PresetCurve=u,c("p192",{type:"short",prime:"p192",p:"ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff",a:"ffffffff ffffffff ffffffff fffffffe ffffffff fffffffc",b:"64210519 e59c80e7 0fa7e9ab 72243049 feb8deec c146b9b1",n:"ffffffff ffffffff ffffffff 99def836 146bc9b1 b4d22831",hash:i.sha256,gRed:!1,g:["188da80e b03090f6 7cbf20eb 43a18800 f4ff0afd 82ff1012","07192b95 ffc8da78 631011ed 6b24cdd5 73f977a1 1e794811"]}),c("p224",{type:"short",prime:"p224",p:"ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001",a:"ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff fffffffe",b:"b4050a85 0c04b3ab f5413256 5044b0b7 d7bfd8ba 270b3943 2355ffb4",n:"ffffffff ffffffff ffffffff ffff16a2 e0b8f03e 13dd2945 5c5c2a3d",hash:i.sha256,gRed:!1,g:["b70e0cbd 6bb4bf7f 321390b9 4a03c1d3 56c21122 343280d6 115c1d21","bd376388 b5f723fb 4c22dfe6 cd4375a0 5a074764 44d58199 85007e34"]}),c("p256",{type:"short",prime:null,p:"ffffffff 00000001 00000000 00000000 00000000 ffffffff ffffffff ffffffff",a:"ffffffff 00000001 00000000 00000000 00000000 ffffffff ffffffff fffffffc",b:"5ac635d8 aa3a93e7 b3ebbd55 769886bc 651d06b0 cc53b0f6 3bce3c3e 27d2604b",n:"ffffffff 00000000 ffffffff ffffffff bce6faad a7179e84 f3b9cac2 fc632551",hash:i.sha256,gRed:!1,g:["6b17d1f2 e12c4247 f8bce6e5 63a440f2 77037d81 2deb33a0 f4a13945 d898c296","4fe342e2 fe1a7f9b 8ee7eb4a 7c0f9e16 2bce3357 6b315ece cbb64068 37bf51f5"]}),c("p384",{type:"short",prime:null,p:"ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe ffffffff 00000000 00000000 ffffffff",a:"ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe ffffffff 00000000 00000000 fffffffc",b:"b3312fa7 e23ee7e4 988e056b e3f82d19 181d9c6e fe814112 0314088f 5013875a c656398d 8a2ed19d 2a85c8ed d3ec2aef",n:"ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff c7634d81 f4372ddf 581a0db2 48b0a77a ecec196a ccc52973",hash:i.sha384,gRed:!1,g:["aa87ca22 be8b0537 8eb1c71e f320ad74 6e1d3b62 8ba79b98 59f741e0 82542a38 5502f25d bf55296c 3a545e38 72760ab7","3617de4a 96262c6f 5d9e98bf 9292dc29 f8f41dbd 289a147c e9da3113 b5f0b8c0 0a60b1ce 1d7e819d 7a431d7c 90ea0e5f"]}),c("p521",{type:"short",prime:null,p:"000001ff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff",a:"000001ff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffc",b:"00000051 953eb961 8e1c9a1f 929a21a0 b68540ee a2da725b 99b315f3 b8b48991 8ef109e1 56193951 ec7e937b 1652c0bd 3bb1bf07 3573df88 3d2c34f1 ef451fd4 6b503f00",n:"000001ff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffa 51868783 bf2f966b 7fcc0148 f709a5d0 3bb5c9b8 899c47ae bb6fb71e 91386409",hash:i.sha512,gRed:!1,g:["000000c6 858e06b7 0404e9cd 9e3ecb66 2395b442 9c648139 053fb521 f828af60 6b4d3dba a14b5e77 efe75928 fe1dc127 a2ffa8de 3348b3c1 856a429b f97e7e31 c2e5bd66","00000118 39296a78 9a3bc004 5c8a5fb4 2c7d1bd9 98f54449 579b4468 17afbd17 273e662c 97ee7299 5ef42640 c550b901 3fad0761 353c7086 a272c240 88be9476 9fd16650"]}),c("curve25519",{type:"mont",prime:"p25519",p:"7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed",a:"76d06",b:"1",n:"1000000000000000 0000000000000000 14def9dea2f79cd6 5812631a5cf5d3ed",hash:i.sha256,gRed:!1,g:["9"]}),c("ed25519",{type:"edwards",prime:"p25519",p:"7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed",a:"-1",c:"1",d:"52036cee2b6ffe73 8cc740797779e898 00700a4d4141d8ab 75eb4dca135978a3",n:"1000000000000000 0000000000000000 14def9dea2f79cd6 5812631a5cf5d3ed",hash:i.sha256,gRed:!1,g:["216936d3cd6e53fec0a4e231fdd6dc5c692cc7609525a7b2c9562d608f25d51a","6666666666666666666666666666666666666666666666666666666666666658"]});try{o=n(91037)}catch(e){o=void 0}c("secp256k1",{type:"short",prime:"k256",p:"ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f",a:"0",b:"7",n:"ffffffff ffffffff ffffffff fffffffe baaedce6 af48a03b bfd25e8c d0364141",h:"1",hash:i.sha256,beta:"7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee",lambda:"5363ad4cc05c30e0a5261c028812645a122e22ea20816678df02967c1b23bd72",basis:[{a:"3086d221a7d46bcde86c90e49284eb15",b:"-e4437ed6010e88286f547fa90abfe4c3"},{a:"114ca50f7a8e2f3f657c1108d9d44cfd8",b:"3086d221a7d46bcde86c90e49284eb15"}],gRed:!1,g:["79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798","483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8",o]})},57954:(e,t,n)=>{"use strict";var o=n(73785),r=n(2156),i=n(80953),a=n(45427),s=n(29931),u=i.assert,c=n(31251),l=n(90611);function d(e){if(!(this instanceof d))return new d(e);"string"==typeof e&&(u(Object.prototype.hasOwnProperty.call(a,e),"Unknown curve "+e),e=a[e]),e instanceof a.PresetCurve&&(e={curve:e}),this.curve=e.curve.curve,this.n=this.curve.n,this.nh=this.n.ushrn(1),this.g=this.curve.g,this.g=e.curve.g,this.g.precompute(e.curve.n.bitLength()+1),this.hash=e.hash||e.curve.hash}e.exports=d,d.prototype.keyPair=function(e){return new c(this,e)},d.prototype.keyFromPrivate=function(e,t){return c.fromPrivate(this,e,t)},d.prototype.keyFromPublic=function(e,t){return c.fromPublic(this,e,t)},d.prototype.genKeyPair=function(e){e||(e={});for(var t=new r({hash:this.hash,pers:e.pers,persEnc:e.persEnc||"utf8",entropy:e.entropy||s(this.hash.hmacStrength),entropyEnc:e.entropy&&e.entropyEnc||"utf8",nonce:this.n.toArray()}),n=this.n.byteLength(),i=this.n.sub(new o(2));;){var a=new o(t.generate(n));if(!(a.cmp(i)>0))return a.iaddn(1),this.keyFromPrivate(a)}},d.prototype._truncateToN=function(e,t){var n=8*e.byteLength()-this.n.bitLength();return n>0&&(e=e.ushrn(n)),!t&&e.cmp(this.n)>=0?e.sub(this.n):e},d.prototype.sign=function(e,t,n,i){"object"==typeof n&&(i=n,n=null),i||(i={}),t=this.keyFromPrivate(t,n),e=this._truncateToN(new o(e,16));for(var a=this.n.byteLength(),s=t.getPrivate().toArray("be",a),u=e.toArray("be",a),c=new r({hash:this.hash,entropy:s,nonce:u,pers:i.pers,persEnc:i.persEnc||"utf8"}),d=this.n.sub(new o(1)),h=0;;h++){var p=i.k?i.k(h):new o(c.generate(this.n.byteLength()));if(!((p=this._truncateToN(p,!0)).cmpn(1)<=0||p.cmp(d)>=0)){var f=this.g.mul(p);if(!f.isInfinity()){var g=f.getX(),m=g.umod(this.n);if(0!==m.cmpn(0)){var _=p.invm(this.n).mul(m.mul(t.getPrivate()).iadd(e));if(0!==(_=_.umod(this.n)).cmpn(0)){var F=(f.getY().isOdd()?1:0)|(0!==g.cmp(m)?2:0);return i.canonical&&_.cmp(this.nh)>0&&(_=this.n.sub(_),F^=1),new l({r:m,s:_,recoveryParam:F})}}}}}},d.prototype.verify=function(e,t,n,r){e=this._truncateToN(new o(e,16)),n=this.keyFromPublic(n,r);var i=(t=new l(t,"hex")).r,a=t.s;if(i.cmpn(1)<0||i.cmp(this.n)>=0)return!1;if(a.cmpn(1)<0||a.cmp(this.n)>=0)return!1;var s,u=a.invm(this.n),c=u.mul(e).umod(this.n),d=u.mul(i).umod(this.n);return this.curve._maxwellTrick?!(s=this.g.jmulAdd(c,n.getPublic(),d)).isInfinity()&&s.eqXToP(i):!(s=this.g.mulAdd(c,n.getPublic(),d)).isInfinity()&&0===s.getX().umod(this.n).cmp(i)},d.prototype.recoverPubKey=function(e,t,n,r){u((3&n)===n,"The recovery param is more than two bits"),t=new l(t,r);var i=this.n,a=new o(e),s=t.r,c=t.s,d=1&n,h=n>>1;if(s.cmp(this.curve.p.umod(this.curve.n))>=0&&h)throw new Error("Unable to find sencond key candinate");s=h?this.curve.pointFromX(s.add(this.curve.n),d):this.curve.pointFromX(s,d);var p=t.r.invm(i),f=i.sub(a).mul(p).umod(i),g=c.mul(p).umod(i);return this.g.mulAdd(f,s,g)},d.prototype.getKeyRecoveryParam=function(e,t,n,o){if(null!==(t=new l(t,o)).recoveryParam)return t.recoveryParam;for(var r=0;r<4;r++){var i;try{i=this.recoverPubKey(e,t,r)}catch(e){continue}if(i.eq(n))return r}throw new Error("Unable to find valid recovery factor")}},31251:(e,t,n)=>{"use strict";var o=n(73785),r=n(80953).assert;function i(e,t){this.ec=e,this.priv=null,this.pub=null,t.priv&&this._importPrivate(t.priv,t.privEnc),t.pub&&this._importPublic(t.pub,t.pubEnc)}e.exports=i,i.fromPublic=function(e,t,n){return t instanceof i?t:new i(e,{pub:t,pubEnc:n})},i.fromPrivate=function(e,t,n){return t instanceof i?t:new i(e,{priv:t,privEnc:n})},i.prototype.validate=function(){var e=this.getPublic();return e.isInfinity()?{result:!1,reason:"Invalid public key"}:e.validate()?e.mul(this.ec.curve.n).isInfinity()?{result:!0,reason:null}:{result:!1,reason:"Public key * N != O"}:{result:!1,reason:"Public key is not a point"}},i.prototype.getPublic=function(e,t){return"string"==typeof e&&(t=e,e=null),this.pub||(this.pub=this.ec.g.mul(this.priv)),t?this.pub.encode(t,e):this.pub},i.prototype.getPrivate=function(e){return"hex"===e?this.priv.toString(16,2):this.priv},i.prototype._importPrivate=function(e,t){this.priv=new o(e,t||16),this.priv=this.priv.umod(this.ec.curve.n)},i.prototype._importPublic=function(e,t){if(e.x||e.y)return"mont"===this.ec.curve.type?r(e.x,"Need x coordinate"):"short"!==this.ec.curve.type&&"edwards"!==this.ec.curve.type||r(e.x&&e.y,"Need both x and y coordinate"),void(this.pub=this.ec.curve.point(e.x,e.y));this.pub=this.ec.curve.decodePoint(e,t)},i.prototype.derive=function(e){return e.validate()||r(e.validate(),"public point not validated"),e.mul(this.priv).getX()},i.prototype.sign=function(e,t,n){return this.ec.sign(e,this,t,n)},i.prototype.verify=function(e,t){return this.ec.verify(e,t,this)},i.prototype.inspect=function(){return""}},90611:(e,t,n)=>{"use strict";var o=n(73785),r=n(80953),i=r.assert;function a(e,t){if(e instanceof a)return e;this._importDER(e,t)||(i(e.r&&e.s,"Signature without r or s"),this.r=new o(e.r,16),this.s=new o(e.s,16),void 0===e.recoveryParam?this.recoveryParam=null:this.recoveryParam=e.recoveryParam)}function s(){this.place=0}function u(e,t){var n=e[t.place++];if(!(128&n))return n;var o=15&n;if(0===o||o>4)return!1;for(var r=0,i=0,a=t.place;i>>=0;return!(r<=127)&&(t.place=a,r)}function c(e){for(var t=0,n=e.length-1;!e[t]&&!(128&e[t+1])&&t>>3);for(e.push(128|n);--n;)e.push(t>>>(n<<3)&255);e.push(t)}}e.exports=a,a.prototype._importDER=function(e,t){e=r.toArray(e,t);var n=new s;if(48!==e[n.place++])return!1;var i=u(e,n);if(!1===i)return!1;if(i+n.place!==e.length)return!1;if(2!==e[n.place++])return!1;var a=u(e,n);if(!1===a)return!1;var c=e.slice(n.place,a+n.place);if(n.place+=a,2!==e[n.place++])return!1;var l=u(e,n);if(!1===l)return!1;if(e.length!==l+n.place)return!1;var d=e.slice(n.place,l+n.place);if(0===c[0]){if(!(128&c[1]))return!1;c=c.slice(1)}if(0===d[0]){if(!(128&d[1]))return!1;d=d.slice(1)}return this.r=new o(c),this.s=new o(d),this.recoveryParam=null,!0},a.prototype.toDER=function(e){var t=this.r.toArray(),n=this.s.toArray();for(128&t[0]&&(t=[0].concat(t)),128&n[0]&&(n=[0].concat(n)),t=c(t),n=c(n);!(n[0]||128&n[1]);)n=n.slice(1);var o=[2];l(o,t.length),(o=o.concat(t)).push(2),l(o,n.length);var i=o.concat(n),a=[48];return l(a,i.length),a=a.concat(i),r.encode(a,e)}},65980:(e,t,n)=>{"use strict";var o=n(33715),r=n(45427),i=n(80953),a=i.assert,s=i.parseBytes,u=n(79087),c=n(23622);function l(e){if(a("ed25519"===e,"only tested with ed25519 so far"),!(this instanceof l))return new l(e);e=r[e].curve,this.curve=e,this.g=e.g,this.g.precompute(e.n.bitLength()+1),this.pointClass=e.point().constructor,this.encodingLength=Math.ceil(e.n.bitLength()/8),this.hash=o.sha512}e.exports=l,l.prototype.sign=function(e,t){e=s(e);var n=this.keyFromSecret(t),o=this.hashInt(n.messagePrefix(),e),r=this.g.mul(o),i=this.encodePoint(r),a=this.hashInt(i,n.pubBytes(),e).mul(n.priv()),u=o.add(a).umod(this.curve.n);return this.makeSignature({R:r,S:u,Rencoded:i})},l.prototype.verify=function(e,t,n){e=s(e),t=this.makeSignature(t);var o=this.keyFromPublic(n),r=this.hashInt(t.Rencoded(),o.pubBytes(),e),i=this.g.mul(t.S());return t.R().add(o.pub().mul(r)).eq(i)},l.prototype.hashInt=function(){for(var e=this.hash(),t=0;t{"use strict";var o=n(80953),r=o.assert,i=o.parseBytes,a=o.cachedProperty;function s(e,t){this.eddsa=e,this._secret=i(t.secret),e.isPoint(t.pub)?this._pub=t.pub:this._pubBytes=i(t.pub)}s.fromPublic=function(e,t){return t instanceof s?t:new s(e,{pub:t})},s.fromSecret=function(e,t){return t instanceof s?t:new s(e,{secret:t})},s.prototype.secret=function(){return this._secret},a(s,"pubBytes",(function(){return this.eddsa.encodePoint(this.pub())})),a(s,"pub",(function(){return this._pubBytes?this.eddsa.decodePoint(this._pubBytes):this.eddsa.g.mul(this.priv())})),a(s,"privBytes",(function(){var e=this.eddsa,t=this.hash(),n=e.encodingLength-1,o=t.slice(0,e.encodingLength);return o[0]&=248,o[n]&=127,o[n]|=64,o})),a(s,"priv",(function(){return this.eddsa.decodeInt(this.privBytes())})),a(s,"hash",(function(){return this.eddsa.hash().update(this.secret()).digest()})),a(s,"messagePrefix",(function(){return this.hash().slice(this.eddsa.encodingLength)})),s.prototype.sign=function(e){return r(this._secret,"KeyPair can only verify"),this.eddsa.sign(e,this)},s.prototype.verify=function(e,t){return this.eddsa.verify(e,t,this)},s.prototype.getSecret=function(e){return r(this._secret,"KeyPair is public only"),o.encode(this.secret(),e)},s.prototype.getPublic=function(e){return o.encode(this.pubBytes(),e)},e.exports=s},23622:(e,t,n)=>{"use strict";var o=n(73785),r=n(80953),i=r.assert,a=r.cachedProperty,s=r.parseBytes;function u(e,t){this.eddsa=e,"object"!=typeof t&&(t=s(t)),Array.isArray(t)&&(t={R:t.slice(0,e.encodingLength),S:t.slice(e.encodingLength)}),i(t.R&&t.S,"Signature without R or S"),e.isPoint(t.R)&&(this._R=t.R),t.S instanceof o&&(this._S=t.S),this._Rencoded=Array.isArray(t.R)?t.R:t.Rencoded,this._Sencoded=Array.isArray(t.S)?t.S:t.Sencoded}a(u,"S",(function(){return this.eddsa.decodeInt(this.Sencoded())})),a(u,"R",(function(){return this.eddsa.decodePoint(this.Rencoded())})),a(u,"Rencoded",(function(){return this.eddsa.encodePoint(this.R())})),a(u,"Sencoded",(function(){return this.eddsa.encodeInt(this.S())})),u.prototype.toBytes=function(){return this.Rencoded().concat(this.Sencoded())},u.prototype.toHex=function(){return r.encode(this.toBytes(),"hex").toUpperCase()},e.exports=u},91037:e=>{e.exports={doubles:{step:4,points:[["e60fce93b59e9ec53011aabc21c23e97b2a31369b87a5ae9c44ee89e2a6dec0a","f7e3507399e595929db99f34f57937101296891e44d23f0be1f32cce69616821"],["8282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508","11f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf"],["175e159f728b865a72f99cc6c6fc846de0b93833fd2222ed73fce5b551e5b739","d3506e0d9e3c79eba4ef97a51ff71f5eacb5955add24345c6efa6ffee9fed695"],["363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640","4e273adfc732221953b445397f3363145b9a89008199ecb62003c7f3bee9de9"],["8b4b5f165df3c2be8c6244b5b745638843e4a781a15bcd1b69f79a55dffdf80c","4aad0a6f68d308b4b3fbd7813ab0da04f9e336546162ee56b3eff0c65fd4fd36"],["723cbaa6e5db996d6bf771c00bd548c7b700dbffa6c0e77bcb6115925232fcda","96e867b5595cc498a921137488824d6e2660a0653779494801dc069d9eb39f5f"],["eebfa4d493bebf98ba5feec812c2d3b50947961237a919839a533eca0e7dd7fa","5d9a8ca3970ef0f269ee7edaf178089d9ae4cdc3a711f712ddfd4fdae1de8999"],["100f44da696e71672791d0a09b7bde459f1215a29b3c03bfefd7835b39a48db0","cdd9e13192a00b772ec8f3300c090666b7ff4a18ff5195ac0fbd5cd62bc65a09"],["e1031be262c7ed1b1dc9227a4a04c017a77f8d4464f3b3852c8acde6e534fd2d","9d7061928940405e6bb6a4176597535af292dd419e1ced79a44f18f29456a00d"],["feea6cae46d55b530ac2839f143bd7ec5cf8b266a41d6af52d5e688d9094696d","e57c6b6c97dce1bab06e4e12bf3ecd5c981c8957cc41442d3155debf18090088"],["da67a91d91049cdcb367be4be6ffca3cfeed657d808583de33fa978bc1ec6cb1","9bacaa35481642bc41f463f7ec9780e5dec7adc508f740a17e9ea8e27a68be1d"],["53904faa0b334cdda6e000935ef22151ec08d0f7bb11069f57545ccc1a37b7c0","5bc087d0bc80106d88c9eccac20d3c1c13999981e14434699dcb096b022771c8"],["8e7bcd0bd35983a7719cca7764ca906779b53a043a9b8bcaeff959f43ad86047","10b7770b2a3da4b3940310420ca9514579e88e2e47fd68b3ea10047e8460372a"],["385eed34c1cdff21e6d0818689b81bde71a7f4f18397e6690a841e1599c43862","283bebc3e8ea23f56701de19e9ebf4576b304eec2086dc8cc0458fe5542e5453"],["6f9d9b803ecf191637c73a4413dfa180fddf84a5947fbc9c606ed86c3fac3a7","7c80c68e603059ba69b8e2a30e45c4d47ea4dd2f5c281002d86890603a842160"],["3322d401243c4e2582a2147c104d6ecbf774d163db0f5e5313b7e0e742d0e6bd","56e70797e9664ef5bfb019bc4ddaf9b72805f63ea2873af624f3a2e96c28b2a0"],["85672c7d2de0b7da2bd1770d89665868741b3f9af7643397721d74d28134ab83","7c481b9b5b43b2eb6374049bfa62c2e5e77f17fcc5298f44c8e3094f790313a6"],["948bf809b1988a46b06c9f1919413b10f9226c60f668832ffd959af60c82a0a","53a562856dcb6646dc6b74c5d1c3418c6d4dff08c97cd2bed4cb7f88d8c8e589"],["6260ce7f461801c34f067ce0f02873a8f1b0e44dfc69752accecd819f38fd8e8","bc2da82b6fa5b571a7f09049776a1ef7ecd292238051c198c1a84e95b2b4ae17"],["e5037de0afc1d8d43d8348414bbf4103043ec8f575bfdc432953cc8d2037fa2d","4571534baa94d3b5f9f98d09fb990bddbd5f5b03ec481f10e0e5dc841d755bda"],["e06372b0f4a207adf5ea905e8f1771b4e7e8dbd1c6a6c5b725866a0ae4fce725","7a908974bce18cfe12a27bb2ad5a488cd7484a7787104870b27034f94eee31dd"],["213c7a715cd5d45358d0bbf9dc0ce02204b10bdde2a3f58540ad6908d0559754","4b6dad0b5ae462507013ad06245ba190bb4850f5f36a7eeddff2c27534b458f2"],["4e7c272a7af4b34e8dbb9352a5419a87e2838c70adc62cddf0cc3a3b08fbd53c","17749c766c9d0b18e16fd09f6def681b530b9614bff7dd33e0b3941817dcaae6"],["fea74e3dbe778b1b10f238ad61686aa5c76e3db2be43057632427e2840fb27b6","6e0568db9b0b13297cf674deccb6af93126b596b973f7b77701d3db7f23cb96f"],["76e64113f677cf0e10a2570d599968d31544e179b760432952c02a4417bdde39","c90ddf8dee4e95cf577066d70681f0d35e2a33d2b56d2032b4b1752d1901ac01"],["c738c56b03b2abe1e8281baa743f8f9a8f7cc643df26cbee3ab150242bcbb891","893fb578951ad2537f718f2eacbfbbbb82314eef7880cfe917e735d9699a84c3"],["d895626548b65b81e264c7637c972877d1d72e5f3a925014372e9f6588f6c14b","febfaa38f2bc7eae728ec60818c340eb03428d632bb067e179363ed75d7d991f"],["b8da94032a957518eb0f6433571e8761ceffc73693e84edd49150a564f676e03","2804dfa44805a1e4d7c99cc9762808b092cc584d95ff3b511488e4e74efdf6e7"],["e80fea14441fb33a7d8adab9475d7fab2019effb5156a792f1a11778e3c0df5d","eed1de7f638e00771e89768ca3ca94472d155e80af322ea9fcb4291b6ac9ec78"],["a301697bdfcd704313ba48e51d567543f2a182031efd6915ddc07bbcc4e16070","7370f91cfb67e4f5081809fa25d40f9b1735dbf7c0a11a130c0d1a041e177ea1"],["90ad85b389d6b936463f9d0512678de208cc330b11307fffab7ac63e3fb04ed4","e507a3620a38261affdcbd9427222b839aefabe1582894d991d4d48cb6ef150"],["8f68b9d2f63b5f339239c1ad981f162ee88c5678723ea3351b7b444c9ec4c0da","662a9f2dba063986de1d90c2b6be215dbbea2cfe95510bfdf23cbf79501fff82"],["e4f3fb0176af85d65ff99ff9198c36091f48e86503681e3e6686fd5053231e11","1e63633ad0ef4f1c1661a6d0ea02b7286cc7e74ec951d1c9822c38576feb73bc"],["8c00fa9b18ebf331eb961537a45a4266c7034f2f0d4e1d0716fb6eae20eae29e","efa47267fea521a1a9dc343a3736c974c2fadafa81e36c54e7d2a4c66702414b"],["e7a26ce69dd4829f3e10cec0a9e98ed3143d084f308b92c0997fddfc60cb3e41","2a758e300fa7984b471b006a1aafbb18d0a6b2c0420e83e20e8a9421cf2cfd51"],["b6459e0ee3662ec8d23540c223bcbdc571cbcb967d79424f3cf29eb3de6b80ef","67c876d06f3e06de1dadf16e5661db3c4b3ae6d48e35b2ff30bf0b61a71ba45"],["d68a80c8280bb840793234aa118f06231d6f1fc67e73c5a5deda0f5b496943e8","db8ba9fff4b586d00c4b1f9177b0e28b5b0e7b8f7845295a294c84266b133120"],["324aed7df65c804252dc0270907a30b09612aeb973449cea4095980fc28d3d5d","648a365774b61f2ff130c0c35aec1f4f19213b0c7e332843967224af96ab7c84"],["4df9c14919cde61f6d51dfdbe5fee5dceec4143ba8d1ca888e8bd373fd054c96","35ec51092d8728050974c23a1d85d4b5d506cdc288490192ebac06cad10d5d"],["9c3919a84a474870faed8a9c1cc66021523489054d7f0308cbfc99c8ac1f98cd","ddb84f0f4a4ddd57584f044bf260e641905326f76c64c8e6be7e5e03d4fc599d"],["6057170b1dd12fdf8de05f281d8e06bb91e1493a8b91d4cc5a21382120a959e5","9a1af0b26a6a4807add9a2daf71df262465152bc3ee24c65e899be932385a2a8"],["a576df8e23a08411421439a4518da31880cef0fba7d4df12b1a6973eecb94266","40a6bf20e76640b2c92b97afe58cd82c432e10a7f514d9f3ee8be11ae1b28ec8"],["7778a78c28dec3e30a05fe9629de8c38bb30d1f5cf9a3a208f763889be58ad71","34626d9ab5a5b22ff7098e12f2ff580087b38411ff24ac563b513fc1fd9f43ac"],["928955ee637a84463729fd30e7afd2ed5f96274e5ad7e5cb09eda9c06d903ac","c25621003d3f42a827b78a13093a95eeac3d26efa8a8d83fc5180e935bcd091f"],["85d0fef3ec6db109399064f3a0e3b2855645b4a907ad354527aae75163d82751","1f03648413a38c0be29d496e582cf5663e8751e96877331582c237a24eb1f962"],["ff2b0dce97eece97c1c9b6041798b85dfdfb6d8882da20308f5404824526087e","493d13fef524ba188af4c4dc54d07936c7b7ed6fb90e2ceb2c951e01f0c29907"],["827fbbe4b1e880ea9ed2b2e6301b212b57f1ee148cd6dd28780e5e2cf856e241","c60f9c923c727b0b71bef2c67d1d12687ff7a63186903166d605b68baec293ec"],["eaa649f21f51bdbae7be4ae34ce6e5217a58fdce7f47f9aa7f3b58fa2120e2b3","be3279ed5bbbb03ac69a80f89879aa5a01a6b965f13f7e59d47a5305ba5ad93d"],["e4a42d43c5cf169d9391df6decf42ee541b6d8f0c9a137401e23632dda34d24f","4d9f92e716d1c73526fc99ccfb8ad34ce886eedfa8d8e4f13a7f7131deba9414"],["1ec80fef360cbdd954160fadab352b6b92b53576a88fea4947173b9d4300bf19","aeefe93756b5340d2f3a4958a7abbf5e0146e77f6295a07b671cdc1cc107cefd"],["146a778c04670c2f91b00af4680dfa8bce3490717d58ba889ddb5928366642be","b318e0ec3354028add669827f9d4b2870aaa971d2f7e5ed1d0b297483d83efd0"],["fa50c0f61d22e5f07e3acebb1aa07b128d0012209a28b9776d76a8793180eef9","6b84c6922397eba9b72cd2872281a68a5e683293a57a213b38cd8d7d3f4f2811"],["da1d61d0ca721a11b1a5bf6b7d88e8421a288ab5d5bba5220e53d32b5f067ec2","8157f55a7c99306c79c0766161c91e2966a73899d279b48a655fba0f1ad836f1"],["a8e282ff0c9706907215ff98e8fd416615311de0446f1e062a73b0610d064e13","7f97355b8db81c09abfb7f3c5b2515888b679a3e50dd6bd6cef7c73111f4cc0c"],["174a53b9c9a285872d39e56e6913cab15d59b1fa512508c022f382de8319497c","ccc9dc37abfc9c1657b4155f2c47f9e6646b3a1d8cb9854383da13ac079afa73"],["959396981943785c3d3e57edf5018cdbe039e730e4918b3d884fdff09475b7ba","2e7e552888c331dd8ba0386a4b9cd6849c653f64c8709385e9b8abf87524f2fd"],["d2a63a50ae401e56d645a1153b109a8fcca0a43d561fba2dbb51340c9d82b151","e82d86fb6443fcb7565aee58b2948220a70f750af484ca52d4142174dcf89405"],["64587e2335471eb890ee7896d7cfdc866bacbdbd3839317b3436f9b45617e073","d99fcdd5bf6902e2ae96dd6447c299a185b90a39133aeab358299e5e9faf6589"],["8481bde0e4e4d885b3a546d3e549de042f0aa6cea250e7fd358d6c86dd45e458","38ee7b8cba5404dd84a25bf39cecb2ca900a79c42b262e556d64b1b59779057e"],["13464a57a78102aa62b6979ae817f4637ffcfed3c4b1ce30bcd6303f6caf666b","69be159004614580ef7e433453ccb0ca48f300a81d0942e13f495a907f6ecc27"],["bc4a9df5b713fe2e9aef430bcc1dc97a0cd9ccede2f28588cada3a0d2d83f366","d3a81ca6e785c06383937adf4b798caa6e8a9fbfa547b16d758d666581f33c1"],["8c28a97bf8298bc0d23d8c749452a32e694b65e30a9472a3954ab30fe5324caa","40a30463a3305193378fedf31f7cc0eb7ae784f0451cb9459e71dc73cbef9482"],["8ea9666139527a8c1dd94ce4f071fd23c8b350c5a4bb33748c4ba111faccae0","620efabbc8ee2782e24e7c0cfb95c5d735b783be9cf0f8e955af34a30e62b945"],["dd3625faef5ba06074669716bbd3788d89bdde815959968092f76cc4eb9a9787","7a188fa3520e30d461da2501045731ca941461982883395937f68d00c644a573"],["f710d79d9eb962297e4f6232b40e8f7feb2bc63814614d692c12de752408221e","ea98e67232d3b3295d3b535532115ccac8612c721851617526ae47a9c77bfc82"]]},naf:{wnd:7,points:[["f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9","388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e672"],["2f8bde4d1a07209355b4a7250a5c5128e88b84bddc619ab7cba8d569b240efe4","d8ac222636e5e3d6d4dba9dda6c9c426f788271bab0d6840dca87d3aa6ac62d6"],["5cbdf0646e5db4eaa398f365f2ea7a0e3d419b7e0330e39ce92bddedcac4f9bc","6aebca40ba255960a3178d6d861a54dba813d0b813fde7b5a5082628087264da"],["acd484e2f0c7f65309ad178a9f559abde09796974c57e714c35f110dfc27ccbe","cc338921b0a7d9fd64380971763b61e9add888a4375f8e0f05cc262ac64f9c37"],["774ae7f858a9411e5ef4246b70c65aac5649980be5c17891bbec17895da008cb","d984a032eb6b5e190243dd56d7b7b365372db1e2dff9d6a8301d74c9c953c61b"],["f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8","ab0902e8d880a89758212eb65cdaf473a1a06da521fa91f29b5cb52db03ed81"],["d7924d4f7d43ea965a465ae3095ff41131e5946f3c85f79e44adbcf8e27e080e","581e2872a86c72a683842ec228cc6defea40af2bd896d3a5c504dc9ff6a26b58"],["defdea4cdb677750a420fee807eacf21eb9898ae79b9768766e4faa04a2d4a34","4211ab0694635168e997b0ead2a93daeced1f4a04a95c0f6cfb199f69e56eb77"],["2b4ea0a797a443d293ef5cff444f4979f06acfebd7e86d277475656138385b6c","85e89bc037945d93b343083b5a1c86131a01f60c50269763b570c854e5c09b7a"],["352bbf4a4cdd12564f93fa332ce333301d9ad40271f8107181340aef25be59d5","321eb4075348f534d59c18259dda3e1f4a1b3b2e71b1039c67bd3d8bcf81998c"],["2fa2104d6b38d11b0230010559879124e42ab8dfeff5ff29dc9cdadd4ecacc3f","2de1068295dd865b64569335bd5dd80181d70ecfc882648423ba76b532b7d67"],["9248279b09b4d68dab21a9b066edda83263c3d84e09572e269ca0cd7f5453714","73016f7bf234aade5d1aa71bdea2b1ff3fc0de2a887912ffe54a32ce97cb3402"],["daed4f2be3a8bf278e70132fb0beb7522f570e144bf615c07e996d443dee8729","a69dce4a7d6c98e8d4a1aca87ef8d7003f83c230f3afa726ab40e52290be1c55"],["c44d12c7065d812e8acf28d7cbb19f9011ecd9e9fdf281b0e6a3b5e87d22e7db","2119a460ce326cdc76c45926c982fdac0e106e861edf61c5a039063f0e0e6482"],["6a245bf6dc698504c89a20cfded60853152b695336c28063b61c65cbd269e6b4","e022cf42c2bd4a708b3f5126f16a24ad8b33ba48d0423b6efd5e6348100d8a82"],["1697ffa6fd9de627c077e3d2fe541084ce13300b0bec1146f95ae57f0d0bd6a5","b9c398f186806f5d27561506e4557433a2cf15009e498ae7adee9d63d01b2396"],["605bdb019981718b986d0f07e834cb0d9deb8360ffb7f61df982345ef27a7479","2972d2de4f8d20681a78d93ec96fe23c26bfae84fb14db43b01e1e9056b8c49"],["62d14dab4150bf497402fdc45a215e10dcb01c354959b10cfe31c7e9d87ff33d","80fc06bd8cc5b01098088a1950eed0db01aa132967ab472235f5642483b25eaf"],["80c60ad0040f27dade5b4b06c408e56b2c50e9f56b9b8b425e555c2f86308b6f","1c38303f1cc5c30f26e66bad7fe72f70a65eed4cbe7024eb1aa01f56430bd57a"],["7a9375ad6167ad54aa74c6348cc54d344cc5dc9487d847049d5eabb0fa03c8fb","d0e3fa9eca8726909559e0d79269046bdc59ea10c70ce2b02d499ec224dc7f7"],["d528ecd9b696b54c907a9ed045447a79bb408ec39b68df504bb51f459bc3ffc9","eecf41253136e5f99966f21881fd656ebc4345405c520dbc063465b521409933"],["49370a4b5f43412ea25f514e8ecdad05266115e4a7ecb1387231808f8b45963","758f3f41afd6ed428b3081b0512fd62a54c3f3afbb5b6764b653052a12949c9a"],["77f230936ee88cbbd73df930d64702ef881d811e0e1498e2f1c13eb1fc345d74","958ef42a7886b6400a08266e9ba1b37896c95330d97077cbbe8eb3c7671c60d6"],["f2dac991cc4ce4b9ea44887e5c7c0bce58c80074ab9d4dbaeb28531b7739f530","e0dedc9b3b2f8dad4da1f32dec2531df9eb5fbeb0598e4fd1a117dba703a3c37"],["463b3d9f662621fb1b4be8fbbe2520125a216cdfc9dae3debcba4850c690d45b","5ed430d78c296c3543114306dd8622d7c622e27c970a1de31cb377b01af7307e"],["f16f804244e46e2a09232d4aff3b59976b98fac14328a2d1a32496b49998f247","cedabd9b82203f7e13d206fcdf4e33d92a6c53c26e5cce26d6579962c4e31df6"],["caf754272dc84563b0352b7a14311af55d245315ace27c65369e15f7151d41d1","cb474660ef35f5f2a41b643fa5e460575f4fa9b7962232a5c32f908318a04476"],["2600ca4b282cb986f85d0f1709979d8b44a09c07cb86d7c124497bc86f082120","4119b88753c15bd6a693b03fcddbb45d5ac6be74ab5f0ef44b0be9475a7e4b40"],["7635ca72d7e8432c338ec53cd12220bc01c48685e24f7dc8c602a7746998e435","91b649609489d613d1d5e590f78e6d74ecfc061d57048bad9e76f302c5b9c61"],["754e3239f325570cdbbf4a87deee8a66b7f2b33479d468fbc1a50743bf56cc18","673fb86e5bda30fb3cd0ed304ea49a023ee33d0197a695d0c5d98093c536683"],["e3e6bd1071a1e96aff57859c82d570f0330800661d1c952f9fe2694691d9b9e8","59c9e0bba394e76f40c0aa58379a3cb6a5a2283993e90c4167002af4920e37f5"],["186b483d056a033826ae73d88f732985c4ccb1f32ba35f4b4cc47fdcf04aa6eb","3b952d32c67cf77e2e17446e204180ab21fb8090895138b4a4a797f86e80888b"],["df9d70a6b9876ce544c98561f4be4f725442e6d2b737d9c91a8321724ce0963f","55eb2dafd84d6ccd5f862b785dc39d4ab157222720ef9da217b8c45cf2ba2417"],["5edd5cc23c51e87a497ca815d5dce0f8ab52554f849ed8995de64c5f34ce7143","efae9c8dbc14130661e8cec030c89ad0c13c66c0d17a2905cdc706ab7399a868"],["290798c2b6476830da12fe02287e9e777aa3fba1c355b17a722d362f84614fba","e38da76dcd440621988d00bcf79af25d5b29c094db2a23146d003afd41943e7a"],["af3c423a95d9f5b3054754efa150ac39cd29552fe360257362dfdecef4053b45","f98a3fd831eb2b749a93b0e6f35cfb40c8cd5aa667a15581bc2feded498fd9c6"],["766dbb24d134e745cccaa28c99bf274906bb66b26dcf98df8d2fed50d884249a","744b1152eacbe5e38dcc887980da38b897584a65fa06cedd2c924f97cbac5996"],["59dbf46f8c94759ba21277c33784f41645f7b44f6c596a58ce92e666191abe3e","c534ad44175fbc300f4ea6ce648309a042ce739a7919798cd85e216c4a307f6e"],["f13ada95103c4537305e691e74e9a4a8dd647e711a95e73cb62dc6018cfd87b8","e13817b44ee14de663bf4bc808341f326949e21a6a75c2570778419bdaf5733d"],["7754b4fa0e8aced06d4167a2c59cca4cda1869c06ebadfb6488550015a88522c","30e93e864e669d82224b967c3020b8fa8d1e4e350b6cbcc537a48b57841163a2"],["948dcadf5990e048aa3874d46abef9d701858f95de8041d2a6828c99e2262519","e491a42537f6e597d5d28a3224b1bc25df9154efbd2ef1d2cbba2cae5347d57e"],["7962414450c76c1689c7b48f8202ec37fb224cf5ac0bfa1570328a8a3d7c77ab","100b610ec4ffb4760d5c1fc133ef6f6b12507a051f04ac5760afa5b29db83437"],["3514087834964b54b15b160644d915485a16977225b8847bb0dd085137ec47ca","ef0afbb2056205448e1652c48e8127fc6039e77c15c2378b7e7d15a0de293311"],["d3cc30ad6b483e4bc79ce2c9dd8bc54993e947eb8df787b442943d3f7b527eaf","8b378a22d827278d89c5e9be8f9508ae3c2ad46290358630afb34db04eede0a4"],["1624d84780732860ce1c78fcbfefe08b2b29823db913f6493975ba0ff4847610","68651cf9b6da903e0914448c6cd9d4ca896878f5282be4c8cc06e2a404078575"],["733ce80da955a8a26902c95633e62a985192474b5af207da6df7b4fd5fc61cd4","f5435a2bd2badf7d485a4d8b8db9fcce3e1ef8e0201e4578c54673bc1dc5ea1d"],["15d9441254945064cf1a1c33bbd3b49f8966c5092171e699ef258dfab81c045c","d56eb30b69463e7234f5137b73b84177434800bacebfc685fc37bbe9efe4070d"],["a1d0fcf2ec9de675b612136e5ce70d271c21417c9d2b8aaaac138599d0717940","edd77f50bcb5a3cab2e90737309667f2641462a54070f3d519212d39c197a629"],["e22fbe15c0af8ccc5780c0735f84dbe9a790badee8245c06c7ca37331cb36980","a855babad5cd60c88b430a69f53a1a7a38289154964799be43d06d77d31da06"],["311091dd9860e8e20ee13473c1155f5f69635e394704eaa74009452246cfa9b3","66db656f87d1f04fffd1f04788c06830871ec5a64feee685bd80f0b1286d8374"],["34c1fd04d301be89b31c0442d3e6ac24883928b45a9340781867d4232ec2dbdf","9414685e97b1b5954bd46f730174136d57f1ceeb487443dc5321857ba73abee"],["f219ea5d6b54701c1c14de5b557eb42a8d13f3abbcd08affcc2a5e6b049b8d63","4cb95957e83d40b0f73af4544cccf6b1f4b08d3c07b27fb8d8c2962a400766d1"],["d7b8740f74a8fbaab1f683db8f45de26543a5490bca627087236912469a0b448","fa77968128d9c92ee1010f337ad4717eff15db5ed3c049b3411e0315eaa4593b"],["32d31c222f8f6f0ef86f7c98d3a3335ead5bcd32abdd94289fe4d3091aa824bf","5f3032f5892156e39ccd3d7915b9e1da2e6dac9e6f26e961118d14b8462e1661"],["7461f371914ab32671045a155d9831ea8793d77cd59592c4340f86cbc18347b5","8ec0ba238b96bec0cbdddcae0aa442542eee1ff50c986ea6b39847b3cc092ff6"],["ee079adb1df1860074356a25aa38206a6d716b2c3e67453d287698bad7b2b2d6","8dc2412aafe3be5c4c5f37e0ecc5f9f6a446989af04c4e25ebaac479ec1c8c1e"],["16ec93e447ec83f0467b18302ee620f7e65de331874c9dc72bfd8616ba9da6b5","5e4631150e62fb40d0e8c2a7ca5804a39d58186a50e497139626778e25b0674d"],["eaa5f980c245f6f038978290afa70b6bd8855897f98b6aa485b96065d537bd99","f65f5d3e292c2e0819a528391c994624d784869d7e6ea67fb18041024edc07dc"],["78c9407544ac132692ee1910a02439958ae04877151342ea96c4b6b35a49f51","f3e0319169eb9b85d5404795539a5e68fa1fbd583c064d2462b675f194a3ddb4"],["494f4be219a1a77016dcd838431aea0001cdc8ae7a6fc688726578d9702857a5","42242a969283a5f339ba7f075e36ba2af925ce30d767ed6e55f4b031880d562c"],["a598a8030da6d86c6bc7f2f5144ea549d28211ea58faa70ebf4c1e665c1fe9b5","204b5d6f84822c307e4b4a7140737aec23fc63b65b35f86a10026dbd2d864e6b"],["c41916365abb2b5d09192f5f2dbeafec208f020f12570a184dbadc3e58595997","4f14351d0087efa49d245b328984989d5caf9450f34bfc0ed16e96b58fa9913"],["841d6063a586fa475a724604da03bc5b92a2e0d2e0a36acfe4c73a5514742881","73867f59c0659e81904f9a1c7543698e62562d6744c169ce7a36de01a8d6154"],["5e95bb399a6971d376026947f89bde2f282b33810928be4ded112ac4d70e20d5","39f23f366809085beebfc71181313775a99c9aed7d8ba38b161384c746012865"],["36e4641a53948fd476c39f8a99fd974e5ec07564b5315d8bf99471bca0ef2f66","d2424b1b1abe4eb8164227b085c9aa9456ea13493fd563e06fd51cf5694c78fc"],["336581ea7bfbbb290c191a2f507a41cf5643842170e914faeab27c2c579f726","ead12168595fe1be99252129b6e56b3391f7ab1410cd1e0ef3dcdcabd2fda224"],["8ab89816dadfd6b6a1f2634fcf00ec8403781025ed6890c4849742706bd43ede","6fdcef09f2f6d0a044e654aef624136f503d459c3e89845858a47a9129cdd24e"],["1e33f1a746c9c5778133344d9299fcaa20b0938e8acff2544bb40284b8c5fb94","60660257dd11b3aa9c8ed618d24edff2306d320f1d03010e33a7d2057f3b3b6"],["85b7c1dcb3cec1b7ee7f30ded79dd20a0ed1f4cc18cbcfcfa410361fd8f08f31","3d98a9cdd026dd43f39048f25a8847f4fcafad1895d7a633c6fed3c35e999511"],["29df9fbd8d9e46509275f4b125d6d45d7fbe9a3b878a7af872a2800661ac5f51","b4c4fe99c775a606e2d8862179139ffda61dc861c019e55cd2876eb2a27d84b"],["a0b1cae06b0a847a3fea6e671aaf8adfdfe58ca2f768105c8082b2e449fce252","ae434102edde0958ec4b19d917a6a28e6b72da1834aff0e650f049503a296cf2"],["4e8ceafb9b3e9a136dc7ff67e840295b499dfb3b2133e4ba113f2e4c0e121e5","cf2174118c8b6d7a4b48f6d534ce5c79422c086a63460502b827ce62a326683c"],["d24a44e047e19b6f5afb81c7ca2f69080a5076689a010919f42725c2b789a33b","6fb8d5591b466f8fc63db50f1c0f1c69013f996887b8244d2cdec417afea8fa3"],["ea01606a7a6c9cdd249fdfcfacb99584001edd28abbab77b5104e98e8e3b35d4","322af4908c7312b0cfbfe369f7a7b3cdb7d4494bc2823700cfd652188a3ea98d"],["af8addbf2b661c8a6c6328655eb96651252007d8c5ea31be4ad196de8ce2131f","6749e67c029b85f52a034eafd096836b2520818680e26ac8f3dfbcdb71749700"],["e3ae1974566ca06cc516d47e0fb165a674a3dabcfca15e722f0e3450f45889","2aeabe7e4531510116217f07bf4d07300de97e4874f81f533420a72eeb0bd6a4"],["591ee355313d99721cf6993ffed1e3e301993ff3ed258802075ea8ced397e246","b0ea558a113c30bea60fc4775460c7901ff0b053d25ca2bdeee98f1a4be5d196"],["11396d55fda54c49f19aa97318d8da61fa8584e47b084945077cf03255b52984","998c74a8cd45ac01289d5833a7beb4744ff536b01b257be4c5767bea93ea57a4"],["3c5d2a1ba39c5a1790000738c9e0c40b8dcdfd5468754b6405540157e017aa7a","b2284279995a34e2f9d4de7396fc18b80f9b8b9fdd270f6661f79ca4c81bd257"],["cc8704b8a60a0defa3a99a7299f2e9c3fbc395afb04ac078425ef8a1793cc030","bdd46039feed17881d1e0862db347f8cf395b74fc4bcdc4e940b74e3ac1f1b13"],["c533e4f7ea8555aacd9777ac5cad29b97dd4defccc53ee7ea204119b2889b197","6f0a256bc5efdf429a2fb6242f1a43a2d9b925bb4a4b3a26bb8e0f45eb596096"],["c14f8f2ccb27d6f109f6d08d03cc96a69ba8c34eec07bbcf566d48e33da6593","c359d6923bb398f7fd4473e16fe1c28475b740dd098075e6c0e8649113dc3a38"],["a6cbc3046bc6a450bac24789fa17115a4c9739ed75f8f21ce441f72e0b90e6ef","21ae7f4680e889bb130619e2c0f95a360ceb573c70603139862afd617fa9b9f"],["347d6d9a02c48927ebfb86c1359b1caf130a3c0267d11ce6344b39f99d43cc38","60ea7f61a353524d1c987f6ecec92f086d565ab687870cb12689ff1e31c74448"],["da6545d2181db8d983f7dcb375ef5866d47c67b1bf31c8cf855ef7437b72656a","49b96715ab6878a79e78f07ce5680c5d6673051b4935bd897fea824b77dc208a"],["c40747cc9d012cb1a13b8148309c6de7ec25d6945d657146b9d5994b8feb1111","5ca560753be2a12fc6de6caf2cb489565db936156b9514e1bb5e83037e0fa2d4"],["4e42c8ec82c99798ccf3a610be870e78338c7f713348bd34c8203ef4037f3502","7571d74ee5e0fb92a7a8b33a07783341a5492144cc54bcc40a94473693606437"],["3775ab7089bc6af823aba2e1af70b236d251cadb0c86743287522a1b3b0dedea","be52d107bcfa09d8bcb9736a828cfa7fac8db17bf7a76a2c42ad961409018cf7"],["cee31cbf7e34ec379d94fb814d3d775ad954595d1314ba8846959e3e82f74e26","8fd64a14c06b589c26b947ae2bcf6bfa0149ef0be14ed4d80f448a01c43b1c6d"],["b4f9eaea09b6917619f6ea6a4eb5464efddb58fd45b1ebefcdc1a01d08b47986","39e5c9925b5a54b07433a4f18c61726f8bb131c012ca542eb24a8ac07200682a"],["d4263dfc3d2df923a0179a48966d30ce84e2515afc3dccc1b77907792ebcc60e","62dfaf07a0f78feb30e30d6295853ce189e127760ad6cf7fae164e122a208d54"],["48457524820fa65a4f8d35eb6930857c0032acc0a4a2de422233eeda897612c4","25a748ab367979d98733c38a1fa1c2e7dc6cc07db2d60a9ae7a76aaa49bd0f77"],["dfeeef1881101f2cb11644f3a2afdfc2045e19919152923f367a1767c11cceda","ecfb7056cf1de042f9420bab396793c0c390bde74b4bbdff16a83ae09a9a7517"],["6d7ef6b17543f8373c573f44e1f389835d89bcbc6062ced36c82df83b8fae859","cd450ec335438986dfefa10c57fea9bcc521a0959b2d80bbf74b190dca712d10"],["e75605d59102a5a2684500d3b991f2e3f3c88b93225547035af25af66e04541f","f5c54754a8f71ee540b9b48728473e314f729ac5308b06938360990e2bfad125"],["eb98660f4c4dfaa06a2be453d5020bc99a0c2e60abe388457dd43fefb1ed620c","6cb9a8876d9cb8520609af3add26cd20a0a7cd8a9411131ce85f44100099223e"],["13e87b027d8514d35939f2e6892b19922154596941888336dc3563e3b8dba942","fef5a3c68059a6dec5d624114bf1e91aac2b9da568d6abeb2570d55646b8adf1"],["ee163026e9fd6fe017c38f06a5be6fc125424b371ce2708e7bf4491691e5764a","1acb250f255dd61c43d94ccc670d0f58f49ae3fa15b96623e5430da0ad6c62b2"],["b268f5ef9ad51e4d78de3a750c2dc89b1e626d43505867999932e5db33af3d80","5f310d4b3c99b9ebb19f77d41c1dee018cf0d34fd4191614003e945a1216e423"],["ff07f3118a9df035e9fad85eb6c7bfe42b02f01ca99ceea3bf7ffdba93c4750d","438136d603e858a3a5c440c38eccbaddc1d2942114e2eddd4740d098ced1f0d8"],["8d8b9855c7c052a34146fd20ffb658bea4b9f69e0d825ebec16e8c3ce2b526a1","cdb559eedc2d79f926baf44fb84ea4d44bcf50fee51d7ceb30e2e7f463036758"],["52db0b5384dfbf05bfa9d472d7ae26dfe4b851ceca91b1eba54263180da32b63","c3b997d050ee5d423ebaf66a6db9f57b3180c902875679de924b69d84a7b375"],["e62f9490d3d51da6395efd24e80919cc7d0f29c3f3fa48c6fff543becbd43352","6d89ad7ba4876b0b22c2ca280c682862f342c8591f1daf5170e07bfd9ccafa7d"],["7f30ea2476b399b4957509c88f77d0191afa2ff5cb7b14fd6d8e7d65aaab1193","ca5ef7d4b231c94c3b15389a5f6311e9daff7bb67b103e9880ef4bff637acaec"],["5098ff1e1d9f14fb46a210fada6c903fef0fb7b4a1dd1d9ac60a0361800b7a00","9731141d81fc8f8084d37c6e7542006b3ee1b40d60dfe5362a5b132fd17ddc0"],["32b78c7de9ee512a72895be6b9cbefa6e2f3c4ccce445c96b9f2c81e2778ad58","ee1849f513df71e32efc3896ee28260c73bb80547ae2275ba497237794c8753c"],["e2cb74fddc8e9fbcd076eef2a7c72b0ce37d50f08269dfc074b581550547a4f7","d3aa2ed71c9dd2247a62df062736eb0baddea9e36122d2be8641abcb005cc4a4"],["8438447566d4d7bedadc299496ab357426009a35f235cb141be0d99cd10ae3a8","c4e1020916980a4da5d01ac5e6ad330734ef0d7906631c4f2390426b2edd791f"],["4162d488b89402039b584c6fc6c308870587d9c46f660b878ab65c82c711d67e","67163e903236289f776f22c25fb8a3afc1732f2b84b4e95dbda47ae5a0852649"],["3fad3fa84caf0f34f0f89bfd2dcf54fc175d767aec3e50684f3ba4a4bf5f683d","cd1bc7cb6cc407bb2f0ca647c718a730cf71872e7d0d2a53fa20efcdfe61826"],["674f2600a3007a00568c1a7ce05d0816c1fb84bf1370798f1c69532faeb1a86b","299d21f9413f33b3edf43b257004580b70db57da0b182259e09eecc69e0d38a5"],["d32f4da54ade74abb81b815ad1fb3b263d82d6c692714bcff87d29bd5ee9f08f","f9429e738b8e53b968e99016c059707782e14f4535359d582fc416910b3eea87"],["30e4e670435385556e593657135845d36fbb6931f72b08cb1ed954f1e3ce3ff6","462f9bce619898638499350113bbc9b10a878d35da70740dc695a559eb88db7b"],["be2062003c51cc3004682904330e4dee7f3dcd10b01e580bf1971b04d4cad297","62188bc49d61e5428573d48a74e1c655b1c61090905682a0d5558ed72dccb9bc"],["93144423ace3451ed29e0fb9ac2af211cb6e84a601df5993c419859fff5df04a","7c10dfb164c3425f5c71a3f9d7992038f1065224f72bb9d1d902a6d13037b47c"],["b015f8044f5fcbdcf21ca26d6c34fb8197829205c7b7d2a7cb66418c157b112c","ab8c1e086d04e813744a655b2df8d5f83b3cdc6faa3088c1d3aea1454e3a1d5f"],["d5e9e1da649d97d89e4868117a465a3a4f8a18de57a140d36b3f2af341a21b52","4cb04437f391ed73111a13cc1d4dd0db1693465c2240480d8955e8592f27447a"],["d3ae41047dd7ca065dbf8ed77b992439983005cd72e16d6f996a5316d36966bb","bd1aeb21ad22ebb22a10f0303417c6d964f8cdd7df0aca614b10dc14d125ac46"],["463e2763d885f958fc66cdd22800f0a487197d0a82e377b49f80af87c897b065","bfefacdb0e5d0fd7df3a311a94de062b26b80c61fbc97508b79992671ef7ca7f"],["7985fdfd127c0567c6f53ec1bb63ec3158e597c40bfe747c83cddfc910641917","603c12daf3d9862ef2b25fe1de289aed24ed291e0ec6708703a5bd567f32ed03"],["74a1ad6b5f76e39db2dd249410eac7f99e74c59cb83d2d0ed5ff1543da7703e9","cc6157ef18c9c63cd6193d83631bbea0093e0968942e8c33d5737fd790e0db08"],["30682a50703375f602d416664ba19b7fc9bab42c72747463a71d0896b22f6da3","553e04f6b018b4fa6c8f39e7f311d3176290d0e0f19ca73f17714d9977a22ff8"],["9e2158f0d7c0d5f26c3791efefa79597654e7a2b2464f52b1ee6c1347769ef57","712fcdd1b9053f09003a3481fa7762e9ffd7c8ef35a38509e2fbf2629008373"],["176e26989a43c9cfeba4029c202538c28172e566e3c4fce7322857f3be327d66","ed8cc9d04b29eb877d270b4878dc43c19aefd31f4eee09ee7b47834c1fa4b1c3"],["75d46efea3771e6e68abb89a13ad747ecf1892393dfc4f1b7004788c50374da8","9852390a99507679fd0b86fd2b39a868d7efc22151346e1a3ca4726586a6bed8"],["809a20c67d64900ffb698c4c825f6d5f2310fb0451c869345b7319f645605721","9e994980d9917e22b76b061927fa04143d096ccc54963e6a5ebfa5f3f8e286c1"],["1b38903a43f7f114ed4500b4eac7083fdefece1cf29c63528d563446f972c180","4036edc931a60ae889353f77fd53de4a2708b26b6f5da72ad3394119daf408f9"]]}}},80953:(e,t,n)=>{"use strict";var o=t,r=n(73785),i=n(79746),a=n(34504);o.assert=i,o.toArray=a.toArray,o.zero2=a.zero2,o.toHex=a.toHex,o.encode=a.encode,o.getNAF=function(e,t,n){var o=new Array(Math.max(e.bitLength(),n)+1);o.fill(0);for(var r=1<(r>>1)-1?(r>>1)-u:u,i.isubn(s)):s=0,o[a]=s,i.iushrn(1)}return o},o.getJSF=function(e,t){var n=[[],[]];e=e.clone(),t=t.clone();for(var o,r=0,i=0;e.cmpn(-r)>0||t.cmpn(-i)>0;){var a,s,u=e.andln(3)+r&3,c=t.andln(3)+i&3;3===u&&(u=-1),3===c&&(c=-1),a=0==(1&u)?0:3!=(o=e.andln(7)+r&7)&&5!==o||2!==c?u:-u,n[0].push(a),s=0==(1&c)?0:3!=(o=t.andln(7)+i&7)&&5!==o||2!==u?c:-c,n[1].push(s),2*r===a+1&&(r=1-r),2*i===s+1&&(i=1-i),e.iushrn(1),t.iushrn(1)}return n},o.cachedProperty=function(e,t,n){var o="_"+t;e.prototype[t]=function(){return void 0!==this[o]?this[o]:this[o]=n.call(this)}},o.parseBytes=function(e){return"string"==typeof e?o.toArray(e,"hex"):e},o.intFromLE=function(e){return new r(e,"hex","le")}},73785:function(e,t,n){!function(e,t){"use strict";function o(e,t){if(!e)throw new Error(t||"Assertion failed")}function r(e,t){e.super_=t;var n=function(){};n.prototype=t.prototype,e.prototype=new n,e.prototype.constructor=e}function i(e,t,n){if(i.isBN(e))return e;this.negative=0,this.words=null,this.length=0,this.red=null,null!==e&&("le"!==t&&"be"!==t||(n=t,t=10),this._init(e||0,t||10,n||"be"))}var a;"object"==typeof e?e.exports=i:t.BN=i,i.BN=i,i.wordSize=26;try{a="undefined"!=typeof window&&void 0!==window.Buffer?window.Buffer:n(85568).Buffer}catch(e){}function s(e,t){var n=e.charCodeAt(t);return n>=65&&n<=70?n-55:n>=97&&n<=102?n-87:n-48&15}function u(e,t,n){var o=s(e,n);return n-1>=t&&(o|=s(e,n-1)<<4),o}function c(e,t,n,o){for(var r=0,i=Math.min(e.length,n),a=t;a=49?s-49+10:s>=17?s-17+10:s}return r}i.isBN=function(e){return e instanceof i||null!==e&&"object"==typeof e&&e.constructor.wordSize===i.wordSize&&Array.isArray(e.words)},i.max=function(e,t){return e.cmp(t)>0?e:t},i.min=function(e,t){return e.cmp(t)<0?e:t},i.prototype._init=function(e,t,n){if("number"==typeof e)return this._initNumber(e,t,n);if("object"==typeof e)return this._initArray(e,t,n);"hex"===t&&(t=16),o(t===(0|t)&&t>=2&&t<=36);var r=0;"-"===(e=e.toString().replace(/\s+/g,""))[0]&&(r++,this.negative=1),r=0;r-=3)a=e[r]|e[r-1]<<8|e[r-2]<<16,this.words[i]|=a<>>26-s&67108863,(s+=24)>=26&&(s-=26,i++);else if("le"===n)for(r=0,i=0;r>>26-s&67108863,(s+=24)>=26&&(s-=26,i++);return this.strip()},i.prototype._parseHex=function(e,t,n){this.length=Math.ceil((e.length-t)/6),this.words=new Array(this.length);for(var o=0;o=t;o-=2)r=u(e,t,o)<=18?(i-=18,a+=1,this.words[a]|=r>>>26):i+=8;else for(o=(e.length-t)%2==0?t+1:t;o=18?(i-=18,a+=1,this.words[a]|=r>>>26):i+=8;this.strip()},i.prototype._parseBase=function(e,t,n){this.words=[0],this.length=1;for(var o=0,r=1;r<=67108863;r*=t)o++;o--,r=r/t|0;for(var i=e.length-n,a=i%o,s=Math.min(i,i-a)+n,u=0,l=n;l1&&0===this.words[this.length-1];)this.length--;return this._normSign()},i.prototype._normSign=function(){return 1===this.length&&0===this.words[0]&&(this.negative=0),this},i.prototype.inspect=function(){return(this.red?""};var l=["","0","00","000","0000","00000","000000","0000000","00000000","000000000","0000000000","00000000000","000000000000","0000000000000","00000000000000","000000000000000","0000000000000000","00000000000000000","000000000000000000","0000000000000000000","00000000000000000000","000000000000000000000","0000000000000000000000","00000000000000000000000","000000000000000000000000","0000000000000000000000000"],d=[0,0,25,16,12,11,10,9,8,8,7,7,7,7,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5],h=[0,0,33554432,43046721,16777216,48828125,60466176,40353607,16777216,43046721,1e7,19487171,35831808,62748517,7529536,11390625,16777216,24137569,34012224,47045881,64e6,4084101,5153632,6436343,7962624,9765625,11881376,14348907,17210368,20511149,243e5,28629151,33554432,39135393,45435424,52521875,60466176];function p(e,t,n){n.negative=t.negative^e.negative;var o=e.length+t.length|0;n.length=o,o=o-1|0;var r=0|e.words[0],i=0|t.words[0],a=r*i,s=67108863&a,u=a/67108864|0;n.words[0]=s;for(var c=1;c>>26,d=67108863&u,h=Math.min(c,t.length-1),p=Math.max(0,c-e.length+1);p<=h;p++){var f=c-p|0;l+=(a=(r=0|e.words[f])*(i=0|t.words[p])+d)/67108864|0,d=67108863&a}n.words[c]=0|d,u=0|l}return 0!==u?n.words[c]=0|u:n.length--,n.strip()}i.prototype.toString=function(e,t){var n;if(t=0|t||1,16===(e=e||10)||"hex"===e){n="";for(var r=0,i=0,a=0;a>>24-r&16777215)||a!==this.length-1?l[6-u.length]+u+n:u+n,(r+=2)>=26&&(r-=26,a--)}for(0!==i&&(n=i.toString(16)+n);n.length%t!=0;)n="0"+n;return 0!==this.negative&&(n="-"+n),n}if(e===(0|e)&&e>=2&&e<=36){var c=d[e],p=h[e];n="";var f=this.clone();for(f.negative=0;!f.isZero();){var g=f.modn(p).toString(e);n=(f=f.idivn(p)).isZero()?g+n:l[c-g.length]+g+n}for(this.isZero()&&(n="0"+n);n.length%t!=0;)n="0"+n;return 0!==this.negative&&(n="-"+n),n}o(!1,"Base should be between 2 and 36")},i.prototype.toNumber=function(){var e=this.words[0];return 2===this.length?e+=67108864*this.words[1]:3===this.length&&1===this.words[2]?e+=4503599627370496+67108864*this.words[1]:this.length>2&&o(!1,"Number can only safely store up to 53 bits"),0!==this.negative?-e:e},i.prototype.toJSON=function(){return this.toString(16)},i.prototype.toBuffer=function(e,t){return o(void 0!==a),this.toArrayLike(a,e,t)},i.prototype.toArray=function(e,t){return this.toArrayLike(Array,e,t)},i.prototype.toArrayLike=function(e,t,n){var r=this.byteLength(),i=n||Math.max(1,r);o(r<=i,"byte array longer than desired length"),o(i>0,"Requested array length <= 0"),this.strip();var a,s,u="le"===t,c=new e(i),l=this.clone();if(u){for(s=0;!l.isZero();s++)a=l.andln(255),l.iushrn(8),c[s]=a;for(;s=4096&&(n+=13,t>>>=13),t>=64&&(n+=7,t>>>=7),t>=8&&(n+=4,t>>>=4),t>=2&&(n+=2,t>>>=2),n+t},i.prototype._zeroBits=function(e){if(0===e)return 26;var t=e,n=0;return 0==(8191&t)&&(n+=13,t>>>=13),0==(127&t)&&(n+=7,t>>>=7),0==(15&t)&&(n+=4,t>>>=4),0==(3&t)&&(n+=2,t>>>=2),0==(1&t)&&n++,n},i.prototype.bitLength=function(){var e=this.words[this.length-1],t=this._countBits(e);return 26*(this.length-1)+t},i.prototype.zeroBits=function(){if(this.isZero())return 0;for(var e=0,t=0;te.length?this.clone().ior(e):e.clone().ior(this)},i.prototype.uor=function(e){return this.length>e.length?this.clone().iuor(e):e.clone().iuor(this)},i.prototype.iuand=function(e){var t;t=this.length>e.length?e:this;for(var n=0;ne.length?this.clone().iand(e):e.clone().iand(this)},i.prototype.uand=function(e){return this.length>e.length?this.clone().iuand(e):e.clone().iuand(this)},i.prototype.iuxor=function(e){var t,n;this.length>e.length?(t=this,n=e):(t=e,n=this);for(var o=0;oe.length?this.clone().ixor(e):e.clone().ixor(this)},i.prototype.uxor=function(e){return this.length>e.length?this.clone().iuxor(e):e.clone().iuxor(this)},i.prototype.inotn=function(e){o("number"==typeof e&&e>=0);var t=0|Math.ceil(e/26),n=e%26;this._expand(t),n>0&&t--;for(var r=0;r0&&(this.words[r]=~this.words[r]&67108863>>26-n),this.strip()},i.prototype.notn=function(e){return this.clone().inotn(e)},i.prototype.setn=function(e,t){o("number"==typeof e&&e>=0);var n=e/26|0,r=e%26;return this._expand(n+1),this.words[n]=t?this.words[n]|1<e.length?(n=this,o=e):(n=e,o=this);for(var r=0,i=0;i>>26;for(;0!==r&&i>>26;if(this.length=n.length,0!==r)this.words[this.length]=r,this.length++;else if(n!==this)for(;ie.length?this.clone().iadd(e):e.clone().iadd(this)},i.prototype.isub=function(e){if(0!==e.negative){e.negative=0;var t=this.iadd(e);return e.negative=1,t._normSign()}if(0!==this.negative)return this.negative=0,this.iadd(e),this.negative=1,this._normSign();var n,o,r=this.cmp(e);if(0===r)return this.negative=0,this.length=1,this.words[0]=0,this;r>0?(n=this,o=e):(n=e,o=this);for(var i=0,a=0;a>26,this.words[a]=67108863&t;for(;0!==i&&a>26,this.words[a]=67108863&t;if(0===i&&a>>13,p=0|a[1],f=8191&p,g=p>>>13,m=0|a[2],_=8191&m,F=m>>>13,y=0|a[3],b=8191&y,v=y>>>13,w=0|a[4],E=8191&w,k=w>>>13,D=0|a[5],S=8191&D,x=D>>>13,C=0|a[6],A=8191&C,T=C>>>13,R=0|a[7],I=8191&R,M=R>>>13,O=0|a[8],B=8191&O,N=O>>>13,L=0|a[9],P=8191&L,U=L>>>13,j=0|s[0],q=8191&j,z=j>>>13,K=0|s[1],G=8191&K,$=K>>>13,H=0|s[2],V=8191&H,W=H>>>13,Y=0|s[3],Z=8191&Y,X=Y>>>13,J=0|s[4],Q=8191&J,ee=J>>>13,te=0|s[5],ne=8191&te,oe=te>>>13,re=0|s[6],ie=8191&re,ae=re>>>13,se=0|s[7],ue=8191&se,ce=se>>>13,le=0|s[8],de=8191&le,he=le>>>13,pe=0|s[9],fe=8191&pe,ge=pe>>>13;n.negative=e.negative^t.negative,n.length=19;var me=(c+(o=Math.imul(d,q))|0)+((8191&(r=(r=Math.imul(d,z))+Math.imul(h,q)|0))<<13)|0;c=((i=Math.imul(h,z))+(r>>>13)|0)+(me>>>26)|0,me&=67108863,o=Math.imul(f,q),r=(r=Math.imul(f,z))+Math.imul(g,q)|0,i=Math.imul(g,z);var _e=(c+(o=o+Math.imul(d,G)|0)|0)+((8191&(r=(r=r+Math.imul(d,$)|0)+Math.imul(h,G)|0))<<13)|0;c=((i=i+Math.imul(h,$)|0)+(r>>>13)|0)+(_e>>>26)|0,_e&=67108863,o=Math.imul(_,q),r=(r=Math.imul(_,z))+Math.imul(F,q)|0,i=Math.imul(F,z),o=o+Math.imul(f,G)|0,r=(r=r+Math.imul(f,$)|0)+Math.imul(g,G)|0,i=i+Math.imul(g,$)|0;var Fe=(c+(o=o+Math.imul(d,V)|0)|0)+((8191&(r=(r=r+Math.imul(d,W)|0)+Math.imul(h,V)|0))<<13)|0;c=((i=i+Math.imul(h,W)|0)+(r>>>13)|0)+(Fe>>>26)|0,Fe&=67108863,o=Math.imul(b,q),r=(r=Math.imul(b,z))+Math.imul(v,q)|0,i=Math.imul(v,z),o=o+Math.imul(_,G)|0,r=(r=r+Math.imul(_,$)|0)+Math.imul(F,G)|0,i=i+Math.imul(F,$)|0,o=o+Math.imul(f,V)|0,r=(r=r+Math.imul(f,W)|0)+Math.imul(g,V)|0,i=i+Math.imul(g,W)|0;var ye=(c+(o=o+Math.imul(d,Z)|0)|0)+((8191&(r=(r=r+Math.imul(d,X)|0)+Math.imul(h,Z)|0))<<13)|0;c=((i=i+Math.imul(h,X)|0)+(r>>>13)|0)+(ye>>>26)|0,ye&=67108863,o=Math.imul(E,q),r=(r=Math.imul(E,z))+Math.imul(k,q)|0,i=Math.imul(k,z),o=o+Math.imul(b,G)|0,r=(r=r+Math.imul(b,$)|0)+Math.imul(v,G)|0,i=i+Math.imul(v,$)|0,o=o+Math.imul(_,V)|0,r=(r=r+Math.imul(_,W)|0)+Math.imul(F,V)|0,i=i+Math.imul(F,W)|0,o=o+Math.imul(f,Z)|0,r=(r=r+Math.imul(f,X)|0)+Math.imul(g,Z)|0,i=i+Math.imul(g,X)|0;var be=(c+(o=o+Math.imul(d,Q)|0)|0)+((8191&(r=(r=r+Math.imul(d,ee)|0)+Math.imul(h,Q)|0))<<13)|0;c=((i=i+Math.imul(h,ee)|0)+(r>>>13)|0)+(be>>>26)|0,be&=67108863,o=Math.imul(S,q),r=(r=Math.imul(S,z))+Math.imul(x,q)|0,i=Math.imul(x,z),o=o+Math.imul(E,G)|0,r=(r=r+Math.imul(E,$)|0)+Math.imul(k,G)|0,i=i+Math.imul(k,$)|0,o=o+Math.imul(b,V)|0,r=(r=r+Math.imul(b,W)|0)+Math.imul(v,V)|0,i=i+Math.imul(v,W)|0,o=o+Math.imul(_,Z)|0,r=(r=r+Math.imul(_,X)|0)+Math.imul(F,Z)|0,i=i+Math.imul(F,X)|0,o=o+Math.imul(f,Q)|0,r=(r=r+Math.imul(f,ee)|0)+Math.imul(g,Q)|0,i=i+Math.imul(g,ee)|0;var ve=(c+(o=o+Math.imul(d,ne)|0)|0)+((8191&(r=(r=r+Math.imul(d,oe)|0)+Math.imul(h,ne)|0))<<13)|0;c=((i=i+Math.imul(h,oe)|0)+(r>>>13)|0)+(ve>>>26)|0,ve&=67108863,o=Math.imul(A,q),r=(r=Math.imul(A,z))+Math.imul(T,q)|0,i=Math.imul(T,z),o=o+Math.imul(S,G)|0,r=(r=r+Math.imul(S,$)|0)+Math.imul(x,G)|0,i=i+Math.imul(x,$)|0,o=o+Math.imul(E,V)|0,r=(r=r+Math.imul(E,W)|0)+Math.imul(k,V)|0,i=i+Math.imul(k,W)|0,o=o+Math.imul(b,Z)|0,r=(r=r+Math.imul(b,X)|0)+Math.imul(v,Z)|0,i=i+Math.imul(v,X)|0,o=o+Math.imul(_,Q)|0,r=(r=r+Math.imul(_,ee)|0)+Math.imul(F,Q)|0,i=i+Math.imul(F,ee)|0,o=o+Math.imul(f,ne)|0,r=(r=r+Math.imul(f,oe)|0)+Math.imul(g,ne)|0,i=i+Math.imul(g,oe)|0;var we=(c+(o=o+Math.imul(d,ie)|0)|0)+((8191&(r=(r=r+Math.imul(d,ae)|0)+Math.imul(h,ie)|0))<<13)|0;c=((i=i+Math.imul(h,ae)|0)+(r>>>13)|0)+(we>>>26)|0,we&=67108863,o=Math.imul(I,q),r=(r=Math.imul(I,z))+Math.imul(M,q)|0,i=Math.imul(M,z),o=o+Math.imul(A,G)|0,r=(r=r+Math.imul(A,$)|0)+Math.imul(T,G)|0,i=i+Math.imul(T,$)|0,o=o+Math.imul(S,V)|0,r=(r=r+Math.imul(S,W)|0)+Math.imul(x,V)|0,i=i+Math.imul(x,W)|0,o=o+Math.imul(E,Z)|0,r=(r=r+Math.imul(E,X)|0)+Math.imul(k,Z)|0,i=i+Math.imul(k,X)|0,o=o+Math.imul(b,Q)|0,r=(r=r+Math.imul(b,ee)|0)+Math.imul(v,Q)|0,i=i+Math.imul(v,ee)|0,o=o+Math.imul(_,ne)|0,r=(r=r+Math.imul(_,oe)|0)+Math.imul(F,ne)|0,i=i+Math.imul(F,oe)|0,o=o+Math.imul(f,ie)|0,r=(r=r+Math.imul(f,ae)|0)+Math.imul(g,ie)|0,i=i+Math.imul(g,ae)|0;var Ee=(c+(o=o+Math.imul(d,ue)|0)|0)+((8191&(r=(r=r+Math.imul(d,ce)|0)+Math.imul(h,ue)|0))<<13)|0;c=((i=i+Math.imul(h,ce)|0)+(r>>>13)|0)+(Ee>>>26)|0,Ee&=67108863,o=Math.imul(B,q),r=(r=Math.imul(B,z))+Math.imul(N,q)|0,i=Math.imul(N,z),o=o+Math.imul(I,G)|0,r=(r=r+Math.imul(I,$)|0)+Math.imul(M,G)|0,i=i+Math.imul(M,$)|0,o=o+Math.imul(A,V)|0,r=(r=r+Math.imul(A,W)|0)+Math.imul(T,V)|0,i=i+Math.imul(T,W)|0,o=o+Math.imul(S,Z)|0,r=(r=r+Math.imul(S,X)|0)+Math.imul(x,Z)|0,i=i+Math.imul(x,X)|0,o=o+Math.imul(E,Q)|0,r=(r=r+Math.imul(E,ee)|0)+Math.imul(k,Q)|0,i=i+Math.imul(k,ee)|0,o=o+Math.imul(b,ne)|0,r=(r=r+Math.imul(b,oe)|0)+Math.imul(v,ne)|0,i=i+Math.imul(v,oe)|0,o=o+Math.imul(_,ie)|0,r=(r=r+Math.imul(_,ae)|0)+Math.imul(F,ie)|0,i=i+Math.imul(F,ae)|0,o=o+Math.imul(f,ue)|0,r=(r=r+Math.imul(f,ce)|0)+Math.imul(g,ue)|0,i=i+Math.imul(g,ce)|0;var ke=(c+(o=o+Math.imul(d,de)|0)|0)+((8191&(r=(r=r+Math.imul(d,he)|0)+Math.imul(h,de)|0))<<13)|0;c=((i=i+Math.imul(h,he)|0)+(r>>>13)|0)+(ke>>>26)|0,ke&=67108863,o=Math.imul(P,q),r=(r=Math.imul(P,z))+Math.imul(U,q)|0,i=Math.imul(U,z),o=o+Math.imul(B,G)|0,r=(r=r+Math.imul(B,$)|0)+Math.imul(N,G)|0,i=i+Math.imul(N,$)|0,o=o+Math.imul(I,V)|0,r=(r=r+Math.imul(I,W)|0)+Math.imul(M,V)|0,i=i+Math.imul(M,W)|0,o=o+Math.imul(A,Z)|0,r=(r=r+Math.imul(A,X)|0)+Math.imul(T,Z)|0,i=i+Math.imul(T,X)|0,o=o+Math.imul(S,Q)|0,r=(r=r+Math.imul(S,ee)|0)+Math.imul(x,Q)|0,i=i+Math.imul(x,ee)|0,o=o+Math.imul(E,ne)|0,r=(r=r+Math.imul(E,oe)|0)+Math.imul(k,ne)|0,i=i+Math.imul(k,oe)|0,o=o+Math.imul(b,ie)|0,r=(r=r+Math.imul(b,ae)|0)+Math.imul(v,ie)|0,i=i+Math.imul(v,ae)|0,o=o+Math.imul(_,ue)|0,r=(r=r+Math.imul(_,ce)|0)+Math.imul(F,ue)|0,i=i+Math.imul(F,ce)|0,o=o+Math.imul(f,de)|0,r=(r=r+Math.imul(f,he)|0)+Math.imul(g,de)|0,i=i+Math.imul(g,he)|0;var De=(c+(o=o+Math.imul(d,fe)|0)|0)+((8191&(r=(r=r+Math.imul(d,ge)|0)+Math.imul(h,fe)|0))<<13)|0;c=((i=i+Math.imul(h,ge)|0)+(r>>>13)|0)+(De>>>26)|0,De&=67108863,o=Math.imul(P,G),r=(r=Math.imul(P,$))+Math.imul(U,G)|0,i=Math.imul(U,$),o=o+Math.imul(B,V)|0,r=(r=r+Math.imul(B,W)|0)+Math.imul(N,V)|0,i=i+Math.imul(N,W)|0,o=o+Math.imul(I,Z)|0,r=(r=r+Math.imul(I,X)|0)+Math.imul(M,Z)|0,i=i+Math.imul(M,X)|0,o=o+Math.imul(A,Q)|0,r=(r=r+Math.imul(A,ee)|0)+Math.imul(T,Q)|0,i=i+Math.imul(T,ee)|0,o=o+Math.imul(S,ne)|0,r=(r=r+Math.imul(S,oe)|0)+Math.imul(x,ne)|0,i=i+Math.imul(x,oe)|0,o=o+Math.imul(E,ie)|0,r=(r=r+Math.imul(E,ae)|0)+Math.imul(k,ie)|0,i=i+Math.imul(k,ae)|0,o=o+Math.imul(b,ue)|0,r=(r=r+Math.imul(b,ce)|0)+Math.imul(v,ue)|0,i=i+Math.imul(v,ce)|0,o=o+Math.imul(_,de)|0,r=(r=r+Math.imul(_,he)|0)+Math.imul(F,de)|0,i=i+Math.imul(F,he)|0;var Se=(c+(o=o+Math.imul(f,fe)|0)|0)+((8191&(r=(r=r+Math.imul(f,ge)|0)+Math.imul(g,fe)|0))<<13)|0;c=((i=i+Math.imul(g,ge)|0)+(r>>>13)|0)+(Se>>>26)|0,Se&=67108863,o=Math.imul(P,V),r=(r=Math.imul(P,W))+Math.imul(U,V)|0,i=Math.imul(U,W),o=o+Math.imul(B,Z)|0,r=(r=r+Math.imul(B,X)|0)+Math.imul(N,Z)|0,i=i+Math.imul(N,X)|0,o=o+Math.imul(I,Q)|0,r=(r=r+Math.imul(I,ee)|0)+Math.imul(M,Q)|0,i=i+Math.imul(M,ee)|0,o=o+Math.imul(A,ne)|0,r=(r=r+Math.imul(A,oe)|0)+Math.imul(T,ne)|0,i=i+Math.imul(T,oe)|0,o=o+Math.imul(S,ie)|0,r=(r=r+Math.imul(S,ae)|0)+Math.imul(x,ie)|0,i=i+Math.imul(x,ae)|0,o=o+Math.imul(E,ue)|0,r=(r=r+Math.imul(E,ce)|0)+Math.imul(k,ue)|0,i=i+Math.imul(k,ce)|0,o=o+Math.imul(b,de)|0,r=(r=r+Math.imul(b,he)|0)+Math.imul(v,de)|0,i=i+Math.imul(v,he)|0;var xe=(c+(o=o+Math.imul(_,fe)|0)|0)+((8191&(r=(r=r+Math.imul(_,ge)|0)+Math.imul(F,fe)|0))<<13)|0;c=((i=i+Math.imul(F,ge)|0)+(r>>>13)|0)+(xe>>>26)|0,xe&=67108863,o=Math.imul(P,Z),r=(r=Math.imul(P,X))+Math.imul(U,Z)|0,i=Math.imul(U,X),o=o+Math.imul(B,Q)|0,r=(r=r+Math.imul(B,ee)|0)+Math.imul(N,Q)|0,i=i+Math.imul(N,ee)|0,o=o+Math.imul(I,ne)|0,r=(r=r+Math.imul(I,oe)|0)+Math.imul(M,ne)|0,i=i+Math.imul(M,oe)|0,o=o+Math.imul(A,ie)|0,r=(r=r+Math.imul(A,ae)|0)+Math.imul(T,ie)|0,i=i+Math.imul(T,ae)|0,o=o+Math.imul(S,ue)|0,r=(r=r+Math.imul(S,ce)|0)+Math.imul(x,ue)|0,i=i+Math.imul(x,ce)|0,o=o+Math.imul(E,de)|0,r=(r=r+Math.imul(E,he)|0)+Math.imul(k,de)|0,i=i+Math.imul(k,he)|0;var Ce=(c+(o=o+Math.imul(b,fe)|0)|0)+((8191&(r=(r=r+Math.imul(b,ge)|0)+Math.imul(v,fe)|0))<<13)|0;c=((i=i+Math.imul(v,ge)|0)+(r>>>13)|0)+(Ce>>>26)|0,Ce&=67108863,o=Math.imul(P,Q),r=(r=Math.imul(P,ee))+Math.imul(U,Q)|0,i=Math.imul(U,ee),o=o+Math.imul(B,ne)|0,r=(r=r+Math.imul(B,oe)|0)+Math.imul(N,ne)|0,i=i+Math.imul(N,oe)|0,o=o+Math.imul(I,ie)|0,r=(r=r+Math.imul(I,ae)|0)+Math.imul(M,ie)|0,i=i+Math.imul(M,ae)|0,o=o+Math.imul(A,ue)|0,r=(r=r+Math.imul(A,ce)|0)+Math.imul(T,ue)|0,i=i+Math.imul(T,ce)|0,o=o+Math.imul(S,de)|0,r=(r=r+Math.imul(S,he)|0)+Math.imul(x,de)|0,i=i+Math.imul(x,he)|0;var Ae=(c+(o=o+Math.imul(E,fe)|0)|0)+((8191&(r=(r=r+Math.imul(E,ge)|0)+Math.imul(k,fe)|0))<<13)|0;c=((i=i+Math.imul(k,ge)|0)+(r>>>13)|0)+(Ae>>>26)|0,Ae&=67108863,o=Math.imul(P,ne),r=(r=Math.imul(P,oe))+Math.imul(U,ne)|0,i=Math.imul(U,oe),o=o+Math.imul(B,ie)|0,r=(r=r+Math.imul(B,ae)|0)+Math.imul(N,ie)|0,i=i+Math.imul(N,ae)|0,o=o+Math.imul(I,ue)|0,r=(r=r+Math.imul(I,ce)|0)+Math.imul(M,ue)|0,i=i+Math.imul(M,ce)|0,o=o+Math.imul(A,de)|0,r=(r=r+Math.imul(A,he)|0)+Math.imul(T,de)|0,i=i+Math.imul(T,he)|0;var Te=(c+(o=o+Math.imul(S,fe)|0)|0)+((8191&(r=(r=r+Math.imul(S,ge)|0)+Math.imul(x,fe)|0))<<13)|0;c=((i=i+Math.imul(x,ge)|0)+(r>>>13)|0)+(Te>>>26)|0,Te&=67108863,o=Math.imul(P,ie),r=(r=Math.imul(P,ae))+Math.imul(U,ie)|0,i=Math.imul(U,ae),o=o+Math.imul(B,ue)|0,r=(r=r+Math.imul(B,ce)|0)+Math.imul(N,ue)|0,i=i+Math.imul(N,ce)|0,o=o+Math.imul(I,de)|0,r=(r=r+Math.imul(I,he)|0)+Math.imul(M,de)|0,i=i+Math.imul(M,he)|0;var Re=(c+(o=o+Math.imul(A,fe)|0)|0)+((8191&(r=(r=r+Math.imul(A,ge)|0)+Math.imul(T,fe)|0))<<13)|0;c=((i=i+Math.imul(T,ge)|0)+(r>>>13)|0)+(Re>>>26)|0,Re&=67108863,o=Math.imul(P,ue),r=(r=Math.imul(P,ce))+Math.imul(U,ue)|0,i=Math.imul(U,ce),o=o+Math.imul(B,de)|0,r=(r=r+Math.imul(B,he)|0)+Math.imul(N,de)|0,i=i+Math.imul(N,he)|0;var Ie=(c+(o=o+Math.imul(I,fe)|0)|0)+((8191&(r=(r=r+Math.imul(I,ge)|0)+Math.imul(M,fe)|0))<<13)|0;c=((i=i+Math.imul(M,ge)|0)+(r>>>13)|0)+(Ie>>>26)|0,Ie&=67108863,o=Math.imul(P,de),r=(r=Math.imul(P,he))+Math.imul(U,de)|0,i=Math.imul(U,he);var Me=(c+(o=o+Math.imul(B,fe)|0)|0)+((8191&(r=(r=r+Math.imul(B,ge)|0)+Math.imul(N,fe)|0))<<13)|0;c=((i=i+Math.imul(N,ge)|0)+(r>>>13)|0)+(Me>>>26)|0,Me&=67108863;var Oe=(c+(o=Math.imul(P,fe))|0)+((8191&(r=(r=Math.imul(P,ge))+Math.imul(U,fe)|0))<<13)|0;return c=((i=Math.imul(U,ge))+(r>>>13)|0)+(Oe>>>26)|0,Oe&=67108863,u[0]=me,u[1]=_e,u[2]=Fe,u[3]=ye,u[4]=be,u[5]=ve,u[6]=we,u[7]=Ee,u[8]=ke,u[9]=De,u[10]=Se,u[11]=xe,u[12]=Ce,u[13]=Ae,u[14]=Te,u[15]=Re,u[16]=Ie,u[17]=Me,u[18]=Oe,0!==c&&(u[19]=c,n.length++),n};function g(e,t,n){return(new m).mulp(e,t,n)}function m(e,t){this.x=e,this.y=t}Math.imul||(f=p),i.prototype.mulTo=function(e,t){var n=this.length+e.length;return 10===this.length&&10===e.length?f(this,e,t):n<63?p(this,e,t):n<1024?function(e,t,n){n.negative=t.negative^e.negative,n.length=e.length+t.length;for(var o=0,r=0,i=0;i>>26)|0)>>>26,a&=67108863}n.words[i]=s,o=a,a=r}return 0!==o?n.words[i]=o:n.length--,n.strip()}(this,e,t):g(this,e,t)},m.prototype.makeRBT=function(e){for(var t=new Array(e),n=i.prototype._countBits(e)-1,o=0;o>=1;return o},m.prototype.permute=function(e,t,n,o,r,i){for(var a=0;a>>=1)r++;return 1<>>=13,n[2*a+1]=8191&i,i>>>=13;for(a=2*t;a>=26,t+=r/67108864|0,t+=i>>>26,this.words[n]=67108863&i}return 0!==t&&(this.words[n]=t,this.length++),this},i.prototype.muln=function(e){return this.clone().imuln(e)},i.prototype.sqr=function(){return this.mul(this)},i.prototype.isqr=function(){return this.imul(this.clone())},i.prototype.pow=function(e){var t=function(e){for(var t=new Array(e.bitLength()),n=0;n>>r}return t}(e);if(0===t.length)return new i(1);for(var n=this,o=0;o=0);var t,n=e%26,r=(e-n)/26,i=67108863>>>26-n<<26-n;if(0!==n){var a=0;for(t=0;t>>26-n}a&&(this.words[t]=a,this.length++)}if(0!==r){for(t=this.length-1;t>=0;t--)this.words[t+r]=this.words[t];for(t=0;t=0),r=t?(t-t%26)/26:0;var i=e%26,a=Math.min((e-i)/26,this.length),s=67108863^67108863>>>i<a)for(this.length-=a,c=0;c=0&&(0!==l||c>=r);c--){var d=0|this.words[c];this.words[c]=l<<26-i|d>>>i,l=d&s}return u&&0!==l&&(u.words[u.length++]=l),0===this.length&&(this.words[0]=0,this.length=1),this.strip()},i.prototype.ishrn=function(e,t,n){return o(0===this.negative),this.iushrn(e,t,n)},i.prototype.shln=function(e){return this.clone().ishln(e)},i.prototype.ushln=function(e){return this.clone().iushln(e)},i.prototype.shrn=function(e){return this.clone().ishrn(e)},i.prototype.ushrn=function(e){return this.clone().iushrn(e)},i.prototype.testn=function(e){o("number"==typeof e&&e>=0);var t=e%26,n=(e-t)/26,r=1<=0);var t=e%26,n=(e-t)/26;if(o(0===this.negative,"imaskn works only with positive numbers"),this.length<=n)return this;if(0!==t&&n++,this.length=Math.min(n,this.length),0!==t){var r=67108863^67108863>>>t<=67108864;t++)this.words[t]-=67108864,t===this.length-1?this.words[t+1]=1:this.words[t+1]++;return this.length=Math.max(this.length,t+1),this},i.prototype.isubn=function(e){if(o("number"==typeof e),o(e<67108864),e<0)return this.iaddn(-e);if(0!==this.negative)return this.negative=0,this.iaddn(e),this.negative=1,this;if(this.words[0]-=e,1===this.length&&this.words[0]<0)this.words[0]=-this.words[0],this.negative=1;else for(var t=0;t>26)-(u/67108864|0),this.words[r+n]=67108863&i}for(;r>26,this.words[r+n]=67108863&i;if(0===s)return this.strip();for(o(-1===s),s=0,r=0;r>26,this.words[r]=67108863&i;return this.negative=1,this.strip()},i.prototype._wordDiv=function(e,t){var n=(this.length,e.length),o=this.clone(),r=e,a=0|r.words[r.length-1];0!=(n=26-this._countBits(a))&&(r=r.ushln(n),o.iushln(n),a=0|r.words[r.length-1]);var s,u=o.length-r.length;if("mod"!==t){(s=new i(null)).length=u+1,s.words=new Array(s.length);for(var c=0;c=0;d--){var h=67108864*(0|o.words[r.length+d])+(0|o.words[r.length+d-1]);for(h=Math.min(h/a|0,67108863),o._ishlnsubmul(r,h,d);0!==o.negative;)h--,o.negative=0,o._ishlnsubmul(r,1,d),o.isZero()||(o.negative^=1);s&&(s.words[d]=h)}return s&&s.strip(),o.strip(),"div"!==t&&0!==n&&o.iushrn(n),{div:s||null,mod:o}},i.prototype.divmod=function(e,t,n){return o(!e.isZero()),this.isZero()?{div:new i(0),mod:new i(0)}:0!==this.negative&&0===e.negative?(s=this.neg().divmod(e,t),"mod"!==t&&(r=s.div.neg()),"div"!==t&&(a=s.mod.neg(),n&&0!==a.negative&&a.iadd(e)),{div:r,mod:a}):0===this.negative&&0!==e.negative?(s=this.divmod(e.neg(),t),"mod"!==t&&(r=s.div.neg()),{div:r,mod:s.mod}):0!=(this.negative&e.negative)?(s=this.neg().divmod(e.neg(),t),"div"!==t&&(a=s.mod.neg(),n&&0!==a.negative&&a.isub(e)),{div:s.div,mod:a}):e.length>this.length||this.cmp(e)<0?{div:new i(0),mod:this}:1===e.length?"div"===t?{div:this.divn(e.words[0]),mod:null}:"mod"===t?{div:null,mod:new i(this.modn(e.words[0]))}:{div:this.divn(e.words[0]),mod:new i(this.modn(e.words[0]))}:this._wordDiv(e,t);var r,a,s},i.prototype.div=function(e){return this.divmod(e,"div",!1).div},i.prototype.mod=function(e){return this.divmod(e,"mod",!1).mod},i.prototype.umod=function(e){return this.divmod(e,"mod",!0).mod},i.prototype.divRound=function(e){var t=this.divmod(e);if(t.mod.isZero())return t.div;var n=0!==t.div.negative?t.mod.isub(e):t.mod,o=e.ushrn(1),r=e.andln(1),i=n.cmp(o);return i<0||1===r&&0===i?t.div:0!==t.div.negative?t.div.isubn(1):t.div.iaddn(1)},i.prototype.modn=function(e){o(e<=67108863);for(var t=(1<<26)%e,n=0,r=this.length-1;r>=0;r--)n=(t*n+(0|this.words[r]))%e;return n},i.prototype.idivn=function(e){o(e<=67108863);for(var t=0,n=this.length-1;n>=0;n--){var r=(0|this.words[n])+67108864*t;this.words[n]=r/e|0,t=r%e}return this.strip()},i.prototype.divn=function(e){return this.clone().idivn(e)},i.prototype.egcd=function(e){o(0===e.negative),o(!e.isZero());var t=this,n=e.clone();t=0!==t.negative?t.umod(e):t.clone();for(var r=new i(1),a=new i(0),s=new i(0),u=new i(1),c=0;t.isEven()&&n.isEven();)t.iushrn(1),n.iushrn(1),++c;for(var l=n.clone(),d=t.clone();!t.isZero();){for(var h=0,p=1;0==(t.words[0]&p)&&h<26;++h,p<<=1);if(h>0)for(t.iushrn(h);h-- >0;)(r.isOdd()||a.isOdd())&&(r.iadd(l),a.isub(d)),r.iushrn(1),a.iushrn(1);for(var f=0,g=1;0==(n.words[0]&g)&&f<26;++f,g<<=1);if(f>0)for(n.iushrn(f);f-- >0;)(s.isOdd()||u.isOdd())&&(s.iadd(l),u.isub(d)),s.iushrn(1),u.iushrn(1);t.cmp(n)>=0?(t.isub(n),r.isub(s),a.isub(u)):(n.isub(t),s.isub(r),u.isub(a))}return{a:s,b:u,gcd:n.iushln(c)}},i.prototype._invmp=function(e){o(0===e.negative),o(!e.isZero());var t=this,n=e.clone();t=0!==t.negative?t.umod(e):t.clone();for(var r,a=new i(1),s=new i(0),u=n.clone();t.cmpn(1)>0&&n.cmpn(1)>0;){for(var c=0,l=1;0==(t.words[0]&l)&&c<26;++c,l<<=1);if(c>0)for(t.iushrn(c);c-- >0;)a.isOdd()&&a.iadd(u),a.iushrn(1);for(var d=0,h=1;0==(n.words[0]&h)&&d<26;++d,h<<=1);if(d>0)for(n.iushrn(d);d-- >0;)s.isOdd()&&s.iadd(u),s.iushrn(1);t.cmp(n)>=0?(t.isub(n),a.isub(s)):(n.isub(t),s.isub(a))}return(r=0===t.cmpn(1)?a:s).cmpn(0)<0&&r.iadd(e),r},i.prototype.gcd=function(e){if(this.isZero())return e.abs();if(e.isZero())return this.abs();var t=this.clone(),n=e.clone();t.negative=0,n.negative=0;for(var o=0;t.isEven()&&n.isEven();o++)t.iushrn(1),n.iushrn(1);for(;;){for(;t.isEven();)t.iushrn(1);for(;n.isEven();)n.iushrn(1);var r=t.cmp(n);if(r<0){var i=t;t=n,n=i}else if(0===r||0===n.cmpn(1))break;t.isub(n)}return n.iushln(o)},i.prototype.invm=function(e){return this.egcd(e).a.umod(e)},i.prototype.isEven=function(){return 0==(1&this.words[0])},i.prototype.isOdd=function(){return 1==(1&this.words[0])},i.prototype.andln=function(e){return this.words[0]&e},i.prototype.bincn=function(e){o("number"==typeof e);var t=e%26,n=(e-t)/26,r=1<>>26,s&=67108863,this.words[a]=s}return 0!==i&&(this.words[a]=i,this.length++),this},i.prototype.isZero=function(){return 1===this.length&&0===this.words[0]},i.prototype.cmpn=function(e){var t,n=e<0;if(0!==this.negative&&!n)return-1;if(0===this.negative&&n)return 1;if(this.strip(),this.length>1)t=1;else{n&&(e=-e),o(e<=67108863,"Number is too big");var r=0|this.words[0];t=r===e?0:re.length)return 1;if(this.length=0;n--){var o=0|this.words[n],r=0|e.words[n];if(o!==r){or&&(t=1);break}}return t},i.prototype.gtn=function(e){return 1===this.cmpn(e)},i.prototype.gt=function(e){return 1===this.cmp(e)},i.prototype.gten=function(e){return this.cmpn(e)>=0},i.prototype.gte=function(e){return this.cmp(e)>=0},i.prototype.ltn=function(e){return-1===this.cmpn(e)},i.prototype.lt=function(e){return-1===this.cmp(e)},i.prototype.lten=function(e){return this.cmpn(e)<=0},i.prototype.lte=function(e){return this.cmp(e)<=0},i.prototype.eqn=function(e){return 0===this.cmpn(e)},i.prototype.eq=function(e){return 0===this.cmp(e)},i.red=function(e){return new E(e)},i.prototype.toRed=function(e){return o(!this.red,"Already a number in reduction context"),o(0===this.negative,"red works only with positives"),e.convertTo(this)._forceRed(e)},i.prototype.fromRed=function(){return o(this.red,"fromRed works only with numbers in reduction context"),this.red.convertFrom(this)},i.prototype._forceRed=function(e){return this.red=e,this},i.prototype.forceRed=function(e){return o(!this.red,"Already a number in reduction context"),this._forceRed(e)},i.prototype.redAdd=function(e){return o(this.red,"redAdd works only with red numbers"),this.red.add(this,e)},i.prototype.redIAdd=function(e){return o(this.red,"redIAdd works only with red numbers"),this.red.iadd(this,e)},i.prototype.redSub=function(e){return o(this.red,"redSub works only with red numbers"),this.red.sub(this,e)},i.prototype.redISub=function(e){return o(this.red,"redISub works only with red numbers"),this.red.isub(this,e)},i.prototype.redShl=function(e){return o(this.red,"redShl works only with red numbers"),this.red.shl(this,e)},i.prototype.redMul=function(e){return o(this.red,"redMul works only with red numbers"),this.red._verify2(this,e),this.red.mul(this,e)},i.prototype.redIMul=function(e){return o(this.red,"redMul works only with red numbers"),this.red._verify2(this,e),this.red.imul(this,e)},i.prototype.redSqr=function(){return o(this.red,"redSqr works only with red numbers"),this.red._verify1(this),this.red.sqr(this)},i.prototype.redISqr=function(){return o(this.red,"redISqr works only with red numbers"),this.red._verify1(this),this.red.isqr(this)},i.prototype.redSqrt=function(){return o(this.red,"redSqrt works only with red numbers"),this.red._verify1(this),this.red.sqrt(this)},i.prototype.redInvm=function(){return o(this.red,"redInvm works only with red numbers"),this.red._verify1(this),this.red.invm(this)},i.prototype.redNeg=function(){return o(this.red,"redNeg works only with red numbers"),this.red._verify1(this),this.red.neg(this)},i.prototype.redPow=function(e){return o(this.red&&!e.red,"redPow(normalNum)"),this.red._verify1(this),this.red.pow(this,e)};var _={k256:null,p224:null,p192:null,p25519:null};function F(e,t){this.name=e,this.p=new i(t,16),this.n=this.p.bitLength(),this.k=new i(1).iushln(this.n).isub(this.p),this.tmp=this._tmp()}function y(){F.call(this,"k256","ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f")}function b(){F.call(this,"p224","ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001")}function v(){F.call(this,"p192","ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff")}function w(){F.call(this,"25519","7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed")}function E(e){if("string"==typeof e){var t=i._prime(e);this.m=t.p,this.prime=t}else o(e.gtn(1),"modulus must be greater than 1"),this.m=e,this.prime=null}function k(e){E.call(this,e),this.shift=this.m.bitLength(),this.shift%26!=0&&(this.shift+=26-this.shift%26),this.r=new i(1).iushln(this.shift),this.r2=this.imod(this.r.sqr()),this.rinv=this.r._invmp(this.m),this.minv=this.rinv.mul(this.r).isubn(1).div(this.m),this.minv=this.minv.umod(this.r),this.minv=this.r.sub(this.minv)}F.prototype._tmp=function(){var e=new i(null);return e.words=new Array(Math.ceil(this.n/13)),e},F.prototype.ireduce=function(e){var t,n=e;do{this.split(n,this.tmp),t=(n=(n=this.imulK(n)).iadd(this.tmp)).bitLength()}while(t>this.n);var o=t0?n.isub(this.p):void 0!==n.strip?n.strip():n._strip(),n},F.prototype.split=function(e,t){e.iushrn(this.n,0,t)},F.prototype.imulK=function(e){return e.imul(this.k)},r(y,F),y.prototype.split=function(e,t){for(var n=4194303,o=Math.min(e.length,9),r=0;r>>22,i=a}i>>>=22,e.words[r-10]=i,0===i&&e.length>10?e.length-=10:e.length-=9},y.prototype.imulK=function(e){e.words[e.length]=0,e.words[e.length+1]=0,e.length+=2;for(var t=0,n=0;n>>=26,e.words[n]=r,t=o}return 0!==t&&(e.words[e.length++]=t),e},i._prime=function(e){if(_[e])return _[e];var t;if("k256"===e)t=new y;else if("p224"===e)t=new b;else if("p192"===e)t=new v;else{if("p25519"!==e)throw new Error("Unknown prime "+e);t=new w}return _[e]=t,t},E.prototype._verify1=function(e){o(0===e.negative,"red works only with positives"),o(e.red,"red works only with red numbers")},E.prototype._verify2=function(e,t){o(0==(e.negative|t.negative),"red works only with positives"),o(e.red&&e.red===t.red,"red works only with red numbers")},E.prototype.imod=function(e){return this.prime?this.prime.ireduce(e)._forceRed(this):e.umod(this.m)._forceRed(this)},E.prototype.neg=function(e){return e.isZero()?e.clone():this.m.sub(e)._forceRed(this)},E.prototype.add=function(e,t){this._verify2(e,t);var n=e.add(t);return n.cmp(this.m)>=0&&n.isub(this.m),n._forceRed(this)},E.prototype.iadd=function(e,t){this._verify2(e,t);var n=e.iadd(t);return n.cmp(this.m)>=0&&n.isub(this.m),n},E.prototype.sub=function(e,t){this._verify2(e,t);var n=e.sub(t);return n.cmpn(0)<0&&n.iadd(this.m),n._forceRed(this)},E.prototype.isub=function(e,t){this._verify2(e,t);var n=e.isub(t);return n.cmpn(0)<0&&n.iadd(this.m),n},E.prototype.shl=function(e,t){return this._verify1(e),this.imod(e.ushln(t))},E.prototype.imul=function(e,t){return this._verify2(e,t),this.imod(e.imul(t))},E.prototype.mul=function(e,t){return this._verify2(e,t),this.imod(e.mul(t))},E.prototype.isqr=function(e){return this.imul(e,e.clone())},E.prototype.sqr=function(e){return this.mul(e,e)},E.prototype.sqrt=function(e){if(e.isZero())return e.clone();var t=this.m.andln(3);if(o(t%2==1),3===t){var n=this.m.add(new i(1)).iushrn(2);return this.pow(e,n)}for(var r=this.m.subn(1),a=0;!r.isZero()&&0===r.andln(1);)a++,r.iushrn(1);o(!r.isZero());var s=new i(1).toRed(this),u=s.redNeg(),c=this.m.subn(1).iushrn(1),l=this.m.bitLength();for(l=new i(2*l*l).toRed(this);0!==this.pow(l,c).cmp(u);)l.redIAdd(u);for(var d=this.pow(l,r),h=this.pow(e,r.addn(1).iushrn(1)),p=this.pow(e,r),f=a;0!==p.cmp(s);){for(var g=p,m=0;0!==g.cmp(s);m++)g=g.redSqr();o(m=0;o--){for(var c=t.words[o],l=u-1;l>=0;l--){var d=c>>l&1;r!==n[0]&&(r=this.sqr(r)),0!==d||0!==a?(a<<=1,a|=d,(4==++s||0===o&&0===l)&&(r=this.mul(r,n[a]),s=0,a=0)):s=0}u=26}return r},E.prototype.convertTo=function(e){var t=e.umod(this.m);return t===e?t.clone():t},E.prototype.convertFrom=function(e){var t=e.clone();return t.red=null,t},i.mont=function(e){return new k(e)},r(k,E),k.prototype.convertTo=function(e){return this.imod(e.ushln(this.shift))},k.prototype.convertFrom=function(e){var t=this.imod(e.mul(this.rinv));return t.red=null,t},k.prototype.imul=function(e,t){if(e.isZero()||t.isZero())return e.words[0]=0,e.length=1,e;var n=e.imul(t),o=n.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m),r=n.isub(o).iushrn(this.shift),i=r;return r.cmp(this.m)>=0?i=r.isub(this.m):r.cmpn(0)<0&&(i=r.iadd(this.m)),i._forceRed(this)},k.prototype.mul=function(e,t){if(e.isZero()||t.isZero())return new i(0)._forceRed(this);var n=e.mul(t),o=n.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m),r=n.isub(o).iushrn(this.shift),a=r;return r.cmp(this.m)>=0?a=r.isub(this.m):r.cmpn(0)<0&&(a=r.iadd(this.m)),a._forceRed(this)},k.prototype.invm=function(e){return this.imod(e._invmp(this.m).mul(this.r2))._forceRed(this)}}(e=n.nmd(e),this)},17519:e=>{"use strict";e.exports={i8:"6.5.4"}},76555:(e,t,n)=>{var o=n(90233);function r(e,t,n){t&&"string"!=typeof t&&(t=t.message||t.name),o(this,{type:e,name:e,cause:"string"!=typeof t?t:n,message:t},"ewr")}function i(e,t){Error.call(this),Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor),r.call(this,"CustomError",e,t)}i.prototype=new Error,e.exports=function(e){var t=function(t,n){return function(e,t,n){var o=function(n,i){r.call(this,t,n,i),"FilesystemError"==t&&(this.code=this.cause.code,this.path=this.cause.path,this.errno=this.cause.errno,this.message=(e.errno[this.cause.errno]?e.errno[this.cause.errno].description:this.cause.message)+(this.cause.path?" ["+this.cause.path+"]":"")),Error.call(this),Error.captureStackTrace&&Error.captureStackTrace(this,o)};return o.prototype=n?new n:new i,o}(e,t,n)};return{CustomError:i,FilesystemError:t("FilesystemError"),createError:t}}},47138:(e,t,n)=>{var o=e.exports.all=[{errno:-2,code:"ENOENT",description:"no such file or directory"},{errno:-1,code:"UNKNOWN",description:"unknown error"},{errno:0,code:"OK",description:"success"},{errno:1,code:"EOF",description:"end of file"},{errno:2,code:"EADDRINFO",description:"getaddrinfo error"},{errno:3,code:"EACCES",description:"permission denied"},{errno:4,code:"EAGAIN",description:"resource temporarily unavailable"},{errno:5,code:"EADDRINUSE",description:"address already in use"},{errno:6,code:"EADDRNOTAVAIL",description:"address not available"},{errno:7,code:"EAFNOSUPPORT",description:"address family not supported"},{errno:8,code:"EALREADY",description:"connection already in progress"},{errno:9,code:"EBADF",description:"bad file descriptor"},{errno:10,code:"EBUSY",description:"resource busy or locked"},{errno:11,code:"ECONNABORTED",description:"software caused connection abort"},{errno:12,code:"ECONNREFUSED",description:"connection refused"},{errno:13,code:"ECONNRESET",description:"connection reset by peer"},{errno:14,code:"EDESTADDRREQ",description:"destination address required"},{errno:15,code:"EFAULT",description:"bad address in system call argument"},{errno:16,code:"EHOSTUNREACH",description:"host is unreachable"},{errno:17,code:"EINTR",description:"interrupted system call"},{errno:18,code:"EINVAL",description:"invalid argument"},{errno:19,code:"EISCONN",description:"socket is already connected"},{errno:20,code:"EMFILE",description:"too many open files"},{errno:21,code:"EMSGSIZE",description:"message too long"},{errno:22,code:"ENETDOWN",description:"network is down"},{errno:23,code:"ENETUNREACH",description:"network is unreachable"},{errno:24,code:"ENFILE",description:"file table overflow"},{errno:25,code:"ENOBUFS",description:"no buffer space available"},{errno:26,code:"ENOMEM",description:"not enough memory"},{errno:27,code:"ENOTDIR",description:"not a directory"},{errno:28,code:"EISDIR",description:"illegal operation on a directory"},{errno:29,code:"ENONET",description:"machine is not on the network"},{errno:31,code:"ENOTCONN",description:"socket is not connected"},{errno:32,code:"ENOTSOCK",description:"socket operation on non-socket"},{errno:33,code:"ENOTSUP",description:"operation not supported on socket"},{errno:34,code:"ENOENT",description:"no such file or directory"},{errno:35,code:"ENOSYS",description:"function not implemented"},{errno:36,code:"EPIPE",description:"broken pipe"},{errno:37,code:"EPROTO",description:"protocol error"},{errno:38,code:"EPROTONOSUPPORT",description:"protocol not supported"},{errno:39,code:"EPROTOTYPE",description:"protocol wrong type for socket"},{errno:40,code:"ETIMEDOUT",description:"connection timed out"},{errno:41,code:"ECHARSET",description:"invalid Unicode character"},{errno:42,code:"EAIFAMNOSUPPORT",description:"address family for hostname not supported"},{errno:44,code:"EAISERVICE",description:"servname not supported for ai_socktype"},{errno:45,code:"EAISOCKTYPE",description:"ai_socktype not supported"},{errno:46,code:"ESHUTDOWN",description:"cannot send after transport endpoint shutdown"},{errno:47,code:"EEXIST",description:"file already exists"},{errno:48,code:"ESRCH",description:"no such process"},{errno:49,code:"ENAMETOOLONG",description:"name too long"},{errno:50,code:"EPERM",description:"operation not permitted"},{errno:51,code:"ELOOP",description:"too many symbolic links encountered"},{errno:52,code:"EXDEV",description:"cross-device link not permitted"},{errno:53,code:"ENOTEMPTY",description:"directory not empty"},{errno:54,code:"ENOSPC",description:"no space left on device"},{errno:55,code:"EIO",description:"i/o error"},{errno:56,code:"EROFS",description:"read-only file system"},{errno:57,code:"ENODEV",description:"no such device"},{errno:58,code:"ESPIPE",description:"invalid seek"},{errno:59,code:"ECANCELED",description:"operation canceled"}];e.exports.errno={},e.exports.code={},o.forEach((function(t){e.exports.errno[t.errno]=t,e.exports.code[t.code]=t})),e.exports.custom=n(76555)(e.exports),e.exports.create=e.exports.custom.createError},94079:(e,t,n)=>{"use strict";var o=n(40210)("%Object.getOwnPropertyDescriptor%");if(o)try{o([],"length")}catch(e){o=null}e.exports=o},17187:e=>{"use strict";var t,n="object"==typeof Reflect?Reflect:null,o=n&&"function"==typeof n.apply?n.apply:function(e,t,n){return Function.prototype.apply.call(e,t,n)};t=n&&"function"==typeof n.ownKeys?n.ownKeys:Object.getOwnPropertySymbols?function(e){return Object.getOwnPropertyNames(e).concat(Object.getOwnPropertySymbols(e))}:function(e){return Object.getOwnPropertyNames(e)};var r=Number.isNaN||function(e){return e!=e};function i(){i.init.call(this)}e.exports=i,e.exports.once=function(e,t){return new Promise((function(n,o){function r(n){e.removeListener(t,i),o(n)}function i(){"function"==typeof e.removeListener&&e.removeListener("error",r),n([].slice.call(arguments))}g(e,t,i,{once:!0}),"error"!==t&&function(e,t,n){"function"==typeof e.on&&g(e,"error",t,{once:!0})}(e,r)}))},i.EventEmitter=i,i.prototype._events=void 0,i.prototype._eventsCount=0,i.prototype._maxListeners=void 0;var a=10;function s(e){if("function"!=typeof e)throw new TypeError('The "listener" argument must be of type Function. Received type '+typeof e)}function u(e){return void 0===e._maxListeners?i.defaultMaxListeners:e._maxListeners}function c(e,t,n,o){var r,i,a,c;if(s(n),void 0===(i=e._events)?(i=e._events=Object.create(null),e._eventsCount=0):(void 0!==i.newListener&&(e.emit("newListener",t,n.listener?n.listener:n),i=e._events),a=i[t]),void 0===a)a=i[t]=n,++e._eventsCount;else if("function"==typeof a?a=i[t]=o?[n,a]:[a,n]:o?a.unshift(n):a.push(n),(r=u(e))>0&&a.length>r&&!a.warned){a.warned=!0;var l=new Error("Possible EventEmitter memory leak detected. "+a.length+" "+String(t)+" listeners added. Use emitter.setMaxListeners() to increase limit");l.name="MaxListenersExceededWarning",l.emitter=e,l.type=t,l.count=a.length,c=l,console&&console.warn&&console.warn(c)}return e}function l(){if(!this.fired)return this.target.removeListener(this.type,this.wrapFn),this.fired=!0,0===arguments.length?this.listener.call(this.target):this.listener.apply(this.target,arguments)}function d(e,t,n){var o={fired:!1,wrapFn:void 0,target:e,type:t,listener:n},r=l.bind(o);return r.listener=n,o.wrapFn=r,r}function h(e,t,n){var o=e._events;if(void 0===o)return[];var r=o[t];return void 0===r?[]:"function"==typeof r?n?[r.listener||r]:[r]:n?function(e){for(var t=new Array(e.length),n=0;n0&&(a=t[0]),a instanceof Error)throw a;var s=new Error("Unhandled error."+(a?" ("+a.message+")":""));throw s.context=a,s}var u=i[e];if(void 0===u)return!1;if("function"==typeof u)o(u,this,t);else{var c=u.length,l=f(u,c);for(n=0;n=0;i--)if(n[i]===t||n[i].listener===t){a=n[i].listener,r=i;break}if(r<0)return this;0===r?n.shift():function(e,t){for(;t+1=0;o--)this.removeListener(e,t[o]);return this},i.prototype.listeners=function(e){return h(this,e,!0)},i.prototype.rawListeners=function(e){return h(this,e,!1)},i.listenerCount=function(e,t){return"function"==typeof e.listenerCount?e.listenerCount(t):p.call(e,t)},i.prototype.listenerCount=p,i.prototype.eventNames=function(){return this._eventsCount>0?t(this._events):[]}},13048:(e,t,n)=>{var o=n(89509).Buffer,r=n(62318);e.exports=function(e,t,n,i){if(o.isBuffer(e)||(e=o.from(e,"binary")),t&&(o.isBuffer(t)||(t=o.from(t,"binary")),8!==t.length))throw new RangeError("salt should be Buffer with 8 byte length");for(var a=n/8,s=o.alloc(a),u=o.alloc(i||0),c=o.alloc(0);a>0||i>0;){var l=new r;l.update(c),l.update(e),t&&l.update(t),c=l.digest();var d=0;if(a>0){var h=s.length-a;d=Math.min(a,c.length),c.copy(s,h,0,d),a-=d}if(d0){var p=u.length-i,f=Math.min(i,c.length-d);c.copy(u,p,d,d+f),i-=f}}return c.fill(0),{key:s,iv:u}}},58875:(e,t,n)=>{var o;!function(){"use strict";var r=!("undefined"==typeof window||!window.document||!window.document.createElement),i={canUseDOM:r,canUseWorkers:"undefined"!=typeof Worker,canUseEventListeners:r&&!(!window.addEventListener&&!window.attachEvent),canUseViewport:r&&!!window.screen};void 0===(o=function(){return i}.call(t,n,t,e))||(e.exports=o)}()},94470:e=>{"use strict";var t=Object.prototype.hasOwnProperty,n=Object.prototype.toString,o=Object.defineProperty,r=Object.getOwnPropertyDescriptor,i=function(e){return"function"==typeof Array.isArray?Array.isArray(e):"[object Array]"===n.call(e)},a=function(e){if(!e||"[object Object]"!==n.call(e))return!1;var o,r=t.call(e,"constructor"),i=e.constructor&&e.constructor.prototype&&t.call(e.constructor.prototype,"isPrototypeOf");if(e.constructor&&!r&&!i)return!1;for(o in e);return void 0===o||t.call(e,o)},s=function(e,t){o&&"__proto__"===t.name?o(e,t.name,{enumerable:!0,configurable:!0,value:t.newValue,writable:!0}):e[t.name]=t.newValue},u=function(e,n){if("__proto__"===n){if(!t.call(e,n))return;if(r)return r(e,n).value}return e[n]};e.exports=function e(){var t,n,o,r,c,l,d=arguments[0],h=1,p=arguments.length,f=!1;for("boolean"==typeof d&&(f=d,d=arguments[1]||{},h=2),(null==d||"object"!=typeof d&&"function"!=typeof d)&&(d={});h{"use strict";e.exports=function(e,t){for(var n=arguments.length,o=new Array(n>2?n-2:0),r=2;r{e.exports.Dispatcher=n(61063)},61063:(e,t,n)=>{"use strict";function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var r=n(73759),i=function(){function e(){o(this,"_callbacks",void 0),o(this,"_isDispatching",void 0),o(this,"_isHandled",void 0),o(this,"_isPending",void 0),o(this,"_lastID",void 0),o(this,"_pendingPayload",void 0),this._callbacks={},this._isDispatching=!1,this._isHandled={},this._isPending={},this._lastID=1}var t=e.prototype;return t.register=function(e){var t="ID_"+this._lastID++;return this._callbacks[t]=e,t},t.unregister=function(e){this._callbacks[e]||r(!1),delete this._callbacks[e]},t.waitFor=function(e){this._isDispatching||r(!1);for(var t=0;t{var t=Object.prototype.hasOwnProperty,n=Object.prototype.toString;e.exports=function(e,o,r){if("[object Function]"!==n.call(o))throw new TypeError("iterator must be a function");var i=e.length;if(i===+i)for(var a=0;a{"use strict";var t="Function.prototype.bind called on incompatible ",n=Array.prototype.slice,o=Object.prototype.toString,r="[object Function]";e.exports=function(e){var i=this;if("function"!=typeof i||o.call(i)!==r)throw new TypeError(t+i);for(var a,s=n.call(arguments,1),u=function(){if(this instanceof a){var t=i.apply(this,s.concat(n.call(arguments)));return Object(t)===t?t:this}return i.apply(e,s.concat(n.call(arguments)))},c=Math.max(0,i.length-s.length),l=[],d=0;d{"use strict";var o=n(17648);e.exports=Function.prototype.bind||o},35673:(e,t,n)=>{var o=n(26272),r=n(79941),i=n(18673),a=new Buffer(0),s=function(){},u=function(e){return"function"==typeof e?e:function(t){t(null,e)}},c=function(e,t){var n=!1,o=!1;return e._read=function(){n=!0},e.destroy=function(){o=!0},t((function(t,r){if(t)return e.emit("error",t);var i=function(){for(var t;null!==(t=r.read());)n=!1,e.push(t)};if(r.on("readable",(function(){n&&i()})),r.on("end",(function(){i(),e.push(null)})),r.on("error",(function(t){e.emit("error",t)})),r.on("close",(function(){i(),process.nextTick((function(){e.emit("close")}))})),e._read=function(){n=!0,i()},e.destroy=function(){o||(o=!0,r.destroy&&r.destroy())},o)return o=!1,void e.destroy();n&&i()})),e},l=function(e,t){var n=s,o=!1;return e._write=function(e,t,o){n=o},e.destroy=function(){o=!0},e.write(a),t((function(t,r){if(t)return e.emit("error",t);r.on("close",(function(){e.emit("close")})),r.on("error",(function(t){e.emit("error",t)})),e._write=function(e,t,n){if(e===a)return n();r.write(e,t,n)};var i=e.emit;if(r.on("finish",(function(){i.call(e,"finish")})),e.destroy=function(){o||(o=!0,r.destroy&&r.destroy())},e.emit=function(t){if("finish"!==t)return i.apply(e,arguments);r.end()},o)return o=!1,void e.destroy();n()})),e};t.readable=function(e,n){return 1===arguments.length?t.readable(null,e):(e||(e={}),c(new r(e),u(n)))},t.writable=function(e,n){return 1===arguments.length?t.writable(null,e):(e||(e={}),l(new o(e),u(n)))},t.duplex=function(e,n,o){if(2===arguments.length)return t.duplex(null,e,n);e||(e={});var r=new i(e);return l(r,u(n)),c(r,u(o)),r}},23419:e=>{e.exports=Array.isArray||function(e){return"[object Array]"==Object.prototype.toString.call(e)}},18673:(e,t,n)=>{e.exports=n(55410)},55410:(e,t,n)=>{e.exports=s;var o=Object.keys||function(e){var t=[];for(var n in e)t.push(n);return t},r=n(16497);r.inherits=n(35717);var i=n(93558),a=n(9315);function s(e){if(!(this instanceof s))return new s(e);i.call(this,e),a.call(this,e),e&&!1===e.readable&&(this.readable=!1),e&&!1===e.writable&&(this.writable=!1),this.allowHalfOpen=!0,e&&!1===e.allowHalfOpen&&(this.allowHalfOpen=!1),this.once("end",u)}function u(){this.allowHalfOpen||this._writableState.ended||process.nextTick(this.end.bind(this))}r.inherits(s,i),function(e,t){for(var n=0,o=e.length;n{e.exports=i;var o=n(12590),r=n(16497);function i(e){if(!(this instanceof i))return new i(e);o.call(this,e)}r.inherits=n(35717),r.inherits(i,o),i.prototype._transform=function(e,t,n){n(null,e)}},93558:(e,t,n)=>{e.exports=l;var o=n(23419),r=n(48764).Buffer;l.ReadableState=c;var i=n(17187).EventEmitter;i.listenerCount||(i.listenerCount=function(e,t){return e.listeners(t).length});var a,s=n(42830),u=n(16497);function c(e,t){var o=(e=e||{}).highWaterMark;this.highWaterMark=o||0===o?o:16384,this.highWaterMark=~~this.highWaterMark,this.buffer=[],this.length=0,this.pipes=null,this.pipesCount=0,this.flowing=!1,this.ended=!1,this.endEmitted=!1,this.reading=!1,this.calledRead=!1,this.sync=!0,this.needReadable=!1,this.emittedReadable=!1,this.readableListening=!1,this.objectMode=!!e.objectMode,this.defaultEncoding=e.defaultEncoding||"utf8",this.ranOut=!1,this.awaitDrain=0,this.readingMore=!1,this.decoder=null,this.encoding=null,e.encoding&&(a||(a=n(26250).s),this.decoder=new a(e.encoding),this.encoding=e.encoding)}function l(e){if(!(this instanceof l))return new l(e);this._readableState=new c(e,this),this.readable=!0,s.call(this)}function d(e,t,n,o,i){var a=function(e,t){var n=null;return r.isBuffer(t)||"string"==typeof t||null==t||e.objectMode||(n=new TypeError("Invalid non-string/buffer chunk")),n}(t,n);if(a)e.emit("error",a);else if(null==n)t.reading=!1,t.ended||function(e,t){if(t.decoder&&!t.ended){var n=t.decoder.end();n&&n.length&&(t.buffer.push(n),t.length+=t.objectMode?1:n.length)}t.ended=!0,t.length>0?f(e):b(e)}(e,t);else if(t.objectMode||n&&n.length>0)if(t.ended&&!i){var s=new Error("stream.push() after EOF");e.emit("error",s)}else t.endEmitted&&i?(s=new Error("stream.unshift() after end event"),e.emit("error",s)):(!t.decoder||i||o||(n=t.decoder.write(n)),t.length+=t.objectMode?1:n.length,i?t.buffer.unshift(n):(t.reading=!1,t.buffer.push(n)),t.needReadable&&f(e),function(e,t){t.readingMore||(t.readingMore=!0,process.nextTick((function(){!function(e,t){for(var n=t.length;!t.reading&&!t.flowing&&!t.ended&&t.lengtht.highWaterMark&&(t.highWaterMark=function(e){if(e>=h)e=h;else{e--;for(var t=1;t<32;t<<=1)e|=e>>t;e++}return e}(e)),e>t.length?t.ended?t.length:(t.needReadable=!0,0):e)}function f(e){var t=e._readableState;t.needReadable=!1,t.emittedReadable||(t.emittedReadable=!0,t.sync?process.nextTick((function(){g(e)})):g(e))}function g(e){e.emit("readable")}function m(e){var t,n=e._readableState;function o(e,o,r){!1===e.write(t)&&n.awaitDrain++}for(n.awaitDrain=0;n.pipesCount&&null!==(t=e.read());)if(1===n.pipesCount?o(n.pipes):v(n.pipes,o),e.emit("data",t),n.awaitDrain>0)return;if(0===n.pipesCount)return n.flowing=!1,void(i.listenerCount(e,"data")>0&&F(e));n.ranOut=!0}function _(){this._readableState.ranOut&&(this._readableState.ranOut=!1,m(this))}function F(e,t){if(e._readableState.flowing)throw new Error("Cannot switch to old mode now.");var n=t||!1,o=!1;e.readable=!0,e.pipe=s.prototype.pipe,e.on=e.addListener=s.prototype.on,e.on("readable",(function(){var t;for(o=!0;!n&&null!==(t=e.read());)e.emit("data",t);null===t&&(o=!1,e._readableState.needReadable=!0)})),e.pause=function(){n=!0,this.emit("pause")},e.resume=function(){n=!1,o?process.nextTick((function(){e.emit("readable")})):this.read(0),this.emit("resume")},e.emit("readable")}function y(e,t){var n,o=t.buffer,i=t.length,a=!!t.decoder,s=!!t.objectMode;if(0===o.length)return null;if(0===i)n=null;else if(s)n=o.shift();else if(!e||e>=i)n=a?o.join(""):r.concat(o,i),o.length=0;else if(e0)throw new Error("endReadable called on non-empty stream");!t.endEmitted&&t.calledRead&&(t.ended=!0,process.nextTick((function(){t.endEmitted||0!==t.length||(t.endEmitted=!0,e.readable=!1,e.emit("end"))})))}function v(e,t){for(var n=0,o=e.length;n0)&&(t.emittedReadable=!1),0===e&&t.needReadable&&(t.length>=t.highWaterMark||t.ended))return f(this),null;if(0===(e=p(e,t))&&t.ended)return n=null,t.length>0&&t.decoder&&(n=y(e,t),t.length-=n.length),0===t.length&&b(this),n;var r=t.needReadable;return t.length-e<=t.highWaterMark&&(r=!0),(t.ended||t.reading)&&(r=!1),r&&(t.reading=!0,t.sync=!0,0===t.length&&(t.needReadable=!0),this._read(t.highWaterMark),t.sync=!1),r&&!t.reading&&(e=p(o,t)),null===(n=e>0?y(e,t):null)&&(t.needReadable=!0,e=0),t.length-=e,0!==t.length||t.ended||(t.needReadable=!0),t.ended&&!t.endEmitted&&0===t.length&&b(this),n},l.prototype._read=function(e){this.emit("error",new Error("not implemented"))},l.prototype.pipe=function(e,t){var n=this,r=this._readableState;switch(r.pipesCount){case 0:r.pipes=e;break;case 1:r.pipes=[r.pipes,e];break;default:r.pipes.push(e)}r.pipesCount+=1;var a=t&&!1===t.end||e===process.stdout||e===process.stderr?l:u;function s(e){e===n&&l()}function u(){e.end()}r.endEmitted?process.nextTick(a):n.once("end",a),e.on("unpipe",s);var c=function(e){return function(){var t=e._readableState;t.awaitDrain--,0===t.awaitDrain&&m(e)}}(n);function l(){e.removeListener("close",h),e.removeListener("finish",p),e.removeListener("drain",c),e.removeListener("error",d),e.removeListener("unpipe",s),n.removeListener("end",u),n.removeListener("end",l),e._writableState&&!e._writableState.needDrain||c()}function d(t){f(),e.removeListener("error",d),0===i.listenerCount(e,"error")&&e.emit("error",t)}function h(){e.removeListener("finish",p),f()}function p(){e.removeListener("close",h),f()}function f(){n.unpipe(e)}return e.on("drain",c),e._events&&e._events.error?o(e._events.error)?e._events.error.unshift(d):e._events.error=[d,e._events.error]:e.on("error",d),e.once("close",h),e.once("finish",p),e.emit("pipe",n),r.flowing||(this.on("readable",_),r.flowing=!0,process.nextTick((function(){m(n)}))),e},l.prototype.unpipe=function(e){var t=this._readableState;if(0===t.pipesCount)return this;if(1===t.pipesCount)return e&&e!==t.pipes||(e||(e=t.pipes),t.pipes=null,t.pipesCount=0,this.removeListener("readable",_),t.flowing=!1,e&&e.emit("unpipe",this)),this;if(!e){var n=t.pipes,o=t.pipesCount;t.pipes=null,t.pipesCount=0,this.removeListener("readable",_),t.flowing=!1;for(var r=0;r{e.exports=a;var o=n(55410),r=n(16497);function i(e,t){this.afterTransform=function(e,n){return function(e,t,n){var o=e._transformState;o.transforming=!1;var r=o.writecb;if(!r)return e.emit("error",new Error("no writecb in Transform class"));o.writechunk=null,o.writecb=null,null!=n&&e.push(n),r&&r(t);var i=e._readableState;i.reading=!1,(i.needReadable||i.length{e.exports=u;var o=n(48764).Buffer;u.WritableState=s;var r=n(16497);r.inherits=n(35717);var i=n(42830);function a(e,t,n){this.chunk=e,this.encoding=t,this.callback=n}function s(e,t){var n=(e=e||{}).highWaterMark;this.highWaterMark=n||0===n?n:16384,this.objectMode=!!e.objectMode,this.highWaterMark=~~this.highWaterMark,this.needDrain=!1,this.ending=!1,this.ended=!1,this.finished=!1;var o=!1===e.decodeStrings;this.decodeStrings=!o,this.defaultEncoding=e.defaultEncoding||"utf8",this.length=0,this.writing=!1,this.sync=!0,this.bufferProcessing=!1,this.onwrite=function(e){!function(e,t){var n=e._writableState,o=n.sync,r=n.writecb;if(function(e){e.writing=!1,e.writecb=null,e.length-=e.writelen,e.writelen=0}(n),t)!function(e,t,n,o,r){n?process.nextTick((function(){r(o)})):r(o),e._writableState.errorEmitted=!0,e.emit("error",o)}(e,0,o,t,r);else{var i=d(0,n);i||n.bufferProcessing||!n.buffer.length||function(e,t){t.bufferProcessing=!0;for(var n=0;n{var o=n(42830);(t=e.exports=n(93558)).Stream=o,t.Readable=t,t.Writable=n(9315),t.Duplex=n(55410),t.Transform=n(12590),t.PassThrough=n(88449),process.browser||"disable"!==process.env.READABLE_STREAM||(e.exports=n(42830))},26272:(e,t,n)=>{e.exports=n(9315)},26250:(e,t,n)=>{var o=n(48764).Buffer,r=o.isEncoding||function(e){switch(e&&e.toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":case"raw":return!0;default:return!1}},i=t.s=function(e){switch(this.encoding=(e||"utf8").toLowerCase().replace(/[-_]/,""),function(e){if(e&&!r(e))throw new Error("Unknown encoding: "+e)}(e),this.encoding){case"utf8":this.surrogateSize=3;break;case"ucs2":case"utf16le":this.surrogateSize=2,this.detectIncompleteChar=s;break;case"base64":this.surrogateSize=3,this.detectIncompleteChar=u;break;default:return void(this.write=a)}this.charBuffer=new o(6),this.charReceived=0,this.charLength=0};function a(e){return e.toString(this.encoding)}function s(e){this.charReceived=e.length%2,this.charLength=this.charReceived?2:0}function u(e){this.charReceived=e.length%3,this.charLength=this.charReceived?3:0}i.prototype.write=function(e){for(var t="";this.charLength;){var n=e.length>=this.charLength-this.charReceived?this.charLength-this.charReceived:e.length;if(e.copy(this.charBuffer,this.charReceived,0,n),this.charReceived+=n,this.charReceived=55296&&o<=56319)){if(this.charReceived=this.charLength=0,0===e.length)return t;break}this.charLength+=this.surrogateSize,t=""}this.detectIncompleteChar(e);var o,r=e.length;if(this.charLength&&(e.copy(this.charBuffer,0,e.length-this.charReceived,r),r-=this.charReceived),r=(t+=e.toString(this.encoding,0,r)).length-1,(o=t.charCodeAt(r))>=55296&&o<=56319){var i=this.surrogateSize;return this.charLength+=i,this.charReceived+=i,this.charBuffer.copy(this.charBuffer,i,0,i),e.copy(this.charBuffer,0,0,i),t.substring(0,r)}return t},i.prototype.detectIncompleteChar=function(e){for(var t=e.length>=3?3:e.length;t>0;t--){var n=e[e.length-t];if(1==t&&n>>5==6){this.charLength=2;break}if(t<=2&&n>>4==14){this.charLength=3;break}if(t<=3&&n>>3==30){this.charLength=4;break}}this.charReceived=t},i.prototype.end=function(e){var t="";if(e&&e.length&&(t=this.write(e)),this.charReceived){var n=this.charReceived,o=this.charBuffer,r=this.encoding;t+=o.slice(0,n).toString(r)}return t}},40210:(e,t,n)=>{"use strict";var o,r=SyntaxError,i=Function,a=TypeError,s=function(e){try{return i('"use strict"; return ('+e+").constructor;")()}catch(e){}},u=Object.getOwnPropertyDescriptor;if(u)try{u({},"")}catch(e){u=null}var c=function(){throw new a},l=u?function(){try{return c}catch(e){try{return u(arguments,"callee").get}catch(e){return c}}}():c,d=n(41405)(),h=Object.getPrototypeOf||function(e){return e.__proto__},p={},f="undefined"==typeof Uint8Array?o:h(Uint8Array),g={"%AggregateError%":"undefined"==typeof AggregateError?o:AggregateError,"%Array%":Array,"%ArrayBuffer%":"undefined"==typeof ArrayBuffer?o:ArrayBuffer,"%ArrayIteratorPrototype%":d?h([][Symbol.iterator]()):o,"%AsyncFromSyncIteratorPrototype%":o,"%AsyncFunction%":p,"%AsyncGenerator%":p,"%AsyncGeneratorFunction%":p,"%AsyncIteratorPrototype%":p,"%Atomics%":"undefined"==typeof Atomics?o:Atomics,"%BigInt%":"undefined"==typeof BigInt?o:BigInt,"%Boolean%":Boolean,"%DataView%":"undefined"==typeof DataView?o:DataView,"%Date%":Date,"%decodeURI%":decodeURI,"%decodeURIComponent%":decodeURIComponent,"%encodeURI%":encodeURI,"%encodeURIComponent%":encodeURIComponent,"%Error%":Error,"%eval%":eval,"%EvalError%":EvalError,"%Float32Array%":"undefined"==typeof Float32Array?o:Float32Array,"%Float64Array%":"undefined"==typeof Float64Array?o:Float64Array,"%FinalizationRegistry%":"undefined"==typeof FinalizationRegistry?o:FinalizationRegistry,"%Function%":i,"%GeneratorFunction%":p,"%Int8Array%":"undefined"==typeof Int8Array?o:Int8Array,"%Int16Array%":"undefined"==typeof Int16Array?o:Int16Array,"%Int32Array%":"undefined"==typeof Int32Array?o:Int32Array,"%isFinite%":isFinite,"%isNaN%":isNaN,"%IteratorPrototype%":d?h(h([][Symbol.iterator]())):o,"%JSON%":"object"==typeof JSON?JSON:o,"%Map%":"undefined"==typeof Map?o:Map,"%MapIteratorPrototype%":"undefined"!=typeof Map&&d?h((new Map)[Symbol.iterator]()):o,"%Math%":Math,"%Number%":Number,"%Object%":Object,"%parseFloat%":parseFloat,"%parseInt%":parseInt,"%Promise%":"undefined"==typeof Promise?o:Promise,"%Proxy%":"undefined"==typeof Proxy?o:Proxy,"%RangeError%":RangeError,"%ReferenceError%":ReferenceError,"%Reflect%":"undefined"==typeof Reflect?o:Reflect,"%RegExp%":RegExp,"%Set%":"undefined"==typeof Set?o:Set,"%SetIteratorPrototype%":"undefined"!=typeof Set&&d?h((new Set)[Symbol.iterator]()):o,"%SharedArrayBuffer%":"undefined"==typeof SharedArrayBuffer?o:SharedArrayBuffer,"%String%":String,"%StringIteratorPrototype%":d?h(""[Symbol.iterator]()):o,"%Symbol%":d?Symbol:o,"%SyntaxError%":r,"%ThrowTypeError%":l,"%TypedArray%":f,"%TypeError%":a,"%Uint8Array%":"undefined"==typeof Uint8Array?o:Uint8Array,"%Uint8ClampedArray%":"undefined"==typeof Uint8ClampedArray?o:Uint8ClampedArray,"%Uint16Array%":"undefined"==typeof Uint16Array?o:Uint16Array,"%Uint32Array%":"undefined"==typeof Uint32Array?o:Uint32Array,"%URIError%":URIError,"%WeakMap%":"undefined"==typeof WeakMap?o:WeakMap,"%WeakRef%":"undefined"==typeof WeakRef?o:WeakRef,"%WeakSet%":"undefined"==typeof WeakSet?o:WeakSet},m=function e(t){var n;if("%AsyncFunction%"===t)n=s("async function () {}");else if("%GeneratorFunction%"===t)n=s("function* () {}");else if("%AsyncGeneratorFunction%"===t)n=s("async function* () {}");else if("%AsyncGenerator%"===t){var o=e("%AsyncGeneratorFunction%");o&&(n=o.prototype)}else if("%AsyncIteratorPrototype%"===t){var r=e("%AsyncGenerator%");r&&(n=h(r.prototype))}return g[t]=n,n},_={"%ArrayBufferPrototype%":["ArrayBuffer","prototype"],"%ArrayPrototype%":["Array","prototype"],"%ArrayProto_entries%":["Array","prototype","entries"],"%ArrayProto_forEach%":["Array","prototype","forEach"],"%ArrayProto_keys%":["Array","prototype","keys"],"%ArrayProto_values%":["Array","prototype","values"],"%AsyncFunctionPrototype%":["AsyncFunction","prototype"],"%AsyncGenerator%":["AsyncGeneratorFunction","prototype"],"%AsyncGeneratorPrototype%":["AsyncGeneratorFunction","prototype","prototype"],"%BooleanPrototype%":["Boolean","prototype"],"%DataViewPrototype%":["DataView","prototype"],"%DatePrototype%":["Date","prototype"],"%ErrorPrototype%":["Error","prototype"],"%EvalErrorPrototype%":["EvalError","prototype"],"%Float32ArrayPrototype%":["Float32Array","prototype"],"%Float64ArrayPrototype%":["Float64Array","prototype"],"%FunctionPrototype%":["Function","prototype"],"%Generator%":["GeneratorFunction","prototype"],"%GeneratorPrototype%":["GeneratorFunction","prototype","prototype"],"%Int8ArrayPrototype%":["Int8Array","prototype"],"%Int16ArrayPrototype%":["Int16Array","prototype"],"%Int32ArrayPrototype%":["Int32Array","prototype"],"%JSONParse%":["JSON","parse"],"%JSONStringify%":["JSON","stringify"],"%MapPrototype%":["Map","prototype"],"%NumberPrototype%":["Number","prototype"],"%ObjectPrototype%":["Object","prototype"],"%ObjProto_toString%":["Object","prototype","toString"],"%ObjProto_valueOf%":["Object","prototype","valueOf"],"%PromisePrototype%":["Promise","prototype"],"%PromiseProto_then%":["Promise","prototype","then"],"%Promise_all%":["Promise","all"],"%Promise_reject%":["Promise","reject"],"%Promise_resolve%":["Promise","resolve"],"%RangeErrorPrototype%":["RangeError","prototype"],"%ReferenceErrorPrototype%":["ReferenceError","prototype"],"%RegExpPrototype%":["RegExp","prototype"],"%SetPrototype%":["Set","prototype"],"%SharedArrayBufferPrototype%":["SharedArrayBuffer","prototype"],"%StringPrototype%":["String","prototype"],"%SymbolPrototype%":["Symbol","prototype"],"%SyntaxErrorPrototype%":["SyntaxError","prototype"],"%TypedArrayPrototype%":["TypedArray","prototype"],"%TypeErrorPrototype%":["TypeError","prototype"],"%Uint8ArrayPrototype%":["Uint8Array","prototype"],"%Uint8ClampedArrayPrototype%":["Uint8ClampedArray","prototype"],"%Uint16ArrayPrototype%":["Uint16Array","prototype"],"%Uint32ArrayPrototype%":["Uint32Array","prototype"],"%URIErrorPrototype%":["URIError","prototype"],"%WeakMapPrototype%":["WeakMap","prototype"],"%WeakSetPrototype%":["WeakSet","prototype"]},F=n(58612),y=n(17642),b=F.call(Function.call,Array.prototype.concat),v=F.call(Function.apply,Array.prototype.splice),w=F.call(Function.call,String.prototype.replace),E=F.call(Function.call,String.prototype.slice),k=/[^%.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|%$))/g,D=/\\(\\)?/g,S=function(e){var t=E(e,0,1),n=E(e,-1);if("%"===t&&"%"!==n)throw new r("invalid intrinsic syntax, expected closing `%`");if("%"===n&&"%"!==t)throw new r("invalid intrinsic syntax, expected opening `%`");var o=[];return w(e,k,(function(e,t,n,r){o[o.length]=n?w(r,D,"$1"):t||e})),o},x=function(e,t){var n,o=e;if(y(_,o)&&(o="%"+(n=_[o])[0]+"%"),y(g,o)){var i=g[o];if(i===p&&(i=m(o)),void 0===i&&!t)throw new a("intrinsic "+e+" exists, but is not available. Please file an issue!");return{alias:n,name:o,value:i}}throw new r("intrinsic "+e+" does not exist!")};e.exports=function(e,t){if("string"!=typeof e||0===e.length)throw new a("intrinsic name must be a non-empty string");if(arguments.length>1&&"boolean"!=typeof t)throw new a('"allowMissing" argument must be a boolean');var n=S(e),o=n.length>0?n[0]:"",i=x("%"+o+"%",t),s=i.name,c=i.value,l=!1,d=i.alias;d&&(o=d[0],v(n,b([0,1],d)));for(var h=1,p=!0;h=n.length){var F=u(c,f);c=(p=!!F)&&"get"in F&&!("originalValue"in F.get)?F.get:c[f]}else p=y(c,f),c=c[f];p&&!l&&(g[s]=c)}}return c}},41405:(e,t,n)=>{"use strict";var o="undefined"!=typeof Symbol&&Symbol,r=n(55419);e.exports=function(){return"function"==typeof o&&"function"==typeof Symbol&&"symbol"==typeof o("foo")&&"symbol"==typeof Symbol("bar")&&r()}},55419:e=>{"use strict";e.exports=function(){if("function"!=typeof Symbol||"function"!=typeof Object.getOwnPropertySymbols)return!1;if("symbol"==typeof Symbol.iterator)return!0;var e={},t=Symbol("test"),n=Object(t);if("string"==typeof t)return!1;if("[object Symbol]"!==Object.prototype.toString.call(t))return!1;if("[object Symbol]"!==Object.prototype.toString.call(n))return!1;for(t in e[t]=42,e)return!1;if("function"==typeof Object.keys&&0!==Object.keys(e).length)return!1;if("function"==typeof Object.getOwnPropertyNames&&0!==Object.getOwnPropertyNames(e).length)return!1;var o=Object.getOwnPropertySymbols(e);if(1!==o.length||o[0]!==t)return!1;if(!Object.prototype.propertyIsEnumerable.call(e,t))return!1;if("function"==typeof Object.getOwnPropertyDescriptor){var r=Object.getOwnPropertyDescriptor(e,t);if(42!==r.value||!0!==r.enumerable)return!1}return!0}},17642:(e,t,n)=>{"use strict";var o=n(58612);e.exports=o.call(Function.call,Object.prototype.hasOwnProperty)},3349:(e,t,n)=>{"use strict";var o=n(89509).Buffer,r=n(70326).Transform;function i(e){r.call(this),this._block=o.allocUnsafe(e),this._blockSize=e,this._blockOffset=0,this._length=[0,0,0,0],this._finalized=!1}n(35717)(i,r),i.prototype._transform=function(e,t,n){var o=null;try{this.update(e,t)}catch(e){o=e}n(o)},i.prototype._flush=function(e){var t=null;try{this.push(this.digest())}catch(e){t=e}e(t)},i.prototype.update=function(e,t){if(function(e,t){if(!o.isBuffer(e)&&"string"!=typeof e)throw new TypeError("Data must be a string or a buffer")}(e),this._finalized)throw new Error("Digest already called");o.isBuffer(e)||(e=o.from(e,t));for(var n=this._block,r=0;this._blockOffset+e.length-r>=this._blockSize;){for(var i=this._blockOffset;i0;++a)this._length[a]+=s,(s=this._length[a]/4294967296|0)>0&&(this._length[a]-=4294967296*s);return this},i.prototype._update=function(){throw new Error("_update is not implemented")},i.prototype.digest=function(e){if(this._finalized)throw new Error("Digest already called");this._finalized=!0;var t=this._digest();void 0!==e&&(t=t.toString(e)),this._block.fill(0),this._blockOffset=0;for(var n=0;n<4;++n)this._length[n]=0;return t},i.prototype._digest=function(){throw new Error("_digest is not implemented")},e.exports=i},9786:e=>{"use strict";var t={};function n(e,n,o){o||(o=Error);var r=function(e){var t,o;function r(t,o,r){return e.call(this,function(e,t,o){return"string"==typeof n?n:n(e,t,o)}(t,o,r))||this}return o=e,(t=r).prototype=Object.create(o.prototype),t.prototype.constructor=t,t.__proto__=o,r}(o);r.prototype.name=o.name,r.prototype.code=e,t[e]=r}function o(e,t){if(Array.isArray(e)){var n=e.length;return e=e.map((function(e){return String(e)})),n>2?"one of ".concat(t," ").concat(e.slice(0,n-1).join(", "),", or ")+e[n-1]:2===n?"one of ".concat(t," ").concat(e[0]," or ").concat(e[1]):"of ".concat(t," ").concat(e[0])}return"of ".concat(t," ").concat(String(e))}n("ERR_INVALID_OPT_VALUE",(function(e,t){return'The value "'+t+'" is invalid for option "'+e+'"'}),TypeError),n("ERR_INVALID_ARG_TYPE",(function(e,t,n){var r,i,a,s,u;if("string"==typeof t&&(i="not ",t.substr(0,i.length)===i)?(r="must not be",t=t.replace(/^not /,"")):r="must be",function(e,t,n){return(void 0===n||n>e.length)&&(n=e.length),e.substring(n-t.length,n)===t}(e," argument"))a="The ".concat(e," ").concat(r," ").concat(o(t,"type"));else{var c=("number"!=typeof u&&(u=0),u+".".length>(s=e).length||-1===s.indexOf(".",u)?"argument":"property");a='The "'.concat(e,'" ').concat(c," ").concat(r," ").concat(o(t,"type"))}return a+". Received type ".concat(typeof n)}),TypeError),n("ERR_STREAM_PUSH_AFTER_EOF","stream.push() after EOF"),n("ERR_METHOD_NOT_IMPLEMENTED",(function(e){return"The "+e+" method is not implemented"})),n("ERR_STREAM_PREMATURE_CLOSE","Premature close"),n("ERR_STREAM_DESTROYED",(function(e){return"Cannot call "+e+" after a stream was destroyed"})),n("ERR_MULTIPLE_CALLBACK","Callback called multiple times"),n("ERR_STREAM_CANNOT_PIPE","Cannot pipe, not readable"),n("ERR_STREAM_WRITE_AFTER_END","write after end"),n("ERR_STREAM_NULL_VALUES","May not write null values to stream",TypeError),n("ERR_UNKNOWN_ENCODING",(function(e){return"Unknown encoding: "+e}),TypeError),n("ERR_STREAM_UNSHIFT_AFTER_END_EVENT","stream.unshift() after end event"),e.exports.q=t},62910:(e,t,n)=>{"use strict";var o=Object.keys||function(e){var t=[];for(var n in e)t.push(n);return t};e.exports=c;var r=n(76748),i=n(70469);n(35717)(c,r);for(var a=o(i.prototype),s=0;s{"use strict";e.exports=r;var o=n(70421);function r(e){if(!(this instanceof r))return new r(e);o.call(this,e)}n(35717)(r,o),r.prototype._transform=function(e,t,n){n(null,e)}},76748:(e,t,n)=>{"use strict";var o;e.exports=k,k.ReadableState=E,n(17187).EventEmitter;var r,i=function(e,t){return e.listeners(t).length},a=n(50677),s=n(48764).Buffer,u=n.g.Uint8Array||function(){},c=n(31616);r=c&&c.debuglog?c.debuglog("stream"):function(){};var l,d,h,p=n(98354),f=n(35072),g=n(31222).getHighWaterMark,m=n(9786).q,_=m.ERR_INVALID_ARG_TYPE,F=m.ERR_STREAM_PUSH_AFTER_EOF,y=m.ERR_METHOD_NOT_IMPLEMENTED,b=m.ERR_STREAM_UNSHIFT_AFTER_END_EVENT;n(35717)(k,a);var v=f.errorOrDestroy,w=["error","close","destroy","pause","resume"];function E(e,t,r){o=o||n(62910),e=e||{},"boolean"!=typeof r&&(r=t instanceof o),this.objectMode=!!e.objectMode,r&&(this.objectMode=this.objectMode||!!e.readableObjectMode),this.highWaterMark=g(this,e,"readableHighWaterMark",r),this.buffer=new p,this.length=0,this.pipes=null,this.pipesCount=0,this.flowing=null,this.ended=!1,this.endEmitted=!1,this.reading=!1,this.sync=!0,this.needReadable=!1,this.emittedReadable=!1,this.readableListening=!1,this.resumeScheduled=!1,this.paused=!0,this.emitClose=!1!==e.emitClose,this.autoDestroy=!!e.autoDestroy,this.destroyed=!1,this.defaultEncoding=e.defaultEncoding||"utf8",this.awaitDrain=0,this.readingMore=!1,this.decoder=null,this.encoding=null,e.encoding&&(l||(l=n(32553).s),this.decoder=new l(e.encoding),this.encoding=e.encoding)}function k(e){if(o=o||n(62910),!(this instanceof k))return new k(e);var t=this instanceof o;this._readableState=new E(e,this,t),this.readable=!0,e&&("function"==typeof e.read&&(this._read=e.read),"function"==typeof e.destroy&&(this._destroy=e.destroy)),a.call(this)}function D(e,t,n,o,i){r("readableAddChunk",t);var a,c=e._readableState;if(null===t)c.reading=!1,function(e,t){if(r("onEofChunk"),!t.ended){if(t.decoder){var n=t.decoder.end();n&&n.length&&(t.buffer.push(n),t.length+=t.objectMode?1:n.length)}t.ended=!0,t.sync?A(e):(t.needReadable=!1,t.emittedReadable||(t.emittedReadable=!0,T(e)))}}(e,c);else if(i||(a=function(e,t){var n,o;return o=t,s.isBuffer(o)||o instanceof u||"string"==typeof t||void 0===t||e.objectMode||(n=new _("chunk",["string","Buffer","Uint8Array"],t)),n}(c,t)),a)v(e,a);else if(c.objectMode||t&&t.length>0)if("string"==typeof t||c.objectMode||Object.getPrototypeOf(t)===s.prototype||(t=function(e){return s.from(e)}(t)),o)c.endEmitted?v(e,new b):S(e,c,t,!0);else if(c.ended)v(e,new F);else{if(c.destroyed)return!1;c.reading=!1,c.decoder&&!n?(t=c.decoder.write(t),c.objectMode||0!==t.length?S(e,c,t,!1):R(e,c)):S(e,c,t,!1)}else o||(c.reading=!1,R(e,c));return!c.ended&&(c.lengtht.highWaterMark&&(t.highWaterMark=function(e){return e>=x?e=x:(e--,e|=e>>>1,e|=e>>>2,e|=e>>>4,e|=e>>>8,e|=e>>>16,e++),e}(e)),e<=t.length?e:t.ended?t.length:(t.needReadable=!0,0))}function A(e){var t=e._readableState;r("emitReadable",t.needReadable,t.emittedReadable),t.needReadable=!1,t.emittedReadable||(r("emitReadable",t.flowing),t.emittedReadable=!0,process.nextTick(T,e))}function T(e){var t=e._readableState;r("emitReadable_",t.destroyed,t.length,t.ended),t.destroyed||!t.length&&!t.ended||(e.emit("readable"),t.emittedReadable=!1),t.needReadable=!t.flowing&&!t.ended&&t.length<=t.highWaterMark,N(e)}function R(e,t){t.readingMore||(t.readingMore=!0,process.nextTick(I,e,t))}function I(e,t){for(;!t.reading&&!t.ended&&(t.length0,t.resumeScheduled&&!t.paused?t.flowing=!0:e.listenerCount("data")>0&&e.resume()}function O(e){r("readable nexttick read 0"),e.read(0)}function B(e,t){r("resume",t.reading),t.reading||e.read(0),t.resumeScheduled=!1,e.emit("resume"),N(e),t.flowing&&!t.reading&&e.read(0)}function N(e){var t=e._readableState;for(r("flow",t.flowing);t.flowing&&null!==e.read(););}function L(e,t){return 0===t.length?null:(t.objectMode?n=t.buffer.shift():!e||e>=t.length?(n=t.decoder?t.buffer.join(""):1===t.buffer.length?t.buffer.first():t.buffer.concat(t.length),t.buffer.clear()):n=t.buffer.consume(e,t.decoder),n);var n}function P(e){var t=e._readableState;r("endReadable",t.endEmitted),t.endEmitted||(t.ended=!0,process.nextTick(U,t,e))}function U(e,t){if(r("endReadableNT",e.endEmitted,e.length),!e.endEmitted&&0===e.length&&(e.endEmitted=!0,t.readable=!1,t.emit("end"),e.autoDestroy)){var n=t._writableState;(!n||n.autoDestroy&&n.finished)&&t.destroy()}}function j(e,t){for(var n=0,o=e.length;n=t.highWaterMark:t.length>0)||t.ended))return r("read: emitReadable",t.length,t.ended),0===t.length&&t.ended?P(this):A(this),null;if(0===(e=C(e,t))&&t.ended)return 0===t.length&&P(this),null;var o,i=t.needReadable;return r("need readable",i),(0===t.length||t.length-e0?L(e,t):null)?(t.needReadable=t.length<=t.highWaterMark,e=0):(t.length-=e,t.awaitDrain=0),0===t.length&&(t.ended||(t.needReadable=!0),n!==e&&t.ended&&P(this)),null!==o&&this.emit("data",o),o},k.prototype._read=function(e){v(this,new y("_read()"))},k.prototype.pipe=function(e,t){var n=this,o=this._readableState;switch(o.pipesCount){case 0:o.pipes=e;break;case 1:o.pipes=[o.pipes,e];break;default:o.pipes.push(e)}o.pipesCount+=1,r("pipe count=%d opts=%j",o.pipesCount,t);var a=t&&!1===t.end||e===process.stdout||e===process.stderr?f:s;function s(){r("onend"),e.end()}o.endEmitted?process.nextTick(a):n.once("end",a),e.on("unpipe",(function t(i,a){r("onunpipe"),i===n&&a&&!1===a.hasUnpiped&&(a.hasUnpiped=!0,r("cleanup"),e.removeListener("close",h),e.removeListener("finish",p),e.removeListener("drain",u),e.removeListener("error",d),e.removeListener("unpipe",t),n.removeListener("end",s),n.removeListener("end",f),n.removeListener("data",l),c=!0,!o.awaitDrain||e._writableState&&!e._writableState.needDrain||u())}));var u=function(e){return function(){var t=e._readableState;r("pipeOnDrain",t.awaitDrain),t.awaitDrain&&t.awaitDrain--,0===t.awaitDrain&&i(e,"data")&&(t.flowing=!0,N(e))}}(n);e.on("drain",u);var c=!1;function l(t){r("ondata");var i=e.write(t);r("dest.write",i),!1===i&&((1===o.pipesCount&&o.pipes===e||o.pipesCount>1&&-1!==j(o.pipes,e))&&!c&&(r("false write response, pause",o.awaitDrain),o.awaitDrain++),n.pause())}function d(t){r("onerror",t),f(),e.removeListener("error",d),0===i(e,"error")&&v(e,t)}function h(){e.removeListener("finish",p),f()}function p(){r("onfinish"),e.removeListener("close",h),f()}function f(){r("unpipe"),n.unpipe(e)}return n.on("data",l),function(e,t,n){if("function"==typeof e.prependListener)return e.prependListener(t,n);e._events&&e._events.error?Array.isArray(e._events.error)?e._events.error.unshift(n):e._events.error=[n,e._events.error]:e.on(t,n)}(e,"error",d),e.once("close",h),e.once("finish",p),e.emit("pipe",n),o.flowing||(r("pipe resume"),n.resume()),e},k.prototype.unpipe=function(e){var t=this._readableState,n={hasUnpiped:!1};if(0===t.pipesCount)return this;if(1===t.pipesCount)return e&&e!==t.pipes||(e||(e=t.pipes),t.pipes=null,t.pipesCount=0,t.flowing=!1,e&&e.emit("unpipe",this,n)),this;if(!e){var o=t.pipes,r=t.pipesCount;t.pipes=null,t.pipesCount=0,t.flowing=!1;for(var i=0;i0,!1!==o.flowing&&this.resume()):"readable"===e&&(o.endEmitted||o.readableListening||(o.readableListening=o.needReadable=!0,o.flowing=!1,o.emittedReadable=!1,r("on readable",o.length,o.reading),o.length?A(this):o.reading||process.nextTick(O,this))),n},k.prototype.addListener=k.prototype.on,k.prototype.removeListener=function(e,t){var n=a.prototype.removeListener.call(this,e,t);return"readable"===e&&process.nextTick(M,this),n},k.prototype.removeAllListeners=function(e){var t=a.prototype.removeAllListeners.apply(this,arguments);return"readable"!==e&&void 0!==e||process.nextTick(M,this),t},k.prototype.resume=function(){var e=this._readableState;return e.flowing||(r("resume"),e.flowing=!e.readableListening,function(e,t){t.resumeScheduled||(t.resumeScheduled=!0,process.nextTick(B,e,t))}(this,e)),e.paused=!1,this},k.prototype.pause=function(){return r("call pause flowing=%j",this._readableState.flowing),!1!==this._readableState.flowing&&(r("pause"),this._readableState.flowing=!1,this.emit("pause")),this._readableState.paused=!0,this},k.prototype.wrap=function(e){var t=this,n=this._readableState,o=!1;for(var i in e.on("end",(function(){if(r("wrapped end"),n.decoder&&!n.ended){var e=n.decoder.end();e&&e.length&&t.push(e)}t.push(null)})),e.on("data",(function(i){r("wrapped data"),n.decoder&&(i=n.decoder.write(i)),n.objectMode&&null==i||(n.objectMode||i&&i.length)&&(t.push(i)||(o=!0,e.pause()))})),e)void 0===this[i]&&"function"==typeof e[i]&&(this[i]=function(t){return function(){return e[t].apply(e,arguments)}}(i));for(var a=0;a{"use strict";e.exports=l;var o=n(9786).q,r=o.ERR_METHOD_NOT_IMPLEMENTED,i=o.ERR_MULTIPLE_CALLBACK,a=o.ERR_TRANSFORM_ALREADY_TRANSFORMING,s=o.ERR_TRANSFORM_WITH_LENGTH_0,u=n(62910);function c(e,t){var n=this._transformState;n.transforming=!1;var o=n.writecb;if(null===o)return this.emit("error",new i);n.writechunk=null,n.writecb=null,null!=t&&this.push(t),o(e);var r=this._readableState;r.reading=!1,(r.needReadable||r.length{"use strict";function o(e){var t=this;this.next=null,this.entry=null,this.finish=function(){!function(e,t,n){var o=e.entry;for(e.entry=null;o;){var r=o.callback;t.pendingcb--,r(undefined),o=o.next}t.corkedRequestsFree.next=e}(t,e)}}var r;e.exports=k,k.WritableState=E;var i,a={deprecate:n(94927)},s=n(50677),u=n(48764).Buffer,c=n.g.Uint8Array||function(){},l=n(35072),d=n(31222).getHighWaterMark,h=n(9786).q,p=h.ERR_INVALID_ARG_TYPE,f=h.ERR_METHOD_NOT_IMPLEMENTED,g=h.ERR_MULTIPLE_CALLBACK,m=h.ERR_STREAM_CANNOT_PIPE,_=h.ERR_STREAM_DESTROYED,F=h.ERR_STREAM_NULL_VALUES,y=h.ERR_STREAM_WRITE_AFTER_END,b=h.ERR_UNKNOWN_ENCODING,v=l.errorOrDestroy;function w(){}function E(e,t,i){r=r||n(62910),e=e||{},"boolean"!=typeof i&&(i=t instanceof r),this.objectMode=!!e.objectMode,i&&(this.objectMode=this.objectMode||!!e.writableObjectMode),this.highWaterMark=d(this,e,"writableHighWaterMark",i),this.finalCalled=!1,this.needDrain=!1,this.ending=!1,this.ended=!1,this.finished=!1,this.destroyed=!1;var a=!1===e.decodeStrings;this.decodeStrings=!a,this.defaultEncoding=e.defaultEncoding||"utf8",this.length=0,this.writing=!1,this.corked=0,this.sync=!0,this.bufferProcessing=!1,this.onwrite=function(e){!function(e,t){var n=e._writableState,o=n.sync,r=n.writecb;if("function"!=typeof r)throw new g;if(function(e){e.writing=!1,e.writecb=null,e.length-=e.writelen,e.writelen=0}(n),t)!function(e,t,n,o,r){--t.pendingcb,n?(process.nextTick(r,o),process.nextTick(T,e,t),e._writableState.errorEmitted=!0,v(e,o)):(r(o),e._writableState.errorEmitted=!0,v(e,o),T(e,t))}(e,n,o,t,r);else{var i=C(n)||e.destroyed;i||n.corked||n.bufferProcessing||!n.bufferedRequest||x(e,n),o?process.nextTick(S,e,n,i,r):S(e,n,i,r)}}(t,e)},this.writecb=null,this.writelen=0,this.bufferedRequest=null,this.lastBufferedRequest=null,this.pendingcb=0,this.prefinished=!1,this.errorEmitted=!1,this.emitClose=!1!==e.emitClose,this.autoDestroy=!!e.autoDestroy,this.bufferedRequestCount=0,this.corkedRequestsFree=new o(this)}function k(e){var t=this instanceof(r=r||n(62910));if(!t&&!i.call(k,this))return new k(e);this._writableState=new E(e,this,t),this.writable=!0,e&&("function"==typeof e.write&&(this._write=e.write),"function"==typeof e.writev&&(this._writev=e.writev),"function"==typeof e.destroy&&(this._destroy=e.destroy),"function"==typeof e.final&&(this._final=e.final)),s.call(this)}function D(e,t,n,o,r,i,a){t.writelen=o,t.writecb=a,t.writing=!0,t.sync=!0,t.destroyed?t.onwrite(new _("write")):n?e._writev(r,t.onwrite):e._write(r,i,t.onwrite),t.sync=!1}function S(e,t,n,o){n||function(e,t){0===t.length&&t.needDrain&&(t.needDrain=!1,e.emit("drain"))}(e,t),t.pendingcb--,o(),T(e,t)}function x(e,t){t.bufferProcessing=!0;var n=t.bufferedRequest;if(e._writev&&n&&n.next){var r=t.bufferedRequestCount,i=new Array(r),a=t.corkedRequestsFree;a.entry=n;for(var s=0,u=!0;n;)i[s]=n,n.isBuf||(u=!1),n=n.next,s+=1;i.allBuffers=u,D(e,t,!0,t.length,i,"",a.finish),t.pendingcb++,t.lastBufferedRequest=null,a.next?(t.corkedRequestsFree=a.next,a.next=null):t.corkedRequestsFree=new o(t),t.bufferedRequestCount=0}else{for(;n;){var c=n.chunk,l=n.encoding,d=n.callback;if(D(e,t,!1,t.objectMode?1:c.length,c,l,d),n=n.next,t.bufferedRequestCount--,t.writing)break}null===n&&(t.lastBufferedRequest=null)}t.bufferedRequest=n,t.bufferProcessing=!1}function C(e){return e.ending&&0===e.length&&null===e.bufferedRequest&&!e.finished&&!e.writing}function A(e,t){e._final((function(n){t.pendingcb--,n&&v(e,n),t.prefinished=!0,e.emit("prefinish"),T(e,t)}))}function T(e,t){var n=C(t);if(n&&(function(e,t){t.prefinished||t.finalCalled||("function"!=typeof e._final||t.destroyed?(t.prefinished=!0,e.emit("prefinish")):(t.pendingcb++,t.finalCalled=!0,process.nextTick(A,e,t)))}(e,t),0===t.pendingcb&&(t.finished=!0,e.emit("finish"),t.autoDestroy))){var o=e._readableState;(!o||o.autoDestroy&&o.endEmitted)&&e.destroy()}return n}n(35717)(k,s),E.prototype.getBuffer=function(){for(var e=this.bufferedRequest,t=[];e;)t.push(e),e=e.next;return t},function(){try{Object.defineProperty(E.prototype,"buffer",{get:a.deprecate((function(){return this.getBuffer()}),"_writableState.buffer is deprecated. Use _writableState.getBuffer instead.","DEP0003")})}catch(e){}}(),"function"==typeof Symbol&&Symbol.hasInstance&&"function"==typeof Function.prototype[Symbol.hasInstance]?(i=Function.prototype[Symbol.hasInstance],Object.defineProperty(k,Symbol.hasInstance,{value:function(e){return!!i.call(this,e)||this===k&&e&&e._writableState instanceof E}})):i=function(e){return e instanceof this},k.prototype.pipe=function(){v(this,new m)},k.prototype.write=function(e,t,n){var o,r=this._writableState,i=!1,a=!r.objectMode&&(o=e,u.isBuffer(o)||o instanceof c);return a&&!u.isBuffer(e)&&(e=function(e){return u.from(e)}(e)),"function"==typeof t&&(n=t,t=null),a?t="buffer":t||(t=r.defaultEncoding),"function"!=typeof n&&(n=w),r.ending?function(e,t){var n=new y;v(e,n),process.nextTick(t,n)}(this,n):(a||function(e,t,n,o){var r;return null===n?r=new F:"string"==typeof n||t.objectMode||(r=new p("chunk",["string","Buffer"],n)),!r||(v(e,r),process.nextTick(o,r),!1)}(this,r,e,n))&&(r.pendingcb++,i=function(e,t,n,o,r,i){if(!n){var a=function(e,t,n){return e.objectMode||!1===e.decodeStrings||"string"!=typeof t||(t=u.from(t,n)),t}(t,o,r);o!==a&&(n=!0,r="buffer",o=a)}var s=t.objectMode?1:o.length;t.length+=s;var c=t.length-1))throw new b(e);return this._writableState.defaultEncoding=e,this},Object.defineProperty(k.prototype,"writableBuffer",{enumerable:!1,get:function(){return this._writableState&&this._writableState.getBuffer()}}),Object.defineProperty(k.prototype,"writableHighWaterMark",{enumerable:!1,get:function(){return this._writableState.highWaterMark}}),k.prototype._write=function(e,t,n){n(new f("_write()"))},k.prototype._writev=null,k.prototype.end=function(e,t,n){var o=this._writableState;return"function"==typeof e?(n=e,e=null,t=null):"function"==typeof t&&(n=t,t=null),null!=e&&this.write(e,t),o.corked&&(o.corked=1,this.uncork()),o.ending||function(e,t,n){t.ending=!0,T(e,t),n&&(t.finished?process.nextTick(n):e.once("finish",n)),t.ended=!0,e.writable=!1}(this,o,n),this},Object.defineProperty(k.prototype,"writableLength",{enumerable:!1,get:function(){return this._writableState.length}}),Object.defineProperty(k.prototype,"destroyed",{enumerable:!1,get:function(){return void 0!==this._writableState&&this._writableState.destroyed},set:function(e){this._writableState&&(this._writableState.destroyed=e)}}),k.prototype.destroy=l.destroy,k.prototype._undestroy=l.undestroy,k.prototype._destroy=function(e,t){t(e)}},30527:(e,t,n)=>{"use strict";var o;function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var i=n(28640),a=Symbol("lastResolve"),s=Symbol("lastReject"),u=Symbol("error"),c=Symbol("ended"),l=Symbol("lastPromise"),d=Symbol("handlePromise"),h=Symbol("stream");function p(e,t){return{value:e,done:t}}function f(e){var t=e[a];if(null!==t){var n=e[h].read();null!==n&&(e[l]=null,e[a]=null,e[s]=null,t(p(n,!1)))}}function g(e){process.nextTick(f,e)}var m=Object.getPrototypeOf((function(){})),_=Object.setPrototypeOf((r(o={get stream(){return this[h]},next:function(){var e=this,t=this[u];if(null!==t)return Promise.reject(t);if(this[c])return Promise.resolve(p(void 0,!0));if(this[h].destroyed)return new Promise((function(t,n){process.nextTick((function(){e[u]?n(e[u]):t(p(void 0,!0))}))}));var n,o=this[l];if(o)n=new Promise(function(e,t){return function(n,o){e.then((function(){t[c]?n(p(void 0,!0)):t[d](n,o)}),o)}}(o,this));else{var r=this[h].read();if(null!==r)return Promise.resolve(p(r,!1));n=new Promise(this[d])}return this[l]=n,n}},Symbol.asyncIterator,(function(){return this})),r(o,"return",(function(){var e=this;return new Promise((function(t,n){e[h].destroy(null,(function(e){e?n(e):t(p(void 0,!0))}))}))})),o),m);e.exports=function(e){var t,n=Object.create(_,(r(t={},h,{value:e,writable:!0}),r(t,a,{value:null,writable:!0}),r(t,s,{value:null,writable:!0}),r(t,u,{value:null,writable:!0}),r(t,c,{value:e._readableState.endEmitted,writable:!0}),r(t,d,{value:function(e,t){var o=n[h].read();o?(n[l]=null,n[a]=null,n[s]=null,e(p(o,!1))):(n[a]=e,n[s]=t)},writable:!0}),t));return n[l]=null,i(e,(function(e){if(e&&"ERR_STREAM_PREMATURE_CLOSE"!==e.code){var t=n[s];return null!==t&&(n[l]=null,n[a]=null,n[s]=null,t(e)),void(n[u]=e)}var o=n[a];null!==o&&(n[l]=null,n[a]=null,n[s]=null,o(p(void 0,!0))),n[c]=!0})),e.on("readable",g.bind(null,n)),n}},98354:(e,t,n)=>{"use strict";function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){for(var n=0;n0?this.tail.next=t:this.head=t,this.tail=t,++this.length}},{key:"unshift",value:function(e){var t={data:e,next:this.head};0===this.length&&(this.tail=t),this.head=t,++this.length}},{key:"shift",value:function(){if(0!==this.length){var e=this.head.data;return 1===this.length?this.head=this.tail=null:this.head=this.head.next,--this.length,e}}},{key:"clear",value:function(){this.head=this.tail=null,this.length=0}},{key:"join",value:function(e){if(0===this.length)return"";for(var t=this.head,n=""+t.data;t=t.next;)n+=e+t.data;return n}},{key:"concat",value:function(e){if(0===this.length)return a.alloc(0);for(var t,n,o,r=a.allocUnsafe(e>>>0),i=this.head,s=0;i;)t=i.data,n=r,o=s,a.prototype.copy.call(t,n,o),s+=i.data.length,i=i.next;return r}},{key:"consume",value:function(e,t){var n;return er.length?r.length:e;if(i===r.length?o+=r:o+=r.slice(0,e),0==(e-=i)){i===r.length?(++n,t.next?this.head=t.next:this.head=this.tail=null):(this.head=t,t.data=r.slice(i));break}++n}return this.length-=n,o}},{key:"_getBuffer",value:function(e){var t=a.allocUnsafe(e),n=this.head,o=1;for(n.data.copy(t),e-=n.data.length;n=n.next;){var r=n.data,i=e>r.length?r.length:e;if(r.copy(t,t.length-e,0,i),0==(e-=i)){i===r.length?(++o,n.next?this.head=n.next:this.head=this.tail=null):(this.head=n,n.data=r.slice(i));break}++o}return this.length-=o,t}},{key:u,value:function(e,t){return s(this,function(e){for(var t=1;t{"use strict";function t(e,t){o(e,t),n(e)}function n(e){e._writableState&&!e._writableState.emitClose||e._readableState&&!e._readableState.emitClose||e.emit("close")}function o(e,t){e.emit("error",t)}e.exports={destroy:function(e,r){var i=this,a=this._readableState&&this._readableState.destroyed,s=this._writableState&&this._writableState.destroyed;return a||s?(r?r(e):e&&(this._writableState?this._writableState.errorEmitted||(this._writableState.errorEmitted=!0,process.nextTick(o,this,e)):process.nextTick(o,this,e)),this):(this._readableState&&(this._readableState.destroyed=!0),this._writableState&&(this._writableState.destroyed=!0),this._destroy(e||null,(function(e){!r&&e?i._writableState?i._writableState.errorEmitted?process.nextTick(n,i):(i._writableState.errorEmitted=!0,process.nextTick(t,i,e)):process.nextTick(t,i,e):r?(process.nextTick(n,i),r(e)):process.nextTick(n,i)})),this)},undestroy:function(){this._readableState&&(this._readableState.destroyed=!1,this._readableState.reading=!1,this._readableState.ended=!1,this._readableState.endEmitted=!1),this._writableState&&(this._writableState.destroyed=!1,this._writableState.ended=!1,this._writableState.ending=!1,this._writableState.finalCalled=!1,this._writableState.prefinished=!1,this._writableState.finished=!1,this._writableState.errorEmitted=!1)},errorOrDestroy:function(e,t){var n=e._readableState,o=e._writableState;n&&n.autoDestroy||o&&o.autoDestroy?e.destroy(t):e.emit("error",t)}}},28640:(e,t,n)=>{"use strict";var o=n(9786).q.ERR_STREAM_PREMATURE_CLOSE;function r(){}e.exports=function e(t,n,i){if("function"==typeof n)return e(t,null,n);n||(n={}),i=function(e){var t=!1;return function(){if(!t){t=!0;for(var n=arguments.length,o=new Array(n),r=0;r{e.exports=function(){throw new Error("Readable.from is not available in the browser")}},64218:(e,t,n)=>{"use strict";var o,r=n(9786).q,i=r.ERR_MISSING_ARGS,a=r.ERR_STREAM_DESTROYED;function s(e){if(e)throw e}function u(e,t,r,i){i=function(e){var t=!1;return function(){t||(t=!0,e.apply(void 0,arguments))}}(i);var s=!1;e.on("close",(function(){s=!0})),void 0===o&&(o=n(28640)),o(e,{readable:t,writable:r},(function(e){if(e)return i(e);s=!0,i()}));var u=!1;return function(t){if(!s&&!u)return u=!0,function(e){return e.setHeader&&"function"==typeof e.abort}(e)?e.abort():"function"==typeof e.destroy?e.destroy():void i(t||new a("pipe"))}}function c(e){e()}function l(e,t){return e.pipe(t)}function d(e){return e.length?"function"!=typeof e[e.length-1]?s:e.pop():s}e.exports=function(){for(var e=arguments.length,t=new Array(e),n=0;n0,(function(e){o||(o=e),e&&a.forEach(c),i||(a.forEach(c),r(o))}))}));return t.reduce(l)}},31222:(e,t,n)=>{"use strict";var o=n(9786).q.ERR_INVALID_OPT_VALUE;e.exports={getHighWaterMark:function(e,t,n,r){var i=function(e,t,n){return null!=e.highWaterMark?e.highWaterMark:t?e[n]:null}(t,r,n);if(null!=i){if(!isFinite(i)||Math.floor(i)!==i||i<0)throw new o(r?n:"highWaterMark",i);return Math.floor(i)}return e.objectMode?16:16384}}},50677:(e,t,n)=>{e.exports=n(17187).EventEmitter},70326:(e,t,n)=>{(t=e.exports=n(76748)).Stream=t,t.Readable=t,t.Writable=n(70469),t.Duplex=n(62910),t.Transform=n(70421),t.PassThrough=n(58994),t.finished=n(28640),t.pipeline=n(64218)},33715:(e,t,n)=>{var o=t;o.utils=n(26436),o.common=n(95772),o.sha=n(89041),o.ripemd=n(12949),o.hmac=n(52344),o.sha1=o.sha.sha1,o.sha256=o.sha.sha256,o.sha224=o.sha.sha224,o.sha384=o.sha.sha384,o.sha512=o.sha.sha512,o.ripemd160=o.ripemd.ripemd160},95772:(e,t,n)=>{"use strict";var o=n(26436),r=n(79746);function i(){this.pending=null,this.pendingTotal=0,this.blockSize=this.constructor.blockSize,this.outSize=this.constructor.outSize,this.hmacStrength=this.constructor.hmacStrength,this.padLength=this.constructor.padLength/8,this.endian="big",this._delta8=this.blockSize/8,this._delta32=this.blockSize/32}t.BlockHash=i,i.prototype.update=function(e,t){if(e=o.toArray(e,t),this.pending?this.pending=this.pending.concat(e):this.pending=e,this.pendingTotal+=e.length,this.pending.length>=this._delta8){var n=(e=this.pending).length%this._delta8;this.pending=e.slice(e.length-n,e.length),0===this.pending.length&&(this.pending=null),e=o.join32(e,0,e.length-n,this.endian);for(var r=0;r>>24&255,o[r++]=e>>>16&255,o[r++]=e>>>8&255,o[r++]=255&e}else for(o[r++]=255&e,o[r++]=e>>>8&255,o[r++]=e>>>16&255,o[r++]=e>>>24&255,o[r++]=0,o[r++]=0,o[r++]=0,o[r++]=0,i=8;i{"use strict";var o=n(26436),r=n(79746);function i(e,t,n){if(!(this instanceof i))return new i(e,t,n);this.Hash=e,this.blockSize=e.blockSize/8,this.outSize=e.outSize/8,this.inner=null,this.outer=null,this._init(o.toArray(t,n))}e.exports=i,i.prototype._init=function(e){e.length>this.blockSize&&(e=(new this.Hash).update(e).digest()),r(e.length<=this.blockSize);for(var t=e.length;t{"use strict";var o=n(26436),r=n(95772),i=o.rotl32,a=o.sum32,s=o.sum32_3,u=o.sum32_4,c=r.BlockHash;function l(){if(!(this instanceof l))return new l;c.call(this),this.h=[1732584193,4023233417,2562383102,271733878,3285377520],this.endian="little"}function d(e,t,n,o){return e<=15?t^n^o:e<=31?t&n|~t&o:e<=47?(t|~n)^o:e<=63?t&o|n&~o:t^(n|~o)}function h(e){return e<=15?0:e<=31?1518500249:e<=47?1859775393:e<=63?2400959708:2840853838}function p(e){return e<=15?1352829926:e<=31?1548603684:e<=47?1836072691:e<=63?2053994217:0}o.inherits(l,c),t.ripemd160=l,l.blockSize=512,l.outSize=160,l.hmacStrength=192,l.padLength=64,l.prototype._update=function(e,t){for(var n=this.h[0],o=this.h[1],r=this.h[2],c=this.h[3],l=this.h[4],F=n,y=o,b=r,v=c,w=l,E=0;E<80;E++){var k=a(i(u(n,d(E,o,r,c),e[f[E]+t],h(E)),m[E]),l);n=l,l=c,c=i(r,10),r=o,o=k,k=a(i(u(F,d(79-E,y,b,v),e[g[E]+t],p(E)),_[E]),w),F=w,w=v,v=i(b,10),b=y,y=k}k=s(this.h[1],r,v),this.h[1]=s(this.h[2],c,w),this.h[2]=s(this.h[3],l,F),this.h[3]=s(this.h[4],n,y),this.h[4]=s(this.h[0],o,b),this.h[0]=k},l.prototype._digest=function(e){return"hex"===e?o.toHex32(this.h,"little"):o.split32(this.h,"little")};var f=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,7,4,13,1,10,6,15,3,12,0,9,5,2,14,11,8,3,10,14,4,9,15,8,1,2,7,0,6,13,11,5,12,1,9,11,10,0,8,12,4,13,3,7,15,14,5,6,2,4,0,5,9,7,12,2,10,14,1,3,8,11,6,15,13],g=[5,14,7,0,9,2,11,4,13,6,15,8,1,10,3,12,6,11,3,7,0,13,5,10,14,15,8,12,4,9,1,2,15,5,1,3,7,14,6,9,11,8,12,2,10,0,4,13,8,6,4,1,3,11,15,0,5,12,2,13,9,7,10,14,12,15,10,4,1,5,8,7,6,2,13,14,0,3,9,11],m=[11,14,15,12,5,8,7,9,11,13,14,15,6,7,9,8,7,6,8,13,11,9,7,15,7,12,15,9,11,7,13,12,11,13,6,7,14,9,13,15,14,8,13,6,5,12,7,5,11,12,14,15,14,15,9,8,9,14,5,6,8,6,5,12,9,15,5,11,6,8,13,12,5,12,13,14,11,8,5,6],_=[8,9,9,11,13,15,15,5,7,7,8,11,14,14,12,6,9,13,15,7,12,8,9,11,7,7,12,7,6,15,13,11,9,7,15,11,8,6,6,14,12,13,5,14,13,13,7,5,15,5,8,11,14,14,6,14,6,9,12,9,12,5,15,8,8,5,12,9,12,5,14,6,8,13,6,5,15,13,11,11]},89041:(e,t,n)=>{"use strict";t.sha1=n(84761),t.sha224=n(10799),t.sha256=n(89344),t.sha384=n(80772),t.sha512=n(45900)},84761:(e,t,n)=>{"use strict";var o=n(26436),r=n(95772),i=n(37038),a=o.rotl32,s=o.sum32,u=o.sum32_5,c=i.ft_1,l=r.BlockHash,d=[1518500249,1859775393,2400959708,3395469782];function h(){if(!(this instanceof h))return new h;l.call(this),this.h=[1732584193,4023233417,2562383102,271733878,3285377520],this.W=new Array(80)}o.inherits(h,l),e.exports=h,h.blockSize=512,h.outSize=160,h.hmacStrength=80,h.padLength=64,h.prototype._update=function(e,t){for(var n=this.W,o=0;o<16;o++)n[o]=e[t+o];for(;o{"use strict";var o=n(26436),r=n(89344);function i(){if(!(this instanceof i))return new i;r.call(this),this.h=[3238371032,914150663,812702999,4144912697,4290775857,1750603025,1694076839,3204075428]}o.inherits(i,r),e.exports=i,i.blockSize=512,i.outSize=224,i.hmacStrength=192,i.padLength=64,i.prototype._digest=function(e){return"hex"===e?o.toHex32(this.h.slice(0,7),"big"):o.split32(this.h.slice(0,7),"big")}},89344:(e,t,n)=>{"use strict";var o=n(26436),r=n(95772),i=n(37038),a=n(79746),s=o.sum32,u=o.sum32_4,c=o.sum32_5,l=i.ch32,d=i.maj32,h=i.s0_256,p=i.s1_256,f=i.g0_256,g=i.g1_256,m=r.BlockHash,_=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298];function F(){if(!(this instanceof F))return new F;m.call(this),this.h=[1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225],this.k=_,this.W=new Array(64)}o.inherits(F,m),e.exports=F,F.blockSize=512,F.outSize=256,F.hmacStrength=192,F.padLength=64,F.prototype._update=function(e,t){for(var n=this.W,o=0;o<16;o++)n[o]=e[t+o];for(;o{"use strict";var o=n(26436),r=n(45900);function i(){if(!(this instanceof i))return new i;r.call(this),this.h=[3418070365,3238371032,1654270250,914150663,2438529370,812702999,355462360,4144912697,1731405415,4290775857,2394180231,1750603025,3675008525,1694076839,1203062813,3204075428]}o.inherits(i,r),e.exports=i,i.blockSize=1024,i.outSize=384,i.hmacStrength=192,i.padLength=128,i.prototype._digest=function(e){return"hex"===e?o.toHex32(this.h.slice(0,12),"big"):o.split32(this.h.slice(0,12),"big")}},45900:(e,t,n)=>{"use strict";var o=n(26436),r=n(95772),i=n(79746),a=o.rotr64_hi,s=o.rotr64_lo,u=o.shr64_hi,c=o.shr64_lo,l=o.sum64,d=o.sum64_hi,h=o.sum64_lo,p=o.sum64_4_hi,f=o.sum64_4_lo,g=o.sum64_5_hi,m=o.sum64_5_lo,_=r.BlockHash,F=[1116352408,3609767458,1899447441,602891725,3049323471,3964484399,3921009573,2173295548,961987163,4081628472,1508970993,3053834265,2453635748,2937671579,2870763221,3664609560,3624381080,2734883394,310598401,1164996542,607225278,1323610764,1426881987,3590304994,1925078388,4068182383,2162078206,991336113,2614888103,633803317,3248222580,3479774868,3835390401,2666613458,4022224774,944711139,264347078,2341262773,604807628,2007800933,770255983,1495990901,1249150122,1856431235,1555081692,3175218132,1996064986,2198950837,2554220882,3999719339,2821834349,766784016,2952996808,2566594879,3210313671,3203337956,3336571891,1034457026,3584528711,2466948901,113926993,3758326383,338241895,168717936,666307205,1188179964,773529912,1546045734,1294757372,1522805485,1396182291,2643833823,1695183700,2343527390,1986661051,1014477480,2177026350,1206759142,2456956037,344077627,2730485921,1290863460,2820302411,3158454273,3259730800,3505952657,3345764771,106217008,3516065817,3606008344,3600352804,1432725776,4094571909,1467031594,275423344,851169720,430227734,3100823752,506948616,1363258195,659060556,3750685593,883997877,3785050280,958139571,3318307427,1322822218,3812723403,1537002063,2003034995,1747873779,3602036899,1955562222,1575990012,2024104815,1125592928,2227730452,2716904306,2361852424,442776044,2428436474,593698344,2756734187,3733110249,3204031479,2999351573,3329325298,3815920427,3391569614,3928383900,3515267271,566280711,3940187606,3454069534,4118630271,4000239992,116418474,1914138554,174292421,2731055270,289380356,3203993006,460393269,320620315,685471733,587496836,852142971,1086792851,1017036298,365543100,1126000580,2618297676,1288033470,3409855158,1501505948,4234509866,1607167915,987167468,1816402316,1246189591];function y(){if(!(this instanceof y))return new y;_.call(this),this.h=[1779033703,4089235720,3144134277,2227873595,1013904242,4271175723,2773480762,1595750129,1359893119,2917565137,2600822924,725511199,528734635,4215389547,1541459225,327033209],this.k=F,this.W=new Array(160)}function b(e,t,n,o,r){var i=e&n^~e&r;return i<0&&(i+=4294967296),i}function v(e,t,n,o,r,i){var a=t&o^~t&i;return a<0&&(a+=4294967296),a}function w(e,t,n,o,r){var i=e&n^e&r^n&r;return i<0&&(i+=4294967296),i}function E(e,t,n,o,r,i){var a=t&o^t&i^o&i;return a<0&&(a+=4294967296),a}function k(e,t){var n=a(e,t,28)^a(t,e,2)^a(t,e,7);return n<0&&(n+=4294967296),n}function D(e,t){var n=s(e,t,28)^s(t,e,2)^s(t,e,7);return n<0&&(n+=4294967296),n}function S(e,t){var n=s(e,t,14)^s(e,t,18)^s(t,e,9);return n<0&&(n+=4294967296),n}function x(e,t){var n=a(e,t,1)^a(e,t,8)^u(e,t,7);return n<0&&(n+=4294967296),n}function C(e,t){var n=s(e,t,1)^s(e,t,8)^c(e,t,7);return n<0&&(n+=4294967296),n}function A(e,t){var n=s(e,t,19)^s(t,e,29)^c(e,t,6);return n<0&&(n+=4294967296),n}o.inherits(y,_),e.exports=y,y.blockSize=1024,y.outSize=512,y.hmacStrength=192,y.padLength=128,y.prototype._prepareBlock=function(e,t){for(var n=this.W,o=0;o<32;o++)n[o]=e[t+o];for(;o{"use strict";var o=n(26436).rotr32;function r(e,t,n){return e&t^~e&n}function i(e,t,n){return e&t^e&n^t&n}function a(e,t,n){return e^t^n}t.ft_1=function(e,t,n,o){return 0===e?r(t,n,o):1===e||3===e?a(t,n,o):2===e?i(t,n,o):void 0},t.ch32=r,t.maj32=i,t.p32=a,t.s0_256=function(e){return o(e,2)^o(e,13)^o(e,22)},t.s1_256=function(e){return o(e,6)^o(e,11)^o(e,25)},t.g0_256=function(e){return o(e,7)^o(e,18)^e>>>3},t.g1_256=function(e){return o(e,17)^o(e,19)^e>>>10}},26436:(e,t,n)=>{"use strict";var o=n(79746),r=n(35717);function i(e,t){return 55296==(64512&e.charCodeAt(t))&&!(t<0||t+1>=e.length)&&56320==(64512&e.charCodeAt(t+1))}function a(e){return(e>>>24|e>>>8&65280|e<<8&16711680|(255&e)<<24)>>>0}function s(e){return 1===e.length?"0"+e:e}function u(e){return 7===e.length?"0"+e:6===e.length?"00"+e:5===e.length?"000"+e:4===e.length?"0000"+e:3===e.length?"00000"+e:2===e.length?"000000"+e:1===e.length?"0000000"+e:e}t.inherits=r,t.toArray=function(e,t){if(Array.isArray(e))return e.slice();if(!e)return[];var n=[];if("string"==typeof e)if(t){if("hex"===t)for((e=e.replace(/[^a-z0-9]+/gi,"")).length%2!=0&&(e="0"+e),r=0;r>6|192,n[o++]=63&a|128):i(e,r)?(a=65536+((1023&a)<<10)+(1023&e.charCodeAt(++r)),n[o++]=a>>18|240,n[o++]=a>>12&63|128,n[o++]=a>>6&63|128,n[o++]=63&a|128):(n[o++]=a>>12|224,n[o++]=a>>6&63|128,n[o++]=63&a|128)}else for(r=0;r>>0}return a},t.split32=function(e,t){for(var n=new Array(4*e.length),o=0,r=0;o>>24,n[r+1]=i>>>16&255,n[r+2]=i>>>8&255,n[r+3]=255&i):(n[r+3]=i>>>24,n[r+2]=i>>>16&255,n[r+1]=i>>>8&255,n[r]=255&i)}return n},t.rotr32=function(e,t){return e>>>t|e<<32-t},t.rotl32=function(e,t){return e<>>32-t},t.sum32=function(e,t){return e+t>>>0},t.sum32_3=function(e,t,n){return e+t+n>>>0},t.sum32_4=function(e,t,n,o){return e+t+n+o>>>0},t.sum32_5=function(e,t,n,o,r){return e+t+n+o+r>>>0},t.sum64=function(e,t,n,o){var r=e[t],i=o+e[t+1]>>>0,a=(i>>0,e[t+1]=i},t.sum64_hi=function(e,t,n,o){return(t+o>>>0>>0},t.sum64_lo=function(e,t,n,o){return t+o>>>0},t.sum64_4_hi=function(e,t,n,o,r,i,a,s){var u=0,c=t;return u+=(c=c+o>>>0)>>0)>>0)>>0},t.sum64_4_lo=function(e,t,n,o,r,i,a,s){return t+o+i+s>>>0},t.sum64_5_hi=function(e,t,n,o,r,i,a,s,u,c){var l=0,d=t;return l+=(d=d+o>>>0)>>0)>>0)>>0)>>0},t.sum64_5_lo=function(e,t,n,o,r,i,a,s,u,c){return t+o+i+s+c>>>0},t.rotr64_hi=function(e,t,n){return(t<<32-n|e>>>n)>>>0},t.rotr64_lo=function(e,t,n){return(e<<32-n|t>>>n)>>>0},t.shr64_hi=function(e,t,n){return e>>>n},t.shr64_lo=function(e,t,n){return(e<<32-n|t>>>n)>>>0}},78892:e=>{"use strict";e.exports=function(e,n){for(var o,r,i,a=e||"",s=n||"div",u={},c=0;c{"use strict";var o=n(99560),r=n(66632),i=n(78892),a=n(36582).parse,s=n(56851).parse;e.exports=function(e,t,n){var r=n?function(e){for(var t,n=e.length,o=-1,r={};++o{"use strict";var o=n(97247),r=n(62686)(o,"div");r.displayName="html",e.exports=r},31742:(e,t,n)=>{"use strict";e.exports=n(52579)},2156:(e,t,n)=>{"use strict";var o=n(33715),r=n(34504),i=n(79746);function a(e){if(!(this instanceof a))return new a(e);this.hash=e.hash,this.predResist=!!e.predResist,this.outLen=this.hash.outSize,this.minEntropy=e.minEntropy||this.hash.hmacStrength,this._reseed=null,this.reseedInterval=null,this.K=null,this.V=null;var t=r.toArray(e.entropy,e.entropyEnc||"hex"),n=r.toArray(e.nonce,e.nonceEnc||"hex"),o=r.toArray(e.pers,e.persEnc||"hex");i(t.length>=this.minEntropy/8,"Not enough entropy. Minimum is: "+this.minEntropy+" bits"),this._init(t,n,o)}e.exports=a,a.prototype._init=function(e,t,n){var o=e.concat(t).concat(n);this.K=new Array(this.outLen/8),this.V=new Array(this.outLen/8);for(var r=0;r=this.minEntropy/8,"Not enough entropy. Minimum is: "+this.minEntropy+" bits"),this._update(e.concat(n||[])),this._reseed=1},a.prototype.generate=function(e,t,n,o){if(this._reseed>this.reseedInterval)throw new Error("Reseed is required");"string"!=typeof t&&(o=n,n=t,t=null),n&&(n=r.toArray(n,o||"hex"),this._update(n));for(var i=[];i.length{"use strict";var o=n(59864),r={childContextTypes:!0,contextType:!0,contextTypes:!0,defaultProps:!0,displayName:!0,getDefaultProps:!0,getDerivedStateFromError:!0,getDerivedStateFromProps:!0,mixins:!0,propTypes:!0,type:!0},i={name:!0,length:!0,prototype:!0,caller:!0,callee:!0,arguments:!0,arity:!0},a={$$typeof:!0,compare:!0,defaultProps:!0,displayName:!0,propTypes:!0,type:!0},s={};function u(e){return o.isMemo(e)?a:s[e.$$typeof]||r}s[o.ForwardRef]={$$typeof:!0,render:!0,defaultProps:!0,displayName:!0,propTypes:!0},s[o.Memo]=a;var c=Object.defineProperty,l=Object.getOwnPropertyNames,d=Object.getOwnPropertySymbols,h=Object.getOwnPropertyDescriptor,p=Object.getPrototypeOf,f=Object.prototype;e.exports=function e(t,n,o){if("string"!=typeof n){if(f){var r=p(n);r&&r!==f&&e(t,r,o)}var a=l(n);d&&(a=a.concat(d(n)));for(var s=u(t),g=u(n),m=0;m{e.exports={CASE_SENSITIVE_TAG_NAMES:["animateMotion","animateTransform","clipPath","feBlend","feColorMatrix","feComponentTransfer","feComposite","feConvolveMatrix","feDiffuseLighting","feDisplacementMap","feDropShadow","feFlood","feFuncA","feFuncB","feFuncG","feFuncR","feGaussainBlur","feImage","feMerge","feMergeNode","feMorphology","feOffset","fePointLight","feSpecularLighting","feSpotLight","feTile","feTurbulence","foreignObject","linearGradient","radialGradient","textPath"]}},38276:(e,t,n)=>{var o="html",r="head",i="body",a=/<([a-zA-Z]+[0-9]?)/,s=//i,u=//i,c=function(){throw new Error("This browser does not support `document.implementation.createHTMLDocument`")},l=function(){throw new Error("This browser does not support `DOMParser.prototype.parseFromString`")};if("function"==typeof window.DOMParser){var d=new window.DOMParser;c=l=function(e,t){return t&&(e="<"+t+">"+e+""),d.parseFromString(e,"text/html")}}if(document.implementation){var h=n(1507).isIE,p=document.implementation.createHTMLDocument(h()?"html-dom-parser":void 0);c=function(e,t){return t?(p.documentElement.getElementsByTagName(t)[0].innerHTML=e,p):(p.documentElement.innerHTML=e,p)}}var f,g=document.createElement("template");g.content&&(f=function(e){return g.innerHTML=e,g.content.childNodes}),e.exports=function(e){var t,n,d,h,p=e.match(a);switch(p&&p[1]&&(t=p[1].toLowerCase()),t){case o:return n=l(e),s.test(e)||(d=n.getElementsByTagName(r)[0])&&d.parentNode.removeChild(d),u.test(e)||(d=n.getElementsByTagName(i)[0])&&d.parentNode.removeChild(d),n.getElementsByTagName(o);case r:case i:return h=c(e).getElementsByTagName(t),u.test(e)&&s.test(e)?h[0].parentNode.childNodes:h;default:return f?f(e):c(e,i).getElementsByTagName(i)[0].childNodes}}},14152:(e,t,n)=>{var o=n(38276),r=n(1507).formatDOM,i=/<(![a-zA-Z\s]+)>/;e.exports=function(e){if("string"!=typeof e)throw new TypeError("First argument must be a string");if(""===e)return[];var t,n=e.match(i);return n&&n[1]&&(t=n[1]),r(o(e),null,t)}},1507:(e,t,n)=>{for(var o,r=n(60885),i=n(21642),a=r.CASE_SENSITIVE_TAG_NAMES,s=i.Comment,u=i.Element,c=i.ProcessingInstruction,l=i.Text,d={},h=0,p=a.length;h{"use strict";var n;Object.defineProperty(t,"__esModule",{value:!0}),t.Doctype=t.CDATA=t.Tag=t.Style=t.Script=t.Comment=t.Directive=t.Text=t.Root=t.isTag=t.ElementType=void 0,function(e){e.Root="root",e.Text="text",e.Directive="directive",e.Comment="comment",e.Script="script",e.Style="style",e.Tag="tag",e.CDATA="cdata",e.Doctype="doctype"}(n=t.ElementType||(t.ElementType={})),t.isTag=function(e){return e.type===n.Tag||e.type===n.Script||e.type===n.Style},t.Root=n.Root,t.Text=n.Text,t.Directive=n.Directive,t.Comment=n.Comment,t.Script=n.Script,t.Style=n.Style,t.Tag=n.Tag,t.CDATA=n.CDATA,t.Doctype=n.Doctype},21642:function(e,t,n){"use strict";var o,r=this&&this.__extends||(o=function(e,t){return(o=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])})(e,t)},function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");function n(){this.constructor=e}o(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}),i=this&&this.__assign||function(){return(i=Object.assign||function(e){for(var t,n=1,o=arguments.length;n0?this.children[this.children.length-1]:null},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"childNodes",{get:function(){return this.children},set:function(e){this.children=e},enumerable:!1,configurable:!0}),t}(u);t.NodeWithChildren=p;var f=function(e){function t(t){return e.call(this,a.ElementType.Root,t)||this}return r(t,e),t}(p);t.Document=f;var g=function(e){function t(t,n,o,r){void 0===o&&(o=[]),void 0===r&&(r="script"===t?a.ElementType.Script:"style"===t?a.ElementType.Style:a.ElementType.Tag);var i=e.call(this,r,o)||this;return i.name=t,i.attribs=n,i}return r(t,e),Object.defineProperty(t.prototype,"tagName",{get:function(){return this.name},set:function(e){this.name=e},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"attributes",{get:function(){var e=this;return Object.keys(this.attribs).map((function(t){var n,o;return{name:t,value:e.attribs[t],namespace:null===(n=e["x-attribsNamespace"])||void 0===n?void 0:n[t],prefix:null===(o=e["x-attribsPrefix"])||void 0===o?void 0:o[t]}}))},enumerable:!1,configurable:!0}),t}(p);function m(e){return a.isTag(e)}function _(e){return e.type===a.ElementType.CDATA}function F(e){return e.type===a.ElementType.Text}function y(e){return e.type===a.ElementType.Comment}function b(e){return e.type===a.ElementType.Directive}function v(e){return e.type===a.ElementType.Root}function w(e,t){var n;if(void 0===t&&(t=!1),F(e))n=new l(e.data);else if(y(e))n=new d(e.data);else if(m(e)){var o=t?E(e.children):[],r=new g(e.name,i({},e.attribs),o);o.forEach((function(e){return e.parent=r})),e["x-attribsNamespace"]&&(r["x-attribsNamespace"]=i({},e["x-attribsNamespace"])),e["x-attribsPrefix"]&&(r["x-attribsPrefix"]=i({},e["x-attribsPrefix"])),n=r}else if(_(e)){o=t?E(e.children):[];var s=new p(a.ElementType.CDATA,o);o.forEach((function(e){return e.parent=s})),n=s}else if(v(e)){o=t?E(e.children):[];var u=new f(o);o.forEach((function(e){return e.parent=u})),e["x-mode"]&&(u["x-mode"]=e["x-mode"]),n=u}else{if(!b(e))throw new Error("Not implemented yet: "+e.type);var c=new h(e.name,e.data);null!=e["x-name"]&&(c["x-name"]=e["x-name"],c["x-publicId"]=e["x-publicId"],c["x-systemId"]=e["x-systemId"]),n=c}return n.startIndex=e.startIndex,n.endIndex=e.endIndex,n}function E(e){for(var t=e.map((function(e){return w(e,!0)})),n=1;n{var o=n(53670),r=n(50484),i=n(14152),a={lowerCaseAttributeNames:!1};function s(e,t){if("string"!=typeof e)throw new TypeError("First argument must be a string");return""===e?[]:o(i(e,(t=t||{}).htmlparser2||a),t)}s.domToReact=o,s.htmlToDOM=i,s.attributesToProps=r,e.exports=s,e.exports.default=s},50484:(e,t,n)=>{var o=n(32686),r=n(74606),i=r.setStyleProp,a=o.html,s=o.svg,u=o.isCustomAttribute,c=Object.prototype.hasOwnProperty;e.exports=function(e){var t,n,o,l;e=e||{};var d={};for(t in e)o=e[t],u(t)?d[t]=o:(n=t.toLowerCase(),c.call(a,n)?d[(l=a[n]).propertyName]=!!(l.hasBooleanValue||l.hasOverloadedBooleanValue&&!o)||o:c.call(s,t)?d[(l=s[t]).propertyName]=o:r.PRESERVE_CUSTOM_ATTRIBUTES&&(d[t]=o));return i(e.style,d),d}},53670:(e,t,n)=>{var o=n(67294),r=n(50484),i=n(74606),a=i.setStyleProp;function s(e){return i.PRESERVE_CUSTOM_ATTRIBUTES&&"tag"===e.type&&i.isCustomComponent(e.name,e.attribs)}e.exports=function e(t,n){for(var i,u,c,l,d=(n=n||{}).library||o,h=d.cloneElement,p=d.createElement,f=d.isValidElement,g=[],m="function"==typeof n.replace,_=n.trim,F=0,y=t.length;F1&&(u=h(u,{key:u.key||F})),g.push(u);else if("text"!==i.type){switch(c=i.attribs,s(i)?a(c.style,c):c&&(c=r(c)),l=null,i.type){case"script":case"style":i.children[0]&&(c.dangerouslySetInnerHTML={__html:i.children[0].data});break;case"tag":"textarea"===i.name&&i.children[0]?c.defaultValue=i.children[0].data:i.children&&i.children.length&&(l=e(i.children,n));break;default:continue}y>1&&(c.key=F),g.push(p(i.name,c,l))}else _?i.data.trim()&&g.push(i.data):g.push(i.data);return 1===g.length?g[0]:g}},74606:(e,t,n)=>{var o=n(67294),r=n(41476).default,i={reactCompat:!0},a=o.version.split(".")[0]>=16;e.exports={PRESERVE_CUSTOM_ATTRIBUTES:a,invertObject:function(e,t){if(!e||"object"!=typeof e)throw new TypeError("First argument must be an object");var n,o,r="function"==typeof t,i={},a={};for(n in e)o=e[n],r&&(i=t(n,o))&&2===i.length?a[i[0]]=i[1]:"string"==typeof o&&(a[o]=n);return a},isCustomComponent:function(e,t){if(-1===e.indexOf("-"))return t&&"string"==typeof t.is;switch(e){case"annotation-xml":case"color-profile":case"font-face":case"font-face-src":case"font-face-uri":case"font-face-format":case"font-face-name":case"missing-glyph":return!1;default:return!0}},setStyleProp:function(e,t){null!=e&&(t.style=r(e,i))}}},89043:function(e,t,n){var o,r;!function(i,a,s){"use strict";void 0===(r="function"==typeof(o=function(){var e=function(e){throw e},t=function(){},n={storeName:"Store",storePrefix:"IDBWrapper-",dbVersion:1,keyPath:"id",autoIncrement:!0,onStoreReady:function(){},onError:e,indexes:[],implementationPreference:["indexedDB","webkitIndexedDB","mozIndexedDB","shimIndexedDB"]},o=function(e,t){for(var o in void 0===t&&"function"==typeof e&&(t=e),"[object Object]"!=Object.prototype.toString.call(e)&&(e={}),n)this[o]=void 0!==e[o]?e[o]:n[o];this.dbName=this.storePrefix+this.storeName,this.dbVersion=parseInt(this.dbVersion,10)||1,t&&(this.onStoreReady=t);var r="object"==typeof window?window:self,i=this.implementationPreference.filter((function(e){return e in r}));this.implementation=i[0],this.idb=r[this.implementation],this.keyRange=r.IDBKeyRange||r.webkitIDBKeyRange||r.mozIDBKeyRange,this.consts={READ_ONLY:"readonly",READ_WRITE:"readwrite",VERSION_CHANGE:"versionchange",NEXT:"next",NEXT_NO_DUPLICATE:"nextunique",PREV:"prev",PREV_NO_DUPLICATE:"prevunique"},this.openDB()},r={constructor:o,version:"1.7.2",db:null,dbName:null,dbVersion:null,store:null,storeName:null,storePrefix:null,keyPath:null,autoIncrement:null,indexes:null,implementationPreference:null,implementation:"",onStoreReady:null,onError:null,_insertIdCount:0,openDB:function(){var e=this.idb.open(this.dbName,this.dbVersion),t=!1;e.onerror=function(e){if(function(e){return"error"in e.target?"VersionError"==e.target.error.name:"errorCode"in e.target&&12==e.target.errorCode}(e))this.onError(new Error("The version number provided is lower than the existing one."));else{var t;if(e.target.error)t=e.target.error;else{var n="IndexedDB unknown error occurred when opening DB "+this.dbName+" version "+this.dbVersion;"errorCode"in e.target&&(n+=" with error code "+e.target.errorCode),t=new Error(n)}this.onError(t)}}.bind(this),e.onsuccess=function(e){if(!t)if(this.db)this.onStoreReady();else if(this.db=e.target.result,"string"!=typeof this.db.version)if(this.db.objectStoreNames.contains(this.storeName)){var n=this.db.transaction([this.storeName],this.consts.READ_ONLY);this.store=n.objectStore(this.storeName);var o=Array.prototype.slice.call(this.getIndexList());this.indexes.forEach((function(e){var n=e.name;if(!n)return t=!0,void this.onError(new Error("Cannot create index: No index name given."));if(this.normalizeIndexData(e),this.hasIndex(n)){var r=this.store.index(n);this.indexComplies(r,e)||(t=!0,this.onError(new Error('Cannot modify index "'+n+'" for current version. Please bump version number to '+(this.dbVersion+1)+"."))),o.splice(o.indexOf(n),1)}else t=!0,this.onError(new Error('Cannot create new index "'+n+'" for current version. Please bump version number to '+(this.dbVersion+1)+"."))}),this),o.length&&(t=!0,this.onError(new Error('Cannot delete index(es) "'+o.toString()+'" for current version. Please bump version number to '+(this.dbVersion+1)+"."))),t||this.onStoreReady()}else this.onError(new Error("Object store couldn't be created."));else this.onError(new Error("The IndexedDB implementation in this browser is outdated. Please upgrade your browser."))}.bind(this),e.onupgradeneeded=function(e){if(this.db=e.target.result,this.db.objectStoreNames.contains(this.storeName))this.store=e.target.transaction.objectStore(this.storeName);else{var n={autoIncrement:this.autoIncrement};null!==this.keyPath&&(n.keyPath=this.keyPath),this.store=this.db.createObjectStore(this.storeName,n)}var o=Array.prototype.slice.call(this.getIndexList());this.indexes.forEach((function(e){var n=e.name;if(n||(t=!0,this.onError(new Error("Cannot create index: No index name given."))),this.normalizeIndexData(e),this.hasIndex(n)){var r=this.store.index(n);this.indexComplies(r,e)||(this.store.deleteIndex(n),this.store.createIndex(n,e.keyPath,{unique:e.unique,multiEntry:e.multiEntry})),o.splice(o.indexOf(n),1)}else this.store.createIndex(n,e.keyPath,{unique:e.unique,multiEntry:e.multiEntry})}),this),o.length&&o.forEach((function(e){this.store.deleteIndex(e)}),this)}.bind(this)},deleteDatabase:function(e,t){if(this.idb.deleteDatabase){this.db.close();var n=this.idb.deleteDatabase(this.dbName);n.onsuccess=e,n.onerror=t}else t(new Error("Browser does not support IndexedDB deleteDatabase!"))},put:function(n,o,r,i){null!==this.keyPath&&(i=r,r=o,o=n),i||(i=e),r||(r=t);var a,s=!1,u=null,c=this.db.transaction([this.storeName],this.consts.READ_WRITE);return c.oncomplete=function(){(s?r:i)(u)},c.onabort=i,c.onerror=i,null!==this.keyPath?(this._addIdPropertyIfNeeded(o),a=c.objectStore(this.storeName).put(o)):a=c.objectStore(this.storeName).put(o,n),a.onsuccess=function(e){s=!0,u=e.target.result},a.onerror=i,c},get:function(n,o,r){r||(r=e),o||(o=t);var i=!1,a=null,s=this.db.transaction([this.storeName],this.consts.READ_ONLY);s.oncomplete=function(){(i?o:r)(a)},s.onabort=r,s.onerror=r;var u=s.objectStore(this.storeName).get(n);return u.onsuccess=function(e){i=!0,a=e.target.result},u.onerror=r,s},remove:function(n,o,r){r||(r=e),o||(o=t);var i=!1,a=null,s=this.db.transaction([this.storeName],this.consts.READ_WRITE);s.oncomplete=function(){(i?o:r)(a)},s.onabort=r,s.onerror=r;var u=s.objectStore(this.storeName).delete(n);return u.onsuccess=function(e){i=!0,a=e.target.result},u.onerror=r,s},batch:function(n,o,r){if(r||(r=e),o||(o=t),"[object Array]"!=Object.prototype.toString.call(n))r(new Error("dataArray argument must be of type Array."));else if(0===n.length)return o(!0);var i=n.length,a=!1,s=!1,u=this.db.transaction([this.storeName],this.consts.READ_WRITE);u.oncomplete=function(){(s?o:r)(s)},u.onabort=r,u.onerror=r;var c=function(){0!=--i||a||(a=!0,s=!0)};return n.forEach((function(e){var t=e.type,n=e.key,o=e.value,i=function(e){u.abort(),a||(a=!0,r(e,t,n))};if("remove"==t){var s=u.objectStore(this.storeName).delete(n);s.onsuccess=c,s.onerror=i}else if("put"==t){var l;null!==this.keyPath?(this._addIdPropertyIfNeeded(o),l=u.objectStore(this.storeName).put(o)):l=u.objectStore(this.storeName).put(o,n),l.onsuccess=c,l.onerror=i}}),this),u},putBatch:function(e,t,n){var o=e.map((function(e){return{type:"put",value:e}}));return this.batch(o,t,n)},upsertBatch:function(n,o,r,i){"function"==typeof o&&(i=r=o,o={}),i||(i=e),r||(r=t),o||(o={}),"[object Array]"!=Object.prototype.toString.call(n)&&i(new Error("dataArray argument must be of type Array."));var a=o.keyField||this.keyPath,s=n.length,u=!1,c=!1,l=0,d=this.db.transaction([this.storeName],this.consts.READ_WRITE);d.oncomplete=function(){c?r(n):i(!1)},d.onabort=i,d.onerror=i;var h=function(e){n[l++][a]=e.target.result,0!=--s||u||(u=!0,c=!0)};return n.forEach((function(e){var t,n=e.key;null!==this.keyPath?(this._addIdPropertyIfNeeded(e),t=d.objectStore(this.storeName).put(e)):t=d.objectStore(this.storeName).put(e,n),t.onsuccess=h,t.onerror=function(e){d.abort(),u||(u=!0,i(e))}}),this),d},removeBatch:function(e,t,n){var o=e.map((function(e){return{type:"remove",key:e}}));return this.batch(o,t,n)},getBatch:function(n,o,r,i){if(r||(r=e),o||(o=t),i||(i="sparse"),"[object Array]"!=Object.prototype.toString.call(n))r(new Error("keyArray argument must be of type Array."));else if(0===n.length)return o([]);var a=[],s=n.length,u=!1,c=null,l=this.db.transaction([this.storeName],this.consts.READ_ONLY);l.oncomplete=function(){(u?o:r)(c)},l.onabort=r,l.onerror=r;var d=function(e){e.target.result||"dense"==i?a.push(e.target.result):"sparse"==i&&a.length++,0==--s&&(u=!0,c=a)};return n.forEach((function(e){var t=l.objectStore(this.storeName).get(e);t.onsuccess=d,t.onerror=function(e){c=e,r(e),l.abort()}}),this),l},getAll:function(n,o){o||(o=e),n||(n=t);var r=this.db.transaction([this.storeName],this.consts.READ_ONLY),i=r.objectStore(this.storeName);return i.getAll?this._getAllNative(r,i,n,o):this._getAllCursor(r,i,n,o),r},_getAllNative:function(e,t,n,o){var r=!1,i=null;e.oncomplete=function(){(r?n:o)(i)},e.onabort=o,e.onerror=o;var a=t.getAll();a.onsuccess=function(e){r=!0,i=e.target.result},a.onerror=o},_getAllCursor:function(e,t,n,o){var r=[],i=!1,a=null;e.oncomplete=function(){(i?n:o)(a)},e.onabort=o,e.onerror=o;var s=t.openCursor();s.onsuccess=function(e){var t=e.target.result;t?(r.push(t.value),t.continue()):(i=!0,a=r)},s.onError=o},clear:function(n,o){o||(o=e),n||(n=t);var r=!1,i=null,a=this.db.transaction([this.storeName],this.consts.READ_WRITE);a.oncomplete=function(){(r?n:o)(i)},a.onabort=o,a.onerror=o;var s=a.objectStore(this.storeName).clear();return s.onsuccess=function(e){r=!0,i=e.target.result},s.onerror=o,a},_addIdPropertyIfNeeded:function(e){void 0===e[this.keyPath]&&(e[this.keyPath]=this._insertIdCount+++Date.now())},getIndexList:function(){return this.store.indexNames},hasIndex:function(e){return this.store.indexNames.contains(e)},normalizeIndexData:function(e){e.keyPath=e.keyPath||e.name,e.unique=!!e.unique,e.multiEntry=!!e.multiEntry},indexComplies:function(e,t){return["keyPath","unique","multiEntry"].every((function(n){if("multiEntry"==n&&void 0===e[n]&&!1===t[n])return!0;if("keyPath"==n&&"[object Array]"==Object.prototype.toString.call(t[n])){var o=t.keyPath,r=e.keyPath;if("string"==typeof r)return o.toString()==r;if("function"!=typeof r.contains&&"function"!=typeof r.indexOf)return!1;if(r.length!==o.length)return!1;for(var i=0,a=o.length;i{t.read=function(e,t,n,o,r){var i,a,s=8*r-o-1,u=(1<>1,l=-7,d=n?r-1:0,h=n?-1:1,p=e[t+d];for(d+=h,i=p&(1<<-l)-1,p>>=-l,l+=s;l>0;i=256*i+e[t+d],d+=h,l-=8);for(a=i&(1<<-l)-1,i>>=-l,l+=o;l>0;a=256*a+e[t+d],d+=h,l-=8);if(0===i)i=1-c;else{if(i===u)return a?NaN:1/0*(p?-1:1);a+=Math.pow(2,o),i-=c}return(p?-1:1)*a*Math.pow(2,i-o)},t.write=function(e,t,n,o,r,i){var a,s,u,c=8*i-r-1,l=(1<>1,h=23===r?Math.pow(2,-24)-Math.pow(2,-77):0,p=o?0:i-1,f=o?1:-1,g=t<0||0===t&&1/t<0?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(s=isNaN(t)?1:0,a=l):(a=Math.floor(Math.log(t)/Math.LN2),t*(u=Math.pow(2,-a))<1&&(a--,u*=2),(t+=a+d>=1?h/u:h*Math.pow(2,1-d))*u>=2&&(a++,u/=2),a+d>=l?(s=0,a=l):a+d>=1?(s=(t*u-1)*Math.pow(2,r),a+=d):(s=t*Math.pow(2,d-1)*Math.pow(2,r),a=0));r>=8;e[n+p]=255&s,p+=f,s/=256,r-=8);for(a=a<0;e[n+p]=255&a,p+=f,a/=256,c-=8);e[n+p-f]|=128*g}},35717:e=>{"function"==typeof Object.create?e.exports=function(e,t){t&&(e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}))}:e.exports=function(e,t){if(t){e.super_=t;var n=function(){};n.prototype=t.prototype,e.prototype=new n,e.prototype.constructor=e}}},18139:e=>{var t=/\/\*[^*]*\*+([^/*][^*]*\*+)*\//g,n=/\n/g,o=/^\s*/,r=/^(\*?[-#/*\\\w]+(\[[0-9a-z_-]+\])?)\s*/,i=/^:\s*/,a=/^((?:'(?:\\'|.)*?'|"(?:\\"|.)*?"|\([^)]*?\)|[^};])+)/,s=/^[;\s]*/,u=/^\s+|\s+$/g,c="";function l(e){return e?e.replace(u,c):c}e.exports=function(e,u){if("string"!=typeof e)throw new TypeError("First argument must be a string");if(!e)return[];u=u||{};var d=1,h=1;function p(e){var t=e.match(n);t&&(d+=t.length);var o=e.lastIndexOf("\n");h=~o?e.length-o:h+e.length}function f(){var e={line:d,column:h};return function(t){return t.position=new g(e),y(),t}}function g(e){this.start=e,this.end={line:d,column:h},this.source=u.source}g.prototype.content=e;var m=[];function _(t){var n=new Error(u.source+":"+d+":"+h+": "+t);if(n.reason=t,n.filename=u.source,n.line=d,n.column=h,n.source=e,!u.silent)throw n;m.push(n)}function F(t){var n=t.exec(e);if(n){var o=n[0];return p(o),e=e.slice(o.length),n}}function y(){F(o)}function b(e){var t;for(e=e||[];t=v();)!1!==t&&e.push(t);return e}function v(){var t=f();if("/"==e.charAt(0)&&"*"==e.charAt(1)){for(var n=2;c!=e.charAt(n)&&("*"!=e.charAt(n)||"/"!=e.charAt(n+1));)++n;if(n+=2,c===e.charAt(n-1))return _("End of comment missing");var o=e.slice(2,n-2);return h+=2,p(o),e=e.slice(n),h+=2,t({type:"comment",comment:o})}}function w(){var e=f(),n=F(r);if(n){if(v(),!F(i))return _("property missing ':'");var o=F(a),u=e({type:"declaration",property:l(n[0].replace(t,c)),value:o?l(o[0].replace(t,c)):c});return F(s),u}}return y(),function(){var e,t=[];for(b(t);e=w();)!1!==e&&(t.push(e),b(t));return t}()}},46260:e=>{"use strict";e.exports=function(e){var t="string"==typeof e?e.charCodeAt(0):e;return t>=97&&t<=122||t>=65&&t<=90}},7961:(e,t,n)=>{"use strict";var o=n(46260),r=n(46195);e.exports=function(e){return o(e)||r(e)}},82584:(e,t,n)=>{"use strict";var o="function"==typeof Symbol&&"symbol"==typeof Symbol.toStringTag,r=n(21924)("Object.prototype.toString"),i=function(e){return!(o&&e&&"object"==typeof e&&Symbol.toStringTag in e)&&"[object Arguments]"===r(e)},a=function(e){return!!i(e)||null!==e&&"object"==typeof e&&"number"==typeof e.length&&e.length>=0&&"[object Array]"!==r(e)&&"[object Function]"===r(e.callee)},s=function(){return i(arguments)}();i.isLegacyArguments=a,e.exports=s?i:a},46195:e=>{"use strict";e.exports=function(e){var t="string"==typeof e?e.charCodeAt(0):e;return t>=48&&t<=57}},48662:e=>{"use strict";var t=Object.prototype.toString,n=Function.prototype.toString,o=/^\s*(?:function)?\*/,r="function"==typeof Symbol&&"symbol"==typeof Symbol.toStringTag,i=Object.getPrototypeOf,a=function(){if(!r)return!1;try{return Function("return function*() {}")()}catch(e){}}(),s=!(!i||!a)&&i(a);e.exports=function(e){return"function"==typeof e&&(!!o.test(n.call(e))||(r?i&&i(e)===s:"[object GeneratorFunction]"===t.call(e)))}},79480:e=>{"use strict";e.exports=function(e){var t="string"==typeof e?e.charCodeAt(0):e;return t>=97&&t<=102||t>=65&&t<=70||t>=48&&t<=57}},33310:e=>{"use strict";e.exports=e=>{if("[object Object]"!==Object.prototype.toString.call(e))return!1;const t=Object.getPrototypeOf(e);return null===t||t===Object.prototype}},85692:(e,t,n)=>{"use strict";var o=n(49804),r=n(16314),i=n(21924),a=i("Object.prototype.toString"),s=n(41405)()&&"symbol"==typeof Symbol.toStringTag,u=r(),c=i("Array.prototype.indexOf",!0)||function(e,t){for(var n=0;n-1}return!!h&&function(e){var t=!1;return o(d,(function(n,o){if(!t)try{t=n.call(e)===o}catch(e){}})),t}(e)}},65452:e=>{var t=Object.prototype,n=t.hasOwnProperty,o=t.toString,r=function(e){return e!=e},i={boolean:1,number:1,string:1,undefined:1},a=e.exports={};a.a=a.type=function(e,t){return typeof e===t},a.defined=function(e){return void 0!==e},a.empty=function(e){var t,r=o.call(e);if("[object Array]"===r||"[object Arguments]"===r)return 0===e.length;if("[object Object]"===r){for(t in e)if(n.call(e,t))return!1;return!0}return"[object String]"===r&&""===e},a.equal=function(e,t){var n,r=o.call(e);if(r!==o.call(t))return!1;if("[object Object]"===r){for(n in e)if(!a.equal(e[n],t[n]))return!1;return!0}if("[object Array]"===r){if((n=e.length)!==t.length)return!1;for(;--n;)if(!a.equal(e[n],t[n]))return!1;return!0}return"[object Function]"===r?e.prototype===t.prototype:"[object Date]"===r?e.getTime()===t.getTime():e===t},a.hosted=function(e,t){var n=typeof t[e];return"object"===n?!!t[e]:!i[n]},a.instance=a.instanceof=function(e,t){return e instanceof t},a.null=function(e){return null===e},a.undefined=function(e){return void 0===e},a.arguments=function(e){var t="[object Arguments]"===o.call(e),n=!a.array(e)&&a.arraylike(e)&&a.object(e)&&a.fn(e.callee);return t||n},a.array=function(e){return"[object Array]"===o.call(e)},a.arguments.empty=function(e){return a.arguments(e)&&0===e.length},a.array.empty=function(e){return a.array(e)&&0===e.length},a.arraylike=function(e){return!!e&&!a.boolean(e)&&n.call(e,"length")&&isFinite(e.length)&&a.number(e.length)&&e.length>=0},a.boolean=function(e){return"[object Boolean]"===o.call(e)},a.false=function(e){return a.boolean(e)&&(!1===e||!1===e.valueOf())},a.true=function(e){return a.boolean(e)&&(!0===e||!0===e.valueOf())},a.date=function(e){return"[object Date]"===o.call(e)},a.element=function(e){return void 0!==e&&"undefined"!=typeof HTMLElement&&e instanceof HTMLElement&&1===e.nodeType},a.error=function(e){return"[object Error]"===o.call(e)},a.fn=a.function=function(e){return"undefined"!=typeof window&&e===window.alert||"[object Function]"===o.call(e)},a.number=function(e){return"[object Number]"===o.call(e)},a.infinite=function(e){return e===1/0||e===-1/0},a.decimal=function(e){return a.number(e)&&!r(e)&&!a.infinite(e)&&e%1!=0},a.divisibleBy=function(e,t){var n=a.infinite(e),o=a.infinite(t),i=a.number(e)&&!r(e)&&a.number(t)&&!r(t)&&0!==t;return n||o||i&&e%t==0},a.int=function(e){return a.number(e)&&!r(e)&&e%1==0},a.maximum=function(e,t){if(r(e))throw new TypeError("NaN is not a valid value");if(!a.arraylike(t))throw new TypeError("second argument must be array-like");for(var n=t.length;--n>=0;)if(e=0;)if(e>t[n])return!1;return!0},a.nan=function(e){return!a.number(e)||e!=e},a.even=function(e){return a.infinite(e)||a.number(e)&&e==e&&e%2==0},a.odd=function(e){return a.infinite(e)||a.number(e)&&e==e&&e%2!=0},a.ge=function(e,t){if(r(e)||r(t))throw new TypeError("NaN is not a valid value");return!a.infinite(e)&&!a.infinite(t)&&e>=t},a.gt=function(e,t){if(r(e)||r(t))throw new TypeError("NaN is not a valid value");return!a.infinite(e)&&!a.infinite(t)&&e>t},a.le=function(e,t){if(r(e)||r(t))throw new TypeError("NaN is not a valid value");return!a.infinite(e)&&!a.infinite(t)&&e<=t},a.lt=function(e,t){if(r(e)||r(t))throw new TypeError("NaN is not a valid value");return!a.infinite(e)&&!a.infinite(t)&&e=t&&e<=n},a.object=function(e){return e&&"[object Object]"===o.call(e)},a.hash=function(e){return a.object(e)&&e.constructor===Object&&!e.nodeType&&!e.setInterval},a.regexp=function(e){return"[object RegExp]"===o.call(e)},a.string=function(e){return"[object String]"===o.call(e)}},5826:e=>{var t={}.toString;e.exports=Array.isArray||function(e){return"[object Array]"==t.call(e)}},35086:(e,t,n)=>{var o=n(48764).Buffer;e.exports=function(e){return o.isBuffer(e)||/\[object (.+Array|Array.+)\]/.test(Object.prototype.toString.call(e))}},69334:(e,t,n)=>{var o=n(57785),r=n(2638),i=n(51753),a=n(89539),s=n(30778),u=new Buffer(0),c={encode:function(e){return"string"==typeof e?e=new Buffer(e):e},decode:function(e){return Buffer.isBuffer(e)?e:new Buffer(e)},buffer:!0,type:"raw"},l=function(){},d=function(e){return e=e.toString(16),"00000000".slice(0,-e.length)+e};e.exports=function(e,t){t||(t={});var n={},h=t.blockSize||65536,p=t.batch||100,f=new Buffer(h);e.put("\0","ignore",l);var g={},m=function(e,t){if(!(this instanceof m))return new m(e,t);t||(t={}),this.name=e,this.blocks=[],this.batch=[],this.bytesWritten=0,this.truncate=!t.append,this.append=t.append,this._shouldInitAppend=this.append&&void 0===t.start,this._destroyed=!1,this._init(t.start||0),o.call(this)};a.inherits(m,o),m.prototype._init=function(e){this.blockIndex=e/h|0,this.blockOffset=e-this.blockIndex*h,this.blockLength=this.blockOffset},m.prototype._flush=function(t){if(!this.batch.length)return t();var n=this.batch[this.batch.length-1].key,o=this.batch;if(this.batch=[],!this.truncate)return e.batch(o,t);this.truncate=!1,this._truncate(o,n,t)},m.prototype._truncate=function(t,n,o){o=s(o);var r=[],i=e.createKeyStream({start:n,end:this.name+"ÿÿ"});i.on("error",o),i.on("data",(function(e){r.push({type:"del",key:e})})),i.on("end",(function(){r.push.apply(r,t),e.batch(r,o)}))},m.prototype._writeBlock=function(t){var n=1===this.blocks.length?this.blocks[0]:Buffer.concat(this.blocks,this.blockLength-this.blockOffset),o=this.blockIndex,r=this.blockOffset,i=this;this.blockOffset=0,this.blockLength=0,this.blockIndex++,this.blocks=[];var a=this.name+"ÿ"+d(o),s=function(e,t,n){return e.length&&i.batch.push({type:"put",key:a,value:e,valueEncoding:c}),!t&&i.batch.lengthi&&(o=e.slice(i),e=e.slice(0,i)),this.bytesWritten+=e.length,this.blockLength+=e.length,this.blocks.push(e),e.lengtho._missing&&(e=e.slice(0,o._missing)),o._missing-=e.length,o._pause(!o.push(e)),!o._missing))};this._reader.on("data",(function(e){for(;e.key>u;)if(!l(f))return;l(e.value)})),this._reader.on("error",(function(e){o.emit("error",e)})),this._reader.on("end",(function(){o.push(null)})),r.call(this)};return a.inherits(_,r),_.prototype.destroy=function(){this._destroyed||(this._destroyed=!0,this._reader.destroy(),process.nextTick(this.emit.bind(this,"close")))},_.prototype._pause=function(e){this._paused!==e&&(this._paused=e,this._paused?this._reader.pause():this._reader.resume())},_.prototype._read=function(){this._pause(!1)},n.remove=function(t,n){n=s(n||l);var o=[],r=e.createKeyStream({start:t+"ÿ",end:t+"ÿÿ"});r.on("error",n),r.on("data",(function(e){o.push({type:"del",key:e})})),r.on("end",(function(){e.batch(o,n)}))},n.size=function(t,n){i.last(e,{start:t+"ÿ",end:t+"ÿÿ",valueEncoding:c},(function(e,o,r){return e&&"range not found"===e.message?n(null,0):e?n(e):o.slice(0,t.length+1)!==t+"ÿ"?n(null,0):void n(null,parseInt(o.toString().slice(t.length+1),16)*h+r.length)}))},n.write=function(e,t,o,r){if("function"==typeof o)return n.write(e,t,null,o);o||(o={}),r||(r=l);var i=n.createWriteStream(e,o);i.on("error",r),i.on("finish",(function(){r()})),i.write(t),i.end()},n.read=function(e,t,o){if("function"==typeof t)return n.read(e,null,t);t||(t={});var r=n.createReadStream(e,t),i=[];r.on("error",o),r.on("data",(function(e){i.push(e)})),r.on("end",(function(){o(null,1===i.length?i[0]:Buffer.concat(i))}))},n.createReadStream=function(e,t){return new _(e,t)},n.createWriteStream=function(e,t){return new m(e,t)},n}},79141:e=>{e.exports=Array.isArray||function(e){return"[object Array]"==Object.prototype.toString.call(e)}},79435:(e,t,n)=>{e.exports=s;var o=Object.keys||function(e){var t=[];for(var n in e)t.push(n);return t},r=n(16497);r.inherits=n(35717);var i=n(67496),a=n(60091);function s(e){if(!(this instanceof s))return new s(e);i.call(this,e),a.call(this,e),e&&!1===e.readable&&(this.readable=!1),e&&!1===e.writable&&(this.writable=!1),this.allowHalfOpen=!0,e&&!1===e.allowHalfOpen&&(this.allowHalfOpen=!1),this.once("end",u)}function u(){this.allowHalfOpen||this._writableState.ended||process.nextTick(this.end.bind(this))}r.inherits(s,i),function(e,t){for(var n=0,o=e.length;n{e.exports=i;var o=n(84987),r=n(16497);function i(e){if(!(this instanceof i))return new i(e);o.call(this,e)}r.inherits=n(35717),r.inherits(i,o),i.prototype._transform=function(e,t,n){n(null,e)}},67496:(e,t,n)=>{e.exports=d;var o=n(79141),r=n(48764).Buffer;d.ReadableState=l;var i=n(17187).EventEmitter;i.listenerCount||(i.listenerCount=function(e,t){return e.listeners(t).length});var a,s=n(42830),u=n(16497);u.inherits=n(35717);var c=n(6297);function l(e,t){var o=n(79435),r=(e=e||{}).highWaterMark,i=e.objectMode?16:16384;this.highWaterMark=r||0===r?r:i,this.highWaterMark=~~this.highWaterMark,this.buffer=[],this.length=0,this.pipes=null,this.pipesCount=0,this.flowing=null,this.ended=!1,this.endEmitted=!1,this.reading=!1,this.sync=!0,this.needReadable=!1,this.emittedReadable=!1,this.readableListening=!1,this.objectMode=!!e.objectMode,t instanceof o&&(this.objectMode=this.objectMode||!!e.readableObjectMode),this.defaultEncoding=e.defaultEncoding||"utf8",this.ranOut=!1,this.awaitDrain=0,this.readingMore=!1,this.decoder=null,this.encoding=null,e.encoding&&(a||(a=n(50981).s),this.decoder=new a(e.encoding),this.encoding=e.encoding)}function d(e){if(n(79435),!(this instanceof d))return new d(e);this._readableState=new l(e,this),this.readable=!0,s.call(this)}function h(e,t,n,o,r){var i=function(e,t){var n=null;return u.isBuffer(t)||u.isString(t)||u.isNullOrUndefined(t)||e.objectMode||(n=new TypeError("Invalid non-string/buffer chunk")),n}(t,n);if(i)e.emit("error",i);else if(u.isNullOrUndefined(n))t.reading=!1,t.ended||function(e,t){if(t.decoder&&!t.ended){var n=t.decoder.end();n&&n.length&&(t.buffer.push(n),t.length+=t.objectMode?1:n.length)}t.ended=!0,g(e)}(e,t);else if(t.objectMode||n&&n.length>0)if(t.ended&&!r){var a=new Error("stream.push() after EOF");e.emit("error",a)}else t.endEmitted&&r?(a=new Error("stream.unshift() after end event"),e.emit("error",a)):(!t.decoder||r||o||(n=t.decoder.write(n)),r||(t.reading=!1),t.flowing&&0===t.length&&!t.sync?(e.emit("data",n),e.read(0)):(t.length+=t.objectMode?1:n.length,r?t.buffer.unshift(n):t.buffer.push(n),t.needReadable&&g(e)),function(e,t){t.readingMore||(t.readingMore=!0,process.nextTick((function(){!function(e,t){for(var n=t.length;!t.reading&&!t.flowing&&!t.ended&&t.lengtht.highWaterMark&&(t.highWaterMark=function(e){if(e>=p)e=p;else{e--;for(var t=1;t<32;t<<=1)e|=e>>t;e++}return e}(e)),e>t.length?t.ended?t.length:(t.needReadable=!0,0):e)}function g(e){var t=e._readableState;t.needReadable=!1,t.emittedReadable||(c("emitReadable",t.flowing),t.emittedReadable=!0,t.sync?process.nextTick((function(){m(e)})):m(e))}function m(e){c("emit readable"),e.emit("readable"),_(e)}function _(e){var t=e._readableState;if(c("flow",t.flowing),t.flowing)do{var n=e.read()}while(null!==n&&t.flowing)}function F(e,t){var n,o=t.buffer,i=t.length,a=!!t.decoder,s=!!t.objectMode;if(0===o.length)return null;if(0===i)n=null;else if(s)n=o.shift();else if(!e||e>=i)n=a?o.join(""):r.concat(o,i),o.length=0;else if(e0)throw new Error("endReadable called on non-empty stream");t.endEmitted||(t.ended=!0,process.nextTick((function(){t.endEmitted||0!==t.length||(t.endEmitted=!0,e.readable=!1,e.emit("end"))})))}d.prototype.read=function(e){c("read",e);var t=this._readableState,n=e;if((!u.isNumber(e)||e>0)&&(t.emittedReadable=!1),0===e&&t.needReadable&&(t.length>=t.highWaterMark||t.ended))return c("read: emitReadable",t.length,t.ended),0===t.length&&t.ended?y(this):g(this),null;if(0===(e=f(e,t))&&t.ended)return 0===t.length&&y(this),null;var o,r=t.needReadable;return c("need readable",r),(0===t.length||t.length-e0?F(e,t):null,u.isNull(o)&&(t.needReadable=!0,e=0),t.length-=e,0!==t.length||t.ended||(t.needReadable=!0),n!==e&&t.ended&&0===t.length&&y(this),u.isNull(o)||this.emit("data",o),o},d.prototype._read=function(e){this.emit("error",new Error("not implemented"))},d.prototype.pipe=function(e,t){var n=this,r=this._readableState;switch(r.pipesCount){case 0:r.pipes=e;break;case 1:r.pipes=[r.pipes,e];break;default:r.pipes.push(e)}r.pipesCount+=1,c("pipe count=%d opts=%j",r.pipesCount,t);var a=t&&!1===t.end||e===process.stdout||e===process.stderr?d:u;function s(e){c("onunpipe"),e===n&&d()}function u(){c("onend"),e.end()}r.endEmitted?process.nextTick(a):n.once("end",a),e.on("unpipe",s);var l=function(e){return function(){var t=e._readableState;c("pipeOnDrain",t.awaitDrain),t.awaitDrain&&t.awaitDrain--,0===t.awaitDrain&&i.listenerCount(e,"data")&&(t.flowing=!0,_(e))}}(n);function d(){c("cleanup"),e.removeListener("close",f),e.removeListener("finish",g),e.removeListener("drain",l),e.removeListener("error",p),e.removeListener("unpipe",s),n.removeListener("end",u),n.removeListener("end",d),n.removeListener("data",h),!r.awaitDrain||e._writableState&&!e._writableState.needDrain||l()}function h(t){c("ondata"),!1===e.write(t)&&(c("false write response, pause",n._readableState.awaitDrain),n._readableState.awaitDrain++,n.pause())}function p(t){c("onerror",t),m(),e.removeListener("error",p),0===i.listenerCount(e,"error")&&e.emit("error",t)}function f(){e.removeListener("finish",g),m()}function g(){c("onfinish"),e.removeListener("close",f),m()}function m(){c("unpipe"),n.unpipe(e)}return e.on("drain",l),n.on("data",h),e._events&&e._events.error?o(e._events.error)?e._events.error.unshift(p):e._events.error=[p,e._events.error]:e.on("error",p),e.once("close",f),e.once("finish",g),e.emit("pipe",n),r.flowing||(c("pipe resume"),n.resume()),e},d.prototype.unpipe=function(e){var t=this._readableState;if(0===t.pipesCount)return this;if(1===t.pipesCount)return e&&e!==t.pipes||(e||(e=t.pipes),t.pipes=null,t.pipesCount=0,t.flowing=!1,e&&e.emit("unpipe",this)),this;if(!e){var n=t.pipes,o=t.pipesCount;t.pipes=null,t.pipesCount=0,t.flowing=!1;for(var r=0;r{e.exports=a;var o=n(79435),r=n(16497);function i(e,t){this.afterTransform=function(e,n){return function(e,t,n){var o=e._transformState;o.transforming=!1;var i=o.writecb;if(!i)return e.emit("error",new Error("no writecb in Transform class"));o.writechunk=null,o.writecb=null,r.isNullOrUndefined(n)||e.push(n),i&&i(t);var a=e._readableState;a.reading=!1,(a.needReadable||a.length{e.exports=u;var o=n(48764).Buffer;u.WritableState=s;var r=n(16497);r.inherits=n(35717);var i=n(42830);function a(e,t,n){this.chunk=e,this.encoding=t,this.callback=n}function s(e,t){var o=n(79435),r=(e=e||{}).highWaterMark,i=e.objectMode?16:16384;this.highWaterMark=r||0===r?r:i,this.objectMode=!!e.objectMode,t instanceof o&&(this.objectMode=this.objectMode||!!e.writableObjectMode),this.highWaterMark=~~this.highWaterMark,this.needDrain=!1,this.ending=!1,this.ended=!1,this.finished=!1;var a=!1===e.decodeStrings;this.decodeStrings=!a,this.defaultEncoding=e.defaultEncoding||"utf8",this.length=0,this.writing=!1,this.corked=0,this.sync=!0,this.bufferProcessing=!1,this.onwrite=function(e){!function(e,t){var n=e._writableState,o=n.sync,r=n.writecb;if(function(e){e.writing=!1,e.writecb=null,e.length-=e.writelen,e.writelen=0}(n),t)!function(e,t,n,o,r){n?process.nextTick((function(){t.pendingcb--,r(o)})):(t.pendingcb--,r(o)),e._writableState.errorEmitted=!0,e.emit("error",o)}(e,n,o,t,r);else{var i=h(0,n);i||n.corked||n.bufferProcessing||!n.buffer.length||d(e,n),o?process.nextTick((function(){l(e,n,i,r)})):l(e,n,i,r)}}(t,e)},this.writecb=null,this.writelen=0,this.buffer=[],this.pendingcb=0,this.prefinished=!1,this.errorEmitted=!1}function u(e){var t=n(79435);if(!(this instanceof u||this instanceof t))return new u(e);this._writableState=new s(e,this),this.writable=!0,i.call(this)}function c(e,t,n,o,r,i,a){t.writelen=o,t.writecb=a,t.writing=!0,t.sync=!0,n?e._writev(r,t.onwrite):e._write(r,i,t.onwrite),t.sync=!1}function l(e,t,n,o){n||function(e,t){0===t.length&&t.needDrain&&(t.needDrain=!1,e.emit("drain"))}(e,t),t.pendingcb--,o(),f(e,t)}function d(e,t){if(t.bufferProcessing=!0,e._writev&&t.buffer.length>1){for(var n=[],o=0;o{(t=e.exports=n(67496)).Stream=n(42830),t.Readable=t,t.Writable=n(60091),t.Duplex=n(79435),t.Transform=n(84987),t.PassThrough=n(1474),process.browser||"disable"!==process.env.READABLE_STREAM||(e.exports=n(42830))},57785:(e,t,n)=>{e.exports=n(60091)},50981:(e,t,n)=>{var o=n(48764).Buffer,r=o.isEncoding||function(e){switch(e&&e.toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":case"raw":return!0;default:return!1}},i=t.s=function(e){switch(this.encoding=(e||"utf8").toLowerCase().replace(/[-_]/,""),function(e){if(e&&!r(e))throw new Error("Unknown encoding: "+e)}(e),this.encoding){case"utf8":this.surrogateSize=3;break;case"ucs2":case"utf16le":this.surrogateSize=2,this.detectIncompleteChar=s;break;case"base64":this.surrogateSize=3,this.detectIncompleteChar=u;break;default:return void(this.write=a)}this.charBuffer=new o(6),this.charReceived=0,this.charLength=0};function a(e){return e.toString(this.encoding)}function s(e){this.charReceived=e.length%2,this.charLength=this.charReceived?2:0}function u(e){this.charReceived=e.length%3,this.charLength=this.charReceived?3:0}i.prototype.write=function(e){for(var t="";this.charLength;){var n=e.length>=this.charLength-this.charReceived?this.charLength-this.charReceived:e.length;if(e.copy(this.charBuffer,this.charReceived,0,n),this.charReceived+=n,this.charReceived=55296&&o<=56319)){if(this.charReceived=this.charLength=0,0===e.length)return t;break}this.charLength+=this.surrogateSize,t=""}this.detectIncompleteChar(e);var o,r=e.length;if(this.charLength&&(e.copy(this.charBuffer,0,e.length-this.charReceived,r),r-=this.charReceived),r=(t+=e.toString(this.encoding,0,r)).length-1,(o=t.charCodeAt(r))>=55296&&o<=56319){var i=this.surrogateSize;return this.charLength+=i,this.charReceived+=i,this.charBuffer.copy(this.charBuffer,i,0,i),e.copy(this.charBuffer,0,0,i),t.substring(0,r)}return t},i.prototype.detectIncompleteChar=function(e){for(var t=e.length>=3?3:e.length;t>0;t--){var n=e[e.length-t];if(1==t&&n>>5==6){this.charLength=2;break}if(t<=2&&n>>4==14){this.charLength=3;break}if(t<=3&&n>>3==30){this.charLength=4;break}}this.charReceived=t},i.prototype.end=function(e){var t="";if(e&&e.length&&(t=this.write(e)),this.charReceived){var n=this.charReceived,o=this.charBuffer,r=this.encoding;t+=o.slice(0,n).toString(r)}return t}},2950:(e,t,n)=>{var o=n(47138);Object.keys(o.code).forEach((function(e){var n=o.code[e];t[e]=function(t){var o=new Error(e+", "+n.description+(t?" '"+t+"'":""));return o.errno=n.errno,o.code=e,o.path=t,o}}))},49942:(e,t,n)=>{var o=n(35673),r=n(98673),i=n(69334),a=n(51753),s=n(30778),u=n(39530),c=n(2950),l=n(68781),d=n(36975),h=function(e,t,n){process.nextTick((function(){e(t,n)}))},p=function(){};e.exports=function(e,t){var n={};e=r(e);var f=i(e.sublevel("blobs"),t),g=l(e.sublevel("stats")),m=e.sublevel("links"),_=d(),F=[],y=Date.now();n.mkdir=function(e,t,o){if("function"==typeof t)return n.mkdir(e,null,t);t||(t=u(777)),o||(o=p),g.follow(e,(function(e,n,r){return e&&"ENOENT"!==e.code?o(e):n?o(c.EEXIST(r)):void g.put(r,{type:"directory",mode:t,size:4096},_.cb(r,o))}))},n.rmdir=function(e,t){t||(t=p),g.follow(e,(function(e,o,r){if(e)return t(e);n.readdir(r,(function(e,n){return e?t(e):n.length?t(c.ENOTEMPTY(r)):void g.del(r,_.cb(r,t))}))}))},n.readdir=function(e,t){g.follow(e,(function(e,n,o){return e?t(e):n?n.isDirectory()?void g.list(o,t):t(c.ENOTDIR(o)):t(c.ENOENT(o))}))};var b=function(e,t,n){t(e,(function(e,t,o){if(e)return n(e);if(!t.isFile())return n(null,t);var r=t&&t.blob||o;f.size(r,(function(e,o){if(e)return n(e);t.size=o,n(null,t)}))}))};n.stat=function(e,t){b(e,g.follow,t)},n.lstat=function(e,t){b(e,g.get,t)},n.exists=function(e,t){g.follow(e,(function(e){t(!e)}))};var v=function(e,t,n,o){o||(o=p),t(e,(function(e,t,r){if(e)return o(e);g.update(r,{mode:n},_.cb(r,o))}))};n.chmod=function(e,t,n){v(e,g.follow,t,n)},n.lchmod=function(e,t,n){v(e,g.get,t,n)};var w=function(e,t,n,o,r){r||(r=p),t(e,(function(e,t,i){if(e)return r(e);g.update(i,{uid:n,gid:o},_.cb(i,r))}))};return n.chown=function(e,t,n,o){w(e,g.follow,t,n,o)},n.lchown=function(e,t,n,o){w(e,g.get,t,n,o)},n.utimes=function(e,t,n,o){o||(o=p),g.follow(e,(function(e,r,i){if(e)return o(e);var a={};t&&(a.atime=t),n&&(a.mtime=n),g.update(i,a,_.cb(i,o))}))},n.rename=function(e,t,o){o||(o=p),g.follow(e,(function(e,r,i){if(e)return o(e);var a=function(){o=_.cb(t,_.cb(i,o)),g.put(t,r,(function(e){if(e)return o(e);g.del(i,o)}))};g.follow(t,(function(e,t,s){return e&&"ENOENT"!==e.code?o(e):t?r.isDirectory()!==t.isDirectory()?o(c.EISDIR(i)):void(t.isDirectory()?n.readdir(s,(function(e,t){return e?o(e):t.length?o(c.ENOTEMPTY(i)):void a()})):a()):a()}))}))},n.realpath=function(e,t,o){if("function"==typeof t)return n.realpath(e,null,t);g.follow(e,(function(e,t,n){if(e)return o(e);o(null,n)}))},n.writeFile=function(e,t,o,r){if("function"==typeof o)return n.writeFile(e,t,null,o);"string"==typeof o&&(o={encoding:o}),o||(o={}),r||(r=p),Buffer.isBuffer(t)||(t=new Buffer(t,o.encoding||"utf-8"));var i=o.flags||"w";o.append="w"!==i[0],g.follow(e,(function(e,n,a){if(e&&"ENOENT"!==e.code)return r(e);if(n&&n.isDirectory())return r(c.EISDIR(a));if(n&&"x"===i[1])return r(c.EEXIST(a));var s=n&&n.blob||a;g.writable(a,(function(e){if(e)return r(e);f.write(s,t,o,(function(e){if(e)return r(e);g.put(a,{ctime:n&&n.ctime,mtime:new Date,mode:o.mode||u(666),type:"file"},_.cb(a,r))}))}))}))},n.appendFile=function(e,t,o,r){if("function"==typeof o)return n.appendFile(e,t,null,o);"string"==typeof o&&(o={encoding:o}),o||(o={}),o.flags="a",n.writeFile(e,t,o,r)},n.unlink=function(e,t){t||(t=p),g.get(e,(function(e,n,o){if(e)return t(e);if(n.isDirectory())return t(c.EISDIR(o));var r=function(e){a(m,{start:e+"ÿ",end:e+"ÿÿ"},(function(n){if(n)return f.remove(e,t);t()}))};g.del(o,_.cb(o,(function(e){return e?t(e):n.link?(i=n.link.slice(0,n.link.indexOf("ÿ")),void m.del(n.link,(function(e){if(e)return t(e);r(i)}))):void m.del(o+"ÿ",(function(e){if(e)return t(e);r(o)}));var i})))}))},n.readFile=function(e,t,o){if("function"==typeof t)return n.readFile(e,null,t);"string"==typeof t&&(t={encoding:t}),t||(t={}),t.encoding,t.flag,g.follow(e,(function(e,n,r){if(e)return o(e);if(n.isDirectory())return o(c.EISDIR(r));var i=n&&n.blob||r;f.read(i,(function(e,n){if(e)return o(e);o(null,t.encoding?n.toString(t.encoding):n)}))}))},n.createReadStream=function(e,t){t||(t={});var n=!1,r=o.readable((function(o){g.follow(e,(function(e,i,a){if(e)return o(e);if(i.isDirectory())return o(c.EISDIR(a));var s=i&&i.blob||a,u=f.createReadStream(s,t);r.emit("open"),u.on("end",(function(){process.nextTick((function(){n||r.emit("close")}))})),o(null,u)}))}));return r.on("close",(function(){n=!0})),r},n.createWriteStream=function(e,t){t||(t={});var n=t.flags||"w",r=!1,i=t.mode||u(666);t.append="a"===n[0];var a=o.writable((function(o){g.follow(e,(function(e,s,u){if(e&&"ENOENT"!==e.code)return o(e);if(s&&s.isDirectory())return o(c.EISDIR(u));if(s&&"x"===n[1])return o(c.EEXIST(u));var l=s&&s.blob||u;g.writable(l,(function(e){if(e)return o(e);var n={ctime:s?s.ctime:new Date,mtime:new Date,mode:i,type:"file"};g.put(u,n,(function(e){if(e)return o(e);var i=f.createWriteStream(l,t);a.emit("open"),i.on("finish",(function(){n.mtime=new Date,g.put(u,n,(function(){_.change(u),r||a.emit("close")}))})),o(null,i)}))}))}))}));return a.on("close",(function(){r=!0})),a},n.truncate=function(e,t,n){g.follow(e,(function(e,o,r){if(e)return n(e);var i=o&&o.blob||r;f.size(i,(function(e,o){if(e)return n(e);g.writable(r,(function(e){if(e)return n(e);if(n=s(_.cb(r,n)),!t)return f.remove(i,n);var a=f.createWriteStream(i,{start:o{var o=n(26470),r=n(30778),i=n(36890),a=n(39530),s=n(86705),u=n(78779),c=n(2950),l=s({type:"directory",mode:a(777),size:4096}),d=function(e){return e="/"===e[0]?e:"/"+e,"/"===(e=o.normalize(e))?e:"/"===e[e.length-1]?e.slice(0,-1):e},h=function(e){var t=e.split("/").length.toString(36);return"0000000000".slice(t.length)+t+e};e.exports=function(e){var t={};return t.normalize=d,t.get=function(t,n){if("/"===(t=d(t)))return process.nextTick(n.bind(null,null,l,"/"));e.get(h(t),{valueEncoding:"json"},(function(e,o){return e&&e.notFound?n(c.ENOENT(t),null,t):e?n(e,null,t):void n(null,s(o),t)}))},t.writable=function(e,n){if("/"===(e=d(e)))return process.nextTick(n.bind(null,c.EPERM(e)));t.follow(o.dirname(e),(function(t,o){return t?n(t):o.isDirectory()?void n(null,e):n(c.ENOTDIR(e))}))},t.list=function(t,n){t=d(t);var o=h("/"===t?t:t+"/"),a=e.createKeyStream({start:o,end:o+"ÿ"});n=r(n),a.on("error",n),a.pipe(i({encoding:"object"},(function(e){e=e.map((function(e){return e.split("/").pop()})),n(null,e)})))},t.follow=function(e,n){!function(e,n){var r="/",i=e.split("/").slice(1),a=function(){t.get(o.join(r,i.shift()),(function(t,o,s){return t?n(t,o,e):(r=o.target||s,i.length?void a():n(null,o,s))}))};a()}(d(e),(function e(o,r,i){return o?n(o,null,i):r.target?t.get(r.target,e):void n(null,s(r),i)}))},t.update=function(e,n,o){t.get(e,(function(e,r,i){return e?o(e):"/"===i?o(c.EPERM(i)):void t.put(i,u(r,n),o)}))},t.put=function(n,o,r){t.writable(n,(function(t,n){if(t)return r(t);e.put(h(n),s(o),{valueEncoding:"json"},r)}))},t.del=function(t,n){if("/"===(t=d(t)))return process.nextTick(n.bind(null,c.EPERM(t)));e.del(h(t),n)},t}},86705:e=>{var t=function(e){return e?"string"==typeof e?new Date(e):e:new Date},n=function(e){this.uid=e.uid||0,this.gid=e.gid||0,this.mode=e.mode||0,this.size=e.size||0,this.mtime=t(e.mtime),this.atime=t(e.atime),this.ctime=t(e.ctime),this.type=e.type,this.target=e.target,this.link=e.link,this.blob=e.blob};n.prototype.isDirectory=function(){return"directory"===this.type},n.prototype.isFile=function(){return"file"===this.type},n.prototype.isBlockDevice=function(){return!1},n.prototype.isCharacterDevice=function(){return!1},n.prototype.isSymbolicLink=function(){return"symlink"===this.type},n.prototype.isFIFO=function(){return!1},n.prototype.isSocket=function(){return!1},e.exports=function(e){return new n(e)}},36975:(e,t,n)=>{var o=n(17187);e.exports=function(){var e={},t=new o.EventEmitter;return t.watch=function(t,n){return e[t]||(e[t]=new o.EventEmitter,e[t].setMaxListeners(0)),n&&e[t].on("change",n),e[t]},t.watcher=function(e,n){var r=new o.EventEmitter,i=function(){r.emit("change","change",e)};return t.watch(e,i),n&&r.on("change",n),r.close=function(){t.unwatch(e,i)},r},t.unwatch=function(t,n){e[t]&&(n?e[t].removeListener("change",n):e[t].removeAllListeners("change"),e[t].listeners("change").length||delete e[t])},t.change=function(n){e[n]&&e[n].emit("change"),t.emit("change",n)},t.cb=function(e,n){return function(o,r){e&&t.change(e),n&&n(o,r)}},t}},80767:e=>{e.exports=function(e){var t=e.reverse,n=e.end,o=e.start,r=[o,n];return null!=o&&null!=n&&r.sort(),t&&(r=r.reverse()),e.start=r[0],e.end=r[1],e}},11798:(e,t,n)=>{var o=n(21889);e.exports=function(e){if(!e.hooks){var t=[],n=[];e.hooks={post:function(e,n){n||(n=e,e="");var r={test:o.checker(e),hook:n};return t.push(r),u(t,r)},pre:function(e,t){t||(t=e,e="");var r={test:o.checker(e),hook:t,safe:!1!==e.safe};return n.push(r),u(n,r)},posthooks:t,prehooks:n},e.on("put",(function(e,t){c({type:"put",key:e,value:t})})),e.on("del",(function(e,t){c({type:"del",key:e,value:t})})),e.on("batch",(function(e){e.forEach(c)}));var r=e.put,i=e.del,a=e.batch;e.put=function(e,t,n,o){return l(!1,[{key:e,value:t,type:"put"}],n,o)},e.del=function(e,t,n){return l(!1,[{key:e,type:"del"}],t,n)},e.batch=function(e,t,n){return l(!0,e,t,n)}}function s(e){return e&&("string"==typeof e?e:"string"==typeof e.prefix?e.prefix:"function"==typeof e.prefix?e.prefix():"")}function u(e,t){return function(){var n=e.indexOf(t);return!!~n&&(e.splice(n,1),!0)}}function c(e){e&&e.type&&t.forEach((function(t){t.test(e.key)&&t.hook(e)}))}function l(t,o,u,c){try{o.forEach((function e(t,r){n.forEach((function(n){if(n.test(String(t.key))){var i={add:function(t,i){if(void 0===t)return this;if(!1===t)return delete o[r];var a=s(t.prefix)||s(i)||n.prefix||"";if(a&&(t.prefix=a),t.key=a+t.key,n.safe&&n.test(String(t.key)))throw new Error("prehook cannot insert into own range");var u=t.keyEncoding||function(e){if(e&&e._getKeyEncoding)return e._getKeyEncoding(e)}(t.prefix),c=t.valueEncoding||function(e){if(e&&e._getValueEncoding)return e._getValueEncoding(e)}(t.prefix);return u&&(t.keyEncoding=u),c&&(t.valueEncoding=c),o.push(t),e(t,o.length-1),this},put:function(e,t){return"object"==typeof e&&(e.type="put"),this.add(e,t)},del:function(e,t){return"object"==typeof e&&(e.type="del"),this.add(e,t)},veto:function(){return this.add(!1)}};n.hook.call(i,t,i.add,o)}}))}))}catch(e){return(c||u)(e)}if(1==(o=o.filter((function(e){return e&&e.type}))).length&&!t){var l=o[0];return"put"==l.type?r.call(e,l.key,l.value,u,c):i.call(e,l.key,u,c)}return a.call(e,o,u,c)}}},99558:(e,t,n)=>{e.exports=l;var o=n(89043),r=n(32554).NI,i=n(89539),a=n(43016),s=n(35086),u=n(86093),c=n(65054);function l(e){if(!(this instanceof l))return new l(e);if(!e)throw new Error("constructor requires at least a location argument");this.IDBOptions={},this.location=e}i.inherits(l,r),l.prototype._open=function(e,t){var n=this,r={storeName:this.location,autoIncrement:!1,keyPath:null,onStoreReady:function(){t&&t(null,n.idb)},onError:function(e){t&&t(e)}};u(r,e),this.IDBOptions=r,this.idb=new o(r)},l.prototype._get=function(e,t,n){this.idb.get(e,(function(o){if(void 0===o)return n(new Error("NotFound"));var r=!0;return!1===t.asBuffer&&(r=!1),t.raw&&(r=!1),r&&(o=o instanceof Uint8Array?c(o):new Buffer(String(o))),n(null,o,e)}),n)},l.prototype._del=function(e,t,n){this.idb.remove(e,n,n)},l.prototype._put=function(e,t,n,o){t instanceof ArrayBuffer&&(t=c(new Uint8Array(t)));var r=this.convertEncoding(e,t,n);Buffer.isBuffer(r.value)&&("function"==typeof t.toArrayBuffer?r.value=new Uint8Array(t.toArrayBuffer()):r.value=new Uint8Array(t)),this.idb.put(r.key,r.value,(function(){o()}),o)},l.prototype.convertEncoding=function(e,t,n){if(n.raw)return{key:e,value:t};if(t){var o=t.toString();"NaN"===o&&(t="NaN")}var r=n.valueEncoding,i={key:e,value:t};return!t||r&&"binary"===r||"object"!=typeof i.value&&(i.value=o),i},l.prototype.iterator=function(e){return"object"!=typeof e&&(e={}),new a(this.idb,e)},l.prototype._batch=function(e,t,n){var o,r,i,a,s=[];if(0===e.length)return setTimeout(n,0);for(o=0;o{var o=n(89539),r=n(32554).YI,i=n(82303);function a(e,t){t||(t={}),this.options=t,r.call(this,e),this._order=t.reverse?"DESC":"ASC",this._limit=t.limit,this._count=0,this._done=!1;var n=i.lowerBound(t),o=i.upperBound(t);try{this._keyRange=n||o?this.db.makeKeyRange({lower:n,upper:o,excludeLower:i.lowerBoundExclusive(t),excludeUpper:i.upperBoundExclusive(t)}):null}catch(e){this._keyRangeError=!0}this.callback=null}e.exports=a,o.inherits(a,r),a.prototype.createIterator=function(){var e=this;e.iterator=e.db.iterate((function(){e.onItem.apply(e,arguments)}),{keyRange:e._keyRange,autoContinue:!1,order:e._order,onError:function(e){console.log("horrible error",e)}})},a.prototype.onItem=function(e,t,n){if(!t&&this.callback)return this.callback(),void(this.callback=!1);var o=!0;this._limit&&this._limit>0&&this._count++>=this._limit&&(o=!1),o&&this.callback(!1,t.key,t.value),t&&t.continue()},a.prototype._next=function(e){return e?this._keyRangeError?e():(this._started||(this.createIterator(),this._started=!0),void(this.callback=e)):new Error("next() requires a callback argument")}},3732:e=>{var t=Object.prototype.hasOwnProperty,n=Object.prototype.toString,o=function(e){var t="function"==typeof e&&!(e instanceof RegExp)||"[object Function]"===n.call(e);return t||"undefined"==typeof window||(t=e===window.setTimeout||e===window.alert||e===window.confirm||e===window.prompt),t};e.exports=function(e,n){if(!o(n))throw new TypeError("iterator must be a function");var r,i,a="string"==typeof e,s=e.length,u=arguments.length>2?arguments[2]:null;if(s===+s)for(r=0;r{e.exports=Object.keys||n(23533)},70426:e=>{var t=Object.prototype.toString;e.exports=function(e){var n=t.call(e),o="[object Arguments]"===n;return o||(o="[object Array]"!==n&&null!==e&&"object"==typeof e&&"number"==typeof e.length&&e.length>=0&&"[object Function]"===t.call(e.callee)),o}},23533:(e,t,n)=>{!function(){"use strict";var t,o=Object.prototype.hasOwnProperty,r=Object.prototype.toString,i=n(3732),a=n(70426),s=!{toString:null}.propertyIsEnumerable("toString"),u=function(){}.propertyIsEnumerable("prototype"),c=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"];t=function(e){var t=null!==e&&"object"==typeof e,n="[object Function]"===r.call(e),l=a(e),d=[];if(!t&&!n&&!l)throw new TypeError("Object.keys called on a non-object");if(l)i(e,(function(e){d.push(e)}));else{var h,p=u&&n;for(h in e)p&&"prototype"===h||!o.call(e,h)||d.push(h)}if(s){var f=e.constructor,g=f&&f.prototype===e;i(c,(function(t){g&&"constructor"===t||!o.call(e,t)||d.push(t)}))}return d},e.exports=t}()},14992:e=>{e.exports=function(e){return null!==e&&("object"==typeof e||"function"==typeof e)}},86093:(e,t,n)=>{var o=n(59693),r=n(14992);e.exports=function(){for(var e={},t=0;t{var o=n(80767);function r(e,t,n){var o,r,i;t.limit=t.reverse?2:1,o=e.createReadStream(t),r=function(e,o){if(t.reverse&&o&&t.start&&o.key.toString()>t.start)return!1;"error"==e?n(o):"end"==e?n(new Error("range not found"),null,null):n(null,o.key,o.value)},i=[],["data","error","end"].forEach((function(e){function t(t){!1!==r(e,t)&&i.forEach((function(e){e()}))}o.on(e,t),i.push((function(){o.removeListener(e,t)}))}))}(t=e.exports=r).first=function(e,t,n){return n||(n=t,t={}),t.reverse=!1,r(e,o(t),n)},t.last=function(e,t,n){return n||(n=t,t={}),t.start,t.reverse=!0,r(e,o(t),(function(o,i,a){if(o){var s=t.start;t.start=null,r(e,t,(function(e,r,i){if(!r)return n(o,null,null);var a=r.toString();a<=s&&(!t.end||a>=t.end)?n(e,r,i):n(o,null,null)}))}else n(o,i,a)}))}},76338:e=>{function t(e,t,n,o){var r={type:e,key:t,value:n,options:o};return o&&o.prefix&&(r.prefix=o.prefix,delete o.prefix),this._operations.push(r),this}function n(e){this._operations=[],this._sdb=e,this.put=t.bind(this,"put"),this.del=t.bind(this,"del")}var o=n.prototype;o.clear=function(){this._operations=[]},o.write=function(e){this._sdb.batch(this._operations,e)},e.exports=n},98673:(e,t,n)=>{n(17187).EventEmitter,process.nextTick;var o=n(97202),r=n(76338),i=n(97780),a=n(11798);e.exports=function(e,t){function n(){}n.prototype=e;var s=new n;if(s.sublevel)return s;var u=(t=t||{}).sep=t.sep||"ÿ";function c(e){return function(t){return(t=i(t=t||{})).reverse?t.start=t.start||u:t.end=t.end||u,e.call(s,t)}}s._options=t,a(s),s.sublevels={},s.sublevel=function(e,t){return s.sublevels[e]?s.sublevels[e]:new o(s,e,t||this._options)},s.methods={},s.prefix=function(e){return""+(e||"")},s.pre=function(e,t){return t||(t=e,e={max:u}),s.hooks.pre(e,t)},s.post=function(e,t){return t||(t=e,e={max:u}),s.hooks.post(e,t)},s.readStream=s.createReadStream=c(s.createReadStream),s.keyStream=s.createKeyStream=c(s.createKeyStream),s.valuesStream=s.createValueStream=c(s.createValueStream);var l=s.batch;return s.batch=function(e,t,n){if(!Array.isArray(e))return new r(s);e.forEach((function(e){e.prefix&&("function"==typeof e.prefix.prefix?e.key=e.prefix.prefix(e.key):"string"==typeof e.prefix&&(e.key=e.prefix+e.key))})),l.call(s,e,t,n)},s}},97780:(e,t,n)=>{var o=n(16313);e.exports=function(e){var t=(e=o(e)).reverse,n=e.max||e.end,r=e.min||e.start,i=[r,n];return null!=r&&null!=n&&i.sort(),t&&(i=i.reverse()),e.start=i[0],e.end=i[1],delete e.min,delete e.max,e}},11012:(e,t,n)=>{e.exports=Object.keys||n(44784)},44784:(e,t,n)=>{!function(){"use strict";var t,o=Object.prototype.hasOwnProperty,r=n(65452),i=n(49804),a=!{toString:null}.propertyIsEnumerable("toString"),s=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"];t=function(e){if(!r.object(e)&&!r.array(e))throw new TypeError("Object.keys called on a non-object");var t,n=[];for(t in e)o.call(e,t)&&n.push(t);return a&&i(s,(function(t){o.call(e,t)&&n.push(t)})),n},e.exports=t}()},83312:e=>{e.exports=function(e){return null!==e&&("object"==typeof e||"function"==typeof e)}},71686:(e,t,n)=>{var o=n(11012),r=n(83312);e.exports=function(){for(var e={},t=0;t{var o=n(17187).EventEmitter,r=n(89539).inherits,i=n(21889),a=n(97780),s=n(71686),u=n(76338);function c(e,t,n){if("string"==typeof n&&(console.error("db.sublevel(name, seperator) is depreciated"),console.error("use db.sublevel(name, {sep: separator})) if you must"),n={sep:n}),!(this instanceof c))return new c(e,t,n);if(!e)throw new Error("must provide db");if(!t)throw new Error("must provide prefix");(n=n||{}).sep=n.sep||"ÿ",this._parent=e,this._options=n,this.options=n,this._prefix=t,this._root=d(this),e.sublevels[t]=this,this.sublevels={},this.methods={};var o=this;this.hooks={pre:function(){return o.pre.apply(o,arguments)},post:function(){return o.post.apply(o,arguments)}}}r(c,o);var l=c.prototype;function d(e){return e._parent?d(e._parent):e}l._key=function(e){var t=this._options.sep;return t+this._prefix+t+e},l._getOptsAndCb=function(e,t){return"function"==typeof e&&(t=e,e={}),{opts:s(e,this._options),cb:t}},l.sublevel=function(e,t){return this.sublevels[e]?this.sublevels[e]:new c(this,e,t||this._options)},l.put=function(e,t,n,o){var r=this._getOptsAndCb(n,o);this._root.put(this.prefix(e),t,r.opts,r.cb)},l.get=function(e,t,n){var o=this._getOptsAndCb(t,n);this._root.get(this.prefix(e),o.opts,o.cb)},l.del=function(e,t,n){var o=this._getOptsAndCb(t,n);this._root.del(this.prefix(e),o.opts,o.cb)},l.batch=function(e,t,n){if(!Array.isArray(e))return new u(this);var o=this,r=this._getOptsAndCb(t,n);e.forEach((function(e){"string"==typeof e.prefix?e.key=e.prefix+e.key:e.key=(e.prefix||o).prefix(e.key),e.prefix&&(e.prefix=null)})),this._root.batch(e,r.opts,r.cb)},l._getKeyEncoding=function(){return this.options.keyEncoding?this.options.keyEncoding:this._parent&&this._parent._getKeyEncoding?this._parent._getKeyEncoding():void 0},l._getValueEncoding=function(){return this.options.valueEncoding?this.options.valueEncoding:this._parent&&this._parent._getValueEncoding?this._parent._getValueEncoding():void 0},l.prefix=function(e){var t=this._options.sep;return this._parent.prefix()+t+this._prefix+t+(e||"")},l.keyStream=l.createKeyStream=function(e){return(e=e||{}).keys=!0,e.values=!1,this.createReadStream(e)},l.valueStream=l.createValueStream=function(e){return(e=e||{}).keys=!1,e.values=!0,e.keys=!1,this.createReadStream(e)},l.readStream=l.createReadStream=function(e){e=e||{};var t=d(this),n=this.prefix(),o=i.prefix(e,n);!function(e,t){["valueEncoding","encoding","keyEncoding","reverse","values","keys","limit","fillCache"].forEach((function(n){t.hasOwnProperty(n)&&(e[n]=t[n])}))}(o,s(e,this._options));var r=t.createReadStream(o);if(!1===o.values){var a;if(a=r.read)r.read=function(e){var t=a.call(this,e);return t&&(t=t.substring(n.length)),t};else{var u=r.emit;r.emit=function(e,t){"data"===e?u.call(this,"data",t.substring(n.length)):u.call(this,e,t)}}return r}return!1===o.keys||((a=r.read)?r.read=function(e){var t=a.call(this,e);return t&&(t.key=t.key.substring(n.length)),t}:r.on("data",(function(e){e.key=e.key.substring(n.length)}))),r},l.writeStream=l.createWriteStream=function(){var e=d(this),t=this.prefix(),n=e.createWriteStream.apply(e,arguments),o=n.write,r=this._options.encoding,i=this._options.valueEncoding,a=this._options.keyEncoding,s=!r&&!i&&!a;return n.write=s?function(e){return e.key=t+e.key,o.call(n,e)}:function(e){return e.key=t+e.key,r&&void 0===e.encoding&&(e.encoding=r),i&&void 0===e.valueEncoding&&(e.valueEncoding=i),a&&void 0===e.keyEncoding&&(e.keyEncoding=a),o.call(n,e)},n},l.approximateSize=function(){var e=d(db);return e.approximateSize.apply(e,arguments)},l.pre=function(e,t){t||(t=e,e=null),e=i.prefix(e,this.prefix(),this._options.sep);var n=d(this._parent),o=this.prefix();return n.hooks.pre(a(e),(function(e,n,r){t({key:e.key.substring(o.length),value:e.value,type:e.type},(function(e,t){n(e,e.prefix?t:t||o)}),r)}))},l.post=function(e,t){t||(t=e,e=null);var n=d(this._parent),o=this.prefix();return e=i.prefix(e,o,this._options.sep),n.hooks.post(a(e),(function(e){t({key:e.key.substring(o.length),value:e.value,type:e.type})}))},e.exports=c},48133:(e,t,n)=>{var o=n(63368),r=n(86667).WriteError,i=o.getOptions,a=o.dispatchError;function s(e){this._levelup=e,this.batch=e.db.batch(),this.ops=[]}s.prototype.put=function(e,t,n){n=i(this._levelup,n);var a=o.encodeKey(e,n),s=o.encodeValue(t,n);try{this.batch.put(a,s)}catch(e){throw new r(e)}return this.ops.push({type:"put",key:a,value:s}),this},s.prototype.del=function(e,t){t=i(this._levelup,t);var n=o.encodeKey(e,t);try{this.batch.del(n)}catch(e){throw new r(e)}return this.ops.push({type:"del",key:n}),this},s.prototype.clear=function(){try{this.batch.clear()}catch(e){throw new r(e)}return this.ops=[],this},s.prototype.write=function(e){var t=this._levelup,n=this.ops;try{this.batch.write((function(o){if(o)return a(t,new r(o),e);t.emit("batch",n),e&&e()}))}catch(e){throw new r(e)}},e.exports=s},86667:(e,t,n)=>{var o=n(47138).create,r=o("LevelUPError"),i=o("NotFoundError",r);i.prototype.notFound=!0,i.prototype.status=404,e.exports={LevelUPError:r,InitializationError:o("InitializationError",r),OpenError:o("OpenError",r),ReadError:o("ReadError",r),WriteError:o("WriteError",r),NotFoundError:i,EncodingError:o("EncodingError",r)}},34918:(e,t,n)=>{var o=n(17187).EventEmitter,r=n(89539).inherits,i=n(47357),a=n(30115),s=n(66944),u=n(86667).WriteError,c=n(86667).ReadError,l=n(86667).NotFoundError,d=n(86667).OpenError,h=n(86667).EncodingError,p=n(86667).InitializationError,f=n(83209),g=n(53028),m=n(63368),_=n(48133),F=m.getOptions,y=m.defaultOptions,b=m.getLevelDOWN,v=m.dispatchError;function w(e,t){return"function"==typeof e?e:t}function E(e,t,n){if(!(this instanceof E))return new E(e,t,n);var r;if(o.call(this),this.setMaxListeners(1/0),"function"==typeof e?((t="object"==typeof t?t:{}).db=e,e=null):"object"==typeof e&&"function"==typeof e.db&&(t=e,e=null),"function"==typeof t&&(n=t,t={}),(!t||"function"!=typeof t.db)&&"string"!=typeof e){if(r=new p("Must provide a location for the database"),n)return process.nextTick((function(){n(r)}));throw r}t=F(this,t),this.options=i(y,t),this._status="new",a(this,"location",e,"e"),this.open(n)}function k(e){return function(t,n){b()[e](t,n||function(){})}}r(E,o),E.prototype.open=function(e){var t,n,o=this;return this.isOpen()?(e&&process.nextTick((function(){e(null,o)})),this):this._isOpening()?e&&this.once("open",(function(){e(null,o)})):(this.emit("opening"),this._status="opening",this.db=new s(this.location),t=this.options.db||b(),void(n=t(this.location)).open(this.options,(function(t){if(t)return v(o,new d(t),e);o.db.setDb(n),o.db=n,o._status="open",e&&e(null,o),o.emit("open"),o.emit("ready")})))},E.prototype.close=function(e){var t=this;if(this.isOpen())this._status="closing",this.db.close((function(){t._status="closed",t.emit("closed"),e&&e.apply(null,arguments)})),this.emit("closing"),this.db=null;else{if("closed"==this._status&&e)return process.nextTick(e);"closing"==this._status&&e?this.once("closed",e):this._isOpening()&&this.once("open",(function(){t.close(e)}))}},E.prototype.isOpen=function(){return"open"==this._status},E.prototype._isOpening=function(){return"opening"==this._status},E.prototype.isClosed=function(){return/^clos/.test(this._status)},E.prototype.get=function(e,t,n){var o,r=this;return"function"!=typeof(n=w(t,n))?v(this,new c("get() requires key and callback arguments")):this._isOpening()||this.isOpen()?(t=m.getOptions(this,t),o=m.encodeKey(e,t),t.asBuffer=m.isValueAsBuffer(t),void this.db.get(o,t,(function(o,i){if(o)return o=/notfound/i.test(o)?new l("Key not found in database ["+e+"]",o):new c(o),v(r,o,n);if(n){try{i=m.decodeValue(i,t)}catch(e){return n(new h(e))}n(null,i)}}))):v(this,new c("Database is not open"),n)},E.prototype.put=function(e,t,n,o){var r,i,a=this;return o=w(n,o),null==e||null==t?v(this,new u("put() requires key and value arguments"),o):this._isOpening()||this.isOpen()?(n=F(this,n),r=m.encodeKey(e,n),i=m.encodeValue(t,n),void this.db.put(r,i,n,(function(n){if(n)return v(a,new u(n),o);a.emit("put",e,t),o&&o()}))):v(this,new u("Database is not open"),o)},E.prototype.del=function(e,t,n){var o,r=this;return n=w(t,n),null==e?v(this,new u("del() requires a key argument"),n):this._isOpening()||this.isOpen()?(t=F(this,t),o=m.encodeKey(e,t),void this.db.del(o,t,(function(t){if(t)return v(r,new u(t),n);r.emit("del",e),n&&n()}))):v(this,new u("Database is not open"),n)},E.prototype.batch=function(e,t,n){var o,r,i,a=this;return arguments.length?(n=w(t,n),Array.isArray(e)?this._isOpening()||this.isOpen()?(t=F(this,t),o=t.keyEncoding,r=t.valueEncoding,i=e.map((function(e){if(void 0===e.type||void 0===e.key)return{};var n,i=e.keyEncoding||o,a=e.valueEncoding||e.encoding||r;return"utf8"!=i&&"binary"!=i||"utf8"!=a&&"binary"!=a?(n={type:e.type,key:m.encodeKey(e.key,t,e)},void 0!==e.value&&(n.value=m.encodeValue(e.value,t,e)),n):e})),void this.db.batch(i,t,(function(t){if(t)return v(a,new u(t),n);a.emit("batch",e),n&&n()}))):v(this,new u("Database is not open"),n):v(this,new u("batch() requires an array argument"),n)):new _(this)},E.prototype.approximateSize=function(e,t,n){var o,r,i=this;return null==e||null==t||"function"!=typeof n?v(this,new c("approximateSize() requires start, end and callback arguments"),n):(o=m.encodeKey(e,this.options),r=m.encodeKey(t,this.options),this._isOpening()||this.isOpen()?void this.db.approximateSize(o,r,(function(e,t){if(e)return v(i,new d(e),n);n&&n(null,t)})):v(this,new u("Database is not open"),n))},E.prototype.readStream=E.prototype.createReadStream=function(e){var t=this;return e=i(this.options,e),new f(e,this,(function(e){return t.db.iterator(e)}))},E.prototype.keyStream=E.prototype.createKeyStream=function(e){return this.createReadStream(i(e,{keys:!0,values:!1}))},E.prototype.valueStream=E.prototype.createValueStream=function(e){return this.createReadStream(i(e,{keys:!1,values:!0}))},E.prototype.writeStream=E.prototype.createWriteStream=function(e){return new g(i(e),this)},E.prototype.toString=function(){return"LevelUP"},e.exports=E,e.exports.copy=m.copy,e.exports.destroy=k("destroy"),e.exports.repair=k("repair")},83209:(e,t,n)=>{var o=n(11892).Readable,r=n(89539).inherits,i=n(47357),a=n(86667).EncodingError,s=n(63368),u={keys:!0,values:!0},c=function(e,t){return{key:s.decodeKey(e,this._options),value:s.decodeValue(t,this._options)}},l=function(e){return s.decodeKey(e,this._options)},d=function(e,t){return s.decodeValue(t,this._options)},h=function(){return null};function p(e,t,n){if(!(this instanceof p))return new p(e,t,n);o.call(this,{objectMode:!0,highWaterMark:e.highWaterMark}),this._db=t,e=this._options=i(u,e),this._keyEncoding=e.keyEncoding||e.encoding,this._valueEncoding=e.valueEncoding||e.encoding,void 0!==this._options.start&&(this._options.start=s.encodeKey(this._options.start,this._options)),void 0!==this._options.end&&(this._options.end=s.encodeKey(this._options.end,this._options)),"number"!=typeof this._options.limit&&(this._options.limit=-1),this._options.keyAsBuffer=s.isKeyAsBuffer(this._options),this._options.valueAsBuffer=s.isValueAsBuffer(this._options),this._makeData=this._options.keys&&this._options.values?c:this._options.keys?l:this._options.values?d:h;var r=this;this._db.isOpen()?this._iterator=n(this._options):this._db.once("ready",(function(){r._destroyed||(r._iterator=n(r._options))}))}r(p,o),p.prototype._read=function e(){var t=this;if(!t._db.isOpen())return t._db.once("ready",(function(){e.call(t)}));t._destroyed||t._iterator.next((function(e,n,o){if(e||void 0===n&&void 0===o)return e||t._destroyed||t.push(null),t._cleanup(e);try{o=t._makeData(n,o)}catch(e){return t._cleanup(new a(e))}t._destroyed||t.push(o)}))},p.prototype._cleanup=function(e){if(!this._destroyed){this._destroyed=!0;var t=this;e&&t.emit("error",e),t._iterator?t._iterator.end((function(){t._iterator=null,t.emit("close")})):t.emit("close")}},p.prototype.destroy=function(){this._cleanup()},p.prototype.toString=function(){return"LevelUP.ReadStream"},e.exports=p},63368:(e,t,n)=>{var o,r,i=n(47357),a=n(86667).LevelUPError,s=["hex","utf8","utf-8","ascii","binary","base64","ucs2","ucs-2","utf16le","utf-16le"],u={createIfMissing:!0,errorIfExists:!1,keyEncoding:"utf8",valueEncoding:"utf8",compression:!0},c=function(){function e(e){return null==e||Buffer.isBuffer(e)}var t={};return t.utf8=t["utf-8"]={encode:function(t){return e(t)?t:String(t)},decode:function(e){return e},buffer:!1,type:"utf8"},t.json={encode:JSON.stringify,decode:JSON.parse,buffer:!1,type:"json"},s.forEach((function(n){t[n]||(t[n]={encode:function(t){return e(t)?t:new Buffer(t,n)},decode:function(e){return process.browser?e.toString(n):e},buffer:!0,type:n})})),t}(),l=(r={},s.forEach((function(e){r[e]={valueEncoding:e}})),r);function d(e,t){var n=t&&t.keyEncoding||e.keyEncoding||"utf8";return c[n]||n}function h(e,t){var n=t&&(t.valueEncoding||t.encoding)||e.valueEncoding||e.encoding||"utf8";return c[n]||n}e.exports={defaultOptions:u,copy:function(e,t,n){e.readStream().pipe(t.writeStream()).on("close",n||function(){}).on("error",n||function(e){throw e})},getOptions:function(e,t){var n="string"==typeof t;return!n&&t&&t.encoding&&!t.valueEncoding&&(t.valueEncoding=t.encoding),i(e&&e.options||{},n?l[t]||l[u.valueEncoding]:t)},getLevelDOWN:function(){if(o)return o;var e,t=n(68232).v6.ct,r="Could not locate LevelDOWN, try `npm install leveldown`";try{e=n(94093).version}catch(e){throw new a(r)}if(!n(61695).satisfies(e,t))throw new a("Installed version of LevelDOWN ("+e+") does not match required version ("+t+")");try{return o=n(70131)}catch(e){throw new a(r)}},dispatchError:function(e,t,n){return"function"==typeof n?n(t):e.emit("error",t)},encodeKey:function(e,t,n){return d(t,n).encode(e)},encodeValue:function(e,t,n){return h(t,n).encode(e)},isValueAsBuffer:function(e,t){return h(e,t).buffer},isKeyAsBuffer:function(e,t){return d(e,t).buffer},decodeValue:function(e,t){return h(t).decode(e)},decodeKey:function(e,t){return d(t).decode(e)}}},53028:(e,t,n)=>{var o=n(42830).Stream,r=n(89539).inherits,i=n(47357),a=n(10022),s=n.g.setImmediate||process.nextTick,u=n(63368).getOptions,c={type:"put"};function l(e,t){if(!(this instanceof l))return new l(e,t);o.call(this),this._options=i(c,u(t,e)),this._db=t,this._buffer=[],this._status="init",this._end=!1,this.writable=!0,this.readable=!1;var n=this,r=function(){n.writable&&(n._status="ready",n.emit("ready"),n._process())};t.isOpen()?s(r):t.once("ready",r)}r(l,o),l.prototype.write=function(e){return!(!this.writable||(this._buffer.push(e),"init"!=this._status&&this._processDelayed(),this._options.maxBufferLength&&this._buffer.length>this._options.maxBufferLength&&(this._writeBlock=!0,1)))},l.prototype.end=function(e){var t=this;e&&this.write(e),s((function(){t._end=!0,t._process()}))},l.prototype.destroy=function(){this.writable=!1,this.end()},l.prototype.destroySoon=function(){this.end()},l.prototype.add=function(e){if(e.props)return e.props.Directory?e.pipe(this._db.writeStream(this._options)):(e.props.File||e.File||"File"==e.type)&&this._write(e),!0},l.prototype._processDelayed=function(){var e=this;s((function(){e._process()}))},l.prototype._process=function(){var e,t=this;if("ready"==t._status||!t.writable)return t._buffer.length&&t.writable?(t._status="writing",e=t._buffer,t._buffer=[],t._db.batch(e.map((function(e){return{type:e.type||t._options.type,key:e.key,value:e.value,keyEncoding:e.keyEncoding||t._options.keyEncoding,valueEncoding:e.valueEncoding||e.encoding||t._options.valueEncoding}})),(function(e){if(t.writable){if("closed"!=t._status&&(t._status="ready"),e)return t.writable=!1,t.emit("error",e);t._process()}})),void(t._writeBlock&&(t._writeBlock=!1,t.emit("drain")))):void(t._end&&"closed"!=t._status&&(t._status="closed",t.writable=!1,t.emit("close")));t._buffer.length&&"closed"!=t._status&&t._processDelayed()},l.prototype._write=function(e){var t=e.path||e.props.path,n=this;t&&e.pipe(a((function(e,o){if(e)return n.writable=!1,n.emit("error",e);n._options.fstreamRoot&&t.indexOf(n._options.fstreamRoot)>-1&&(t=t.substr(n._options.fstreamRoot.length+1)),n.write({key:t,value:o.slice(0)})})))},l.prototype.toString=function(){return"LevelUP.WriteStream"},e.exports=l},65238:e=>{e.exports=Array.isArray||function(e){return"[object Array]"==Object.prototype.toString.call(e)}},30115:function(e){var t;t=function(){var e="function"==typeof Object.defineProperty?function(e,t,n){return Object.defineProperty(e,t,n),e}:function(e,t,n){return e[t]=n.value,e};return function(t,n,o,r){var i;if(r=function(e,t){var n="object"==typeof t,o=!n&&"string"==typeof t,r=function(e){return n?!!t[e]:!!o&&t.indexOf(e[0])>-1};return{enumerable:r("enumerable"),configurable:r("configurable"),writable:r("writable"),value:e}}(o,r),"object"==typeof n){for(i in n)Object.hasOwnProperty.call(n,i)&&(r.value=n[i],e(t,i,r));return t}return e(t,n,r)}},e.exports?e.exports=t():this.prr=t()},32422:(e,t,n)=>{e.exports=s;var o=Object.keys||function(e){var t=[];for(var n in e)t.push(n);return t},r=n(16497);r.inherits=n(35717);var i=n(66810),a=n(54160);function s(e){if(!(this instanceof s))return new s(e);i.call(this,e),a.call(this,e),e&&!1===e.readable&&(this.readable=!1),e&&!1===e.writable&&(this.writable=!1),this.allowHalfOpen=!0,e&&!1===e.allowHalfOpen&&(this.allowHalfOpen=!1),this.once("end",u)}function u(){this.allowHalfOpen||this._writableState.ended||process.nextTick(this.end.bind(this))}r.inherits(s,i),function(e,t){for(var n=0,o=e.length;n{e.exports=i;var o=n(31036),r=n(16497);function i(e){if(!(this instanceof i))return new i(e);o.call(this,e)}r.inherits=n(35717),r.inherits(i,o),i.prototype._transform=function(e,t,n){n(null,e)}},66810:(e,t,n)=>{e.exports=l;var o=n(65238),r=n(48764).Buffer;l.ReadableState=c;var i=n(17187).EventEmitter;i.listenerCount||(i.listenerCount=function(e,t){return e.listeners(t).length});var a,s=n(42830),u=n(16497);function c(e,t){var o=(e=e||{}).highWaterMark;this.highWaterMark=o||0===o?o:16384,this.highWaterMark=~~this.highWaterMark,this.buffer=[],this.length=0,this.pipes=null,this.pipesCount=0,this.flowing=!1,this.ended=!1,this.endEmitted=!1,this.reading=!1,this.calledRead=!1,this.sync=!0,this.needReadable=!1,this.emittedReadable=!1,this.readableListening=!1,this.objectMode=!!e.objectMode,this.defaultEncoding=e.defaultEncoding||"utf8",this.ranOut=!1,this.awaitDrain=0,this.readingMore=!1,this.decoder=null,this.encoding=null,e.encoding&&(a||(a=n(45951).s),this.decoder=new a(e.encoding),this.encoding=e.encoding)}function l(e){if(!(this instanceof l))return new l(e);this._readableState=new c(e,this),this.readable=!0,s.call(this)}function d(e,t,n,o,i){var a=function(e,t){var n=null;return r.isBuffer(t)||"string"==typeof t||null==t||e.objectMode||(n=new TypeError("Invalid non-string/buffer chunk")),n}(t,n);if(a)e.emit("error",a);else if(null==n)t.reading=!1,t.ended||function(e,t){if(t.decoder&&!t.ended){var n=t.decoder.end();n&&n.length&&(t.buffer.push(n),t.length+=t.objectMode?1:n.length)}t.ended=!0,t.length>0?f(e):b(e)}(e,t);else if(t.objectMode||n&&n.length>0)if(t.ended&&!i){var s=new Error("stream.push() after EOF");e.emit("error",s)}else t.endEmitted&&i?(s=new Error("stream.unshift() after end event"),e.emit("error",s)):(!t.decoder||i||o||(n=t.decoder.write(n)),t.length+=t.objectMode?1:n.length,i?t.buffer.unshift(n):(t.reading=!1,t.buffer.push(n)),t.needReadable&&f(e),function(e,t){t.readingMore||(t.readingMore=!0,process.nextTick((function(){!function(e,t){for(var n=t.length;!t.reading&&!t.flowing&&!t.ended&&t.lengtht.highWaterMark&&(t.highWaterMark=function(e){if(e>=h)e=h;else{e--;for(var t=1;t<32;t<<=1)e|=e>>t;e++}return e}(e)),e>t.length?t.ended?t.length:(t.needReadable=!0,0):e)}function f(e){var t=e._readableState;t.needReadable=!1,t.emittedReadable||(t.emittedReadable=!0,t.sync?process.nextTick((function(){g(e)})):g(e))}function g(e){e.emit("readable")}function m(e){var t,n=e._readableState;function o(e,o,r){!1===e.write(t)&&n.awaitDrain++}for(n.awaitDrain=0;n.pipesCount&&null!==(t=e.read());)if(1===n.pipesCount?o(n.pipes):v(n.pipes,o),e.emit("data",t),n.awaitDrain>0)return;if(0===n.pipesCount)return n.flowing=!1,void(i.listenerCount(e,"data")>0&&F(e));n.ranOut=!0}function _(){this._readableState.ranOut&&(this._readableState.ranOut=!1,m(this))}function F(e,t){if(e._readableState.flowing)throw new Error("Cannot switch to old mode now.");var n=t||!1,o=!1;e.readable=!0,e.pipe=s.prototype.pipe,e.on=e.addListener=s.prototype.on,e.on("readable",(function(){var t;for(o=!0;!n&&null!==(t=e.read());)e.emit("data",t);null===t&&(o=!1,e._readableState.needReadable=!0)})),e.pause=function(){n=!0,this.emit("pause")},e.resume=function(){n=!1,o?process.nextTick((function(){e.emit("readable")})):this.read(0),this.emit("resume")},e.emit("readable")}function y(e,t){var n,o=t.buffer,i=t.length,a=!!t.decoder,s=!!t.objectMode;if(0===o.length)return null;if(0===i)n=null;else if(s)n=o.shift();else if(!e||e>=i)n=a?o.join(""):r.concat(o,i),o.length=0;else if(e0)throw new Error("endReadable called on non-empty stream");!t.endEmitted&&t.calledRead&&(t.ended=!0,process.nextTick((function(){t.endEmitted||0!==t.length||(t.endEmitted=!0,e.readable=!1,e.emit("end"))})))}function v(e,t){for(var n=0,o=e.length;n0)&&(t.emittedReadable=!1),0===e&&t.needReadable&&(t.length>=t.highWaterMark||t.ended))return f(this),null;if(0===(e=p(e,t))&&t.ended)return n=null,t.length>0&&t.decoder&&(n=y(e,t),t.length-=n.length),0===t.length&&b(this),n;var r=t.needReadable;return t.length-e<=t.highWaterMark&&(r=!0),(t.ended||t.reading)&&(r=!1),r&&(t.reading=!0,t.sync=!0,0===t.length&&(t.needReadable=!0),this._read(t.highWaterMark),t.sync=!1),r&&!t.reading&&(e=p(o,t)),null===(n=e>0?y(e,t):null)&&(t.needReadable=!0,e=0),t.length-=e,0!==t.length||t.ended||(t.needReadable=!0),t.ended&&!t.endEmitted&&0===t.length&&b(this),n},l.prototype._read=function(e){this.emit("error",new Error("not implemented"))},l.prototype.pipe=function(e,t){var n=this,r=this._readableState;switch(r.pipesCount){case 0:r.pipes=e;break;case 1:r.pipes=[r.pipes,e];break;default:r.pipes.push(e)}r.pipesCount+=1;var a=t&&!1===t.end||e===process.stdout||e===process.stderr?l:u;function s(e){e===n&&l()}function u(){e.end()}r.endEmitted?process.nextTick(a):n.once("end",a),e.on("unpipe",s);var c=function(e){return function(){var t=e._readableState;t.awaitDrain--,0===t.awaitDrain&&m(e)}}(n);function l(){e.removeListener("close",h),e.removeListener("finish",p),e.removeListener("drain",c),e.removeListener("error",d),e.removeListener("unpipe",s),n.removeListener("end",u),n.removeListener("end",l),e._writableState&&!e._writableState.needDrain||c()}function d(t){f(),e.removeListener("error",d),0===i.listenerCount(e,"error")&&e.emit("error",t)}function h(){e.removeListener("finish",p),f()}function p(){e.removeListener("close",h),f()}function f(){n.unpipe(e)}return e.on("drain",c),e._events&&e._events.error?o(e._events.error)?e._events.error.unshift(d):e._events.error=[d,e._events.error]:e.on("error",d),e.once("close",h),e.once("finish",p),e.emit("pipe",n),r.flowing||(this.on("readable",_),r.flowing=!0,process.nextTick((function(){m(n)}))),e},l.prototype.unpipe=function(e){var t=this._readableState;if(0===t.pipesCount)return this;if(1===t.pipesCount)return e&&e!==t.pipes||(e||(e=t.pipes),t.pipes=null,t.pipesCount=0,this.removeListener("readable",_),t.flowing=!1,e&&e.emit("unpipe",this)),this;if(!e){var n=t.pipes,o=t.pipesCount;t.pipes=null,t.pipesCount=0,this.removeListener("readable",_),t.flowing=!1;for(var r=0;r{e.exports=a;var o=n(32422),r=n(16497);function i(e,t){this.afterTransform=function(e,n){return function(e,t,n){var o=e._transformState;o.transforming=!1;var r=o.writecb;if(!r)return e.emit("error",new Error("no writecb in Transform class"));o.writechunk=null,o.writecb=null,null!=n&&e.push(n),r&&r(t);var i=e._readableState;i.reading=!1,(i.needReadable||i.length{e.exports=u;var o=n(48764).Buffer;u.WritableState=s;var r=n(16497);r.inherits=n(35717);var i=n(42830);function a(e,t,n){this.chunk=e,this.encoding=t,this.callback=n}function s(e,t){var n=(e=e||{}).highWaterMark;this.highWaterMark=n||0===n?n:16384,this.objectMode=!!e.objectMode,this.highWaterMark=~~this.highWaterMark,this.needDrain=!1,this.ending=!1,this.ended=!1,this.finished=!1;var o=!1===e.decodeStrings;this.decodeStrings=!o,this.defaultEncoding=e.defaultEncoding||"utf8",this.length=0,this.writing=!1,this.sync=!0,this.bufferProcessing=!1,this.onwrite=function(e){!function(e,t){var n=e._writableState,o=n.sync,r=n.writecb;if(function(e){e.writing=!1,e.writecb=null,e.length-=e.writelen,e.writelen=0}(n),t)!function(e,t,n,o,r){n?process.nextTick((function(){r(o)})):r(o),e._writableState.errorEmitted=!0,e.emit("error",o)}(e,0,o,t,r);else{var i=d(0,n);i||n.bufferProcessing||!n.buffer.length||function(e,t){t.bufferProcessing=!0;for(var n=0;n{var o=n(42830);(t=e.exports=n(66810)).Stream=o,t.Readable=t,t.Writable=n(54160),t.Duplex=n(32422),t.Transform=n(31036),t.PassThrough=n(78264),process.browser||"disable"!==process.env.READABLE_STREAM||(e.exports=n(42830))},45951:(e,t,n)=>{var o=n(48764).Buffer,r=o.isEncoding||function(e){switch(e&&e.toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":case"raw":return!0;default:return!1}},i=t.s=function(e){switch(this.encoding=(e||"utf8").toLowerCase().replace(/[-_]/,""),function(e){if(e&&!r(e))throw new Error("Unknown encoding: "+e)}(e),this.encoding){case"utf8":this.surrogateSize=3;break;case"ucs2":case"utf16le":this.surrogateSize=2,this.detectIncompleteChar=s;break;case"base64":this.surrogateSize=3,this.detectIncompleteChar=u;break;default:return void(this.write=a)}this.charBuffer=new o(6),this.charReceived=0,this.charLength=0};function a(e){return e.toString(this.encoding)}function s(e){this.charReceived=e.length%2,this.charLength=this.charReceived?2:0}function u(e){this.charReceived=e.length%3,this.charLength=this.charReceived?3:0}i.prototype.write=function(e){for(var t="";this.charLength;){var n=e.length>=this.charLength-this.charReceived?this.charLength-this.charReceived:e.length;if(e.copy(this.charBuffer,this.charReceived,0,n),this.charReceived+=n,this.charReceived=55296&&o<=56319)){if(this.charReceived=this.charLength=0,0===e.length)return t;break}this.charLength+=this.surrogateSize,t=""}this.detectIncompleteChar(e);var o,r=e.length;if(this.charLength&&(e.copy(this.charBuffer,0,e.length-this.charReceived,r),r-=this.charReceived),r=(t+=e.toString(this.encoding,0,r)).length-1,(o=t.charCodeAt(r))>=55296&&o<=56319){var i=this.surrogateSize;return this.charLength+=i,this.charReceived+=i,this.charBuffer.copy(this.charBuffer,i,0,i),e.copy(this.charBuffer,0,0,i),t.substring(0,r)}return t},i.prototype.detectIncompleteChar=function(e){for(var t=e.length>=3?3:e.length;t>0;t--){var n=e[e.length-t];if(1==t&&n>>5==6){this.charLength=2;break}if(t<=2&&n>>4==14){this.charLength=3;break}if(t<=3&&n>>3==30){this.charLength=4;break}}this.charReceived=t},i.prototype.end=function(e){var t="";if(e&&e.length&&(t=this.write(e)),this.charReceived){var n=this.charReceived,o=this.charBuffer,r=this.encoding;t+=o.slice(0,n).toString(r)}return t}},47357:e=>{e.exports=function(){for(var e={},t=0;t{"use strict";e.exports=JSON.parse('{"v6":{"ct":"~0.10.0"}}')},58303:(e,t,n)=>{var o=n(31934);e.exports=function(e){var t=o(e,"line-height"),n=parseFloat(t,10);if(t===n+""){var r=e.style.lineHeight;e.style.lineHeight=t+"em",t=o(e,"line-height"),n=parseFloat(t,10),r?e.style.lineHeight=r:delete e.style.lineHeight}if(-1!==t.indexOf("pt")?(n*=4,n/=3):-1!==t.indexOf("mm")?(n*=96,n/=25.4):-1!==t.indexOf("cm")?(n*=96,n/=2.54):-1!==t.indexOf("in")?n*=96:-1!==t.indexOf("pc")&&(n*=16),n=Math.round(n),"normal"===t){var i=e.nodeName,a=document.createElement(i);a.innerHTML=" ","TEXTAREA"===i.toUpperCase()&&a.setAttribute("rows","1");var s=o(e,"font-size");a.style.fontSize=s,a.style.padding="0px",a.style.border="0px";var u=document.body;u.appendChild(a),n=a.offsetHeight,u.removeChild(a)}return n}},87100:(e,t,n)=>{"use strict";var o=n(67294),r=n(8425);function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function a(e,t){for(var n=0;ne.length)&&(t=e.length);for(var n=0,o=new Array(t);n2&&void 0!==arguments[2]?arguments[2]:0;if(0===o.Children.count(e.props.children))return e;var r=[];o.Children.forEach(e.props.children,(function(e){"string"==typeof e?(n+=1,r.push.apply(r,l(p(e,t)))):o.isValidElement(e)?"string"==typeof e.type&&t.ignoreTags.indexOf(e.type.toUpperCase())>=0?r.push(e):r.push(f(e,t,++n)):r.push(e)}));var i={key:"linkified-element-".concat(n)};for(var a in e.props)i[a]=e.props[a];return o.cloneElement(e,i,r)}var g=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&u(e,t)}(p,e);var t,n,r,l,d=(r=p,l=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,t=s(r);if(l){var n=s(this).constructor;e=Reflect.construct(t,arguments,n)}else e=t.apply(this,arguments);return c(this,e)});function p(){return i(this,p),d.apply(this,arguments)}return t=p,(n=[{key:"render",value:function(){var e={key:"linkified-element-0"};for(var t in this.props)"options"!==t&&"tagName"!==t&&(e[t]=this.props[t]);var n=new h(this.props.options),r=this.props.tagName||"span";return f(o.createElement(r,e),n,0)}}])&&a(t.prototype,n),p}(o.Component);e.exports=g},8425:(e,t)=>{"use strict";function n(e){this.j={},this.jr=[],this.jd=null,this.t=e}Object.defineProperty(t,"__esModule",{value:!0}),n.prototype={accepts:function(){return!!this.t},tt:function(e,t){if(t&&t.j)return this.j[e]=t,t;var n=t,r=this.j[e];if(r)return n&&(r.t=n),r;r=o();var i=s(this,e);return i?(Object.assign(r.j,i.j),r.jr.append(i.jr),r.jr=i.jd,r.t=n||i.t):r.t=n,this.j[e]=r,r}};var o=function(){return new n},r=function(e){return new n(e)},i=function(e,t,n){e.j[t]||(e.j[t]=n)},a=function(e,t,n){e.jr.push([t,n])},s=function(e,t){var n=e.j[t];if(n)return n;for(var o=0;o=s)return[];for(;a0&&void 0!==arguments[0]?arguments[0]:[],t=o(),n=r(y),s=r(d),P=o(),G=r(x),$=[[z,s],[j,s],[q,s]],H=function(){var e=r(d);return e.j={"-":P},e.jr=[].concat($),e},V=function(e){var t=H();return t.t=e,t};c(t,[["@",r(f)],[".",r(m)],["+",r(b)],["#",r(v)],["?",r(w)],["/",r(E)],["_",r(k)],[":",r(g)],["{",r(C)],["[",r(A)],["<",r(T)],["(",r(R)],["}",r(I)],["]",r(M)],[">",r(O)],[")",r(B)],["&",r(N)]]),u(t,[",",";","!",'"',"'"],r(_)),i(t,"\n",r(F)),a(t,K,G),i(G,"\n",o()),a(G,K,G);for(var W=0;W2&&void 0!==arguments[2]?arguments[2]:{},o=Object.create(e.prototype);for(var r in n)o[r]=n[r];o.constructor=t,t.prototype=o}(Z,n,t),n}Z.prototype={t:"token",isLink:!1,toString:function(){return this.v},toHref:function(){return this.toString()},startIndex:function(){return this.tk[0].s},endIndex:function(){return this.tk[this.tk.length-1].e},toObject:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:H.defaultProtocol;return{type:this.t,value:this.v,isLink:this.isLink,href:this.toHref(e),start:this.startIndex(),end:this.endIndex()}}};var J=X("email",{isLink:!0}),Q=X("email",{isLink:!0,toHref:function(){return"mailto:"+this.toString()}}),ee=X("text"),te=X("nl"),ne=X("url",{isLink:!0,toHref:function(){for(var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:H.defaultProtocol,t=this.tk,n=!1,o=!1,r=[],i=0;t[i].t===D;)n=!0,r.push(t[i].v),i++;for(;t[i].t===E;)o=!0,r.push(t[i].v),i++;for(;i=0&&p++,r++,d++;if(p<0)for(var f=r-d;f0&&(i.push(ie(ee,t,a)),a=[]),r-=p,d-=p;var g=h.t,m=n.slice(r-d,r);i.push(ie(g,t,m))}}return a.length>0&&i.push(ie(ee,t,a)),i}(se.parser.start,e,function(e,t){for(var n=Array.from(t.replace(/[A-Z]/g,(function(e){return e.toLowerCase()}))),o=n.length,r=[],i=0,a=0;a=0&&(h+=n[a].length,p++),l+=n[a].length,i+=n[a].length,a++;h<0||(i-=h,a-=p,l-=h,r.push({t:d.t,v:t.substr(i-l,l),s:i-l,e:i}))}return r}(se.scanner.start,e))}t.find=function(e){for(var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null,n=ce(e),o=[],r=0;r1&&void 0!==arguments[1]?arguments[1]:null,n=ce(e);return 1===n.length&&n[0].isLink&&(!t||n[0].t===t)},t.tokenize=ce},28175:(e,t,n)=>{e.exports=n(87100)},2043:function(e,t,n){var o,r;!function(i,a){"use strict";void 0===(r="function"==typeof(o=function(){var e=function(){},t="undefined",n=typeof window!==t&&typeof window.navigator!==t&&/Trident\/|MSIE /.test(window.navigator.userAgent),o=["trace","debug","info","warn","error"];function r(e,t){var n=e[t];if("function"==typeof n.bind)return n.bind(e);try{return Function.prototype.bind.call(n,e)}catch(t){return function(){return Function.prototype.apply.apply(n,[e,arguments])}}}function i(){console.log&&(console.log.apply?console.log.apply(console,arguments):Function.prototype.apply.apply(console.log,[console,arguments])),console.trace&&console.trace()}function a(o){return"debug"===o&&(o="log"),typeof console!==t&&("trace"===o&&n?i:void 0!==console[o]?r(console,o):void 0!==console.log?r(console,"log"):e)}function s(t,n){for(var r=0;r=0&&n<=a.levels.SILENT))throw"log.setLevel() called with invalid level: "+n;if(i=n,!1!==r&&function(e){var n=(o[e]||"silent").toUpperCase();if(typeof window!==t&&u){try{return void(window.localStorage[u]=n)}catch(e){}try{window.document.cookie=encodeURIComponent(u)+"="+n+";"}catch(e){}}}(n),s.call(a,n,e),typeof console===t&&n{function n(e){return void 0!==e&&""!==e}function o(e,t){return Object.hasOwnProperty.call(e,t)}function r(e,t){return Object.hasOwnProperty.call(e,t)&&t}t.compare=function(e,t){if(Buffer.isBuffer(e)){for(var n=Math.min(e.length,t.length),o=0;ot?1:0};var i=t.lowerBoundKey=function(e){return r(e,"gt")||r(e,"gte")||r(e,"min")||(e.reverse?r(e,"end"):r(e,"start"))||void 0},a=t.lowerBound=function(e,t){var n=i(e);return n?e[n]:t},s=t.lowerBoundInclusive=function(e){return!o(e,"gt")},u=t.upperBoundInclusive=function(e){return!o(e,"lt")},c=t.lowerBoundExclusive=function(e){return!s(e)},l=t.upperBoundExclusive=function(e){return!u(e)},d=t.upperBoundKey=function(e){return r(e,"lt")||r(e,"lte")||r(e,"max")||(e.reverse?r(e,"start"):r(e,"end"))||void 0},h=t.upperBound=function(e,t){var n=d(e);return n?e[n]:t};function p(e){return e}t.start=function(e,t){return e.reverse?h(e,t):a(e,t)},t.end=function(e,t){return e.reverse?a(e,t):h(e,t)},t.startInclusive=function(e){return e.reverse?u(e):s(e)},t.endInclusive=function(e){return e.reverse?s(e):u(e)},t.toLtgt=function(e,n,r,i,a){n=n||{},r=r||p;var s=arguments.length>3,u=t.lowerBoundKey(e),c=t.upperBoundKey(e);return u?"gt"===u?n.gt=r(e.gt,!1):n.gte=r(e[u],!1):s&&(n.gte=r(i,!1)),c?"lt"===c?n.lt=r(e.lt,!0):n.lte=r(e[c],!0):s&&(n.lte=r(a,!0)),null!=e.reverse&&(n.reverse=!!e.reverse),o(n,"max")&&delete n.max,o(n,"min")&&delete n.min,o(n,"start")&&delete n.start,o(n,"end")&&delete n.end,n},t.contains=function(e,o,r){r=r||t.compare;var i=a(e);if(n(i)&&((s=r(o,i))<0||0===s&&c(e)))return!1;var s,u=h(e);return!n(u)||!((s=r(o,u))>0||0===s&&l(e))},t.filter=function(e,n){return function(o){return t.contains(e,o,n)}}},78234:(e,t,n)=>{"use strict";var o=n(96464);e.exports=function(e,t){for(var n,l,d,h,p,f,g,m,_,F,y,b,v=t||{},w=!1!==v.padding,E=!1!==v.delimiterStart,k=!1!==v.delimiterEnd,D=(v.align||[]).concat(),S=!1!==v.alignDelimiters,x=[],C=v.stringLength||u,A=-1,T=e.length,R=[],I=[],M=[],O=[],B=[],N=0;++AN&&(N=d);++lh)&&(B[l]=p)),M.push(f);R[A]=M,I[A]=O}if(l=-1,d=N,"object"==typeof D&&"length"in D)for(;++lB[l]&&(B[l]=p),O[l]=p),M[l]=f;for(R.splice(1,0,M),I.splice(1,0,O),A=-1,T=R.length,g=[];++A{"use strict";let n,o,r;Object.defineProperty(t,"__esModule",{value:!0}),t.RoomType=t.RoomCreateTypeField=t.MsgType=t.EventType=void 0,t.EventType=n,function(e){e.RoomCanonicalAlias="m.room.canonical_alias",e.RoomCreate="m.room.create",e.RoomJoinRules="m.room.join_rules",e.RoomMember="m.room.member",e.RoomThirdPartyInvite="m.room.third_party_invite",e.RoomPowerLevels="m.room.power_levels",e.RoomName="m.room.name",e.RoomTopic="m.room.topic",e.RoomAvatar="m.room.avatar",e.RoomPinnedEvents="m.room.pinned_events",e.RoomEncryption="m.room.encryption",e.RoomHistoryVisibility="m.room.history_visibility",e.RoomGuestAccess="m.room.guest_access",e.RoomServerAcl="m.room.server_acl",e.RoomTombstone="m.room.tombstone",e.RoomAliases="m.room.aliases",e.SpaceChild="m.space.child",e.SpaceParent="m.space.parent",e.RoomRedaction="m.room.redaction",e.RoomMessage="m.room.message",e.RoomMessageEncrypted="m.room.encrypted",e.Sticker="m.sticker",e.CallInvite="m.call.invite",e.CallCandidates="m.call.candidates",e.CallAnswer="m.call.answer",e.CallHangup="m.call.hangup",e.CallReject="m.call.reject",e.CallSelectAnswer="m.call.select_answer",e.CallNegotiate="m.call.negotiate",e.CallReplaces="m.call.replaces",e.CallAssertedIdentity="m.call.asserted_identity",e.CallAssertedIdentityPrefix="org.matrix.call.asserted_identity",e.KeyVerificationRequest="m.key.verification.request",e.KeyVerificationStart="m.key.verification.start",e.KeyVerificationCancel="m.key.verification.cancel",e.KeyVerificationMac="m.key.verification.mac",e.KeyVerificationDone="m.key.verification.done",e.RoomMessageFeedback="m.room.message.feedback",e.Reaction="m.reaction",e.Typing="m.typing",e.Receipt="m.receipt",e.Presence="m.presence",e.FullyRead="m.fully_read",e.Tag="m.tag",e.PushRules="m.push_rules",e.Direct="m.direct",e.IgnoredUserList="m.ignored_user_list",e.RoomKey="m.room_key",e.RoomKeyRequest="m.room_key_request",e.ForwardedRoomKey="m.forwarded_room_key",e.Dummy="m.dummy"}(n||(t.EventType=n={})),t.MsgType=o,function(e){e.Text="m.text",e.Emote="m.emote",e.Notice="m.notice",e.Image="m.image",e.File="m.file",e.Audio="m.audio",e.Location="m.location",e.Video="m.video"}(o||(t.MsgType=o={})),t.RoomCreateTypeField="type",t.RoomType=r,function(e){e.Space="m.space"}(r||(t.RoomType=r={}))},20771:(e,t,n)=>{"use strict";var o=n(95318);Object.defineProperty(t,"__esModule",{value:!0}),t.ReEmitter=void 0;var r=o(n(59713));t.ReEmitter=class{constructor(e){(0,r.default)(this,"target",void 0),this.target=e}reEmit(e,t){for(const n of t){const t=(...t)=>{"error"===n&&0===this.target.listenerCount("error")||this.target.emit(n,...t,e)};e.on(n,t)}}}},79118:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.AutoDiscovery=void 0;var o=n(7434),r=n(8575);class i{static get ERROR_INVALID(){return"Invalid homeserver discovery response"}static get ERROR_GENERIC_FAILURE(){return"Failed to get autodiscovery configuration from server"}static get ERROR_INVALID_HS_BASE_URL(){return"Invalid base_url for m.homeserver"}static get ERROR_INVALID_HOMESERVER(){return"Homeserver URL does not appear to be a valid Matrix homeserver"}static get ERROR_INVALID_IS_BASE_URL(){return"Invalid base_url for m.identity_server"}static get ERROR_INVALID_IDENTITY_SERVER(){return"Identity server URL does not appear to be a valid identity server"}static get ERROR_INVALID_IS(){return"Invalid identity server discovery response"}static get ERROR_MISSING_WELLKNOWN(){return"No .well-known JSON file found"}static get ERROR_INVALID_JSON(){return"Invalid JSON"}static get ALL_ERRORS(){return[i.ERROR_INVALID,i.ERROR_GENERIC_FAILURE,i.ERROR_INVALID_HS_BASE_URL,i.ERROR_INVALID_HOMESERVER,i.ERROR_INVALID_IS_BASE_URL,i.ERROR_INVALID_IDENTITY_SERVER,i.ERROR_INVALID_IS,i.ERROR_MISSING_WELLKNOWN,i.ERROR_INVALID_JSON]}static get FAIL_ERROR(){return"FAIL_ERROR"}static get FAIL_PROMPT(){return"FAIL_PROMPT"}static get PROMPT(){return"PROMPT"}static get SUCCESS(){return"SUCCESS"}static async fromDiscoveryConfig(e){const t={"m.homeserver":{state:i.FAIL_ERROR,error:i.ERROR_INVALID,base_url:null},"m.identity_server":{state:i.PROMPT,error:null,base_url:null}};if(!e||!e["m.homeserver"])return o.logger.error("No m.homeserver key in config"),t["m.homeserver"].state=i.FAIL_PROMPT,t["m.homeserver"].error=i.ERROR_INVALID,Promise.resolve(t);if(!e["m.homeserver"].base_url)return o.logger.error("No m.homeserver base_url in config"),t["m.homeserver"].state=i.FAIL_PROMPT,t["m.homeserver"].error=i.ERROR_INVALID_HS_BASE_URL,Promise.resolve(t);const n=this._sanitizeWellKnownUrl(e["m.homeserver"].base_url);if(!n)return o.logger.error("Invalid base_url for m.homeserver"),t["m.homeserver"].error=i.ERROR_INVALID_HS_BASE_URL,Promise.resolve(t);const r=await this._fetchWellKnownObject(`${n}/_matrix/client/versions`);if(!r||!r.raw.versions)return o.logger.error("Invalid /versions response"),t["m.homeserver"].error=i.ERROR_INVALID_HOMESERVER,t["m.homeserver"].base_url=n,Promise.resolve(t);t["m.homeserver"]={state:i.SUCCESS,error:null,base_url:n};let a="";if(e["m.identity_server"]){const n={"m.homeserver":t["m.homeserver"],"m.identity_server":{state:i.FAIL_PROMPT,error:i.ERROR_INVALID_IS,base_url:null}};if(a=this._sanitizeWellKnownUrl(e["m.identity_server"].base_url),!a)return o.logger.error("Invalid base_url for m.identity_server"),n["m.identity_server"].error=i.ERROR_INVALID_IS_BASE_URL,Promise.resolve(n);const r=await this._fetchWellKnownObject(`${a}/_matrix/identity/api/v1`);if(!r||!r.raw||"SUCCESS"!==r.action)return o.logger.error("Invalid /api/v1 response"),n["m.identity_server"].error=i.ERROR_INVALID_IDENTITY_SERVER,n["m.identity_server"].base_url=a,Promise.resolve(n)}return a&&a.length>0&&(t["m.identity_server"]={state:i.SUCCESS,error:null,base_url:a}),Object.keys(e).map((n=>{if("m.homeserver"===n||"m.identity_server"===n){const o=["error","state","base_url"];for(const r of Object.keys(e[n]))o.includes(r)||(t[n][r]=e[n][r])}else t[n]=e[n]})),Promise.resolve(t)}static async findClientConfig(e){if(!e||"string"!=typeof e||0===e.length)throw new Error("'domain' must be a string of non-zero length");const t={"m.homeserver":{state:i.FAIL_ERROR,error:i.ERROR_INVALID,base_url:null},"m.identity_server":{state:i.PROMPT,error:null,base_url:null}},n=await this._fetchWellKnownObject(`https://${e}/.well-known/matrix/client`);return n&&"SUCCESS"===n.action?i.fromDiscoveryConfig(n.raw):(o.logger.error("No response or error when parsing .well-known"),n.reason&&o.logger.error(n.reason),"IGNORE"===n.action?t["m.homeserver"]={state:i.PROMPT,error:null,base_url:null}:(t["m.homeserver"].state=i.FAIL_PROMPT,t["m.homeserver"].error=i.ERROR_INVALID),Promise.resolve(t))}static async getRawClientConfig(e){if(!e||"string"!=typeof e||0===e.length)throw new Error("'domain' must be a string of non-zero length");const t=await this._fetchWellKnownObject(`https://${e}/.well-known/matrix/client`);return t&&t.raw||{}}static _sanitizeWellKnownUrl(e){if(!e)return!1;try{let t=null;try{t=r.URL?new r.URL(e):new URL(e)}catch(n){t=new URL(e)}if(!t||!t.hostname)return!1;if("http:"!==t.protocol&&"https:"!==t.protocol)return!1;const n=t.port?`:${t.port}`:"",o=t.pathname?t.pathname:"";let i=`${t.protocol}//${t.hostname}${n}${o}`;return i.endsWith("/")&&(i=i.substring(0,i.length-1)),i}catch(e){return o.logger.error(e),!1}}static async _fetchWellKnownObject(e){return new Promise((function(t,o){const r=n(48070).getRequest();if(!r)throw new Error("No request library available");r({method:"GET",uri:e,timeout:5e3},((e,n,o)=>{if(e||n&&(n.statusCode<200||n.statusCode>=300)){let o="FAIL_PROMPT",r=(e?e.message:null)||"General failure";return n&&404===n.statusCode&&(o="IGNORE",r=i.ERROR_MISSING_WELLKNOWN),void t({raw:{},action:o,reason:r,error:e})}try{t({raw:JSON.parse(o),action:"SUCCESS"})}catch(e){let n=i.ERROR_INVALID;"SyntaxError"===e.name&&(n=i.ERROR_INVALID_JSON),t({raw:{},action:"FAIL_PROMPT",reason:n,error:e})}}))}))}}t.AutoDiscovery=i},22246:(e,t,n)=>{"use strict";var o=n(20862);Object.defineProperty(t,"__esModule",{value:!0}),t.MatrixBaseApis=l;var r=n(91415),i=n(7434),a=n(31707),s=o(n(3102)),u=n(17715);function c(e,t){switch(e){case r.SERVICE_TYPES.IS:return t+u.PREFIX_IDENTITY_V2+"/terms";case r.SERVICE_TYPES.IM:return t+"/_matrix/integrations/v1/terms";default:throw new Error("Unsupported service type")}}function l(e){s.checkObjectHasKeys(e,["baseUrl","request"]),this.baseUrl=e.baseUrl,this.idBaseUrl=e.idBaseUrl,this.identityServer=e.identityServer;const t={baseUrl:e.baseUrl,idBaseUrl:e.idBaseUrl,accessToken:e.accessToken,request:e.request,prefix:u.PREFIX_R0,onlyData:!0,extraParams:e.queryParams,localTimeoutMs:e.localTimeoutMs,useAuthorizationHeader:e.useAuthorizationHeader};this._http=new u.MatrixHttpApi(this,t),this._txnCtr=0}l.prototype.getHomeserverUrl=function(){return this.baseUrl},l.prototype.getIdentityServerUrl=function(e=!1){return e&&(this.idBaseUrl.startsWith("http://")||this.idBaseUrl.startsWith("https://"))?this.idBaseUrl.split("://")[1]:this.idBaseUrl},l.prototype.setIdentityServerUrl=function(e){this.idBaseUrl=s.ensureNoTrailingSlash(e),this._http.setIdBaseUrl(this.idBaseUrl)},l.prototype.getAccessToken=function(){return this._http.opts.accessToken||null},l.prototype.isLoggedIn=function(){return void 0!==this._http.opts.accessToken},l.prototype.makeTxnId=function(){return"m"+(new Date).getTime()+"."+this._txnCtr++},l.prototype.isUsernameAvailable=function(e){return this._http.authedRequest(void 0,"GET","/register/available",{username:e}).then((e=>e.available))},l.prototype.register=function(e,t,n,o,r,i,a,s){!0===r?r={email:!0}:null==r&&(r={}),"function"==typeof a&&(s=a,a=void 0),n&&(o.session=n);const u={auth:o};return null!=e&&(u.username=e),null!=t&&(u.password=t),r.email&&(u.bind_email=!0),r.msisdn&&(u.bind_msisdn=!0),null!=i&&(u.guest_access_token=i),null!=a&&(u.inhibit_login=a),null!=t&&(u.x_show_msisdn=!0),this.registerRequest(u,void 0,s)},l.prototype.registerGuest=function(e,t){return(e=e||{}).body=e.body||{},this.registerRequest(e.body,"guest",t)},l.prototype.registerRequest=function(e,t,n){const o={};return t&&(o.kind=t),this._http.request(n,"POST","/register",o,e)},l.prototype.loginFlows=function(e){return this._http.request(e,"GET","/login")},l.prototype.login=function(e,t,n){const o={type:e};return s.extend(o,t),this._http.authedRequest(((e,t)=>{t&&t.access_token&&t.user_id&&(this._http.opts.accessToken=t.access_token,this.credentials={userId:t.user_id}),n&&n(e,t)}),"POST","/login",void 0,o)},l.prototype.loginWithPassword=function(e,t,n){return this.login("m.login.password",{user:e,password:t},n)},l.prototype.loginWithSAML2=function(e,t){return this.login("m.login.saml2",{relay_state:e},t)},l.prototype.getCasLoginUrl=function(e){return this.getSsoLoginUrl(e,"cas")},l.prototype.getSsoLoginUrl=function(e,t,n){void 0===t&&(t="sso");let o="/login/"+t+"/redirect";return n&&(o+="/"+n),this._http.getUrl(o,{redirectUrl:e},u.PREFIX_R0)},l.prototype.loginWithToken=function(e,t){return this.login("m.login.token",{token:e},t)},l.prototype.logout=function(e){return this._http.authedRequest(e,"POST","/logout")},l.prototype.deactivateAccount=function(e,t){if("function"==typeof t)throw new Error("deactivateAccount no longer accepts a callback parameter");const n={};return e&&(n.auth=e),void 0!==t&&(n.erase=t),this._http.authedRequest(void 0,"POST","/account/deactivate",void 0,n)},l.prototype.getFallbackAuthUrl=function(e,t){const n=s.encodeUri("/auth/$loginType/fallback/web",{$loginType:e});return this._http.getUrl(n,{session:t},u.PREFIX_R0)},l.prototype.createRoom=async function(e,t){const n=(e.invite_3pid||[]).filter((e=>!e.id_access_token));if(n.length>0&&this.identityServer&&this.identityServer.getAccessToken&&await this.doesServerAcceptIdentityAccessToken()){const e=await this.identityServer.getAccessToken();if(e)for(const t of n)t.id_access_token=e}return this._http.authedRequest(t,"POST","/createRoom",void 0,e)},l.prototype.fetchRelations=async function(e,t,n,o,r){const i={};r.from&&(i.from=r.from);const a=s.encodeParams(i),c=s.encodeUri("/rooms/$roomId/relations/$eventId/$relationType/$eventType?"+a,{$roomId:e,$eventId:t,$relationType:n,$eventType:o});return await this._http.authedRequest(void 0,"GET",c,null,null,{prefix:u.PREFIX_UNSTABLE})},l.prototype.roomState=function(e,t){const n=s.encodeUri("/rooms/$roomId/state",{$roomId:e});return this._http.authedRequest(t,"GET",n)},l.prototype.fetchRoomEvent=function(e,t,n){const o=s.encodeUri("/rooms/$roomId/event/$eventId",{$roomId:e,$eventId:t});return this._http.authedRequest(n,"GET",o)},l.prototype.members=function(e,t,n,o,r){const i={};t&&(i.membership=t),n&&(i.not_membership=n),o&&(i.at=o);const a=s.encodeParams(i),u=s.encodeUri("/rooms/$roomId/members?"+a,{$roomId:e});return this._http.authedRequest(r,"GET",u)},l.prototype.upgradeRoom=function(e,t){const n=s.encodeUri("/rooms/$roomId/upgrade",{$roomId:e});return this._http.authedRequest(void 0,"POST",n,void 0,{new_version:t})},l.prototype.getGroupSummary=function(e){const t=s.encodeUri("/groups/$groupId/summary",{$groupId:e});return this._http.authedRequest(void 0,"GET",t)},l.prototype.getGroupProfile=function(e){const t=s.encodeUri("/groups/$groupId/profile",{$groupId:e});return this._http.authedRequest(void 0,"GET",t)},l.prototype.setGroupProfile=function(e,t){const n=s.encodeUri("/groups/$groupId/profile",{$groupId:e});return this._http.authedRequest(void 0,"POST",n,void 0,t)},l.prototype.setGroupJoinPolicy=function(e,t){const n=s.encodeUri("/groups/$groupId/settings/m.join_policy",{$groupId:e});return this._http.authedRequest(void 0,"PUT",n,void 0,{"m.join_policy":t})},l.prototype.getGroupUsers=function(e){const t=s.encodeUri("/groups/$groupId/users",{$groupId:e});return this._http.authedRequest(void 0,"GET",t)},l.prototype.getGroupInvitedUsers=function(e){const t=s.encodeUri("/groups/$groupId/invited_users",{$groupId:e});return this._http.authedRequest(void 0,"GET",t)},l.prototype.getGroupRooms=function(e){const t=s.encodeUri("/groups/$groupId/rooms",{$groupId:e});return this._http.authedRequest(void 0,"GET",t)},l.prototype.inviteUserToGroup=function(e,t){const n=s.encodeUri("/groups/$groupId/admin/users/invite/$userId",{$groupId:e,$userId:t});return this._http.authedRequest(void 0,"PUT",n,void 0,{})},l.prototype.removeUserFromGroup=function(e,t){const n=s.encodeUri("/groups/$groupId/admin/users/remove/$userId",{$groupId:e,$userId:t});return this._http.authedRequest(void 0,"PUT",n,void 0,{})},l.prototype.addUserToGroupSummary=function(e,t,n){const o=s.encodeUri(n?"/groups/$groupId/summary/$roleId/users/$userId":"/groups/$groupId/summary/users/$userId",{$groupId:e,$roleId:n,$userId:t});return this._http.authedRequest(void 0,"PUT",o,void 0,{})},l.prototype.removeUserFromGroupSummary=function(e,t){const n=s.encodeUri("/groups/$groupId/summary/users/$userId",{$groupId:e,$userId:t});return this._http.authedRequest(void 0,"DELETE",n,void 0,{})},l.prototype.addRoomToGroupSummary=function(e,t,n){const o=s.encodeUri(n?"/groups/$groupId/summary/$categoryId/rooms/$roomId":"/groups/$groupId/summary/rooms/$roomId",{$groupId:e,$categoryId:n,$roomId:t});return this._http.authedRequest(void 0,"PUT",o,void 0,{})},l.prototype.removeRoomFromGroupSummary=function(e,t){const n=s.encodeUri("/groups/$groupId/summary/rooms/$roomId",{$groupId:e,$roomId:t});return this._http.authedRequest(void 0,"DELETE",n,void 0,{})},l.prototype.addRoomToGroup=function(e,t,n){void 0===n&&(n=!0);const o=s.encodeUri("/groups/$groupId/admin/rooms/$roomId",{$groupId:e,$roomId:t});return this._http.authedRequest(void 0,"PUT",o,void 0,{"m.visibility":{type:n?"public":"private"}})},l.prototype.updateGroupRoomVisibility=function(e,t,n){const o=s.encodeUri("/groups/$groupId/admin/rooms/$roomId/config/m.visibility",{$groupId:e,$roomId:t});return this._http.authedRequest(void 0,"PUT",o,void 0,{type:n?"public":"private"})},l.prototype.removeRoomFromGroup=function(e,t){const n=s.encodeUri("/groups/$groupId/admin/rooms/$roomId",{$groupId:e,$roomId:t});return this._http.authedRequest(void 0,"DELETE",n,void 0,{})},l.prototype.acceptGroupInvite=function(e,t=null){const n=s.encodeUri("/groups/$groupId/self/accept_invite",{$groupId:e});return this._http.authedRequest(void 0,"PUT",n,void 0,t||{})},l.prototype.joinGroup=function(e){const t=s.encodeUri("/groups/$groupId/self/join",{$groupId:e});return this._http.authedRequest(void 0,"PUT",t,void 0,{})},l.prototype.leaveGroup=function(e){const t=s.encodeUri("/groups/$groupId/self/leave",{$groupId:e});return this._http.authedRequest(void 0,"PUT",t,void 0,{})},l.prototype.getJoinedGroups=function(){const e=s.encodeUri("/joined_groups");return this._http.authedRequest(void 0,"GET",e)},l.prototype.createGroup=function(e){const t=s.encodeUri("/create_group");return this._http.authedRequest(void 0,"POST",t,void 0,e)},l.prototype.getPublicisedGroups=function(e){const t=s.encodeUri("/publicised_groups");return this._http.authedRequest(void 0,"POST",t,void 0,{user_ids:e})},l.prototype.setGroupPublicity=function(e,t){const n=s.encodeUri("/groups/$groupId/self/update_publicity",{$groupId:e});return this._http.authedRequest(void 0,"PUT",n,void 0,{publicise:t})},l.prototype.getStateEvent=function(e,t,n,o){const r={$roomId:e,$eventType:t,$stateKey:n};let i=s.encodeUri("/rooms/$roomId/state/$eventType",r);return void 0!==n&&(i=s.encodeUri(i+"/$stateKey",r)),this._http.authedRequest(o,"GET",i)},l.prototype.sendStateEvent=function(e,t,n,o,r){const i={$roomId:e,$eventType:t,$stateKey:o};let a=s.encodeUri("/rooms/$roomId/state/$eventType",i);return void 0!==o&&(a=s.encodeUri(a+"/$stateKey",i)),this._http.authedRequest(r,"PUT",a,void 0,n)},l.prototype.roomInitialSync=function(e,t,n){s.isFunction(t)&&(n=t,t=void 0);const o=s.encodeUri("/rooms/$roomId/initialSync",{$roomId:e});return t||(t=30),this._http.authedRequest(n,"GET",o,{limit:t})},l.prototype.setRoomReadMarkersHttpRequest=function(e,t,n,o){const r=s.encodeUri("/rooms/$roomId/read_markers",{$roomId:e}),i={"m.fully_read":t,"m.read":n,"m.hidden":Boolean(!!o&&o.hidden)};return this._http.authedRequest(void 0,"POST",r,void 0,i)},l.prototype.getJoinedRooms=function(){const e=s.encodeUri("/joined_rooms");return this._http.authedRequest(void 0,"GET",e)},l.prototype.getJoinedRoomMembers=function(e){const t=s.encodeUri("/rooms/$roomId/joined_members",{$roomId:e});return this._http.authedRequest(void 0,"GET",t)},l.prototype.publicRooms=function(e,t){"function"==typeof e&&(t=e,e={}),void 0===e&&(e={});const n={};return e.server&&(n.server=e.server,delete e.server),0===Object.keys(e).length&&0===Object.keys(n).length?this._http.authedRequest(t,"GET","/publicRooms"):this._http.authedRequest(t,"POST","/publicRooms",n,e)},l.prototype.createAlias=function(e,t,n){const o=s.encodeUri("/directory/room/$alias",{$alias:e}),r={room_id:t};return this._http.authedRequest(n,"PUT",o,void 0,r)},l.prototype.deleteAlias=function(e,t){const n=s.encodeUri("/directory/room/$alias",{$alias:e});return this._http.authedRequest(t,"DELETE",n,void 0,void 0)},l.prototype.unstableGetLocalAliases=function(e,t){const n=s.encodeUri("/rooms/$roomId/aliases",{$roomId:e}),o=u.PREFIX_UNSTABLE+"/org.matrix.msc2432";return this._http.authedRequest(t,"GET",n,null,null,{prefix:o})},l.prototype.getRoomIdForAlias=function(e,t){const n=s.encodeUri("/directory/room/$alias",{$alias:e});return this._http.authedRequest(t,"GET",n)},l.prototype.resolveRoomAlias=function(e,t){const n=s.encodeUri("/directory/room/$alias",{$alias:e});return this._http.request(t,"GET",n)},l.prototype.getRoomDirectoryVisibility=function(e,t){const n=s.encodeUri("/directory/list/room/$roomId",{$roomId:e});return this._http.authedRequest(t,"GET",n)},l.prototype.setRoomDirectoryVisibility=function(e,t,n){const o=s.encodeUri("/directory/list/room/$roomId",{$roomId:e});return this._http.authedRequest(n,"PUT",o,void 0,{visibility:t})},l.prototype.setRoomDirectoryVisibilityAppService=function(e,t,n,o){const r=s.encodeUri("/directory/list/appservice/$networkId/$roomId",{$networkId:e,$roomId:t});return this._http.authedRequest(o,"PUT",r,void 0,{visibility:n})},l.prototype.searchUserDirectory=function(e){const t={search_term:e.term};return void 0!==e.limit&&(t.limit=e.limit),this._http.authedRequest(void 0,"POST","/user_directory/search",void 0,t)},l.prototype.uploadContent=function(e,t){return this._http.uploadContent(e,t)},l.prototype.cancelUpload=function(e){return this._http.cancelUpload(e)},l.prototype.getCurrentUploads=function(){return this._http.getCurrentUploads()},l.prototype.getProfileInfo=function(e,t,n){s.isFunction(t)&&(n=t,t=void 0);const o=t?s.encodeUri("/profile/$userId/$info",{$userId:e,$info:t}):s.encodeUri("/profile/$userId",{$userId:e});return this._http.authedRequest(n,"GET",o)},l.prototype.getThreePids=function(e){return this._http.authedRequest(e,"GET","/account/3pid",void 0,void 0)},l.prototype.addThreePid=function(e,t,n){const o={threePidCreds:e,bind:t};return this._http.authedRequest(n,"POST","/account/3pid",null,o)},l.prototype.addThreePidOnly=async function(e){const t=await this.isVersionSupported("r0.6.0")?u.PREFIX_R0:u.PREFIX_UNSTABLE;return this._http.authedRequest(void 0,"POST","/account/3pid/add",null,e,{prefix:t})},l.prototype.bindThreePid=async function(e){const t=await this.isVersionSupported("r0.6.0")?u.PREFIX_R0:u.PREFIX_UNSTABLE;return this._http.authedRequest(void 0,"POST","/account/3pid/bind",null,e,{prefix:t})},l.prototype.unbindThreePid=async function(e,t){const n={medium:e,address:t,id_server:this.getIdentityServerUrl(!0)},o=await this.isVersionSupported("r0.6.0")?u.PREFIX_R0:u.PREFIX_UNSTABLE;return this._http.authedRequest(void 0,"POST","/account/3pid/unbind",null,n,{prefix:o})},l.prototype.deleteThreePid=function(e,t){const n={medium:e,address:t};return this._http.authedRequest(void 0,"POST","/account/3pid/delete",null,n)},l.prototype.setPassword=function(e,t,n){const o={auth:e,new_password:t};return this._http.authedRequest(n,"POST","/account/password",null,o)},l.prototype.getDevices=function(){return this._http.authedRequest(void 0,"GET","/devices",void 0,void 0)},l.prototype.getDevice=function(e){const t=s.encodeUri("/devices/$device_id",{$device_id:e});return this._http.authedRequest(void 0,"GET",t,void 0,void 0)},l.prototype.setDeviceDetails=function(e,t){const n=s.encodeUri("/devices/$device_id",{$device_id:e});return this._http.authedRequest(void 0,"PUT",n,void 0,t)},l.prototype.deleteDevice=function(e,t){const n=s.encodeUri("/devices/$device_id",{$device_id:e}),o={};return t&&(o.auth=t),this._http.authedRequest(void 0,"DELETE",n,void 0,o)},l.prototype.deleteMultipleDevices=function(e,t){const n={devices:e};return t&&(n.auth=t),this._http.authedRequest(void 0,"POST","/delete_devices",void 0,n)},l.prototype.getPushers=function(e){return this._http.authedRequest(e,"GET","/pushers",void 0,void 0)},l.prototype.setPusher=function(e,t){return this._http.authedRequest(t,"POST","/pushers/set",null,e)},l.prototype.getPushRules=function(e){return this._http.authedRequest(e,"GET","/pushrules/").then((e=>a.PushProcessor.rewriteDefaultRules(e)))},l.prototype.addPushRule=function(e,t,n,o,r){const i=s.encodeUri("/pushrules/"+e+"/$kind/$ruleId",{$kind:t,$ruleId:n});return this._http.authedRequest(r,"PUT",i,void 0,o)},l.prototype.deletePushRule=function(e,t,n,o){const r=s.encodeUri("/pushrules/"+e+"/$kind/$ruleId",{$kind:t,$ruleId:n});return this._http.authedRequest(o,"DELETE",r)},l.prototype.setPushRuleEnabled=function(e,t,n,o,r){const i=s.encodeUri("/pushrules/"+e+"/$kind/$ruleId/enabled",{$kind:t,$ruleId:n});return this._http.authedRequest(r,"PUT",i,void 0,{enabled:o})},l.prototype.setPushRuleActions=function(e,t,n,o,r){const i=s.encodeUri("/pushrules/"+e+"/$kind/$ruleId/actions",{$kind:t,$ruleId:n});return this._http.authedRequest(r,"PUT",i,void 0,{actions:o})},l.prototype.search=function(e,t){const n={};return e.next_batch&&(n.next_batch=e.next_batch),this._http.authedRequest(t,"POST","/search",n,e.body)},l.prototype.uploadKeysRequest=function(e,t,n){return this._http.authedRequest(n,"POST","/keys/upload",void 0,e)},l.prototype.uploadKeySignatures=function(e){return this._http.authedRequest(void 0,"POST","/keys/signatures/upload",void 0,e,{prefix:u.PREFIX_UNSTABLE})},l.prototype.downloadKeysForUsers=function(e,t){if(s.isFunction(t))throw new Error("downloadKeysForUsers no longer accepts a callback parameter");const n={device_keys:{}};return"token"in(t=t||{})&&(n.token=t.token),e.forEach((e=>{n.device_keys[e]=[]})),this._http.authedRequest(void 0,"POST","/keys/query",void 0,n)},l.prototype.claimOneTimeKeys=function(e,t,n){const o={};void 0===t&&(t="signed_curve25519");for(let n=0;n{const n=e[0].toLowerCase(),r=e[1].toLowerCase(),a=t.sha256(`${n} ${r} ${o.pepper}`).replace(/\+/g,"-").replace(/\//g,"_");return i[a]=e[0],a})),o.algorithm="sha256"}else{if(!r.algorithms.includes("none"))throw new Error("Unsupported identity server: unknown hash algorithm");o.addresses=e.map((e=>{const t=`${e[0].toLowerCase()} ${e[1].toLowerCase()}`;return i[t]=e[0],t})),o.algorithm="none"}const a=await this._http.idServerRequest(void 0,"POST","/lookup",o,u.PREFIX_IDENTITY_V2,t);if(!a||!a.mappings)return[];const s=[];for(const e of Object.keys(a.mappings)){const t=a.mappings[e],n=i[e];if(!n)throw new Error("Identity server returned more results than expected");s.push({address:n,mxid:t})}return s},l.prototype.lookupThreePid=async function(e,t,n,o){const r=(await this.identityHashedLookup([[t,e]],o)).find((e=>e.address===t));if(!r)return n&&n(null,{}),{};const i={address:t,medium:e,mxid:r.mxid};return n&&n(null,i),i},l.prototype.bulkLookupThreePids=async function(e,t){const n=await this.identityHashedLookup(e.map((e=>[e[1],e[0]])),t),o=[];for(const t of n){const n=e.find((e=>e[1]===t.address));if(!n)throw new Error("Identity sever returned unexpected results");o.push([n[0],t.address,t.mxid])}return{threepids:o}},l.prototype.getIdentityAccount=function(e){return this._http.idServerRequest(void 0,"GET","/account",void 0,u.PREFIX_IDENTITY_V2,e)},l.prototype.sendToDevice=function(e,t,n){const o=s.encodeUri("/sendToDevice/$eventType/$txnId",{$eventType:e,$txnId:n||this.makeTxnId()}),r={messages:t},a=Object.keys(t).reduce(((e,n)=>(e[n]=Object.keys(t[n]),e)),{});return i.logger.log(`PUT ${o}`,a),this._http.authedRequest(void 0,"PUT",o,void 0,r)},l.prototype.getThirdpartyProtocols=function(){return this._http.authedRequest(void 0,"GET","/thirdparty/protocols",void 0,void 0).then((e=>{if(!e||"object"!=typeof e)throw new Error(`/thirdparty/protocols did not return an object: ${e}`);return e}))},l.prototype.getThirdpartyLocation=function(e,t){const n=s.encodeUri("/thirdparty/location/$protocol",{$protocol:e});return this._http.authedRequest(void 0,"GET",n,t,void 0)},l.prototype.getThirdpartyUser=function(e,t){const n=s.encodeUri("/thirdparty/user/$protocol",{$protocol:e});return this._http.authedRequest(void 0,"GET",n,t,void 0)},l.prototype.getTerms=function(e,t){const n=c(e,t);return this._http.requestOtherUrl(void 0,"GET",n)},l.prototype.agreeToTerms=function(e,t,n,o){const r=c(e,t),i={Authorization:"Bearer "+n};return this._http.requestOtherUrl(void 0,"POST",r,null,{user_accepts:o},{headers:i})},l.prototype.reportEvent=function(e,t,n,o){const r=s.encodeUri("/rooms/$roomId/report/$eventId",{$roomId:e,$eventId:t});return this._http.authedRequest(void 0,"POST",r,null,{score:n,reason:o})},l.prototype.getSpaceSummary=function(e,t,n,o,r,i){const a=s.encodeUri("/rooms/$roomId/spaces",{$roomId:e});return this._http.authedRequest(void 0,"POST",a,null,{max_rooms_per_space:t,suggested_only:n,auto_join_only:o,limit:r,batch:i},{prefix:"/_matrix/client/unstable/org.matrix.msc2946"})}},8743:(e,t,n)=>{"use strict";var o=n(95318),r=n(20862);Object.defineProperty(t,"__esModule",{value:!0});var i={};t.default=void 0;var a=r(n(48070));Object.keys(a).forEach((function(e){"default"!==e&&"__esModule"!==e&&(Object.prototype.hasOwnProperty.call(i,e)||e in t&&t[e]===a[e]||Object.defineProperty(t,e,{enumerable:!0,get:function(){return a[e]}}))}));var s=o(n(24770)),u=o(n(80129));let c;a.request((function(e,t){return e.qs=u.default.stringify(e.qs||{},e.qsStringifyOptions),(0,s.default)(e,t)}));try{c=n.g.indexedDB}catch(e){}c&&a.setCryptoStoreFactory((function(){return new a.IndexedDBCryptoStore(c,"matrix-js-sdk:crypto")}));var l=a;t.default=l,n.g.matrixcs=a},62168:(e,t,n)=>{"use strict";var o=n(20862),r=n(95318);Object.defineProperty(t,"__esModule",{value:!0}),t.MatrixClient=N,t.CRYPTO_ENABLED=void 0;var i=r(n(8575)),a=n(17187),s=n(22246),u=n(27906),c=n(64551),l=n(24369),d=n(88910),h=n(41398),p=n(25641),f=n(59679),g=n(62931),m=o(n(3102)),_=n(17715),F=n(73667),y=o(n(44656)),b=o(n(32772)),v=n(20771),w=n(40635),E=n(7434),k=n(12600),D=n(34077),S=n(91597),x=n(98401),C=n(31707),A=n(83998),T=n(79118),R=n(54830);const I=(0,k.isCryptoAvailable)();t.CRYPTO_ENABLED=I;const M=6e5;function O(e,t,n){const o=[];for(const[r,i]of Object.entries(e))try{const e=B(i,t);e.session_id=r,e.room_id=n,o.push(e)}catch(e){E.logger.log("Failed to decrypt megolm session from backup",e)}return o}function B(e,t){return JSON.parse(t.decrypt(e.session_data.ephemeral,e.session_data.mac,e.session_data.ciphertext))}function N(e){e.baseUrl=m.ensureNoTrailingSlash(e.baseUrl),e.idBaseUrl=m.ensureNoTrailingSlash(e.idBaseUrl),s.MatrixBaseApis.call(this,e),this.olmVersion=null,this.reEmitter=new v.ReEmitter(this),this.usingExternalCrypto=e.usingExternalCrypto,this.store=e.store||new p.StubStore,this.deviceId=e.deviceId||null;const t=e.userId||null;if(this.credentials={userId:t},e.deviceToImport?this.deviceId?E.logger.warn("not importing device because device ID is provided to constructor independently of exported data"):this.credentials.userId?E.logger.warn("not importing device because user ID is provided to constructor independently of exported data"):e.deviceToImport.deviceId?(this.deviceId=e.deviceToImport.deviceId,this.credentials.userId=e.deviceToImport.userId,this._exportedOlmDeviceToImport=e.deviceToImport.olmDevice):E.logger.warn("not importing device because no device ID in exported data"):e.pickleKey&&(this.pickleKey=e.pickleKey),this.scheduler=e.scheduler,this.scheduler){const e=this;this.scheduler.setProcessFunction((async function(t){const n=e.getRoom(t.getRoomId());t.status!==l.EventStatus.SENDING&&j(n,t,l.EventStatus.SENDING);const o=await q(e,t);return n&&n.updatePendingEvent(t,l.EventStatus.SENT,o.event_id),o}))}this.clientRunning=!1;const n=(0,f.createNewMatrixCall)(this);this._supportsVoip=!1,n?(this._callEventHandler=new g.CallEventHandler(this),this._supportsVoip=!0,this.on("sync",this._startCallEventHandler)):this._callEventHandler=null,this._syncingRetry=null,this._syncApi=null,this._peekSync=null,this._isGuest=!1,this._ongoingScrollbacks={},this.timelineSupport=Boolean(e.timelineSupport),this.urlPreviewCache={},this._notifTimelineSet=null,this.unstableClientRelationAggregation=!!e.unstableClientRelationAggregation,this._crypto=null,this._cryptoStore=e.cryptoStore,this._sessionStore=e.sessionStore,this._verificationMethods=e.verificationMethods,this._cryptoCallbacks=e.cryptoCallbacks||{},this._forceTURN=e.forceTURN||!1,this._iceCandidatePoolSize=void 0===e.iceCandidatePoolSize?0:e.iceCandidatePoolSize,this._supportsCallTransfer=e.supportsCallTransfer||!1,this._fallbackICEServerAllowed=e.fallbackICEServerAllowed||!1,this._roomList=new w.RoomList(this._cryptoStore),this._pushProcessor=new C.PushProcessor(this),this._serverVersionsPromise=null,this._cachedCapabilities=null,this._clientWellKnown=void 0,this._clientWellKnownPromise=void 0,this._turnServers=[],this._turnServersExpiry=0,this._checkTurnServersIntervalID=null,this.on("Event.decrypted",(e=>{const t=e.getPushActions(),n=this._pushProcessor.actionsForEvent(e);e.setPushActions(n);const o=this.getRoom(e.getRoomId());if(!o)return;const r=o.getUnreadNotificationCount("highlight"),i=!(!t||!t.tweaks||!t.tweaks.highlight),a=!(!n||!n.tweaks||!n.tweaks.highlight);if((i!==a||r>0)&&!o.hasUserReadEvent(this.getUserId(),e.getId())){let e=r;a&&!i&&e++,!a&&i&&e--,o.setUnreadNotificationCount("highlight",e),o.getUnreadNotificationCount("total"){if(t&&this.isRoomEncrypted(t.roomId)){const n=e.getContent();if(!(Object.keys(n).filter((e=>Object.keys(n[e]["m.read"]).includes(this.getUserId()))).length>0))return;const o=20,r=t.getLiveTimeline().getEvents();let i=0;for(let e=r.length-1;e>=0;e--){if(e===r.length-o)return;const n=r[e];if(t.hasUserReadEvent(this.getUserId(),n.getId()))break;const a=this.getPushActionsForEvent(n);i+=a.tweaks&&a.tweaks.highlight?1:0}t.setUnreadNotificationCount("highlight",i)}}))}async function L(e,t,n,o,r,i){if(!e._crypto)throw new Error("End-to-End encryption disabled");await e._crypto.setDeviceVerification(t,n,o,r,i)}function P(e,t){for(const n of t)e.prototype[n]=function(...e){if(!this._crypto)throw new Error("End-to-end encryption disabled");return this._crypto[n](...e)}}function U(e,t,n,o){return Promise.resolve().then((function(){const o=function(e,t,n){if(t.isEncrypted())return null;if(!e.isRoomEncrypted(t.getRoomId()))return null;if(!e._crypto&&e.usingExternalCrypto)return null;if("m.reaction"===t.getType())return null;if(!e._crypto)throw new Error("This room is configured to use encryption, but your client does not support encryption.");return e._crypto.encryptEvent(t,n)}(e,n,t);return o?(j(t,n,l.EventStatus.ENCRYPTING),o.then((()=>{j(t,n,l.EventStatus.SENDING)}))):null})).then((function(){let o;return e.scheduler&&(o=e.scheduler.queueEvent(n),o&&e.scheduler.getQueueForEvent(n).length>1&&j(t,n,l.EventStatus.QUEUED)),o||(o=q(e,n),t&&(o=o.then((e=>(t.updatePendingEvent(n,l.EventStatus.SENT,e.event_id),e))))),o})).then((function(e){return o&&o(null,e),e}),(function(e){E.logger.error("Error sending event",e.stack||e);try{n.error=e,j(t,n,l.EventStatus.NOT_SENT),e.event=n,o&&o(e)}catch(t){E.logger.error("Exception in error handler!",t.stack||e)}throw e}))}function j(e,t,n){e?e.updatePendingEvent(t,n):t.setStatus(n)}function q(e,t){let n=t.getTxnId();n||(n=e.makeTxnId(),t.setTxnId(n));const o={$roomId:t.getRoomId(),$eventType:t.getWireType(),$stateKey:t.getStateKey(),$txnId:n};let r;if(t.isState()){let e="/rooms/$roomId/state/$eventType";t.getStateKey()&&t.getStateKey().length>0&&(e="/rooms/$roomId/state/$eventType/$stateKey"),r=m.encodeUri(e,o)}else if(t.isRedaction()){const e="/rooms/$roomId/redact/$redactsEventId/$txnId";r=m.encodeUri(e,Object.assign({$redactsEventId:t.event.redacts},o))}else r=m.encodeUri("/rooms/$roomId/send/$eventType/$txnId",o);return e._http.authedRequest(void 0,"PUT",r,void 0,t.getWireContent()).then((e=>(E.logger.log(`Event sent to ${t.getRoomId()} with event id ${e.event_id}`),e)))}function z(e,t,n,o,r,i){m.isFunction(r)&&(i=r,r=void 0);const a=m.encodeUri("/rooms/$room_id/$membership",{$room_id:t,$membership:o});return e._http.authedRequest(i,"POST",a,void 0,{user_id:n,reason:r})}function K(e,t,n){e&&e(n),t(n)}function G(e,t,n){e&&e(null,n),t(n)}function $(e,t={}){const n=Boolean(t.preventReEmit),o=!1!==t.decrypt;return function(t){const r=new l.MatrixEvent(t);return r.isEncrypted()&&(n||e.reEmitter.reEmit(r,["Event.decrypted"]),o&&e.decryptEventIfNeeded(r)),n||e.reEmitter.reEmit(r,["Event.replaced"]),r}}m.inherits(N,a.EventEmitter),m.extend(N.prototype,s.MatrixBaseApis.prototype),N.prototype.rehydrateDevice=async function(){if(this._crypto)throw new Error("Cannot rehydrate device after crypto is initialized");if(!this._cryptoCallbacks.getDehydrationKey)return;const e=await this.getDehydratedDevice();if(!e)return;if(!e.device_data||!e.device_id)return void E.logger.info("no dehydrated device found");const t=new n.g.Olm.Account;try{const n=e.device_data;if(n.algorithm!==R.DEHYDRATION_ALGORITHM)return void E.logger.warn("Wrong algorithm for dehydrated device");E.logger.log("unpickling dehydrated device");const o=await this._cryptoCallbacks.getDehydrationKey(n,(e=>{t.unpickle(new Uint8Array(e),n.account)}));if(t.unpickle(o,n.account),E.logger.log("unpickled device"),!0===(await this._http.authedRequest(void 0,"POST","/dehydrated_device/claim",void 0,{device_id:e.device_id},{prefix:"/_matrix/client/unstable/org.matrix.msc2697.v2"})).success){this.deviceId=e.device_id,E.logger.info("using dehydrated device");const n=this.pickleKey||"DEFAULT_KEY";return this._exportedOlmDeviceToImport={pickledAccount:t.pickle(n),sessions:[],pickleKey:n},t.free(),this.deviceId}return t.free(),void E.logger.info("not using dehydrated device")}catch(e){t.free(),E.logger.warn("could not unpickle",e)}},N.prototype.getDehydratedDevice=async function(){try{return await this._http.authedRequest(void 0,"GET","/dehydrated_device",void 0,void 0,{prefix:"/_matrix/client/unstable/org.matrix.msc2697.v2"})}catch(e){return void E.logger.info("could not get dehydrated device",e.toString())}},N.prototype.setDehydrationKey=async function(e,t={},n){if(this._crypto)return await this._crypto._dehydrationManager.setKeyAndQueueDehydration(e,t,n);E.logger.warn("not dehydrating device if crypto is not enabled")},N.prototype.createDehydratedDevice=async function(e,t={},n){if(this._crypto)return await this._crypto._dehydrationManager.setKey(e,t,n),await this._crypto._dehydrationManager.dehydrateDevice();E.logger.warn("not dehydrating device if crypto is not enabled")},N.prototype.exportDevice=async function(){if(this._crypto)return{userId:this.credentials.userId,deviceId:this.deviceId,olmDevice:await this._crypto._olmDevice.export()};E.logger.warn("not exporting device if crypto is not enabled")},N.prototype.clearStores=function(){if(this._clientRunning)throw new Error("Cannot clear stores while client is running");const e=[];return e.push(this.store.deleteAllData()),this._cryptoStore&&e.push(this._cryptoStore.deleteAllData()),Promise.all(e)},N.prototype.getUserId=function(){return this.credentials&&this.credentials.userId?this.credentials.userId:null},N.prototype.getDomain=function(){return this.credentials&&this.credentials.userId?this.credentials.userId.replace(/^.*?:/,""):null},N.prototype.getUserIdLocalpart=function(){return this.credentials&&this.credentials.userId?this.credentials.userId.split(":")[0].substring(1):null},N.prototype.getDeviceId=function(){return this.deviceId},N.prototype.supportsVoip=function(){return this._supportsVoip},N.prototype.setForceTURN=function(e){this._forceTURN=e},N.prototype.setSupportsCallTransfer=function(e){this._supportsCallTransfer=e},N.prototype.createCall=function(e){return(0,f.createNewMatrixCall)(this,e)},N.prototype.getSyncState=function(){return this._syncApi?this._syncApi.getSyncState():null},N.prototype.getSyncStateData=function(){return this._syncApi?this._syncApi.getSyncStateData():null},N.prototype.isInitialSyncComplete=function(){const e=this.getSyncState();return!!e&&("PREPARED"===e||"SYNCING"===e)},N.prototype.isGuest=function(){return this._isGuest},N.prototype.getScheduler=function(){return this.scheduler},N.prototype.setGuest=function(e){this._isGuest=e},N.prototype.retryImmediately=function(){return this._syncApi.retryImmediately()},N.prototype.getNotifTimelineSet=function(){return this._notifTimelineSet},N.prototype.setNotifTimelineSet=function(e){this._notifTimelineSet=e},N.prototype.getCapabilities=function(e=!1){const t=(new Date).getTime();return this._cachedCapabilities&&!e&&t(E.logger.error(e),null))).then((e=>{e||(e={});const n=e.capabilities||{},o=Object.keys(n).length?216e5:6e4+5e3*Math.random();return this._cachedCapabilities={capabilities:n,expiration:t+o},E.logger.log("Caching capabilities: ",n),n}))},N.prototype.initCrypto=async function(){if(!(0,k.isCryptoAvailable)())throw new Error("End-to-end encryption not supported in this js-sdk build: did you remember to load the olm library?");if(this._crypto)return void E.logger.warn("Attempt to re-initialise e2e encryption on MatrixClient");if(!this._sessionStore)throw new Error("Cannot enable encryption: no sessionStore provided");if(!this._cryptoStore)throw new Error("Cannot enable encryption: no cryptoStore provided");E.logger.log("Crypto: Starting up crypto store..."),await this._cryptoStore.startup(),E.logger.log("Crypto: initialising roomlist..."),await this._roomList.init();const e=this.getUserId();if(null===e)throw new Error("Cannot enable encryption on MatrixClient with unknown userId: ensure userId is passed in createClient().");if(null===this.deviceId)throw new Error("Cannot enable encryption on MatrixClient with unknown deviceId: ensure deviceId is passed in createClient().");const t=new k.Crypto(this,this._sessionStore,e,this.deviceId,this.store,this._cryptoStore,this._roomList,this._verificationMethods);this.reEmitter.reEmit(t,["crypto.keyBackupFailed","crypto.keyBackupSessionsRemaining","crypto.roomKeyRequest","crypto.roomKeyRequestCancellation","crypto.warning","crypto.devicesUpdated","crypto.willUpdateDevices","deviceVerificationChanged","userTrustStatusChanged","crossSigning.keysChanged"]),E.logger.log("Crypto: initialising crypto object..."),await t.init({exportedOlmDevice:this._exportedOlmDeviceToImport,pickleKey:this.pickleKey}),delete this._exportedOlmDeviceToImport,this.olmVersion=k.Crypto.getOlmVersion(),t.registerEventHandlers(this),this._crypto=t},N.prototype.isCryptoEnabled=function(){return null!==this._crypto},N.prototype.getDeviceEd25519Key=function(){return this._crypto?this._crypto.getDeviceEd25519Key():null},N.prototype.getDeviceCurve25519Key=function(){return this._crypto?this._crypto.getDeviceCurve25519Key():null},N.prototype.uploadKeys=function(){if(null===this._crypto)throw new Error("End-to-end encryption disabled");return this._crypto.uploadDeviceKeys()},N.prototype.downloadKeys=function(e,t){return null===this._crypto?Promise.reject(new Error("End-to-end encryption disabled")):this._crypto.downloadKeys(e,t)},N.prototype.getStoredDevicesForUser=function(e){if(null===this._crypto)throw new Error("End-to-end encryption disabled");return this._crypto.getStoredDevicesForUser(e)||[]},N.prototype.getStoredDevice=function(e,t){if(null===this._crypto)throw new Error("End-to-end encryption disabled");return this._crypto.getStoredDevice(e,t)||null},N.prototype.setDeviceVerified=function(e,t,n){void 0===n&&(n=!0);const o=L(this,e,t,n,null);return e==this.credentials.userId&&this._crypto.checkKeyBackup(),o},N.prototype.setDeviceBlocked=function(e,t,n){return void 0===n&&(n=!0),L(this,e,t,null,n)},N.prototype.setDeviceKnown=function(e,t,n){return void 0===n&&(n=!0),L(this,e,t,null,null,n)},N.prototype.requestVerificationDM=function(e,t){if(null===this._crypto)throw new Error("End-to-end encryption disabled");return this._crypto.requestVerificationDM(e,t)},N.prototype.findVerificationRequestDMInProgress=function(e){if(null===this._crypto)throw new Error("End-to-end encryption disabled");return this._crypto.findVerificationRequestDMInProgress(e)},N.prototype.getVerificationRequestsToDeviceInProgress=function(e){if(null===this._crypto)throw new Error("End-to-end encryption disabled");return this._crypto.getVerificationRequestsToDeviceInProgress(e)},N.prototype.requestVerification=function(e,t){if(null===this._crypto)throw new Error("End-to-end encryption disabled");return this._crypto.requestVerification(e,t)},N.prototype.beginKeyVerification=function(e,t,n){if(null===this._crypto)throw new Error("End-to-end encryption disabled");return this._crypto.beginKeyVerification(e,t,n)},N.prototype.setGlobalBlacklistUnverifiedDevices=function(e){if(null===this._crypto)throw new Error("End-to-end encryption disabled");this._crypto.setGlobalBlacklistUnverifiedDevices(e)},N.prototype.getGlobalBlacklistUnverifiedDevices=function(){if(null===this._crypto)throw new Error("End-to-end encryption disabled");return this._crypto.getGlobalBlacklistUnverifiedDevices()},N.prototype.setGlobalErrorOnUnknownDevices=function(e){if(null===this._crypto)throw new Error("End-to-end encryption disabled");this._crypto.setGlobalErrorOnUnknownDevices(e)},N.prototype.getGlobalErrorOnUnknownDevices=function(){if(null===this._crypto)throw new Error("End-to-end encryption disabled");return this._crypto.getGlobalErrorOnUnknownDevices()},P(N,["getCrossSigningId","getStoredCrossSigningForUser","checkUserTrust","checkDeviceTrust","checkOwnCrossSigningTrust","checkCrossSigningPrivateKey","legacyDeviceVerification","prepareToEncrypt","isCrossSigningReady","bootstrapCrossSigning","getCryptoTrustCrossSignedDevices","setCryptoTrustCrossSignedDevices","countSessionsNeedingBackup"]),P(N,["getEventEncryptionInfo","createRecoveryKeyFromPassphrase","isSecretStorageReady","bootstrapSecretStorage","addSecretStorageKey","hasSecretStorageKey","storeSecret","getSecret","isSecretStored","requestSecret","getDefaultSecretStorageKeyId","setDefaultSecretStorageKeyId","checkSecretStorageKey","checkSecretStoragePrivateKey"]),N.prototype.getEventSenderDeviceInfo=async function(e){return this._crypto?this._crypto.getEventSenderDeviceInfo(e):null},N.prototype.isEventSenderVerified=async function(e){const t=await this.getEventSenderDeviceInfo(e);return!!t&&t.isVerified()},N.prototype.cancelAndResendEventRoomKeyRequest=function(e){return e.cancelAndResendKeyRequest(this._crypto,this.getUserId())},N.prototype.setRoomEncryption=function(e,t){if(!this._crypto)throw new Error("End-to-End encryption disabled");return this._crypto.setRoomEncryption(e,t)},N.prototype.isRoomEncrypted=function(e){const t=this.getRoom(e);return!!t&&(!!t.currentState.getStateEvents("m.room.encryption","")||this._roomList.isRoomEncrypted(e))},N.prototype.forceDiscardSession=function(e){if(!this._crypto)throw new Error("End-to-End encryption disabled");this._crypto.forceDiscardSession(e)},N.prototype.exportRoomKeys=function(){return this._crypto?this._crypto.exportRoomKeys():Promise.reject(new Error("End-to-end encryption disabled"))},N.prototype.importRoomKeys=function(e,t){if(!this._crypto)throw new Error("End-to-end encryption disabled");return this._crypto.importRoomKeys(e,t)},N.prototype.checkKeyBackup=function(){return this._crypto.checkKeyBackup()},N.prototype.getKeyBackupVersion=function(){return this._http.authedRequest(void 0,"GET","/room_keys/version",void 0,void 0,{prefix:_.PREFIX_UNSTABLE}).then((e=>{if(e.algorithm!==b.MEGOLM_BACKUP_ALGORITHM){const t="Unknown backup algorithm: "+e.algorithm;return Promise.reject(t)}if("object"==typeof e.auth_data&&e.auth_data.public_key)return e;{const e="Invalid backup data returned";return Promise.reject(e)}})).catch((e=>{if("M_NOT_FOUND"===e.errcode)return null;throw e}))},N.prototype.isKeyBackupTrusted=function(e){return this._crypto.isKeyBackupTrusted(e)},N.prototype.getKeyBackupEnabled=function(){if(null===this._crypto)throw new Error("End-to-end encryption disabled");return this._crypto._checkedForBackup?Boolean(this._crypto.backupKey):null},N.prototype.enableKeyBackup=function(e){if(null===this._crypto)throw new Error("End-to-end encryption disabled");this._crypto.backupInfo=e,this._crypto.backupKey&&this._crypto.backupKey.free(),this._crypto.backupKey=new n.g.Olm.PkEncryption,this._crypto.backupKey.set_recipient_key(e.auth_data.public_key),this.emit("crypto.keyBackupStatus",!0),this._crypto.scheduleKeyBackupSend()},N.prototype.disableKeyBackup=function(){if(null===this._crypto)throw new Error("End-to-end encryption disabled");this._crypto.backupInfo=null,this._crypto.backupKey&&this._crypto.backupKey.free(),this._crypto.backupKey=null,this.emit("crypto.keyBackupStatus",!1)},N.prototype.prepareKeyBackupVersion=async function(e,{secureSecretStorage:t=!1}={}){if(null===this._crypto)throw new Error("End-to-end encryption disabled");const{keyInfo:n,encodedPrivateKey:o,privateKey:r}=await this.createRecoveryKeyFromPassphrase(e);t&&(await this.storeSecret("m.megolm_backup.v1",(0,b.encodeBase64)(r)),E.logger.info("Key backup private key stored in secret storage"));const i={public_key:n.pubkey};return n.passphrase&&(i.private_key_salt=n.passphrase.salt,i.private_key_iterations=n.passphrase.iterations),{algorithm:b.MEGOLM_BACKUP_ALGORITHM,auth_data:i,recovery_key:o}},N.prototype.isKeyBackupKeyStored=async function(){return this.isSecretStored("m.megolm_backup.v1",!1)},N.prototype.createKeyBackupVersion=async function(e){if(null===this._crypto)throw new Error("End-to-end encryption disabled");const t={algorithm:e.algorithm,auth_data:e.auth_data};await this._crypto._signObject(t.auth_data),this._cryptoCallbacks.getCrossSigningKey&&this._crypto._crossSigningInfo.getId()&&await this._crypto._crossSigningInfo.signObject(t.auth_data,"master");const n=await this._http.authedRequest(void 0,"POST","/room_keys/version",void 0,t,{prefix:_.PREFIX_UNSTABLE});return await this.checkKeyBackup(),this.getKeyBackupEnabled()||E.logger.error("Key backup not usable even though we just created it"),n},N.prototype.deleteKeyBackupVersion=function(e){if(null===this._crypto)throw new Error("End-to-end encryption disabled");this._crypto.backupInfo&&this._crypto.backupInfo.version===e&&this.disableKeyBackup();const t=m.encodeUri("/room_keys/version/$version",{$version:e});return this._http.authedRequest(void 0,"DELETE",t,void 0,void 0,{prefix:_.PREFIX_UNSTABLE})},N.prototype._makeKeyBackupPath=function(e,t,n){let o;return o=void 0!==t?m.encodeUri("/room_keys/keys/$roomId/$sessionId",{$roomId:e,$sessionId:t}):void 0!==e?m.encodeUri("/room_keys/keys/$roomId",{$roomId:e}):"/room_keys/keys",{path:o,queryData:void 0===n?void 0:{version:n}}},N.prototype.sendKeyBackup=function(e,t,n,o){if(null===this._crypto)throw new Error("End-to-end encryption disabled");const r=this._makeKeyBackupPath(e,t,n);return this._http.authedRequest(void 0,"PUT",r.path,r.queryData,o,{prefix:_.PREFIX_UNSTABLE})},N.prototype.scheduleAllGroupSessionsForBackup=async function(){if(null===this._crypto)throw new Error("End-to-end encryption disabled");await this._crypto.scheduleAllGroupSessionsForBackup()},N.prototype.flagAllGroupSessionsForBackup=function(){if(null===this._crypto)throw new Error("End-to-end encryption disabled");return this._crypto.flagAllGroupSessionsForBackup()},N.prototype.isValidRecoveryKey=function(e){try{return(0,D.decodeRecoveryKey)(e),!0}catch(e){return!1}},N.prototype.keyBackupKeyFromPassword=function(e,t){return(0,S.keyFromAuthData)(t.auth_data,e)},N.prototype.keyBackupKeyFromRecoveryKey=function(e){return(0,D.decodeRecoveryKey)(e)},N.RESTORE_BACKUP_ERROR_BAD_KEY="RESTORE_BACKUP_ERROR_BAD_KEY",N.prototype.restoreKeyBackupWithPassword=async function(e,t,n,o,r){const i=await(0,S.keyFromAuthData)(o.auth_data,e);return this._restoreKeyBackup(i,t,n,o,r)},N.prototype.restoreKeyBackupWithSecretStorage=async function(e,t,n,o){const r=await this.getSecret("m.megolm_backup.v1"),i=(0,k.fixBackupKey)(r);if(i){const[e]=await this._crypto.getSecretStorageKey();await this.storeSecret("m.megolm_backup.v1",i,[e])}const a=(0,b.decodeBase64)(i||r);return this._restoreKeyBackup(a,t,n,e,o)},N.prototype.restoreKeyBackupWithRecoveryKey=function(e,t,n,o,r){const i=(0,D.decodeRecoveryKey)(e);return this._restoreKeyBackup(i,t,n,o,r)},N.prototype.restoreKeyBackupWithCache=async function(e,t,n,o){const r=await this._crypto.getSessionBackupPrivateKey();if(!r)throw new Error("Couldn't get key");return this._restoreKeyBackup(r,e,t,n,o)},N.prototype._restoreKeyBackup=function(e,t,o,r,{cacheCompleteCallback:i,progressCallback:a}={}){if(null===this._crypto)throw new Error("End-to-end encryption disabled");let s=0,u=[];const c=this._makeKeyBackupPath(t,o,r.version),l=new n.g.Olm.PkDecryption;let d;try{d=l.init_with_private_key(e)}catch(e){throw l.free(),e}return d!==r.auth_data.public_key?Promise.reject({errcode:N.RESTORE_BACKUP_ERROR_BAD_KEY}):(this._crypto.storeSessionBackupPrivateKey(e).catch((e=>{E.logger.warn("Error caching session backup key:",e)})).then(i),a&&a({stage:"fetch"}),this._http.authedRequest(void 0,"GET",c.path,c.queryData,void 0,{prefix:_.PREFIX_UNSTABLE}).then((e=>{if(e.rooms)for(const[t,n]of Object.entries(e.rooms)){if(!n.sessions)continue;s+=Object.keys(n.sessions).length;const e=O(n.sessions,l,t);for(const n of e)n.room_id=t,u.push(n)}else if(e.sessions)s=Object.keys(e.sessions).length,u=O(e.sessions,l,t);else{s=1;try{const n=B(e,l);n.room_id=t,n.session_id=o,u.push(n)}catch(e){E.logger.log("Failed to decrypt megolm session from backup",e)}}return this.importRoomKeys(u,{progressCallback:a,untrusted:!0,source:"backup"})})).then((()=>this._crypto.setTrustedBackupPubKey(d))).then((()=>({total:s,imported:u.length}))).finally((()=>{l.free()})))},N.prototype.deleteKeysFromBackup=function(e,t,n){if(null===this._crypto)throw new Error("End-to-end encryption disabled");const o=this._makeKeyBackupPath(e,t,n);return this._http.authedRequest(void 0,"DELETE",o.path,o.queryData,void 0,{prefix:_.PREFIX_UNSTABLE})},N.prototype.sendSharedHistoryKeys=async function(e,t){if(null===this._crypto)throw new Error("End-to-end encryption disabled");const n=this._roomList.getRoomEncryption(e);if(!n)return void E.logger.error("Unknown room. Not sharing decryption keys");const o=await this._crypto.downloadKeys(t),r={};for(const[e,t]of Object.entries(o))r[e]=Object.values(t);const i=this._crypto._getRoomDecryptor(e,n.algorithm);i.sendSharedHistoryInboundSessions?await i.sendSharedHistoryInboundSessions(r):E.logger.warning("Algorithm does not support sharing previous keys",n.algorithm)},N.prototype.getGroup=function(e){return this.store.getGroup(e)},N.prototype.getGroups=function(){return this.store.getGroups()},N.prototype.getMediaConfig=function(e){return this._http.authedRequest(e,"GET","/config",void 0,void 0,{prefix:_.PREFIX_MEDIA_R0})},N.prototype.getRoom=function(e){return this.store.getRoom(e)},N.prototype.getRooms=function(){return this.store.getRooms()},N.prototype.getVisibleRooms=function(){const e=this.store.getRooms(),t=new Set;for(const n of e){const e=n.currentState.getStateEvents("m.room.create","");if(e){const n=e.getContent().predecessor;n&&n.room_id&&t.add(n.room_id)}}return e.filter((e=>!e.currentState.getStateEvents("m.room.tombstone","")||!t.has(e.roomId)))},N.prototype.getUser=function(e){return this.store.getUser(e)},N.prototype.getUsers=function(){return this.store.getUsers()},N.prototype.setAccountData=function(e,t,n){const o=m.encodeUri("/user/$userId/account_data/$type",{$userId:this.credentials.userId,$type:e}),r=(0,_.retryNetworkOperation)(5,(()=>this._http.authedRequest(void 0,"PUT",o,void 0,t)));return n&&r.then((e=>n(null,e)),n),r},N.prototype.getAccountData=function(e){return this.store.getAccountData(e)},N.prototype.getAccountDataFromServer=async function(e){if(this.isInitialSyncComplete()){const t=this.store.getAccountData(e);return t?t.getContent():null}const t=m.encodeUri("/user/$userId/account_data/$type",{$userId:this.credentials.userId,$type:e});try{return await this._http.authedRequest(void 0,"GET",t,void 0)}catch(e){if(e.data&&"M_NOT_FOUND"===e.data.errcode)return null;throw e}},N.prototype.getIgnoredUsers=function(){const e=this.getAccountData("m.ignored_user_list");return e&&e.getContent()&&e.getContent().ignored_users?Object.keys(e.getContent().ignored_users):[]},N.prototype.setIgnoredUsers=function(e,t){const n={ignored_users:{}};return e.map((e=>n.ignored_users[e]={})),this.setAccountData("m.ignored_user_list",n,t)},N.prototype.isUserIgnored=function(e){return-1!==this.getIgnoredUsers().indexOf(e)},N.prototype.joinRoom=function(e,t,n){if(m.isFunction(t))throw new Error("Expected 'opts' object, got function.");void 0===(t=t||{}).syncRoom&&(t.syncRoom=!0);const o=this.getRoom(e);if(o&&o.hasMembershipState(this.credentials.userId,"join"))return Promise.resolve(o);let r=Promise.resolve();t.inviteSignUrl&&(r=this._http.requestOtherUrl(void 0,"POST",t.inviteSignUrl,{mxid:this.credentials.userId}));const i={};t.viaServers&&(i.server_name=t.viaServers);const a={qsStringifyOptions:{arrayFormat:"repeat"}},s=this;return new Promise(((o,u)=>{r.then((function(t){const n={};t&&(n.third_party_signed=t);const o=m.encodeUri("/join/$roomid",{$roomid:e});return s._http.authedRequest(void 0,"POST",o,i,n,a)})).then((function(e){const n=e.room_id,o=new c.SyncApi(s,s._clientOpts).createRoom(n);return t.syncRoom,Promise.resolve(o)})).then((function(e){G(n,o,e)}),(function(e){K(n,u,e)}))}))},N.prototype.resendEvent=function(e,t){return j(t,e,l.EventStatus.SENDING),U(this,t,e)},N.prototype.cancelPendingEvent=function(e){if([l.EventStatus.QUEUED,l.EventStatus.NOT_SENT].indexOf(e.status)<0)throw new Error("cannot cancel an event with status "+e.status);this.scheduler&&this.scheduler.removeEventFromQueue(e),j(this.getRoom(e.getRoomId()),e,l.EventStatus.CANCELLED)},N.prototype.setRoomName=function(e,t,n){return this.sendStateEvent(e,"m.room.name",{name:t},void 0,n)},N.prototype.setRoomTopic=function(e,t,n){return this.sendStateEvent(e,"m.room.topic",{topic:t},void 0,n)},N.prototype.getRoomTags=function(e,t){const n=m.encodeUri("/user/$userId/rooms/$roomId/tags/",{$userId:this.credentials.userId,$roomId:e});return this._http.authedRequest(t,"GET",n,void 0)},N.prototype.setRoomTag=function(e,t,n,o){const r=m.encodeUri("/user/$userId/rooms/$roomId/tags/$tag",{$userId:this.credentials.userId,$roomId:e,$tag:t});return this._http.authedRequest(o,"PUT",r,void 0,n)},N.prototype.deleteRoomTag=function(e,t,n){const o=m.encodeUri("/user/$userId/rooms/$roomId/tags/$tag",{$userId:this.credentials.userId,$roomId:e,$tag:t});return this._http.authedRequest(n,"DELETE",o,void 0,void 0)},N.prototype.setRoomAccountData=function(e,t,n,o){const r=m.encodeUri("/user/$userId/rooms/$roomId/account_data/$type",{$userId:this.credentials.userId,$roomId:e,$type:t});return this._http.authedRequest(o,"PUT",r,void 0,n)},N.prototype.setPowerLevel=function(e,t,n,o,r){let i={users:{}};o&&"m.room.power_levels"===o.getType()&&(i=m.deepCopy(o.getContent())),i.users[t]=n;const a=m.encodeUri("/rooms/$roomId/state/m.room.power_levels",{$roomId:e});return this._http.authedRequest(r,"PUT",a,void 0,i)},N.prototype.sendEvent=function(e,t,n,o,r){return this._sendCompleteEvent(e,{type:t,content:n},o,r)},N.prototype._sendCompleteEvent=function(e,t,n,o){m.isFunction(n)&&(o=n,n=void 0),n||(n=this.makeTxnId());const r=new l.MatrixEvent(Object.assign(t,{event_id:"~"+e+":"+n,user_id:this.credentials.userId,sender:this.credentials.userId,room_id:e,origin_server_ts:(new Date).getTime()})),i=this.getRoom(e),a=r.getAssociatedId();if(a&&a.startsWith("~")){const e=i.getPendingEvents().find((e=>e.getId()===a));e.once("Event.localEventIdReplaced",(()=>{r.updateAssociatedId(e.getId())}))}const s=r.getType();return E.logger.log(`sendEvent of type ${s} in ${e} with txnId ${n}`),r.setTxnId(n),r.setStatus(l.EventStatus.SENDING),i&&i.addPendingEvent(r,n),r.status===l.EventStatus.NOT_SENT?Promise.reject(new Error("Event blocked by other events not yet sent")):U(this,i,r,o)},N.prototype.redactEvent=function(e,t,n,o){const r=("object"==typeof o?o:{}).reason,i="function"==typeof o?o:void 0;return this._sendCompleteEvent(e,{type:"m.room.redaction",content:{reason:r},redacts:t},n,i)},N.prototype.sendMessage=function(e,t,n,o){return m.isFunction(n)&&(o=n,n=void 0),this.sendEvent(e,"m.room.message",t,n,o)},N.prototype.sendTextMessage=function(e,t,n,o){const r=y.makeTextMessage(t);return this.sendMessage(e,r,n,o)},N.prototype.sendNotice=function(e,t,n,o){const r=y.makeNotice(t);return this.sendMessage(e,r,n,o)},N.prototype.sendEmoteMessage=function(e,t,n,o){const r=y.makeEmoteMessage(t);return this.sendMessage(e,r,n,o)},N.prototype.sendImageMessage=function(e,t,n,o,r){m.isFunction(o)&&(r=o,o=void 0),o||(o="Image");const i={msgtype:"m.image",url:t,info:n,body:o};return this.sendMessage(e,i,r)},N.prototype.sendStickerMessage=function(e,t,n,o,r){m.isFunction(o)&&(r=o,o=void 0),o||(o="Sticker");const i={url:t,info:n,body:o};return this.sendEvent(e,"m.sticker",i,r,void 0)},N.prototype.sendHtmlMessage=function(e,t,n,o){const r=y.makeHtmlMessage(t,n);return this.sendMessage(e,r,o)},N.prototype.sendHtmlNotice=function(e,t,n,o){const r=y.makeHtmlNotice(t,n);return this.sendMessage(e,r,o)},N.prototype.sendHtmlEmote=function(e,t,n,o){const r=y.makeHtmlEmote(t,n);return this.sendMessage(e,r,o)},N.prototype.sendReceipt=function(e,t,n,o){if("function"==typeof n&&(o=n,n={}),this.isGuest())return Promise.resolve({});const r=m.encodeUri("/rooms/$roomId/receipt/$receiptType/$eventId",{$roomId:e.getRoomId(),$receiptType:t,$eventId:e.getId()}),i=this._http.authedRequest(o,"POST",r,void 0,n||{}),a=this.getRoom(e.getRoomId());return a&&a._addLocalEchoReceipt(this.credentials.userId,e,t),i},N.prototype.sendReadReceipt=async function(e,t,n){"function"==typeof t&&(n=t,t={}),t||(t={});const o=e.getId(),r=this.getRoom(e.getRoomId());if(r&&r.hasPendingEvent(o))throw new Error(`Cannot set read receipt to a pending event (${o})`);const i={"m.hidden":Boolean(t.hidden)};return this.sendReceipt(e,"m.read",i,n)},N.prototype.setRoomReadMarkers=async function(e,t,n,o){const r=this.getRoom(e);if(r&&r.hasPendingEvent(t))throw new Error(`Cannot set read marker to a pending event (${t})`);let i;if(n){if(i=n.getId(),r&&r.hasPendingEvent(i))throw new Error(`Cannot set read receipt to a pending event (${i})`);r&&r._addLocalEchoReceipt(this.credentials.userId,n,"m.read")}return this.setRoomReadMarkersHttpRequest(e,t,i,o)},N.prototype.getUrlPreview=function(e,t,n){const o=(t=6e4*Math.floor(t/6e4))+"_"+e,r=this.urlPreviewCache[o];if(r)return n&&r.then(n).catch(n),r;const i=this._http.authedRequest(n,"GET","/preview_url",{url:e,ts:t},void 0,{prefix:_.PREFIX_MEDIA_R0});return this.urlPreviewCache[o]=i,i},N.prototype.sendTyping=function(e,t,n,o){if(this.isGuest())return Promise.resolve({});const r=m.encodeUri("/rooms/$roomId/typing/$userId",{$roomId:e,$userId:this.credentials.userId}),i={typing:t};return t&&(i.timeout=n||2e4),this._http.authedRequest(o,"PUT",r,void 0,i)},N.prototype.getRoomUpgradeHistory=function(e,t=!1){let n=this.getRoom(e);if(!n)return[];const o=[n];let r=n.currentState.getStateEvents("m.room.create","");for(;r;){E.logger.log(`Looking at ${r.getId()}`);const e=r.getContent().predecessor;if(!e||!e.room_id)break;{E.logger.log(`Looking at predecessor ${e.room_id}`);const n=this.getRoom(e.room_id);if(!n)break;if(t){const e=n.currentState.getStateEvents("m.room.tombstone","");if(!e||e.getContent().replacement_room!==n.roomId)break}o.splice(0,0,n),r=n.currentState.getStateEvents("m.room.create","")}}let i=n.currentState.getStateEvents("m.room.tombstone","");for(;i;){const e=this.getRoom(i.getContent().replacement_room);if(!e)break;if(e.roomId===n.roomId)break;if(t){if(r=e.currentState.getStateEvents("m.room.create",""),!r||!r.getContent().predecessor)break;if(r.getContent().predecessor.room_id!==n.roomId)break}if(o.push(e),new Set(o.map((e=>e.roomId))).sizethis.leave(e).then((()=>{r[e]=null})).catch((t=>(r[e]=t,null)));for(const e of o)i.push(a(e.roomId));return Promise.all(i).then((()=>r))},N.prototype.ban=function(e,t,n,o){return z(this,e,t,"ban",n,o)},N.prototype.forget=function(e,t,n){void 0===t&&(t=!0);const o=z(this,e,void 0,"forget",void 0,n);if(!t)return o;const r=this;return o.then((function(t){return r.store.removeRoom(e),r.emit("deleteRoom",e),t}))},N.prototype.unban=function(e,t,n){const o=m.encodeUri("/rooms/$roomId/unban",{$roomId:e}),r={user_id:t};return this._http.authedRequest(n,"POST",o,void 0,r)},N.prototype.kick=function(e,t,n,o){return function(e,t,n,o,r,i){m.isFunction(r)&&(i=r,r=void 0);const a=m.encodeUri("/rooms/$roomId/state/m.room.member/$userId",{$roomId:t,$userId:n});return e._http.authedRequest(i,"PUT",a,void 0,{membership:"leave",reason:r})}(this,e,t,0,n,o)},N.prototype.getPushActionsForEvent=function(e){return e.getPushActions()||e.setPushActions(this._pushProcessor.actionsForEvent(e)),e.getPushActions()},N.prototype.setProfileInfo=function(e,t,n){const o=m.encodeUri("/profile/$userId/$info",{$userId:this.credentials.userId,$info:e});return this._http.authedRequest(n,"PUT",o,void 0,t)},N.prototype.setDisplayName=async function(e,t){const n=await this.setProfileInfo("displayname",{displayname:e},t),o=this.getUser(this.getUserId());return o&&(o.displayName=e,o.emit("User.displayName",o.events.presence,o)),n},N.prototype.setAvatarUrl=async function(e,t){const n=await this.setProfileInfo("avatar_url",{avatar_url:e},t),o=this.getUser(this.getUserId());return o&&(o.avatarUrl=e,o.emit("User.avatarUrl",o.events.presence,o)),n},N.prototype.mxcUrlToHttp=function(e,t,n,o,r){return(0,F.getHttpUriForMxc)(this.baseUrl,e,t,n,o,r)},N.prototype._unstable_setStatusMessage=function(e){const t="im.vector.user_status";return Promise.all(this.getRooms().map((n=>{const o="join"===n.getMyMembership(),r=2===n.getInvitedAndJoinedMemberCount();return o&&r&&n.currentState.mayClientSendStateEvent(t,this)?this.sendStateEvent(n.roomId,t,{status:e},this.getUserId()):Promise.resolve()})))},N.prototype.setPresence=function(e,t){const n=m.encodeUri("/presence/$userId/status",{$userId:this.credentials.userId});if("string"==typeof e&&(e={presence:e}),-1==["offline","online","unavailable"].indexOf(e.presence))throw new Error("Bad presence value: "+e.presence);return this._http.authedRequest(t,"PUT",n,void 0,e)},N.prototype.getPresence=function(e,t){const n=m.encodeUri("/presence/$userId/status",{$userId:e});return this._http.authedRequest(t,"GET",n,void 0,void 0)},N.prototype.scrollback=function(e,t,n){m.isFunction(t)&&(n=t,t=void 0),t=t||30;let o=0,r=this._ongoingScrollbacks[e.roomId]||{};if(r.promise)return r.promise;if(r.errorTs){const e=Date.now()-r.errorTs;o=Math.max(3e3-e,0)}if(null===e.oldState.paginationToken)return Promise.resolve(e);const i=this.store.scrollback(e,t).length;if(i===t)return Promise.resolve(e);t-=i;const a=this,s=new Promise(((r,i)=>{(0,m.sleep)(o).then((function(){return a._createMessagesRequest(e.roomId,e.oldState.paginationToken,t,"b")})).then((function(t){const o=t.chunk.map($(a));if(t.state){const n=t.state.map($(a));e.currentState.setUnknownStateEvents(n)}e.addEventsToTimeline(o,!0,e.getLiveTimeline()),e.oldState.paginationToken=t.end,0===t.chunk.length&&(e.oldState.paginationToken=null),a.store.storeEvents(e,o,t.end,!0),a._ongoingScrollbacks[e.roomId]=null,G(n,r,e)}),(function(t){a._ongoingScrollbacks[e.roomId]={errorTs:Date.now()},K(n,i,t)}))}));return r={promise:s,errorTs:null},this._ongoingScrollbacks[e.roomId]=r,s},N.prototype.getEventTimeline=function(e,t){if(!this.timelineSupport)throw new Error("timeline support is disabled. Set the 'timelineSupport' parameter to true when creating MatrixClient to enable it.");if(e.getTimelineForEvent(t))return Promise.resolve(e.getTimelineForEvent(t));const n=m.encodeUri("/rooms/$roomId/context/$eventId",{$roomId:e.room.roomId,$eventId:t});let o;this._clientOpts.lazyLoadMembers&&(o={filter:JSON.stringify(u.Filter.LAZY_LOADING_MESSAGES_FILTER)});const r=this;return r._http.authedRequest(void 0,"GET",n,o).then((function(n){if(!n.event)throw new Error("'event' not in '/context' result - homeserver too old?");if(e.getTimelineForEvent(t))return e.getTimelineForEvent(t);n.events_after.reverse();const o=n.events_after.concat([n.event]).concat(n.events_before).map(r.getEventMapper());let i=e.getTimelineForEvent(o[0].getId());if(i){const e=n.state.map(r.getEventMapper());i.getState(d.EventTimeline.BACKWARDS).setUnknownStateEvents(e)}else i=e.addTimeline(),i.initialiseState(n.state.map(r.getEventMapper())),i.getState(d.EventTimeline.FORWARDS).paginationToken=n.end;return e.addEventsToTimeline(o,!0,i,n.start),e.getTimelineForEvent(t)||i}))},N.prototype._createMessagesRequest=function(e,t,n,o,r){const i=m.encodeUri("/rooms/$roomId/messages",{$roomId:e});void 0===n&&(n=30);const a={from:t,limit:n,dir:o};let s=null;return this._clientOpts.lazyLoadMembers&&(s=Object.assign({},u.Filter.LAZY_LOADING_MESSAGES_FILTER)),r&&(s=s||{},Object.assign(s,r.getRoomTimelineFilterComponent())),s&&(a.filter=JSON.stringify(s)),this._http.authedRequest(void 0,"GET",i,a)},N.prototype.paginateEventTimeline=function(e,t){const n=e.getTimelineSet()===this._notifTimelineSet,o=(t=t||{}).backwards||!1;if(n&&!o)throw new Error("paginateNotifTimeline can only paginate backwards");const r=o?d.EventTimeline.BACKWARDS:d.EventTimeline.FORWARDS,i=e.getPaginationToken(r);if(!i)return Promise.resolve(!1);const a=e._paginationRequests[r];if(a)return a;let s,u,c;const l=this;if(n)s="/notifications",u={limit:"limit"in t?t.limit:30,only:"highlight"},i&&"end"!==i&&(u.from=i),c=this._http.authedRequest(void 0,"GET","/notifications",u,void 0).then((function(t){const n=t.next_token,i=[];for(let e=0;e{r.then((function(){o.getPushRules().then((function(t){o.pushRules=t,e()}),(function(e){t(e)}))}),(function(e){o.getPushRules().then((function(n){o.pushRules=n,t(e)}),(function(n){t(e)}))}))}))},N.prototype.searchMessageText=function(e,t){const n={search_term:e.query};return"keys"in e&&(n.keys=e.keys),this.search({body:{search_categories:{room_events:n}}},t)},N.prototype.searchRoomEvents=function(e){const t={search_categories:{room_events:{search_term:e.term,filter:e.filter,order_by:"recent",event_context:{before_limit:1,after_limit:1,include_profile:!0}}}},n={_query:t,results:[],highlights:[]};return this.search({body:t}).then(this._processRoomEventsSearch.bind(this,n))},N.prototype.backPaginateRoomEventsSearch=function(e){if(!e.next_batch)return Promise.reject(new Error("Cannot backpaginate event search any further"));if(e.pendingRequest)return e.pendingRequest;const t={body:e._query,next_batch:e.next_batch},n=this.search(t).then(this._processRoomEventsSearch.bind(this,e)).finally((function(){e.pendingRequest=null}));return e.pendingRequest=n,n},N.prototype._processRoomEventsSearch=function(e,t){const n=t.search_categories.room_events;e.count=n.count,e.next_batch=n.next_batch;const o={};n.highlights.forEach((function(e){o[e]=1})),e.highlights.forEach((function(e){o[e]=1})),e.highlights=Object.keys(o);const r=n.results?n.results.length:0;for(let t=0;tM)E.logger.debug("TURN creds are valid for another "+t+" ms: not fetching new ones."),e=!0;else{E.logger.debug("Fetching new TURN credentials");try{const t=await this.turnServer();if(t.uris){E.logger.log("Got TURN URIs: "+t.uris+" refresh in "+t.ttl+" secs");const n={urls:t.uris,username:t.username,credential:t.password};this._turnServers=[n],this._turnServersExpiry=Date.now()+1e3*t.ttl,e=!0}}catch(e){E.logger.error("Failed to get TURN URIs",e),403===e.httpStatus&&(E.logger.info("TURN access unavailable for this account: stopping credentials checks"),null!==this._checkTurnServersIntervalID&&n.g.clearInterval(this._checkTurnServersIntervalID),this._checkTurnServersIntervalID=null)}}return e},N.prototype.setFallbackICEServerAllowed=function(e){this._fallbackICEServerAllowed=e},N.prototype.isFallbackICEServerAllowed=function(){return this._fallbackICEServerAllowed},N.prototype.isSynapseAdministrator=function(){const e=m.encodeUri("/_synapse/admin/v1/users/$userId/admin",{$userId:this.getUserId()});return this._http.authedRequest(void 0,"GET",e,void 0,void 0,{prefix:""}).then((e=>e.admin))},N.prototype.whoisSynapseUser=function(e){const t=m.encodeUri("/_synapse/admin/v1/whois/$userId",{$userId:e});return this._http.authedRequest(void 0,"GET",t,void 0,void 0,{prefix:""})},N.prototype.deactivateSynapseUser=function(e){const t=m.encodeUri("/_synapse/admin/v1/deactivate/$userId",{$userId:e});return this._http.authedRequest(void 0,"POST",t,void 0,void 0,{prefix:""})},N.prototype.startClient=async function(e){if(this.clientRunning)return;this.clientRunning=!0,"number"==typeof e&&(e={initialSyncLimit:e});const t=this.getUserId();t&&this.store.storeUser(new A.User(t)),this._crypto&&(this._crypto.uploadDeviceKeys(),this._crypto.start()),this._supportsVoip&&(this._checkTurnServersIntervalID=setInterval((()=>{this._checkTurnServers()}),M),this._checkTurnServers()),this._syncApi&&(E.logger.error("Still have sync object whilst not running: stopping old one"),this._syncApi.stop()),(e=Object.assign({},e)).crypto=this._crypto,e.canResetEntireTimeline=e=>!!this._canResetTimelineCallback&&this._canResetTimelineCallback(e),this._clientOpts=e,this._syncApi=new c.SyncApi(this,e),this._syncApi.sync(),void 0!==e.clientWellKnownPollPeriod&&(this._clientWellKnownIntervalID=setInterval((()=>{this._fetchClientWellKnown()}),1e3*e.clientWellKnownPollPeriod),this._fetchClientWellKnown())},N.prototype._fetchClientWellKnown=async function(){this._clientWellKnownPromise=T.AutoDiscovery.getRawClientConfig(this.getDomain()),this._clientWellKnown=await this._clientWellKnownPromise,this.emit("WellKnown.client",this._clientWellKnown)},N.prototype.getClientWellKnown=function(){return this._clientWellKnown},N.prototype.waitForClientWellKnown=function(){return this._clientWellKnownPromise},N.prototype._storeClientOptions=function(){const e=["boolean","string","number"],t=Object.entries(this._clientOpts).filter((([t,n])=>e.includes(typeof n))).reduce(((e,[t,n])=>(e[t]=n,e)),{});return this.store.storeClientOptions(t)},N.prototype._unstable_getSharedRooms=async function(e){if(!await this.doesServerSupportUnstableFeature("uk.half-shot.msc2666"))throw Error("Server does not support shared_rooms API");const t=m.encodeUri("/uk.half-shot.msc2666/user/shared_rooms/$userId",{$userId:e});return(await this._http.authedRequest(void 0,"GET",t,void 0,void 0,{prefix:_.PREFIX_UNSTABLE})).joined},N.prototype.stopClient=function(){E.logger.log("stopping MatrixClient"),this.clientRunning=!1,this._syncApi&&(this._syncApi.stop(),this._syncApi=null),this._crypto&&this._crypto.stop(),this._peekSync&&this._peekSync.stopPeeking(),this._callEventHandler&&(this._callEventHandler.stop(),this._callEventHandler=null),n.g.clearInterval(this._checkTurnServersIntervalID),void 0!==this._clientWellKnownIntervalID&&n.g.clearInterval(this._clientWellKnownIntervalID)},N.prototype.getVersions=function(){return this._serverVersionsPromise||(this._serverVersionsPromise=this._http.request(void 0,"GET","/_matrix/client/versions",void 0,void 0,{prefix:""}).catch((e=>{throw this._serverVersionsPromise=null,e}))),this._serverVersionsPromise},N.prototype.isVersionSupported=async function(e){const{versions:t}=await this.getVersions();return t&&t.includes(e)},N.prototype.doesServerSupportLazyLoading=async function(){const e=await this.getVersions();if(!e)return!1;const t=e.versions,n=e.unstable_features;return t&&t.includes("r0.5.0")||n&&n["m.lazy_load_members"]},N.prototype.doesServerRequireIdServerParam=async function(){const e=await this.getVersions();if(!e)return!0;const t=e.versions;if(t&&t.includes("r0.6.0"))return!1;const n=e.unstable_features;return!n||void 0===n["m.require_identity_server"]||n["m.require_identity_server"]},N.prototype.doesServerAcceptIdentityAccessToken=async function(){const e=await this.getVersions();if(!e)return!1;const t=e.versions,n=e.unstable_features;return t&&t.includes("r0.6.0")||n&&n["m.id_access_token"]},N.prototype.doesServerSupportSeparateAddAndBind=async function(){const e=await this.getVersions();if(!e)return!1;const t=e.versions,n=e.unstable_features;return t&&t.includes("r0.6.0")||n&&n["m.separate_add_and_bind"]},N.prototype.doesServerSupportUnstableFeature=async function(e){const t=await this.getVersions();if(!t)return!1;const n=t.unstable_features;return n&&!!n[e]},N.prototype.doesServerForceEncryptionForPreset=async function(e){const t=await this.getVersions();if(!t)return!1;const n=t.unstable_features;return n&&!!n[`io.element.e2ee_forced.${e}`]},N.prototype.hasLazyLoadMembersEnabled=function(){return!!this._clientOpts.lazyLoadMembers},N.prototype.setCanResetTimelineCallback=function(e){this._canResetTimelineCallback=e},N.prototype.getCanResetTimelineCallback=function(){return this._canResetTimelineCallback},N.prototype.relations=async function(e,t,n,o,r={}){const i=function(e,t,n){return"m.reaction"===n?n:e.isRoomEncrypted(t)?"m.room.encrypted":n}(this,e,o),a=await this.fetchRelations(e,t,n,i,r),s=this.getEventMapper();let u;a.original_event&&(u=s(a.original_event));let c=a.chunk.map(s);if("m.room.encrypted"===i){const e=u?c.concat(u):c;await Promise.all(e.map((e=>new Promise((t=>e.once("Event.decrypted",t)))))),c=c.filter((e=>e.getType()===o))}return u&&"m.replace"===n&&(c=c.filter((e=>e.getSender()===u.getSender()))),{originalEvent:u,events:c,nextBatch:a.next_batch}},N.prototype.getEventMapper=function(e){return $(this,e)},N.prototype.getCrossSigningCacheCallbacks=function(){return this._crypto&&this._crypto._crossSigningInfo.getCacheCallbacks()},N.prototype.generateClientSecret=function(){return(0,x.randomString)(32)},N.prototype.decryptEventIfNeeded=function(e,t){return e.shouldAttemptDecryption()&&e.attemptDecryption(this._crypto,t),e.isBeingDecrypted()?e._decryptionPromise:Promise.resolve()}},44656:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.makeHtmlMessage=function(e,t){return{msgtype:"m.text",format:"org.matrix.custom.html",body:e,formatted_body:t}},t.makeHtmlNotice=function(e,t){return{msgtype:"m.notice",format:"org.matrix.custom.html",body:e,formatted_body:t}},t.makeHtmlEmote=function(e,t){return{msgtype:"m.emote",format:"org.matrix.custom.html",body:e,formatted_body:t}},t.makeTextMessage=function(e){return{msgtype:"m.text",body:e}},t.makeNotice=function(e){return{msgtype:"m.notice",body:e}},t.makeEmoteMessage=function(e){return{msgtype:"m.emote",body:e}}},73667:(e,t,n)=>{"use strict";var o=n(20862);Object.defineProperty(t,"__esModule",{value:!0}),t.getHttpUriForMxc=function(e,t,n,o,i,a){if("string"!=typeof t||!t)return"";if(0!==t.indexOf("mxc://"))return a?t:"";let s=t.slice(6),u="/_matrix/media/r0/download/";const c={};n&&(c.width=Math.round(n)),o&&(c.height=Math.round(o)),i&&(c.method=i),Object.keys(c).length>0&&(u="/_matrix/media/r0/thumbnail/");const l=s.indexOf("#");let d="";return l>=0&&(d=s.substr(l),s=s.substr(0,l)),e+u+s+(0===Object.keys(c).length?"":"?"+r.encodeParams(c))+d};var r=o(n(3102))},3075:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.createCryptoStoreCacheCallbacks=function(e,t){return{getCrossSigningKeyCache:async function(n,r){const i=await new Promise((t=>e.doTxn("readonly",[a.IndexedDBCryptoStore.STORE_ACCOUNT],(o=>{e.getSecretStorePrivateKey(o,t,n)}))));if(i&&i.ciphertext){const e=Buffer.from(t._pickleKey),r=await(0,s.decryptAES)(i,e,n);return(0,o.decodeBase64)(r)}return i},storeCrossSigningKeyCache:async function(n,r){if(!(r instanceof Uint8Array))throw new Error(`storeCrossSigningKeyCache expects Uint8Array, got ${r}`);const i=Buffer.from(t._pickleKey);return r=await(0,s.encryptAES)((0,o.encodeBase64)(r),i,n),e.doTxn("readwrite",[a.IndexedDBCryptoStore.STORE_ACCOUNT],(t=>{e.storeSecretStorePrivateKey(t,n,r)}))}}},t.requestKeysDuringVerification=async function(e,t,n){if(e.getUserId()===t)return i.logger.log("Cross-signing: Self-verification done; requesting keys"),new Promise(((t,r)=>{const a=e,s=a._crypto._crossSigningInfo,u=new c(s.userId,{getCrossSigningKey:async e=>{i.logger.debug("Cross-signing: requesting secret",e,n);const{promise:t}=a.requestSecret(`m.cross_signing.${e}`,[n]),r=await t,s=(0,o.decodeBase64)(r);return Uint8Array.from(s)}},s._cacheCallbacks);u.keys=s.keys;const l=new Promise(((e,t)=>{setTimeout(e,6e4,new Error("Timeout"))})),d=new Promise((async e=>{if(!await a._crypto.getSessionBackupPrivateKey()){i.logger.info("No cached backup key found. Requesting...");const e=a.requestSecret("m.megolm_backup.v1",[n]),t=await e.promise;i.logger.info("Got key backup key, decoding...");const r=(0,o.decodeBase64)(t);i.logger.info("Decoded backup key, storing..."),a._crypto.storeSessionBackupPrivateKey(Uint8Array.from(r)),i.logger.info("Backup key stored. Starting backup restore...");const s=await a.getKeyBackupVersion();a.restoreKeyBackupWithCache(void 0,void 0,s).then((()=>{i.logger.info("Backup restored.")}))}e()}));return Promise.race([Promise.all([u.getCrossSigningKey("master"),u.getCrossSigningKey("self_signing"),u.getCrossSigningKey("user_signing"),d]),l]).then(t,r)})).catch((e=>{i.logger.warn("Cross-signing: failure while requesting keys:",e)}))},t.DeviceTrustLevel=t.UserTrustLevel=t.CrossSigningLevel=t.CrossSigningInfo=void 0;var o=n(32772),r=n(17187),i=n(7434),a=n(57585),s=n(2611);function u(e){return Object.values(e.keys)[0]}class c extends r.EventEmitter{constructor(e,t,n){super(),Object.defineProperty(this,"userId",{enumerable:!0,value:e}),this._callbacks=t||{},this._cacheCallbacks=n||{},this.keys={},this.firstUse=!0,this.crossSigningVerifiedBefore=!1}static fromStorage(e,t){const n=new c(t);for(const t in e)e.hasOwnProperty(t)&&(n[t]=e[t]);return n}toStorage(){return{keys:this.keys,firstUse:this.firstUse,crossSigningVerifiedBefore:this.crossSigningVerifiedBefore}}async getCrossSigningKey(e,t){const o=["master","self_signing","user_signing"].indexOf(e)>=0;if(!this._callbacks.getCrossSigningKey)throw new Error("No getCrossSigningKey callback supplied");function r(e){if(!e)return;const o=new n.g.Olm.PkSigning,r=o.init_with_seed(e);if(r===t)return[r,o];o.free()}let i;void 0===t&&(t=this.getId(e)),this._cacheCallbacks.getCrossSigningKeyCache&&o&&(i=await this._cacheCallbacks.getCrossSigningKeyCache(e,t));const a=r(i);if(a)return a;i=await this._callbacks.getCrossSigningKey(e,t);const s=r(i);if(s)return this._cacheCallbacks.storeCrossSigningKeyCache&&o&&await this._cacheCallbacks.storeCrossSigningKeyCache(e,i),s;if(!i)throw new Error("getCrossSigningKey callback for "+e+" returned falsey");throw new Error("Key type "+e+" from getCrossSigningKey callback did not match")}async isStoredInSecretStorage(e){const t=await e.isStored("m.cross_signing.master",!1)||{};function n(e){for(const n of Object.keys(t))e[n]||delete t[n]}for(const t of["self_signing","user_signing"])n(await e.isStored(`m.cross_signing.${t}`,!1)||{});return Object.keys(t).length?t:null}static async storeInSecretStorage(e,t){for(const[n,r]of e){const e=(0,o.encodeBase64)(r);await t.store(`m.cross_signing.${n}`,e)}}static async getFromSecretStorage(e,t){const n=await t.get(`m.cross_signing.${e}`);return n?(0,o.decodeBase64)(n):null}async isStoredInKeyCache(e){const t=this._cacheCallbacks;if(!t)return!1;const n=e?[e]:["master","self_signing","user_signing"];for(const e of n)if(!await t.getCrossSigningKeyCache(e))return!1;return!0}async getCrossSigningKeysFromCache(){const e=new Map,t=this._cacheCallbacks;if(!t)return e;for(const n of["master","self_signing","user_signing"]){const o=await t.getCrossSigningKeyCache(n);o&&e.set(n,o)}return e}getId(e){return e=e||"master",this.keys[e]?u(this.keys[e]):null}async resetKeys(e){if(!this._callbacks.saveCrossSigningKeys)throw new Error("No saveCrossSigningKeys callback supplied");if(void 0===e||e&l.MASTER||!this.keys.master)e=l.MASTER|l.USER_SIGNING|l.SELF_SIGNING;else if(0===e)return;const t={},r={};let i,a;try{if(e&l.MASTER?(i=new n.g.Olm.PkSigning,t.master=i.generate_seed(),a=i.init_with_seed(t.master),r.master={user_id:this.userId,usage:["master"],keys:{["ed25519:"+a]:a}}):[a,i]=await this.getCrossSigningKey("master"),e&l.SELF_SIGNING){const e=new n.g.Olm.PkSigning;try{t.self_signing=e.generate_seed();const n=e.init_with_seed(t.self_signing);r.self_signing={user_id:this.userId,usage:["self_signing"],keys:{["ed25519:"+n]:n}},(0,o.pkSign)(r.self_signing,i,this.userId,a)}finally{e.free()}}if(e&l.USER_SIGNING){const e=new n.g.Olm.PkSigning;try{t.user_signing=e.generate_seed();const n=e.init_with_seed(t.user_signing);r.user_signing={user_id:this.userId,usage:["user_signing"],keys:{["ed25519:"+n]:n}},(0,o.pkSign)(r.user_signing,i,this.userId,a)}finally{e.free()}}Object.assign(this.keys,r),this._callbacks.saveCrossSigningKeys(t)}finally{i&&i.free()}}clearKeys(){this.keys={}}setKeys(e){const t={};if(e.master){if(e.master.user_id!==this.userId){const t="Mismatched user ID "+e.master.user_id+" in master key from "+this.userId;throw i.logger.error(t),new Error(t)}this.keys.master?u(e.master)!==this.getId()&&(this.firstUse=!1):this.firstUse=!0,t.master=e.master}else{if(!this.keys.master)throw new Error("Tried to set cross-signing keys without a master key");t.master=this.keys.master}const n=u(t.master);if(e.user_signing){if(e.user_signing.user_id!==this.userId){const t="Mismatched user ID "+e.master.user_id+" in user_signing key from "+this.userId;throw i.logger.error(t),new Error(t)}try{(0,o.pkVerify)(e.user_signing,n,this.userId)}catch(e){throw i.logger.error("invalid signature on user-signing key"),e}}if(e.self_signing){if(e.self_signing.user_id!==this.userId){const t="Mismatched user ID "+e.master.user_id+" in self_signing key from "+this.userId;throw i.logger.error(t),new Error(t)}try{(0,o.pkVerify)(e.self_signing,n,this.userId)}catch(e){throw i.logger.error("invalid signature on self-signing key"),e}}e.master&&(this.keys.master=e.master,this.keys.self_signing=null,this.keys.user_signing=null),e.self_signing&&(this.keys.self_signing=e.self_signing),e.user_signing&&(this.keys.user_signing=e.user_signing)}updateCrossSigningVerifiedBefore(e){!this.crossSigningVerifiedBefore&&e&&(this.crossSigningVerifiedBefore=!0)}async signObject(e,t){if(!this.keys[t])throw new Error("Attempted to sign with "+t+" key but no such key present");const[n,r]=await this.getCrossSigningKey(t);try{return(0,o.pkSign)(e,r,this.userId,n),e}finally{r.free()}}async signUser(e){if(this.keys.user_signing)return this.signObject(e.keys.master,"user_signing");i.logger.info("No user signing key: not signing user")}async signDevice(e,t){if(e!==this.userId)throw new Error(`Trying to sign ${e}'s device; can only sign our own device`);if(this.keys.self_signing)return this.signObject({algorithms:t.algorithms,keys:t.keys,device_id:t.deviceId,user_id:e},"self_signing");i.logger.info("No self signing key: not signing device")}checkUserTrust(e){if(this.userId===e.userId&&this.getId()&&this.getId()===e.getId()&&this.getId("self_signing")&&this.getId("self_signing")===e.getId("self_signing"))return new d(!0,!0,this.firstUse);if(!this.keys.user_signing)return new d(!1,!1,e.firstUse);let t;const n=e.keys.master,r=this.getId("user_signing");try{(0,o.pkVerify)(n,r,this.userId),t=!0}catch(e){t=!1}return new d(t,e.crossSigningVerifiedBefore,e.firstUse)}checkDeviceTrust(e,t,n,r){const i=this.checkUserTrust(e),a=e.keys.self_signing;if(!a)return new h(!1,!1,n,r);const s=function(e,t){return{algorithms:e.algorithms,keys:e.keys,device_id:e.deviceId,user_id:t,signatures:e.signatures}}(t,e.userId);try{return(0,o.pkVerify)(a,e.getId(),e.userId),(0,o.pkVerify)(s,u(a),e.userId),h.fromUserTrustLevel(i,n,r)}catch(e){return new h(!1,!1,n,r)}}getCacheCallbacks(){return this._cacheCallbacks}}t.CrossSigningInfo=c;const l={MASTER:4,USER_SIGNING:2,SELF_SIGNING:1};t.CrossSigningLevel=l;class d{constructor(e,t,n){this._crossSigningVerified=e,this._crossSigningVerifiedBefore=t,this._tofu=n}isVerified(){return this.isCrossSigningVerified()}isCrossSigningVerified(){return this._crossSigningVerified}wasCrossSigningVerified(){return this._crossSigningVerifiedBefore}isTofu(){return this._tofu}}t.UserTrustLevel=d;class h{constructor(e,t,n,o){this._crossSigningVerified=e,this._tofu=t,this._localVerified=n,this._trustCrossSignedDevices=o}static fromUserTrustLevel(e,t,n){return new h(e._crossSigningVerified,e._tofu,t,n)}isVerified(){return Boolean(this.isLocallyVerified()||this._trustCrossSignedDevices&&this.isCrossSigningVerified())}isCrossSigningVerified(){return this._crossSigningVerified}isLocallyVerified(){return this._localVerified}isTofu(){return this._tofu}}t.DeviceTrustLevel=h},36670:(e,t,n)=>{"use strict";var o=n(20862);Object.defineProperty(t,"__esModule",{value:!0}),t.DeviceList=void 0;var r=n(17187),i=n(7434),a=n(23272),s=n(3075),u=o(n(32772)),c=n(57585),l=n(3102);class d extends r.EventEmitter{constructor(e,t,n,o=250){super(),this._cryptoStore=t,this._devices={},this._crossSigningInfo={},this._userByIdentityKey={},this._deviceTrackingStatus={},this._syncToken=null,this._serialiser=new h(e,n,this),this._keyDownloadsInProgressByUser={},this._keyDownloadChunkSize=o,this._dirty=!1,this._savePromise=null,this._resolveSavePromise=null,this._savePromiseTime=null,this._saveTimer=null,this._hasFetched=null}async load(){await this._cryptoStore.doTxn("readonly",[c.IndexedDBCryptoStore.STORE_DEVICE_DATA],(e=>{this._cryptoStore.getEndToEndDeviceData(e,(e=>{this._hasFetched=Boolean(e&&e.devices),this._devices=e?e.devices:{},this._crossSigningInfo=e&&e.crossSigningInfo||{},this._deviceTrackingStatus=e?e.trackingStatus:{},this._syncToken=e?e.syncToken:null,this._userByIdentityKey={};for(const e of Object.keys(this._devices)){const t=this._devices[e];for(const n of Object.keys(t)){const o=t[n].keys["curve25519:"+n];void 0!==o&&(this._userByIdentityKey[o]=e)}}}))}));for(const e of Object.keys(this._deviceTrackingStatus))2==this._deviceTrackingStatus[e]&&(this._deviceTrackingStatus[e]=1)}stop(){null!==this._saveTimer&&clearTimeout(this._saveTimer)}async saveIfDirty(e){if(!this._dirty)return Promise.resolve(!1);void 0===e&&(e=500);const t=Date.now+e;this._savePromiseTime&&t{this._resolveSavePromise=e})),this._savePromise=n),null===this._saveTimer){const n=this._resolveSavePromise;this._savePromiseTime=t,this._saveTimer=setTimeout((()=>{i.logger.log("Saving device tracking data",this._syncToken),this._savePromiseTime=null,this._saveTimer=null,this._savePromise=null,this._resolveSavePromise=null,this._cryptoStore.doTxn("readwrite",[c.IndexedDBCryptoStore.STORE_DEVICE_DATA],(e=>{this._cryptoStore.storeEndToEndDeviceData({devices:this._devices,crossSigningInfo:this._crossSigningInfo,trackingStatus:this._deviceTrackingStatus,syncToken:this._syncToken},e)})).then((()=>{this._dirty=!1,n()}),(e=>{i.logger.error("Failed to save device tracking data",this._syncToken),i.logger.error(e)}))}),e)}return n}getSyncToken(){return this._syncToken}setSyncToken(e){this._syncToken=e}downloadKeys(e,t){const n=[],o=[];if(e.forEach((e=>{const r=this._deviceTrackingStatus[e];this._keyDownloadsInProgressByUser[e]?(i.logger.log(`downloadKeys: already have a download in progress for ${e}: awaiting its result`),o.push(this._keyDownloadsInProgressByUser[e])):(t||3!=r)&&n.push(e)})),0!=n.length){i.logger.log("downloadKeys: downloading for",n);const e=this._doKeyDownload(n);o.push(e)}return 0===o.length&&i.logger.log("downloadKeys: already have all necessary keys"),Promise.all(o).then((()=>this._getDevicesFromStore(e)))}_getDevicesFromStore(e){const t={},n=this;return e.map((function(e){t[e]={},(n.getStoredDevicesForUser(e)||[]).map((function(n){t[e][n.deviceId]=n}))})),t}getKnownUserIds(){return Object.keys(this._devices)}getStoredDevicesForUser(e){const t=this._devices[e];if(!t)return null;const n=[];for(const e in t)t.hasOwnProperty(e)&&n.push(a.DeviceInfo.fromStorage(t[e],e));return n}getRawStoredDevicesForUser(e){return this._devices[e]}getStoredCrossSigningForUser(e){return this._crossSigningInfo[e]?s.CrossSigningInfo.fromStorage(this._crossSigningInfo[e],e):null}storeCrossSigningForUser(e,t){this._crossSigningInfo[e]=t,this._dirty=!0}getStoredDevice(e,t){const n=this._devices[e];if(n&&n[t])return a.DeviceInfo.fromStorage(n[t],t)}getUserByIdentityKey(e,t){return e!==u.OLM_ALGORITHM&&e!==u.MEGOLM_ALGORITHM?null:this._userByIdentityKey[t]}getDeviceByIdentityKey(e,t){const n=this.getUserByIdentityKey(e,t);if(!n)return null;const o=this._devices[n];if(!o)return null;for(const e in o){if(!o.hasOwnProperty(e))continue;const n=o[e];for(const o in n.keys)if(n.keys.hasOwnProperty(o)&&0===o.indexOf("curve25519:")&&n.keys[o]==t)return a.DeviceInfo.fromStorage(n,e)}return null}storeDevicesForUser(e,t){if(void 0!==this._devices[e])for(const[t,n]of Object.entries(this._devices[e])){const e=n.keys["curve25519:"+t];delete this._userByIdentityKey[e]}this._devices[e]=t;for(const[n,o]of Object.entries(t)){const t=o.keys["curve25519:"+n];this._userByIdentityKey[t]=e}this._dirty=!0}startTrackingDeviceList(e){if("string"!=typeof e)throw new Error("userId must be a string; was "+e);this._deviceTrackingStatus[e]||(i.logger.log("Now tracking device list for "+e),this._deviceTrackingStatus[e]=1,this._dirty=!0)}stopTrackingDeviceList(e){this._deviceTrackingStatus[e]&&(i.logger.log("No longer tracking device list for "+e),this._deviceTrackingStatus[e]=0,this._dirty=!0)}stopTrackingAllDeviceLists(){for(const e of Object.keys(this._deviceTrackingStatus))this._deviceTrackingStatus[e]=0;this._dirty=!0}invalidateUserDeviceList(e){this._deviceTrackingStatus[e]&&(i.logger.log("Marking device list outdated for",e),this._deviceTrackingStatus[e]=1,this._dirty=!0)}refreshOutdatedDeviceLists(){this.saveIfDirty();const e=[];for(const t of Object.keys(this._deviceTrackingStatus))1==this._deviceTrackingStatus[t]&&e.push(t);return this._doKeyDownload(e)}_setRawStoredDevicesForUser(e,t){if(void 0!==this._devices[e])for(const[t,n]of Object.entries(this._devices[e])){const e=n.keys["curve25519:"+t];delete this._userByIdentityKey[e]}this._devices[e]=t;for(const[n,o]of Object.entries(t)){const t=o.keys["curve25519:"+n];this._userByIdentityKey[t]=e}}setRawStoredCrossSigningForUser(e,t){this._crossSigningInfo[e]=t}_doKeyDownload(e){if(0===e.length)return Promise.resolve();const t=this._serialiser.updateDevicesForUsers(e,this._syncToken).then((()=>{n(!0)}),(t=>{throw i.logger.error("Error downloading keys for "+e+":",t),n(!1),t}));e.forEach((e=>{this._keyDownloadsInProgressByUser[e]=t,1==this._deviceTrackingStatus[e]&&(this._deviceTrackingStatus[e]=2)}));const n=n=>{this.emit("crypto.willUpdateDevices",e,!this._hasFetched),e.forEach((e=>{this._dirty=!0,this._keyDownloadsInProgressByUser[e]===t?(delete this._keyDownloadsInProgressByUser[e],2==this._deviceTrackingStatus[e]&&(n?(this._deviceTrackingStatus[e]=3,i.logger.log("Device list for",e,"now up to date")):this._deviceTrackingStatus[e]=1)):i.logger.log("Another update in the queue for",e,"- not marking up-to-date")})),this.saveIfDirty(),this.emit("crypto.devicesUpdated",e,!this._hasFetched),this._hasFetched=!0};return t}}t.DeviceList=d;class h{constructor(e,t,n){this._baseApis=e,this._olmDevice=t,this._deviceList=n,this._downloadInProgress=!1,this._keyDownloadsQueuedByUser={},this._queuedQueryDeferred=null,this._syncToken=null}updateDevicesForUsers(e,t){return e.forEach((e=>{this._keyDownloadsQueuedByUser[e]=!0})),this._queuedQueryDeferred||(this._queuedQueryDeferred=(0,l.defer)()),this._syncToken=t,this._downloadInProgress?(i.logger.log("Queued key download for",e),this._queuedQueryDeferred.promise):this._doQueuedQueries()}_doQueuedQueries(){if(this._downloadInProgress)throw new Error("DeviceListUpdateSerialiser._doQueuedQueries called with request active");const e=Object.keys(this._keyDownloadsQueuedByUser);this._keyDownloadsQueuedByUser={};const t=this._queuedQueryDeferred;this._queuedQueryDeferred=null,i.logger.log("Starting key download for",e),this._downloadInProgress=!0;const n={};this._syncToken&&(n.token=this._syncToken);const o=[];for(let t=0;tthis._baseApis.downloadKeysForUsers(r,n)))}return(0,l.chunkPromises)(o,3).then((async t=>{const n=Object.assign({},...t.map((e=>e.device_keys||{}))),o=Object.assign({},...t.map((e=>e.master_keys||{}))),r=Object.assign({},...t.map((e=>e.self_signing_keys||{}))),a=Object.assign({},...t.map((e=>e.user_signing_keys||{})));for(const t of e){await(0,l.sleep)(5);try{await this._processQueryResponseForUser(t,n[t],{master:o[t],self_signing:r[t],user_signing:a[t]})}catch(e){i.logger.error(`Error processing keys for ${t}:`,e)}}})).then((()=>{i.logger.log("Completed key download for "+e),this._downloadInProgress=!1,t.resolve(),this._queuedQueryDeferred&&this._doQueuedQueries()}),(n=>{i.logger.warn("Error downloading keys for "+e+":",n),this._downloadInProgress=!1,t.reject(n)})),t.promise}async _processQueryResponseForUser(e,t,n){i.logger.log("got device keys for "+e+":",t),i.logger.log("got cross-signing keys for "+e+":",n);{const n={},o=this._deviceList.getRawStoredDevicesForUser(e);o&&Object.keys(o).forEach((e=>{const t=a.DeviceInfo.fromStorage(o[e],e);n[e]=t})),await async function(e,t,n,o,r,a){let s=!1;for(const e in n)if(n.hasOwnProperty(e)&&!(e in o)){if(t===r&&e===a){i.logger.warn(`Local device ${e} missing from sync, skipping removal`);continue}i.logger.log("Device "+t+":"+e+" has been removed"),delete n[e],s=!0}for(const r in o){if(!o.hasOwnProperty(r))continue;const a=o[r];a.user_id===t?a.device_id===r?await p(e,n,a)&&(s=!0):i.logger.warn("Mismatched device_id "+a.device_id+" in keys from "+t+":"+r):i.logger.warn("Mismatched user_id "+a.user_id+" in keys from "+t+":"+r)}return s}(this._olmDevice,e,n,t||{},this._baseApis.getUserId(),this._baseApis.deviceId);const r={};Object.keys(n).forEach((e=>{r[e]=n[e].toStorage()})),this._deviceList._setRawStoredDevicesForUser(e,r)}if(n&&(n.master||n.self_signing||n.user_signing)){const t=this._deviceList.getStoredCrossSigningForUser(e)||new s.CrossSigningInfo(e);t.setKeys(n),this._deviceList.setRawStoredCrossSigningForUser(e,t.toStorage()),this._deviceList.emit("userCrossSigningUpdated",e)}}}async function p(e,t,n){if(!n.keys)return!1;const o=n.device_id,r=n.user_id,s="ed25519:"+o,c=n.keys[s];if(!c)return i.logger.warn("Device "+r+":"+o+" has no ed25519 key"),!1;const l=n.unsigned||{},d=n.signatures||{};try{await u.verifySignature(e,n,r,o,c)}catch(e){return i.logger.warn("Unable to verify signature on device "+r+":"+o+":"+e),!1}let h;if(o in t){if(h=t[o],h.getFingerprint()!=c)return i.logger.warn("Ed25519 key for device "+r+":"+o+" has changed"),!1}else t[o]=h=new a.DeviceInfo(o);return h.keys=n.keys||{},h.algorithms=n.algorithms||[],h.unsigned=l,h.signatures=d,!0}},70636:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.EncryptionSetupOperation=t.EncryptionSetupBuilder=void 0;var o=n(7434),r=n(24369),i=n(17187),a=n(3075),s=n(57585),u=n(17715);t.EncryptionSetupBuilder=class{constructor(e,t){this.accountDataClientAdapter=new l(e),this.crossSigningCallbacks=new d,this.ssssCryptoCallbacks=new h(t),this._crossSigningKeys=null,this._keySignatures=null,this._keyBackupInfo=null}addCrossSigningKeys(e,t){this._crossSigningKeys={authUpload:e,keys:t}}addSessionBackup(e){this._keyBackupInfo=e}addSessionBackupPrivateKeyToCache(e){this._sessionBackupPrivateKey=e}addKeySignature(e,t,n){this._keySignatures||(this._keySignatures={});const o=this._keySignatures[e]||{};this._keySignatures[e]=o,o[t]=n}setAccountData(e,t){return this.accountDataClientAdapter.setAccountData(e,t)}buildOperation(){const e=this.accountDataClientAdapter._values;return new c(e,this._crossSigningKeys,this._keyBackupInfo,this._keySignatures)}async persist(e){if(this._crossSigningKeys){const t=(0,a.createCryptoStoreCacheCallbacks)(e._cryptoStore,e._olmDevice);for(const e of["master","self_signing","user_signing"]){o.logger.log(`Cache ${e} cross-signing private key locally`);const n=this.crossSigningCallbacks.privateKeys.get(e);await t.storeCrossSigningKeyCache(e,n)}await e._cryptoStore.doTxn("readwrite",[s.IndexedDBCryptoStore.STORE_ACCOUNT],(t=>{e._cryptoStore.storeCrossSigningKeys(t,this._crossSigningKeys.keys)}))}this._sessionBackupPrivateKey&&await e.storeSessionBackupPrivateKey(this._sessionBackupPrivateKey)}};class c{constructor(e,t,n,o){this._accountData=e,this._crossSigningKeys=t,this._keyBackupInfo=n,this._keySignatures=o}async apply(e){const t=e._baseApis;if(this._crossSigningKeys){const n={};for(const[e,t]of Object.entries(this._crossSigningKeys.keys))n[e+"_key"]=t;await this._crossSigningKeys.authUpload((e=>t.uploadDeviceSigningKeys(e,n))),e._crossSigningInfo.setKeys(this._crossSigningKeys.keys)}if(this._accountData)for(const[e,n]of this._accountData)await t.setAccountData(e,n);this._keySignatures&&await t.uploadKeySignatures(this._keySignatures),this._keyBackupInfo&&(this._keyBackupInfo.version?await t._http.authedRequest(void 0,"PUT","/room_keys/version/"+this._keyBackupInfo.version,void 0,{algorithm:this._keyBackupInfo.algorithm,auth_data:this._keyBackupInfo.auth_data},{prefix:u.PREFIX_UNSTABLE}):await t._http.authedRequest(void 0,"POST","/room_keys/version",void 0,this._keyBackupInfo,{prefix:u.PREFIX_UNSTABLE}))}}t.EncryptionSetupOperation=c;class l extends i.EventEmitter{constructor(e){super(),this._existingValues=e,this._values=new Map}getAccountDataFromServer(e){return Promise.resolve(this.getAccountData(e))}getAccountData(e){const t=this._values.get(e);if(t)return t;const n=this._existingValues[e];return n?n.getContent():null}setAccountData(e,t){const n=this._values.get(e);return this._values.set(e,t),Promise.resolve().then((()=>{const o=new r.MatrixEvent({type:e,content:t});this.emit("accountData",o,n)}))}}class d{constructor(){this.privateKeys=new Map}getCrossSigningKeyCache(e,t){return this.getCrossSigningKey(e,t)}storeCrossSigningKeyCache(e,t){return this.privateKeys.set(e,t),Promise.resolve()}getCrossSigningKey(e,t){return Promise.resolve(this.privateKeys.get(e))}saveCrossSigningKeys(e){for(const[t,n]of Object.entries(e))this.privateKeys.set(t,n)}}class h{constructor(e){this._privateKeys=new Map,this._delegateCryptoCallbacks=e}async getSecretStorageKey({keys:e},t){for(const t of Object.keys(e)){const e=this._privateKeys.get(t);if(e)return[t,e]}if(this._delegateCryptoCallbacks){const n=await this._delegateCryptoCallbacks.getSecretStorageKey({keys:e},t);if(n){const[e,t]=n;this._privateKeys.set(e,t)}return n}}addPrivateKey(e,t,n){this._privateKeys.set(e,n),this._delegateCryptoCallbacks&&this._delegateCryptoCallbacks.cacheSecretStorageKey&&this._delegateCryptoCallbacks.cacheSecretStorageKey(e,t,n)}}},72573:(e,t,n)=>{"use strict";var o=n(20862);Object.defineProperty(t,"__esModule",{value:!0}),t.OlmDevice=u,t.WITHHELD_MESSAGES=void 0;var r=n(7434),i=n(57585),a=o(n(91994));function s(e){if(void 0===e)throw new Error("payloadString undefined");if(e.length>49152){const t=new Error("Message too long ("+e.length+" bytes). The maximum for an encrypted message is 49152 bytes.");throw t.data={errcode:"M_TOO_LARGE",error:"Payload too large for encrypted message"},t}}function u(e){this._cryptoStore=e,this._pickleKey="DEFAULT_KEY",this.deviceCurve25519Key=null,this.deviceEd25519Key=null,this._maxOneTimeKeys=null,this._outboundGroupSessionStore={},this._inboundGroupSessionMessageIndexes={},this._sessionsInProgress={},this._olmPrekeyPromise=Promise.resolve()}u.prototype.init=async function(e={}){let t;const o=new n.g.Olm.Account,{pickleKey:a,fromExportedDevice:s}=e;try{s?(a&&r.logger.warn("ignoring opts.pickleKey because opts.fromExportedDevice is present."),this._pickleKey=s.pickleKey,await async function(e,t,n,o){await t.doTxn("readwrite",[i.IndexedDBCryptoStore.STORE_ACCOUNT,i.IndexedDBCryptoStore.STORE_SESSIONS],(n=>{t.storeAccount(n,e.pickledAccount),e.sessions.forEach((e=>{const{deviceKey:o,sessionId:r}=e,i={session:e.session,lastReceivedMessageTs:e.lastReceivedMessageTs};t.storeEndToEndSession(o,r,i,n)}))})),o.unpickle(n,e.pickledAccount)}(s,this._cryptoStore,this._pickleKey,o)):(a&&(this._pickleKey=a),await async function(e,t,n){await e.doTxn("readwrite",[i.IndexedDBCryptoStore.STORE_ACCOUNT],(o=>{e.getAccount(o,(r=>{null!==r?n.unpickle(t,r):(n.create(),r=n.pickle(t),e.storeAccount(o,r))}))}))}(this._cryptoStore,this._pickleKey,o)),t=JSON.parse(o.identity_keys()),this._maxOneTimeKeys=o.max_number_of_one_time_keys()}finally{o.free()}this.deviceCurve25519Key=t.curve25519,this.deviceEd25519Key=t.ed25519},u.getOlmVersion=function(){return n.g.Olm.get_library_version()},u.prototype._getAccount=function(e,t){this._cryptoStore.getAccount(e,(e=>{const o=new n.g.Olm.Account;try{o.unpickle(this._pickleKey,e),t(o)}finally{o.free()}}))},u.prototype._storeAccount=function(e,t){this._cryptoStore.storeAccount(e,t.pickle(this._pickleKey))},u.prototype.export=async function(){const e={pickleKey:this._pickleKey};return await this._cryptoStore.doTxn("readonly",[i.IndexedDBCryptoStore.STORE_ACCOUNT,i.IndexedDBCryptoStore.STORE_SESSIONS],(t=>{this._cryptoStore.getAccount(t,(t=>{e.pickledAccount=t})),e.sessions=[],this._cryptoStore.getAllEndToEndSessions(t,(t=>{e.sessions.push(t)}))})),e},u.prototype._getSession=function(e,t,n,o){this._cryptoStore.getEndToEndSession(e,t,n,(e=>{this._unpickleSession(e,o)}))},u.prototype._unpickleSession=function(e,t){const o=new n.g.Olm.Session;try{o.unpickle(this._pickleKey,e.session),t(Object.assign({},e,{session:o}))}finally{o.free()}},u.prototype._saveSession=function(e,t,n){const o=t.session.session_id(),r=Object.assign(t,{session:t.session.pickle(this._pickleKey)});this._cryptoStore.storeEndToEndSession(e,o,r,n)},u.prototype._getUtility=function(e){const t=new n.g.Olm.Utility;try{return e(t)}finally{t.free()}},u.prototype.sign=async function(e){let t;return await this._cryptoStore.doTxn("readonly",[i.IndexedDBCryptoStore.STORE_ACCOUNT],(n=>{this._getAccount(n,(n=>{t=n.sign(e)}))})),t},u.prototype.getOneTimeKeys=async function(){let e;return await this._cryptoStore.doTxn("readonly",[i.IndexedDBCryptoStore.STORE_ACCOUNT],(t=>{this._getAccount(t,(t=>{e=JSON.parse(t.one_time_keys())}))})),e},u.prototype.maxNumberOfOneTimeKeys=function(){return this._maxOneTimeKeys},u.prototype.markKeysAsPublished=async function(){await this._cryptoStore.doTxn("readwrite",[i.IndexedDBCryptoStore.STORE_ACCOUNT],(e=>{this._getAccount(e,(t=>{t.mark_keys_as_published(),this._storeAccount(e,t)}))}))},u.prototype.generateOneTimeKeys=function(e){return this._cryptoStore.doTxn("readwrite",[i.IndexedDBCryptoStore.STORE_ACCOUNT],(t=>{this._getAccount(t,(n=>{n.generate_one_time_keys(e),this._storeAccount(t,n)}))}))},u.prototype.generateFallbackKey=async function(){await this._cryptoStore.doTxn("readwrite",[i.IndexedDBCryptoStore.STORE_ACCOUNT],(e=>{this._getAccount(e,(t=>{t.generate_fallback_key(),this._storeAccount(e,t)}))}))},u.prototype.getFallbackKey=async function(){let e;return await this._cryptoStore.doTxn("readonly",[i.IndexedDBCryptoStore.STORE_ACCOUNT],(t=>{this._getAccount(t,(t=>{e=JSON.parse(t.fallback_key())}))})),e},u.prototype.createOutboundSession=async function(e,t){let o;return await this._cryptoStore.doTxn("readwrite",[i.IndexedDBCryptoStore.STORE_ACCOUNT,i.IndexedDBCryptoStore.STORE_SESSIONS],(r=>{this._getAccount(r,(i=>{const a=new n.g.Olm.Session;try{a.create_outbound(i,e,t),o=a.session_id(),this._storeAccount(r,i);const n={session:a,lastReceivedMessageTs:Date.now()};this._saveSession(e,n,r)}finally{a.free()}}))}),r.logger.withPrefix("[createOutboundSession]")),o},u.prototype.createInboundSession=async function(e,t,o){if(0!==t)throw new Error("Need messageType == 0 to create inbound session");let a;return await this._cryptoStore.doTxn("readwrite",[i.IndexedDBCryptoStore.STORE_ACCOUNT,i.IndexedDBCryptoStore.STORE_SESSIONS],(r=>{this._getAccount(r,(i=>{const s=new n.g.Olm.Session;try{s.create_inbound_from(i,e,o),i.remove_one_time_keys(s),this._storeAccount(r,i);const n=s.decrypt(t,o),u={session:s,lastReceivedMessageTs:Date.now()};this._saveSession(e,u,r),a={payload:n,session_id:s.session_id()}}finally{s.free()}}))}),r.logger.withPrefix("[createInboundSession]")),a},u.prototype.getSessionIdsForDevice=async function(e){const t=r.logger.withPrefix("[getSessionIdsForDevice]");if(this._sessionsInProgress[e]){t.debug(`Waiting for Olm session for ${e} to be created`);try{await this._sessionsInProgress[e]}catch(e){}}let n;return await this._cryptoStore.doTxn("readonly",[i.IndexedDBCryptoStore.STORE_SESSIONS],(t=>{this._cryptoStore.getEndToEndSessions(e,t,(e=>{n=Object.keys(e)}))}),t),n},u.prototype.getSessionIdForDevice=async function(e,t,n){const o=await this.getSessionInfoForDevice(e,t,n);if(0===o.length)return null;let r=0;for(let e=1;ea||n===a&&t.sessionId{this._cryptoStore.getEndToEndSessions(e,t,(e=>{const t=Object.keys(e).sort();for(const n of t)this._unpickleSession(e[n],(e=>{o.push({lastReceivedMessageTs:e.lastReceivedMessageTs,hasReceivedMessage:e.session.has_received_message(),sessionId:n})}))}))}),n),o},u.prototype.encryptMessage=async function(e,t,n){let o;return s(n),await this._cryptoStore.doTxn("readwrite",[i.IndexedDBCryptoStore.STORE_SESSIONS],(i=>{this._getSession(e,t,i,(a=>{const s=a.session.describe();r.logger.log("encryptMessage: Olm Session ID "+t+" to "+e+": "+s),o=a.session.encrypt(n),this._saveSession(e,a,i)}))}),r.logger.withPrefix("[encryptMessage]")),o},u.prototype.decryptMessage=async function(e,t,n,o){let a;return await this._cryptoStore.doTxn("readwrite",[i.IndexedDBCryptoStore.STORE_SESSIONS],(i=>{this._getSession(e,t,i,(s=>{const u=s.session.describe();r.logger.log("decryptMessage: Olm Session ID "+t+" from "+e+": "+u),a=s.session.decrypt(n,o),s.lastReceivedMessageTs=Date.now(),this._saveSession(e,s,i)}))}),r.logger.withPrefix("[decryptMessage]")),a},u.prototype.matchesSession=async function(e,t,n,o){if(0!==n)return!1;let a;return await this._cryptoStore.doTxn("readonly",[i.IndexedDBCryptoStore.STORE_SESSIONS],(n=>{this._getSession(e,t,n,(e=>{a=e.session.matches_inbound(o)}))}),r.logger.withPrefix("[matchesSession]")),a},u.prototype.recordSessionProblem=async function(e,t,n){await this._cryptoStore.storeEndToEndSessionProblem(e,t,n)},u.prototype.sessionMayHaveProblems=async function(e,t){return await this._cryptoStore.getEndToEndSessionProblem(e,t)},u.prototype.filterOutNotifiedErrorDevices=async function(e){return await this._cryptoStore.filterOutNotifiedErrorDevices(e)},u.prototype._saveOutboundGroupSession=function(e){const t=e.pickle(this._pickleKey);this._outboundGroupSessionStore[e.session_id()]=t},u.prototype._getOutboundGroupSession=function(e,t){const o=this._outboundGroupSessionStore[e];if(void 0===o)throw new Error("Unknown outbound group session "+e);const r=new n.g.Olm.OutboundGroupSession;try{return r.unpickle(this._pickleKey,o),t(r)}finally{r.free()}},u.prototype.createOutboundGroupSession=function(){const e=new n.g.Olm.OutboundGroupSession;try{return e.create(),this._saveOutboundGroupSession(e),e.session_id()}finally{e.free()}},u.prototype.encryptGroupMessage=function(e,t){const n=this;return r.logger.log(`encrypting msg with megolm session ${e}`),s(t),this._getOutboundGroupSession(e,(function(e){const o=e.encrypt(t);return n._saveOutboundGroupSession(e),o}))},u.prototype.getOutboundGroupSessionKey=function(e){return this._getOutboundGroupSession(e,(function(e){return{chain_index:e.message_index(),key:e.session_key()}}))},u.prototype._unpickleInboundGroupSession=function(e,t){const o=new n.g.Olm.InboundGroupSession;try{return o.unpickle(this._pickleKey,e.session),t(o)}finally{o.free()}},u.prototype._getInboundGroupSession=function(e,t,n,o,r){this._cryptoStore.getEndToEndInboundGroupSession(t,n,o,((t,n)=>{if(null!==t){if(null!==e&&e!==t.room_id)throw new Error("Mismatched room_id for inbound group session (expected "+t.room_id+", was "+e+")");this._unpickleInboundGroupSession(t,(e=>{r(e,t,n)}))}else r(null,null,n)}))},u.prototype.addInboundGroupSession=async function(e,t,o,a,s,u,c,l={}){await this._cryptoStore.doTxn("readwrite",[i.IndexedDBCryptoStore.STORE_INBOUND_GROUP_SESSIONS,i.IndexedDBCryptoStore.STORE_INBOUND_GROUP_SESSIONS_WITHHELD,i.IndexedDBCryptoStore.STORE_SHARED_HISTORY_INBOUND_GROUP_SESSIONS],(i=>{this._getInboundGroupSession(e,t,a,i,((d,h)=>{const p=new n.g.Olm.InboundGroupSession;try{if(c?p.import_session(s):p.create(s),a!=p.session_id())throw new Error("Mismatched group session ID from senderKey: "+t);if(d&&(r.logger.log("Update for megolm session "+t+"/"+a),d.first_known_index()<=p.first_known_index()&&(d.first_known_index()!=p.first_known_index()||l.untrusted||!h.untrusted)))return void r.logger.log(`Keeping existing megolm session ${a}`);r.logger.info("Storing megolm session "+t+"/"+a+" with first index "+p.first_known_index());const n=Object.assign({},l,{room_id:e,session:p.pickle(this._pickleKey),keysClaimed:u,forwardingCurve25519KeyChain:o});this._cryptoStore.storeEndToEndInboundGroupSession(t,a,n,i),!d&&l.sharedHistory&&this._cryptoStore.addSharedHistoryInboundGroupSession(e,t,a,i)}finally{p.free()}}))}),r.logger.withPrefix("[addInboundGroupSession]"))},u.prototype.addInboundGroupSessionWithheld=async function(e,t,n,o,r){await this._cryptoStore.doTxn("readwrite",[i.IndexedDBCryptoStore.STORE_INBOUND_GROUP_SESSIONS_WITHHELD],(i=>{this._cryptoStore.storeEndToEndInboundGroupSessionWithheld(t,n,{room_id:e,code:o,reason:r},i)}))};const c={"m.unverified":"The sender has disabled encrypting to unverified devices.","m.blacklisted":"The sender has blocked you.","m.unauthorised":"You are not authorised to read the message.","m.no_olm":"Unable to establish a secure channel."};function l(e){return e.code&&e.code in c?c[e.code]:e.reason?e.reason:"decryption key withheld"}t.WITHHELD_MESSAGES=c,u.prototype.decryptGroupMessage=async function(e,t,n,o,s,u){let c,d;if(await this._cryptoStore.doTxn("readwrite",[i.IndexedDBCryptoStore.STORE_INBOUND_GROUP_SESSIONS,i.IndexedDBCryptoStore.STORE_INBOUND_GROUP_SESSIONS_WITHHELD],(r=>{this._getInboundGroupSession(e,t,n,r,((e,i,h)=>{if(null===e)return h&&(d=new a.DecryptionError("MEGOLM_UNKNOWN_INBOUND_SESSION_ID",l(h),{session:t+"|"+n})),void(c=null);let p;try{p=e.decrypt(o)}catch(e){return void(d=e&&"OLM.UNKNOWN_MESSAGE_INDEX"===e.message&&h?new a.DecryptionError("MEGOLM_UNKNOWN_INBOUND_SESSION_ID",l(h),{session:t+"|"+n}):e)}let f=p.plaintext;if(void 0===f)f=p;else{const e=t+"|"+n+"|"+p.message_index;if(e in this._inboundGroupSessionMessageIndexes){const t=this._inboundGroupSessionMessageIndexes[e];if(t.id!==s||t.timestamp!==u)return void(d=new Error("Duplicate message index, possible replay attack: "+e))}this._inboundGroupSessionMessageIndexes[e]={id:s,timestamp:u}}i.session=e.pickle(this._pickleKey),this._cryptoStore.storeEndToEndInboundGroupSession(t,n,i,r),c={result:f,keysClaimed:i.keysClaimed||{},senderKey:t,forwardingCurve25519KeyChain:i.forwardingCurve25519KeyChain||[],untrusted:i.untrusted}}))}),r.logger.withPrefix("[decryptGroupMessage]")),d)throw d;return c},u.prototype.hasInboundSessionKeys=async function(e,t,n){let o;return await this._cryptoStore.doTxn("readonly",[i.IndexedDBCryptoStore.STORE_INBOUND_GROUP_SESSIONS,i.IndexedDBCryptoStore.STORE_INBOUND_GROUP_SESSIONS_WITHHELD],(i=>{this._cryptoStore.getEndToEndInboundGroupSession(t,n,i,(i=>{null!==i?e!==i.room_id?(r.logger.warn(`requested keys for inbound group session ${t}|${n}, with incorrect room_id (expected ${i.room_id}, was ${e})`),o=!1):o=!0:o=!1}))}),r.logger.withPrefix("[hasInboundSessionKeys]")),o},u.prototype.getInboundGroupSessionKey=async function(e,t,n,o){let a;return await this._cryptoStore.doTxn("readonly",[i.IndexedDBCryptoStore.STORE_INBOUND_GROUP_SESSIONS,i.IndexedDBCryptoStore.STORE_INBOUND_GROUP_SESSIONS_WITHHELD],(r=>{this._getInboundGroupSession(e,t,n,r,((e,t)=>{if(null===e)return void(a=null);void 0===o&&(o=e.first_known_index());const n=e.export_session(o),r=(t.keysClaimed||{}).ed25519||null;a={chain_index:o,key:n,forwarding_curve25519_key_chain:t.forwardingCurve25519KeyChain||[],sender_claimed_ed25519_key:r,shared_history:t.sharedHistory||!1}}))}),r.logger.withPrefix("[getInboundGroupSessionKey]")),a},u.prototype.exportInboundGroupSession=function(e,t,n){return this._unpickleInboundGroupSession(n,(o=>{const r=o.first_known_index();return{sender_key:e,sender_claimed_keys:n.keysClaimed,room_id:n.room_id,session_id:t,session_key:o.export_session(r),forwarding_curve25519_key_chain:o.forwardingCurve25519KeyChain||[],first_known_index:o.first_known_index(),"org.matrix.msc3061.shared_history":n.sharedHistory||!1}}))},u.prototype.getSharedHistoryInboundGroupSessions=async function(e){let t;return await this._cryptoStore.doTxn("readonly",[i.IndexedDBCryptoStore.STORE_SHARED_HISTORY_INBOUND_GROUP_SESSIONS],(n=>{t=this._cryptoStore.getSharedHistoryInboundGroupSessions(e,n)}),r.logger.withPrefix("[getSharedHistoryInboundGroupSessionsForRoom]")),t},u.prototype.verifySignature=function(e,t,n){this._getUtility((function(o){o.ed25519_verify(e,t,n)}))}},66617:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.OutgoingRoomKeyRequestManager=t.ROOM_KEY_REQUEST_STATES=void 0;var o=n(7434);const r={UNSENT:0,SENT:1,CANCELLATION_PENDING:2,CANCELLATION_PENDING_AND_WILL_RESEND:3};function i(e){return e.room_id+" / "+e.session_id}function a(e){return"["+e.map((e=>`${e.userId}:${e.deviceId}`)).join(",")+"]"}t.ROOM_KEY_REQUEST_STATES=r,t.OutgoingRoomKeyRequestManager=class{constructor(e,t,n){this._baseApis=e,this._deviceId=t,this._cryptoStore=n,this._sendOutgoingRoomKeyRequestsTimer=null,this._sendOutgoingRoomKeyRequestsRunning=!1,this._clientRunning=!1}start(){this._clientRunning=!0}stop(){o.logger.log("stopping OutgoingRoomKeyRequestManager"),this._clientRunning=!1}sendQueuedRequests(){this._startTimer()}async queueRoomKeyRequest(e,t,n=!1){const i=await this._cryptoStore.getOutgoingRoomKeyRequest(e);if(i)switch(i.state){case r.CANCELLATION_PENDING_AND_WILL_RESEND:case r.UNSENT:return;case r.CANCELLATION_PENDING:{const e=n?r.CANCELLATION_PENDING_AND_WILL_RESEND:r.SENT;await this._cryptoStore.updateOutgoingRoomKeyRequest(i.requestId,r.CANCELLATION_PENDING,{state:e,cancellationTxnId:this._baseApis.makeTxnId()});break}case r.SENT:if(n){const a=r.CANCELLATION_PENDING_AND_WILL_RESEND,s=await this._cryptoStore.updateOutgoingRoomKeyRequest(i.requestId,r.SENT,{state:a,cancellationTxnId:this._baseApis.makeTxnId(),requestTxnId:this._baseApis.makeTxnId()});if(!s)return await this.queueRoomKeyRequest(e,t,n);try{await this._sendOutgoingRoomKeyRequestCancellation(s,!0)}catch(e){o.logger.error("Error sending room key request cancellation; will retry later.",e)}}break;default:throw new Error("unhandled state: "+i.state)}else await this._cryptoStore.getOrAddOutgoingRoomKeyRequest({requestBody:e,recipients:t,requestId:this._baseApis.makeTxnId(),state:r.UNSENT})}cancelRoomKeyRequest(e){return this._cryptoStore.getOutgoingRoomKeyRequest(e).then((t=>{if(t)switch(t.state){case r.CANCELLATION_PENDING:case r.CANCELLATION_PENDING_AND_WILL_RESEND:return;case r.UNSENT:return o.logger.log("deleting unnecessary room key request for "+i(e)),this._cryptoStore.deleteOutgoingRoomKeyRequest(t.requestId,r.UNSENT);case r.SENT:return this._cryptoStore.updateOutgoingRoomKeyRequest(t.requestId,r.SENT,{state:r.CANCELLATION_PENDING,cancellationTxnId:this._baseApis.makeTxnId()}).then((t=>{t?this._sendOutgoingRoomKeyRequestCancellation(t).catch((e=>{o.logger.error("Error sending room key request cancellation; will retry later.",e),this._startTimer()})):o.logger.log("Tried to cancel room key request for "+i(e)+" but it was already cancelled in another tab")}));default:throw new Error("unhandled state: "+t.state)}}))}getOutgoingSentRoomKeyRequest(e,t){return this._cryptoStore.getOutgoingRoomKeyRequestsByTarget(e,t,[r.SENT])}async cancelAndResendAllOutgoingRequests(){const e=await this._cryptoStore.getAllOutgoingRoomKeyRequestsByState(r.SENT);return Promise.all(e.map((({requestBody:e,recipients:t})=>this.queueRoomKeyRequest(e,t,!0))))}_startTimer(){this._sendOutgoingRoomKeyRequestsTimer||(this._sendOutgoingRoomKeyRequestsTimer=n.g.setTimeout((()=>{if(this._sendOutgoingRoomKeyRequestsRunning)throw new Error("RoomKeyRequestSend already in progress!");this._sendOutgoingRoomKeyRequestsRunning=!0,this._sendOutgoingRoomKeyRequests().finally((()=>{this._sendOutgoingRoomKeyRequestsRunning=!1})).catch((e=>{o.logger.warn(`error in OutgoingRoomKeyRequestManager: ${e}`)}))}),500))}_sendOutgoingRoomKeyRequests(){return this._clientRunning?this._cryptoStore.getOutgoingRoomKeyRequestByState([r.CANCELLATION_PENDING,r.CANCELLATION_PENDING_AND_WILL_RESEND,r.UNSENT]).then((e=>{if(!e)return void(this._sendOutgoingRoomKeyRequestsTimer=null);let t;switch(e.state){case r.UNSENT:t=this._sendOutgoingRoomKeyRequest(e);break;case r.CANCELLATION_PENDING:t=this._sendOutgoingRoomKeyRequestCancellation(e);break;case r.CANCELLATION_PENDING_AND_WILL_RESEND:t=this._sendOutgoingRoomKeyRequestCancellation(e,!0)}return t.then((()=>this._sendOutgoingRoomKeyRequests())).catch((e=>{o.logger.error("Error sending room key request; will retry later.",e),this._sendOutgoingRoomKeyRequestsTimer=null}))})):(this._sendOutgoingRoomKeyRequestsTimer=null,Promise.resolve())}_sendOutgoingRoomKeyRequest(e){o.logger.log(`Requesting keys for ${i(e.requestBody)} from ${a(e.recipients)}(id ${e.requestId})`);const t={action:"request",requesting_device_id:this._deviceId,request_id:e.requestId,body:e.requestBody};return this._sendMessageToDevices(t,e.recipients,e.requestTxnId||e.requestId).then((()=>this._cryptoStore.updateOutgoingRoomKeyRequest(e.requestId,r.UNSENT,{state:r.SENT})))}_sendOutgoingRoomKeyRequestCancellation(e,t){o.logger.log(`Sending cancellation for key request for ${i(e.requestBody)} to ${a(e.recipients)} (cancellation id ${e.cancellationTxnId})`);const n={action:"request_cancellation",requesting_device_id:this._deviceId,request_id:e.requestId};return this._sendMessageToDevices(n,e.recipients,e.cancellationTxnId).then((()=>t?this._cryptoStore.updateOutgoingRoomKeyRequest(e.requestId,r.CANCELLATION_PENDING_AND_WILL_RESEND,{state:r.UNSENT}):this._cryptoStore.deleteOutgoingRoomKeyRequest(e.requestId,r.CANCELLATION_PENDING)))}_sendMessageToDevices(e,t,n){const o={};for(const n of t)o[n.userId]||(o[n.userId]={}),o[n.userId][n.deviceId]=e;return this._baseApis.sendToDevice("m.room_key_request",o,n)}}},40635:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.RoomList=void 0;var o=n(57585);t.RoomList=class{constructor(e){this._cryptoStore=e,this._roomEncryption={}}async init(){await this._cryptoStore.doTxn("readwrite",[o.IndexedDBCryptoStore.STORE_ROOMS],(e=>{this._cryptoStore.getEndToEndRooms(e,(e=>{this._roomEncryption=e}))}))}getRoomEncryption(e){return this._roomEncryption[e]||null}isRoomEncrypted(e){return Boolean(this.getRoomEncryption(e))}async setRoomEncryption(e,t){this._roomEncryption[e]=t,await this._cryptoStore.doTxn("readwrite",[o.IndexedDBCryptoStore.STORE_ROOMS],(n=>{this._cryptoStore.storeEndToEndRoom(e,t,n)}))}}},44823:(e,t,n)=>{"use strict";var o=n(20862);Object.defineProperty(t,"__esModule",{value:!0}),t.SecretStorage=t.SECRET_STORAGE_ALGORITHM_V1_AES=void 0;var r=n(17187),i=n(7434),a=o(n(32772)),s=n(98401),u=n(2611);const c="m.secret_storage.v1.aes-hmac-sha2";t.SECRET_STORAGE_ALGORITHM_V1_AES=c;class l extends r.EventEmitter{constructor(e,t){super(),this._baseApis=e,this._cryptoCallbacks=t,this._requests={},this._incomingRequests={}}async getDefaultKeyId(){const e=await this._baseApis.getAccountDataFromServer("m.secret_storage.default_key");return e?e.key:null}setDefaultKeyId(e){return new Promise((async(t,n)=>{const o=n=>{"m.secret_storage.default_key"===n.getType()&&n.getContent().key===e&&(this._baseApis.removeListener("accountData",o),t())};this._baseApis.on("accountData",o);try{await this._baseApis.setAccountData("m.secret_storage.default_key",{key:e})}catch(e){this._baseApis.removeListener("accountData",o),n(e)}}))}async addKey(e,t,n){const o={algorithm:e};if(t||(t={}),t.name&&(o.name=t.name),e!==c)throw new Error(`Unknown key algorithm ${t.algorithm}`);if(t.passphrase&&(o.passphrase=t.passphrase),t.key){const{iv:e,mac:n}=await l._calculateKeyCheck(t.key);o.iv=e,o.mac=n}if(!n)do{n=(0,s.randomString)(32)}while(await this._baseApis.getAccountDataFromServer(`m.secret_storage.key.${n}`));return await this._baseApis.setAccountData(`m.secret_storage.key.${n}`,o),{keyId:n,keyInfo:o}}async getKey(e){if(e||(e=await this.getDefaultKeyId()),!e)return null;const t=await this._baseApis.getAccountDataFromServer("m.secret_storage.key."+e);return t?[e,t]:null}async hasKey(e){return!!await this.getKey(e)}async checkKey(e,t){if(t.algorithm===c){if(t.mac){const{mac:n}=await l._calculateKeyCheck(e,t.iv);return t.mac.replace(/=+$/g,"")===n.replace(/=+$/g,"")}return!0}throw new Error("Unknown algorithm")}static async _calculateKeyCheck(e,t){return await(0,u.encryptAES)("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0",e,"",t)}async store(e,t,n){const o={};if(!n){const e=await this.getDefaultKeyId();if(!e)throw new Error("No keys specified and no default key present");n=[e]}if(0===n.length)throw new Error("Zero keys given to encrypt with!");for(const r of n){const n=await this._baseApis.getAccountDataFromServer("m.secret_storage.key."+r);if(!n)throw new Error("Unknown key: "+r);if(n.algorithm===c){const i={[r]:n},[,a]=await this._getSecretStorageKey(i,e);o[r]=await a.encrypt(t)}else i.logger.warn("unknown algorithm for secret storage key "+r+": "+n.algorithm)}await this._baseApis.setAccountData(e,{encrypted:o})}async _fixupStoredSecret(e,t){const n=Object.keys(t);return 1===n.length&&"encrypted"!==n[0]&&t[n[0]].passthrough&&await this.hasKey(n[0])?(i.logger.log("Fixing up passthrough secret: "+e),await this.storePassthrough(e,n[0]),await this._baseApis.getAccountDataFromServer(e)):null}async get(e){let t=await this._baseApis.getAccountDataFromServer(e);if(!t)return;if(!t.encrypted&&(t=await this._fixupStoredSecret(e,t),!t||!t.encrypted))throw new Error("Content is not encrypted!");const n={};for(const e of Object.keys(t.encrypted)){const o=await this._baseApis.getAccountDataFromServer("m.secret_storage.key."+e),r=t.encrypted[e];o.algorithm===c&&r.iv&&r.ciphertext&&r.mac&&(n[e]=o)}if(0===Object.keys(n).length)throw new Error(`Could not decrypt ${e} because none of the keys it is encrypted with are for a supported algorithm`);let o,r;try{[o,r]=await this._getSecretStorageKey(n,e);const i=t.encrypted[o];return i.passthrough?(0,a.encodeBase64)(r.get_private_key()):await r.decrypt(i)}finally{r&&r.free&&r.free()}}async isStored(e,t){let n=await this._baseApis.getAccountDataFromServer(e);if(!n)return null;if(!n.encrypted&&(n=await this._fixupStoredSecret(e,n),!n||!n.encrypted))return null;void 0===t&&(t=!0);const o={};for(const e of Object.keys(n.encrypted)){const t=await this._baseApis.getAccountDataFromServer("m.secret_storage.key."+e);if(!t)continue;const r=n.encrypted[e];t.algorithm===c&&r.iv&&r.ciphertext&&r.mac&&(o[e]=t)}return Object.keys(o).length?o:null}request(e,t){const n=this._baseApis.makeTxnId(),o=this._requests[n]={name:e,devices:t},r=new Promise(((e,t)=>{o.resolve=e,o.reject=t})),a={name:e,action:"request",requesting_device_id:this._baseApis.deviceId,request_id:n},s={};for(const e of t)s[e]=a;return i.logger.info(`Request secret ${e} from ${t}, id ${n}`),this._baseApis.sendToDevice("m.secret.request",{[this._baseApis.getUserId()]:s}),{request_id:n,promise:r,cancel:e=>{const r={action:"request_cancellation",requesting_device_id:this._baseApis.deviceId,request_id:n},i={};for(const e of t)i[e]=r;this._baseApis.sendToDevice("m.secret.request",{[this._baseApis.getUserId()]:i}),o.reject(new Error(e||"Cancelled"))}}}async _onRequestReceived(e){const t=e.getSender(),n=e.getContent();if(t!==this._baseApis.getUserId()||!(n.name&&n.action&&n.requesting_device_id&&n.request_id))return;const o=n.requesting_device_id;if("request_cancellation"===n.action)this._incomingRequests[o]&&this._incomingRequests[o][n.request_id]&&(i.logger.info("received request cancellation for secret ("+t+", "+o+", "+n.request_id+")"),this.baseApis.emit("crypto.secrets.requestCancelled",{user_id:t,device_id:o,request_id:n.request_id}));else if("request"===n.action){if(o===this._baseApis.deviceId)return;if(i.logger.info("received request for secret ("+t+", "+o+", "+n.request_id+")"),!this._cryptoCallbacks.onSecretRequested)return;const e=await this._cryptoCallbacks.onSecretRequested(t,o,n.request_id,n.name,this._baseApis.checkDeviceTrust(t,o));if(e){i.logger.info(`Preparing ${n.name} secret for ${o}`);const r={type:"m.secret.send",content:{request_id:n.request_id,secret:e}},s={algorithm:a.OLM_ALGORITHM,sender_key:this._baseApis._crypto._olmDevice.deviceCurve25519Key,ciphertext:{}};await a.ensureOlmSessionsForDevices(this._baseApis._crypto._olmDevice,this._baseApis,{[t]:[this._baseApis.getStoredDevice(t,o)]}),await a.encryptMessageForDevice(s.ciphertext,this._baseApis.getUserId(),this._baseApis.deviceId,this._baseApis._crypto._olmDevice,t,this._baseApis.getStoredDevice(t,o),r);const u={[t]:{[o]:s}};i.logger.info(`Sending ${n.name} secret for ${o}`),this._baseApis.sendToDevice("m.room.encrypted",u)}else i.logger.info(`Request denied for ${n.name} secret for ${o}`)}}_onSecretReceived(e){if(e.getSender()!==this._baseApis.getUserId())return;const t=e.getContent();i.logger.log("got secret share for request",t.request_id);const n=this._requests[t.request_id];if(n){const o=this._baseApis._crypto._deviceList.getDeviceByIdentityKey(a.OLM_ALGORITHM,e.getSenderKey());if(!o)return void i.logger.log("secret share from unknown device with key",e.getSenderKey());if(!n.devices.includes(o.deviceId))return void i.logger.log("unsolicited secret share from device",o.deviceId);i.logger.log(`Successfully received secret ${n.name} from ${o.deviceId}`),n.resolve(t.secret)}}async _getSecretStorageKey(e,t){if(!this._cryptoCallbacks.getSecretStorageKey)throw new Error("No getSecretStorageKey callback supplied");const n=await this._cryptoCallbacks.getSecretStorageKey({keys:e},t);if(!n)throw new Error("getSecretStorageKey callback returned falsey");if(n.length<2)throw new Error("getSecretStorageKey callback returned invalid data");const[o,r]=n;if(!e[o])throw new Error("App returned unknown key from getSecretStorageKey!");if(e[o].algorithm===c)return[o,{encrypt:async function(e){return await(0,u.encryptAES)(e,r,t)},decrypt:async function(e){return await(0,u.decryptAES)(e,r,t)}}];throw new Error("Unknown key type: "+e[o].algorithm)}}t.SecretStorage=l},2611:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.encryptAES=function(...e){return i?async function(e,t,n,o){let a;o?a=(0,r.decodeBase64)(o):(a=new Uint8Array(16),window.crypto.getRandomValues(a)),a[8]&=127;const[s,c]=await u(t,n),l=(new TextEncoder).encode(e),d=await i.encrypt({name:"AES-CTR",counter:a,length:64},s,l),h=await i.sign({name:"HMAC"},c,d);return{iv:(0,r.encodeBase64)(a),ciphertext:(0,r.encodeBase64)(d),mac:(0,r.encodeBase64)(h)}}(...e):async function(e,t,n,i){const a=(0,o.getCrypto)();if(!a)throw new Error("No usable crypto implementation");let u;u=i?(0,r.decodeBase64)(i):a.randomBytes(16),u[8]&=127;const[c,l]=s(t,n),d=a.createCipheriv("aes-256-ctr",c,u),h=d.update(e,"utf-8","base64")+d.final("base64"),p=a.createHmac("sha256",l).update(h,"base64").digest("base64");return{iv:(0,r.encodeBase64)(u),ciphertext:h,mac:p}}(...e)},t.decryptAES=function(...e){return i?async function(e,t,n){const[o,a]=await u(t,n),s=(0,r.decodeBase64)(e.ciphertext);if(!await i.verify({name:"HMAC"},a,(0,r.decodeBase64)(e.mac),s))throw new Error(`Error decrypting secret ${n}: bad MAC`);const c=await i.decrypt({name:"AES-CTR",counter:(0,r.decodeBase64)(e.iv),length:64},o,s);return(new TextDecoder).decode(new Uint8Array(c))}(...e):async function(e,t,n){const i=(0,o.getCrypto)();if(!i)throw new Error("No usable crypto implementation");const[a,u]=s(t,n);if(i.createHmac("sha256",u).update(e.ciphertext,"base64").digest("base64").replace(/=+$/g,"")!==e.mac.replace(/=+$/g,""))throw new Error(`Error decrypting secret ${n}: bad MAC`);const c=i.createDecipheriv("aes-256-ctr",a,(0,r.decodeBase64)(e.iv));return c.update(e.ciphertext,"base64","utf-8")+c.final("utf-8")}(...e)};var o=n(3102),r=n(32772);const i="undefined"!=typeof window&&window.crypto?window.crypto.subtle||window.crypto.webkitSubtle:null,a=new Uint8Array(8);function s(e,t){const n=(0,o.getCrypto)(),r=n.createHmac("sha256",a).update(e).digest(),i=Buffer.alloc(1,1),s=n.createHmac("sha256",r).update(t,"utf-8").update(i).digest();return i[0]=2,[s,n.createHmac("sha256",r).update(s).update(t,"utf-8").update(i).digest()]}async function u(e,t){const n=await i.importKey("raw",e,{name:"HKDF"},!1,["deriveBits"]),o=await i.deriveBits({name:"HKDF",salt:a,info:(new TextEncoder).encode(t),hash:"SHA-256"},n,512),r=o.slice(0,32),s=o.slice(32),u=i.importKey("raw",r,{name:"AES-CTR"},!1,["encrypt","decrypt"]),c=i.importKey("raw",s,{name:"HMAC",hash:{name:"SHA-256"}},!1,["sign","verify"]);return await Promise.all([u,c])}},21897:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.registerAlgorithm=function(e,t,r){n[e]=t,o[e]=r},t.UnknownDeviceError=t.DecryptionError=t.DecryptionAlgorithm=t.EncryptionAlgorithm=t.DECRYPTION_CLASSES=t.ENCRYPTION_CLASSES=void 0;const n={};t.ENCRYPTION_CLASSES=n;const o={};t.DECRYPTION_CLASSES=o,t.EncryptionAlgorithm=class{constructor(e){this._userId=e.userId,this._deviceId=e.deviceId,this._crypto=e.crypto,this._olmDevice=e.olmDevice,this._baseApis=e.baseApis,this._roomId=e.roomId}prepareToEncrypt(e){}onRoomMembership(e,t,n){}},t.DecryptionAlgorithm=class{constructor(e){this._userId=e.userId,this._crypto=e.crypto,this._olmDevice=e.olmDevice,this._baseApis=e.baseApis,this._roomId=e.roomId}onRoomKeyEvent(e){}importRoomKey(e){}hasKeysForKeyRequest(e){return Promise.resolve(!1)}shareKeysWithDevice(e){throw new Error("shareKeysWithDevice not supported for this DecryptionAlgorithm")}async retryDecryptionFromSender(e){}};class r extends Error{constructor(e,t,n){super(t),this.code=e,this.name="DecryptionError",this.detailedString=function(e,t){let n=e.name+"[msg: "+e.message;return t&&(n+=", "+Object.keys(t).map((e=>e+": "+t[e])).join(", ")),n+="]",n}(this,n)}}t.DecryptionError=r;class i extends Error{constructor(e,t){super(e),this.name="UnknownDeviceError",this.devices=t}}t.UnknownDeviceError=i},91994:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),n(23072),n(17125);var o=n(21897);Object.keys(o).forEach((function(e){"default"!==e&&"__esModule"!==e&&(e in t&&t[e]===o[e]||Object.defineProperty(t,e,{enumerable:!0,get:function(){return o[e]}}))}))},17125:(e,t,n)=>{"use strict";var o=n(20862),r=n(7434),i=o(n(3102)),a=o(n(32772)),s=n(21897),u=n(72573);function c(e,t=!1){this.sessionId=e,this.useCount=0,this.creationTime=(new Date).getTime(),this.sharedWithDevices={},this.blockedDevicesNotified={},this.sharedHistory=t}function l(e){(0,i.polyfillSuper)(this,s.EncryptionAlgorithm,e),this._setupPromise=Promise.resolve(),this._outboundSessions={},this._sessionRotationPeriodMsgs=100,this._sessionRotationPeriodMs=6048e5,void 0!==e.config.rotation_period_ms&&(this._sessionRotationPeriodMs=e.config.rotation_period_ms),void 0!==e.config.rotation_period_msgs&&(this._sessionRotationPeriodMsgs=e.config.rotation_period_msgs)}function d(e){(0,i.polyfillSuper)(this,s.DecryptionAlgorithm,e),this._pendingEvents={},this.olmlib=a}c.prototype.needsRotation=function(e,t){const n=(new Date).getTime()-this.creationTime;return(this.useCount>=e||n>=t)&&(r.logger.log("Rotating megolm session after "+this.useCount+" messages, "+n+"ms"),!0)},c.prototype.markSharedWithDevice=function(e,t,n){this.sharedWithDevices[e]||(this.sharedWithDevices[e]={}),this.sharedWithDevices[e][t]=n},c.prototype.markNotifiedBlockedDevice=function(e,t){this.blockedDevicesNotified[e]||(this.blockedDevicesNotified[e]={}),this.blockedDevicesNotified[e][t]=!0},c.prototype.sharedWithTooManyDevices=function(e){for(const t in this.sharedWithDevices)if(this.sharedWithDevices.hasOwnProperty(t)){if(!e.hasOwnProperty(t))return r.logger.log("Starting new megolm session because we shared with "+t),!0;for(const n in this.sharedWithDevices[t])if(this.sharedWithDevices[t].hasOwnProperty(n)&&!e[t].hasOwnProperty(n))return r.logger.log("Starting new megolm session because we shared with "+t+":"+n),!0}},i.inherits(l,s.EncryptionAlgorithm),l.prototype._ensureOutboundSession=async function(e,t,n,o){let i;function s(){return i}const u=this._setupPromise.then((async s=>{i=s;const u=function(e){const t=e.currentState&&e.currentState.getStateEvents("m.room.history_visibility",""),n=t&&t.getContent()&&t.getContent().history_visibility;return["world_readable","shared"].includes(n)}(e);i&&u!==i.sharedHistory&&(i=null),i&&i.needsRotation(this._sessionRotationPeriodMsgs,this._sessionRotationPeriodMs)&&(r.logger.log("Starting new megolm session because we need to rotate."),i=null),i&&i.sharedWithTooManyDevices(t)&&(i=null),i||(r.logger.log(`Starting new megolm session for room ${this._roomId}`),i=await this._prepareNewSession(u),r.logger.log(`Started new megolm session ${i.sessionId} for room ${this._roomId}`),this._outboundSessions[i.sessionId]=i);const c={};for(const[e,n]of Object.entries(t))for(const[t,o]of Object.entries(n))o.getIdentityKey()!=this._olmDevice.deviceCurve25519Key&&(i.sharedWithDevices[e]&&void 0!==i.sharedWithDevices[e][t]||(c[e]=c[e]||[],c[e].push(o)));const l=this._olmDevice.getOutboundGroupSessionKey(i.sessionId),d={type:"m.room_key",content:{algorithm:a.MEGOLM_ALGORITHM,room_id:this._roomId,session_id:i.sessionId,session_key:l.key,chain_index:l.chain_index,"org.matrix.msc3061.shared_history":u}},[h,p]=await a.getExistingOlmSessions(this._olmDevice,this._baseApis,c);await Promise.all([(async()=>{r.logger.debug(`Sharing keys with existing Olm sessions in ${this._roomId}`),await this._shareKeyWithOlmSessions(i,l,d,p),r.logger.debug(`Shared keys with existing Olm sessions in ${this._roomId}`)})(),(async()=>{r.logger.debug(`Sharing keys (start phase 1) with new Olm sessions in ${this._roomId}`);const e=[],t=Date.now(),n=[];await this._shareKeyWithDevices(i,l,d,h,e,o?1e4:2e3,n),r.logger.debug(`Shared keys (end phase 1) with new Olm sessions in ${this._roomId}`),!o&&Date.now()-t<1e4?(async()=>{const t={},o=new Set;for(const e of n)o.add(e);const a=[];for(const{userId:n,deviceInfo:r}of e){const e=n.slice(n.indexOf(":")+1);o.has(e)?(t[n]=t[n]||[],t[n].push(r)):a.push({userId:n,deviceInfo:r})}r.logger.debug(`Sharing keys (start phase 2) with new Olm sessions in ${this._roomId}`),await this._shareKeyWithDevices(i,l,d,t,a,3e4),r.logger.debug(`Shared keys (end phase 2) with new Olm sessions in ${this._roomId}`),await this._notifyFailedOlmDevices(i,l,a)})():await this._notifyFailedOlmDevices(i,l,e),r.logger.debug(`Shared keys (all phases done) with new Olm sessions in ${this._roomId}`)})(),(async()=>{r.logger.debug(`Notifying blocked devices in ${this._roomId}`);const e={};let t=0;for(const[o,r]of Object.entries(n))for(const[n,a]of Object.entries(r))i.blockedDevicesNotified[o]&&void 0!==i.blockedDevicesNotified[o][n]||(e[o]=e[o]||{},e[o][n]={device:a},t++);await this._notifyBlockedDevices(i,e),r.logger.debug(`Notified ${t} blocked devices in ${this._roomId}`)})()])}));return u.catch((e=>{r.logger.error(`Failed to ensure outbound session in ${this._roomId}`,e)})),this._setupPromise=u.then(s,s),u.then(s)},l.prototype._prepareNewSession=async function(e){const t=this._olmDevice.createOutboundGroupSession(),n=this._olmDevice.getOutboundGroupSessionKey(t);return await this._olmDevice.addInboundGroupSession(this._roomId,this._olmDevice.deviceCurve25519Key,[],t,n.key,{ed25519:this._olmDevice.deviceEd25519Key},!1,{sharedHistory:e}),this._crypto.backupGroupSession(this._roomId,this._olmDevice.deviceCurve25519Key,[],t,n.key),new c(t,e)},l.prototype._getDevicesWithoutSessions=function(e,t,n){n=n||[];for(const[o,r]of Object.entries(t)){const t=e[o];for(const e of r){const r=e.deviceId;t[r].sessionId||(n.push({userId:o,deviceInfo:e}),delete t[r])}}return n},l.prototype._splitDevices=function(e){let t=[];const n=[t];for(const[o,r]of Object.entries(e)){for(const e of Object.values(r))t.push({userId:o,deviceInfo:e.device});t.length>20&&(t=[],n.push(t))}return 0===t.length&&n.pop(),n},l.prototype._encryptAndSendKeysToDevices=function(e,t,n,o){const i={},s=[];for(let e=0;e{for(const e of Object.keys(i)){for(const t of Object.keys(i[e]))0===Object.keys(i[e][t].ciphertext).length&&(r.logger.log("No ciphertext for device "+e+":"+t+": pruning"),delete i[e][t]);0===Object.keys(i[e]).length&&(r.logger.log("Pruned all devices for user "+e),delete i[e])}if(0!==Object.keys(i).length)return this._baseApis.sendToDevice("m.room.encrypted",i).then((()=>{for(const n of Object.keys(i))for(const o of Object.keys(i[n]))e.markSharedWithDevice(n,o,t)}));r.logger.log("No users left to send to: aborting")}))},l.prototype._sendBlockedNotificationsToDevices=async function(e,t,n){const o={};for(const e of t){const t=e.userId,r=e.deviceInfo,i=r.deviceInfo.deviceId,a=Object.assign({},n);a.code=r.code,a.reason=r.reason,"m.no_olm"===a.code&&(delete a.room_id,delete a.session_id),o[t]||(o[t]={}),o[t][i]=a}await this._baseApis.sendToDevice("org.matrix.room_key.withheld",o);for(const t of Object.keys(o))for(const n of Object.keys(o[t]))e.markNotifiedBlockedDevice(t,n)},l.prototype.reshareKeyWithDevice=async function(e,t,n,o){const i=this._outboundSessions[t];if(!i)return void r.logger.debug(`megolm session ${t} not found: not re-sharing keys`);if(void 0===i.sharedWithDevices[n])return void r.logger.debug(`megolm session ${t} never shared with user ${n}`);const s=i.sharedWithDevices[n][o.deviceId];if(void 0===s)return void r.logger.debug("megolm session ID "+t+" never shared with device "+n+":"+o.deviceId);const u=await this._olmDevice.getInboundGroupSessionKey(this._roomId,e,t,s);if(!u)return void r.logger.warn(`No inbound session key found for megolm ${t}: not re-sharing keys`);await a.ensureOlmSessionsForDevices(this._olmDevice,this._baseApis,{[n]:[o]});const c={type:"m.forwarded_room_key",content:{algorithm:a.MEGOLM_ALGORITHM,room_id:this._roomId,session_id:t,session_key:u.key,chain_index:u.chain_index,sender_key:e,sender_claimed_ed25519_key:u.sender_claimed_ed25519_key,forwarding_curve25519_key_chain:u.forwarding_curve25519_key_chain,"org.matrix.msc3061.shared_history":u.shared_history||!1}},l={algorithm:a.OLM_ALGORITHM,sender_key:this._olmDevice.deviceCurve25519Key,ciphertext:{}};await a.encryptMessageForDevice(l.ciphertext,this._userId,this._deviceId,this._olmDevice,n,o,c),await this._baseApis.sendToDevice("m.room.encrypted",{[n]:{[o.deviceId]:l}}),r.logger.debug(`Re-shared key for megolm session ${t} with ${n}:${o.deviceId}`)},l.prototype._shareKeyWithDevices=async function(e,t,n,o,i,s,u){r.logger.debug(`Ensuring Olm sessions for devices in ${this._roomId}`);const c=await a.ensureOlmSessionsForDevices(this._olmDevice,this._baseApis,o,s,u,r.logger.withPrefix(`[${this._roomId}]`));r.logger.debug(`Ensured Olm sessions for devices in ${this._roomId}`),this._getDevicesWithoutSessions(c,o,i),r.logger.debug(`Sharing keys with Olm sessions in ${this._roomId}`),await this._shareKeyWithOlmSessions(e,t,n,c),r.logger.debug(`Shared keys with Olm sessions in ${this._roomId}`)},l.prototype._shareKeyWithOlmSessions=async function(e,t,n,o){const i=this._splitDevices(o);for(let o=0;o{try{r.logger.debug(`Getting devices in ${this._roomId}`);const[t,n]=await this._getDevicesInRoom(e);this._crypto.getGlobalErrorOnUnknownDevices()&&this._removeUnknownDevices(t),r.logger.debug(`Ensuring outbound session in ${this._roomId}`),await this._ensureOutboundSession(e,t,n,!0),r.logger.debug(`Ready to encrypt events for ${this._roomId}`)}catch(e){r.logger.error(`Failed to prepare to encrypt events for ${this._roomId}`,e)}finally{delete this.encryptionPreparationMetadata,delete this.encryptionPreparation}})()},l.prototype.encryptMessage=async function(e,t,n){if(r.logger.log(`Starting to encrypt event for ${this._roomId}`),this.encryptionPreparation)try{await this.encryptionPreparation}catch(e){}const[o,i]=await this._getDevicesInRoom(e);this._crypto.getGlobalErrorOnUnknownDevices()&&this._checkForUnknownDevices(o);const s=await this._ensureOutboundSession(e,o,i),u={room_id:this._roomId,type:t,content:n},c=this._olmDevice.encryptGroupMessage(s.sessionId,JSON.stringify(u)),l={algorithm:a.MEGOLM_ALGORITHM,sender_key:this._olmDevice.deviceCurve25519Key,ciphertext:c,session_id:s.sessionId,device_id:this._deviceId};return s.useCount++,l},l.prototype.forceDiscardSession=function(){this._setupPromise=this._setupPromise.then((()=>null))},l.prototype._checkForUnknownDevices=function(e){const t={};if(Object.keys(e).forEach((n=>{Object.keys(e[n]).forEach((o=>{const r=e[n][o];r.isUnverified()&&!r.isKnown()&&(t[n]||(t[n]={}),t[n][o]=r)}))})),Object.keys(t).length)throw new s.UnknownDeviceError("This room contains unknown devices which have not been verified. We strongly recommend you verify them before continuing.",t)},l.prototype._removeUnknownDevices=function(e){for(const[t,n]of Object.entries(e)){for(const[e,t]of Object.entries(n))t.isUnverified()&&!t.isKnown()&&delete n[e];0===Object.keys(n).length&&delete e[t]}},l.prototype._getDevicesInRoom=async function(e){const t=(await e.getEncryptionTargetMembers()).map((function(e){return e.userId}));let n=this._crypto.getGlobalBlacklistUnverifiedDevices();"boolean"==typeof e.getBlacklistUnverifiedDevices()&&(n=e.getBlacklistUnverifiedDevices());const o=await this._crypto.downloadKeys(t,!1),r={};for(const e in o){if(!o.hasOwnProperty(e))continue;const t=o[e];for(const o in t){if(!t.hasOwnProperty(o))continue;const i=this._crypto.checkDeviceTrust(e,o);if(t[o].isBlocked()||!i.isVerified()&&n){r[e]||(r[e]={});const n=t[o].isBlocked()?{code:"m.blacklisted",reason:u.WITHHELD_MESSAGES["m.blacklisted"]}:{code:"m.unverified",reason:u.WITHHELD_MESSAGES["m.unverified"]};n.deviceInfo=t[o],r[e][o]=n,delete t[o]}}}return[o,r]},i.inherits(d,s.DecryptionAlgorithm);const h={no_olm:"The sender was unable to establish a secure channel.",unknown:"The secure channel with the sender was corrupted."};d.prototype.decryptEvent=async function(e){const t=e.getWireContent();if(!t.sender_key||!t.session_id||!t.ciphertext)throw new s.DecryptionError("MEGOLM_MISSING_FIELDS","Missing fields in input");let n;this._addEventToPendingList(e);try{n=await this._olmDevice.decryptGroupMessage(e.getRoomId(),t.sender_key,t.session_id,t.ciphertext,e.getId(),e.getTs())}catch(n){if("DecryptionError"===n.name)throw n;let o="OLM_DECRYPT_GROUP_MESSAGE_ERROR";throw n&&"OLM.UNKNOWN_MESSAGE_INDEX"===n.message&&(this._requestKeysForEvent(e),o="OLM_UNKNOWN_MESSAGE_INDEX"),new s.DecryptionError(o,n?n.toString():"Unknown Error: Error is undefined",{session:t.sender_key+"|"+t.session_id})}if(null===n){this._requestKeysForEvent(e);const n=await this._olmDevice.sessionMayHaveProblems(t.sender_key,e.getTs()-12e4);if(n){let e=h[n.type]||h.unknown;throw n.fixed&&(e+=" Trying to create a new secure channel and re-requesting the keys."),new s.DecryptionError("MEGOLM_UNKNOWN_INBOUND_SESSION_ID",e,{session:t.sender_key+"|"+t.session_id})}throw new s.DecryptionError("MEGOLM_UNKNOWN_INBOUND_SESSION_ID","The sender's device has not sent us the keys for this message.",{session:t.sender_key+"|"+t.session_id})}this._removeEventFromPendingList(e);const o=JSON.parse(n.result);if(o.room_id!==e.getRoomId())throw new s.DecryptionError("MEGOLM_BAD_ROOM","Message intended for room "+o.room_id);return{clearEvent:o,senderCurve25519Key:n.senderKey,claimedEd25519Key:n.keysClaimed.ed25519,forwardingCurve25519KeyChain:n.forwardingCurve25519KeyChain,untrusted:n.untrusted}},d.prototype._requestKeysForEvent=function(e){const t=e.getWireContent(),n=e.getKeyRequestRecipients(this._userId);this._crypto.requestRoomKey({room_id:e.getRoomId(),algorithm:t.algorithm,sender_key:t.sender_key,session_id:t.session_id},n)},d.prototype._addEventToPendingList=function(e){const t=e.getWireContent(),n=t.sender_key,o=t.session_id;this._pendingEvents[n]||(this._pendingEvents[n]=new Map);const r=this._pendingEvents[n];r.has(o)||r.set(o,new Set),r.get(o).add(e)},d.prototype._removeEventFromPendingList=function(e){const t=e.getWireContent(),n=t.sender_key,o=t.session_id,r=this._pendingEvents[n],i=r&&r.get(o);i&&(i.delete(e),0===i.size&&r.delete(n),0===r.size&&delete this._pendingEvents[n])},d.prototype.onRoomKeyEvent=function(e){const t=e.getContent(),n=t.session_id;let o,i=e.getSenderKey(),a=[],s=!1;if(!t.room_id||!n||!t.session_key)return void r.logger.error("key event is missing fields");if(!i)return void r.logger.error("key event has no sender key (not encrypted?)");if("m.forwarded_room_key"==e.getType()){if(s=!0,a=t.forwarding_curve25519_key_chain,Array.isArray(a)||(a=[]),a=a.slice(),a.push(i),i=t.sender_key,!i)return void r.logger.error("forwarded_room_key event is missing sender_key field");const e=t.sender_claimed_ed25519_key;if(!e)return void r.logger.error("forwarded_room_key_event is missing sender_claimed_ed25519_key field");o={ed25519:e}}else o=e.getKeysClaimed();const u={};return t["org.matrix.msc3061.shared_history"]&&(u.sharedHistory=!0),this._olmDevice.addInboundGroupSession(t.room_id,i,a,n,t.session_key,o,s,u).then((()=>{this._retryDecryption(i,n).then((e=>{e&&this._crypto.cancelRoomKeyRequest({algorithm:t.algorithm,room_id:t.room_id,session_id:t.session_id,sender_key:i})}))})).then((()=>{this._crypto.backupGroupSession(t.room_id,i,a,t.session_id,t.session_key,o,s)})).catch((e=>{r.logger.error(`Error handling m.room_key_event: ${e}`)}))},d.prototype.onRoomKeyWithheldEvent=async function(e){const t=e.getContent(),n=t.sender_key;if("m.no_olm"===t.code){const o=e.getSender();if(r.logger.warn(`${o}:${n} was unable to establish an olm session with us`),await this._olmDevice.getSessionIdForDevice(n))return r.logger.debug("New session already created. Not creating a new one."),await this._olmDevice.recordSessionProblem(n,"no_olm",!0),void this.retryDecryptionFromSender(n);let i=this._crypto._deviceList.getDeviceByIdentityKey(t.algorithm,n);if(!i&&(await this._crypto.downloadKeys([o],!1),i=this._crypto._deviceList.getDeviceByIdentityKey(t.algorithm,n),!i))return r.logger.info("Couldn't find device for identity key "+n+": not establishing session"),await this._olmDevice.recordSessionProblem(n,"no_olm",!1),void this.retryDecryptionFromSender(n);await a.ensureOlmSessionsForDevices(this._olmDevice,this._baseApis,{[o]:[i]},!1);const s={algorithm:a.OLM_ALGORITHM,sender_key:this._olmDevice.deviceCurve25519Key,ciphertext:{}};await a.encryptMessageForDevice(s.ciphertext,this._userId,this._deviceId,this._olmDevice,o,i,{type:"m.dummy"}),await this._olmDevice.recordSessionProblem(n,"no_olm",!0),this.retryDecryptionFromSender(n),await this._baseApis.sendToDevice("m.room.encrypted",{[o]:{[i.deviceId]:s}})}else await this._olmDevice.addInboundGroupSessionWithheld(t.room_id,n,t.session_id,t.code,t.reason)},d.prototype.hasKeysForKeyRequest=function(e){const t=e.requestBody;return this._olmDevice.hasInboundSessionKeys(t.room_id,t.sender_key,t.session_id)},d.prototype.shareKeysWithDevice=function(e){const t=e.userId,n=e.deviceId,o=this._crypto.getStoredDevice(t,n),i=e.requestBody;this.olmlib.ensureOlmSessionsForDevices(this._olmDevice,this._baseApis,{[t]:[o]}).then((e=>e[t][n].sessionId?(r.logger.log("sharing keys for session "+i.sender_key+"|"+i.session_id+" with device "+t+":"+n),this._buildKeyForwardingMessage(i.room_id,i.sender_key,i.session_id)):null)).then((e=>{const r={algorithm:a.OLM_ALGORITHM,sender_key:this._olmDevice.deviceCurve25519Key,ciphertext:{}};return this.olmlib.encryptMessageForDevice(r.ciphertext,this._userId,this._deviceId,this._olmDevice,t,o,e).then((()=>{const e={[t]:{[n]:r}};return this._baseApis.sendToDevice("m.room.encrypted",e)}))}))},d.prototype._buildKeyForwardingMessage=async function(e,t,n){const o=await this._olmDevice.getInboundGroupSessionKey(e,t,n);return{type:"m.forwarded_room_key",content:{algorithm:a.MEGOLM_ALGORITHM,room_id:e,sender_key:t,sender_claimed_ed25519_key:o.sender_claimed_ed25519_key,session_id:n,session_key:o.key,chain_index:o.chain_index,forwarding_curve25519_key_chain:o.forwarding_curve25519_key_chain,"org.matrix.msc3061.shared_history":o.shared_history||!1}}},d.prototype.importRoomKey=function(e,t={}){const n={};return t.untrusted&&(n.untrusted=!0),e["org.matrix.msc3061.shared_history"]&&(n.sharedHistory=!0),this._olmDevice.addInboundGroupSession(e.room_id,e.sender_key,e.forwarding_curve25519_key_chain,e.session_id,e.session_key,e.sender_claimed_keys,!0,n).then((()=>{"backup"!==t.source&&this._crypto.backupGroupSession(e.room_id,e.sender_key,e.forwarding_curve25519_key_chain,e.session_id,e.session_key,e.sender_claimed_keys,!0).catch((e=>{r.logger.log("Failed to back up megolm session",e)})),this._retryDecryption(e.sender_key,e.session_id)}))},d.prototype._retryDecryption=async function(e,t){const n=this._pendingEvents[e];if(!n)return!0;const o=n.get(t);return!o||(r.logger.debug("Retrying decryption on events",[...o]),await Promise.all([...o].map((async e=>{try{await e.attemptDecryption(this._crypto,{isRetry:!0})}catch(e){}}))),!(this._pendingEvents[e]||{})[t])},d.prototype.retryDecryptionFromSender=async function(e){const t=this._pendingEvents[e];return!t||(delete this._pendingEvents[e],await Promise.all([...t].map((async([e,t])=>{await Promise.all([...t].map((async e=>{try{await e.attemptDecryption(this._crypto)}catch(e){}})))}))),!this._pendingEvents[e])},d.prototype.sendSharedHistoryInboundSessions=async function(e){await a.ensureOlmSessionsForDevices(this._olmDevice,this._baseApis,e),r.logger.log("sendSharedHistoryInboundSessions to users",Object.keys(e));const t=await this._olmDevice.getSharedHistoryInboundGroupSessions(this._roomId);r.logger.log("shared-history sessions",t);for(const[n,o]of t){const t=await this._buildKeyForwardingMessage(this._roomId,n,o),i=[],s={};for(const[n,o]of Object.entries(e)){s[n]={};for(const e of o){const o={algorithm:a.OLM_ALGORITHM,sender_key:this._olmDevice.deviceCurve25519Key,ciphertext:{}};s[n][e.deviceId]=o,i.push(a.encryptMessageForDevice(o.ciphertext,this._userId,this._deviceId,this._olmDevice,n,e,t))}}await Promise.all(i);for(const e of Object.keys(s)){for(const t of Object.keys(s[e]))0===Object.keys(s[e][t].ciphertext).length&&(r.logger.log("No ciphertext for device "+e+":"+t+": pruning"),delete s[e][t]);0===Object.keys(s[e]).length&&(r.logger.log("Pruned all devices for user "+e),delete s[e])}if(0===Object.keys(s).length)return void r.logger.log("No users left to send to: aborting");await this._baseApis.sendToDevice("m.room.encrypted",s)}},(0,s.registerAlgorithm)(a.MEGOLM_ALGORITHM,l,d)},23072:(e,t,n)=>{"use strict";var o=n(20862),r=n(7434),i=o(n(3102)),a=o(n(32772)),s=n(23272),u=n(21897);const c=s.DeviceInfo.DeviceVerification;function l(e){(0,i.polyfillSuper)(this,u.EncryptionAlgorithm,e),this._sessionPrepared=!1,this._prepPromise=null}function d(e){(0,i.polyfillSuper)(this,u.DecryptionAlgorithm,e)}i.inherits(l,u.EncryptionAlgorithm),l.prototype._ensureSession=function(e){if(this._prepPromise)return this._prepPromise;if(this._sessionPrepared)return Promise.resolve();const t=this;return this._prepPromise=t._crypto.downloadKeys(e).then((function(n){return t._crypto.ensureOlmSessionsForUsers(e)})).then((function(){t._sessionPrepared=!0})).finally((function(){t._prepPromise=null})),this._prepPromise},l.prototype.encryptMessage=async function(e,t,n){const o=(await e.getEncryptionTargetMembers()).map((function(e){return e.userId})),r=this;await this._ensureSession(o);const i={room_id:e.roomId,type:t,content:n},s={algorithm:a.OLM_ALGORITHM,sender_key:r._olmDevice.deviceCurve25519Key,ciphertext:{}},u=[];for(let e=0;es))},i.inherits(d,u.DecryptionAlgorithm),d.prototype.decryptEvent=async function(e){const t=e.getWireContent(),n=t.sender_key,o=t.ciphertext;if(!o)throw new u.DecryptionError("OLM_MISSING_CIPHERTEXT","Missing ciphertext");if(!(this._olmDevice.deviceCurve25519Key in o))throw new u.DecryptionError("OLM_NOT_INCLUDED_IN_RECIPIENTS","Not included in recipients");const r=o[this._olmDevice.deviceCurve25519Key];let i;try{i=await this._decryptMessage(n,r)}catch(e){throw new u.DecryptionError("OLM_BAD_ENCRYPTED_MESSAGE","Bad Encrypted Message",{sender:n,err:e})}const a=JSON.parse(i);if(a.recipient!=this._userId)throw new u.DecryptionError("OLM_BAD_RECIPIENT","Message was intented for "+a.recipient);if(a.recipient_keys.ed25519!=this._olmDevice.deviceEd25519Key)throw new u.DecryptionError("OLM_BAD_RECIPIENT_KEY","Message not intended for this device",{intended:a.recipient_keys.ed25519,our_key:this._olmDevice.deviceEd25519Key});if(a.sender!=e.getSender())throw new u.DecryptionError("OLM_FORWARDED_MESSAGE","Message forwarded from "+a.sender,{reported_sender:e.getSender()});if(a.room_id!==e.getRoomId())throw new u.DecryptionError("OLM_BAD_ROOM","Message intended for room "+a.room_id,{reported_room:e.room_id});return{clearEvent:a,senderCurve25519Key:n,claimedEd25519Key:(a.keys||{}).ed25519||null}},d.prototype._decryptMessage=async function(e,t){if(0!==t.type)return this._reallyDecryptMessage(e,t);{const n=this._olmDevice._olmPrekeyPromise.then((()=>this._reallyDecryptMessage(e,t)));return this._olmDevice._olmPrekeyPromise=n.catch((()=>{})),await n}},d.prototype._reallyDecryptMessage=async function(e,t){const n=await this._olmDevice.getSessionIdsForDevice(e),o={};for(let i=0;i{"use strict";var o=n(95318);Object.defineProperty(t,"__esModule",{value:!0}),t.DehydrationManager=t.DEHYDRATION_ALGORITHM=void 0;var r=o(n(59713)),i=n(32772),a=n(57585),s=n(2611),u=o(n(69141)),c=n(7434);const l="org.matrix.msc2697.v1.olm.libolm_pickle";t.DEHYDRATION_ALGORITHM=l;const d=6048e5;t.DehydrationManager=class{constructor(e){this.crypto=e,(0,r.default)(this,"inProgress",!1),(0,r.default)(this,"timeoutId",void 0),(0,r.default)(this,"key",void 0),(0,r.default)(this,"keyInfo",void 0),(0,r.default)(this,"deviceDisplayName",void 0),this.getDehydrationKeyFromCache()}async getDehydrationKeyFromCache(){return await this.crypto._cryptoStore.doTxn("readonly",[a.IndexedDBCryptoStore.STORE_ACCOUNT],(e=>{this.crypto._cryptoStore.getSecretStorePrivateKey(e,(async e=>{if(e){const{key:t,keyInfo:o,deviceDisplayName:r,time:a}=e,u=Buffer.from(this.crypto._olmDevice._pickleKey),c=await(0,s.decryptAES)(t,u,l);this.key=(0,i.decodeBase64)(c),this.keyInfo=o,this.deviceDisplayName=r;const h=Date.now(),p=Math.max(1,a+d-h);this.timeoutId=n.g.setTimeout(this.dehydrateDevice.bind(this),p)}}),"dehydration")}))}async setKeyAndQueueDehydration(e,t={},n){await this.setKey(e,t,n)||this.dehydrateDevice()}async setKey(e,t={},o){if(!e)return this.timeoutId&&(n.g.clearTimeout(this.timeoutId),this.timeoutId=void 0),await this.crypto._cryptoStore.doTxn("readwrite",[a.IndexedDBCryptoStore.STORE_ACCOUNT],(e=>{this.crypto._cryptoStore.storeSecretStorePrivateKey(e,"dehydration",null)})),this.key=void 0,void(this.keyInfo=void 0);let r=this.key&&e.length==this.key.length;for(let t=0;r&&t{this.crypto._cryptoStore.storeSecretStorePrivateKey(e,"dehydration",{keyInfo:this.keyInfo,key:t,deviceDisplayName:this.deviceDisplayName,time:Date.now()})})),c.logger.log("Attempting to dehydrate device"),c.logger.log("Creating account");const o=new n.g.Olm.Account;o.create();const r=JSON.parse(o.identity_keys()),h=o.max_number_of_one_time_keys();o.generate_one_time_keys(h/2),o.generate_fallback_key();const p=JSON.parse(o.one_time_keys()),f=JSON.parse(o.fallback_key());o.mark_keys_as_published();const g=o.pickle(new Uint8Array(this.key)),m={algorithm:l,account:g};this.keyInfo.passphrase&&(m.passphrase=this.keyInfo.passphrase),c.logger.log("Uploading account to server");const _=(await this.crypto._baseApis._http.authedRequest(void 0,"PUT","/dehydrated_device",void 0,{device_data:m,initial_device_display_name:this.deviceDisplayName},{prefix:"/_matrix/client/unstable/org.matrix.msc2697.v2"})).device_id;c.logger.log("Preparing device keys",_);const F={algorithms:this.crypto._supportedAlgorithms,device_id:_,user_id:this.crypto._userId,keys:{[`ed25519:${_}`]:r.ed25519,[`curve25519:${_}`]:r.curve25519}},y=o.sign(u.default.stringify(F));F.signatures={[this.crypto._userId]:{[`ed25519:${_}`]:y}},this.crypto._crossSigningInfo.getId("self_signing")&&await this.crypto._crossSigningInfo.signObject(F,"self_signing"),c.logger.log("Preparing one-time keys");const b={};for(const[e,t]of Object.entries(p.curve25519)){const n={key:t},r=o.sign(u.default.stringify(n));n.signatures={[this.crypto._userId]:{[`ed25519:${_}`]:r}},b[`signed_curve25519:${e}`]=n}c.logger.log("Preparing fallback keys");const v={};for(const[e,t]of Object.entries(f.curve25519)){const n={key:t,fallback:!0},r=o.sign(u.default.stringify(n));n.signatures={[this.crypto._userId]:{[`ed25519:${_}`]:r}},v[`signed_curve25519:${e}`]=n}return c.logger.log("Uploading keys to server"),await this.crypto._baseApis._http.authedRequest(void 0,"POST","/keys/upload/"+encodeURI(_),void 0,{device_keys:F,one_time_keys:b,"org.matrix.msc2732.fallback_keys":v}),c.logger.log("Done dehydrating"),this.timeoutId=n.g.setTimeout(this.dehydrateDevice.bind(this),d),_}finally{this.inProgress=!1}}}stop(){this.timeoutId&&(n.g.clearTimeout(this.timeoutId),this.timeoutId=void 0)}}},23272:(e,t)=>{"use strict";function n(e){Object.defineProperty(this,"deviceId",{enumerable:!0,value:e}),this.algorithms=[],this.keys={},this.verified=o.UNVERIFIED,this.known=!1,this.unsigned={},this.signatures={}}Object.defineProperty(t,"__esModule",{value:!0}),t.DeviceInfo=n,n.fromStorage=function(e,t){const o=new n(t);for(const t in e)e.hasOwnProperty(t)&&(o[t]=e[t]);return o},n.prototype.toStorage=function(){return{algorithms:this.algorithms,keys:this.keys,verified:this.verified,known:this.known,unsigned:this.unsigned,signatures:this.signatures}},n.prototype.getFingerprint=function(){return this.keys["ed25519:"+this.deviceId]},n.prototype.getIdentityKey=function(){return this.keys["curve25519:"+this.deviceId]},n.prototype.getDisplayName=function(){return this.unsigned.device_display_name||null},n.prototype.isBlocked=function(){return this.verified==o.BLOCKED},n.prototype.isVerified=function(){return this.verified==o.VERIFIED},n.prototype.isUnverified=function(){return this.verified==o.UNVERIFIED},n.prototype.isKnown=function(){return 1==this.known},n.DeviceVerification={VERIFIED:1,UNVERIFIED:0,BLOCKED:-1};const o=n.DeviceVerification},12600:(e,t,n)=>{"use strict";var o=n(20862),r=n(95318);Object.defineProperty(t,"__esModule",{value:!0}),t.isCryptoAvailable=function(){return Boolean(n.g.Olm)},t.Crypto=B,t.fixBackupKey=N,t.verificationMethods=void 0;var i=r(n(69141)),a=n(17187),s=n(20771),u=n(7434),c=o(n(3102)),l=n(72573),d=o(n(32772)),h=n(36670),p=n(23272),f=o(n(91994)),g=n(3075),m=n(70636),_=n(44823),F=n(66617),y=n(57585),b=n(51696),v=n(56381),w=n(91597),E=n(34077),k=n(85279),D=n(22842),S=n(89588),x=n(4028),C=n(19489),A=n(2611),T=n(54830),R=n(24369);const I=p.DeviceInfo.DeviceVerification,M={[b.ReciprocateQRCode.NAME]:b.ReciprocateQRCode,[v.SAS.NAME]:v.SAS,[b.SHOW_QR_CODE_METHOD]:x.IllegalMethod,[b.SCAN_QR_CODE_METHOD]:x.IllegalMethod},O={RECIPROCATE_QR_CODE:b.ReciprocateQRCode.NAME,SAS:v.SAS.NAME};function B(e,t,n,o,r,i,a,c){if(this._onDeviceListUserCrossSigningUpdated=this._onDeviceListUserCrossSigningUpdated.bind(this),this._trustCrossSignedDevices=!0,this._reEmitter=new s.ReEmitter(this),this._baseApis=e,this._sessionStore=t,this._userId=n,this._deviceId=o,this._clientStore=r,this._cryptoStore=i,this._roomList=a,c){this._verificationMethods=new Map;for(const e of c)"string"==typeof e?M[e]&&this._verificationMethods.set(e,M[e]):e.NAME?this._verificationMethods.set(e.NAME,e):u.logger.warn(`Excluding unknown verification method ${e}`)}else this._verificationMethods=M;this.backupInfo=null,this.backupKey=null,this._checkedForBackup=!1,this._sendingBackups=!1,this._olmDevice=new l.OlmDevice(i),this._deviceList=new h.DeviceList(e,i,this._olmDevice),this._deviceList.on("userCrossSigningUpdated",this._onDeviceListUserCrossSigningUpdated),this._reEmitter.reEmit(this._deviceList,["crypto.devicesUpdated","crypto.willUpdateDevices"]),this._lastOneTimeKeyCheck=null,this._oneTimeKeyCheckInProgress=!1,this._roomEncryptors={},this._roomDecryptors={},this._supportedAlgorithms=Object.keys(f.DECRYPTION_CLASSES),this._deviceKeys={},this._globalBlacklistUnverifiedDevices=!1,this._globalErrorOnUnknownDevices=!0,this._outgoingRoomKeyRequestManager=new F.OutgoingRoomKeyRequestManager(e,this._deviceId,this._cryptoStore),this._receivedRoomKeyRequests=[],this._receivedRoomKeyRequestCancellations=[],this._processingRoomKeyRequests=!1,this._lazyLoadMembers=!1,this._roomDeviceTrackingState={},this._lastNewSessionForced={},this._toDeviceVerificationRequests=new S.ToDeviceRequests,this._inRoomVerificationRequests=new D.InRoomRequests,this._sendKeyRequestsImmediately=!1;const d=this._baseApis._cryptoCallbacks||{},p=(0,g.createCryptoStoreCacheCallbacks)(i,this._olmDevice);this._crossSigningInfo=new g.CrossSigningInfo(n,d,p),this._secretStorage=new _.SecretStorage(e,d),this._dehydrationManager=new T.DehydrationManager(this),!d.getCrossSigningKey&&d.getSecretStorageKey&&(d.getCrossSigningKey=async e=>g.CrossSigningInfo.getFromSecretStorage(e,this._secretStorage))}function N(e){if("string"!=typeof e||e.indexOf(",")<0)return null;const t=Uint8Array.from(e.split(","),(e=>parseInt(e)));return d.encodeBase64(t)}async function L(e){const t=[],n={};if(e.getNeedsNewFallback()){const o=await e._olmDevice.getFallbackKey();for(const[r,i]of Object.entries(o.curve25519)){const o={key:i,fallback:!0};n["signed_curve25519:"+r]=o,t.push(e._signObject(o))}e.setNeedsNewFallback(!1)}const o=await e._olmDevice.getOneTimeKeys(),r={};for(const n in o.curve25519)if(o.curve25519.hasOwnProperty(n)){const i={key:o.curve25519[n]};r["signed_curve25519:"+n]=i,t.push(e._signObject(i))}await Promise.all(t);const i=await e._baseApis.uploadKeysRequest({one_time_keys:r,"org.matrix.msc2732.fallback_keys":n});return await e._olmDevice.markKeysAsPublished(),i}t.verificationMethods=O,c.inherits(B,a.EventEmitter),B.prototype.init=async function(e){const{exportedOlmDevice:t,pickleKey:o}=e||{};u.logger.log("Crypto: initialising Olm..."),await n.g.Olm.init(),u.logger.log(t?"Crypto: initialising Olm device from exported device...":"Crypto: initialising Olm device..."),await this._olmDevice.init({fromExportedDevice:t,pickleKey:o}),u.logger.log("Crypto: loading device list..."),await this._deviceList.load(),this._deviceKeys["ed25519:"+this._deviceId]=this._olmDevice.deviceEd25519Key,this._deviceKeys["curve25519:"+this._deviceId]=this._olmDevice.deviceCurve25519Key,u.logger.log("Crypto: fetching own devices...");let r=this._deviceList.getRawStoredDevicesForUser(this._userId);if(r||(r={}),!r[this._deviceId]){u.logger.log("Crypto: adding this device to the store...");const e={keys:this._deviceKeys,algorithms:this._supportedAlgorithms,verified:I.VERIFIED,known:!0};r[this._deviceId]=e,this._deviceList.storeDevicesForUser(this._userId,r),this._deviceList.saveIfDirty()}await this._cryptoStore.doTxn("readonly",[y.IndexedDBCryptoStore.STORE_ACCOUNT],(e=>{this._cryptoStore.getCrossSigningKeys(e,(e=>{e&&0!==Object.keys(e).length&&(u.logger.log("Loaded cross-signing public keys from crypto store"),this._crossSigningInfo.setKeys(e))}))})),this._deviceList.startTrackingDeviceList(this._userId),u.logger.log("Crypto: checking for key backup..."),this._checkAndStartKeyBackup()},B.prototype.getCryptoTrustCrossSignedDevices=function(){return this._trustCrossSignedDevices},B.prototype.setCryptoTrustCrossSignedDevices=function(e){this._trustCrossSignedDevices=e;for(const e of this._deviceList.getKnownUserIds()){const t=this._deviceList.getRawStoredDevicesForUser(e);for(const n of Object.keys(t)){const t=this.checkDeviceTrust(e,n);if(!t.isLocallyVerified()&&t.isCrossSigningVerified()){const t=this._deviceList.getStoredDevice(e,n);this.emit("deviceVerificationChanged",e,n,t)}}}},B.prototype.createRecoveryKeyFromPassphrase=async function(e){const t=new n.g.Olm.PkDecryption;try{const n={};if(e){const o=await(0,w.keyFromPassphrase)(e);n.passphrase={algorithm:"m.pbkdf2",iterations:o.iterations,salt:o.salt},n.pubkey=t.init_with_private_key(o.key)}else n.pubkey=t.generate_key();const o=t.get_private_key();return{keyInfo:n,encodedPrivateKey:(0,E.encodeRecoveryKey)(o),privateKey:o}}finally{t&&t.free()}},B.prototype.isCrossSigningReady=async function(){const e=this._crossSigningInfo.getId(),t=await this._crossSigningInfo.isStoredInKeyCache()||await this._crossSigningInfo.isStoredInSecretStorage(this._secretStorage);return!(!e||!t)},B.prototype.isSecretStorageReady=async function(){const e=await this._secretStorage.hasKey(),t=await this._crossSigningInfo.isStoredInSecretStorage(this._secretStorage),n=!this._baseApis.getKeyBackupEnabled()||this._baseApis.isKeyBackupKeyStored();return!!(e&&t&&n)},B.prototype.bootstrapCrossSigning=async function({authUploadDeviceSigningKeys:e,setupNewCrossSigning:t}={}){u.logger.log("Bootstrapping cross-signing");const n=this._baseApis._cryptoCallbacks,o=new m.EncryptionSetupBuilder(this._baseApis.store.accountData,n),r=new g.CrossSigningInfo(this._userId,o.crossSigningCallbacks,o.crossSigningCallbacks),i=this._crossSigningInfo.getId(),a=await this._crossSigningInfo.isStoredInKeyCache(),s=await this._crossSigningInfo.isStoredInSecretStorage(this._secretStorage),c=a||s;u.logger.log({setupNewCrossSigning:t,publicKeysOnDevice:i,privateKeysInCache:a,privateKeysInStorage:s,privateKeysExistSomewhere:c}),!c||t?(u.logger.log("Cross-signing private keys not found locally or in secret storage, creating new keys"),await(async()=>{r.resetKeys(),await this._signObject(r.keys.master),o.addCrossSigningKeys(e,r.keys);const t=this._deviceList.getStoredDevice(this._userId,this._deviceId),n=await r.signDevice(this._userId,t);o.addKeySignature(this._userId,this._deviceId,n),this.backupInfo&&(await r.signObject(this.backupInfo.auth_data,"master"),o.addSessionBackup(this.backupInfo))})()):i&&a?u.logger.log("Cross-signing public keys trusted and private keys found locally"):s&&(u.logger.log("Cross-signing private keys not found locally, but they are available in secret storage, reading storage and caching locally"),await this.checkOwnCrossSigningTrust({allowPrivateKeyRequests:!0}));const l=o.crossSigningCallbacks.privateKeys;if(l.size&&!this._baseApis._cryptoCallbacks.saveCrossSigningKeys){const e=new _.SecretStorage(o.accountDataClientAdapter,o.ssssCryptoCallbacks);await e.hasKey()&&(u.logger.log("Storing new cross-signing private keys in secret storage"),await g.CrossSigningInfo.storeInSecretStorage(l,e))}const d=o.buildOperation();await d.apply(this),await o.persist(this),u.logger.log("Cross-signing ready")},B.prototype.bootstrapSecretStorage=async function({createSecretStorageKey:e=(async()=>({})),keyBackupInfo:t,setupNewKeyBackup:n,setupNewSecretStorage:o,getKeyBackupPassphrase:r}={}){u.logger.log("Bootstrapping Secure Secret Storage");const i=this._baseApis._cryptoCallbacks,a=new m.EncryptionSetupBuilder(this._baseApis.store.accountData,i),s=new _.SecretStorage(a.accountDataClientAdapter,a.ssssCryptoCallbacks);let c=null;const l=async(e,t)=>{e=e||{},t&&(e.key=t);const{keyId:n,keyInfo:o}=await s.addKey(_.SECRET_STORAGE_ALGORITHM_V1_AES,e);return t&&a.ssssCryptoCallbacks.addPrivateKey(n,o,t),await s.setDefaultKeyId(n),n},h=async e=>{if(this._crossSigningInfo.getId()&&await this._crossSigningInfo.isStoredInKeyCache("master"))try{u.logger.log("Adding cross-signing signature to key backup"),await this._crossSigningInfo.signObject(e,"master")}catch(e){u.logger.error("Signing key backup with cross-signing keys failed",e)}else u.logger.warn("Cross-signing keys not available, skipping signature on key backup")},p=await this.getSecretStorageKey(),[f,F]=p||[null,null],y=!o&&F&&F.algorithm===_.SECRET_STORAGE_ALGORITHM_V1_AES;if(u.logger.log({keyBackupInfo:t,setupNewKeyBackup:n,setupNewSecretStorage:o,storageExists:y,oldKeyInfo:F}),y||t)if(!y&&t){u.logger.log("Secret storage does not exist, using key backup key");const e=await this.getSessionBackupPrivateKey()||await r(),n={};t.auth_data.private_key_salt&&t.auth_data.private_key_iterations&&(n.passphrase={algorithm:"m.pbkdf2",iterations:t.auth_data.private_key_iterations,salt:t.auth_data.private_key_salt,bits:256}),c=await l(n,e),await s.store("m.megolm_backup.v1",d.encodeBase64(e),[c]),await h(t.auth_data),a.addSessionBackup(t)}else u.logger.log("Secret storage exists"),F&&F.algorithm===_.SECRET_STORAGE_ALGORITHM_V1_AES&&await(async(e,t)=>{if(!t.mac){const n=await this._baseApis._cryptoCallbacks.getSecretStorageKey({keys:{[e]:t}},"");if(n){const o=n[1];a.ssssCryptoCallbacks.addPrivateKey(e,t,o);const{iv:r,mac:i}=await _.SecretStorage._calculateKeyCheck(o);t.iv=r,t.mac=i,await a.setAccountData(`m.secret_storage.key.${e}`,t)}}})(f,F);else{u.logger.log("Secret storage does not exist, creating new storage key");const{keyInfo:t,privateKey:n}=await e();c=await l(t,n)}if(!this._baseApis._cryptoCallbacks.saveCrossSigningKeys&&await this.isCrossSigningReady()&&(c||!await this._crossSigningInfo.isStoredInSecretStorage(s))){u.logger.log("Copying cross-signing private keys from cache to secret storage");const e=await this._crossSigningInfo.getCrossSigningKeysFromCache();await g.CrossSigningInfo.storeInSecretStorage(e,s)}if(n&&!t){u.logger.log("Creating new message key backup version");const e=await this._baseApis.prepareKeyBackupVersion(null,{secureSecretStorage:!1}),t=(0,E.decodeRecoveryKey)(e.recovery_key);await s.store("m.megolm_backup.v1",d.encodeBase64(t));const n={algorithm:e.algorithm,auth_data:e.auth_data};await h(n.auth_data),await this._signObject(n.auth_data),a.addSessionBackup(n)}const b=await s.get("m.megolm_backup.v1");if(b){u.logger.info("Got session backup key from secret storage: caching");const e=N(b);e&&await s.store("m.megolm_backup.v1",e,[c||f]);const t=new Uint8Array(d.decodeBase64(e||b));await a.addSessionBackupPrivateKeyToCache(t)}const v=a.buildOperation();await v.apply(this),await a.persist(this),u.logger.log("Secure Secret Storage ready")},B.prototype.addSecretStorageKey=function(e,t,n){return this._secretStorage.addKey(e,t,n)},B.prototype.hasSecretStorageKey=function(e){return this._secretStorage.hasKey(e)},B.prototype.getSecretStorageKey=function(e){return this._secretStorage.getKey(e)},B.prototype.storeSecret=function(e,t,n){return this._secretStorage.store(e,t,n)},B.prototype.getSecret=function(e){return this._secretStorage.get(e)},B.prototype.isSecretStored=function(e,t){return this._secretStorage.isStored(e,t)},B.prototype.requestSecret=function(e,t){return t||(t=Object.keys(this._deviceList.getRawStoredDevicesForUser(this._userId))),this._secretStorage.request(e,t)},B.prototype.getDefaultSecretStorageKeyId=function(){return this._secretStorage.getDefaultKeyId()},B.prototype.setDefaultSecretStorageKeyId=function(e){return this._secretStorage.setDefaultKeyId(e)},B.prototype.checkSecretStorageKey=function(e,t){return this._secretStorage.checkKey(e,t)},B.prototype.checkSecretStoragePrivateKey=function(e,t){let o=null;try{return o=new n.g.Olm.PkDecryption,o.init_with_private_key(e)===t}finally{o&&o.free()}},B.prototype.getSessionBackupPrivateKey=async function(){let e=await new Promise((e=>{this._cryptoStore.doTxn("readonly",[y.IndexedDBCryptoStore.STORE_ACCOUNT],(t=>{this._cryptoStore.getSecretStorePrivateKey(t,e,"m.megolm_backup.v1")}))}));if(e&&"string"==typeof e&&(e=new Uint8Array(d.decodeBase64(N(e)||e)),await this.storeSessionBackupPrivateKey(e)),e&&e.ciphertext){const t=Buffer.from(this._olmDevice._pickleKey),n=await(0,A.decryptAES)(e,t,"m.megolm_backup.v1");e=d.decodeBase64(n)}return e},B.prototype.storeSessionBackupPrivateKey=async function(e){if(!(e instanceof Uint8Array))throw new Error(`storeSessionBackupPrivateKey expects Uint8Array, got ${e}`);const t=Buffer.from(this._olmDevice._pickleKey);return e=await(0,A.encryptAES)(d.encodeBase64(e),t,"m.megolm_backup.v1"),this._cryptoStore.doTxn("readwrite",[y.IndexedDBCryptoStore.STORE_ACCOUNT],(t=>{this._cryptoStore.storeSecretStorePrivateKey(t,"m.megolm_backup.v1",e)}))},B.prototype.checkCrossSigningPrivateKey=function(e,t){let o=null;try{return o=new n.g.Olm.PkSigning,o.init_with_seed(e)===t}finally{o&&o.free()}},B.prototype._afterCrossSigningLocalKeyChange=async function(){u.logger.info("Starting cross-signing key change post-processing");const e=this._deviceList.getStoredDevice(this._userId,this._deviceId),t=await this._crossSigningInfo.signDevice(this._userId,e);u.logger.info(`Starting background key sig upload for ${this._deviceId}`);const n=({shouldEmit:e})=>this._baseApis.uploadKeySignatures({[this._userId]:{[this._deviceId]:t}}).then((t=>{const{failures:o}=t||{};if(Object.keys(o||[]).length>0)throw e&&this._baseApis.emit("crypto.keySignatureUploadFailure",o,"_afterCrossSigningLocalKeyChange",n),new C.KeySignatureUploadError("Key upload failed",{failures:o});u.logger.info(`Finished background key sig upload for ${this._deviceId}`)})).catch((e=>{u.logger.error(`Error during background key sig upload for ${this._deviceId}`,e)}));n({shouldEmit:!0});const o=this._baseApis._cryptoCallbacks.shouldUpgradeDeviceVerifications;if(o){u.logger.info("Starting device verification upgrade");const e={};for(const[t,n]of Object.entries(this._deviceList._crossSigningInfo)){const o=await this._checkForDeviceVerificationUpgrade(t,g.CrossSigningInfo.fromStorage(n,t));o&&(e[t]=o)}if(Object.keys(e).length>0){u.logger.info(`Found ${Object.keys(e).length} verif users to upgrade`);try{const t=await o({users:e});if(t)for(const n of t)n in e&&await this._baseApis.setDeviceVerified(n,e[n].crossSigningInfo.getId())}catch(e){u.logger.log("shouldUpgradeDeviceVerifications threw an error: not upgrading",e)}}u.logger.info("Finished device verification upgrade")}u.logger.info("Finished cross-signing key change post-processing")},B.prototype._checkForDeviceVerificationUpgrade=async function(e,t){const n=this._crossSigningInfo.checkUserTrust(t);if(t.firstUse&&!n.verified){const n=this._deviceList.getRawStoredDevicesForUser(e),o=await this._checkForValidDeviceSignature(e,t.keys.master,n);if(o.length)return{devices:o.map((e=>p.DeviceInfo.fromStorage(n[e],e))),crossSigningInfo:t}}},B.prototype._checkForValidDeviceSignature=async function(e,t,n){const o=[];if(n&&t.signatures&&t.signatures[e])for(const r of Object.keys(t.signatures[e])){const[,i]=r.split(":",2);if(i in n&&n[i].verified===I.VERIFIED)try{await d.verifySignature(this._olmDevice,t,e,i,n[i].keys[r]),o.push(i)}catch(e){}}return o},B.prototype.getCrossSigningId=function(e){return this._crossSigningInfo.getId(e)},B.prototype.getStoredCrossSigningForUser=function(e){return this._deviceList.getStoredCrossSigningForUser(e)},B.prototype.checkUserTrust=function(e){const t=this._deviceList.getStoredCrossSigningForUser(e);return t?this._crossSigningInfo.checkUserTrust(t):new g.UserTrustLevel(!1,!1,!1)},B.prototype.checkDeviceTrust=function(e,t){const n=this._deviceList.getStoredDevice(e,t);return this._checkDeviceInfoTrust(e,n)},B.prototype._checkDeviceInfoTrust=function(e,t){const n=!(!t||!t.isVerified()),o=this._deviceList.getStoredCrossSigningForUser(e);if(t&&o){const r=this._trustCrossSignedDevices||e===this._userId;return this._crossSigningInfo.checkDeviceTrust(o,t,n,r)}return new g.DeviceTrustLevel(!1,!1,n,!1)},B.prototype._onDeviceListUserCrossSigningUpdated=async function(e){if(e===this._userId){const t=this._deviceList.getStoredCrossSigningForUser(e),n=t?t.getId():null,o=this._crossSigningInfo.getId(),r=o!==n;o&&n&&!r?await this.checkOwnCrossSigningTrust():(this._storeTrustedSelfKeys(null),this.emit("crossSigning.keysChanged",{}),this.emit("userTrustStatusChanged",this._userId,this.checkUserTrust(e)))}else{await this._checkDeviceVerifications(e);const t=this._deviceList.getStoredCrossSigningForUser(e);t&&(t.updateCrossSigningVerifiedBefore(this.checkUserTrust(e).isCrossSigningVerified()),this._deviceList.setRawStoredCrossSigningForUser(e,t.toStorage())),this.emit("userTrustStatusChanged",e,this.checkUserTrust(e))}},B.prototype.checkOwnCrossSigningTrust=async function({allowPrivateKeyRequests:e=!1}={}){const t=this._userId;await this.downloadKeys([this._userId]);const n=await this._crossSigningInfo.getCrossSigningKeysFromCache(),o=this._deviceList.getStoredCrossSigningForUser(t);if(!o)return void u.logger.error("Got cross-signing update event for user "+t+" but no new cross-signing information found!");const r=o.getId(),i=this._crossSigningInfo.getId()!==r,a=o.getId()&&!n.has("master");if(i&&u.logger.info("Got new master public key",r),e&&(i||a)){u.logger.info("Attempting to retrieve cross-signing master private key");let e=null;try{e=(await this._crossSigningInfo.getCrossSigningKey("master",r))[1],u.logger.info("Got cross-signing master private key")}finally{e&&e.free()}}const s=this._crossSigningInfo.getId("self_signing"),c=this._crossSigningInfo.getId("user_signing");this._storeTrustedSelfKeys(o.keys);const l=s!==o.getId("self_signing"),d=c!==o.getId("user_signing"),h=o.getId("self_signing")&&!n.has("self_signing"),p=o.getId("user_signing")&&!n.has("user_signing"),f={};if(l&&u.logger.info("Got new self-signing key",o.getId("self_signing")),e&&(l||h)){u.logger.info("Attempting to retrieve cross-signing self-signing private key");let e=null;try{e=(await this._crossSigningInfo.getCrossSigningKey("self_signing",o.getId("self_signing")))[1],u.logger.info("Got cross-signing self-signing private key")}finally{e&&e.free()}const t=this._deviceList.getStoredDevice(this._userId,this._deviceId),n=await this._crossSigningInfo.signDevice(this._userId,t);f[this._deviceId]=n}if(d&&u.logger.info("Got new user-signing key",o.getId("user_signing")),e&&(d||p)){u.logger.info("Attempting to retrieve cross-signing user-signing private key");let e=null;try{e=(await this._crossSigningInfo.getCrossSigningKey("user_signing",o.getId("user_signing")))[1],u.logger.info("Got cross-signing user-signing private key")}finally{e&&e.free()}}if(i){const e=this._crossSigningInfo.keys.master;await this._signObject(e);const t=e.signatures[this._userId]["ed25519:"+this._deviceId];f[this._crossSigningInfo.getId()]=Object.assign({},e,{signatures:{[this._userId]:{["ed25519:"+this._deviceId]:t}}})}const g=Object.keys(f);if(g.length){const e=({shouldEmit:t})=>(u.logger.info(`Starting background key sig upload for ${g}`),this._baseApis.uploadKeySignatures({[this._userId]:f}).then((n=>{const{failures:o}=n||{};if(u.logger.info(`Finished background key sig upload for ${g}`),Object.keys(o||[]).length>0)throw t&&this._baseApis.emit("crypto.keySignatureUploadFailure",o,"checkOwnCrossSigningTrust",e),new C.KeySignatureUploadError("Key upload failed",{failures:o})})).catch((e=>{u.logger.error(`Error during background key sig upload for ${g}`,e)})));e({shouldEmit:!0})}this.emit("userTrustStatusChanged",t,this.checkUserTrust(t)),i&&(this._baseApis.emit("crossSigning.keysChanged",{}),await this._afterCrossSigningLocalKeyChange()),await this.checkKeyBackup()},B.prototype._storeTrustedSelfKeys=async function(e){e?this._crossSigningInfo.setKeys(e):this._crossSigningInfo.clearKeys(),await this._cryptoStore.doTxn("readwrite",[y.IndexedDBCryptoStore.STORE_ACCOUNT],(e=>{this._cryptoStore.storeCrossSigningKeys(e,this._crossSigningInfo.keys)}))},B.prototype._checkDeviceVerifications=async function(e){const t=this._baseApis._cryptoCallbacks.shouldUpgradeDeviceVerifications;if(t){if(u.logger.info(`Starting device verification upgrade for ${e}`),this._crossSigningInfo.keys.user_signing){const n=this._deviceList.getStoredCrossSigningForUser(e);if(n){const o=await this._checkForDeviceVerificationUpgrade(e,n);o&&(await t({users:{[e]:o}})).includes(e)&&await this._baseApis.setDeviceVerified(e,n.getId())}}u.logger.info(`Finished device verification upgrade for ${e}`)}},B.prototype._checkAndStartKeyBackup=async function(){if(u.logger.log("Checking key backup status..."),this._baseApis.isGuest())return u.logger.log("Skipping key backup check since user is guest"),this._checkedForBackup=!0,null;let e;try{e=await this._baseApis.getKeyBackupVersion()}catch(e){return u.logger.log("Error checking for active key backup",e),404===e.httpStatus&&(this._checkedForBackup=!0),null}this._checkedForBackup=!0;const t=await this.isKeyBackupTrusted(e);return t.usable&&!this.backupInfo?(u.logger.log("Found usable key backup v"+e.version+": enabling key backups"),this._baseApis.enableKeyBackup(e)):!t.usable&&this.backupInfo?(u.logger.log("No usable key backup: disabling key backup"),this._baseApis.disableKeyBackup()):t.usable||this.backupInfo?t.usable&&this.backupInfo&&(e.version!==this.backupInfo.version?(u.logger.log("On backup version "+this.backupInfo.version+" but found version "+e.version+": switching."),this._baseApis.disableKeyBackup(),this._baseApis.enableKeyBackup(e),await this.scheduleAllGroupSessionsForBackup()):u.logger.log("Backup version "+e.version+" still current")):u.logger.log("No usable key backup: not enabling key backup"),{backupInfo:e,trustInfo:t}},B.prototype.setTrustedBackupPubKey=async function(e){this._sessionStore.setLocalTrustedBackupPubKey(e),await this.checkKeyBackup()},B.prototype.checkKeyBackup=async function(){return this._checkedForBackup=!1,this._checkAndStartKeyBackup()},B.prototype.isKeyBackupTrusted=async function(e){const t={usable:!1,trusted_locally:!1,sigs:[]};if(!(e&&e.algorithm&&e.auth_data&&e.auth_data.public_key&&e.auth_data.signatures))return u.logger.info("Key backup is absent or missing required data"),t;const n=this._sessionStore.getLocalTrustedBackupPubKey();e.auth_data.public_key===n&&(u.logger.info("Backup public key "+n+" is trusted locally"),t.trusted_locally=!0);const o=e.auth_data.signatures[this._userId]||[];for(const n of Object.keys(o)){const o=n.split(":");if("ed25519"!==o[0]){u.logger.log("Ignoring unknown signature type: "+o[0]);continue}const r={deviceId:o[1]},i=this._crossSigningInfo.getId();if(i===r.deviceId){r.crossSigningId=!0;try{await d.verifySignature(this._olmDevice,e.auth_data,this._userId,r.deviceId,i),r.valid=!0}catch(e){u.logger.warning("Bad signature from cross signing key "+i,e),r.valid=!1}t.sigs.push(r);continue}const a=this._deviceList.getStoredDevice(this._userId,r.deviceId);if(a){r.device=a,r.deviceTrust=await this.checkDeviceTrust(this._userId,r.deviceId);try{await d.verifySignature(this._olmDevice,e.auth_data,this._userId,a.deviceId,a.getFingerprint()),r.valid=!0}catch(t){u.logger.info("Bad signature from key ID "+n+" userID "+this._userId+" device ID "+a.deviceId+" fingerprint: "+a.getFingerprint(),e.auth_data,t),r.valid=!1}}else r.valid=null,u.logger.info("Ignoring signature from unknown key "+n);t.sigs.push(r)}return t.usable=t.sigs.some((e=>e.valid&&(e.device&&e.deviceTrust.isVerified()||e.crossSigningId))),t.usable|=t.trusted_locally,t},B.prototype.enableLazyLoading=function(){this._lazyLoadMembers=!0},B.prototype.registerEventHandlers=function(e){const t=this;e.on("RoomMember.membership",(function(e,n,o){try{t._onRoomMembership(e,n,o)}catch(e){u.logger.error("Error handling membership change:",e)}})),e.on("toDeviceEvent",t._onToDeviceEvent.bind(t));const n=t._onTimelineEvent.bind(t);e.on("Room.timeline",n),e.on("Event.decrypted",n)},B.prototype.start=function(){this._outgoingRoomKeyRequestManager.start()},B.prototype.stop=function(){this._outgoingRoomKeyRequestManager.stop(),this._deviceList.stop(),this._dehydrationManager.stop()},B.getOlmVersion=function(){return l.OlmDevice.getOlmVersion()},B.prototype.getDeviceEd25519Key=function(){return this._olmDevice.deviceEd25519Key},B.prototype.getDeviceCurve25519Key=function(){return this._olmDevice.deviceCurve25519Key},B.prototype.setGlobalBlacklistUnverifiedDevices=function(e){this._globalBlacklistUnverifiedDevices=e},B.prototype.getGlobalBlacklistUnverifiedDevices=function(){return this._globalBlacklistUnverifiedDevices},B.prototype.setGlobalErrorOnUnknownDevices=function(e){this._globalErrorOnUnknownDevices=e},B.prototype.getGlobalErrorOnUnknownDevices=function(){return this._globalErrorOnUnknownDevices},B.prototype.uploadDeviceKeys=function(){const e=this,t=e._userId,n=e._deviceId,o={algorithms:e._supportedAlgorithms,device_id:n,keys:e._deviceKeys,user_id:t};return e._signObject(o).then((()=>e._baseApis.uploadKeysRequest({device_keys:o})))},B.prototype.updateOneTimeKeyCount=function(e){if(!isFinite(e))throw new TypeError("Parameter for updateOneTimeKeyCount has to be a number");this._oneTimeKeyCount=e},B.prototype.setNeedsNewFallback=function(e){this._needsNewFallback=!!e},B.prototype.getNeedsNewFallback=function(){return this._needsNewFallback},B.prototype.downloadKeys=function(e,t){return this._deviceList.downloadKeys(e,t)},B.prototype.getStoredDevicesForUser=function(e){return this._deviceList.getStoredDevicesForUser(e)},B.prototype.getStoredDevice=function(e,t){return this._deviceList.getStoredDevice(e,t)},B.prototype.saveDeviceList=function(e){return this._deviceList.saveIfDirty(e)},B.prototype.setDeviceVerification=async function(e,t,n,o,r){void 0===n&&(n=null),void 0===o&&(o=null),void 0===r&&(r=null);const i=this._deviceList.getStoredCrossSigningForUser(e);if(i&&i.getId()===t){if(null!==o||null!==r)throw new Error("Cannot set blocked or known for a cross-signing key");if(!n)throw new Error("Cannot set a cross-signing key as unverified");if(this._crossSigningInfo.getId()||e!==this._crossSigningInfo.userId||(this._storeTrustedSelfKeys(i.keys),this.emit("userTrustStatusChanged",this._userId,this.checkUserTrust(e))),e!==this._userId){u.logger.info("Master key "+i.getId()+" for "+e+" marked verified. Signing...");const n=await this._crossSigningInfo.signUser(i);if(n){const o=async({shouldEmit:r})=>{u.logger.info("Uploading signature for "+e+"...");const i=await this._baseApis.uploadKeySignatures({[e]:{[t]:n}}),{failures:a}=i||{};if(Object.keys(a||[]).length>0)throw r&&this._baseApis.emit("crypto.keySignatureUploadFailure",a,"setDeviceVerification",o),new C.KeySignatureUploadError("Key upload failed",{failures:a})};await o({shouldEmit:!0})}return n}return i}const a=this._deviceList.getRawStoredDevicesForUser(e);if(!a||!a[t])throw new Error("Unknown device "+e+":"+t);const s=a[t];let c=s.verified;n?c=I.VERIFIED:null!==n&&c==I.VERIFIED&&(c=I.UNVERIFIED),o?c=I.BLOCKED:null!==o&&c==I.BLOCKED&&(c=I.UNVERIFIED);let l=s.known;if(null!==r&&(l=r),s.verified===c&&s.known===l||(s.verified=c,s.known=l,this._deviceList.storeDevicesForUser(e,a),this._deviceList.saveIfDirty()),n&&e===this._userId){let n;if(u.logger.info("Own device "+t+" marked verified: signing"),this.checkDeviceTrust(e,t).isCrossSigningVerified()?u.logger.log(`Own device ${t} already cross-signing verified`):n=await this._crossSigningInfo.signDevice(e,p.DeviceInfo.fromStorage(s,t)),n){const o=async({shouldEmit:r})=>{u.logger.info("Uploading signature for "+t);const i=await this._baseApis.uploadKeySignatures({[e]:{[t]:n}}),{failures:a}=i||{};if(Object.keys(a||[]).length>0)throw r&&this._baseApis.emit("crypto.keySignatureUploadFailure",a,"setDeviceVerification",o),new C.KeySignatureUploadError("Key upload failed",{failures:a})};await o({shouldEmit:!0})}}const d=p.DeviceInfo.fromStorage(s,t);return this.emit("deviceVerificationChanged",e,t,d),d},B.prototype.findVerificationRequestDMInProgress=function(e){return this._inRoomVerificationRequests.findRequestInProgress(e)},B.prototype.getVerificationRequestsToDeviceInProgress=function(e){return this._toDeviceVerificationRequests.getRequestsInProgress(e)},B.prototype.requestVerificationDM=function(e,t){const n=this._inRoomVerificationRequests.findRequestInProgress(t);if(n)return Promise.resolve(n);const o=new D.InRoomChannel(this._baseApis,t,e);return this._requestVerificationWithChannel(e,o,this._inRoomVerificationRequests)},B.prototype.requestVerification=function(e,t){t||(t=Object.keys(this._deviceList.getRawStoredDevicesForUser(e)));const n=this._toDeviceVerificationRequests.findRequestInProgress(e,t);if(n)return Promise.resolve(n);const o=new S.ToDeviceChannel(this._baseApis,e,t,S.ToDeviceChannel.makeTransactionId());return this._requestVerificationWithChannel(e,o,this._toDeviceVerificationRequests)},B.prototype._requestVerificationWithChannel=async function(e,t,n){let o=new k.VerificationRequest(t,this._verificationMethods,this._baseApis);t.transactionId&&n.setRequestByChannel(t,o),await o.sendRequest();const r=n.getRequestByChannel(t);return r?o=r:(u.logger.log(`Crypto: adding new request to requestsByTxnId with id ${t.transactionId} ${t.roomId}`),n.setRequestByChannel(t,o)),o},B.prototype.beginKeyVerification=function(e,t,n,o=null){let r;if(o){if(r=this._toDeviceVerificationRequests.getRequestBySenderAndTxnId(t,o),!r)throw new Error(`No request found for user ${t} with transactionId ${o}`)}else{o=S.ToDeviceChannel.makeTransactionId();const e=new S.ToDeviceChannel(this._baseApis,t,[n],o,n);r=new k.VerificationRequest(e,this._verificationMethods,this._baseApis),this._toDeviceVerificationRequests.setRequestBySenderAndTxnId(t,o,r)}return r.beginKeyVerification(e,{userId:t,deviceId:n})},B.prototype.legacyDeviceVerification=async function(e,t,n){const o=S.ToDeviceChannel.makeTransactionId(),r=new S.ToDeviceChannel(this._baseApis,e,[t],o,t),i=new k.VerificationRequest(r,this._verificationMethods,this._baseApis);this._toDeviceVerificationRequests.setRequestBySenderAndTxnId(e,o,i);const a=i.beginKeyVerification(n,{userId:e,deviceId:t});return await Promise.race([a.verify(),i.waitFor((e=>e.started))]),i},B.prototype.getOlmSessionsForUser=async function(e){const t=this.getStoredDevicesForUser(e)||[],n={};for(let e=0;e0)return null;if(e.isKeySourceUntrusted())return null;const o=this._deviceList.getDeviceByIdentityKey(n,t);if(null===o)return null;const r=e.getClaimedEd25519Key();return r?r!==o.getFingerprint()?(u.logger.warn("Event "+e.getId()+" claims ed25519 key "+r+" but sender device has key "+o.getFingerprint()),null):o:(u.logger.warn("Event "+e.getId()+" claims no ed25519 key: cannot verify sending device"),null)},B.prototype.getEventEncryptionInfo=function(e){const t={};if(t.senderKey=e.getSenderKey(),t.algorithm=e.getWireContent().algorithm,!t.senderKey||!t.algorithm)return t.encrypted=!1,t;t.encrypted=!0,e.getForwardingCurve25519KeyChain().length>0||e.isKeySourceUntrusted()?t.authenticated=!1:t.authenticated=!0,t.sender=this._deviceList.getDeviceByIdentityKey(t.algorithm,t.senderKey);const n=e.getClaimedEd25519Key();return n||(u.logger.warn("Event "+e.getId()+" claims no ed25519 key: cannot verify sending device"),t.mismatchedSender=!0),t.sender&&n!==t.sender.getFingerprint()&&(u.logger.warn("Event "+e.getId()+" claims ed25519 key "+n+"but sender device has key "+t.sender.getFingerprint()),t.mismatchedSender=!0),t},B.prototype.forceDiscardSession=function(e){const t=this._roomEncryptors[e];if(void 0===t)throw new Error("Room not encrypted");if(void 0===t.forceDiscardSession)throw new Error("Room encryption algorithm doesn't support session discarding");t.forceDiscardSession()},B.prototype.setRoomEncryption=async function(e,t,n){if(!t.algorithm)return void u.logger.log("Ignoring setRoomEncryption with no algorithm");const o=this._roomList.getRoomEncryption(e);if(o&&JSON.stringify(o)!=JSON.stringify(t))return void u.logger.error("Ignoring m.room.encryption event which requests a change of config in "+e);if(this._roomEncryptors[e])return;let r=null;o||(r=this._roomList.setRoomEncryption(e,t));const i=f.ENCRYPTION_CLASSES[t.algorithm];if(!i)throw new Error("Unable to encrypt with "+t.algorithm);const a=new i({userId:this._userId,deviceId:this._deviceId,crypto:this,olmDevice:this._olmDevice,baseApis:this._baseApis,roomId:e,config:t});this._roomEncryptors[e]=a,r&&await r,this._lazyLoadMembers?u.logger.log("Enabling encryption in "+e):(u.logger.log("Enabling encryption in "+e+"; starting to track device lists for all users therein"),await this.trackRoomDevices(e),this.inhibitDeviceQuery||this._deviceList.refreshOutdatedDeviceLists())},B.prototype.trackRoomDevices=function(e){let t=this._roomDeviceTrackingState[e];return t||(t=(async()=>{if(!this._roomEncryptors[e])return;const t=this._clientStore.getRoom(e);if(!t)throw new Error(`Unable to start tracking devices in unknown room ${e}`);u.logger.log(`Starting to track devices for room ${e} ...`),(await t.getEncryptionTargetMembers()).forEach((e=>{this._deviceList.startTrackingDeviceList(e.userId)}))})(),this._roomDeviceTrackingState[e]=t.catch((t=>{throw this._roomDeviceTrackingState[e]=null,t}))),t},B.prototype.ensureOlmSessionsForUsers=function(e){const t={};for(let n=0;n{this._cryptoStore.getAllEndToEndInboundGroupSessions(t,(t=>{if(null===t)return;const n=this._olmDevice.exportInboundGroupSession(t.senderKey,t.sessionId,t.sessionData);delete n.first_known_index,n.algorithm=d.MEGOLM_ALGORITHM,e.push(n)}))})),e},B.prototype.importRoomKeys=function(e,t={}){let n=0,o=0;const r=e.length;function i(){t.progressCallback({stage:"load_keys",successes:n,failures:o,total:r})}return Promise.all(e.map((e=>e.room_id&&e.algorithm?this._getRoomDecryptor(e.room_id,e.algorithm).importRoomKey(e,t).finally((e=>{n++,t.progressCallback&&i()})):(u.logger.warn("ignoring room key entry with missing fields",e),o++,t.progressCallback&&i(),null))))},B.prototype.scheduleKeyBackupSend=async function(e=1e4){if(!this._sendingBackups){this._sendingBackups=!0;try{const t=Math.random()*e;await(0,c.sleep)(t);let n=0;for(;;){if(!this.backupKey)return;try{if(0===await this._backupPendingKeys(200))return;n=0}catch(e){if(n++,u.logger.log("Key backup request failed",e),e.data&&("M_NOT_FOUND"==e.data.errcode||"M_WRONG_ROOM_KEYS_VERSION"==e.data.errcode))throw await this.checkKeyBackup(),this.emit("crypto.keyBackupFailed",e.data.errcode),e}n&&await(0,c.sleep)(1e3*Math.pow(2,Math.min(n-1,4)))}}finally{this._sendingBackups=!1}}},B.prototype._backupPendingKeys=async function(e){const t=await this._cryptoStore.getSessionsNeedingBackup(e);if(!t.length)return 0;let n=await this._cryptoStore.countSessionsNeedingBackup();this.emit("crypto.keyBackupSessionsRemaining",n);const o={};for(const e of t){const t=e.sessionData.room_id;void 0===o[t]&&(o[t]={sessions:{}});const n=await this._olmDevice.exportInboundGroupSession(e.senderKey,e.sessionId,e.sessionData);n.algorithm=d.MEGOLM_ALGORITHM,delete n.session_id,delete n.room_id;const r=n.first_known_index;delete n.first_known_index;const i=this.backupKey.encrypt(JSON.stringify(n)),a=(n.forwarding_curve25519_key_chain||[]).length,s=this._deviceList.getUserByIdentityKey(d.MEGOLM_ALGORITHM,e.senderKey),u=this._deviceList.getDeviceByIdentityKey(d.MEGOLM_ALGORITHM,e.senderKey),c=this._checkDeviceInfoTrust(s,u).isVerified();o[t].sessions[e.sessionId]={first_message_index:r,forwarded_count:a,is_verified:c,session_data:i}}return await this._baseApis.sendKeyBackup(void 0,void 0,this.backupInfo.version,{rooms:o}),await this._cryptoStore.unmarkSessionsNeedingBackup(t),n=await this._cryptoStore.countSessionsNeedingBackup(),this.emit("crypto.keyBackupSessionsRemaining",n),t.length},B.prototype.backupGroupSession=async function(e,t,n,o,r,i,a){await this._cryptoStore.markSessionsNeedingBackup([{senderKey:t,sessionId:o}]),this.backupInfo&&this.scheduleKeyBackupSend()},B.prototype.scheduleAllGroupSessionsForBackup=async function(){await this.flagAllGroupSessionsForBackup(),this.scheduleKeyBackupSend(0)},B.prototype.flagAllGroupSessionsForBackup=async function(){await this._cryptoStore.doTxn("readwrite",[y.IndexedDBCryptoStore.STORE_INBOUND_GROUP_SESSIONS,y.IndexedDBCryptoStore.STORE_BACKUP],(e=>{this._cryptoStore.getAllEndToEndInboundGroupSessions(e,(t=>{null!==t&&this._cryptoStore.markSessionsNeedingBackup([t],e)}))}));const e=await this._cryptoStore.countSessionsNeedingBackup();return this.emit("crypto.keyBackupSessionsRemaining",e),e},B.prototype.countSessionsNeedingBackup=function(){return this._cryptoStore.countSessionsNeedingBackup()},B.prototype.prepareToEncrypt=function(e){const t=e.roomId,n=this._roomEncryptors[t];n&&n.prepareToEncrypt(e)},B.prototype.encryptEvent=async function(e,t){if(!t)throw new Error("Cannot send encrypted messages in unknown rooms");const n=e.getRoomId(),o=this._roomEncryptors[n];if(!o)throw new Error("Room was previously configured to use encryption, but is no longer. Perhaps the homeserver is hiding the configuration event.");this._roomDeviceTrackingState[n]||this.trackRoomDevices(n),await this._roomDeviceTrackingState[n];let r=e.getContent();const i=r["m.relates_to"];i&&(r=Object.assign({},r),delete r["m.relates_to"]);const a=await o.encryptMessage(t,e.getType(),r);i&&(a["m.relates_to"]=i),e.makeEncrypted("m.room.encrypted",a,this._olmDevice.deviceCurve25519Key,this._olmDevice.deviceEd25519Key)},B.prototype.decryptEvent=async function(e){if(e.isRedacted()){const t=new R.MatrixEvent(e.getUnsigned().redacted_because),n=await this.decryptEvent(t);return{clearEvent:{room_id:e.getRoomId(),type:"m.room.message",content:{},unsigned:{redacted_because:n.clearEvent}}}}{const t=e.getWireContent(),n=this._getRoomDecryptor(e.getRoomId(),t.algorithm);return await n.decryptEvent(e)}},B.prototype.handleDeviceListChanges=async function(e,t){e.oldSyncToken&&await this._evalDeviceListChanges(t)},B.prototype.requestRoomKey=function(e,t,n=!1){return this._outgoingRoomKeyRequestManager.queueRoomKeyRequest(e,t,n).then((()=>{this._sendKeyRequestsImmediately&&this._outgoingRoomKeyRequestManager.sendQueuedRequests()})).catch((e=>{u.logger.error("Error requesting key for event",e)}))},B.prototype.cancelRoomKeyRequest=function(e){this._outgoingRoomKeyRequestManager.cancelRoomKeyRequest(e).catch((e=>{u.logger.warn("Error clearing pending room key requests",e)}))},B.prototype.cancelAndResendAllOutgoingKeyRequests=function(){return this._outgoingRoomKeyRequestManager.cancelAndResendAllOutgoingRequests()},B.prototype.onCryptoEvent=async function(e){const t=e.getRoomId(),n=e.getContent();try{await this.setRoomEncryption(t,n,!0)}catch(e){u.logger.error("Error configuring encryption in room "+t+":",e)}},B.prototype.onSyncWillProcess=async function(e){e.oldSyncToken||(u.logger.log("Initial sync performed - resetting device tracking state"),this._deviceList.stopTrackingAllDeviceLists(),this._deviceList.startTrackingDeviceList(this._userId),this._roomDeviceTrackingState={}),this._sendKeyRequestsImmediately=!1},B.prototype.onSyncCompleted=async function(e){const t=e.nextSyncToken;this._deviceList.setSyncToken(e.nextSyncToken),this._deviceList.saveIfDirty(),this._deviceList.lastKnownSyncToken=t,this._deviceList.startTrackingDeviceList(this._userId),this._deviceList.refreshOutdatedDeviceLists(),e.catchingUp||(function(e){if(e._oneTimeKeyCheckInProgress)return;const t=Date.now();if(null!==e._lastOneTimeKeyCheck&&t-e._lastOneTimeKeyCheck<6e4)return;e._lastOneTimeKeyCheck=t;const n=e._olmDevice.maxNumberOfOneTimeKeys(),o=Math.floor(n/2);e._oneTimeKeyCheckInProgress=!0,Promise.resolve().then((()=>void 0!==e._oneTimeKeyCount?Promise.resolve(e._oneTimeKeyCount):e._baseApis.uploadKeysRequest({}).then((e=>e.one_time_key_counts.signed_curve25519||0)))).then((t=>async function(t){for(;o>t||e.getNeedsNewFallback();){if(o>t){u.logger.info("generating oneTimeKeys");const n=Math.min(o-t,5);await e._olmDevice.generateOneTimeKeys(n)}e.getNeedsNewFallback()&&(u.logger.info("generating fallback key"),await e._olmDevice.generateFallbackKey()),u.logger.info("calling _uploadOneTimeKeys");const n=await L(e);if(!n.one_time_key_counts||!n.one_time_key_counts.signed_curve25519)throw new Error("response for uploading keys does not contain one_time_key_counts.signed_curve25519");t=n.one_time_key_counts.signed_curve25519}}(t))).catch((e=>{u.logger.error("Error uploading one-time keys",e.stack||e)})).finally((()=>{e._oneTimeKeyCount=void 0,e._oneTimeKeyCheckInProgress=!1}))}(this),this._processReceivedRoomKeyRequests(),this._outgoingRoomKeyRequestManager.sendQueuedRequests(),this._sendKeyRequestsImmediately=!0)},B.prototype._evalDeviceListChanges=async function(e){if(e.changed&&Array.isArray(e.changed)&&e.changed.forEach((e=>{this._deviceList.invalidateUserDeviceList(e)})),e.left&&Array.isArray(e.left)&&e.left.length){const t=new Set(await this._getTrackedE2eUsers());e.left.forEach((e=>{t.has(e)||this._deviceList.stopTrackingDeviceList(e)}))}},B.prototype._getTrackedE2eUsers=async function(){const e=[];for(const t of this._getTrackedE2eRooms()){const n=await t.getEncryptionTargetMembers();for(const t of n)e.push(t.userId)}return e},B.prototype._getTrackedE2eRooms=function(){return this._clientStore.getRooms().filter((e=>{if(!this._roomEncryptors[e.roomId])return!1;if(!this._roomDeviceTrackingState[e.roomId])return!1;const t=e.getMyMembership();return"join"===t||"invite"===t}))},B.prototype._onToDeviceEvent=function(e){try{u.logger.log(`received to_device ${e.getType()} from: ${e.getSender()} id: ${e.getId()}`),"m.room_key"==e.getType()||"m.forwarded_room_key"==e.getType()?this._onRoomKeyEvent(e):"m.room_key_request"==e.getType()?this._onRoomKeyRequestEvent(e):"m.secret.request"===e.getType()?this._secretStorage._onRequestReceived(e):"m.secret.send"===e.getType()?this._secretStorage._onSecretReceived(e):"org.matrix.room_key.withheld"===e.getType()?this._onRoomKeyWithheldEvent(e):e.getContent().transaction_id?this._onKeyVerificationMessage(e):"m.bad.encrypted"===e.getContent().msgtype?this._onToDeviceBadEncrypted(e):(e.isBeingDecrypted()||e.shouldAttemptDecryption())&&(e.isBeingDecrypted()||e.attemptDecryption(this),e.once("Event.decrypted",(e=>{this._onToDeviceEvent(e)})))}catch(e){u.logger.error("Error handling toDeviceEvent:",e)}},B.prototype._onRoomKeyEvent=function(e){const t=e.getContent();t.room_id&&t.algorithm?(this._checkedForBackup||this._checkAndStartKeyBackup(),this._getRoomDecryptor(t.room_id,t.algorithm).onRoomKeyEvent(e)):u.logger.error("key event is missing fields")},B.prototype._onRoomKeyWithheldEvent=function(e){const t=e.getContent();if(!(("m.no_olm"===t.code||t.room_id&&t.session_id)&&t.algorithm&&t.sender_key))return void u.logger.error("key withheld event is missing fields");u.logger.info(`Got room key withheld event from ${e.getSender()} (${t.sender_key}) for ${t.algorithm}/${t.room_id}/${t.session_id} with reason ${t.code} (${t.reason})`);const n=this._getRoomDecryptor(t.room_id,t.algorithm);if(n.onRoomKeyWithheldEvent&&n.onRoomKeyWithheldEvent(e),!t.room_id){const e=this._getRoomDecryptors(t.algorithm);for(const n of e)n.retryDecryptionFromSender(t.sender_key)}},B.prototype._onKeyVerificationMessage=function(e){S.ToDeviceChannel.validateEvent(e,this._baseApis)&&this._handleVerificationEvent(e,this._toDeviceVerificationRequests,(e=>{if(!S.ToDeviceChannel.canCreateRequest(S.ToDeviceChannel.getEventType(e)))return;const t=e.getContent(),n=t&&t.from_device;if(!n)return;const o=e.getSender(),r=new S.ToDeviceChannel(this._baseApis,o,[n]);return new k.VerificationRequest(r,this._verificationMethods,this._baseApis)}))},B.prototype._onTimelineEvent=function(e,t,n,o,{liveEvent:r}={}){D.InRoomChannel.validateEvent(e,this._baseApis)&&this._handleVerificationEvent(e,this._inRoomVerificationRequests,(e=>{const t=new D.InRoomChannel(this._baseApis,e.getRoomId());return new k.VerificationRequest(t,this._verificationMethods,this._baseApis)}),r)},B.prototype._handleVerificationEvent=async function(e,t,n,o=!0){let r=t.getRequest(e),i=!1;if(!r){if(r=n(e),!r)return void u.logger.log(`Crypto: could not find VerificationRequest for ${e.getType()}, and could not create one, so ignoring.`);i=!0,t.setRequest(e,r)}e.setVerificationRequest(r);try{await r.channel.handleEvent(e,r,o)}catch(e){u.logger.error("error while handling verification event: "+e.message)}i&&!r.initiatedByMe&&!r.invalid&&!r.observeOnly&&this._baseApis.emit("crypto.verification.request",r)},B.prototype._onToDeviceBadEncrypted=async function(e){const t=e.getWireContent(),n=e.getSender(),o=t.algorithm,r=t.sender_key,i=()=>{const e=this._getRoomDecryptors(d.MEGOLM_ALGORITHM);for(const t of e)t.retryDecryptionFromSender(r)};if(void 0===n||void 0===r||void 0===r)return;this._lastNewSessionForced[n]=this._lastNewSessionForced[n]||{};const a=this._lastNewSessionForced[n][r]||0;if(a+36e5>Date.now())return u.logger.debug("New session already forced with device "+n+":"+r+" at "+a+": not forcing another"),await this._olmDevice.recordSessionProblem(r,"wedged",!0),void i();let s=this._deviceList.getDeviceByIdentityKey(o,r);if(!s&&(await this.downloadKeys([n],!1),s=this._deviceList.getDeviceByIdentityKey(o,r),!s))return u.logger.info("Couldn't find device for identity key "+r+": not re-establishing session"),await this._olmDevice.recordSessionProblem(r,"wedged",!1),void i();const c={};c[n]=[s],await d.ensureOlmSessionsForDevices(this._olmDevice,this._baseApis,c,!0),this._lastNewSessionForced[n][r]=Date.now();const l={algorithm:d.OLM_ALGORITHM,sender_key:this._olmDevice.deviceCurve25519Key,ciphertext:{}};await d.encryptMessageForDevice(l.ciphertext,this._userId,this._deviceId,this._olmDevice,n,s,{type:"m.dummy"}),await this._olmDevice.recordSessionProblem(r,"wedged",!0),i(),await this._baseApis.sendToDevice("m.room.encrypted",{[n]:{[s.deviceId]:l}});const h=await this._outgoingRoomKeyRequestManager.getOutgoingSentRoomKeyRequest(n,s.deviceId);for(const e of h)this.requestRoomKey(e.requestBody,e.recipients,!0)},B.prototype._onRoomMembership=function(e,t,n){const o=t.roomId,r=this._roomEncryptors[o];r&&(this._roomDeviceTrackingState[o]&&("join"==t.membership?(u.logger.log("Join event for "+t.userId+" in "+o),this._deviceList.startTrackingDeviceList(t.userId)):"invite"==t.membership&&this._clientStore.getRoom(o).shouldEncryptForInvitedMembers()&&(u.logger.log("Invite event for "+t.userId+" in "+o),this._deviceList.startTrackingDeviceList(t.userId))),r.onRoomMembership(e,t,n))},B.prototype._onRoomKeyRequestEvent=function(e){const t=e.getContent();if("request"===t.action){const t=new P(e);this._receivedRoomKeyRequests.push(t)}else if("request_cancellation"===t.action){const t=new U(e);this._receivedRoomKeyRequestCancellations.push(t)}},B.prototype._processReceivedRoomKeyRequests=async function(){if(!this._processingRoomKeyRequests){this._processingRoomKeyRequests=!0;try{const e=this._receivedRoomKeyRequests;this._receivedRoomKeyRequests=[];const t=this._receivedRoomKeyRequestCancellations;this._receivedRoomKeyRequestCancellations=[],await Promise.all(e.map((e=>this._processReceivedRoomKeyRequest(e)))),await Promise.all(t.map((e=>this._processReceivedRoomKeyRequestCancellation(e))))}catch(e){u.logger.error(`Error processing room key requsts: ${e}`)}finally{this._processingRoomKeyRequests=!1}}},B.prototype._processReceivedRoomKeyRequest=async function(e){const t=e.userId,n=e.deviceId,o=e.requestBody,r=o.room_id,i=o.algorithm;if(u.logger.log(`m.room_key_request from ${t}:${n} for ${r} / ${o.session_id} (id ${e.requestId})`),t!==this._userId){if(!this._roomEncryptors[r])return void u.logger.debug(`room key request for unencrypted room ${r}`);const e=this._roomEncryptors[r],i=this._deviceList.getStoredDevice(t,n);if(!i)return void u.logger.debug(`Ignoring keyshare for unknown device ${t}:${n}`);try{await e.reshareKeyWithDevice(o.sender_key,o.session_id,t,i)}catch(e){u.logger.warn("Failed to re-share keys for session "+o.session_id+" with device "+t+":"+i.deviceId,e)}return}if(n===this._deviceId)return void u.logger.log("Ignoring room key request from ourselves");if(!this._roomDecryptors[r])return void u.logger.log(`room key request for unencrypted room ${r}`);const a=this._roomDecryptors[r][i];if(a)if(await a.hasKeysForKeyRequest(e)){if(e.share=()=>{a.shareKeysWithDevice(e)},this.checkDeviceTrust(t,n).isVerified())return u.logger.log("device is already verified: sharing keys"),void e.share();this.emit("crypto.roomKeyRequest",e)}else u.logger.log(`room key request for unknown session ${r} / `+o.session_id);else u.logger.log(`room key request for unknown alg ${i} in room ${r}`)},B.prototype._processReceivedRoomKeyRequestCancellation=async function(e){u.logger.log(`m.room_key_request cancellation for ${e.userId}:${e.deviceId} (id ${e.requestId})`),this.emit("crypto.roomKeyRequestCancellation",e)},B.prototype._getRoomDecryptor=function(e,t){let n,o;if((e=e||null)&&(n=this._roomDecryptors[e],n||(this._roomDecryptors[e]=n={}),o=n[t],o))return o;const r=f.DECRYPTION_CLASSES[t];if(!r)throw new f.DecryptionError("UNKNOWN_ENCRYPTION_ALGORITHM",'Unknown encryption algorithm "'+t+'".');return o=new r({userId:this._userId,crypto:this,olmDevice:this._olmDevice,baseApis:this._baseApis,roomId:e}),n&&(n[t]=o),o},B.prototype._getRoomDecryptors=function(e){const t=[];for(const n of Object.values(this._roomDecryptors))e in n&&t.push(n[e]);return t},B.prototype._signObject=async function(e){const t=e.signatures||{},n=e.unsigned;delete e.signatures,delete e.unsigned,t[this._userId]=t[this._userId]||{},t[this._userId]["ed25519:"+this._deviceId]=await this._olmDevice.sign(i.default.stringify(e)),e.signatures=t,void 0!==n&&(e.unsigned=n)};class P{constructor(e){const t=e.getContent();this.userId=e.getSender(),this.deviceId=t.requesting_device_id,this.requestId=t.request_id,this.requestBody=t.body||{},this.share=()=>{throw new Error("don't know how to share keys for this request yet")}}}class U{constructor(e){const t=e.getContent();this.userId=e.getSender(),this.deviceId=t.requesting_device_id,this.requestId=t.request_id}}},91597:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.keyFromAuthData=async function(e,t){if(!n.g.Olm)throw new Error("Olm is not available");if(!e.private_key_salt||!e.private_key_iterations)throw new Error("Salt and/or iterations not found: this backup cannot be restored with a passphrase");return await i(t,e.private_key_salt,e.private_key_iterations,e.private_key_bits||256)},t.keyFromPassphrase=async function(e){if(!n.g.Olm)throw new Error("Olm is not available");const t=(0,o.randomString)(32);return{key:await i(e,t,r,256),salt:t,iterations:r}},t.deriveKey=i;var o=n(98401);const r=5e5;async function i(e,t,o,r=256){const i=n.g.crypto.subtle,a=n.g.TextEncoder;if(!i||!a)throw new Error("Password-based backup is not avaiable on this platform");const s=await i.importKey("raw",(new a).encode(e),{name:"PBKDF2"},!1,["deriveBits"]),u=await i.deriveBits({name:"PBKDF2",salt:(new a).encode(t),iterations:o,hash:"SHA-512"},s,r);return new Uint8Array(u)}},32772:(e,t,n)=>{"use strict";var o=n(95318),r=n(20862);Object.defineProperty(t,"__esModule",{value:!0}),t.encryptMessageForDevice=async function(e,t,n,o,r,s,u){const c=s.getIdentityKey(),l=await o.getSessionIdForDevice(c);if(null===l)return;i.logger.log("Using sessionid "+l+" for device "+r+":"+s.deviceId);const d={sender:t,sender_device:n,keys:{ed25519:o.deviceEd25519Key},recipient:r,recipient_keys:{ed25519:s.getFingerprint()}};a.extend(d,u),e[c]=await o.encryptMessage(c,l,JSON.stringify(d))},t.getExistingOlmSessions=async function(e,t,n){const o={},r={},i=[];for(const[t,a]of Object.entries(n))for(const n of a){const a=n.deviceId,s=n.getIdentityKey();i.push((async()=>{const i=await e.getSessionIdForDevice(s,!0);null===i?(o[t]=o[t]||[],o[t].push(n)):(r[t]=r[t]||{},r[t][a]={device:n,sessionId:i})})())}return await Promise.all(i),[o,r]},t.ensureOlmSessionsForDevices=async function(e,t,n,o,r,a,s){"number"==typeof o&&(s=a,a=r,r=o,o=!1),s||(s=i.logger);const c=[],l={},d={};for(const[,t]of Object.entries(n))for(const n of t){const t=n.getIdentityKey();t!==e.deviceCurve25519Key&&(e._sessionsInProgress[t]||(e._sessionsInProgress[t]=new Promise((n=>{d[t]=(...o)=>{delete e._sessionsInProgress[t],n(...o)}}))))}for(const[t,r]of Object.entries(n)){l[t]={};for(const n of r){const r=n.deviceId,i=n.getIdentityKey();if(i===e.deviceCurve25519Key){s.info("Attempted to start session with ourself! Ignoring"),l[t][r]={device:n,sessionId:null};continue}const a=`for ${i} (${t}:${r})`,u=await e.getSessionIdForDevice(i,d[i],s);null!==u&&d[i]&&d[i](),(null===u||o)&&(o?s.info(`Forcing new Olm session ${a}`):s.info(`Making new Olm session ${a}`),c.push([t,r])),l[t][r]={device:n,sessionId:u}}}if(0===c.length)return l;let h,p=`one-time keys for ${c.length} devices`;try{s.debug(`Claiming ${p}`),h=await t.claimOneTimeKeys(c,"signed_curve25519",r),s.debug(`Claimed ${p}`)}catch(e){for(const e of Object.values(d))e();throw s.log(`Failed to claim ${p}`,e,c),e}a&&"failures"in h&&a.push(...Object.keys(h.failures));const f=h.one_time_keys||{},g=[];for(const[t,r]of Object.entries(n)){const n=f[t]||{};for(let i=0;i{d[h]&&d[h](e),l[t][c].sessionId=e}),(e=>{throw d[h]&&d[h](),e}))):(s.warn(`No one-time keys (alg=signed_curve25519) for device ${t}:${c}`),d[h]&&d[h]())}}return p=`Olm sessions for ${g.length} devices`,s.debug(`Starting ${p}`),await Promise.all(g),s.debug(`Started ${p}`),l},t.verifySignature=c,t.pkSign=function(e,t,o,r){let i=!1;if(t instanceof Uint8Array){const e=new n.g.Olm.PkSigning;r=e.init_with_seed(t),t=e,i=!0}const a=e.signatures||{};delete e.signatures;const u=e.unsigned;e.unsigned&&delete e.unsigned;try{const n=a[o]||{};return a[o]=n,n["ed25519:"+r]=t.sign(s.default.stringify(e))}finally{e.signatures=a,u&&(e.unsigned=u),i&&t.free()}},t.pkVerify=function(e,t,o){const r="ed25519:"+t;if(!(e.signatures&&e.signatures[o]&&e.signatures[o][r]))throw new Error("No signature");const i=e.signatures[o][r],a=new n.g.Olm.Utility,u=e.signatures;delete e.signatures;const c=e.unsigned;e.unsigned&&delete e.unsigned;try{a.ed25519_verify(t,s.default.stringify(e),i)}finally{e.signatures=u,c&&(e.unsigned=c),a.free()}},t.encodeBase64=l,t.encodeUnpaddedBase64=function(e){return l(e).replace(/=+$/g,"")},t.decodeBase64=function(e){return Buffer.from(e,"base64")},t.MEGOLM_BACKUP_ALGORITHM=t.MEGOLM_ALGORITHM=t.OLM_ALGORITHM=void 0;var i=n(7434),a=r(n(3102)),s=o(n(69141));async function u(e,t,n,o){const r=o.deviceId;try{await c(e,t,n,r,o.getFingerprint())}catch(e){return i.logger.error("Unable to verify signature on one-time key for device "+n+":"+r+":",e),null}let a;try{a=await e.createOutboundSession(o.getIdentityKey(),t.key)}catch(e){return i.logger.error("Error starting olm session with device "+n+":"+r+": "+e),null}return i.logger.log("Started new olm sessionid "+a+" for device "+n+":"+r),a}async function c(e,t,n,o,r){const i="ed25519:"+o,a=((t.signatures||{})[n]||{})[i];if(!a)throw Error("No signature");const u=Object.assign({},t);delete u.unsigned,delete u.signatures;const c=s.default.stringify(u);e.verifySignature(r,c,a)}function l(e){return Buffer.from(e).toString("base64")}t.OLM_ALGORITHM="m.olm.v1.curve25519-aes-sha2",t.MEGOLM_ALGORITHM="m.megolm.v1.aes-sha2",t.MEGOLM_BACKUP_ALGORITHM="m.megolm_backup.v1.curve25519-aes-sha2"},34077:(e,t,n)=>{"use strict";var o=n(95318);Object.defineProperty(t,"__esModule",{value:!0}),t.encodeRecoveryKey=function(e){const t=new Buffer(i.length+e.length+1);t.set(i,0),t.set(e,i.length);let n=0;for(let e=0;e{"use strict";var o=n(20862);Object.defineProperty(t,"__esModule",{value:!0}),t.upgradeDatabase=function(e,t){r.logger.log(`Upgrading IndexedDBCryptoStore from version ${t} to 10`),t<1&&function(e){const t=e.createObjectStore("outgoingRoomKeyRequests",{keyPath:"requestId"});t.createIndex("session",["requestBody.room_id","requestBody.session_id"]),t.createIndex("state","state")}(e),t<2&&e.createObjectStore("account"),t<3&&e.createObjectStore("sessions",{keyPath:["deviceKey","sessionId"]}).createIndex("deviceKey","deviceKey"),t<4&&e.createObjectStore("inbound_group_sessions",{keyPath:["senderCurve25519Key","sessionId"]}),t<5&&e.createObjectStore("device_data"),t<6&&e.createObjectStore("rooms"),t<7&&e.createObjectStore("sessions_needing_backup",{keyPath:["senderCurve25519Key","sessionId"]}),t<8&&e.createObjectStore("inbound_group_sessions_withheld",{keyPath:["senderCurve25519Key","sessionId"]}),t<9&&(e.createObjectStore("session_problems",{keyPath:["deviceKey","time"]}).createIndex("deviceKey","deviceKey"),e.createObjectStore("notified_error_devices",{keyPath:["userId","deviceId"]})),t<10&&e.createObjectStore("shared_history_inbound_group_sessions",{keyPath:["roomId"]})},t.Backend=t.VERSION=void 0;var r=n(7434),i=o(n(3102));function a(e,t){e._mx_abortexception=t;try{e.abort()}catch(t){}}function s(e){return new Promise(((t,n)=>{e.oncomplete=()=>{void 0!==e._mx_abortexception&&n(e._mx_abortexception),t()},e.onerror=t=>{void 0!==e._mx_abortexception?n(e._mx_abortexception):(r.logger.log("Error performing indexeddb txn",t),n(t.target.error))},e.onabort=t=>{void 0!==e._mx_abortexception?n(e._mx_abortexception):(r.logger.log("Error performing indexeddb txn",t),n(t.target.error))}}))}t.VERSION=10,t.Backend=class{constructor(e){this._db=e,this._nextTxnId=0,e.onversionchange=t=>{r.logger.log(`versionchange for indexeddb ${this._dbName}: closing`),e.close()}}getOrAddOutgoingRoomKeyRequest(e){const t=e.requestBody;return new Promise(((n,o)=>{const i=this._db.transaction("outgoingRoomKeyRequests","readwrite");i.onerror=o,this._getOutgoingRoomKeyRequest(i,t,(o=>{if(o)return r.logger.log(`already have key request outstanding for ${t.room_id} / ${t.session_id}: not sending another`),void n(o);r.logger.log(`enqueueing key request for ${t.room_id} / `+t.session_id),i.oncomplete=()=>{n(e)},i.objectStore("outgoingRoomKeyRequests").add(e)}))}))}getOutgoingRoomKeyRequest(e){return new Promise(((t,n)=>{const o=this._db.transaction("outgoingRoomKeyRequests","readonly");o.onerror=n,this._getOutgoingRoomKeyRequest(o,e,(e=>{t(e)}))}))}_getOutgoingRoomKeyRequest(e,t,n){e.objectStore("outgoingRoomKeyRequests").index("session").openCursor([t.room_id,t.session_id]).onsuccess=e=>{const o=e.target.result;if(!o)return void n(null);const r=o.value;i.deepCompare(r.requestBody,t)?n(r):o.continue()}}getOutgoingRoomKeyRequestByState(e){if(0===e.length)return Promise.resolve(null);let t,n=0;const o=this._db.transaction("outgoingRoomKeyRequests","readonly"),r=o.objectStore("outgoingRoomKeyRequests"),i=e[n];return r.index("state").openCursor(i).onsuccess=function o(r){const i=r.target.result;if(i)return void(t=i.value);if(n++,n>=e.length)return;const a=e[n];r.target.source.openCursor(a).onsuccess=o},s(o).then((()=>t))}getAllOutgoingRoomKeyRequestsByState(e){return new Promise(((t,n)=>{const o=this._db.transaction("outgoingRoomKeyRequests","readonly").objectStore("outgoingRoomKeyRequests").index("state").getAll(e);o.onsuccess=e=>t(e.target.result),o.onerror=e=>n(e.target.error)}))}getOutgoingRoomKeyRequestsByTarget(e,t,n){let o=0;const r=[],i=this._db.transaction("outgoingRoomKeyRequests","readonly"),a=i.objectStore("outgoingRoomKeyRequests"),u=n[o];return a.index("state").openCursor(u).onsuccess=function i(a){const s=a.target.result;if(s){const n=s.value;n.recipients.includes({userId:e,deviceId:t})&&r.push(n),s.continue()}else{if(o++,o>=n.length)return;const e=n[o];a.target.source.openCursor(e).onsuccess=i}},s(i).then((()=>r))}updateOutgoingRoomKeyRequest(e,t,n){let o=null;const i=this._db.transaction("outgoingRoomKeyRequests","readwrite");return i.objectStore("outgoingRoomKeyRequests").openCursor(e).onsuccess=function(e){const i=e.target.result;if(!i)return;const a=i.value;a.state==t?(Object.assign(a,n),i.update(a),o=a):r.logger.warn(`Cannot update room key request from ${t} as it was already updated to ${a.state}`)},s(i).then((()=>o))}deleteOutgoingRoomKeyRequest(e,t){const n=this._db.transaction("outgoingRoomKeyRequests","readwrite");return n.objectStore("outgoingRoomKeyRequests").openCursor(e).onsuccess=e=>{const n=e.target.result;if(!n)return;const o=n.value;o.state==t?n.delete():r.logger.warn(`Cannot delete room key request in state ${o.state} (expected ${t})`)},s(n)}getAccount(e,t){const n=e.objectStore("account").get("-");n.onsuccess=function(){try{t(n.result||null)}catch(t){a(e,t)}}}storeAccount(e,t){e.objectStore("account").put(t,"-")}getCrossSigningKeys(e,t){const n=e.objectStore("account").get("crossSigningKeys");n.onsuccess=function(){try{t(n.result||null)}catch(t){a(e,t)}}}getSecretStorePrivateKey(e,t,n){const o=e.objectStore("account").get(`ssss_cache:${n}`);o.onsuccess=function(){try{t(o.result||null)}catch(t){a(e,t)}}}storeCrossSigningKeys(e,t){e.objectStore("account").put(t,"crossSigningKeys")}storeSecretStorePrivateKey(e,t,n){e.objectStore("account").put(n,`ssss_cache:${t}`)}countEndToEndSessions(e,t){const n=e.objectStore("sessions").count();n.onsuccess=function(){try{t(n.result)}catch(t){a(e,t)}}}getEndToEndSessions(e,t,n){const o=t.objectStore("sessions").index("deviceKey").openCursor(e),r={};o.onsuccess=function(){const e=o.result;if(e)r[e.value.sessionId]={session:e.value.session,lastReceivedMessageTs:e.value.lastReceivedMessageTs},e.continue();else try{n(r)}catch(e){a(t,e)}}}getEndToEndSession(e,t,n,o){const r=n.objectStore("sessions").get([e,t]);r.onsuccess=function(){try{r.result?o({session:r.result.session,lastReceivedMessageTs:r.result.lastReceivedMessageTs}):o(null)}catch(e){a(n,e)}}}getAllEndToEndSessions(e,t){const n=e.objectStore("sessions").openCursor();n.onsuccess=function(){try{const e=n.result;e?(t(e.value),e.continue()):t(null)}catch(t){a(e,t)}}}storeEndToEndSession(e,t,n,o){o.objectStore("sessions").put({deviceKey:e,sessionId:t,session:n.session,lastReceivedMessageTs:n.lastReceivedMessageTs})}async storeEndToEndSessionProblem(e,t,n){const o=this._db.transaction("session_problems","readwrite");return o.objectStore("session_problems").put({deviceKey:e,type:t,fixed:n,time:Date.now()}),s(o)}async getEndToEndSessionProblem(e,t){let n;const o=this._db.transaction("session_problems","readwrite"),r=o.objectStore("session_problems").index("deviceKey").getAll(e);return r.onsuccess=e=>{const o=r.result;if(!o.length)return void(n=null);o.sort(((e,t)=>e.time-t.time));const i=o[o.length-1];for(const e of o)if(e.time>t)return void(n=Object.assign({},e,{fixed:i.fixed}));n=i.fixed?null:i},await s(o),n}async filterOutNotifiedErrorDevices(e){const t=this._db.transaction("notified_error_devices","readwrite").objectStore("notified_error_devices"),n=[];return await Promise.all(e.map((e=>new Promise((o=>{const{userId:r,deviceInfo:i}=e,a=t.get([r,i.deviceId]);a.onsuccess=function(){a.result||(t.put({userId:r,deviceId:i.deviceId}),n.push(e)),o()}}))))),n}getEndToEndInboundGroupSession(e,t,n,o){let r=!1,i=!1;const s=n.objectStore("inbound_group_sessions").get([e,t]);s.onsuccess=function(){try{r=s.result?s.result.session:null,!1!==i&&o(r,i)}catch(e){a(n,e)}};const u=n.objectStore("inbound_group_sessions_withheld").get([e,t]);u.onsuccess=function(){try{i=u.result?u.result.session:null,!1!==r&&o(r,i)}catch(e){a(n,e)}}}getAllEndToEndInboundGroupSessions(e,t){const n=e.objectStore("inbound_group_sessions").openCursor();n.onsuccess=function(){const o=n.result;if(o){try{t({senderKey:o.value.senderCurve25519Key,sessionId:o.value.sessionId,sessionData:o.value.session})}catch(t){a(e,t)}o.continue()}else try{t(null)}catch(t){a(e,t)}}}addEndToEndInboundGroupSession(e,t,n,o){const i=o.objectStore("inbound_group_sessions").add({senderCurve25519Key:e,sessionId:t,session:n});i.onerror=n=>{"ConstraintError"===i.error.name?(n.stopPropagation(),n.preventDefault(),r.logger.log("Ignoring duplicate inbound group session: "+e+" / "+t)):a(o,new Error("Failed to add inbound group session: "+i.error))}}storeEndToEndInboundGroupSession(e,t,n,o){o.objectStore("inbound_group_sessions").put({senderCurve25519Key:e,sessionId:t,session:n})}storeEndToEndInboundGroupSessionWithheld(e,t,n,o){o.objectStore("inbound_group_sessions_withheld").put({senderCurve25519Key:e,sessionId:t,session:n})}getEndToEndDeviceData(e,t){const n=e.objectStore("device_data").get("-");n.onsuccess=function(){try{t(n.result||null)}catch(t){a(e,t)}}}storeEndToEndDeviceData(e,t){t.objectStore("device_data").put(e,"-")}storeEndToEndRoom(e,t,n){n.objectStore("rooms").put(t,e)}getEndToEndRooms(e,t){const n={},o=e.objectStore("rooms").openCursor();o.onsuccess=function(){const r=o.result;if(r)n[r.key]=r.value,r.continue();else try{t(n)}catch(t){a(e,t)}}}getSessionsNeedingBackup(e){return new Promise(((t,n)=>{const o=[],r=this._db.transaction(["sessions_needing_backup","inbound_group_sessions"],"readonly");r.onerror=n,r.oncomplete=function(){t(o)};const i=r.objectStore("sessions_needing_backup"),a=r.objectStore("inbound_group_sessions"),s=i.openCursor();s.onsuccess=function(){const t=s.result;if(t){const n=a.get(t.key);n.onsuccess=function(){o.push({senderKey:n.result.senderCurve25519Key,sessionId:n.result.sessionId,sessionData:n.result.session})},(!e||o.length{const o=t.count();o.onerror=n,o.onsuccess=()=>e(o.result)}))}unmarkSessionsNeedingBackup(e,t){t||(t=this._db.transaction("sessions_needing_backup","readwrite"));const n=t.objectStore("sessions_needing_backup");return Promise.all(e.map((e=>new Promise(((t,o)=>{const r=n.delete([e.senderKey,e.sessionId]);r.onsuccess=t,r.onerror=o})))))}markSessionsNeedingBackup(e,t){t||(t=this._db.transaction("sessions_needing_backup","readwrite"));const n=t.objectStore("sessions_needing_backup");return Promise.all(e.map((e=>new Promise(((t,o)=>{const r=n.put({senderCurve25519Key:e.senderKey,sessionId:e.sessionId});r.onsuccess=t,r.onerror=o})))))}addSharedHistoryInboundGroupSession(e,t,n,o){o||(o=this._db.transaction("shared_history_inbound_group_sessions","readwrite"));const r=o.objectStore("shared_history_inbound_group_sessions"),i=r.get([e]);i.onsuccess=()=>{const{sessions:o}=i.result||{sessions:[]};o.push([t,n]),r.put({roomId:e,sessions:o})}}getSharedHistoryInboundGroupSessions(e,t){t||(t=this._db.transaction("shared_history_inbound_group_sessions","readonly"));const n=t.objectStore("shared_history_inbound_group_sessions").get([e]);return new Promise(((e,t)=>{n.onsuccess=()=>{const{sessions:t}=n.result||{sessions:[]};e(t)},n.onerror=t}))}doTxn(e,t,n,o=r.logger){const i=this._db.transaction(t,e),a=s(i),u=n(i);return a.then((()=>u))}}},57585:(e,t,n)=>{"use strict";var o=n(20862);Object.defineProperty(t,"__esModule",{value:!0}),t.IndexedDBCryptoStore=void 0;var r=n(7434),i=n(84250),a=n(11045),s=o(n(35251)),u=n(19489),c=o(n(33415));class l{constructor(e,t){this._indexedDB=e,this._dbName=t,this._backendPromise=null,this._backend=null}static exists(e,t){return c.exists(e,t)}startup(){return this._backendPromise||(this._backendPromise=new Promise(((e,t)=>{if(!this._indexedDB)return void t(new Error("no indexeddb support available"));r.logger.log(`connecting to indexeddb ${this._dbName}`);const n=this._indexedDB.open(this._dbName,s.VERSION);n.onupgradeneeded=e=>{const t=e.target.result,n=e.oldVersion;s.upgradeDatabase(t,n)},n.onblocked=()=>{r.logger.log("can't yet open IndexedDBCryptoStore because it is open elsewhere")},n.onerror=e=>{r.logger.log("Error connecting to indexeddb",e),t(e.target.error)},n.onsuccess=t=>{const n=t.target.result;r.logger.log(`connected to indexeddb ${this._dbName}`),e(new s.Backend(n))}})).then((e=>e.doTxn("readonly",[l.STORE_INBOUND_GROUP_SESSIONS,l.STORE_INBOUND_GROUP_SESSIONS_WITHHELD],(t=>{e.getEndToEndInboundGroupSession("","",t,(()=>{}))})).then((()=>e)))).catch((e=>{if("VersionError"===e.name)throw r.logger.warn("Crypto DB is too new for us to use!",e),new u.InvalidCryptoStoreError(u.InvalidCryptoStoreError.TOO_NEW);r.logger.warn(`unable to connect to indexeddb ${this._dbName}: falling back to localStorage store: ${e}`);try{return new i.LocalStorageCryptoStore(n.g.localStorage)}catch(e){return r.logger.warn(`unable to open localStorage: falling back to in-memory store: ${e}`),new a.MemoryCryptoStore}})).then((e=>{this._backend=e}))),this._backendPromise}deleteAllData(){return new Promise(((e,t)=>{if(!this._indexedDB)return void t(new Error("no indexeddb support available"));r.logger.log(`Removing indexeddb instance: ${this._dbName}`);const n=this._indexedDB.deleteDatabase(this._dbName);n.onblocked=()=>{r.logger.log("can't yet delete IndexedDBCryptoStore because it is open elsewhere")},n.onerror=e=>{r.logger.log("Error deleting data from indexeddb",e),t(e.target.error)},n.onsuccess=()=>{r.logger.log(`Removed indexeddb instance: ${this._dbName}`),e()}})).catch((e=>{r.logger.warn(`unable to delete IndexedDBCryptoStore: ${e}`)}))}getOrAddOutgoingRoomKeyRequest(e){return this._backend.getOrAddOutgoingRoomKeyRequest(e)}getOutgoingRoomKeyRequest(e){return this._backend.getOutgoingRoomKeyRequest(e)}getOutgoingRoomKeyRequestByState(e){return this._backend.getOutgoingRoomKeyRequestByState(e)}getAllOutgoingRoomKeyRequestsByState(e){return this._backend.getAllOutgoingRoomKeyRequestsByState(e)}getOutgoingRoomKeyRequestsByTarget(e,t,n){return this._backend.getOutgoingRoomKeyRequestsByTarget(e,t,n)}updateOutgoingRoomKeyRequest(e,t,n){return this._backend.updateOutgoingRoomKeyRequest(e,t,n)}deleteOutgoingRoomKeyRequest(e,t){return this._backend.deleteOutgoingRoomKeyRequest(e,t)}getAccount(e,t){this._backend.getAccount(e,t)}storeAccount(e,t){this._backend.storeAccount(e,t)}getCrossSigningKeys(e,t){this._backend.getCrossSigningKeys(e,t)}getSecretStorePrivateKey(e,t,n){this._backend.getSecretStorePrivateKey(e,t,n)}storeCrossSigningKeys(e,t){this._backend.storeCrossSigningKeys(e,t)}storeSecretStorePrivateKey(e,t,n){this._backend.storeSecretStorePrivateKey(e,t,n)}countEndToEndSessions(e,t){this._backend.countEndToEndSessions(e,t)}getEndToEndSession(e,t,n,o){this._backend.getEndToEndSession(e,t,n,o)}getEndToEndSessions(e,t,n){this._backend.getEndToEndSessions(e,t,n)}getAllEndToEndSessions(e,t){this._backend.getAllEndToEndSessions(e,t)}storeEndToEndSession(e,t,n,o){this._backend.storeEndToEndSession(e,t,n,o)}storeEndToEndSessionProblem(e,t,n){return this._backend.storeEndToEndSessionProblem(e,t,n)}getEndToEndSessionProblem(e,t){return this._backend.getEndToEndSessionProblem(e,t)}filterOutNotifiedErrorDevices(e){return this._backend.filterOutNotifiedErrorDevices(e)}getEndToEndInboundGroupSession(e,t,n,o){this._backend.getEndToEndInboundGroupSession(e,t,n,o)}getAllEndToEndInboundGroupSessions(e,t){this._backend.getAllEndToEndInboundGroupSessions(e,t)}addEndToEndInboundGroupSession(e,t,n,o){this._backend.addEndToEndInboundGroupSession(e,t,n,o)}storeEndToEndInboundGroupSession(e,t,n,o){this._backend.storeEndToEndInboundGroupSession(e,t,n,o)}storeEndToEndInboundGroupSessionWithheld(e,t,n,o){this._backend.storeEndToEndInboundGroupSessionWithheld(e,t,n,o)}storeEndToEndDeviceData(e,t){this._backend.storeEndToEndDeviceData(e,t)}getEndToEndDeviceData(e,t){this._backend.getEndToEndDeviceData(e,t)}storeEndToEndRoom(e,t,n){this._backend.storeEndToEndRoom(e,t,n)}getEndToEndRooms(e,t){this._backend.getEndToEndRooms(e,t)}getSessionsNeedingBackup(e){return this._backend.getSessionsNeedingBackup(e)}countSessionsNeedingBackup(e){return this._backend.countSessionsNeedingBackup(e)}unmarkSessionsNeedingBackup(e,t){return this._backend.unmarkSessionsNeedingBackup(e,t)}markSessionsNeedingBackup(e,t){return this._backend.markSessionsNeedingBackup(e,t)}addSharedHistoryInboundGroupSession(e,t,n,o){this._backend.addSharedHistoryInboundGroupSession(e,t,n,o)}getSharedHistoryInboundGroupSessions(e,t){return this._backend.getSharedHistoryInboundGroupSessions(e,t)}doTxn(e,t,n,o){return this._backend.doTxn(e,t,n,o)}}t.IndexedDBCryptoStore=l,l.STORE_ACCOUNT="account",l.STORE_SESSIONS="sessions",l.STORE_INBOUND_GROUP_SESSIONS="inbound_group_sessions",l.STORE_INBOUND_GROUP_SESSIONS_WITHHELD="inbound_group_sessions_withheld",l.STORE_SHARED_HISTORY_INBOUND_GROUP_SESSIONS="shared_history_inbound_group_sessions",l.STORE_DEVICE_DATA="device_data",l.STORE_ROOMS="rooms",l.STORE_BACKUP="sessions_needing_backup"},84250:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.LocalStorageCryptoStore=void 0;var o=n(7434),r=n(11045);const i="crypto.account",a="crypto.cross_signing_keys",s="crypto.notified_error_devices",u="crypto.device_data",c="crypto.inboundgroupsessions/",l="crypto.sessionsneedingbackup";function d(e){return"crypto.sessions/"+e}function h(e){return"crypto.session.problems/"+e}function p(e,t){return c+e+"/"+t}function f(e,t){return"crypto.inboundgroupsessions.withheld/"+e+"/"+t}function g(e){return"crypto.rooms/"+e}class m extends r.MemoryCryptoStore{constructor(e){super(),this.store=e}static exists(e){const t=e.length;for(let n=0;ne.time-t.time)),F(this.store,o,r)}async getEndToEndSessionProblem(e,t){const n=h(e),o=_(this.store,n)||[];if(!o.length)return null;const r=o[o.length-1];for(const e of o)if(e.time>t)return Object.assign({},e,{fixed:r.fixed});return r.fixed?null:r}async filterOutNotifiedErrorDevices(e){const t=_(this.store,s)||{},n=[];for(const o of e){const{userId:e,deviceInfo:r}=o;e in t?r.deviceId in t[e]||(n.push(o),t[e][r.deviceId]=!0):(n.push(o),t[e]={[r.deviceId]:!0})}return F(this.store,s,t),n}getEndToEndInboundGroupSession(e,t,n,o){o(_(this.store,p(e,t)),_(this.store,f(e,t)))}getAllEndToEndInboundGroupSessions(e,t){for(let e=0;e{n.push({senderKey:t,sessionId:r,sessionData:e})})),e&&o.length>=e)break}return Promise.resolve(n)}countSessionsNeedingBackup(){const e=_(this.store,l)||{};return Promise.resolve(Object.keys(e).length)}unmarkSessionsNeedingBackup(e){const t=_(this.store,l)||{};for(const n of e)delete t[n.senderKey+"/"+n.sessionId];return F(this.store,l,t),Promise.resolve()}markSessionsNeedingBackup(e){const t=_(this.store,l)||{};for(const n of e)t[n.senderKey+"/"+n.sessionId]=!0;return F(this.store,l,t),Promise.resolve()}deleteAllData(){return this.store.removeItem(i),Promise.resolve()}getAccount(e,t){t(_(this.store,i))}storeAccount(e,t){F(this.store,i,t)}getCrossSigningKeys(e,t){t(_(this.store,a))}getSecretStorePrivateKey(e,t,n){t(_(this.store,`crypto.ssss_cache.${n}`))}storeCrossSigningKeys(e,t){F(this.store,a,t)}storeSecretStorePrivateKey(e,t,n){F(this.store,`crypto.ssss_cache.${t}`,n)}doTxn(e,t,n){return Promise.resolve(n(null))}}function _(e,t){try{return JSON.parse(e.getItem(t))}catch(e){o.logger.log("Error: Failed to get key %s: %s",t,e.stack||e),o.logger.log(e.stack)}return null}function F(e,t,n){e.setItem(t,JSON.stringify(n))}t.LocalStorageCryptoStore=m},11045:(e,t,n)=>{"use strict";var o=n(20862),r=n(95318);Object.defineProperty(t,"__esModule",{value:!0}),t.MemoryCryptoStore=void 0;var i=r(n(59713)),a=n(7434),s=o(n(3102));function u(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function c(e){for(var t=1;t{const n=this._getOutgoingRoomKeyRequest(t);return n?(a.logger.log(`already have key request outstanding for ${t.room_id} / ${t.session_id}: not sending another`),n):(a.logger.log(`enqueueing key request for ${t.room_id} / `+t.session_id),this._outgoingRoomKeyRequests.push(e),e)}))}getOutgoingRoomKeyRequest(e){return Promise.resolve(this._getOutgoingRoomKeyRequest(e))}_getOutgoingRoomKeyRequest(e){for(const t of this._outgoingRoomKeyRequests)if(s.deepCompare(t.requestBody,e))return t;return null}getOutgoingRoomKeyRequestByState(e){for(const t of this._outgoingRoomKeyRequests)for(const n of e)if(t.state===n)return Promise.resolve(t);return Promise.resolve(null)}getAllOutgoingRoomKeyRequestsByState(e){return Promise.resolve(this._outgoingRoomKeyRequests.filter((t=>t.state==e)))}getOutgoingRoomKeyRequestsByTarget(e,t,n){const o=[];for(const r of this._outgoingRoomKeyRequests)for(const i of n)r.state===i&&r.recipients.includes({userId:e,deviceId:t})&&o.push(r);return Promise.resolve(o)}updateOutgoingRoomKeyRequest(e,t,n){for(const o of this._outgoingRoomKeyRequests)if(o.requestId===e)return o.state!=t?(a.logger.warn(`Cannot update room key request from ${t} as it was already updated to ${o.state}`),Promise.resolve(null)):(Object.assign(o,n),Promise.resolve(o));return Promise.resolve(null)}deleteOutgoingRoomKeyRequest(e,t){for(let n=0;n{Object.entries(n).forEach((([n,o])=>{t(c(c({},o),{},{deviceKey:e,sessionId:n}))}))}))}storeEndToEndSession(e,t,n,o){let r=this._sessions[e];void 0===r&&(r={},this._sessions[e]=r),r[t]=n}async storeEndToEndSessionProblem(e,t,n){const o=this._sessionProblems[e]=this._sessionProblems[e]||[];o.push({type:t,fixed:n,time:Date.now()}),o.sort(((e,t)=>e.time-t.time))}async getEndToEndSessionProblem(e,t){const n=this._sessionProblems[e]||[];if(!n.length)return null;const o=n[n.length-1];for(const e of n)if(e.time>t)return Object.assign({},e,{fixed:o.fixed});return o.fixed?null:o}async filterOutNotifiedErrorDevices(e){const t=this._notifiedErrorDevices,n=[];for(const o of e){const{userId:e,deviceInfo:r}=o;e in t?r.deviceId in t[e]||(n.push(o),t[e][r.deviceId]=!0):(n.push(o),t[e]={[r.deviceId]:!0})}return n}getEndToEndInboundGroupSession(e,t,n,o){const r=e+"/"+t;o(this._inboundGroupSessions[r]||null,this._inboundGroupSessionsWithheld[r]||null)}getAllEndToEndInboundGroupSessions(e,t){for(const e of Object.keys(this._inboundGroupSessions))t({senderKey:e.substr(0,43),sessionId:e.substr(44),sessionData:this._inboundGroupSessions[e]});t(null)}addEndToEndInboundGroupSession(e,t,n,o){const r=e+"/"+t;void 0===this._inboundGroupSessions[r]&&(this._inboundGroupSessions[r]=n)}storeEndToEndInboundGroupSession(e,t,n,o){this._inboundGroupSessions[e+"/"+t]=n}storeEndToEndInboundGroupSessionWithheld(e,t,n,o){const r=e+"/"+t;this._inboundGroupSessionsWithheld[r]=n}getEndToEndDeviceData(e,t){t(this._deviceData)}storeEndToEndDeviceData(e,t){this._deviceData=e}storeEndToEndRoom(e,t,n){this._rooms[e]=t}getEndToEndRooms(e,t){t(this._rooms)}getSessionsNeedingBackup(e){const t=[];for(const n in this._sessionsNeedingBackup)if(this._inboundGroupSessions[n]&&(t.push({senderKey:n.substr(0,43),sessionId:n.substr(44),sessionData:this._inboundGroupSessions[n]}),e&&n.length>=e))break;return Promise.resolve(t)}countSessionsNeedingBackup(){return Promise.resolve(Object.keys(this._sessionsNeedingBackup).length)}unmarkSessionsNeedingBackup(e){for(const t of e){const e=t.senderKey+"/"+t.sessionId;delete this._sessionsNeedingBackup[e]}return Promise.resolve()}markSessionsNeedingBackup(e){for(const t of e){const e=t.senderKey+"/"+t.sessionId;this._sessionsNeedingBackup[e]=!0}return Promise.resolve()}addSharedHistoryInboundGroupSession(e,t,n){const o=this._sharedHistoryInboundGroupSessions[e]||[];o.push([t,n]),this._sharedHistoryInboundGroupSessions[e]=o}getSharedHistoryInboundGroupSessions(e){return Promise.resolve(this._sharedHistoryInboundGroupSessions[e]||[])}doTxn(e,t,n){return Promise.resolve(n(null))}}},41631:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.VerificationBase=t.SwitchStartEventError=void 0;var o=n(24369),r=n(17187),i=n(7434),a=n(23272),s=n(16702),u=n(3075);const c=new Error("Verification timed out");class l extends Error{constructor(e){super(),this.startEvent=e}}t.SwitchStartEventError=l;class d extends r.EventEmitter{constructor(e,t,n,o,r,i){super(),this._channel=e,this._baseApis=t,this.userId=n,this.deviceId=o,this.startEvent=r,this.request=i,this.cancelled=!1,this._done=!1,this._promise=null,this._transactionTimeoutTimer=null}get initiatedByMe(){if(!this.startEvent)return!0;const e=this.startEvent.getSender(),t=this.startEvent.getContent();return e===this._baseApis.getUserId()&&t.from_device===this._baseApis.getDeviceId()}_resetTimer(){i.logger.info("Refreshing/starting the verification transaction timeout timer"),null!==this._transactionTimeoutTimer&&clearTimeout(this._transactionTimeoutTimer),this._transactionTimeoutTimer=setTimeout((()=>{this._done||this.cancelled||(i.logger.info("Triggering verification timeout"),this.cancel(c))}),6e5)}_endTimer(){null!==this._transactionTimeoutTimer&&(clearTimeout(this._transactionTimeoutTimer),this._transactionTimeoutTimer=null)}_send(e,t){return this._channel.send(e,t)}_waitForEvent(e){if(this._done)return Promise.reject(new Error("Verification is already done"));const t=this.request.getEventFromOtherParty(e);return t?Promise.resolve(t):(this._expectedEvent=e,new Promise(((e,t)=>{this._resolveEvent=e,this._rejectEvent=t})))}canSwitchStartEvent(){return!1}switchStartEvent(e){if(this.canSwitchStartEvent(e))if(i.logger.log("Verification Base: switching verification start event",{restartingFlow:!!this._rejectEvent}),this._rejectEvent){const t=this._rejectEvent;this._rejectEvent=void 0,t(new l(e))}else this.startEvent=e}handleEvent(e){if(!this._done)if(e.getType()===this._expectedEvent)"m.key.verification.done"!==this._expectedEvent&&(this._expectedEvent=void 0,this._rejectEvent=void 0,this._resetTimer(),this._resolveEvent(e));else if("m.key.verification.cancel"===e.getType()){const t=this._reject;if(this._reject=void 0,t){const n=e.getContent(),{reason:o,code:r}=n;t(new Error(`Other side cancelled verification because ${o} (${r})`))}}else if(this._expectedEvent){const t=new Error("Unexpected message: expecting "+this._expectedEvent+" but got "+e.getType());if(this._expectedEvent=void 0,this._rejectEvent){const e=this._rejectEvent;this._rejectEvent=void 0,e(t)}this.cancel(t)}}done(){if(this._endTimer(),!this._done)return this.request.onVerifierFinished(),this._resolve(),(0,u.requestKeysDuringVerification)(this._baseApis,this.userId,this.deviceId)}cancel(e){if(this._endTimer(),!this._done){if(this.cancelled=!0,this.request.onVerifierCancelled(),this.userId&&this.deviceId)if(e===c){const e=(0,s.newTimeoutError)();this._send(e.getType(),e.getContent())}else if(e instanceof o.MatrixEvent){if(e.getSender()!==this.userId){const t=e.getContent();"m.key.verification.cancel"===e.getType()?(t.code=t.code||"m.unknown",t.reason=t.reason||t.body||"Unknown reason",this._send("m.key.verification.cancel",t)):this._send("m.key.verification.cancel",{code:"m.unknown",reason:t.body||"Unknown reason"})}}else this._send("m.key.verification.cancel",{code:"m.unknown",reason:e.toString()});null!==this._promise?this._reject&&this._reject(e):this._promise=Promise.reject(e),this.emit("cancel",e)}}verify(){return this._promise||(this._promise=new Promise(((e,t)=>{this._resolve=(...t)=>{this._done=!0,this._endTimer(),e(...t)},this._reject=(...e)=>{this._done=!0,this._endTimer(),t(...e)}})),this._doVerification&&!this._started&&(this._started=!0,this._resetTimer(),Promise.resolve(this._doVerification()).then(this.done.bind(this),this.cancel.bind(this)))),this._promise}async _verifyKeys(e,t,n){const o=[];for(const[r,s]of Object.entries(t)){const t=r.split(":",2)[1],u=this._baseApis.getStoredDevice(e,t);if(u)await n(r,u,s),o.push(t);else{const u=this._baseApis._crypto._deviceList.getStoredCrossSigningForUser(e);u&&u.getId()===t?(await n(r,a.DeviceInfo.fromStorage({keys:{[r]:t}},t),s),o.push(t)):i.logger.warn(`verification: Could not find device ${t} to verify`)}}if(!o.length)throw new Error("No devices could be verified");i.logger.info("Verification completed! Marking devices verified: ",o);for(const t of o)await this._baseApis.setDeviceVerified(e,t)}}t.VerificationBase=d},16702:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.newVerificationError=r,t.errorFactory=i,t.errorFromEvent=function(e){const t=e.getContent();if(t){const{code:e,reason:n}=t;return{code:e,reason:n}}return{code:"Unknown error",reason:"m.unknown"}},t.newInvalidMessageError=t.newUserMismatchError=t.newKeyMismatchError=t.newUnexpectedMessageError=t.newUnknownMethodError=t.newUnknownTransactionError=t.newTimeoutError=t.newUserCancelledError=void 0;var o=n(24369);function r(e,t,n){const r=Object.assign({},{code:e,reason:t},n);return new o.MatrixEvent({type:"m.key.verification.cancel",content:r})}function i(e,t){return function(n){return r(e,t,n)}}const a=i("m.user","Cancelled by user");t.newUserCancelledError=a;const s=i("m.timeout","Timed out");t.newTimeoutError=s;const u=i("m.unknown_transaction","Unknown transaction");t.newUnknownTransactionError=u;const c=i("m.unknown_method","Unknown method");t.newUnknownMethodError=c;const l=i("m.unexpected_message","Unexpected message");t.newUnexpectedMessageError=l;const d=i("m.key_mismatch","Key mismatch");t.newKeyMismatchError=d;const h=i("m.user_error","User mismatch");t.newUserMismatchError=h;const p=i("m.invalid_message","Invalid message");t.newInvalidMessageError=p},4028:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.IllegalMethod=void 0;var o=n(41631);class r extends o.VerificationBase{static factory(...e){return new r(...e)}static get NAME(){return"org.matrix.illegal_method"}async _doVerification(){throw new Error("Verification is not possible with this method")}}t.IllegalMethod=r},51696:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.QRCodeData=t.ReciprocateQRCode=t.SCAN_QR_CODE_METHOD=t.SHOW_QR_CODE_METHOD=void 0;var o=n(41631),r=n(16702),i=n(32772),a=n(7434);t.SHOW_QR_CODE_METHOD="m.qr_code.show.v1",t.SCAN_QR_CODE_METHOD="m.qr_code.scan.v1";class s extends o.VerificationBase{static factory(...e){return new s(...e)}static get NAME(){return"m.reciprocate.v1"}async _doVerification(){if(!this.startEvent)throw new Error("It is not currently possible to start verificationwith this method yet.");const{qrCodeData:e}=this.request;if(this.startEvent.getContent().secret!==e.encodedSharedSecret)throw(0,r.newKeyMismatchError)();await new Promise(((e,t)=>{this.reciprocateQREvent={confirm:e,cancel:()=>t((0,r.newUserCancelledError)())},this.emit("show_reciprocate_qr",this.reciprocateQREvent)}));const t={};switch(e.mode){case u:{const n=e.otherUserMasterKey;t[`ed25519:${n}`]=n;break}case c:{const n=this.request.targetDevice.deviceId;t[`ed25519:${n}`]=e.otherDeviceKey;break}case l:{const n=e.myMasterKey;t[`ed25519:${n}`]=n;break}}await this._verifyKeys(this.userId,t,((e,n,o)=>{const i=t[e];if(!i)throw(0,r.newKeyMismatchError)();if(o!==i)throw a.logger.error("key ID from key info does not match"),(0,r.newKeyMismatchError)();for(const e in n.keys){if(!e.startsWith("ed25519"))continue;const o=t[e];if(!o)throw(0,r.newKeyMismatchError)();if(n.keys[e]!==o)throw a.logger.error("master key does not match"),(0,r.newKeyMismatchError)()}}))}}t.ReciprocateQRCode=s;const u=0,c=1,l=2;class d{constructor(e,t,n,o,r,i){this._sharedSecret=t,this._mode=e,this._otherUserMasterKey=n,this._otherDeviceKey=o,this._myMasterKey=r,this._buffer=i}static async create(e,t){const n=d._generateSharedSecret(),o=d._determineMode(e,t);let r=null,i=null,a=null;if(o===u)r=t.getStoredCrossSigningForUser(e.otherUserId).getId("master");else if(o===c)i=await d._getOtherDeviceKey(e,t);else if(o===l){const e=t.getUserId();a=t.getStoredCrossSigningForUser(e).getId("master")}const s=d._generateQrData(e,t,o,n,r,i,a),h=d._generateBuffer(s);return new d(o,n,r,i,a,h)}get buffer(){return this._buffer}get mode(){return this._mode}get otherDeviceKey(){return this._otherDeviceKey}get otherUserMasterKey(){return this._otherUserMasterKey}get myMasterKey(){return this._myMasterKey}get encodedSharedSecret(){return this._sharedSecret}static _generateSharedSecret(){const e=new Uint8Array(11);return n.g.crypto.getRandomValues(e),(0,i.encodeUnpaddedBase64)(e)}static async _getOtherDeviceKey(e,t){const n=t.getUserId(),o=e.targetDevice,r=o?o.deviceId:null,i=t.getStoredDevice(n,r);if(!i)throw new Error("could not find device "+r);return i.getFingerprint()}static _determineMode(e,t){const n=t.getUserId(),o=e.otherUserId;let r=u;return n===o&&(r=t.checkUserTrust(n).isCrossSigningVerified()?c:l),r}static _generateQrData(e,t,n,o,r,i,a){const s=t.getUserId(),d={prefix:"MATRIX",version:2,mode:n,transactionId:e.channel.transactionId,firstKeyB64:"",secondKeyB64:"",secretB64:o},h=t.getStoredCrossSigningForUser(s);return n===u?(d.firstKeyB64=h.getId("master"),d.secondKeyB64=r):n===c?(d.firstKeyB64=h.getId("master"),d.secondKeyB64=i):n===l&&(d.firstKeyB64=t.getDeviceEd25519Key(),d.secondKeyB64=a),d}static _generateBuffer(e){let t=Buffer.alloc(0);const n=e=>{const n=Buffer.from([e]);t=Buffer.concat([t,n])},o=(e,n,o=!0)=>{const r=Buffer.from(e,n);o&&(e=>{const n=Buffer.alloc(2);n.writeInt16BE(e,0),t=Buffer.concat([t,n])})(r.byteLength),t=Buffer.concat([t,r])},r=e=>{const n=(0,i.decodeBase64)(e),o=Buffer.from(n);t=Buffer.concat([t,o])};return o(e.prefix,"ascii",!1),n(e.version),n(e.mode),o(e.transactionId,"utf-8"),r(e.firstKeyB64),r(e.secondKeyB64),r(e.secretB64),t}}t.QRCodeData=d},56381:(e,t,n)=>{"use strict";var o=n(95318);Object.defineProperty(t,"__esModule",{value:!0}),t.SAS=void 0;var r=n(41631),i=o(n(69141)),a=n(16702),s=n(7434);const u="m.key.verification.start",c=["m.key.verification.accept","m.key.verification.key","m.key.verification.mac"];let l;const d=(0,a.errorFactory)("m.mismatched_sas","Mismatched short authentication string"),h=(0,a.errorFactory)("m.mismatched_commitment","Mismatched commitment"),p=[["🐶","dog"],["🐱","cat"],["🦁","lion"],["🐎","horse"],["🦄","unicorn"],["🐷","pig"],["🐘","elephant"],["🐰","rabbit"],["🐼","panda"],["🐓","rooster"],["🐧","penguin"],["🐢","turtle"],["🐟","fish"],["🐙","octopus"],["🦋","butterfly"],["🌷","flower"],["🌳","tree"],["🌵","cactus"],["🍄","mushroom"],["🌏","globe"],["🌙","moon"],["☁️","cloud"],["🔥","fire"],["🍌","banana"],["🍎","apple"],["🍓","strawberry"],["🌽","corn"],["🍕","pizza"],["🎂","cake"],["❤️","heart"],["🙂","smiley"],["🤖","robot"],["🎩","hat"],["👓","glasses"],["🔧","spanner"],["🎅","santa"],["👍","thumbs up"],["☂️","umbrella"],["⌛","hourglass"],["⏰","clock"],["🎁","gift"],["💡","light bulb"],["📕","book"],["✏️","pencil"],["📎","paperclip"],["✂️","scissors"],["🔒","lock"],["🔑","key"],["🔨","hammer"],["☎️","telephone"],["🏁","flag"],["🚂","train"],["🚲","bicycle"],["✈️","aeroplane"],["🚀","rocket"],["🏆","trophy"],["⚽","ball"],["🎸","guitar"],["🎺","trumpet"],["🔔","bell"],["⚓️","anchor"],["🎧","headphones"],["📁","folder"],["📌","pin"]],f={decimal:function(e){return[1e3+(e[0]<<5|e[1]>>3),1e3+((7&e[1])<<10|e[2]<<2|e[3]>>6),1e3+((63&e[3])<<7|e[4]>>1)]},emoji:function(e){return[e[0]>>2,(3&e[0])<<4|e[1]>>4,(15&e[1])<<2|e[2]>>6,63&e[2],e[3]>>2,(3&e[3])<<4|e[4]>>4,(15&e[4])<<2|e[5]>>6].map((e=>p[e]))}};function g(e,t){const n={};for(const o of t)o in f&&(n[o]=f[o](e));return n}const m={"hkdf-hmac-sha256":"calculate_mac","hmac-sha256":"calculate_mac_long_kdf"};function _(e,t){return function(...n){const o=e[m[t]].apply(e,n);return s.logger.log("SAS calculateMAC:",t,n,o),o}}const F={"curve25519-hkdf-sha256":function(e,t,n){const o=`${e._baseApis.getUserId()}|${e._baseApis.deviceId}|${e.ourSASPubKey}|`,r=`${e.userId}|${e.deviceId}|${e.theirSASPubKey}|`,i="MATRIX_KEY_VERIFICATION_SAS|"+(e.initiatedByMe?o+r:r+o)+e._channel.transactionId;return t.generate_bytes(i,n)},curve25519:function(e,t,n){const o=`${e._baseApis.getUserId()}${e._baseApis.deviceId}`,r=`${e.userId}${e.deviceId}`,i="MATRIX_KEY_VERIFICATION_SAS"+(e.initiatedByMe?o+r:r+o)+e._channel.transactionId;return t.generate_bytes(i,n)}},y=["curve25519-hkdf-sha256","curve25519"],b=["sha256"],v=["hkdf-hmac-sha256","hmac-sha256"],w=Object.keys(f),E=new Set(y),k=new Set(b),D=new Set(v),S=new Set(w);function x(e,t){return e instanceof Array?e.filter((e=>t.has(e))):[]}class C extends r.VerificationBase{static get NAME(){return"m.sas.v1"}get events(){return c}async _doVerification(){await n.g.Olm.init(),l=l||new n.g.Olm.Utility,await this._baseApis.downloadKeys([this.userId]);let e=!1;do{try{return this.initiatedByMe?await this._doSendVerification():await this._doRespondVerification()}catch(t){if(!(t instanceof r.SwitchStartEventError))throw t;this.startEvent=t.startEvent,e=!0}}while(e)}canSwitchStartEvent(e){if(e.getType()!==u)return!1;const t=e.getContent();return t&&t.method===C.NAME&&this._waitingForAccept}async _sendStart(){const e=this._channel.completeContent(u,{method:C.NAME,from_device:this._baseApis.deviceId,key_agreement_protocols:y,hashes:b,message_authentication_codes:v,short_authentication_string:w});return await this._channel.sendCompleted(u,e),e}async _doSendVerification(){let e,t;if(this._waitingForAccept=!0,e=this.startEvent?this._channel.completedContentFromEvent(this.startEvent):await this._sendStart(),!this.initiatedByMe)throw new r.SwitchStartEventError(this.startEvent);try{t=await this._waitForEvent("m.key.verification.accept")}finally{this._waitingForAccept=!1}let o=t.getContent();const s=x(o.short_authentication_string,S);if(!(E.has(o.key_agreement_protocol)&&k.has(o.hash)&&D.has(o.message_authentication_code)&&s.length))throw(0,a.newUnknownMethodError)();if("string"!=typeof o.commitment)throw(0,a.newInvalidMessageError)();const u=o.key_agreement_protocol,c=o.message_authentication_code,p=o.commitment,f=new n.g.Olm.SAS;try{this.ourSASPubKey=f.get_pubkey(),await this._send("m.key.verification.key",{key:this.ourSASPubKey}),t=await this._waitForEvent("m.key.verification.key"),o=t.getContent();const n=o.key+i.default.stringify(e);if(l.sha256(n)!==p)throw h();this.theirSASPubKey=o.key,f.set_their_key(o.key);const r=F[u](this,f,6),m=new Promise(((e,t)=>{this.sasEvent={sas:g(r,s),confirm:async()=>{try{await this._sendMAC(f,c),e()}catch(e){t(e)}},cancel:()=>t((0,a.newUserCancelledError)()),mismatch:()=>t(d())},this.emit("show_sas",this.sasEvent)}));[t]=await Promise.all([this._waitForEvent("m.key.verification.mac").then((e=>(this._expectedEvent="m.key.verification.done",e))),m]),o=t.getContent(),await this._checkMAC(f,o,c)}finally{f.free()}}async _doRespondVerification(){let e=this._channel.completedContentFromEvent(this.startEvent);const t=x(y,new Set(e.key_agreement_protocols))[0],o=x(b,new Set(e.hashes))[0],r=x(v,new Set(e.message_authentication_codes))[0],s=x(e.short_authentication_string,S);if(void 0===t||void 0===o||void 0===r||!s.length)throw(0,a.newUnknownMethodError)();const u=new n.g.Olm.SAS;try{const n=u.get_pubkey()+i.default.stringify(e);await this._send("m.key.verification.accept",{key_agreement_protocol:t,hash:o,message_authentication_code:r,short_authentication_string:s,commitment:l.sha256(n)});let c=await this._waitForEvent("m.key.verification.key");e=c.getContent(),this.theirSASPubKey=e.key,u.set_their_key(e.key),this.ourSASPubKey=u.get_pubkey(),await this._send("m.key.verification.key",{key:this.ourSASPubKey});const h=F[t](this,u,6),p=new Promise(((e,t)=>{this.sasEvent={sas:g(h,s),confirm:async()=>{try{await this._sendMAC(u,r),e()}catch(e){t(e)}},cancel:()=>t((0,a.newUserCancelledError)()),mismatch:()=>t(d())},this.emit("show_sas",this.sasEvent)}));[c]=await Promise.all([this._waitForEvent("m.key.verification.mac").then((e=>(this._expectedEvent="m.key.verification.done",e))),p]),e=c.getContent(),await this._checkMAC(u,e,r)}finally{u.free()}}_sendMAC(e,t){const n={},o=[],r="MATRIX_KEY_VERIFICATION_MAC"+this._baseApis.getUserId()+this._baseApis.deviceId+this.userId+this.deviceId+this._channel.transactionId,i=`ed25519:${this._baseApis.deviceId}`;n[i]=_(e,t)(this._baseApis.getDeviceEd25519Key(),r+i),o.push(i);const a=this._baseApis.getCrossSigningId();if(a){const i=`ed25519:${a}`;n[i]=_(e,t)(a,r+i),o.push(i)}const s=_(e,t)(o.sort().join(","),r+"KEY_IDS");return this._send("m.key.verification.mac",{mac:n,keys:s})}async _checkMAC(e,t,n){const o="MATRIX_KEY_VERIFICATION_MAC"+this.userId+this.deviceId+this._baseApis.getUserId()+this._baseApis.deviceId+this._channel.transactionId;if(t.keys!==_(e,n)(Object.keys(t.mac).sort().join(","),o+"KEY_IDS"))throw(0,a.newKeyMismatchError)();await this._verifyKeys(this.userId,t.mac,((t,r,i)=>{if(i!==_(e,n)(r.keys[t],o+t))throw(0,a.newKeyMismatchError)()}))}}t.SAS=C},22842:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.InRoomRequests=t.InRoomChannel=void 0;var o=n(85279),r=n(7434);const i="m.room.message",a="m.reference",s="m.relates_to";class u{constructor(e,t,n=null){this._client=e,this._roomId=t,this.userId=n,this._requestEventId=null}get receiveStartFromOtherDevices(){return!0}get roomId(){return this._roomId}get transactionId(){return this._requestEventId}static getOtherPartyUserId(e,t){if(u.getEventType(e)!==o.REQUEST_TYPE)return;const n=t.getUserId(),r=e.getSender(),i=e.getContent().to;return r===n?i:i===n?r:void 0}getTimestamp(e){return e.getTs()}static canCreateRequest(e){return e===o.REQUEST_TYPE}static getTransactionId(e){if(u.getEventType(e)===o.REQUEST_TYPE)return e.getId();{const t=e.getRelation();if(t&&t.rel_type===a)return t.event_id}}static validateEvent(e,t){const n=u.getTransactionId(e);if("string"!=typeof n||0===n.length)return!1;const i=u.getEventType(e),a=e.getContent();if(i===o.REQUEST_TYPE){if(!a||"string"!=typeof a.to||!a.to.length)return r.logger.log("InRoomChannel: validateEvent: no valid to "+(a&&a.to)),!1;if(!u.getOtherPartyUserId(e,t))return r.logger.log(`InRoomChannel: validateEvent: not directed to or sent by me: ${e.getSender()}, ${a&&a.to}`),!1}return o.VerificationRequest.validateEvent(i,e,t)}static getEventType(e){const t=e.getType();if(t===i){const t=e.getContent();if(t){const{msgtype:e}=t;if(e===o.REQUEST_TYPE)return o.REQUEST_TYPE}}return t&&t!==o.REQUEST_TYPE?t:""}async handleEvent(e,t,n){if(t.hasEventId(e.getId()))return;const o=u.getEventType(e);if(e.getRoomId()!==this._roomId)return;if(null===this.userId){const t=u.getOtherPartyUserId(e,this._client);t&&(this.userId=t)}const i=this._client.getUserId(),a=e.getSender();if(null!==this.userId&&a!==i&&a!==this.userId)return void r.logger.log(`InRoomChannel: ignoring verification event from non-participating sender ${a}`);null===this._requestEventId&&(this._requestEventId=u.getTransactionId(e));const s=!!e.getUnsigned().transaction_id,c=e.getSender()===this._client.getUserId();return await t.handleEvent(o,e,n,s,c)}completedContentFromEvent(e){const t=Object.assign({},e.getContent());return t[s]=e.getRelation(),t}completeContent(e,t){return t=Object.assign({},t),e!==o.REQUEST_TYPE&&e!==o.READY_TYPE&&e!==o.START_TYPE||(t.from_device=this._client.getDeviceId()),e===o.REQUEST_TYPE?t={body:this._client.getUserId()+" is requesting to verify your key, but your client does not support in-chat key verification. You will need to use legacy key verification to verify keys.",msgtype:o.REQUEST_TYPE,to:this.userId,from_device:t.from_device,methods:t.methods}:t[s]={rel_type:a,event_id:this.transactionId},t}send(e,t){const n=this.completeContent(e,t);return this.sendCompleted(e,n)}async sendCompleted(e,t){let n=e;e===o.REQUEST_TYPE&&(n=i);const r=await this._client.sendEvent(this._roomId,n,t);e===o.REQUEST_TYPE&&(this._requestEventId=r.event_id)}}t.InRoomChannel=u,t.InRoomRequests=class{constructor(){this._requestsByRoomId=new Map}getRequest(e){const t=e.getRoomId(),n=u.getTransactionId(e);return this._getRequestByTxnId(t,n)}getRequestByChannel(e){return this._getRequestByTxnId(e.roomId,e.transactionId)}_getRequestByTxnId(e,t){const n=this._requestsByRoomId.get(e);if(n)return n.get(t)}setRequest(e,t){this._setRequest(e.getRoomId(),u.getTransactionId(e),t)}setRequestByChannel(e,t){this._setRequest(e.roomId,e.transactionId,t)}_setRequest(e,t,n){let o=this._requestsByRoomId.get(e);o||(o=new Map,this._requestsByRoomId.set(e,o)),o.set(t,n)}removeRequest(e){const t=e.getRoomId(),n=this._requestsByRoomId.get(t);n&&(n.delete(u.getTransactionId(e)),0===n.size&&this._requestsByRoomId.delete(t))}findRequestInProgress(e){const t=this._requestsByRoomId.get(e);if(t)for(const e of t.values())if(e.pending)return e}}},89588:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.ToDeviceRequests=t.ToDeviceChannel=void 0;var o=n(98401),r=n(7434),i=n(85279),a=n(16702),s=n(24369);class u{constructor(e,t,n,o=null,r=null){this._client=e,this.userId=t,this._devices=n,this.transactionId=o,this._deviceId=r}isToDevices(e){if(e.length===this._devices.length){for(const t of e)if(!this._devices.find((e=>e.deviceId===t.deviceId)))return!1;return!0}return!1}get deviceId(){return this._deviceId}static getEventType(e){return e.getType()}static getTransactionId(e){const t=e.getContent();return t&&t.transaction_id}static canCreateRequest(e){return e===i.REQUEST_TYPE||e===i.START_TYPE}static validateEvent(e,t){if(e.isCancelled())return r.logger.warn("Ignoring flagged verification request from "+e.getSender()),!1;const n=e.getContent();if(!n)return r.logger.warn("ToDeviceChannel.validateEvent: invalid: no content"),!1;if(!n.transaction_id)return r.logger.warn("ToDeviceChannel.validateEvent: invalid: no transaction_id"),!1;const o=e.getType();if(o===i.REQUEST_TYPE){if(!Number.isFinite(n.timestamp))return r.logger.warn("ToDeviceChannel.validateEvent: invalid: no timestamp"),!1;if(e.getSender()===t.getUserId()&&n.from_device==t.getDeviceId())return r.logger.warn("ToDeviceChannel.validateEvent: invalid: from own device"),!1}return i.VerificationRequest.validateEvent(o,e,t)}getTimestamp(e){const t=e.getContent();return t&&t.timestamp}async handleEvent(e,t,n){const o=e.getType(),r=e.getContent();if(o===i.REQUEST_TYPE||o===i.READY_TYPE||o===i.START_TYPE){this.transactionId||(this.transactionId=r.transaction_id);const e=r.from_device;if(!this._deviceId&&this._devices.includes(e)&&(this._deviceId=e),!this._deviceId||this._deviceId!==e){const t=this.completeContent((0,a.errorFromEvent)((0,a.newUnexpectedMessageError)()));return this._sendToDevices(i.CANCEL_TYPE,t,[e])}}const s=t.phase===i.PHASE_STARTED||t.phase===i.PHASE_READY;await t.handleEvent(e.getType(),e,n,!1,!1);const u=t.phase===i.PHASE_STARTED||t.phase===i.PHASE_READY;if((o===i.START_TYPE||o===i.READY_TYPE)&&!s&&u&&this._deviceId){const e=this._devices.filter((e=>e!==this._deviceId&&e!==this._client.getDeviceId()));if(e.length){const t=this.completeContent({code:"m.accepted",reason:"Verification request accepted by another device"});await this._sendToDevices(i.CANCEL_TYPE,t,e)}}}completedContentFromEvent(e){return e.getContent()}completeContent(e,t){return t=Object.assign({},t),this.transactionId&&(t.transaction_id=this.transactionId),e!==i.REQUEST_TYPE&&e!==i.READY_TYPE&&e!==i.START_TYPE||(t.from_device=this._client.getDeviceId()),e===i.REQUEST_TYPE&&(t.timestamp=Date.now()),t}send(e,t={}){e!==i.REQUEST_TYPE&&e!==i.START_TYPE||this.transactionId||(this.transactionId=u.makeTransactionId());const n=this.completeContent(e,t);return this.sendCompleted(e,n)}async sendCompleted(e,t){let n;n=e===i.REQUEST_TYPE?await this._sendToDevices(e,t,this._devices):await this._sendToDevices(e,t,[this._deviceId]);const o=new s.MatrixEvent({sender:this._client.getUserId(),content:t,type:e});return await this._request.handleEvent(e,o,!0,!0,!0),n}_sendToDevices(e,t,n){if(n.length){const o={};for(const e of n)o[e]=t;return this._client.sendToDevice(e,{[this.userId]:o})}return Promise.resolve()}static makeTransactionId(){return(0,o.randomString)(32)}}t.ToDeviceChannel=u,t.ToDeviceRequests=class{constructor(){this._requestsByUserId=new Map}getRequest(e){return this.getRequestBySenderAndTxnId(e.getSender(),u.getTransactionId(e))}getRequestByChannel(e){return this.getRequestBySenderAndTxnId(e.userId,e.transactionId)}getRequestBySenderAndTxnId(e,t){const n=this._requestsByUserId.get(e);if(n)return n.get(t)}setRequest(e,t){this.setRequestBySenderAndTxnId(e.getSender(),u.getTransactionId(e),t)}setRequestByChannel(e,t){this.setRequestBySenderAndTxnId(e.userId,e.transactionId,t)}setRequestBySenderAndTxnId(e,t,n){let o=this._requestsByUserId.get(e);o||(o=new Map,this._requestsByUserId.set(e,o)),o.set(t,n)}removeRequest(e){const t=e.getSender(),n=this._requestsByUserId.get(t);n&&(n.delete(u.getTransactionId(e)),0===n.size&&this._requestsByUserId.delete(t))}findRequestInProgress(e,t){const n=this._requestsByUserId.get(e);if(n)for(const e of n.values())if(e.pending&&e.channel.isToDevices(t))return e}getRequestsInProgress(e){const t=this._requestsByUserId.get(e);return t?Array.from(t.values()).filter((e=>e.pending)):[]}}},85279:(e,t,n)=>{"use strict";var o=n(95318);Object.defineProperty(t,"__esModule",{value:!0}),t.VerificationRequest=t.PHASE_DONE=t.PHASE_CANCELLED=t.PHASE_STARTED=t.PHASE_READY=t.PHASE_REQUESTED=t.PHASE_UNSENT=t.READY_TYPE=t.DONE_TYPE=t.CANCEL_TYPE=t.START_TYPE=t.REQUEST_TYPE=t.EVENT_PREFIX=void 0;var r=o(n(59713)),i=n(7434),a=n(17187),s=n(16702),u=n(51696);const c="m.key.verification.";t.EVENT_PREFIX=c;const l=c+"request";t.REQUEST_TYPE=l;const d=c+"start";t.START_TYPE=d;const h=c+"cancel";t.CANCEL_TYPE=h;const p=c+"done";t.DONE_TYPE=p;const f=c+"ready";t.READY_TYPE=f,t.PHASE_UNSENT=1,t.PHASE_REQUESTED=2,t.PHASE_READY=3,t.PHASE_STARTED=4,t.PHASE_CANCELLED=5,t.PHASE_DONE=6;class g extends a.EventEmitter{constructor(e,t,n){super(),(0,r.default)(this,"_cancelOnTimeout",(()=>{try{this.initiatedByMe?this.cancel({reason:"Other party didn't accept in time",code:"m.timeout"}):this.cancel({reason:"User didn't accept in time",code:"m.timeout"})}catch(e){i.logger.error("Error while cancelling verification request",e)}})),this.channel=e,this.channel._request=this,this._verificationMethods=t,this._client=n,this._commonMethods=[],this._setPhase(1,!1),this._eventsByUs=new Map,this._eventsByThem=new Map,this._observeOnly=!1,this._timeoutTimer=null,this._accepting=!1,this._declining=!1,this._verifierHasFinished=!1,this._cancelled=!1,this._chosenMethod=null,this._qrCodeData=null,this._requestReceivedAt=null}static validateEvent(e,t,n){const o=t.getContent();return!(!e||!e.startsWith(c))&&(o?e!==l&&e!==f||Array.isArray(o.methods)?e!==l&&e!==f&&e!==d||"string"==typeof o.from_device&&0!==o.from_device.length||(i.logger.log("VerificationRequest: validateEvent: fail because from_device"),!1):(i.logger.log("VerificationRequest: validateEvent: fail because methods"),!1):(i.logger.log("VerificationRequest: validateEvent: no content"),!1))}get invalid(){return 1===this.phase}get requested(){return 2===this.phase}get cancelled(){return 5===this.phase}get ready(){return 3===this.phase}get started(){return 4===this.phase}get done(){return 6===this.phase}get methods(){return this._commonMethods}get chosenMethod(){return this._chosenMethod}calculateEventTimeout(e){let t=this.channel.getTimestamp(e)+6e5;if(this._requestReceivedAt&&!this.initiatedByMe&&this.phase<=2){const e=this._requestReceivedAt+12e4;t=Math.min(t,e)}return Math.max(0,t-Date.now())}get timeout(){const e=this._getEventByEither(l);return e?this.calculateEventTimeout(e):0}get requestEvent(){return this._getEventByEither(l)}get phase(){return this._phase}get verifier(){return this._verifier}get canAccept(){return this.phase<3&&!this._accepting&&!this._declining}get accepting(){return this._accepting}get declining(){return this._declining}get pending(){return!this.observeOnly&&6!==this._phase&&5!==this._phase}get qrCodeData(){return this._qrCodeData}otherPartySupportsMethod(e,t=!1){if(!t&&!this.ready&&!this.started)return!1;const n=this._eventsByThem.get(l)||this._eventsByThem.get(f);if(!n){if(this.started&&this.initiatedByMe){const t=this._eventsByUs.get(d),n=t&&t.getContent();return e==(n&&n.method)}return!1}const o=n.getContent();if(!o)return!1;const{methods:r}=o;return!!Array.isArray(r)&&r.includes(e)}get initiatedByMe(){const e=this._eventsByUs.size+this._eventsByThem.size===0;if(1===this._phase&&e)return!0;const t=this._eventsByUs.has(l),n=this._eventsByThem.has(l);if(t&&!n)return!0;if(!t&&n)return!1;const o=this._eventsByUs.has(d),r=this._eventsByThem.has(d);return!(!o||r)}get requestingUserId(){return this.initiatedByMe?this._client.getUserId():this.otherUserId}get receivingUserId(){return this.initiatedByMe?this.otherUserId:this._client.getUserId()}get otherUserId(){return this.channel.userId}get isSelfVerification(){return this._client.getUserId()===this.otherUserId}get cancellingUserId(){const e=this._eventsByUs.get(h),t=this._eventsByThem.get(h);return e&&(!t||e.getId(){const o=()=>{let r=!1;return e(this)?(t(this),r=!0):this.cancelled&&(n(new Error("cancelled")),r=!0),r&&this.off("change",o),r};o()||this.on("change",o)}))}_setPhase(e,t=!0){this._phase=e,t&&this.emit("change")}_getEventByEither(e){return this._eventsByThem.get(e)||this._eventsByUs.get(e)}_getEventBy(e,t){return t?this._eventsByThem.get(e):this._eventsByUs.get(e)}_calculatePhaseTransitions(){const e=[{phase:1}],t=()=>e[e.length-1].phase,n=this._eventsByThem.has(l),o=this._getEventBy(l,n);o&&e.push({phase:2,event:o});const r=o&&this._getEventBy(f,!n);let i;if(r&&2===t()&&e.push({phase:3,event:r}),r||!o){const e=this._eventsByThem.get(d),t=this._eventsByUs.get(d);i=e&&t?e.getSender()this._verificationMethods.has(e)))}if(this.observeOnly||2!==t&&4!==t&&3!==t||this.channel.receiveStartFromOtherDevices&&this._wasSentByOwnUser(n)&&!this._wasSentByOwnDevice(n)&&(this._observeOnly=!0),4===t){const{method:e}=n.getContent();this._verifier||this.observeOnly||(this._verifier=this._createVerifier(e,n),this._verifier?this._chosenMethod=e:this.cancel({code:"m.unknown_method",reason:`Unknown method: ${e}`}))}}_applyPhaseTransitions(){const e=this._calculatePhaseTransitions(),t=e.findIndex((e=>e.phase===this.phase)),n=e.slice(t+1);for(const e of n)this._transitionToPhase(e);return n}_isWinningStartRace(e){if(e.getType()!==d)return!1;const t=this._verifier.startEvent;let n,o;if(this.isSelfVerification)if(t){const e=t.getContent();n=e&&e.from_device}else n=this._client.getDeviceId();else n=t?t.getSender():this._client.getUserId();if(this.isSelfVerification){const t=e.getContent();o=t&&t.from_device}else o=e.getSender();return o3===e.phase))&&this.otherPartySupportsMethod(u.SCAN_QR_CODE_METHOD,!0)&&(this._qrCodeData=await u.QRCodeData.create(this,this._client));const e=c[c.length-1],{phase:t}=e;this._setupTimeout(t),this._setPhase(t)}else this._observeOnly!==a&&this.emit("change")}finally{i.logger.log(`Verification request ${this.channel.transactionId}: ${e} event with id:${t.getId()}, content:${JSON.stringify(t.getContent())} deviceId:${this.channel.deviceId}, sender:${t.getSender()}, isSentByUs:${r}, isLiveEvent:${n}, isRemoteEcho:${o}, phase:${s}=>${this.phase}, observeOnly:${a}=>${this._observeOnly}`)}}_setupTimeout(e){!this._timeoutTimer&&!this.observeOnly&&2===e&&(this._timeoutTimer=setTimeout(this._cancelOnTimeout,this.timeout)),this._timeoutTimer&&(4===e||3===e||6===e||5===e)&&(clearTimeout(this._timeoutTimer),this._timeoutTimer=null)}async _cancelOnError(e,t){if(e===d){const e=t.getContent().method;if(!this._verificationMethods.has(e))return await this.cancel((0,s.errorFromEvent)((0,s.newUnknownMethodError)())),!0}const n=e===l&&1!==this.phase,o=e===f&&2!==this.phase;if(1!==this.phase&&(n||o)){i.logger.warn(`Cancelling, unexpected ${e} verification event from ${t.getSender()}`);const n=`Unexpected ${e} event in phase ${this.phase}`;return await this.cancel((0,s.errorFromEvent)((0,s.newUnexpectedMessageError)({reason:n}))),!0}return!1}_adjustObserveOnly(e,t){t||(this._observeOnly=!0),this.calculateEventTimeout(e)<3e3&&(this._observeOnly=!0)}_addEvent(e,t,n){if(n?this._eventsByUs.set(e,t):this._eventsByThem.set(e,t),e===l){for(const[e,t]of this._eventsByThem.entries())t.getSender()!==this.otherUserId&&this._eventsByThem.delete(e);this._requestReceivedAt=Date.now()}}_createVerifier(e,t=null,n=null){n||(n=this.targetDevice);const{userId:o,deviceId:r}=n,a=this._verificationMethods.get(e);if(a)return new a(this.channel,this._client,o,r,t,this);i.logger.warn("could not find verifier constructor for method",e)}_wasSentByOwnUser(e){return e.getSender()===this._client.getUserId()}_wasSentByOwnDevice(e){if(!this._wasSentByOwnUser(e))return!1;const t=e.getContent();return!(!t||t.from_device!==this._client.getDeviceId())}onVerifierCancelled(){this._cancelled=!0;const e=this._applyPhaseTransitions();e.length&&this._setPhase(e[e.length-1].phase)}onVerifierFinished(){this.channel.send("m.key.verification.done",{}),this._verifierHasFinished=!0;const e=this._applyPhaseTransitions();e.length&&this._setPhase(e[e.length-1].phase)}getEventFromOtherParty(e){return this._eventsByThem.get(e)}}t.VerificationRequest=g},19489:(e,t)=>{"use strict";function n(e,t){const n=`Store is invalid because ${e}, please stop the client, delete all data and start the client again`,o=Reflect.construct(Error,[n]);return Reflect.setPrototypeOf(o,Reflect.getPrototypeOf(this)),o.reason=e,o.value=t,o}function o(e){const t=`Crypto store is invalid because ${e}, please stop the client, delete all data and start the client again`,n=Reflect.construct(Error,[t]);return Reflect.setPrototypeOf(n,Reflect.getPrototypeOf(this)),n.reason=e,n.name="InvalidCryptoStoreError",n}Object.defineProperty(t,"__esModule",{value:!0}),t.InvalidStoreError=n,t.InvalidCryptoStoreError=o,t.KeySignatureUploadError=void 0,n.TOGGLED_LAZY_LOADING="TOGGLED_LAZY_LOADING",n.prototype=Object.create(Error.prototype,{constructor:{value:Error,enumerable:!1,writable:!0,configurable:!0}}),Reflect.setPrototypeOf(n,Error),o.TOO_NEW="TOO_NEW",o.prototype=Object.create(Error.prototype,{constructor:{value:Error,enumerable:!1,writable:!0,configurable:!0}}),Reflect.setPrototypeOf(o,Error);class r extends Error{constructor(e,t){super(e),this.value=t}}t.KeySignatureUploadError=r},33564:(e,t)=>{"use strict";function n(e){this.filter_json=e,this.types=e.types||null,this.not_types=e.not_types||[],this.rooms=e.rooms||null,this.not_rooms=e.not_rooms||[],this.senders=e.senders||null,this.not_senders=e.not_senders||[],this.contains_url=e.contains_url||null}Object.defineProperty(t,"__esModule",{value:!0}),t.FilterComponent=n,n.prototype.check=function(e){return this._checkFields(e.getRoomId(),e.getSender(),e.getType(),!!e.getContent()&&void 0!==e.getContent().url)},n.prototype._checkFields=function(e,t,n,o){const r={rooms:function(t){return e===t},senders:function(e){return t===e},types:function(e){return function(e,t){if(t.endsWith("*")){const n=t.slice(0,-1);return e.substr(0,n.length)===n}return e===t}(n,e)}},i=this;for(let e=0;e0)return!1;const o=i[t];if(o&&o.length>0&&!o.some(n))return!1}const a=this.filter_json.contains_url;return void 0===a||a===o},n.prototype.filter=function(e){return e.filter(this.check,this)},n.prototype.limit=function(){return void 0!==this.filter_json.limit?this.filter_json.limit:10}},27906:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.Filter=i;var o=n(33564);function r(e,t,n){const o=t.split(".");let r=e;for(let e=0;e{"use strict";var o=n(20862),r=n(95318);Object.defineProperty(t,"__esModule",{value:!0}),t.MatrixHttpApi=h,t.retryNetworkOperation=async function(e,t){let n=0,o=null;for(;n0){const e=1e3*Math.pow(2,n);u.logger.log(`network operation failed ${n} times, retrying in ${e}ms...`),await new Promise((t=>setTimeout(t,e)))}return await t()}catch(e){if(!(e instanceof g))throw e;n+=1,o=e}throw o},t.AbortError=t.ConnectionError=t.MatrixError=t.PREFIX_MEDIA_R0=t.PREFIX_IDENTITY_V2=t.PREFIX_IDENTITY_V1=t.PREFIX_UNSTABLE=t.PREFIX_R0=void 0;var i=r(n(59713)),a=n(37811),s=o(n(3102)),u=n(7434),c=o(n(82731));function l(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function d(e){for(var t=1;t0&&(_+="?"+F.join("&")),u.open("POST",_),this.useAuthorizationHeader&&u.setRequestHeader("Authorization","Bearer "+this.opts.accessToken),u.setRequestHeader("Content-Type",r),u.send(a),f=e.promise,f.abort=u.abort.bind(u)}else{const e={};o&&i&&(e.filename=i),f=this.authedRequest(t.callback,"POST","/upload",e,a,{prefix:"/_matrix/media/r0",headers:{"Content-Type":r},json:!1,bodyParser:g})}const _=this,F=f.finally((function(){for(let e=0;e<_.uploads.length;++e)if(_.uploads[e]===h)return void _.uploads.splice(e,1)}));return F.abort=f.abort,h.promise=F,this.uploads.push(h),F},cancelUpload:function(e){return!!e.abort&&(e.abort(),!0)},getCurrentUploads:function(){return this.uploads},idServerRequest:function(e,t,n,o,r,i){if(!this.opts.idBaseUrl)throw new Error("No Identity Server base URL set");const a=this.opts.idBaseUrl+r+n;if(void 0!==e&&!s.isFunction(e))throw Error("Expected callback to be a function but got "+typeof e);const u={uri:a,method:t,withCredentials:!1,json:!0,_matrix_opts:this.opts,headers:{}};"GET"===t?u.qs=o:"object"==typeof o&&(u.json=o),i&&(u.headers.Authorization=`Bearer ${i}`);const c=s.defer();return this.opts.request(u,p(c,e,this.opts.onlyData)),c.promise},authedRequest:function(e,t,n,o,r,i){o||(o={}),this.useAuthorizationHeader?(isFinite(i)&&(i={localTimeoutMs:i}),i||(i={}),i.headers||(i.headers={}),i.headers.Authorization||(i.headers.Authorization="Bearer "+this.opts.accessToken),o.access_token&&delete o.access_token):o.access_token||(o.access_token=this.opts.accessToken);const a=this.request(e,t,n,o,r,i),s=this;return a.catch((function(e){"M_UNKNOWN_TOKEN"==e.errcode?s.event_emitter.emit("Session.logged_out",e):"M_CONSENT_NOT_GIVEN"==e.errcode&&s.event_emitter.emit("no_consent",e.message,e.data.consent_uri)})),a},request:function(e,t,n,o,r,i){const a=void 0!==(i=i||{}).prefix?i.prefix:this.opts.prefix,s=this.opts.baseUrl+a+n;return this.requestOtherUrl(e,t,s,o,r,i)},requestOtherUrl:function(e,t,n,o,r,i){return null==i?i={}:isFinite(i)&&(i={localTimeoutMs:i}),this._request(e,t,n,o,r,i)},getUrl:function(e,t,n){let o="";return t&&(o="?"+s.encodeParams(t)),this.opts.baseUrl+n+e+o},_request:function(e,t,n,o,r,i){if(void 0!==e&&!s.isFunction(e))throw Error("Expected callback to be a function but got "+typeof e);i=i||{};const a=this;this.opts.extraParams&&(o=d(d({},o),this.opts.extraParams));const u=s.extend({},i.headers||{}),l=void 0===i.json||i.json;let h=i.bodyParser;l&&(r&&(r=JSON.stringify(r),u["content-type"]="application/json"),u.accept||(u.accept="application/json"),void 0===h&&(h=function(e){return JSON.parse(e)}));const g=s.defer();let m,_,F=!1;const y=i.localTimeoutMs||this.opts.localTimeoutMs,b=()=>{y&&(m&&c.clearTimeout(m),m=c.setTimeout((function(){F=!0,_&&_.abort&&_.abort(),g.reject(new f({error:"Locally timed out waiting for a response",errcode:"ORG.MATRIX.JSSDK_TIMEOUT",timeout:y}))}),y))};b();const v=g.promise;try{_=this.opts.request({uri:n,method:t,withCredentials:!1,qs:o,qsStringifyOptions:i.qsStringifyOptions,useQuerystring:!0,body:r,json:!1,timeout:y,headers:u||{},_matrix_opts:this.opts},(function(t,n,o){y&&(c.clearTimeout(m),F)||p(g,e,a.opts.onlyData,h)(t,n,o)})),_&&("onprogress"in _&&(_.onprogress=e=>{b()}),_.abort&&(v.abort=_.abort.bind(_)))}catch(t){g.reject(t),e&&e(t)}return v}};const p=function(e,t,n,o){return t=t||function(){},function(r,i,s){if(r&&("AbortError"===r.name||"aborted"===r||r instanceof f||(r=new g("request failed",r))),!r)try{(i.status||i.statusCode)>=400?r=function(e,t){const n=e.status||e.statusCode,o=function(e){let t;if(e.getResponseHeader?t=e.getResponseHeader("Content-Type"):e.headers&&(t=e.headers["content-type"]||null),!t)return null;try{return(0,a.parse)(t)}catch(e){throw new Error(`Error parsing Content-Type '${t}': ${e}`)}}(e);let r;if(o)if("application/json"===o.type){const e="object"==typeof t?t:JSON.parse(t);r=new f(e)}else"text/plain"===o.type&&(r=new Error(`Server returned ${n} error: ${t}`));return r||(r=new Error(`Server returned ${n} error`)),r.httpStatus=n,r}(i,s):o&&(s=o(s))}catch(e){r=new Error(`Error parsing server response: ${e}`)}if(r)e.reject(r),t(r);else{const o={code:i.status||i.statusCode,headers:i.headers,data:s};e.resolve(n?s:o),t(null,n?s:o)}}};class f extends Error{constructor(e){super(`MatrixError: ${(e=e||{}).errcode}`),this.errcode=e.errcode,this.name=e.errcode||"Unknown error code",this.message=e.error||"Unknown message",this.data=e}}t.MatrixError=f;class g extends Error{constructor(e,t){super(e+(t?`: ${t.message}`:"")),this._cause=t}get name(){return"ConnectionError"}get cause(){return this._cause}}t.ConnectionError=g;class m extends Error{constructor(){super("Operation aborted")}get name(){return"AbortError"}}t.AbortError=m},33415:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.exists=function(e,t){return new Promise(((n,o)=>{let r=!0;const i=e.open(t);i.onupgradeneeded=()=>{r=!1},i.onblocked=()=>o(),i.onsuccess=()=>{i.result.close(),r||e.deleteDatabase(t),n(r)},i.onerror=e=>o(e.target.error)}))}},28670:(e,t,n)=>{"use strict";var o=n(20862),r=n(95318);Object.defineProperty(t,"__esModule",{value:!0}),t.InteractiveAuth=l;var i=r(n(8575)),a=o(n(3102)),s=n(7434);const u="m.login.email.identity",c="m.login.msisdn";function l(e){this._matrixClient=e.matrixClient,this._data=e.authData||{},this._requestCallback=e.doRequest,this._busyChangedCallback=e.busyChanged,this._stateUpdatedCallback=e.stateUpdated||e.startAuthStage,this._resolveFunc=null,this._rejectFunc=null,this._inputs=e.inputs||{},this._requestEmailTokenCallback=e.requestEmailToken,e.sessionId&&(this._data.session=e.sessionId),this._clientSecret=e.clientSecret||this._matrixClient.generateClientSecret(),this._emailSid=e.emailSid,void 0===this._emailSid&&(this._emailSid=null),this._requestingEmailToken=!1,this._chosenFlow=null,this._currentStage=null,this._submitPromise=null}l.prototype={attemptAuth:function(){return new Promise(((e,t)=>{if(this._resolveFunc=e,this._rejectFunc=t,this._data&&this._data.flows)this._startNextAuthStage();else{this._busyChangedCallback&&this._busyChangedCallback(!0);let e=null;this._data.session&&(e={session:this._data.session}),this._doRequest(e).finally((()=>{this._busyChangedCallback&&this._busyChangedCallback(!1)}))}}))},poll:async function(){if(!this._data.session)return;if(!this._resolveFunc)return;if(this._submitPromise)return;let e={};if(this._currentStage==u&&this._emailSid){const t={sid:this._emailSid,client_secret:this._clientSecret};if(await this._matrixClient.doesServerRequireIdServerParam()){const e=i.default.parse(this._matrixClient.getIdentityServerUrl());t.id_server=e.host}e={type:u,threepid_creds:t,threepidCreds:t}}this.submitAuthDict(e,!0)},getSessionId:function(){return this._data?this._data.session:void 0},getClientSecret:function(){return this._clientSecret},getStageParams:function(e){let t={};return this._data&&this._data.params&&(t=this._data.params),t[e]},getChosenFlow(){return this._chosenFlow},submitAuthDict:async function(e,t){if(!this._resolveFunc)throw new Error("submitAuthDict() called before attemptAuth()");for(!t&&this._busyChangedCallback&&this._busyChangedCallback(!0);this._submitPromise;)try{await this._submitPromise}catch(e){}let n;this._data.session?(n={session:this._data.session},a.extend(n,e)):n=e;try{this._submitPromise=this._doRequest(n,t),await this._submitPromise}finally{this._submitPromise=null,!t&&this._busyChangedCallback&&this._busyChangedCallback(!1)}},getEmailSid:function(){return this._emailSid},setEmailSid:function(e){this._emailSid=e},_doRequest:async function(e,t){try{const n=await this._requestCallback(e,t);this._resolveFunc(n),this._resolveFunc=null,this._rejectFunc=null}catch(e){const n=e.data?e.data.flows:null,o=this._data.flows||Boolean(n);401===e.httpStatus&&e.data&&o||(t?s.logger.log("Background poll request failed doing UI auth: ignoring",e):this._rejectFunc(e)),e.data.flows||e.data.completed||e.data.session||(e.data.flows=this._data.flows,e.data.completed=this._data.completed,e.data.session=this._data.session),this._data=e.data;try{this._startNextAuthStage()}catch(e){this._rejectFunc(e),this._resolveFunc=null,this._rejectFunc=null}if(!this._emailSid&&!this._requestingEmailToken&&this._chosenFlow.stages.includes("m.login.email.identity")){this._requestingEmailToken=!0;try{const e=await this._requestEmailTokenCallback(this._inputs.emailAddress,this._clientSecret,1,this._data.session);this._emailSid=e.sid}catch(e){this._rejectFunc(e),this._resolveFunc=null,this._rejectFunc=null}finally{this._requestingEmailToken=!1}}}},_startNextAuthStage:function(){const e=this._chooseStage();if(!e)throw new Error("No incomplete flows from the server");if(this._currentStage=e,"m.login.dummy"===e)return void this.submitAuthDict({type:"m.login.dummy"});if(this._data&&this._data.errcode||this._data.error)return void this._stateUpdatedCallback(e,{errcode:this._data.errcode||"",error:this._data.error||""});const t={};e==u&&(t.emailSid=this._emailSid),this._stateUpdatedCallback(e,t)},_chooseStage:function(){null===this._chosenFlow&&(this._chosenFlow=this._chooseFlow()),s.logger.log("Active flow => %s",JSON.stringify(this._chosenFlow));const e=this._firstUncompletedStage(this._chosenFlow);return s.logger.log("Next stage: %s",e),e},_chooseFlow:function(){const e=this._data.flows||[],t=Boolean(this._inputs.emailAddress)||Boolean(this._emailSid),n=Boolean(this._inputs.phoneCountry)&&Boolean(this._inputs.phoneNumber);for(const o of e){let e=!1,r=!1;for(const t of o.stages)t===u?e=!0:t==c&&(r=!0);if(e==t&&r==n)return o}const o=new Error("No appropriate authentication flow found");throw o.name="NoAuthFlowFoundError",o.required_stages=[],t&&o.required_stages.push(u),n&&o.required_stages.push(c),o.available_flows=e,o},_firstUncompletedStage:function(e){const t=(this._data||{}).completed||[];for(let n=0;n{"use strict";var o=n(95318);Object.defineProperty(t,"__esModule",{value:!0}),t.logger=void 0;var r=o(n(2043));r.default.methodFactory=function(e,t,n){return function(...t){return this.prefix&&t.unshift(this.prefix),"error"===e||"warn"===e||"trace"===e||"info"===e?console[e](...t):console.log(...t)}};const i=r.default.getLogger("matrix");t.logger=i,i.setLevel(r.default.levels.DEBUG),function e(t){t.withPrefix=function(t){return function(t){const n=r.default.getLogger(`matrix-${t}`);return n.prefix!==t&&(e(n),n.prefix=t,n.setLevel(r.default.levels.DEBUG)),n}((this.prefix||"")+t)}}(i)},48070:(e,t,n)=>{"use strict";var o=n(20862);Object.defineProperty(t,"__esModule",{value:!0});var r={request:!0,getRequest:!0,wrapRequest:!0,setCryptoStoreFactory:!0,createClient:!0,ContentHelpers:!0,createNewMatrixCall:!0,setMatrixCallAudioInput:!0,setMatrixCallVideoInput:!0};t.request=function(e){R=e},t.getRequest=function(){return R},t.wrapRequest=function(e){const t=R;R=function(n,o){return e(t,n,o)}},t.setCryptoStoreFactory=function(e){I=e},t.createClient=function(e){return"string"==typeof e&&(e={baseUrl:e}),e.request=e.request||R,e.store=e.store||new a.MemoryStore({localStorage:n.g.localStorage}),e.scheduler=e.scheduler||new s.MatrixScheduler,e.cryptoStore=e.cryptoStore||I(),new u.MatrixClient(e)},Object.defineProperty(t,"createNewMatrixCall",{enumerable:!0,get:function(){return T.createNewMatrixCall}}),Object.defineProperty(t,"setMatrixCallAudioInput",{enumerable:!0,get:function(){return T.setAudioInput}}),Object.defineProperty(t,"setMatrixCallVideoInput",{enumerable:!0,get:function(){return T.setVideoInput}}),t.ContentHelpers=void 0;var i=n(11045);Object.keys(i).forEach((function(e){"default"!==e&&"__esModule"!==e&&(Object.prototype.hasOwnProperty.call(r,e)||e in t&&t[e]===i[e]||Object.defineProperty(t,e,{enumerable:!0,get:function(){return i[e]}}))}));var a=n(11703);Object.keys(a).forEach((function(e){"default"!==e&&"__esModule"!==e&&(Object.prototype.hasOwnProperty.call(r,e)||e in t&&t[e]===a[e]||Object.defineProperty(t,e,{enumerable:!0,get:function(){return a[e]}}))}));var s=n(39443);Object.keys(s).forEach((function(e){"default"!==e&&"__esModule"!==e&&(Object.prototype.hasOwnProperty.call(r,e)||e in t&&t[e]===s[e]||Object.defineProperty(t,e,{enumerable:!0,get:function(){return s[e]}}))}));var u=n(62168);Object.keys(u).forEach((function(e){"default"!==e&&"__esModule"!==e&&(Object.prototype.hasOwnProperty.call(r,e)||e in t&&t[e]===u[e]||Object.defineProperty(t,e,{enumerable:!0,get:function(){return u[e]}}))}));var c=n(17715);Object.keys(c).forEach((function(e){"default"!==e&&"__esModule"!==e&&(Object.prototype.hasOwnProperty.call(r,e)||e in t&&t[e]===c[e]||Object.defineProperty(t,e,{enumerable:!0,get:function(){return c[e]}}))}));var l=n(79118);Object.keys(l).forEach((function(e){"default"!==e&&"__esModule"!==e&&(Object.prototype.hasOwnProperty.call(r,e)||e in t&&t[e]===l[e]||Object.defineProperty(t,e,{enumerable:!0,get:function(){return l[e]}}))}));var d=n(22741);Object.keys(d).forEach((function(e){"default"!==e&&"__esModule"!==e&&(Object.prototype.hasOwnProperty.call(r,e)||e in t&&t[e]===d[e]||Object.defineProperty(t,e,{enumerable:!0,get:function(){return d[e]}}))}));var h=n(19489);Object.keys(h).forEach((function(e){"default"!==e&&"__esModule"!==e&&(Object.prototype.hasOwnProperty.call(r,e)||e in t&&t[e]===h[e]||Object.defineProperty(t,e,{enumerable:!0,get:function(){return h[e]}}))}));var p=n(24369);Object.keys(p).forEach((function(e){"default"!==e&&"__esModule"!==e&&(Object.prototype.hasOwnProperty.call(r,e)||e in t&&t[e]===p[e]||Object.defineProperty(t,e,{enumerable:!0,get:function(){return p[e]}}))}));var f=n(27366);Object.keys(f).forEach((function(e){"default"!==e&&"__esModule"!==e&&(Object.prototype.hasOwnProperty.call(r,e)||e in t&&t[e]===f[e]||Object.defineProperty(t,e,{enumerable:!0,get:function(){return f[e]}}))}));var g=n(70142);Object.keys(g).forEach((function(e){"default"!==e&&"__esModule"!==e&&(Object.prototype.hasOwnProperty.call(r,e)||e in t&&t[e]===g[e]||Object.defineProperty(t,e,{enumerable:!0,get:function(){return g[e]}}))}));var m=n(88910);Object.keys(m).forEach((function(e){"default"!==e&&"__esModule"!==e&&(Object.prototype.hasOwnProperty.call(r,e)||e in t&&t[e]===m[e]||Object.defineProperty(t,e,{enumerable:!0,get:function(){return m[e]}}))}));var _=n(33705);Object.keys(_).forEach((function(e){"default"!==e&&"__esModule"!==e&&(Object.prototype.hasOwnProperty.call(r,e)||e in t&&t[e]===_[e]||Object.defineProperty(t,e,{enumerable:!0,get:function(){return _[e]}}))}));var F=n(32848);Object.keys(F).forEach((function(e){"default"!==e&&"__esModule"!==e&&(Object.prototype.hasOwnProperty.call(r,e)||e in t&&t[e]===F[e]||Object.defineProperty(t,e,{enumerable:!0,get:function(){return F[e]}}))}));var y=n(26860);Object.keys(y).forEach((function(e){"default"!==e&&"__esModule"!==e&&(Object.prototype.hasOwnProperty.call(r,e)||e in t&&t[e]===y[e]||Object.defineProperty(t,e,{enumerable:!0,get:function(){return y[e]}}))}));var b=n(83998);Object.keys(b).forEach((function(e){"default"!==e&&"__esModule"!==e&&(Object.prototype.hasOwnProperty.call(r,e)||e in t&&t[e]===b[e]||Object.defineProperty(t,e,{enumerable:!0,get:function(){return b[e]}}))}));var v=n(27906);Object.keys(v).forEach((function(e){"default"!==e&&"__esModule"!==e&&(Object.prototype.hasOwnProperty.call(r,e)||e in t&&t[e]===v[e]||Object.defineProperty(t,e,{enumerable:!0,get:function(){return v[e]}}))}));var w=n(34969);Object.keys(w).forEach((function(e){"default"!==e&&"__esModule"!==e&&(Object.prototype.hasOwnProperty.call(r,e)||e in t&&t[e]===w[e]||Object.defineProperty(t,e,{enumerable:!0,get:function(){return w[e]}}))}));var E=n(28670);Object.keys(E).forEach((function(e){"default"!==e&&"__esModule"!==e&&(Object.prototype.hasOwnProperty.call(r,e)||e in t&&t[e]===E[e]||Object.defineProperty(t,e,{enumerable:!0,get:function(){return E[e]}}))}));var k=n(91415);Object.keys(k).forEach((function(e){"default"!==e&&"__esModule"!==e&&(Object.prototype.hasOwnProperty.call(r,e)||e in t&&t[e]===k[e]||Object.defineProperty(t,e,{enumerable:!0,get:function(){return k[e]}}))}));var D=n(99789);Object.keys(D).forEach((function(e){"default"!==e&&"__esModule"!==e&&(Object.prototype.hasOwnProperty.call(r,e)||e in t&&t[e]===D[e]||Object.defineProperty(t,e,{enumerable:!0,get:function(){return D[e]}}))}));var S=n(55837);Object.keys(S).forEach((function(e){"default"!==e&&"__esModule"!==e&&(Object.prototype.hasOwnProperty.call(r,e)||e in t&&t[e]===S[e]||Object.defineProperty(t,e,{enumerable:!0,get:function(){return S[e]}}))}));var x=n(57585);Object.keys(x).forEach((function(e){"default"!==e&&"__esModule"!==e&&(Object.prototype.hasOwnProperty.call(r,e)||e in t&&t[e]===x[e]||Object.defineProperty(t,e,{enumerable:!0,get:function(){return x[e]}}))}));var C=n(73667);Object.keys(C).forEach((function(e){"default"!==e&&"__esModule"!==e&&(Object.prototype.hasOwnProperty.call(r,e)||e in t&&t[e]===C[e]||Object.defineProperty(t,e,{enumerable:!0,get:function(){return C[e]}}))}));var A=o(n(44656));t.ContentHelpers=A;var T=n(59679);let R,I=()=>new i.MemoryCryptoStore},43558:(e,t)=>{"use strict";function n(e){this._timeline=[e],this._ourEventIndex=0,this._paginateTokens={b:null,f:null},this._paginateRequests={b:null,f:null}}Object.defineProperty(t,"__esModule",{value:!0}),t.EventContext=n,n.prototype.getEvent=function(){return this._timeline[this._ourEventIndex]},n.prototype.getTimeline=function(){return this._timeline},n.prototype.getOurEventIndex=function(){return this._ourEventIndex},n.prototype.getPaginateToken=function(e){return this._paginateTokens[e?"b":"f"]},n.prototype.setPaginateToken=function(e,t){this._paginateTokens[t?"b":"f"]=e},n.prototype.addEvents=function(e,t){t?(this._timeline=e.concat(this._timeline),this._ourEventIndex+=e.length):this._timeline=this._timeline.concat(e)}},33705:(e,t,n)=>{"use strict";var o=n(20862);Object.defineProperty(t,"__esModule",{value:!0}),t.EventTimelineSet=d;var r=n(17187),i=n(88910),a=n(24369),s=o(n(3102)),u=n(7434),c=n(49690);let l;function d(e,t){this.room=e,this._timelineSupport=Boolean(t.timelineSupport),this._liveTimeline=new i.EventTimeline(this),this._unstableClientRelationAggregation=!!t.unstableClientRelationAggregation,this._timelines=[this._liveTimeline],this._eventIdToTimeline={},this._filter=t.filter||null,this._unstableClientRelationAggregation&&(this._relations={})}l=u.logger.log.bind(u.logger),s.inherits(d,r.EventEmitter),d.prototype.getTimelines=function(){return this._timelines},d.prototype.getFilter=function(){return this._filter},d.prototype.setFilter=function(e){this._filter=e},d.prototype.getPendingEvents=function(){return this.room?this._filter?this._filter.filterRoomTimeline(this.room.getPendingEvents()):this.room.getPendingEvents():[]},d.prototype.getLiveTimeline=function(){return this._liveTimeline},d.prototype.eventIdToTimeline=function(e){return this._eventIdToTimeline[e]},d.prototype.replaceEventId=function(e,t){const n=this._eventIdToTimeline[e];n&&(delete this._eventIdToTimeline[e],this._eventIdToTimeline[t]=n)},d.prototype.resetLiveTimeline=function(e,t){const n=!this._timelineSupport||!t,o=this._liveTimeline,r=n?o.forkLive(i.EventTimeline.FORWARDS):o.fork(i.EventTimeline.FORWARDS);n?(this._timelines=[r],this._eventIdToTimeline={}):this._timelines.push(r),t&&o.setPaginationToken(t,i.EventTimeline.FORWARDS),r.setPaginationToken(e,i.EventTimeline.BACKWARDS),this._liveTimeline=r,this.emit("Room.timelineReset",this.room,this,n)},d.prototype.getTimelineForEvent=function(e){const t=this._eventIdToTimeline[e];return void 0===t?null:t},d.prototype.findEventById=function(e){const t=this.getTimelineForEvent(e);if(t)return t.getEvents().find((function(t){return t.getId()==e}))},d.prototype.addTimeline=function(){if(!this._timelineSupport)throw new Error("timeline support is disabled. Set the 'timelineSupport' parameter to true when creating MatrixClient to enable it.");const e=new i.EventTimeline(this);return this._timelines.push(e),e},d.prototype.addEventsToTimeline=function(e,t,n,o){if(!n)throw new Error("'timeline' not specified for EventTimelineSet.addEventsToTimeline");if(!t&&n==this._liveTimeline)throw new Error("EventTimelineSet.addEventsToTimeline cannot be used for adding events to the live timeline - use Room.addLiveEvents instead");if(this._filter&&!(e=this._filter.filterRoomTimeline(e)).length)return;const r=t?i.EventTimeline.BACKWARDS:i.EventTimeline.FORWARDS,a=t?i.EventTimeline.FORWARDS:i.EventTimeline.BACKWARDS;let s=!1,c=!1;for(let o=0;o{this.aggregateRelations(e)}));const t=e.getRelation();if(!t)return;const n=t.event_id,o=t.rel_type,r=e.getType();let i=this._relations[n];i||(i=this._relations[n]={});let s=i[o];s||(s=i[o]={});let u,l=s[r];l||(l=s[r]=new c.Relations(o,r,this.room),u=this.findEventById(n)||this.room.getPendingEvent(n),u&&l.setTargetEvent(u)),l.addEvent(e)}},88910:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.EventTimeline=r;var o=n(26860);function r(e){this._eventTimelineSet=e,this._roomId=e.room?e.room.roomId:null,this._events=[],this._baseIndex=0,this._startState=new o.RoomState(this._roomId),this._startState.paginationToken=null,this._endState=new o.RoomState(this._roomId),this._endState.paginationToken=null,this._prevTimeline=null,this._nextTimeline=null,this._paginationRequests={b:null,f:null},this._name=this._roomId+":"+(new Date).toISOString()}r.BACKWARDS="b",r.FORWARDS="f",r.prototype.initialiseState=function(e){if(this._events.length>0)throw new Error("Cannot initialise state after events are added");for(const t of e)Object.freeze(t);this._startState.setStateEvents(e),this._endState.setStateEvents(e)},r.prototype.forkLive=function(e){const t=this.getState(e),n=new r(this._eventTimelineSet);return n._startState=t.clone(),n._endState=t,this._endState=t.clone(),n},r.prototype.fork=function(e){const t=this.getState(e),n=new r(this._eventTimelineSet);return n._startState=t.clone(),n._endState=t.clone(),n},r.prototype.getRoomId=function(){return this._roomId},r.prototype.getFilter=function(){return this._eventTimelineSet.getFilter()},r.prototype.getTimelineSet=function(){return this._eventTimelineSet},r.prototype.getBaseIndex=function(){return this._baseIndex},r.prototype.getEvents=function(){return this._events},r.prototype.getState=function(e){if(e==r.BACKWARDS)return this._startState;if(e==r.FORWARDS)return this._endState;throw new Error("Invalid direction '"+e+"'")},r.prototype.getPaginationToken=function(e){return this.getState(e).paginationToken},r.prototype.setPaginationToken=function(e,t){this.getState(t).paginationToken=e},r.prototype.getNeighbouringTimeline=function(e){if(e==r.BACKWARDS)return this._prevTimeline;if(e==r.FORWARDS)return this._nextTimeline;throw new Error("Invalid direction '"+e+"'")},r.prototype.setNeighbouringTimeline=function(e,t){if(this.getNeighbouringTimeline(t))throw new Error("timeline already has a neighbouring timeline - cannot reset neighbour (direction: "+t+")");if(t==r.BACKWARDS)this._prevTimeline=e;else{if(t!=r.FORWARDS)throw new Error("Invalid direction '"+t+"'");this._nextTimeline=e}this.setPaginationToken(null,t)},r.prototype.addEvent=function(e,t){const n=t?this._startState:this._endState,o=this.getTimelineSet();let i;o.room&&o.room.getUnfilteredTimelineSet()===o&&(r.setEventMetadata(e,n,t),e.isState()&&(n.setStateEvents([e]),e.sender&&("m.room.member"!==e.getType()||t)||r.setEventMetadata(e,n,t))),i=t?0:this._events.length,this._events.splice(i,0,e),t&&this._baseIndex++},r.setEventMetadata=function(e,t,n){e.sender=t.getSentinelMember(e.getSender()),"m.room.member"===e.getType()&&(e.target=t.getSentinelMember(e.getStateKey())),e.isState()&&n&&(e.forwardLooking=!1)},r.prototype.removeEvent=function(e){for(let t=this._events.length-1;t>=0;t--){const n=this._events[t];if(n.getId()==e)return this._events.splice(t,1),t{"use strict";var o=n(20862);Object.defineProperty(t,"__esModule",{value:!0}),t.MatrixEvent=t.EventStatus=void 0;var r=n(17187),i=o(n(3102)),a=n(7434);t.EventStatus={NOT_SENT:"not_sent",ENCRYPTING:"encrypting",SENDING:"sending",QUEUED:"queued",SENT:"sent",CANCELLED:"cancelled"};const s={};function u(e){return s[e]||(s[e]=e),s[e]}const c=function(e){["state_key","type","sender","room_id","membership"].forEach((t=>{e[t]&&(e[t]=u(e[t]))})),["membership","avatar_url","displayname"].forEach((t=>{e.content&&e.content[t]&&(e.content[t]=u(e.content[t]))})),["rel_type"].forEach((t=>{e.content&&e.content["m.relates_to"]&&e.content["m.relates_to"][t]&&(e.content["m.relates_to"][t]=u(e.content["m.relates_to"][t]))})),this.event=e||{},this.sender=null,this.target=null,this.status=null,this.error=null,this.forwardLooking=!0,this._pushActions=null,this._replacingEvent=null,this._localRedactionEvent=null,this._isCancelled=!1,this._clearEvent={},this._senderCurve25519Key=null,this._claimedEd25519Key=null,this._forwardingCurve25519KeyChain=[],this._untrusted=null,this._decryptionPromise=null,this._retryDecryption=!1,this.verificationRequest=null,this._txnId=e.txn_id||null,this._localTimestamp=Date.now()-this.getAge()};t.MatrixEvent=c,i.inherits(c,r.EventEmitter),i.extend(c.prototype,{getId:function(){return this.event.event_id},getSender:function(){return this.event.sender||this.event.user_id},getType:function(){return this._clearEvent.type||this.event.type},getWireType:function(){return this.event.type},getRoomId:function(){return this.event.room_id},getTs:function(){return this.event.origin_server_ts},getDate:function(){return this.event.origin_server_ts?new Date(this.event.origin_server_ts):null},getOriginalContent:function(){return this._localRedactionEvent?{}:this._clearEvent.content||this.event.content||{}},getContent:function(){return this._localRedactionEvent?{}:this._replacingEvent?this._replacingEvent.getContent()["m.new_content"]||{}:this.getOriginalContent()},getWireContent:function(){return this.event.content||{}},getPrevContent:function(){return this.getUnsigned().prev_content||this.event.prev_content||{}},getDirectionalContent:function(){return this.forwardLooking?this.getContent():this.getPrevContent()},getAge:function(){return this.getUnsigned().age||this.event.age},getLocalAge:function(){return Date.now()-this._localTimestamp},getStateKey:function(){return this.event.state_key},isState:function(){return void 0!==this.event.state_key},makeEncrypted:function(e,t,n,o){this._clearEvent={type:this.event.type,content:this.event.content},this.event.type=e,this.event.content=t,this._senderCurve25519Key=n,this._claimedEd25519Key=o},isBeingDecrypted:function(){return null!=this._decryptionPromise},isDecryptionFailure:function(){return this._clearEvent&&this._clearEvent.content&&"m.bad.encrypted"===this._clearEvent.content.msgtype},shouldAttemptDecryption:function(){return this.isEncrypted()&&!this.isBeingDecrypted()&&null===this.getClearContent()},attemptDecryption:async function(e,t={}){if("boolean"==typeof t&&(t={isRetry:t}),!this.isEncrypted())throw new Error("Attempt to decrypt event which isn't encrypted");if(this._clearEvent&&this._clearEvent.content&&"m.bad.encrypted"!==this._clearEvent.content.msgtype)throw new Error("Attempt to decrypt event which has already been decrypted");return this._decryptionPromise?(a.logger.log(`Event ${this.getId()} already being decrypted; queueing a retry`),this._retryDecryption=!0,this._decryptionPromise):(this._decryptionPromise=this._decryptionLoop(e,t),this._decryptionPromise)},cancelAndResendKeyRequest:function(e,t){const n=this.getWireContent();return e.requestRoomKey({algorithm:n.algorithm,room_id:this.getRoomId(),session_id:n.session_id,sender_key:n.sender_key},this.getKeyRequestRecipients(t),!0)},getKeyRequestRecipients:function(e){const t=this.getWireContent(),n=[{userId:e,deviceId:"*"}],o=this.getSender();return o!==e&&n.push({userId:o,deviceId:t.device_id}),n},_decryptionLoop:async function(e,t={}){for(await Promise.resolve();;){let n,o;this._retryDecryption=!1;try{e?(n=await e.decryptEvent(this),!0===t.isRetry&&a.logger.info(`Decrypted event on retry (id=${this.getId()})`)):n=this._badEncryptedMessage("Encryption not enabled")}catch(e){if("DecryptionError"!==e.name){const n=t.isRetry?"re":"";return a.logger.error(`Error ${n}decrypting event (id=${this.getId()}): ${e.stack||e}`),this._decryptionPromise=null,void(this._retryDecryption=!1)}if(o=e,this._retryDecryption){a.logger.log(`Got error decrypting event (id=${this.getId()}: ${e}), but retrying`);continue}a.logger.warn(`Error decrypting event (id=${this.getId()}): ${e.detailedString}`),n=this._badEncryptedMessage(e.message)}return this._decryptionPromise=null,this._retryDecryption=!1,this._setClearData(n),this.setPushActions(null),void(!1!==t.emit&&this.emit("Event.decrypted",this,o))}},_badEncryptedMessage:function(e){return{clearEvent:{type:"m.room.message",content:{msgtype:"m.bad.encrypted",body:"** Unable to decrypt: "+e+" **"}}}},_setClearData:function(e){this._clearEvent=e.clearEvent,this._senderCurve25519Key=e.senderCurve25519Key||null,this._claimedEd25519Key=e.claimedEd25519Key||null,this._forwardingCurve25519KeyChain=e.forwardingCurve25519KeyChain||[],this._untrusted=e.untrusted||!1},getClearContent:function(){const e=this._clearEvent;return e&&e.content?e.content:null},isEncrypted:function(){return!this.isState()&&"m.room.encrypted"===this.event.type},getSenderKey:function(){return this._senderCurve25519Key},getKeysClaimed:function(){return{ed25519:this._claimedEd25519Key}},getClaimedEd25519Key:function(){return this._claimedEd25519Key},getForwardingCurve25519KeyChain:function(){return this._forwardingCurve25519KeyChain},isKeySourceUntrusted:function(){return this._untrusted},getUnsigned:function(){return this.event.unsigned||{}},unmarkLocallyRedacted:function(){const e=this._localRedactionEvent;return this._localRedactionEvent=null,this.event.unsigned&&(this.event.unsigned.redacted_because=null),!!e},markLocallyRedacted:function(e){this._localRedactionEvent||(this.emit("Event.beforeRedaction",this,e),this._localRedactionEvent=e,this.event.unsigned||(this.event.unsigned={}),this.event.unsigned.redacted_because=e.event)},makeRedacted:function(e){if(!e.event)throw new Error("invalid redaction_event in makeRedacted");let t;for(t in this._localRedactionEvent=null,this.emit("Event.beforeRedaction",this,e),this._replacingEvent=null,this.event.unsigned||(this.event.unsigned={}),this.event.unsigned.redacted_because=e.event,this.event)this.event.hasOwnProperty(t)&&(l[t]||delete this.event[t]);const n=d[this.getType()]||{},o=this.getContent();for(t in o)o.hasOwnProperty(t)&&(n[t]||delete o[t])},isRedacted:function(){return Boolean(this.getUnsigned().redacted_because)},isRedaction:function(){return"m.room.redaction"===this.getType()},getRedactionEvent:function(){return this.isRedacted()?this._clearEvent.unsigned?this._clearEvent.unsigned.redacted_because:this.event.unsigned.redacted_because?this.event.unsigned.redacted_because:{}:null},getPushActions:function(){return this._pushActions},setPushActions:function(e){this._pushActions=e},handleRemoteEcho:function(e){const t=this.getUnsigned(),n=this.getId();this.event=e,t.redacted_because&&(this.event.unsigned||(this.event.unsigned={}),this.event.unsigned.redacted_because=t.redacted_because),this.setStatus(null),this.getId()!==n&&this.emit("Event.localEventIdReplaced",this)},isSending(){return!!this.status},setStatus(e){this.status=e,this.emit("Event.status",this,e)},replaceLocalEventId(e){this.event.event_id=e,this.emit("Event.localEventIdReplaced",this)},isRelation(e){const t=this.getWireContent(),n=t&&t["m.relates_to"];return n&&n.rel_type&&n.event_id&&(e&&n.rel_type===e||!e)},getRelation(){return this.isRelation()?this.getWireContent()["m.relates_to"]:null},makeReplaced(e){this.isRedacted()&&e||this._replacingEvent!==e&&(this._replacingEvent=e,this.emit("Event.replaced",this))},getAssociatedStatus(){return this._replacingEvent?this._replacingEvent.status:this._localRedactionEvent?this._localRedactionEvent.status:this.status},getServerAggregatedRelation(e){const t=this.getUnsigned()["m.relations"];if(t)return t[e]},replacingEventId(){const e=this.getServerAggregatedRelation("m.replace");return e?e.event_id:this._replacingEvent?this._replacingEvent.getId():void 0},replacingEvent(){return this._replacingEvent},replacingEventDate(){const e=this.getServerAggregatedRelation("m.replace");if(e){const t=e.origin_server_ts;if(Number.isFinite(t))return new Date(t)}else if(this._replacingEvent)return this._replacingEvent.getDate()},localRedactionEvent(){return this._localRedactionEvent},getAssociatedId(){const e=this.getRelation();return e?e.event_id:this.isRedaction()?this.event.redacts:void 0},hasAssocation(){return!!this.getAssociatedId()},updateAssociatedId(e){const t=this.getRelation();t?t.event_id=e:this.isRedaction()&&(this.event.redacts=e)},flagCancelled(e=!0){this._isCancelled=e},isCancelled(){return this._isCancelled},toJSON(){const e={type:this.getType(),sender:this.getSender(),content:this.getContent(),event_id:this.getId(),origin_server_ts:this.getTs(),unsigned:this.getUnsigned(),room_id:this.getRoomId()};return this.isRedaction()&&(e.redacts=this.event.redacts),this.isEncrypted()?{decrypted:e,encrypted:this.event}:e},setVerificationRequest:function(e){this.verificationRequest=e},setTxnId(e){this._txnId=e},getTxnId(){return this._txnId}});const l=["event_id","type","room_id","user_id","sender","state_key","prev_state","content","unsigned","origin_server_ts"].reduce((function(e,t){return e[t]=1,e}),{}),d={"m.room.member":{membership:1},"m.room.create":{creator:1},"m.room.join_rules":{join_rule:1},"m.room.power_levels":{ban:1,events:1,events_default:1,kick:1,redact:1,state_default:1,users:1,users_default:1},"m.room.aliases":{aliases:1}}},70142:(e,t,n)=>{"use strict";var o=n(20862);Object.defineProperty(t,"__esModule",{value:!0}),t.Group=a;var r=o(n(3102)),i=n(17187);function a(e){this.groupId=e,this.name=null,this.avatarUrl=null,this.myMembership=null,this.inviter=null}r.inherits(a,i.EventEmitter),a.prototype.setProfile=function(e,t){this.name===e&&this.avatarUrl===t||(this.name=e||this.groupId,this.avatarUrl=t,this.emit("Group.profile",this))},a.prototype.setMyMembership=function(e){this.myMembership!==e&&(this.myMembership=e,this.emit("Group.myMembership",this))},a.prototype.setInviter=function(e){this.inviter=e}},49690:(e,t,n)=>{"use strict";var o=n(95318);Object.defineProperty(t,"__esModule",{value:!0}),t.Relations=void 0;var r=o(n(59713)),i=n(17187),a=n(24369),s=n(7434);class u extends i.EventEmitter{constructor(e,t,n){super(),(0,r.default)(this,"_onEventStatus",((e,t)=>{e.isSending()?t===a.EventStatus.CANCELLED&&(e.removeListener("Event.status",this._onEventStatus),this._removeEvent(e)):e.removeListener("Event.status",this._onEventStatus)})),(0,r.default)(this,"_onBeforeRedaction",(async e=>{if(this._relations.has(e)){if(this._relations.delete(e),"m.annotation"===this.relationType)this._removeAnnotationFromAggregation(e);else if("m.replace"===this.relationType&&this._targetEvent){const e=await this.getLastReplacement();this._targetEvent.makeReplaced(e)}e.removeListener("Event.beforeRedaction",this._onBeforeRedaction),this.emit("Relations.redaction",e)}})),this.relationType=e,this.eventType=t,this._relationEventIds=new Set,this._relations=new Set,this._annotationsByKey={},this._annotationsBySender={},this._sortedAnnotationsByKey=[],this._targetEvent=null,this._room=n,this._creationEmitted=!1}async addEvent(e){if(this._relationEventIds.has(e.getId()))return;const t=e.getRelation();if(!t)return void s.logger.error("Event must have relation info");const n=t.rel_type,o=e.getType();if(this.relationType===n&&this.eventType===o){if(e.isSending()&&e.on("Event.status",this._onEventStatus),this._relations.add(e),this._relationEventIds.add(e.getId()),"m.annotation"===this.relationType)this._addAnnotationToAggregation(e);else if("m.replace"===this.relationType&&this._targetEvent){const e=await this.getLastReplacement();this._targetEvent.makeReplaced(e)}e.on("Event.beforeRedaction",this._onBeforeRedaction),this.emit("Relations.add",e),this._maybeEmitCreated()}else s.logger.error("Event relation info doesn't match this container")}async _removeEvent(e){if(!this._relations.has(e))return;const t=e.getRelation();if(!t)return void s.logger.error("Event must have relation info");const n=t.rel_type,o=e.getType();if(this.relationType===n&&this.eventType===o){if(this._relations.delete(e),"m.annotation"===this.relationType)this._removeAnnotationFromAggregation(e);else if("m.replace"===this.relationType&&this._targetEvent){const e=await this.getLastReplacement();this._targetEvent.makeReplaced(e)}this.emit("Relations.remove",e)}else s.logger.error("Event relation info doesn't match this container")}getRelations(){return[...this._relations]}_addAnnotationToAggregation(e){const{key:t}=e.getRelation();if(!t)return;let n=this._annotationsByKey[t];n||(n=this._annotationsByKey[t]=new Set,this._sortedAnnotationsByKey.push([t,n])),n.add(e),this._sortedAnnotationsByKey.sort(((e,t)=>{const n=e[1];return t[1].size-n.size}));const o=e.getSender();let r=this._annotationsBySender[o];r||(r=this._annotationsBySender[o]=new Set),r.add(e)}_removeAnnotationFromAggregation(e){const{key:t}=e.getRelation();if(!t)return;const n=this._annotationsByKey[t];n&&(n.delete(e),this._sortedAnnotationsByKey.sort(((e,t)=>{const n=e[1];return t[1].size-n.size})));const o=e.getSender(),r=this._annotationsBySender[o];r&&r.delete(e)}getSortedAnnotationsByKey(){return"m.annotation"!==this.relationType?null:this._sortedAnnotationsByKey}getAnnotationsBySender(){return"m.annotation"!==this.relationType?null:this._annotationsBySender}async getLastReplacement(){if("m.replace"!==this.relationType)return null;if(!this._targetEvent)return null;const e=this._targetEvent.getServerAggregatedRelation("m.replace"),t=e&&e.origin_server_ts,n=this.getRelations().reduce(((e,n)=>n.getSender()!==this._targetEvent.getSender()||t&&t>n.getTs()||e&&e.getTs()>n.getTs()?e:n),null);return null!=n&&n.shouldAttemptDecryption()?await n.attemptDecryption(this._room._client._crypto):null!=n&&n.isBeingDecrypted()&&await n._decryptionPromise,n}async setTargetEvent(e){if(!this._targetEvent){if(this._targetEvent=e,"m.replace"===this.relationType){const e=await this.getLastReplacement();e&&this._targetEvent.makeReplaced(e)}this._maybeEmitCreated()}}_maybeEmitCreated(){this._creationEmitted||this._targetEvent&&this._relations.size&&(this._creationEmitted=!0,this._targetEvent.emit("Event.relationsCreated",this.relationType,this.eventType))}}t.Relations=u},32848:(e,t,n)=>{"use strict";var o=n(20862);Object.defineProperty(t,"__esModule",{value:!0}),t.RoomMember=s;var r=n(17187),i=n(73667),a=o(n(3102));function s(e,t){this.roomId=e,this.userId=t,this.typing=!1,this.name=t,this.rawDisplayName=t,this.powerLevel=0,this.powerLevelNorm=0,this.user=null,this.membership=null,this.events={member:null},this._isOutOfBand=!1,this._updateModifiedTime()}a.inherits(s,r.EventEmitter),s.prototype.markOutOfBand=function(){this._isOutOfBand=!0},s.prototype.isOutOfBand=function(){return this._isOutOfBand},s.prototype.setMembershipEvent=function(e,t){if("m.room.member"!==e.getType())return;this._isOutOfBand=!1,this.events.member=e;const n=this.membership;this.membership=e.getDirectionalContent().membership;const o=this.name;this.name=function(e,t,n){if(!t||t===e)return e;if(!a.removeHiddenChars(t))return e;if(!n)return t;let o=u.test(t);return o||(o=c.test(t)),o||(o=n.getUserIdsWithDisplayName(t).some((t=>t!==e))),o?t+" ("+e+")":t}(this.userId,e.getDirectionalContent().displayname,t),this.rawDisplayName=e.getDirectionalContent().displayname||this.userId,n!==this.membership&&(this._updateModifiedTime(),this.emit("RoomMember.membership",e,this,n)),o!==this.name&&(this._updateModifiedTime(),this.emit("RoomMember.name",e,this,o))},s.prototype.setPowerLevelEvent=function(e){if("m.room.power_levels"!==e.getType())return;const t=e.getDirectionalContent();let n=t.users_default||0;const o=t.users||{};Object.values(o).forEach((function(e){n=Math.max(n,e)}));const r=this.powerLevel,i=this.powerLevelNorm;void 0!==o[this.userId]?this.powerLevel=o[this.userId]:void 0!==t.users_default?this.powerLevel=t.users_default:this.powerLevel=0,this.powerLevelNorm=0,n>0&&(this.powerLevelNorm=100*this.powerLevel/n),r===this.powerLevel&&i===this.powerLevelNorm||(this._updateModifiedTime(),this.emit("RoomMember.powerLevel",e,this))},s.prototype.setTypingEvent=function(e){if("m.typing"!==e.getType())return;const t=this.typing;this.typing=!1;const n=e.getContent().user_ids;Array.isArray(n)&&(-1!==n.indexOf(this.userId)&&(this.typing=!0),t!==this.typing&&(this._updateModifiedTime(),this.emit("RoomMember.typing",e,this)))},s.prototype._updateModifiedTime=function(){this._modified=Date.now()},s.prototype.getLastModifiedTime=function(){return this._modified},s.prototype.isKicked=function(){return"leave"===this.membership&&this.events.member.getSender()!==this.events.member.getStateKey()},s.prototype.getDMInviter=function(){if(this.events.member){const e=this.events.member;let t=e.getContent(),n=e.getSender();if("join"===t.membership&&(t=e.getPrevContent(),n=e.getUnsigned().prev_sender),"invite"===t.membership&&t.is_direct)return n}},s.prototype.getAvatarUrl=function(e,t,n,o,r,a){void 0===r&&(r=!0);const s=this.getMxcAvatarUrl();if(!s&&!r)return null;return(0,i.getHttpUriForMxc)(e,s,t,n,o,a)||null},s.prototype.getMxcAvatarUrl=function(){return this.events.member?this.events.member.getDirectionalContent().avatar_url:this.user?this.user.avatarUrl:null};const u=/@.+:.+/,c=/[\u200E\u200F\u202A-\u202F]/},26860:(e,t,n)=>{"use strict";var o=n(20862);Object.defineProperty(t,"__esModule",{value:!0}),t.RoomState=c;var r=n(17187),i=n(32848),a=n(7434),s=o(n(3102)),u=n(42481);function c(e,t){this.roomId=e,this.members={},this.events=new Map,this.paginationToken=null,this._sentinels={},this._updateModifiedTime(),this._displayNameToUserIds={},this._userIdsToDisplayNames={},this._tokenToInvite={},this._joinedMemberCount=null,this._summaryJoinedMemberCount=null,this._invitedMemberCount=null,this._summaryInvitedMemberCount=null,t||(t={status:1}),this._oobMemberFlags=t}function l(e,t,n){const o=e._userIdsToDisplayNames[t];if(delete e._userIdsToDisplayNames[t],o){const n=s.removeHiddenChars(o),r=e._displayNameToUserIds[n];if(r){const o=r.filter((e=>e!==t));e._displayNameToUserIds[n]=o}}e._userIdsToDisplayNames[t]=n;const r=n&&s.removeHiddenChars(n);r&&(e._displayNameToUserIds[r]||(e._displayNameToUserIds[r]=[]),e._displayNameToUserIds[r].push(t))}s.inherits(c,r.EventEmitter),c.prototype.getJoinedMemberCount=function(){return null!==this._summaryJoinedMemberCount?this._summaryJoinedMemberCount:(null===this._joinedMemberCount&&(this._joinedMemberCount=this.getMembers().reduce(((e,t)=>"join"===t.membership?e+1:e),0)),this._joinedMemberCount)},c.prototype.setJoinedMemberCount=function(e){this._summaryJoinedMemberCount=e},c.prototype.getInvitedMemberCount=function(){return null!==this._summaryInvitedMemberCount?this._summaryInvitedMemberCount:(null===this._invitedMemberCount&&(this._invitedMemberCount=this.getMembers().reduce(((e,t)=>"invite"===t.membership?e+1:e),0)),this._invitedMemberCount)},c.prototype.setInvitedMemberCount=function(e){this._summaryInvitedMemberCount=e},c.prototype.getMembers=function(){return Object.values(this.members)},c.prototype.getMembersExcept=function(e){return Object.values(this.members).filter((t=>!e.includes(t.userId)))},c.prototype.getMember=function(e){return this.members[e]||null},c.prototype.getSentinelMember=function(e){if(!e)return null;let t=this._sentinels[e];if(void 0===t){t=new i.RoomMember(this.roomId,e);const n=this.members[e];n&&t.setMembershipEvent(n.events.member,this),this._sentinels[e]=t}return t},c.prototype.getStateEvents=function(e,t){if(!this.events.has(e))return void 0===t?[]:null;if(void 0===t)return Array.from(this.events.get(e).values());return this.events.get(e).get(t)||null},c.prototype.clone=function(){const e=new c(this.roomId,this._oobMemberFlags),t=this._oobMemberFlags.status;return this._oobMemberFlags.status=1,Array.from(this.events.values()).forEach((t=>{e.setStateEvents(Array.from(t.values()))})),this._oobMemberFlags.status=t,null!==this._summaryInvitedMemberCount&&e.setInvitedMemberCount(this.getInvitedMemberCount()),null!==this._summaryJoinedMemberCount&&e.setJoinedMemberCount(this.getJoinedMemberCount()),3==this._oobMemberFlags.status&&this.getMembers().forEach((t=>{t.isOutOfBand()&&e.getMember(t.userId).markOutOfBand()})),e},c.prototype.setUnknownStateEvents=function(e){const t=e.filter((e=>!this.events.has(e.getType())||!this.events.get(e.getType()).has(e.getStateKey())));this.setStateEvents(t)},c.prototype.setStateEvents=function(e){const t=this;this._updateModifiedTime(),e.forEach((function(e){if(e.getRoomId()!==t.roomId)return;if(!e.isState())return;const n=t._getStateEventMatching(e);t._setStateEvent(e),"m.room.member"===e.getType()&&(l(t,e.getStateKey(),e.getContent().displayname),function(e,t){if(!t.getContent().third_party_invite)return;const n=(t.getContent().third_party_invite.signed||{}).token;n&&e.getStateEvents("m.room.third_party_invite",n)&&(e._tokenToInvite[n]=t)}(t,e)),t.emit("RoomState.events",e,t,n)})),e.forEach((function(e){if(e.getRoomId()===t.roomId&&e.isState())if("m.room.member"===e.getType()){const n=e.getStateKey();"leave"!==e.getContent().membership&&"ban"!==e.getContent().membership||(e.getContent().avatar_url=e.getContent().avatar_url||e.getPrevContent().avatar_url,e.getContent().displayname=e.getContent().displayname||e.getPrevContent().displayname);const o=t._getOrCreateMember(n,e);o.setMembershipEvent(e,t),t._updateMember(o),t.emit("RoomState.members",e,t,o)}else"m.room.power_levels"===e.getType()&&(Object.values(t.members).forEach((function(n){const o=n.getLastModifiedTime();n.setPowerLevelEvent(e),o!==n.getLastModifiedTime()&&t.emit("RoomState.members",e,t,n)})),t._sentinels={})}))},c.prototype._getOrCreateMember=function(e,t){let n=this.members[e];return n||(n=new i.RoomMember(this.roomId,e),this.members[e]=n,this.emit("RoomState.newMember",t,this,n)),n},c.prototype._setStateEvent=function(e){this.events.has(e.getType())||this.events.set(e.getType(),new Map),this.events.get(e.getType()).set(e.getStateKey(),e)},c.prototype._getStateEventMatching=function(e){return this.events.has(e.getType())?this.events.get(e.getType()).get(e.getStateKey()):null},c.prototype._updateMember=function(e){const t=this.getStateEvents("m.room.power_levels","");t&&e.setPowerLevelEvent(t),delete this._sentinels[e.userId],this.members[e.userId]=e,this._joinedMemberCount=null,this._invitedMemberCount=null},c.prototype.needsOutOfBandMembers=function(){return 1===this._oobMemberFlags.status},c.prototype.markOutOfBandMembersStarted=function(){1===this._oobMemberFlags.status&&(this._oobMemberFlags.status=2)},c.prototype.markOutOfBandMembersFailed=function(){2===this._oobMemberFlags.status&&(this._oobMemberFlags.status=1)},c.prototype.clearOutOfBandMembers=function(){let e=0;Object.keys(this.members).forEach((t=>{this.members[t].isOutOfBand()&&(++e,delete this.members[t])})),a.logger.log(`LL: RoomState removed ${e} members...`),this._oobMemberFlags.status=1},c.prototype.setOutOfBandMembers=function(e){a.logger.log(`LL: RoomState about to set ${e.length} OOB members ...`),2===this._oobMemberFlags.status&&(a.logger.log("LL: RoomState put in OOB_STATUS_FINISHED state ..."),this._oobMemberFlags.status=3,e.forEach((e=>this._setOutOfBandMember(e))))},c.prototype._setOutOfBandMember=function(e){if("m.room.member"!==e.getType())return;const t=e.getStateKey(),n=this.getMember(t);if(n&&!n.isOutOfBand())return;const o=this._getOrCreateMember(t,e);o.setMembershipEvent(e,this),o.markOutOfBand(),l(this,o.userId,o.name),this._setStateEvent(e),this._updateMember(o),this.emit("RoomState.members",e,this,o)},c.prototype.setTypingEvent=function(e){Object.values(this.members).forEach((function(t){t.setTypingEvent(e)}))},c.prototype.getInviteForThreePidToken=function(e){return this._tokenToInvite[e]||null},c.prototype._updateModifiedTime=function(){this._modified=Date.now()},c.prototype.getLastModifiedTime=function(){return this._modified},c.prototype.getUserIdsWithDisplayName=function(e){return this._displayNameToUserIds[s.removeHiddenChars(e)]||[]},c.prototype.maySendRedactionForEvent=function(e,t){const n=this.getMember(t);if(!n||"leave"===n.membership)return!1;if(e.status||e.isRedacted())return!1;const o=this.maySendEvent("m.room.redaction",t);return e.getSender()===t?o:this._hasSufficientPowerLevelFor("redact",n.powerLevel)},c.prototype._hasSufficientPowerLevelFor=function(e,t){const n=this.getStateEvents("m.room.power_levels","");let o={};n&&(o=n.getContent());let r=50;return s.isNumber(o[e])&&(r=o[e]),t>=r},c.prototype.maySendMessage=function(e){return this._maySendEventOfType("m.room.message",e,!1)},c.prototype.maySendEvent=function(e,t){return this._maySendEventOfType(e,t,!1)},c.prototype.mayClientSendStateEvent=function(e,t){return!t.isGuest()&&this.maySendStateEvent(e,t.credentials.userId)},c.prototype.maySendStateEvent=function(e,t){return this._maySendEventOfType(e,t,!0)},c.prototype._maySendEventOfType=function(e,t,n){const o=this.getStateEvents("m.room.power_levels","");let r,i={},a=0,s=0,u=0;if(o){r=o.getContent(),i=r.events||{},a=Number.isFinite(r.state_default)?r.state_default:50;const e=r.users&&r.users[t];Number.isFinite(e)?u=e:Number.isFinite(r.users_default)&&(u=r.users_default),Number.isFinite(r.events_default)&&(s=r.events_default)}let c=n?a:s;return Number.isFinite(i[e])&&(c=i[e]),u>=c},c.prototype.mayTriggerNotifOfType=function(e,t){const n=this.getMember(t);if(!n)return!1;const o=this.getStateEvents("m.room.power_levels","");let r=50;return o&&o.getContent()&&o.getContent().notifications&&s.isNumber(o.getContent().notifications[e])&&(r=o.getContent().notifications[e]),n.powerLevel>=r},c.prototype.getJoinRule=function(){const e=this.getStateEvents(u.EventType.RoomJoinRules,"");return(e?e.getContent():{}).join_rule||"invite"}},65205:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.RoomSummary=function(e,t){this.roomId=e,this.info=t}},27366:(e,t,n)=>{"use strict";var o=n(20862),r=n(95318);Object.defineProperty(t,"__esModule",{value:!0}),t.Room=v;var i=r(n(59713)),a=n(17187),s=n(33705),u=n(88910),c=n(73667),l=o(n(3102)),d=n(24369),h=n(32848),p=n(65205),f=n(7434),g=n(20771),m=n(42481);function _(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function F(e){for(var t=1;t{const t=new d.MatrixEvent(e);"m.room.encrypted"===t.getType()&&await t.attemptDecryption(this._client._crypto),t.setStatus(d.EventStatus.NOT_SENT),this.addPendingEvent(t,t.getTxnId())}))}this._blacklistUnverifiedDevices=null,this._selfMembership=null,this._summaryHeroes=null,this._opts.lazyLoadMembers?this._membersPromise=null:this._membersPromise=Promise.resolve(),this.getTypeWarning=!1,this.getVersionWarning=!1}function w(e){return`mx_pending_events_${e}`}l.inherits(v,a.EventEmitter),v.prototype.decryptCriticalEvents=function(){const e=this.getEventReadUpTo(this._client.getUserId(),!0),t=this.getLiveTimeline().getEvents(),n=t.findIndex((t=>t.event.event_id===e)),o=t.slice(n).filter((e=>e.shouldAttemptDecryption())).reverse().map((e=>e.attemptDecryption(this._client._crypto,{isRetry:!0})));return Promise.allSettled(o)},v.prototype.decryptAllEvents=function(){const e=this.getUnfilteredTimelineSet().getLiveTimeline().getEvents().filter((e=>e.shouldAttemptDecryption())).reverse().map((e=>e.attemptDecryption(this._client._crypto,{isRetry:!0})));return Promise.allSettled(e)},v.prototype.getVersion=function(){const e=this.currentState.getStateEvents("m.room.create","");if(!e)return this.getVersionWarning||(f.logger.warn("[getVersion] Room "+this.roomId+" does not have an m.room.create event"),this.getVersionWarning=!0),"1";const t=e.getContent().room_version;return void 0===t?"1":t},v.prototype.shouldUpgradeToVersion=function(){return y.includes(this.getVersion())?null:"6"},v.prototype.getRecommendedVersion=async function(){let e=(await this._client.getCapabilities())["m.room_versions"];if(!e){e={default:"6",available:{}};for(const t of y)e.available[t]="stable"}let t=this._checkVersionAgainstCapability(e);if(t.urgent&&t.needsUpgrade){if(f.logger.warn("Refreshing room version capability because the server looks to be supporting a newer room version we don't know about."),e=(await this._client.getCapabilities(!0))["m.room_versions"],!e)return f.logger.warn("No room version capability - assuming upgrade required."),t;t=this._checkVersionAgainstCapability(e)}return t},v.prototype._checkVersionAgainstCapability=function(e){const t=this.getVersion();f.logger.log(`[${this.roomId}] Current version: ${t}`),f.logger.log(`[${this.roomId}] Version capability: `,e);const n={version:t,needsUpgrade:!1,urgent:!1};return t===e.default||Object.keys(e.available).filter((t=>"stable"===e.available[t])).includes(t)||(n.version=e.default,n.needsUpgrade=!0,n.urgent=!!this.getVersion().match(/^[0-9]+[0-9.]*$/g),n.urgent?f.logger.warn(`URGENT upgrade required on ${this.roomId}`):f.logger.warn(`Non-urgent upgrade required on ${this.roomId}`)),n},v.prototype.userMayUpgradeRoom=function(e){return this.currentState.maySendStateEvent("m.room.tombstone",e)},v.prototype.getPendingEvents=function(){if("detached"!==this._opts.pendingEventOrdering)throw new Error("Cannot call getPendingEvents with pendingEventOrdering == "+this._opts.pendingEventOrdering);return this._pendingEventList},v.prototype.removePendingEvent=function(e){if("detached"!==this._opts.pendingEventOrdering)throw new Error("Cannot call removePendingEvent with pendingEventOrdering == "+this._opts.pendingEventOrdering);const t=l.removeElement(this._pendingEventList,(function(t){return t.getId()==e}),!1);return this._savePendingEvents(),t},v.prototype.hasPendingEvent=function(e){return"detached"===this._opts.pendingEventOrdering&&this._pendingEventList.some((t=>t.getId()===e))},v.prototype.getPendingEvent=function(e){return"detached"!==this._opts.pendingEventOrdering?null:this._pendingEventList.find((t=>t.getId()===e))},v.prototype.getLiveTimeline=function(){return this.getUnfilteredTimelineSet().getLiveTimeline()},v.prototype.getLastActiveTimestamp=function(){const e=this.getLiveTimeline().getEvents();return e.length?e[e.length-1].getTs():Number.MIN_SAFE_INTEGER},v.prototype.getMyMembership=function(){return this._selfMembership},v.prototype.getDMInviter=function(){if(this.myUserId){const e=this.getMember(this.myUserId);if(e)return e.getDMInviter()}if("invite"===this._selfMembership&&2==this.getInvitedAndJoinedMemberCount()&&this._summaryHeroes.length)return this._summaryHeroes[0]},v.prototype.guessDMUserId=function(){const e=this.getMember(this.myUserId);if(e){const t=e.getDMInviter();if(t)return t}if(Array.isArray(this._summaryHeroes)&&this._summaryHeroes.length)return this._summaryHeroes[0];const t=this.currentState.getMembers().find((e=>e.userId!==this.myUserId));return t?t.userId:this.myUserId},v.prototype.getAvatarFallbackMember=function(){if(this.getInvitedAndJoinedMemberCount()>2)return;const e=Array.isArray(this._summaryHeroes)&&this._summaryHeroes.length;if(e){const e=this._summaryHeroes.map((e=>this.getMember(e))).find((e=>!!e));if(e)return e}const t=this.currentState.getMembers();if(t.length<=2){const e=t.find((e=>e.userId!==this.myUserId));if(e)return e}if(e){const e=this._summaryHeroes.map((e=>this._client.getUser(e))).find((e=>!!e));if(e){const t=new h.RoomMember(this.roomId,e.userId);return t.user=e,t}}},v.prototype.updateMyMembership=function(e){const t=this._selfMembership;this._selfMembership=e,t!==e&&("leave"===e&&this._cleanupAfterLeaving(),this.emit("Room.myMembership",this,e,t))},v.prototype._loadMembersFromServer=async function(){const e=this._client.store.getSyncToken(),t=l.encodeParams({not_membership:"leave",at:e}),n=l.encodeUri("/rooms/$roomId/members?"+t,{$roomId:this.roomId}),o=this._client._http;return(await o.authedRequest(void 0,"GET",n)).chunk},v.prototype._loadMembers=async function(){let e=!1,t=await this._client.store.getOutOfBandMembers(this.roomId);return null===t&&(e=!0,t=await this._loadMembersFromServer(),f.logger.log(`LL: got ${t.length} members from server for room ${this.roomId}`)),{memberEvents:t.map(this._client.getEventMapper()),fromServer:e}},v.prototype.loadMembersIfNeeded=function(){if(this._membersPromise)return this._membersPromise;this.currentState.markOutOfBandMembersStarted();const e=this._loadMembers().then((e=>(this.currentState.setOutOfBandMembers(e.memberEvents),this._client.isCryptoEnabled()&&this._client.isRoomEncrypted(this.roomId)&&this._client._crypto.trackRoomDevices(this.roomId),e.fromServer))).catch((e=>{throw this._membersPromise=null,this.currentState.markOutOfBandMembersFailed(),e}));return e.then((e=>{if(e){const e=this.currentState.getMembers().filter((e=>e.isOutOfBand())).map((e=>e.events.member.event));return f.logger.log(`LL: telling store to write ${e.length} members for room ${this.roomId}`),this._client.store.setOutOfBandMembers(this.roomId,e).catch((e=>{f.logger.log("LL: storing OOB room members failed, oh well",e)}))}})).catch((e=>{f.logger.error(e)})),this._membersPromise=e,this._membersPromise},v.prototype.clearLoadedMembersIfNeeded=async function(){this._opts.lazyLoadMembers&&this._membersPromise&&(await this.loadMembersIfNeeded(),await this._client.store.clearOutOfBandMembers(this.roomId),this.currentState.clearOutOfBandMembers(),this._membersPromise=null)},v.prototype._cleanupAfterLeaving=function(){this.clearLoadedMembersIfNeeded().catch((e=>{f.logger.error(`error after clearing loaded members from room ${this.roomId} after leaving`),f.logger.log(e)}))},v.prototype.resetLiveTimeline=function(e,t){for(let n=0;ne.isUnverified())))return!0;return!1},v.prototype.getTimelineSets=function(){return this._timelineSets},v.prototype.getUnfilteredTimelineSet=function(){return this._timelineSets[0]},v.prototype.getTimelineForEvent=function(e){return this.getUnfilteredTimelineSet().getTimelineForEvent(e)},v.prototype.addTimeline=function(){return this.getUnfilteredTimelineSet().addTimeline()},v.prototype.findEventById=function(e){return this.getUnfilteredTimelineSet().findEventById(e)},v.prototype.getUnreadNotificationCount=function(e){return e=e||"total",this._notificationCounts[e]},v.prototype.setUnreadNotificationCount=function(e,t){this._notificationCounts[e]=t},v.prototype.setSummary=function(e){const t=e["m.heroes"],n=e["m.joined_member_count"],o=e["m.invited_member_count"];Number.isInteger(n)&&this.currentState.setJoinedMemberCount(n),Number.isInteger(o)&&this.currentState.setInvitedMemberCount(o),Array.isArray(t)&&(this._summaryHeroes=t.filter((e=>e!==this.myUserId)))},v.prototype.setBlacklistUnverifiedDevices=function(e){this._blacklistUnverifiedDevices=e},v.prototype.getBlacklistUnverifiedDevices=function(){return this._blacklistUnverifiedDevices},v.prototype.getAvatarUrl=function(e,t,n,o,r){const i=this.currentState.getStateEvents(m.EventType.RoomAvatar,"");if(void 0===r&&(r=!0),!i&&!r)return null;const a=i?i.getContent().url:null;return a?(0,c.getHttpUriForMxc)(e,a,t,n,o):null},v.prototype.getMxcAvatarUrl=function(){const e=this.currentState.getStateEvents(m.EventType.RoomAvatar,"");return e?e.getContent().url:null},v.prototype.getAliases=function(){const e=[],t=this.currentState.getStateEvents("m.room.aliases");if(t)for(let n=0;n"string"==typeof e&&"#"===e[0]&&!!e.endsWith(`:${o.getStateKey()}`)));Array.prototype.push.apply(e,t)}}return e},v.prototype.getCanonicalAlias=function(){const e=this.currentState.getStateEvents("m.room.canonical_alias","");return e&&e.getContent().alias||null},v.prototype.getAltAliases=function(){const e=this.currentState.getStateEvents("m.room.canonical_alias","");return e&&e.getContent().alt_aliases||[]},v.prototype.addEventsToTimeline=function(e,t,n,o){n.getTimelineSet().addEventsToTimeline(e,t,n,o)},v.prototype.getMember=function(e){return this.currentState.getMember(e)},v.prototype.getMembers=function(){return this.currentState.getMembers()},v.prototype.getJoinedMembers=function(){return this.getMembersWithMembership("join")},v.prototype.getJoinedMemberCount=function(){return this.currentState.getJoinedMemberCount()},v.prototype.getInvitedMemberCount=function(){return this.currentState.getInvitedMemberCount()},v.prototype.getInvitedAndJoinedMemberCount=function(){return this.getInvitedMemberCount()+this.getJoinedMemberCount()},v.prototype.getMembersWithMembership=function(e){return this.currentState.getMembers().filter((function(t){return t.membership===e}))},v.prototype.getEncryptionTargetMembers=async function(){await this.loadMembersIfNeeded();let e=this.getMembersWithMembership("join");return this.shouldEncryptForInvitedMembers()&&(e=e.concat(this.getMembersWithMembership("invite"))),e},v.prototype.shouldEncryptForInvitedMembers=function(){const e=this.currentState.getStateEvents("m.room.history_visibility","");return e&&e.getContent()&&"joined"!==e.getContent().history_visibility},v.prototype.getDefaultRoomName=function(e){return k(this,e,!0)},v.prototype.hasMembershipState=function(e,t){const n=this.getMember(e);return!!n&&n.membership===t},v.prototype.getOrCreateFilteredTimelineSet=function(e){if(this._filteredTimelineSets[e.filterId])return this._filteredTimelineSets[e.filterId];const t=Object.assign({filter:e},this._opts),n=new s.EventTimelineSet(this,t);this.reEmitter.reEmit(n,["Room.timeline","Room.timelineReset"]),this._filteredTimelineSets[e.filterId]=n,this._timelineSets.push(n);const o=this.getLiveTimeline();o.getEvents().forEach((function(e){n.addLiveEvent(e)}));let r=o;for(;r.getNeighbouringTimeline(u.EventTimeline.BACKWARDS);)r=r.getNeighbouringTimeline(u.EventTimeline.BACKWARDS);return n.getLiveTimeline().setPaginationToken(r.getPaginationToken(u.EventTimeline.BACKWARDS),u.EventTimeline.BACKWARDS),n},v.prototype.removeFilteredTimelineSet=function(e){const t=this._filteredTimelineSets[e.filterId];delete this._filteredTimelineSets[e.filterId];const n=this._timelineSets.indexOf(t);n>-1&&this._timelineSets.splice(n,1)},v.prototype._addLiveEvent=function(e,t,n){if(e.isRedaction()){const t=e.event.redacts,n=this.getUnfilteredTimelineSet().findEventById(t);n&&(n.makeRedacted(e),n.getStateKey()&&this.currentState.getStateEvents(n.getType(),n.getStateKey()).getId()===n.getId()&&this.currentState.setStateEvents([n]),this.emit("Room.redaction",e,this))}if(e.getUnsigned().transaction_id){const t=this._txnToEvent[e.getUnsigned().transaction_id];if(t)return void this._handleRemoteEcho(e,t)}for(let o=0;oe.status===d.EventStatus.NOT_SENT))&&(f.logger.warn("Setting event as NOT_SENT due to messages in the same state"),e.setStatus(d.EventStatus.NOT_SENT)),this._pendingEventList.push(e),this._savePendingEvents(),e.isRelation()&&this._aggregateNonLiveRelation(e),e.isRedaction()){const t=e.event.redacts;let n=this._pendingEventList&&this._pendingEventList.find((e=>e.getId()===t));n||(n=this.getUnfilteredTimelineSet().findEventById(t)),n&&(n.markLocallyRedacted(e),this.emit("Room.redaction",e,this))}}else for(let t=0;tF(F({},e.event),{},{txn_id:e.getTxnId()}))).filter((e=>{const t="m.room.encrypted"===e.type,n=this._client.isRoomEncrypted(this.roomId);return t||!n})),{store:t}=this._client._sessionStore;this._pendingEventList.length>0?t.setItem(w(this.roomId),JSON.stringify(e)):t.removeItem(w(this.roomId))}},v.prototype._aggregateNonLiveRelation=function(e){for(let t=0;t ${o} old status ${r}`),delete this._txnToEvent[e.getUnsigned().transaction_id],this._pendingEventList&&this.removePendingEvent(n),t.handleRemoteEcho(e.event);for(let e=0;e{const n=e.getMember(t);return n?n.name:t}));else{let n=e.currentState.getMembers().filter((e=>e.userId!==t&&("invite"===e.membership||"join"===e.membership)));n.sort(((e,t)=>e.userId.localeCompare(t.userId))),n=n.slice(0,5),i=n.map((e=>e.name))}if(r)return D(i,r);if("join"==e.getMyMembership()){const t=e.currentState.getStateEvents("m.room.third_party_invite");if(t&&t.length)return`Inviting ${D(t.map((e=>e.getContent().display_name)))}`}let a=i;return a.length||(a=e.currentState.getMembers().filter((e=>e.userId!==t&&"invite"!==e.membership&&"join"!==e.membership)).map((e=>e.name))),a.length?`Empty room (was ${D(a)})`:"Empty room"}function D(e,t=e.length+1){const n=t-1;return e.length?1===e.length&&n<=1?e[0]:2===e.length&&n<=2?`${e[0]} and ${e[1]}`:n>1?`${e[0]} and ${n} others`:`${e[0]} and 1 other`:"Empty room"}E[d.EventStatus.ENCRYPTING]=[d.EventStatus.SENDING,d.EventStatus.NOT_SENT],E[d.EventStatus.SENDING]=[d.EventStatus.ENCRYPTING,d.EventStatus.QUEUED,d.EventStatus.NOT_SENT,d.EventStatus.SENT],E[d.EventStatus.QUEUED]=[d.EventStatus.SENDING,d.EventStatus.CANCELLED],E[d.EventStatus.SENT]=[],E[d.EventStatus.NOT_SENT]=[d.EventStatus.SENDING,d.EventStatus.QUEUED,d.EventStatus.CANCELLED],E[d.EventStatus.CANCELLED]=[],v.prototype.updatePendingEvent=function(e,t,n){if(f.logger.log(`setting pendingEvent status to ${t} in ${e.getRoomId()} event ID ${e.getId()} -> ${n}`),t==d.EventStatus.SENT&&!n)throw new Error("updatePendingEvent called with status=SENT, but no new event id");if(t==d.EventStatus.SENT&&this.getUnfilteredTimelineSet().eventIdToTimeline(n))return;const o=e.status,r=e.getId();if(!o)throw new Error("updatePendingEventStatus called on an event which is not a local echo.");const i=E[o];if(!i||i.indexOf(t)<0)throw new Error("Invalid EventStatus transition "+o+"->"+t);if(e.setStatus(t),t==d.EventStatus.SENT){e.replaceLocalEventId(n);for(let e=0;ee.getId()===r));if(-1!==e){const[t]=this._pendingEventList.splice(e,1);t.isRedaction()&&this._revertRedactionLocalEcho(t)}}this.removeEvent(r)}this._savePendingEvents(),this.emit("Room.localEchoUpdated",e,this,r,o)},v.prototype._revertRedactionLocalEcho=function(e){const t=e.event.redacts;if(!t)return;const n=this.getUnfilteredTimelineSet().findEventById(t);n&&(n.unmarkLocallyRedacted(),this.emit("Room.redactionCancelled",e,this),n.isRelation()&&this._aggregateNonLiveRelation(n))},v.prototype.addLiveEvents=function(e,t,n){let o;if(t&&-1===["replace","ignore"].indexOf(t))throw new Error("duplicateStrategy MUST be either 'replace' or 'ignore'");for(o=0;o=0;--e){const o=this.timeline[e];if(o.getId()===t)return!1;if(o.getId()===n)return!0}return!1},v.prototype.getReceiptsForEvent=function(e){return this._receiptCacheByEventId[e.getId()]||[]},v.prototype.addReceipt=function(e,t){void 0===t&&(t=!1),t||this._addReceiptsToStructure(e,this._realReceipts),this._addReceiptsToStructure(e,this._receipts),this._receiptCacheByEventId=this._buildReceiptCache(this._receipts),this.emit("Room.receipt",e,this)},v.prototype._addReceiptsToStructure=function(e,t){const n=this;Object.keys(e.getContent()).forEach((function(o){Object.keys(e.getContent()[o]).forEach((function(r){Object.keys(e.getContent()[o][r]).forEach((function(i){const a=e.getContent()[o][r][i];t[r]||(t[r]={});const s=t[r][i];if(s){const e=n.getUnfilteredTimelineSet().compareEventOrdering(s.eventId,o);if(null!==e&&e>=0)return}else t[r][i]={};t[r][i]={eventId:o,data:a}}))}))}))},v.prototype._buildReceiptCache=function(e){const t={};return Object.keys(e).forEach((function(n){Object.keys(e[n]).forEach((function(o){const r=e[n][o];t[r.eventId]||(t[r.eventId]=[]),t[r.eventId].push({userId:o,type:n,data:r.data})}))})),t},v.prototype._addLocalEchoReceipt=function(e,t,n){this.addReceipt(b(e,t,n),!0)},v.prototype.addTags=function(e){this.tags=e.getContent().tags||{},this.emit("Room.tags",e,this)},v.prototype.addAccountData=function(e){for(let t=0;tr.powerLevel&&(t=!1),t},v.prototype.getJoinRule=function(){return this.currentState.getJoinRule()},v.prototype.getType=function(){const e=this.currentState.getStateEvents("m.room.create","");if(e)return e.getContent()[m.RoomCreateTypeField];this.getTypeWarning||(f.logger.warn("[getType] Room "+this.roomId+" does not have an m.room.create event"),this.getTypeWarning=!0)},v.prototype.isSpaceRoom=function(){return this.getType()===m.RoomType.Space}},41398:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.SearchResult=r;var o=n(43558);function r(e,t){this.rank=e,this.context=t}r.fromJson=function(e,t){const n=e.context||{},i=n.events_before||[],a=n.events_after||[],s=new o.EventContext(t(e.result));return s.setPaginateToken(n.start,!0),s.addEvents(i.map(t),!0),s.addEvents(a.map(t),!1),s.setPaginateToken(n.end,!1),new r(e.rank,s)}},83998:(e,t,n)=>{"use strict";var o=n(20862);Object.defineProperty(t,"__esModule",{value:!0}),t.User=a;var r=o(n(3102)),i=n(17187);function a(e){this.userId=e,this.presence="offline",this.presenceStatusMsg=null,this._unstable_statusMessage="",this.displayName=e,this.rawDisplayName=e,this.avatarUrl=null,this.lastActiveAgo=0,this.lastPresenceTs=0,this.currentlyActive=!1,this.events={presence:null,profile:null},this._updateModifiedTime()}r.inherits(a,i.EventEmitter),a.prototype.setPresenceEvent=function(e){if("m.presence"!==e.getType())return;const t=null===this.events.presence;this.events.presence=e;const n=[];(e.getContent().presence!==this.presence||t)&&n.push("User.presence"),e.getContent().avatar_url&&e.getContent().avatar_url!==this.avatarUrl&&n.push("User.avatarUrl"),e.getContent().displayname&&e.getContent().displayname!==this.displayName&&n.push("User.displayName"),void 0!==e.getContent().currently_active&&e.getContent().currently_active!==this.currentlyActive&&n.push("User.currentlyActive"),this.presence=e.getContent().presence,n.push("User.lastPresenceTs"),e.getContent().status_msg&&(this.presenceStatusMsg=e.getContent().status_msg),e.getContent().displayname&&(this.displayName=e.getContent().displayname),e.getContent().avatar_url&&(this.avatarUrl=e.getContent().avatar_url),this.lastActiveAgo=e.getContent().last_active_ago,this.lastPresenceTs=Date.now(),this.currentlyActive=e.getContent().currently_active,this._updateModifiedTime();for(let t=0;t{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.PushProcessor=s;var o=n(3102),r=n(7434);const i=["override","content","room","sender","underride"],a=[{rule_id:".m.rule.tombstone",default:!0,enabled:!0,conditions:[{kind:"event_match",key:"type",pattern:"m.room.tombstone"},{kind:"event_match",key:"state_key",pattern:""}],actions:["notify",{set_tweak:"highlight",value:!0}]},{rule_id:".m.rule.reaction",default:!0,enabled:!0,conditions:[{kind:"event_match",key:"type",pattern:"m.reaction"}],actions:["dont_notify"]}];function s(e){const t={},n=(e,t)=>{for(let n=0;n]*)([0-9]*)$/);if(!i)return!1;const a=i[1],s=parseInt(i[2]);if(isNaN(s))return!1;switch(a){case"":case"==":return r==s;case"<":return r":return r>s;case"<=":return r<=s;case">=":return r>=s;default:return!1}},l=function(t,n){let r=n.getContent();if(n.isEncrypted()&&n.getClearContent()&&(r=n.getClearContent()),!r||!r.body||"string"!=typeof r.body)return!1;const i=e.getRoom(n.getRoomId());if(!(i&&i.currentState&&i.currentState.members&&i.currentState.getMember(e.credentials.userId)))return!1;const a=i.currentState.getMember(e.credentials.userId).name,s=new RegExp("(^|\\W)"+(0,o.escapeRegExp)(a)+"(\\W|$)","i");return r.body.search(s)>-1},d=function(e,t){if(!e.key)return!1;const n=p(e.key,t);if("string"!=typeof n)return!1;if(e.value)return e.value===n;if("string"!=typeof e.pattern)return!1;let o;return o="content.body"==e.key?h("(^|\\W)",e.pattern,"(\\W|$)"):h("^",e.pattern,"$"),!!n.match(o)},h=function(e,n,r){return t[n]||(t[n]=new RegExp(e+(0,o.globToRegexp)(n)+r,"i")),t[n]},p=function(e,t){const n=e.split(".");let r;const i=n[0];for("content"===i?(r=t.getContent(),n.shift()):"type"===i?(r=t.getType(),n.shift()):r=t.event;n.length>0;){const e=n.shift();if((0,o.isNullOrUndefined)(r[e]))return null;r=r[e]}return r};this.ruleMatchesEvent=function(e,t){let n=!0;for(let o=0;ot.rule_id===e.rule_id));if(t)t.default=e.default,t.conditions=e.conditions,t.actions=e.actions;else{const t=e.rule_id;r.logger.warn(`Adding default global override for ${t}`),n.push(e)}}return t}},98401:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.randomString=function(e){return r(e,o+n+"0123456789")},t.randomLowercaseString=function(e){return r(e,n)},t.randomUppercaseString=function(e){return r(e,o)};const n="abcdefghijklmnopqrstuvwxyz",o="ABCDEFGHIJKLMNOPQRSTUVWXYZ";function r(e,t){let n="";for(let o=0;o{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.setNow=function(e){s=e||Date.now},t.setTimeout=function(e,t){(t=t||0)<0&&(t=0);const n=Array.prototype.slice.call(arguments,2),o=s()+t,r=i++,c={runAt:o,func:e,params:n,key:r},d=l(a,(function(e){return e.runAt-o}));return a.splice(d,0,c),u(),r},t.clearTimeout=function(e){if(0===a.length)return;let t;for(t=0;tt)break;e=a.shift(),e.key,r.push(e)}u();for(let t=0;t>1;t(e[r])>0?o=r:n=r+1}return n}},39443:(e,t,n)=>{"use strict";var o=n(20862);Object.defineProperty(t,"__esModule",{value:!0}),t.MatrixScheduler=i;var r=o(n(3102));function i(e,t){this.retryAlgorithm=e||i.RETRY_BACKOFF_RATELIMIT,this.queueAlgorithm=t||i.QUEUE_MESSAGES,this._queues={},this._activeQueues=[],this._procFn=null}function a(e){e._procFn&&Object.keys(e._queues).filter((function(t){return-1===e._activeQueues.indexOf(t)&&e._queues[t].length>0})).forEach((function(t){e._activeQueues.push(t),c(),s(e,t)}))}function s(e,t){const n=function(e,t){const n=e._queues[t];return Array.isArray(n)?n[0]:null}(e,t);if(!n){const n=e._activeQueues.indexOf(t);return n>=0&&e._activeQueues.splice(n,1),void c()}c(e._queues[t].length),Promise.resolve().then((()=>e._procFn(n.event))).then((function(o){u(e,t),c(n.event.getId()),n.defer.resolve(o),s(e,t)}),(function(o){n.attempts+=1;const r=e.retryAlgorithm(n.event,n.attempts,o);c(n.attempts,n.event.getId()),-1===r?(c(n.event.getId()),u(e,t),n.defer.reject(o),s(e,t)):setTimeout((function(){s(e,t)}),r)}))}function u(e,t){const n=e._queues[t];return Array.isArray(n)?n.shift():null}function c(){}n(7434),i.prototype.getQueueForEvent=function(e){const t=this.queueAlgorithm(e);return t&&this._queues[t]?this._queues[t].map((function(e){return e.event})):null},i.prototype.removeEventFromQueue=function(e){const t=this.queueAlgorithm(e);if(!t||!this._queues[t])return!1;let n=!1;return r.removeElement(this._queues[t],(function(t){if(t.event.getId()===e.getId())return n=!0,!0})),n},i.prototype.setProcessFunction=function(e){this._procFn=e,a(this)},i.prototype.queueEvent=function(e){const t=this.queueAlgorithm(e);if(!t)return null;this._queues[t]||(this._queues[t]=[]);const n=r.defer();return this._queues[t].push({event:e,defer:n,attempts:0}),e.getId(),a(this),n.promise},i.RETRY_BACKOFF_RATELIMIT=function(e,t,n){if(400===n.httpStatus||403===n.httpStatus||401===n.httpStatus)return-1;if("rejected"===n.cors)return-1;if("M_TOO_LARGE"===n.name)return-1;if("M_LIMIT_EXCEEDED"===n.name){const e=n.data.retry_after_ms;if(e>0)return e}return t>4?-1:1e3*Math.pow(2,t)},i.QUEUE_MESSAGES=function(e){return"m.room.message"===e.getType()||e.hasAssocation()?"message":null}},91415:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.SERVICE_TYPES=void 0;const n=Object.freeze({IS:"SERVICE_TYPE_IS",IM:"SERVICE_TYPE_IM"});t.SERVICE_TYPES=n},53861:(e,t,n)=>{"use strict";var o=n(20862);Object.defineProperty(t,"__esModule",{value:!0}),t.LocalIndexedDBStoreBackend=h;var r=n(22741),i=o(n(3102)),a=o(n(33415)),s=n(7434);function u(e,t,n){const o=e.openCursor(t);return new Promise(((e,t)=>{const r=[];o.onerror=e=>{t(new Error("Query failed: "+e.target.errorCode))},o.onsuccess=t=>{const o=t.target.result;o?(r.push(n(o)),o.continue()):e(r)}}))}function c(e){return new Promise(((t,n)=>{e.oncomplete=function(e){t(e)},e.onerror=function(e){n(e.target.error)}}))}function l(e){return new Promise(((t,n)=>{e.onsuccess=function(e){t(e)},e.onerror=function(e){n(e.target.error)}}))}function d(e){return l(e).then((e=>e.target.result))}function h(e,t){this.indexedDB=e,this._dbName="matrix-js-sdk:"+(t||"default"),this.db=null,this._disconnected=!0,this._syncAccumulator=new r.SyncAccumulator,this._isNewlyCreated=!1}h.exists=function(e,t){return t="matrix-js-sdk:"+(t||"default"),a.exists(e,t)},h.prototype={connect:function(){if(!this._disconnected)return s.logger.log("LocalIndexedDBStoreBackend.connect: already connected or connecting"),Promise.resolve();this._disconnected=!1,s.logger.log("LocalIndexedDBStoreBackend.connect: connecting...");const e=this.indexedDB.open(this._dbName,3);return e.onupgradeneeded=e=>{const t=e.target.result,n=e.oldVersion;s.logger.log(`LocalIndexedDBStoreBackend.connect: upgrading from ${n}`),n<1&&(this._isNewlyCreated=!0,function(e){e.createObjectStore("users",{keyPath:["userId"]}),e.createObjectStore("accountData",{keyPath:["type"]}),e.createObjectStore("sync",{keyPath:["clobber"]})}(t)),n<2&&function(e){e.createObjectStore("oob_membership_events",{keyPath:["room_id","state_key"]}).createIndex("room","room_id")}(t),n<3&&function(e){e.createObjectStore("client_options",{keyPath:["clobber"]})}(t)},e.onblocked=()=>{s.logger.log("can't yet open LocalIndexedDBStoreBackend because it is open elsewhere")},s.logger.log("LocalIndexedDBStoreBackend.connect: awaiting connection..."),l(e).then((e=>(s.logger.log("LocalIndexedDBStoreBackend.connect: connected"),this.db=e.target.result,this.db.onversionchange=()=>{this.db.close()},this._init())))},isNewlyCreated:function(){return Promise.resolve(this._isNewlyCreated)},_init:function(){return Promise.all([this._loadAccountData(),this._loadSyncData()]).then((([e,t])=>{s.logger.log("LocalIndexedDBStoreBackend: loaded initial data"),this._syncAccumulator.accumulate({next_batch:t.nextBatch,rooms:t.roomsData,groups:t.groupsData,account_data:{events:e}},!0)}))},getOutOfBandMembers:function(e){return new Promise(((t,n)=>{const o=this.db.transaction(["oob_membership_events"],"readonly").objectStore("oob_membership_events").index("room"),r=IDBKeyRange.only(e),i=o.openCursor(r),a=[];let s=!1;i.onsuccess=e=>{const n=e.target.result;if(!n)return a.length||s?t(a):t(null);const o=n.value;o.oob_written?s=!0:a.push(o),n.continue()},i.onerror=e=>{n(e)}})).then((t=>(s.logger.log(`LL: got ${t&&t.length} membershipEvents from storage for room ${e} ...`),t)))},setOutOfBandMembers:async function(e,t){s.logger.log(`LL: backend about to store ${t.length} members for ${e}`);const n=this.db.transaction(["oob_membership_events"],"readwrite"),o=n.objectStore("oob_membership_events");t.forEach((e=>{o.put(e)}));const r={room_id:e,oob_written:!0,state_key:0};o.put(r),await c(n),s.logger.log(`LL: backend done storing for ${e}!`)},clearOutOfBandMembers:async function(e){const t=this.db.transaction(["oob_membership_events"],"readonly").objectStore("oob_membership_events").index("room"),n=IDBKeyRange.only(e),o=d(t.openKeyCursor(n,"next")).then((e=>e&&e.primaryKey[1])),r=d(t.openKeyCursor(n,"prev")).then((e=>e&&e.primaryKey[1])),[i,a]=await Promise.all([o,r]),u=this.db.transaction(["oob_membership_events"],"readwrite").objectStore("oob_membership_events"),c=IDBKeyRange.bound([e,i],[e,a]);var l;s.logger.log(`LL: Deleting all users + marker in storage for room ${e}, with key range:`,[e,i],[e,a]),await(l=u.delete(c),new Promise(((e,t)=>{l.onsuccess=()=>e(l),l.onerror=e=>t(e)})))},clearDatabase:function(){return new Promise(((e,t)=>{s.logger.log(`Removing indexeddb instance: ${this._dbName}`);const n=this.indexedDB.deleteDatabase(this._dbName);n.onblocked=()=>{s.logger.log(`can't yet delete indexeddb ${this._dbName} because it is open elsewhere`)},n.onerror=t=>{s.logger.warn(`unable to delete js-sdk store indexeddb: ${t.target.error}`),e()},n.onsuccess=()=>{s.logger.log(`Removed indexeddb instance: ${this._dbName}`),e()}}))},getSavedSync:function(e){void 0===e&&(e=!0);const t=this._syncAccumulator.getJSON();return t.nextBatch?e?Promise.resolve(i.deepCopy(t)):Promise.resolve(t):Promise.resolve(null)},getNextBatchToken:function(){return Promise.resolve(this._syncAccumulator.getNextBatchToken())},setSyncData:function(e){return Promise.resolve().then((()=>{this._syncAccumulator.accumulate(e)}))},syncToDatabase:function(e){const t=this._syncAccumulator.getJSON(!0);return Promise.all([this._persistUserPresenceEvents(e),this._persistAccountData(t.accountData),this._persistSyncData(t.nextBatch,t.roomsData,t.groupsData)])},_persistSyncData:function(e,t,n){return s.logger.log("Persisting sync data up to",e),i.promiseTry((()=>{const o=this.db.transaction(["sync"],"readwrite");return o.objectStore("sync").put({clobber:"-",nextBatch:e,roomsData:t,groupsData:n}),c(o)}))},_persistAccountData:function(e){return i.promiseTry((()=>{const t=this.db.transaction(["accountData"],"readwrite"),n=t.objectStore("accountData");for(let t=0;t{const t=this.db.transaction(["users"],"readwrite"),n=t.objectStore("users");for(const t of e)n.put({userId:t[0],event:t[1]});return c(t)}))},getUserPresenceEvents:function(){return i.promiseTry((()=>u(this.db.transaction(["users"],"readonly").objectStore("users"),void 0,(e=>[e.value.userId,e.value.event]))))},_loadAccountData:function(){return s.logger.log("LocalIndexedDBStoreBackend: loading account data..."),i.promiseTry((()=>u(this.db.transaction(["accountData"],"readonly").objectStore("accountData"),void 0,(e=>e.value)).then((e=>(s.logger.log("LocalIndexedDBStoreBackend: loaded account data"),e)))))},_loadSyncData:function(){return s.logger.log("LocalIndexedDBStoreBackend: loading sync data..."),i.promiseTry((()=>u(this.db.transaction(["sync"],"readonly").objectStore("sync"),void 0,(e=>e.value)).then((e=>(s.logger.log("LocalIndexedDBStoreBackend: loaded sync data"),e.length>1&&s.logger.warn("loadSyncData: More than 1 sync row found."),e.length>0?e[0]:{})))))},getClientOptions:function(){return Promise.resolve().then((()=>u(this.db.transaction(["client_options"],"readonly").objectStore("client_options"),void 0,(e=>{if(e.value&&e.value&&e.value.options)return e.value.options})).then((e=>e[0]))))},storeClientOptions:async function(e){const t=this.db.transaction(["client_options"],"readwrite");t.objectStore("client_options").put({clobber:"-",options:e}),await c(t)}}},64215:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.RemoteIndexedDBStoreBackend=i;var o=n(7434),r=n(3102);function i(e,t,n){this._workerScript=e,this._dbName=t,this._workerApi=n,this._worker=null,this._nextSeq=0,this._inFlight={},this._startPromise=null}i.prototype={connect:function(){return this._ensureStarted().then((()=>this._doCmd("connect")))},clearDatabase:function(){return this._ensureStarted().then((()=>this._doCmd("clearDatabase")))},isNewlyCreated:function(){return this._doCmd("isNewlyCreated")},getSavedSync:function(){return this._doCmd("getSavedSync")},getNextBatchToken:function(){return this._doCmd("getNextBatchToken")},setSyncData:function(e){return this._doCmd("setSyncData",[e])},syncToDatabase:function(e){return this._doCmd("syncToDatabase",[e])},getOutOfBandMembers:function(e){return this._doCmd("getOutOfBandMembers",[e])},setOutOfBandMembers:function(e,t){return this._doCmd("setOutOfBandMembers",[e,t])},clearOutOfBandMembers:function(e){return this._doCmd("clearOutOfBandMembers",[e])},getClientOptions:function(){return this._doCmd("getClientOptions")},storeClientOptions:function(e){return this._doCmd("storeClientOptions",[e])},getUserPresenceEvents:function(){return this._doCmd("getUserPresenceEvents")},_ensureStarted:function(){return null===this._startPromise&&(this._worker=new this._workerApi(this._workerScript),this._worker.onmessage=this._onWorkerMessage.bind(this),this._startPromise=this._doCmd("_setupWorker",[this._dbName]).then((()=>{o.logger.log("IndexedDB worker is ready")}))),this._startPromise},_doCmd:function(e,t){return Promise.resolve().then((()=>{const n=this._nextSeq++,o=(0,r.defer)();return this._inFlight[n]=o,this._worker.postMessage({command:e,seq:n,args:t}),o.promise}))},_onWorkerMessage:function(e){const t=e.data;if("cmd_success"==t.command||"cmd_fail"==t.command){if(void 0===t.seq)return void o.logger.error("Got reply from worker with no seq");const e=this._inFlight[t.seq];if(void 0===e)return void o.logger.error("Got reply for unknown seq "+t.seq);if(delete this._inFlight[t.seq],"cmd_success"==t.command)e.resolve(t.result);else{const n=new Error(t.error.message);n.name=t.error.name,e.reject(n)}}else o.logger.warn("Unrecognised message from worker: "+t)}}},99789:(e,t,n)=>{"use strict";var o=n(20862);Object.defineProperty(t,"__esModule",{value:!0}),t.IndexedDBStore=h;var r=n(11703),i=o(n(3102)),a=n(17187),s=n(53861),u=n(64215),c=n(83998),l=n(24369),d=n(7434);function h(e){if(r.MemoryStore.call(this,e),!e.indexedDB)throw new Error("Missing required option: indexedDB");if(e.workerScript){let t=e.workerApi;t||(t=n.g.Worker),this.backend=new u.RemoteIndexedDBStoreBackend(e.workerScript,e.dbName,t)}else this.backend=new s.LocalIndexedDBStoreBackend(e.indexedDB,e.dbName);this.startedUp=!1,this._syncTs=0,this._userModifiedMap={}}function p(e,t){return async function(...n){try{return await e.call(this,...n)}catch(e){d.logger.error("IndexedDBStore failure, degrading to MemoryStore",e),this.emit("degraded",e);try{d.logger.log("IndexedDBStore trying to delete degraded data"),await this.backend.clearDatabase(),d.logger.log("IndexedDBStore delete after degrading succeeeded")}catch(e){d.logger.warn("IndexedDBStore delete after degrading failed",e)}if(Object.setPrototypeOf(this,r.MemoryStore.prototype),t)return await r.MemoryStore.prototype[t].call(this,...n)}}}i.inherits(h,r.MemoryStore),i.extend(h.prototype,a.EventEmitter.prototype),h.exists=function(e,t){return s.LocalIndexedDBStoreBackend.exists(e,t)},h.prototype.startup=function(){return this.startedUp?(d.logger.log("IndexedDBStore.startup: already started"),Promise.resolve()):(d.logger.log("IndexedDBStore.startup: connecting to backend"),this.backend.connect().then((()=>(d.logger.log("IndexedDBStore.startup: loading presence events"),this.backend.getUserPresenceEvents()))).then((e=>{d.logger.log("IndexedDBStore.startup: processing presence events"),e.forEach((([e,t])=>{const n=new c.User(e);t&&n.setPresenceEvent(new l.MatrixEvent(t)),this._userModifiedMap[n.userId]=n.getLastModifiedTime(),this.storeUser(n)}))})))},h.prototype.getSavedSync=p((function(){return this.backend.getSavedSync()}),"getSavedSync"),h.prototype.isNewlyCreated=p((function(){return this.backend.isNewlyCreated()}),"isNewlyCreated"),h.prototype.getSavedSyncToken=p((function(){return this.backend.getNextBatchToken()}),"getSavedSyncToken"),h.prototype.deleteAllData=p((function(){return r.MemoryStore.prototype.deleteAllData.call(this),this.backend.clearDatabase().then((()=>{d.logger.log("Deleted indexeddb data.")}),(e=>{throw d.logger.error(`Failed to delete indexeddb data: ${e}`),e}))})),h.prototype.wantsSave=function(){return Date.now()-this._syncTs>3e5},h.prototype.save=function(e){return e||this.wantsSave()?this._reallySave():Promise.resolve()},h.prototype._reallySave=p((function(){this._syncTs=Date.now();const e=[];for(const t of this.getUsers())this._userModifiedMap[t.userId]!==t.getLastModifiedTime()&&t.events.presence&&(e.push([t.userId,t.events.presence.event]),this._userModifiedMap[t.userId]=t.getLastModifiedTime());return this.backend.syncToDatabase(e)})),h.prototype.setSyncData=p((function(e){return this.backend.setSyncData(e)}),"setSyncData"),h.prototype.getOutOfBandMembers=p((function(e){return this.backend.getOutOfBandMembers(e)}),"getOutOfBandMembers"),h.prototype.setOutOfBandMembers=p((function(e,t){return r.MemoryStore.prototype.setOutOfBandMembers.call(this,e,t),this.backend.setOutOfBandMembers(e,t)}),"setOutOfBandMembers"),h.prototype.clearOutOfBandMembers=p((function(e){return r.MemoryStore.prototype.clearOutOfBandMembers.call(this),this.backend.clearOutOfBandMembers(e)}),"clearOutOfBandMembers"),h.prototype.getClientOptions=p((function(){return this.backend.getClientOptions()}),"getClientOptions"),h.prototype.storeClientOptions=p((function(e){return r.MemoryStore.prototype.storeClientOptions.call(this,e),this.backend.storeClientOptions(e)}),"storeClientOptions")},11703:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.MemoryStore=i;var o=n(83998);function r(e){return"string"==typeof e&&!!e&&"undefined"!==e&&"null"!==e||"number"==typeof e}function i(e){e=e||{},this.rooms={},this.groups={},this.users={},this.syncToken=null,this.filters={},this.accountData={},this.localStorage=e.localStorage,this._oobMembers={},this._clientOptions={}}i.prototype={getSyncToken:function(){return this.syncToken},isNewlyCreated:function(){return Promise.resolve(!0)},setSyncToken:function(e){this.syncToken=e},storeGroup:function(e){this.groups[e.groupId]=e},getGroup:function(e){return this.groups[e]||null},getGroups:function(){return Object.values(this.groups)},storeRoom:function(e){this.rooms[e.roomId]=e,e.currentState.on("RoomState.members",this._onRoomMember.bind(this));const t=this;e.currentState.getMembers().forEach((function(n){t._onRoomMember(null,e.currentState,n)}))},_onRoomMember:function(e,t,n){if("invite"===n.membership)return;const r=this.users[n.userId]||new o.User(n.userId);n.name&&(r.setDisplayName(n.name),n.events.member&&r.setRawDisplayName(n.events.member.getDirectionalContent().displayname)),n.events.member&&n.events.member.getContent().avatar_url&&r.setAvatarUrl(n.events.member.getContent().avatar_url),this.users[r.userId]=r},getRoom:function(e){return this.rooms[e]||null},getRooms:function(){return Object.values(this.rooms)},removeRoom:function(e){this.rooms[e]&&this.rooms[e].removeListener("RoomState.members",this._onRoomMember),delete this.rooms[e]},getRoomSummaries:function(){return Object.values(this.rooms).map((function(e){return e.summary}))},storeUser:function(e){this.users[e.userId]=e},getUser:function(e){return this.users[e]||null},getUsers:function(){return Object.values(this.users)},scrollback:function(e,t){return[]},storeEvents:function(e,t,n,o){},storeFilter:function(e){e&&(this.filters[e.userId]||(this.filters[e.userId]={}),this.filters[e.userId][e.filterId]=e)},getFilter:function(e,t){return this.filters[e]&&this.filters[e][t]?this.filters[e][t]:null},getFilterIdByName:function(e){if(!this.localStorage)return null;const t="mxjssdk_memory_filter_"+e;try{const e=this.localStorage.getItem(t);if(r(e))return e}catch(e){}return null},setFilterIdByName:function(e,t){if(!this.localStorage)return;const n="mxjssdk_memory_filter_"+e;try{r(t)?this.localStorage.setItem(n,t):this.localStorage.removeItem(n)}catch(e){}},storeAccountDataEvents:function(e){const t=this;e.forEach((function(e){t.accountData[e.getType()]=e}))},getAccountData:function(e){return this.accountData[e]},setSyncData:function(e){return Promise.resolve()},wantsSave:function(){return!1},save:function(e){},startup:function(){return Promise.resolve()},getSavedSync:function(){return Promise.resolve(null)},getSavedSyncToken:function(){return Promise.resolve(null)},deleteAllData:function(){return this.rooms={},this.users={},this.syncToken=null,this.filters={},this.accountData={},Promise.resolve()},getOutOfBandMembers:function(e){return Promise.resolve(this._oobMembers[e]||null)},setOutOfBandMembers:function(e,t){return this._oobMembers[e]=t,Promise.resolve()},clearOutOfBandMembers:function(){return this._oobMembers={},Promise.resolve()},getClientOptions:function(){return Promise.resolve(this._clientOptions)},storeClientOptions:function(e){return this._clientOptions=Object.assign({},e),Promise.resolve()}}},55837:(e,t,n)=>{"use strict";var o=n(20862);Object.defineProperty(t,"__esModule",{value:!0}),t.WebStorageSessionStore=a;var r=o(n(3102));n(7434);const i="session.e2e.";function a(e){if(this.store=e,!(r.isFunction(e.getItem)&&r.isFunction(e.setItem)&&r.isFunction(e.removeItem)&&r.isFunction(e.key)&&"number"==typeof e.length))throw new Error("Supplied webStore does not meet the WebStorage API interface")}a.prototype={removeEndToEndAccount:function(){this.store.removeItem(s)},getEndToEndAccount:function(){return this.store.getItem(s)},getAllEndToEndDevices:function(){const e=d(""),t={};for(let n=0;n{"use strict";function n(){this.fromToken=null}Object.defineProperty(t,"__esModule",{value:!0}),t.StubStore=n,n.prototype={isNewlyCreated:function(){return Promise.resolve(!0)},getSyncToken:function(){return this.fromToken},setSyncToken:function(e){this.fromToken=e},storeGroup:function(e){},getGroup:function(e){return null},getGroups:function(){return[]},storeRoom:function(e){},getRoom:function(e){return null},getRooms:function(){return[]},removeRoom:function(e){},getRoomSummaries:function(){return[]},storeUser:function(e){},getUser:function(e){return null},getUsers:function(){return[]},scrollback:function(e,t){return[]},storeEvents:function(e,t,n,o){},storeFilter:function(e){},getFilter:function(e,t){return null},getFilterIdByName:function(e){return null},setFilterIdByName:function(e,t){},storeAccountDataEvents:function(e){},getAccountData:function(e){},setSyncData:function(e){return Promise.resolve()},wantsSave:function(){return!1},save:function(){},startup:function(){return Promise.resolve()},getSavedSync:function(){return Promise.resolve(null)},getSavedSyncToken:function(){return Promise.resolve(null)},deleteAllData:function(){return Promise.resolve()},getOutOfBandMembers:function(){return Promise.resolve(null)},setOutOfBandMembers:function(){return Promise.resolve()},clearOutOfBandMembers:function(){return Promise.resolve()},getClientOptions:function(){return Promise.resolve()},storeClientOptions:function(){return Promise.resolve()}}},22741:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.SyncAccumulator=void 0;var o=n(7434),r=n(3102);function i(e,t){null!==t.state_key&&void 0!==t.state_key&&t.type&&(e[t.type]||(e[t.type]=Object.create(null)),e[t.type][t.state_key]=t)}t.SyncAccumulator=class{constructor(e){(e=e||{}).maxTimelineEntries=e.maxTimelineEntries||50,this.opts=e,this.accountData={},this.inviteRooms={},this.joinRooms={},this.nextBatch=null,this.groups={invite:{},join:{},leave:{}}}accumulate(e,t){this._accumulateRooms(e,t),this._accumulateGroups(e),this._accumulateAccountData(e),this.nextBatch=e.next_batch}_accumulateAccountData(e){e.account_data&&e.account_data.events&&e.account_data.events.forEach((e=>{this.accountData[e.type]=e}))}_accumulateRooms(e,t){e.rooms&&(e.rooms.invite&&Object.keys(e.rooms.invite).forEach((n=>{this._accumulateRoom(n,"invite",e.rooms.invite[n],t)})),e.rooms.join&&Object.keys(e.rooms.join).forEach((n=>{this._accumulateRoom(n,"join",e.rooms.join[n],t)})),e.rooms.leave&&Object.keys(e.rooms.leave).forEach((n=>{this._accumulateRoom(n,"leave",e.rooms.leave[n],t)})))}_accumulateRoom(e,t,n,r){switch(t){case"invite":this._accumulateInviteState(e,n);break;case"join":this.inviteRooms[e]&&delete this.inviteRooms[e],this._accumulateJoinState(e,n,r);break;case"leave":this.inviteRooms[e]?delete this.inviteRooms[e]:delete this.joinRooms[e];break;default:o.logger.error("Unknown cateogory: ",t)}}_accumulateInviteState(e,t){if(!t.invite_state||!t.invite_state.events)return;if(!this.inviteRooms[e])return void(this.inviteRooms[e]={invite_state:t.invite_state});const n=this.inviteRooms[e];t.invite_state.events.forEach((e=>{let t=!1;for(let o=0;o{o._accountData[e.type]=e})),t.unread_notifications&&(o._unreadNotifications=t.unread_notifications),t.summary){const e="m.heroes",n="m.invited_member_count",r="m.joined_member_count",i=o._summary,a=t.summary;i[e]=a[e]||i[e],i[r]=a[r]||i[r],i[n]=a[n]||i[n]}if(t.ephemeral&&t.ephemeral.events&&t.ephemeral.events.forEach((e=>{"m.receipt"===e.type&&e.content&&Object.keys(e.content).forEach((t=>{e.content[t]["m.read"]&&Object.keys(e.content[t]["m.read"]).forEach((n=>{o._readReceipts[n]={data:e.content[t]["m.read"][n],eventId:t}}))}))})),t.timeline&&t.timeline.limited&&(o._timeline=[]),t.state&&t.state.events&&t.state.events.forEach((e=>{i(o._currentState,e)})),t.timeline&&t.timeline.events&&t.timeline.events.forEach(((e,r)=>{let a;if(i(o._currentState,e),n)a=e;else{a=Object.assign({},e),void 0!==a.unsigned&&(a.unsigned=Object.assign({},a.unsigned));const t=e.unsigned?e.unsigned.age:e.age;void 0!==t&&(a._localTs=Date.now()-t)}o._timeline.push({event:a,token:0===r?t.timeline.prev_batch:null})})),o._timeline.length>this.opts.maxTimelineEntries)for(let e=o._timeline.length-this.opts.maxTimelineEntries;e{this._accumulateGroup(t,"invite",e.groups.invite[t])})),e.groups.join&&Object.keys(e.groups.join).forEach((t=>{this._accumulateGroup(t,"join",e.groups.join[t])})),e.groups.leave&&Object.keys(e.groups.leave).forEach((t=>{this._accumulateGroup(t,"leave",e.groups.leave[t])})))}_accumulateGroup(e,t,n){for(const t of["invite","join","leave"])delete this.groups[t][e];this.groups[t][e]=n}getJSON(e){const t={join:{},invite:{},leave:{}};Object.keys(this.inviteRooms).forEach((e=>{t.invite[e]=this.inviteRooms[e]})),Object.keys(this.joinRooms).forEach((n=>{const o=this.joinRooms[n],a={ephemeral:{events:[]},account_data:{events:[]},state:{events:[]},timeline:{events:[],prev_batch:null},unread_notifications:o._unreadNotifications,summary:o._summary};Object.keys(o._accountData).forEach((e=>{a.account_data.events.push(o._accountData[e])}));const s={type:"m.receipt",room_id:n,content:{}};Object.keys(o._readReceipts).forEach((e=>{const t=o._readReceipts[e];s.content[t.eventId]||(s.content[t.eventId]={"m.read":{}}),s.content[t.eventId]["m.read"][e]=t.data})),Object.keys(s.content).length>0&&a.ephemeral.events.push(s),o._timeline.forEach((t=>{if(!a.timeline.prev_batch){if(!t.token)return;a.timeline.prev_batch=t.token}let n;!e&&t.event._localTs?(n=Object.assign({},t.event),void 0!==n.unsigned&&(n.unsigned=Object.assign({},n.unsigned)),delete n._localTs,n.unsigned=n.unsigned||{},n.unsigned.age=Date.now()-t.event._localTs):n=t.event,a.timeline.events.push(n)}));const u=Object.create(null);for(let e=a.timeline.events.length-1;e>=0;e--){const t=a.timeline.events[e];if(null===t.state_key||void 0===t.state_key)continue;const n=(0,r.deepCopy)(t);n.unsigned&&(n.unsigned.prev_content&&(n.content=n.unsigned.prev_content),n.unsigned.prev_sender&&(n.sender=n.unsigned.prev_sender)),i(u,n)}Object.keys(o._currentState).forEach((e=>{Object.keys(o._currentState[e]).forEach((t=>{let n=o._currentState[e][t];u[e]&&u[e][t]&&(n=u[e][t]),a.state.events.push(n)}))})),t.join[n]=a}));const n=[];return Object.keys(this.accountData).forEach((e=>{n.push(this.accountData[e])})),{nextBatch:this.nextBatch,roomsData:t,groupsData:this.groups,accountData:n}}getNextBatchToken(){return this.nextBatch}}},64551:(e,t,n)=>{"use strict";var o=n(20862);Object.defineProperty(t,"__esModule",{value:!0}),t.SyncApi=g;var r=n(83998),i=n(27366),a=n(70142),s=o(n(3102)),u=n(27906),c=n(88910),l=n(31707),d=n(7434),h=n(19489);function p(e,t){return"FILTER_SYNC_"+e+(t?"_"+t:"")}function f(...e){d.logger.log(...e)}function g(e,t){this.client=e,(t=t||{}).initialSyncLimit=void 0===t.initialSyncLimit?8:t.initialSyncLimit,t.resolveInvitesToProfiles=t.resolveInvitesToProfiles||!1,t.pollTimeout=t.pollTimeout||3e4,t.pendingEventOrdering=t.pendingEventOrdering||"chronological",t.canResetEntireTimeline||(t.canResetEntireTimeline=function(e){return!1}),this.opts=t,this._peekRoom=null,this._currentSyncRequest=null,this._syncState=null,this._syncStateData=null,this._catchingUp=!1,this._running=!1,this._keepAliveTimer=null,this._connectionReturnedDefer=null,this._notifEvents=[],this._failedSyncCount=0,this._storeIsInvalid=!1,e.getNotifTimelineSet()&&e.reEmitter.reEmit(e.getNotifTimelineSet(),["Room.timeline","Room.timelineReset"])}function m(e,t){const n=new r.User(t);return e.reEmitter.reEmit(n,["User.avatarUrl","User.displayName","User.presence","User.currentlyActive","User.lastPresenceTs"]),n}g.prototype.createRoom=function(e){const t=this.client,{timelineSupport:n,unstableClientRelationAggregation:o}=t,r=new i.Room(e,t,t.getUserId(),{lazyLoadMembers:this.opts.lazyLoadMembers,pendingEventOrdering:this.opts.pendingEventOrdering,timelineSupport:n,unstableClientRelationAggregation:o});return t.reEmitter.reEmit(r,["Room.name","Room.timeline","Room.redaction","Room.redactionCancelled","Room.receipt","Room.tags","Room.timelineReset","Room.localEchoUpdated","Room.accountData","Room.myMembership","Room.replaceEvent"]),this._registerStateListeners(r),r},g.prototype.createGroup=function(e){const t=this.client,n=new a.Group(e);return t.reEmitter.reEmit(n,["Group.profile","Group.myMembership"]),t.store.storeGroup(n),n},g.prototype._registerStateListeners=function(e){const t=this.client;t.reEmitter.reEmit(e.currentState,["RoomState.events","RoomState.members","RoomState.newMember"]),e.currentState.on("RoomState.newMember",(function(e,n,o){o.user=t.getUser(o.userId),t.reEmitter.reEmit(o,["RoomMember.name","RoomMember.typing","RoomMember.powerLevel","RoomMember.membership"])}))},g.prototype._deregisterStateListeners=function(e){e.currentState.removeAllListeners("RoomState.events"),e.currentState.removeAllListeners("RoomState.members"),e.currentState.removeAllListeners("RoomState.newMember")},g.prototype.syncLeftRooms=function(){const e=this.client,t=this,n=new u.Filter(this.client.credentials.userId);n.setTimelineLimit(1),n.setIncludeLeaveRooms(!0);const o=this.opts.pollTimeout+8e4,r={timeout:0};return e.getOrCreateFilter(p(e.credentials.userId,"LEFT_ROOMS"),n).then((function(t){return r.filter=t,e._http.authedRequest(void 0,"GET","/sync",r,void 0,o)})).then((function(n){let o=[];n.rooms&&n.rooms.leave&&(o=t._mapSyncResponseToRoomArray(n.rooms.leave));const r=[];return o.forEach((function(n){const o=n.room;if(r.push(o),!n.isBrandNewRoom)return;n.timeline=n.timeline||{};const i=t._mapSyncEventsFormat(n.timeline,o),a=t._mapSyncEventsFormat(n.state,o);o.getLiveTimeline().setPaginationToken(n.timeline.prev_batch,c.EventTimeline.BACKWARDS),t._processRoomEvents(o,a,i),o.recalculate(),e.store.storeRoom(o),e.emit("Room",o),t._processEventsForNotifs(o,i)})),r}))},g.prototype.peek=function(e){if(this._peekRoom&&this._peekRoom.roomId===e)return Promise.resolve(this._peekRoom);const t=this.client;return this._peekRoom=this.createRoom(e),this.client.roomInitialSync(e,20).then((e=>{e.messages=e.messages||{},e.messages.chunk=e.messages.chunk||[],e.state=e.state||[];const n=s.deepCopy(e.state).map(t.getEventMapper()),o=e.state.map(t.getEventMapper()),r=e.messages.chunk.map(t.getEventMapper());return e.presence&&Array.isArray(e.presence)&&e.presence.map(t.getEventMapper()).forEach((function(e){let n=t.store.getUser(e.getContent().user_id);n?n.setPresenceEvent(e):(n=m(t,e.getContent().user_id),n.setPresenceEvent(e),t.store.storeUser(n)),t.emit("event",e)})),e.messages.start&&(this._peekRoom.oldState.paginationToken=e.messages.start),this._peekRoom.oldState.setStateEvents(n),this._peekRoom.currentState.setStateEvents(o),this._resolveInvites(this._peekRoom),this._peekRoom.recalculate(),this._peekRoom.addEventsToTimeline(r.reverse(),!0,this._peekRoom.getLiveTimeline(),e.messages.start),t.store.storeRoom(this._peekRoom),t.emit("Room",this._peekRoom),this._peekPoll(this._peekRoom),this._peekRoom}))},g.prototype.stopPeeking=function(){this._peekRoom=null},g.prototype._peekPoll=function(e,t){if(this._peekRoom!==e)return void f("Stopped peeking in room %s",e.roomId);const n=this;this.client._http.authedRequest(void 0,"GET","/events",{room_id:e.roomId,timeout:3e4,from:t},void 0,5e4).then((function(t){if(n._peekRoom!==e)return void f("Stopped peeking in room %s",e.roomId);t.chunk.filter((function(e){return"m.presence"===e.type})).map(n.client.getEventMapper()).forEach((function(e){let t=n.client.store.getUser(e.getContent().user_id);t?t.setPresenceEvent(e):(t=m(n.client,e.getContent().user_id),t.setPresenceEvent(e),n.client.store.storeUser(t)),n.client.emit("event",e)}));const o=t.chunk.filter((function(t){return t.room_id===e.roomId&&t.event_id})).map(n.client.getEventMapper());e.addLiveEvents(o),n._peekPoll(e,t.end)}),(function(o){d.logger.error("[%s] Peek poll failed: %s",e.roomId,o),setTimeout((function(){n._peekPoll(e,t)}),3e4)}))},g.prototype.getSyncState=function(){return this._syncState},g.prototype.getSyncStateData=function(){return this._syncStateData},g.prototype.recoverFromSyncStartupError=async function(e,t){await e;const n=this._startKeepAlives();this._updateSyncState("ERROR",{error:t}),await n},g.prototype._wasLazyLoadingToggled=async function(e){e=!!e;let t=!1;if(!await this.client.store.isNewlyCreated()){const n=await this.client.store.getClientOptions();return n&&(t=!!n.lazyLoadMembers),t!==e}return!1},g.prototype._shouldAbortSync=function(e){return"M_UNKNOWN_TOKEN"===e.errcode&&(d.logger.warn("Token no longer valid - assuming logout"),this.stop(),!0)},g.prototype.sync=function(){const e=this.client,t=this;this._running=!0,n.g.window&&n.g.window.addEventListener&&(this._onOnlineBound=this._onOnline.bind(this),n.g.window.addEventListener("online",this._onOnlineBound,!1));let o=Promise.resolve(),r=null;function i(){const n=new u.Filter(e.credentials.userId);return n.setTimelineLimit(t.opts.initialSyncLimit),n}const a=async()=>{if(f("Checking lazy load status..."),this.opts.lazyLoadMembers&&e.isGuest()&&(this.opts.lazyLoadMembers=!1),this.opts.lazyLoadMembers&&(f("Checking server lazy load support..."),await e.doesServerSupportLazyLoading()?(f("Enabling lazy load on sync filter..."),this.opts.filter||(this.opts.filter=i()),this.opts.filter.setLazyLoadMembers(!0)):(f("LL: lazy loading requested but not supported by server, so disabling"),this.opts.lazyLoadMembers=!1)),f("Checking whether lazy loading has changed in store..."),await this._wasLazyLoadingToggled(this.opts.lazyLoadMembers)){this._storeIsInvalid=!0;const e=h.InvalidStoreError.TOGGLED_LAZY_LOADING,t=new h.InvalidStoreError(e,!!this.opts.lazyLoadMembers);return this._updateSyncState("ERROR",{error:t}),void d.logger.warn("InvalidStoreError: store is not usable: stopping sync.")}this.opts.lazyLoadMembers&&this.opts.crypto&&this.opts.crypto.enableLazyLoading();try{f("Storing client options..."),await this.client._storeClientOptions(),f("Stored client options")}catch(e){throw d.logger.error("Storing client options failed",e),e}s()};async function s(){let n,a;f("Getting filter..."),n=t.opts.filter?t.opts.filter:i();try{a=await e.getOrCreateFilter(p(e.credentials.userId),n)}catch(e){if(d.logger.error("Getting filter failed",e),t._shouldAbortSync(e))return;return f("Waiting for saved sync before retrying filter..."),await t.recoverFromSyncStartupError(o,e),void s()}e.resetNotifTimelineSet(),null===t._currentSyncRequest&&(f("Sending first sync request..."),t._currentSyncRequest=t._doSyncRequest({filterId:a},r)),f("Waiting for saved sync before starting sync processing..."),await o,t._sync({filterId:a})}e.isGuest()?t._sync({}):(f("Getting saved sync token..."),o=e.store.getSavedSyncToken().then((t=>(f("Got saved sync token"),r=t,f("Getting saved sync..."),e.store.getSavedSync()))).then((e=>{if(f(`Got reply from saved sync, exists? ${!!e}`),e)return t._syncFromCache(e)})).catch((e=>{d.logger.error("Getting saved sync failed",e)})),async function n(){try{f("Getting push rules...");const t=await e.getPushRules();f("Got push rules"),e.pushRules=t}catch(e){if(d.logger.error("Getting push rules failed",e),t._shouldAbortSync(e))return;return f("Waiting for saved sync before retrying push rules..."),await t.recoverFromSyncStartupError(o,e),void n()}a()}())},g.prototype.stop=function(){f("SyncApi.stop"),n.g.window&&(n.g.window.removeEventListener("online",this._onOnlineBound,!1),this._onOnlineBound=void 0),this._running=!1,this._currentSyncRequest&&this._currentSyncRequest.abort(),this._keepAliveTimer&&(clearTimeout(this._keepAliveTimer),this._keepAliveTimer=null)},g.prototype.retryImmediately=function(){return!!this._connectionReturnedDefer&&(this._startKeepAlives(0),!0)},g.prototype._syncFromCache=async function(e){f("sync(): not doing HTTP hit, instead returning stored /sync data");const t=e.nextBatch;this.client.store.setSyncToken(t);const n={oldSyncToken:null,nextSyncToken:t,catchingUp:!1,fromCache:!0},o={next_batch:t,rooms:e.roomsData,groups:e.groupsData,account_data:{events:e.accountData}};try{await this._processSyncResponse(n,o)}catch(e){d.logger.error("Error processing cached sync",e.stack||e)}this._storeIsInvalid||this._updateSyncState("PREPARED",n)},g.prototype._sync=async function(e){const t=this.client;if(!this._running)return f("Sync no longer running: exiting."),this._connectionReturnedDefer&&(this._connectionReturnedDefer.reject(),this._connectionReturnedDefer=null),void this._updateSyncState("STOPPED");const n=t.store.getSyncToken();let o;try{null===this._currentSyncRequest&&(this._currentSyncRequest=this._doSyncRequest(e,n)),o=await this._currentSyncRequest}catch(t){return void this._onSyncError(t,e)}finally{this._currentSyncRequest=null}t.store.setSyncToken(o.next_batch),this._failedSyncCount=0,await t.store.setSyncData(o);const r={oldSyncToken:n,nextSyncToken:o.next_batch,catchingUp:this._catchingUp};this.opts.crypto&&await this.opts.crypto.onSyncWillProcess(r);try{await this._processSyncResponse(r,o)}catch(e){d.logger.error("Caught /sync error",e.stack||e),this.client.emit("sync.unexpectedError",e)}r.catchingUp=this._catchingUp,e.hasSyncedBefore||(this._updateSyncState("PREPARED",r),e.hasSyncedBefore=!0),this.opts.crypto&&await this.opts.crypto.onSyncCompleted(r),this._updateSyncState("SYNCING",r),t.store.wantsSave()&&(this.opts.crypto&&await this.opts.crypto.saveDeviceList(0),t.store.save()),this._sync(e)},g.prototype._doSyncRequest=function(e,t){const n=this._getSyncParams(e,t);return this.client._http.authedRequest(void 0,"GET","/sync",n,void 0,n.timeout+8e4)},g.prototype._getSyncParams=function(e,t){let n=this.opts.pollTimeout;("SYNCING"!==this.getSyncState()||this._catchingUp)&&(this._catchingUp=!0,n=0);let o=e.filterId;this.client.isGuest()&&!o&&(o=this._getGuestFilter());const r={filter:o,timeout:n};return this.opts.disablePresence&&(r.set_presence="offline"),t?r.since=t:r._cacheBuster=Date.now(),"ERROR"!=this.getSyncState()&&"RECONNECTING"!=this.getSyncState()||(r.timeout=0),r},g.prototype._onSyncError=function(e,t){if(!this._running)return f("Sync no longer running: exiting"),this._connectionReturnedDefer&&(this._connectionReturnedDefer.reject(),this._connectionReturnedDefer=null),void this._updateSyncState("STOPPED");d.logger.error("/sync error %s",e),d.logger.error(e),this._shouldAbortSync(e)||(this._failedSyncCount++,d.logger.log("Number of consecutive failed sync requests:",this._failedSyncCount),f("Starting keep-alive"),this._startKeepAlives().then((e=>{e&&"ERROR"===this.getSyncState()&&this._updateSyncState("CATCHUP",{oldSyncToken:null,nextSyncToken:null,catchingUp:!0}),this._sync(t)})),this._currentSyncRequest=null,this._updateSyncState(this._failedSyncCount>=3?"ERROR":"RECONNECTING",{error:e}))},g.prototype._processSyncResponse=async function(e,t){const n=this.client,o=this;if(t.presence&&Array.isArray(t.presence.events)&&t.presence.events.map(n.getEventMapper()).forEach((function(e){let t=n.store.getUser(e.getSender());t?t.setPresenceEvent(e):(t=m(n,e.getSender()),t.setPresenceEvent(e),n.store.storeUser(t)),n.emit("event",e)})),t.account_data&&Array.isArray(t.account_data.events)){const e=t.account_data.events.map(n.getEventMapper()),o=e.reduce(((e,t)=>(e[t.getId()]=n.store.getAccountData(t.getType()),e)),{});n.store.storeAccountDataEvents(e),e.forEach((function(e){if("m.push_rules"===e.getType()){const t=e.getContent();n.pushRules=l.PushProcessor.rewriteDefaultRules(t)}const t=o[e.getId()];return n.emit("accountData",e,t),e}))}if(t.to_device&&Array.isArray(t.to_device.events)&&t.to_device.events.length>0){const e=[];t.to_device.events.map(n.getEventMapper()).map((t=>{if("m.key.verification.cancel"===t.getType()){const n=t.getContent().transaction_id;n&&e.push(n)}return t})).forEach((function(t){const o=t.getContent();if("m.room.message"!=t.getType()||"m.bad.encrypted"!=o.msgtype){if("m.key.verification.start"===t.getType()||"m.key.verification.request"===t.getType()){const n=o.transaction_id;e.includes(n)&&t.flagCancelled()}n.emit("toDeviceEvent",t)}else d.logger.log("Ignoring undecryptable to-device event from "+t.getSender())}))}else this._catchingUp=!1;t.groups&&(t.groups.invite&&this._processGroupSyncEntry(t.groups.invite,"invite"),t.groups.join&&this._processGroupSyncEntry(t.groups.join,"join"),t.groups.leave&&this._processGroupSyncEntry(t.groups.leave,"leave"));let r=[],i=[],a=[];if(t.rooms&&(t.rooms.invite&&(r=this._mapSyncResponseToRoomArray(t.rooms.invite)),t.rooms.join&&(i=this._mapSyncResponseToRoomArray(t.rooms.join)),t.rooms.leave&&(a=this._mapSyncResponseToRoomArray(t.rooms.leave))),this._notifEvents=[],r.forEach((function(e){const t=e.room,r=o._mapSyncEventsFormat(e.invite_state,t);o._processRoomEvents(t,r),e.isBrandNewRoom&&(t.recalculate(),n.store.storeRoom(t),n.emit("Room",t)),r.forEach((function(e){n.emit("event",e)})),t.updateMyMembership("invite")})),await s.promiseMapSeries(i,(async function(t){const r=t.room,i=o._mapSyncEventsFormat(t.state,r),a=o._mapSyncEventsFormat(t.timeline,r,!1),u=o._mapSyncEventsFormat(t.ephemeral),l=o._mapSyncEventsFormat(t.account_data),d=n.isRoomEncrypted(r.roomId);if(t.unread_notifications&&(r.setUnreadNotificationCount("total",t.unread_notifications.notification_count),(!d||d&&r.getUnreadNotificationCount("highlight")<=0)&&r.setUnreadNotificationCount("highlight",t.unread_notifications.highlight_count)),t.timeline=t.timeline||{},t.isBrandNewRoom)r.getLiveTimeline().setPaginationToken(t.timeline.prev_batch,c.EventTimeline.BACKWARDS);else if(t.timeline.limited){let i=!0;for(let e=a.length-1;e>=0;e--){const t=a[e].getId();if(r.getTimelineForEvent(t)){f("Already have event "+t+" in limited sync - not resetting"),i=!1,a.splice(0,e);break}}i&&(o._deregisterStateListeners(r),r.resetLiveTimeline(t.timeline.prev_batch,o.opts.canResetEntireTimeline(r.roomId)?null:e.oldSyncToken),n.resetNotifTimelineSet(),o._registerStateListeners(r))}async function h(e){if(n.emit("event",e),e.isState()&&"m.room.encryption"==e.getType()&&o.opts.crypto&&await o.opts.crypto.onCryptoEvent(e),e.isState()&&"im.vector.user_status"===e.getType()){let t=n.store.getUser(e.getStateKey());t?t._unstable_updateStatusMessage(e):(t=m(n,e.getStateKey()),t._unstable_updateStatusMessage(e),n.store.storeUser(t))}}o._processRoomEvents(r,i,a,e.fromCache),t.summary&&r.setSummary(t.summary),r.addEphemeralEvents(u),r.addAccountData(l),r.recalculate(),t.isBrandNewRoom&&(n.store.storeRoom(r),n.emit("Room",r)),o._processEventsForNotifs(r,a),await s.promiseMapSeries(i,h),await s.promiseMapSeries(a,h),u.forEach((function(e){n.emit("event",e)})),l.forEach((function(e){n.emit("event",e)})),r.updateMyMembership("join"),r.decryptCriticalEvents()})),a.forEach((function(e){const t=e.room,r=o._mapSyncEventsFormat(e.state,t),i=o._mapSyncEventsFormat(e.timeline,t),a=o._mapSyncEventsFormat(e.account_data);o._processRoomEvents(t,r,i),t.addAccountData(a),t.recalculate(),e.isBrandNewRoom&&(n.store.storeRoom(t),n.emit("Room",t)),o._processEventsForNotifs(t,i),r.forEach((function(e){n.emit("event",e)})),i.forEach((function(e){n.emit("event",e)})),a.forEach((function(e){n.emit("event",e)})),t.updateMyMembership("leave")})),e.oldSyncToken&&this._notifEvents.length&&(this._notifEvents.sort((function(e,t){return e.getTs()-t.getTs()})),this._notifEvents.forEach((function(e){n.getNotifTimelineSet().addLiveEvent(e)}))),t.device_lists&&this.opts.crypto&&await this.opts.crypto.handleDeviceListChanges(e,t.device_lists),this.opts.crypto&&t.device_one_time_keys_count){const e=t.device_one_time_keys_count.signed_curve25519||0;this.opts.crypto.updateOneTimeKeyCount(e)}if(this.opts.crypto&&t["org.matrix.msc2732.device_unused_fallback_key_types"]){const e=t["org.matrix.msc2732.device_unused_fallback_key_types"];this.opts.crypto.setNeedsNewFallback(e instanceof Array&&!e.includes("signed_curve25519"))}},g.prototype._startKeepAlives=function(e){void 0===e&&(e=2e3+Math.floor(5e3*Math.random())),null!==this._keepAliveTimer&&clearTimeout(this._keepAliveTimer);const t=this;return e>0?t._keepAliveTimer=setTimeout(t._pokeKeepAlive.bind(t),e):t._pokeKeepAlive(),this._connectionReturnedDefer||(this._connectionReturnedDefer=s.defer()),this._connectionReturnedDefer.promise},g.prototype._pokeKeepAlive=function(e){void 0===e&&(e=!1);const t=this;function n(){clearTimeout(t._keepAliveTimer),t._connectionReturnedDefer&&(t._connectionReturnedDefer.resolve(e),t._connectionReturnedDefer=null)}this.client._http.request(void 0,"GET","/_matrix/client/versions",void 0,void 0,{prefix:"",localTimeoutMs:15e3}).then((function(){n()}),(function(o){400==o.httpStatus||404==o.httpStatus?t._keepAliveTimer=setTimeout(n,2e3):(e=!0,t._keepAliveTimer=setTimeout(t._pokeKeepAlive.bind(t,e),5e3+Math.floor(5e3*Math.random())),t._updateSyncState("ERROR",{error:o}))}))},g.prototype._processGroupSyncEntry=function(e,t){for(const n of Object.keys(e)){const o=e[n];let r=this.client.store.getGroup(n);const i=null===r;null===r&&(r=this.createGroup(n)),o.profile&&r.setProfile(o.profile.name,o.profile.avatar_url),o.inviter&&r.setInviter({userId:o.inviter}),r.setMyMembership(t),i&&this.client.emit("Group",r)}},g.prototype._mapSyncResponseToRoomArray=function(e){const t=this.client,n=this;return Object.keys(e).map((function(o){const r=e[o];let i=t.store.getRoom(o),a=!1;return i||(i=n.createRoom(o),a=!0),r.room=i,r.isBrandNewRoom=a,r}))},g.prototype._mapSyncEventsFormat=function(e,t,n=!0){if(!e||!Array.isArray(e.events))return[];const o=this.client.getEventMapper({decrypt:n});return e.events.map((function(e){return t&&(e.room_id=t.roomId),o(e)}))},g.prototype._resolveInvites=function(e){if(!e||!this.opts.resolveInvitesToProfiles)return;const t=this.client;e.getMembersWithMembership("invite").forEach((function(n){if(n._requestedProfileInfo)return;n._requestedProfileInfo=!0;const o=t.getUser(n.userId);let r;r=o?Promise.resolve({avatar_url:o.avatarUrl,displayname:o.displayName}):t.getProfileInfo(n.userId),r.then((function(t){const o=n.events.member;"invite"===o.getContent().membership&&(o.getContent().avatar_url=t.avatar_url,o.getContent().displayname=t.displayname,n.setMembershipEvent(o,e.currentState))}),(function(e){}))}))},g.prototype._processRoomEvents=function(e,t,n,o){const r=e.getLiveTimeline(),i=0==r.getEvents().length;if(i){for(const e of t)this.client.getPushActionsForEvent(e);r.initialiseState(t)}this._resolveInvites(e),e.recalculate(),i||(e.oldState.setStateEvents(t||[]),e.currentState.setStateEvents(t||[])),e.addLiveEvents(n||[],null,o)},g.prototype._processEventsForNotifs=function(e,t){if(this.client.getNotifTimelineSet())for(let e=0;e{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.TimelineWindow=r,t.TimelineIndex=i;var o=n(88910);n(7434);function r(e,t,n){n=n||{},this._client=e,this._timelineSet=t,this._start=null,this._end=null,this._eventCount=0,this._windowLimit=n.windowLimit||1e3}function i(e,t){this.timeline=e,this.index=t}r.prototype.load=function(e,t){const n=this;t=t||20;const o=function(o){let r;const a=o.getEvents();if(e){for(let t=0;t0&&this.unpaginate(t,e!=o.EventTimeline.BACKWARDS),!0}return!1},r.prototype.canPaginate=function(e){const t=this.getTimelineIndex(e);if(!t)return!1;if(e==o.EventTimeline.BACKWARDS){if(t.index>t.minIndex())return!0}else if(t.indexthis._eventCount||e<0)throw new Error("Attemting to unpaginate "+e+" events, but only have "+this._eventCount+" in the timeline");for(;e>0;){const o=t?n.advance(e):n.retreat(e);if(o<=0)throw new Error("Unable to unpaginate any further, but still have "+this._eventCount+" events");e-=o,this._eventCount-=o,this._eventCount}},r.prototype.getEvents=function(){if(!this._start)return[];const e=[];let t=this._start.timeline;for(;;){const n=t.getEvents();let r=0,i=n.length;t===this._start.timeline&&(r=this._start.index+t.getBaseIndex()),t===this._end.timeline&&(i=this._end.index+t.getBaseIndex());for(let t=r;t0)return this.index+=t,t;const n=this.timeline.getNeighbouringTimeline(e<0?o.EventTimeline.BACKWARDS:o.EventTimeline.FORWARDS);return n?(this.timeline=n,this.index=e<0?this.maxIndex():this.minIndex(),this.advance(e)):0},i.prototype.retreat=function(e){return-1*this.advance(-1*e)}},3102:(e,t,n)=>{"use strict";var o=n(95318);Object.defineProperty(t,"__esModule",{value:!0}),t.encodeParams=function(e){let t="";for(const n in e)e.hasOwnProperty(n)&&(t+="&"+encodeURIComponent(n)+"="+encodeURIComponent(e[n]));return t.substring(1)},t.encodeUri=function(e,t){for(const n in t)t.hasOwnProperty(n)&&(e=e.replace(n,encodeURIComponent(t[n])));return e},t.removeElement=function(e,t,n){let o,r;if(n){for(o=e.length-1;o>=0;o--)if(t(e[o],o,e))return r=e[o],e.splice(o,1),r}else for(o=0;o?@[\]^_`{|}~\u2000-\u206f\u2e00-\u2e7f]/g,"").toLowerCase()},t.escapeRegExp=s,t.globToRegexp=function(e,t){t="boolean"!=typeof t||t;let n=s(e);return n=n.replace(/\\\*/g,".*"),n=n.replace(/\?/g,"."),t&&(n=n.replace(/\\\[(!|)(.*)\\]/g,(function(e,t,n,o,r){return"["+(t?"^":"")+n.replace(/\\-/,"-")+"]"}))),n},t.ensureNoTrailingSlash=function(e){return e&&e.endsWith("/")?e.substr(0,e.length-1):e},t.sleep=function(e,t){return new Promise((n=>{setTimeout(n,e,t)}))},t.isNullOrUndefined=function(e){return null==e},t.defer=function(){let e,t;const n=new Promise(((n,o)=>{e=n,t=o}));return{resolve:e,reject:t,promise:n}},t.promiseMapSeries=async function(e,t){for(const n of await e)await t(await n)},t.promiseTry=function(e){return new Promise((t=>t(e())))},t.chunkPromises=async function(e,t){const n=[];for(let o=0;oe()))));return n},t.setCrypto=function(e){u=e},t.getCrypto=function(){return u};var r=o(n(85067));function i(e){return"string"==typeof e?(0,r.default)(e.normalize("NFD").replace(a,"")):""}const a=/[\u2000-\u200F\u202A-\u202F\u0300-\u036f\uFEFF\s]/g;function s(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}let u},59679:(e,t,n)=>{"use strict";var o=n(20862),r=n(95318);Object.defineProperty(t,"__esModule",{value:!0}),t.getDesktopCapturerSources=function(){return window.electron.getDesktopCapturerSources({thumbnailSize:{height:176,width:312},types:["screen","window"]})},t.setAudioInput=function(e){D=e},t.setVideoInput=function(e){S=e},t.createNewMatrixCall=function(e,t,n){if("undefined"==typeof window||"undefined"==typeof document)return null;try{if(!Boolean(window.RTCPeerConnection||window.RTCSessionDescription||window.RTCIceCandidate||navigator.mediaDevices))return a.logger.error("WebRTC is not supported in this browser / environment"),null}catch(e){return a.logger.error("Exception thrown when trying to access WebRTC",e),null}const o=!!n&&n.forceTURN,r={client:e,roomId:t,turnServers:e.getTurnServers(),forceTURN:e._forceTURN||o},i=new w(r);return e.reEmitter.reEmit(i,Object.values(_)),i},t.MatrixCall=t.CallError=t.CallErrorCode=t.CallEvent=t.CallParty=t.CallDirection=t.CallType=t.CallState=void 0;var i=r(n(59713)),a=n(7434),s=n(17187),u=o(n(3102)),c=n(42481),l=n(98401),d=n(15964),h=n(49704);let p,f,g,m,_,F;var y;t.CallState=p,function(e){e.Fledgling="fledgling",e.InviteSent="invite_sent",e.WaitLocalMedia="wait_local_media",e.CreateOffer="create_offer",e.CreateAnswer="create_answer",e.Connecting="connecting",e.Connected="connected",e.Ringing="ringing",e.Ended="ended"}(p||(t.CallState=p={})),t.CallType=f,function(e){e.Voice="voice",e.Video="video"}(f||(t.CallType=f={})),t.CallDirection=g,function(e){e.Inbound="inbound",e.Outbound="outbound"}(g||(t.CallDirection=g={})),t.CallParty=m,function(e){e.Local="local",e.Remote="remote"}(m||(t.CallParty=m={})),t.CallEvent=_,function(e){e.Hangup="hangup",e.State="state",e.Error="error",e.Replaced="replaced",e.LocalHoldUnhold="local_hold_unhold",e.RemoteHoldUnhold="remote_hold_unhold",e.HoldUnhold="hold_unhold",e.FeedsChanged="feeds_changed",e.AssertedIdentityChanged="asserted_identity_changed"}(_||(t.CallEvent=_={})),t.CallErrorCode=F,function(e){e.UserHangup="user_hangup",e.LocalOfferFailed="local_offer_failed",e.NoUserMedia="no_user_media",e.UnknownDevices="unknown_devices",e.SendInvite="send_invite",e.CreateAnswer="create_answer",e.SendAnswer="send_answer",e.SetRemoteDescription="set_remote_description",e.SetLocalDescription="set_local_description",e.AnsweredElsewhere="answered_elsewhere",e.IceFailed="ice_failed",e.InviteTimeout="invite_timeout",e.Replaced="replaced",e.SignallingFailed="signalling_timeout",e.UserBusy="user_busy"}(F||(t.CallErrorCode=F={})),function(e){e.Audio="audio",e.Video="video"}(y||(y={}));class b extends Error{constructor(e,t,n){super(t+": "+n),(0,i.default)(this,"code",void 0),this.code=e}}function v(){return Date.now().toString()+(0,l.randomString)(16)}t.CallError=b;class w extends s.EventEmitter{constructor(e){super(),(0,i.default)(this,"roomId",void 0),(0,i.default)(this,"type",void 0),(0,i.default)(this,"callId",void 0),(0,i.default)(this,"state",void 0),(0,i.default)(this,"hangupParty",void 0),(0,i.default)(this,"hangupReason",void 0),(0,i.default)(this,"direction",void 0),(0,i.default)(this,"ourPartyId",void 0),(0,i.default)(this,"client",void 0),(0,i.default)(this,"forceTURN",void 0),(0,i.default)(this,"turnServers",void 0),(0,i.default)(this,"candidateSendQueue",void 0),(0,i.default)(this,"candidateSendTries",void 0),(0,i.default)(this,"sentEndOfCandidates",void 0),(0,i.default)(this,"peerConn",void 0),(0,i.default)(this,"feeds",void 0),(0,i.default)(this,"screenSharingStream",void 0),(0,i.default)(this,"localAVStream",void 0),(0,i.default)(this,"inviteOrAnswerSent",void 0),(0,i.default)(this,"waitForLocalAVStream",void 0),(0,i.default)(this,"config",void 0),(0,i.default)(this,"successor",void 0),(0,i.default)(this,"opponentMember",void 0),(0,i.default)(this,"opponentVersion",void 0),(0,i.default)(this,"opponentPartyId",void 0),(0,i.default)(this,"opponentCaps",void 0),(0,i.default)(this,"inviteTimeout",void 0),(0,i.default)(this,"remoteOnHold",void 0),(0,i.default)(this,"unholdingRemote",void 0),(0,i.default)(this,"micMuted",void 0),(0,i.default)(this,"vidMuted",void 0),(0,i.default)(this,"callStatsAtEnd",void 0),(0,i.default)(this,"makingOffer",void 0),(0,i.default)(this,"ignoreOffer",void 0),(0,i.default)(this,"remoteCandidateBuffer",new Map),(0,i.default)(this,"remoteAssertedIdentity",void 0),(0,i.default)(this,"gotUserMediaForInvite",(async e=>{if(this.successor)this.successor.gotUserMediaForAnswer(e);else if(this.callHasEnded())this.stopAllMedia();else{this.localAVStream=e,a.logger.info("Got local AV stream with id "+this.localAVStream.id),this.setState(p.CreateOffer),a.logger.debug("gotUserMediaForInvite -> "+this.type),this.screenSharingStream?(a.logger.debug("Setting screen sharing stream to the local video element"),this.pushNewFeed(this.screenSharingStream,this.client.getUserId(),d.SDPStreamMetadataPurpose.Screenshare)):this.pushNewFeed(e,this.client.getUserId(),d.SDPStreamMetadataPurpose.Usermedia),E(e.getAudioTracks(),!0);for(const t of e.getAudioTracks())a.logger.info("Adding audio track with id "+t.id),this.peerConn.addTrack(t,e);for(const t of(this.screenSharingStream||e).getVideoTracks())a.logger.info("Adding video track with id "+t.id),this.peerConn.addTrack(t,e)}})),(0,i.default)(this,"gotUserMediaForAnswer",(async e=>{if(this.callHasEnded())return;this.pushNewFeed(e,this.client.getUserId(),d.SDPStreamMetadataPurpose.Usermedia),this.localAVStream=e,a.logger.info("Got local AV stream with id "+this.localAVStream.id),E(e.getAudioTracks(),!0);for(const t of e.getTracks())this.peerConn.addTrack(t,e);let t;this.setState(p.CreateAnswer);try{t=await this.peerConn.createAnswer()}catch(e){return a.logger.debug("Failed to create answer: ",e),void this.terminate(m.Local,F.CreateAnswer,!0)}try{await this.peerConn.setLocalDescription(t),this.setState(p.Connecting),await new Promise((e=>{setTimeout(e,200)})),this.sendAnswer()}catch(e){return a.logger.debug("Error setting local description!",e),void this.terminate(m.Local,F.SetLocalDescription,!0)}})),(0,i.default)(this,"gotLocalIceCandidate",(e=>{if(e.candidate){if(a.logger.debug("Call "+this.callId+" got local ICE "+e.candidate.sdpMid+" candidate: "+e.candidate.candidate),this.callHasEnded())return;""===e.candidate.candidate&&this.sentEndOfCandidates||(this.queueCandidate(e.candidate),""===e.candidate.candidate&&(this.sentEndOfCandidates=!0))}})),(0,i.default)(this,"onIceGatheringStateChange",(e=>{if(a.logger.debug("ice gathering state changed to "+this.peerConn.iceGatheringState),"complete"===this.peerConn.iceGatheringState&&!this.sentEndOfCandidates){const e={candidate:""};this.queueCandidate(e),this.sentEndOfCandidates=!0}})),(0,i.default)(this,"gotLocalOffer",(async e=>{if(a.logger.debug("Created offer: ",e),this.callHasEnded())return void a.logger.debug("Ignoring newly created offer on call ID "+this.callId+" because the call has ended");try{await this.peerConn.setLocalDescription(e)}catch(e){return a.logger.debug("Error setting local description!",e),void this.terminate(m.Local,F.SetLocalDescription,!0)}if("gathering"===this.peerConn.iceGatheringState&&await new Promise((e=>{setTimeout(e,200)})),this.callHasEnded())return;const t=this.state===p.CreateOffer?c.EventType.CallInvite:c.EventType.CallNegotiate,n={lifetime:6e4};this.state===p.CreateOffer?n.offer=this.peerConn.localDescription:n.description=this.peerConn.localDescription,this.client._supportsCallTransfer&&(n.capabilities={"m.call.transferee":!0}),a.logger.info(`Discarding ${this.candidateSendQueue.length} candidates that will be sent in offer`),this.candidateSendQueue=[];try{await this.sendVoipEvent(t,n)}catch(e){a.logger.error("Failed to send invite",e),e.event&&this.client.cancelPendingEvent(e.event);let t=F.SignallingFailed,n="Signalling failed";return this.state===p.CreateOffer&&(t=F.SendInvite,n="Failed to send invite"),"UnknownDeviceError"==e.name&&(t=F.UnknownDevices,n="Unknown devices present in the room"),this.emit(_.Error,new b(t,n,e)),void this.terminate(m.Local,t,!1)}this.sendCandidateQueue(),this.state===p.CreateOffer&&(this.inviteOrAnswerSent=!0,this.setState(p.InviteSent),this.inviteTimeout=setTimeout((()=>{this.inviteTimeout=null,this.state===p.InviteSent&&this.hangup(F.InviteTimeout,!1)}),6e4))})),(0,i.default)(this,"getLocalOfferFailed",(e=>{a.logger.error("Failed to get local offer",e),this.emit(_.Error,new b(F.LocalOfferFailed,"Failed to get local offer!",e)),this.terminate(m.Local,F.LocalOfferFailed,!1)})),(0,i.default)(this,"getUserMediaFailed",(e=>{this.successor?this.successor.getUserMediaFailed(e):(a.logger.warn("Failed to get user media - ending call",e),this.emit(_.Error,new b(F.NoUserMedia,"Couldn't start capturing media! Is your microphone set up and does this app have permission?",e)),this.terminate(m.Local,F.NoUserMedia,!1))})),(0,i.default)(this,"onIceConnectionStateChanged",(()=>{this.callHasEnded()||(a.logger.debug("Call ID "+this.callId+": ICE connection state changed to: "+this.peerConn.iceConnectionState),"connected"==this.peerConn.iceConnectionState?this.setState(p.Connected):"failed"==this.peerConn.iceConnectionState&&this.hangup(F.IceFailed,!1))})),(0,i.default)(this,"onSignallingStateChanged",(()=>{a.logger.debug("call "+this.callId+": Signalling state changed to: "+this.peerConn.signalingState)})),(0,i.default)(this,"onTrack",(e=>{var t;if(0===e.streams.length)return void a.logger.warn(`Streamless ${e.track.kind} found: ignoring.`);const n=null===(t=this.feeds.find((e=>!e.isLocal())))||void 0===t?void 0:t.stream;if(n&&e.streams[0].id!==n.id)return void a.logger.warn(`Ignoring new stream ID ${e.streams[0].id}: we already have stream ID ${n.id}`);n||a.logger.info("Got remote stream with id "+e.streams[0].id);const o=e.streams[0];a.logger.debug(`Track id ${e.track.id} of kind ${e.track.kind} added`),this.pushNewFeed(o,this.getOpponentMember().userId,d.SDPStreamMetadataPurpose.Usermedia),a.logger.info("playing remote. stream active? "+o.active)})),(0,i.default)(this,"onNegotiationNeeded",(async()=>{if(a.logger.info("Negotation is needed!"),this.state===p.CreateOffer||0!==this.opponentVersion){this.makingOffer=!0;try{const e=await this.peerConn.createOffer();await this.gotLocalOffer(e)}catch(e){return void this.getLocalOfferFailed(e)}finally{this.makingOffer=!1}}else a.logger.info("Opponent does not support renegotiation: ignoring negotiationneeded event")})),(0,i.default)(this,"onHangupReceived",(e=>{a.logger.debug("Hangup received for call ID "+this.callId),this.partyIdMatches(e)||this.state===p.Ringing?this.terminate(m.Remote,e.reason||F.UserHangup,!0):a.logger.info(`Ignoring message from party ID ${e.party_id}: our partner is ${this.opponentPartyId}`)})),(0,i.default)(this,"onRejectReceived",(e=>{a.logger.debug("Reject received for call ID "+this.callId),[p.InviteSent,p.Ringing].includes(this.state)||this.state===p.Fledgling&&this.direction===g.Inbound?this.terminate(m.Remote,e.reason||F.UserHangup,!0):a.logger.debug(`Call is in state: ${this.state}: ignoring reject`)})),(0,i.default)(this,"onAnsweredElsewhere",(e=>{a.logger.debug("Call ID "+this.callId+" answered elsewhere"),this.terminate(m.Remote,F.AnsweredElsewhere,!0)})),this.roomId=e.roomId,this.client=e.client,this.type=null,this.forceTURN=e.forceTURN,this.ourPartyId=this.client.deviceId,this.turnServers=e.turnServers||[],0===this.turnServers.length&&this.client.isFallbackICEServerAllowed()&&this.turnServers.push({urls:["stun:turn.matrix.org"]});for(const e of this.turnServers)u.checkObjectHasKeys(e,["urls"]);this.callId=v(),this.state=p.Fledgling,this.candidateSendQueue=[],this.candidateSendTries=0,this.sentEndOfCandidates=!1,this.inviteOrAnswerSent=!1,this.makingOffer=!1,this.remoteOnHold=!1,this.unholdingRemote=!1,this.micMuted=!1,this.vidMuted=!1,this.feeds=[]}async placeVoiceCall(){a.logger.debug("placeVoiceCall"),this.checkForErrorListener();const e=k(y.Audio);this.type=f.Voice,await this.placeCallWithConstraints(e)}async placeVideoCall(){a.logger.debug("placeVideoCall"),this.checkForErrorListener();const e=k(y.Video);this.type=f.Video,await this.placeCallWithConstraints(e)}async placeScreenSharingCall(e){a.logger.debug("placeScreenSharingCall"),this.checkForErrorListener();try{var t;const n=await async function(e){var t;if(null!==(t=window.electron)&&void 0!==t&&t.getDesktopCapturerSources&&e){a.logger.debug("Electron getDesktopCapturerSources() is available...");const t=await e();return t?{audio:!1,video:{mandatory:{chromeMediaSource:"desktop",chromeMediaSourceId:t.id}}}:null}return a.logger.debug("Electron desktopCapturer is not available..."),{audio:!1,video:!0}}(e);if(!n)return void this.terminate(m.Local,F.NoUserMedia,!1);null!==(t=window.electron)&&void 0!==t&&t.getDesktopCapturerSources?(a.logger.debug("Getting screen stream using getUserMedia()..."),this.screenSharingStream=await navigator.mediaDevices.getUserMedia(n)):(a.logger.debug("Getting screen stream using getDisplayMedia()..."),this.screenSharingStream=await navigator.mediaDevices.getDisplayMedia(n)),a.logger.debug("Got screen stream, requesting audio stream...");const o=k(y.Audio);this.placeCallWithConstraints(o)}catch(e){this.emit(_.Error,new b(F.NoUserMedia,"Failed to get screen-sharing stream: ",e)),this.terminate(m.Local,F.NoUserMedia,!1)}this.type=f.Video}getOpponentMember(){return this.opponentMember}opponentCanBeTransferred(){return Boolean(this.opponentCaps&&this.opponentCaps["m.call.transferee"])}getRemoteAssertedIdentity(){return this.remoteAssertedIdentity}getFeeds(){return this.feeds}getLocalFeeds(){return this.feeds.filter((e=>e.isLocal()))}getRemoteFeeds(){return this.feeds.filter((e=>!e.isLocal()))}noIncomingFeeds(){return!this.feeds.some((e=>!e.isLocal()))}pushNewFeed(e,t,n){const o=this.feeds.find((t=>t.stream.id===e.id));o?o.setNewStream(e):(this.feeds.push(new h.CallFeed(e,t,n,this.client,this.roomId)),this.emit(_.FeedsChanged,this.feeds))}deleteAllFeeds(){this.feeds=[],this.emit(_.FeedsChanged,this.feeds)}async getCurrentCallStats(){return this.callHasEnded()?this.callStatsAtEnd:this.collectCallStats()}async collectCallStats(){if(!this.peerConn)return;const e=await this.peerConn.getStats(),t=[];for(const n of e)t.push(n[1]);return t}async initWithInvite(e){var t;const n=e.getContent();this.direction=g.Inbound,await this.client._checkTurnServers()||a.logger.warn("Failed to get TURN credentials! Proceeding with call anyway..."),this.peerConn=this.createPeerConnection(),this.chooseOpponent(e);try{await this.peerConn.setRemoteDescription(n.offer),await this.addBufferedIceCandidates()}catch(e){return a.logger.debug("Failed to set remote description",e),void this.terminate(m.Local,F.SetRemoteDescription,!1)}const o=null===(t=this.feeds.find((e=>!e.isLocal())))||void 0===t?void 0:t.stream;if(!o||0===o.getTracks().length)return a.logger.error("No remote stream or no tracks after setting remote description!"),void this.terminate(m.Local,F.SetRemoteDescription,!1);this.type=o.getTracks().some((e=>"video"===e.kind))?f.Video:f.Voice,this.setState(p.Ringing),e.getLocalAge()&&setTimeout((()=>{this.state==p.Ringing&&(a.logger.debug("Call invite has expired. Hanging up."),this.hangupParty=m.Remote,this.setState(p.Ended),this.stopAllMedia(),"closed"!=this.peerConn.signalingState&&this.peerConn.close(),this.emit(_.Hangup))}),n.lifetime-e.getLocalAge())}initWithHangup(e){this.setState(p.Ended)}async answer(){if(!this.inviteOrAnswerSent)if(a.logger.debug(`Answering call ${this.callId} of type ${this.type}`),this.localAVStream||this.waitForLocalAVStream)this.localAVStream?this.gotUserMediaForAnswer(this.localAVStream):this.waitForLocalAVStream&&this.setState(p.WaitLocalMedia);else{const e=k(this.type==f.Video?y.Video:y.Audio);a.logger.log("Getting user media with constraints",e),this.setState(p.WaitLocalMedia),this.waitForLocalAVStream=!0;try{const t=await navigator.mediaDevices.getUserMedia(e);this.waitForLocalAVStream=!1,this.gotUserMediaForAnswer(t)}catch(e){return void this.getUserMediaFailed(e)}}}replacedBy(e){a.logger.debug(this.callId+" being replaced by "+e.callId),this.state===p.WaitLocalMedia?(a.logger.debug("Telling new call to wait for local media"),e.waitForLocalAVStream=!0):(this.state===p.CreateOffer||this.state===p.InviteSent)&&(a.logger.debug("Handing local stream to new call"),e.gotUserMediaForAnswer(this.localAVStream),delete this.localAVStream),this.successor=e,this.emit(_.Replaced,e),this.hangup(F.Replaced,!0)}hangup(e,t){if(this.callHasEnded())return;if(a.logger.debug("Ending call "+this.callId),this.terminate(m.Local,e,!t),this.state===p.WaitLocalMedia)return;const n={};e!==F.UserHangup&&(n.reason=e),this.sendVoipEvent(c.EventType.CallHangup,n)}reject(){if(this.state!==p.Ringing)throw Error("Call must be in 'ringing' state to reject!");if(this.opponentVersion<1)return a.logger.info(`Opponent version is less than 1 (${this.opponentVersion}): sending hangup instead of reject`),void this.hangup(F.UserHangup,!0);a.logger.debug("Rejecting call: "+this.callId),this.terminate(m.Local,F.UserHangup,!0),this.sendVoipEvent(c.EventType.CallReject,{})}setLocalVideoMuted(e){this.vidMuted=e,this.updateMuteStatus()}isLocalVideoMuted(){return this.vidMuted}setMicrophoneMuted(e){this.micMuted=e,this.updateMuteStatus()}isMicrophoneMuted(){return this.micMuted}isRemoteOnHold(){return this.remoteOnHold}setRemoteOnHold(e){if(this.isRemoteOnHold()!==e){this.remoteOnHold=e,e||(this.unholdingRemote=!0);for(const t of this.peerConn.getTransceivers())t.direction=e?"inactive":"sendrecv";this.updateMuteStatus(),this.emit(_.RemoteHoldUnhold,this.remoteOnHold)}}isLocalOnHold(){if(this.state!==p.Connected)return!1;if(this.unholdingRemote)return!1;let e=!0;for(const t of this.peerConn.getTransceivers())["inactive","recvonly"].includes(t.currentDirection)||(e=!1);return e}sendDtmfDigit(e){for(const t of this.peerConn.getSenders())if("audio"===t.track.kind&&t.dtmf)return void t.dtmf.insertDTMF(e);throw new Error("Unable to find a track to send DTMF on")}updateMuteStatus(){if(!this.localAVStream)return;const e=this.micMuted||this.remoteOnHold;E(this.localAVStream.getAudioTracks(),!e);const t=this.vidMuted||this.remoteOnHold;E(this.localAVStream.getVideoTracks(),!t)}async sendAnswer(){const e={answer:{sdp:this.peerConn.localDescription.sdp,type:this.peerConn.localDescription.type}};this.client._supportsCallTransfer&&(e.capabilities={"m.call.transferee":!0}),a.logger.info(`Discarding ${this.candidateSendQueue.length} candidates that will be sent in answer`),this.candidateSendQueue=[];try{await this.sendVoipEvent(c.EventType.CallAnswer,e),this.inviteOrAnswerSent=!0}catch(e){this.setState(p.Ringing),this.client.cancelPendingEvent(e.event);let t=F.SendAnswer,n="Failed to send answer";throw"UnknownDeviceError"==e.name&&(t=F.UnknownDevices,n="Unknown devices present in the room"),this.emit(_.Error,new b(t,n,e)),e}this.sendCandidateQueue()}async onRemoteIceCandidatesReceived(e){if(this.callHasEnded())return;const t=e.getContent().candidates;if(!t)return void a.logger.info("Ignoring candidates event with no candidates!");const n=0===e.getContent().version?null:e.getContent().party_id||null;if(void 0===this.opponentPartyId){a.logger.info(`Bufferring ${t.length} candidates until we pick an opponent`);const e=this.remoteCandidateBuffer.get(n)||[];return e.push(...t),void this.remoteCandidateBuffer.set(n,e)}this.partyIdMatches(e.getContent())?await this.addIceCandidates(t):a.logger.info(`Ignoring candidates from party ID ${e.getContent().party_id}: we have chosen party ID ${this.opponentPartyId}`)}async onAnswerReceived(e){if(a.logger.debug(`Got answer for call ID ${this.callId} from party ID ${e.getContent().party_id}`),this.callHasEnded())a.logger.debug(`Ignoring answer because call ID ${this.callId} has ended`);else if(void 0===this.opponentPartyId){this.chooseOpponent(e),await this.addBufferedIceCandidates(),this.setState(p.Connecting);try{await this.peerConn.setRemoteDescription(e.getContent().answer)}catch(e){return a.logger.debug("Failed to set remote description",e),void this.terminate(m.Local,F.SetRemoteDescription,!1)}if(null!==this.opponentPartyId)try{await this.sendVoipEvent(c.EventType.CallSelectAnswer,{selected_party_id:this.opponentPartyId})}catch(e){a.logger.warn("Failed to send select_answer event",e)}}else a.logger.info(`Ignoring answer from party ID ${e.getContent().party_id}: we already have an answer/reject from ${this.opponentPartyId}`)}async onSelectAnswerReceived(e){if(this.direction!==g.Inbound)return void a.logger.warn("Got select_answer for an outbound call: ignoring");const t=e.getContent().selected_party_id;null!=t?t!==this.ourPartyId&&(a.logger.info(`Got select_answer for party ID ${t}: we are party ID ${this.ourPartyId}.`),this.terminate(m.Remote,F.AnsweredElsewhere,!0)):a.logger.warn("Got nonsensical select_answer with null/undefined selected_party_id: ignoring")}async onNegotiateReceived(e){const t=e.getContent().description;if(!t||!t.sdp||!t.type)return void a.logger.info("Ignoring invalid m.call.negotiate event");const n=this.direction===g.Inbound,o="offer"===t.type&&(this.makingOffer||"stable"!=this.peerConn.signalingState);if(this.ignoreOffer=!n&&o,this.ignoreOffer)return void a.logger.info("Ignoring colliding negotiate event because we're impolite");const r=this.isLocalOnHold();"answer"===t.type&&(this.unholdingRemote=!1);try{if(await this.peerConn.setRemoteDescription(t),"offer"===t.type){for(const e of this.peerConn.getTransceivers())e.direction=this.isRemoteOnHold()?"inactive":"sendrecv";const e=await this.peerConn.createAnswer();await this.peerConn.setLocalDescription(e);for(const e of this.peerConn.getTransceivers())e.direction=e.currentDirection;this.sendVoipEvent(c.EventType.CallNegotiate,{description:this.peerConn.localDescription})}}catch(e){a.logger.warn("Failed to complete negotiation",e)}const i=this.isLocalOnHold();r!==i&&(this.emit(_.LocalHoldUnhold,i),this.emit(_.HoldUnhold,i))}async onAssertedIdentityReceived(e){e.getContent().asserted_identity&&(this.remoteAssertedIdentity={id:e.getContent().asserted_identity.id,displayName:e.getContent().asserted_identity.display_name},this.emit(_.AssertedIdentityChanged))}callHasEnded(){return this.state===p.Ended}setState(e){const t=this.state;this.state=e,this.emit(_.State,e,t)}sendVoipEvent(e,t){return this.client.sendEvent(this.roomId,e,Object.assign({},t,{version:1,call_id:this.callId,party_id:this.ourPartyId}))}queueCandidate(e){if(this.candidateSendQueue.push(e),this.state===p.Ringing||!this.inviteOrAnswerSent)return;const t=this.direction===g.Inbound?500:2e3;0===this.candidateSendTries&&setTimeout((()=>{this.sendCandidateQueue()}),t)}async transfer(e){const t=await this.client.getProfileInfo(e),n=v(),o={replacement_id:v(),target_user:{id:e,display_name:t.display_name,avatar_url:t.avatar_url},create_call:n};await this.sendVoipEvent(c.EventType.CallReplaces,o),await this.terminate(m.Local,F.Replaced,!0)}async transferToCall(e){const t=await this.client.getProfileInfo(e.getOpponentMember().userId),n=await this.client.getProfileInfo(this.getOpponentMember().userId),o=v(),r={replacement_id:v(),target_user:{id:this.getOpponentMember().userId,display_name:n.display_name,avatar_url:n.avatar_url},await_call:o};await e.sendVoipEvent(c.EventType.CallReplaces,r);const i={replacement_id:v(),target_user:{id:e.getOpponentMember().userId,display_name:t.display_name,avatar_url:t.avatar_url},create_call:o};await this.sendVoipEvent(c.EventType.CallReplaces,i),await this.terminate(m.Local,F.Replaced,!0),await e.terminate(m.Local,F.Replaced,!0)}async terminate(e,t,n){this.callHasEnded()||(this.callStatsAtEnd=await this.collectCallStats(),this.inviteTimeout&&(clearTimeout(this.inviteTimeout),this.inviteTimeout=null),t!==F.Replaced&&this.stopAllMedia(),this.deleteAllFeeds(),this.hangupParty=e,this.hangupReason=t,this.setState(p.Ended),this.peerConn&&"closed"!==this.peerConn.signalingState&&this.peerConn.close(),n&&this.emit(_.Hangup,this))}stopAllMedia(){a.logger.debug(`stopAllMedia (stream=${this.localAVStream})`);for(const e of this.feeds)for(const t of e.stream.getTracks())t.stop()}checkForErrorListener(){if(0===this.listeners("error").length)throw new Error("You MUST attach an error listener using call.on('error', function() {})")}async sendCandidateQueue(){if(0===this.candidateSendQueue.length)return;const e=this.candidateSendQueue;this.candidateSendQueue=[],++this.candidateSendTries;const t={candidates:e};a.logger.debug("Attempting to send "+e.length+" candidates");try{await this.sendVoipEvent(c.EventType.CallCandidates,t)}catch(t){if(t.event&&this.client.cancelPendingEvent(t.event),this.candidateSendQueue.push(...e),this.candidateSendTries>5){a.logger.debug("Failed to send candidates on attempt "+this.candidateSendTries+". Giving up on this call.",t);const e=F.SignallingFailed,n="Signalling failed";return this.emit(_.Error,new b(e,n,t)),void this.hangup(e,!1)}const n=500*Math.pow(2,this.candidateSendTries);++this.candidateSendTries,a.logger.debug("Failed to send candidates. Retrying in "+n+"ms",t),setTimeout((()=>{this.sendCandidateQueue()}),n)}}async placeCallWithConstraints(e){a.logger.log("Getting user media with constraints",e),this.client._callEventHandler.calls.set(this.callId,this),this.setState(p.WaitLocalMedia),this.direction=g.Outbound,this.config=e,await this.client._checkTurnServers()||a.logger.warn("Failed to get TURN credentials! Proceeding with call anyway..."),this.peerConn=this.createPeerConnection();try{const t=await navigator.mediaDevices.getUserMedia(e);this.gotUserMediaForInvite(t)}catch(e){return void this.getUserMediaFailed(e)}}createPeerConnection(){const e=new window.RTCPeerConnection({iceTransportPolicy:this.forceTURN?"relay":void 0,iceServers:this.turnServers,iceCandidatePoolSize:this.client._iceCandidatePoolSize});return e.addEventListener("iceconnectionstatechange",this.onIceConnectionStateChanged),e.addEventListener("signalingstatechange",this.onSignallingStateChanged),e.addEventListener("icecandidate",this.gotLocalIceCandidate),e.addEventListener("icegatheringstatechange",this.onIceGatheringStateChange),e.addEventListener("track",this.onTrack),e.addEventListener("negotiationneeded",this.onNegotiationNeeded),e}partyIdMatches(e){return(0===e.version?null:e.party_id||null)===this.opponentPartyId}chooseOpponent(e){const t=e.getContent();a.logger.debug(`Choosing party ID ${t.party_id} for call ID ${this.callId}`),this.opponentVersion=t.version,0===this.opponentVersion?this.opponentPartyId=null:this.opponentPartyId=t.party_id||null,this.opponentCaps=t.capabilities||{},this.opponentMember=e.sender}async addBufferedIceCandidates(){const e=this.remoteCandidateBuffer.get(this.opponentPartyId);e&&(a.logger.info(`Adding ${e.length} buffered candidates for opponent ${this.opponentPartyId}`),await this.addIceCandidates(e)),this.remoteCandidateBuffer=null}async addIceCandidates(e){for(const t of e)if(null!==t.sdpMid&&void 0!==t.sdpMid||null!==t.sdpMLineIndex&&void 0!==t.sdpMLineIndex){a.logger.debug("Call "+this.callId+" got remote ICE "+t.sdpMid+" candidate: "+t.candidate);try{await this.peerConn.addIceCandidate(t)}catch(e){this.ignoreOffer||a.logger.info("Failed to add remote ICE candidate",e)}}else a.logger.debug("Ignoring remote ICE candidate with no sdpMid or sdpMLineIndex")}}function E(e,t){for(let n=0;n{"use strict";var o=n(95318);Object.defineProperty(t,"__esModule",{value:!0}),t.CallEventHandler=void 0;var r=o(n(59713)),i=n(7434),a=n(59679),s=n(42481);t.CallEventHandler=class{constructor(e){(0,r.default)(this,"client",void 0),(0,r.default)(this,"calls",void 0),(0,r.default)(this,"callEventBuffer",void 0),(0,r.default)(this,"candidateEventsByCall",void 0),(0,r.default)(this,"evaluateEventBuffer",(async()=>{if("SYNCING"===this.client.getSyncState()){await Promise.all(this.callEventBuffer.map((e=>{this.client.decryptEventIfNeeded(e)})));const e=new Set;for(const t of this.callEventBuffer)t.getType()!==s.EventType.CallAnswer&&t.getType()!==s.EventType.CallHangup||e.add(t.getContent().call_id);for(const t of this.callEventBuffer)if(t.getType()!==s.EventType.CallInvite||!e.has(t.getContent().call_id))try{this.handleCallEvent(t)}catch(e){i.logger.error("Caught exception handling call event",e)}this.callEventBuffer=[]}})),(0,r.default)(this,"onEvent",(e=>{this.client.decryptEventIfNeeded(e),(this.eventIsACall(e)||e.isBeingDecrypted())&&this.callEventBuffer.push(e),(e.isBeingDecrypted()||e.isDecryptionFailure())&&e.once("Event.decrypted",(()=>{if(this.eventIsACall(e))if(this.callEventBuffer.includes(e))this.evaluateEventBuffer();else try{this.handleCallEvent(e)}catch(e){i.logger.error("Caught exception handling call event",e)}}))})),this.client=e,this.calls=new Map,this.callEventBuffer=[],this.candidateEventsByCall=new Map}start(){this.client.on("sync",this.evaluateEventBuffer),this.client.on("event",this.onEvent)}stop(){this.client.removeListener("sync",this.evaluateEventBuffer),this.client.removeListener("event",this.onEvent)}eventIsACall(e){const t=e.getType();return t.startsWith("m.call.")||t.startsWith("org.matrix.call.")}handleCallEvent(e){const t=e.getContent();let n=t.call_id?this.calls.get(t.call_id):void 0;if(e.getType()===s.EventType.CallInvite){if(e.getSender()===this.client.credentials.userId)return;if(e.getLocalAge()>t.lifetime-3e3)return;if(n&&n.state===a.CallState.Ended)return;n&&i.logger.log(`WARN: Already have a MatrixCall with id ${t.call_id} but got an invite. Clobbering.`);const o=this.client.getTurnServersExpiry()-Date.now();if(i.logger.info("Current turn creds expire in "+o+" ms"),n=(0,a.createNewMatrixCall)(this.client,e.getRoomId(),{forceTURN:this.client._forceTURN}),!n)return void i.logger.log("Incoming call ID "+t.call_id+" but this client doesn't support WebRTC");if(n.callId=t.call_id,n.initWithInvite(e),this.calls.set(n.callId,n),this.candidateEventsByCall.get(n.callId))for(const e of this.candidateEventsByCall.get(n.callId))n.onRemoteIceCandidatesReceived(e);let r;for(const e of this.calls.values()){const t=[a.CallState.WaitLocalMedia,a.CallState.CreateOffer,a.CallState.InviteSent].includes(e.state);if(n.roomId===e.roomId&&e.direction===a.CallDirection.Outbound&&t){r=e;break}}r?r.state===a.CallState.WaitLocalMedia||r.state===a.CallState.CreateOffer||r.callId>n.callId?(i.logger.log("Glare detected: answering incoming call "+n.callId+" and canceling outgoing call "+r.callId),r.replacedBy(n),n.answer()):(i.logger.log("Glare detected: rejecting incoming call "+n.callId+" and keeping outgoing call "+r.callId),n.hangup(a.CallErrorCode.Replaced,!0)):this.client.emit("Call.incoming",n)}else if(e.getType()===s.EventType.CallAnswer){if(!n)return;e.getSender()===this.client.credentials.userId?n.state===a.CallState.Ringing&&n.onAnsweredElsewhere(t):n.onAnswerReceived(e)}else if(e.getType()===s.EventType.CallCandidates){if(e.getSender()===this.client.credentials.userId)return;n?n.onRemoteIceCandidatesReceived(e):(this.candidateEventsByCall.has(t.call_id)||this.candidateEventsByCall.set(t.call_id,[]),this.candidateEventsByCall.get(t.call_id).push(e))}else if([s.EventType.CallHangup,s.EventType.CallReject].includes(e.getType()))n?n.state!==a.CallState.Ended&&(e.getType()===s.EventType.CallHangup?n.onHangupReceived(t):n.onRejectReceived(t),this.calls.delete(t.call_id)):(n=(0,a.createNewMatrixCall)(this.client,e.getRoomId()),n&&(n.callId=t.call_id,n.initWithHangup(e),this.calls.set(t.call_id,n)));else if(e.getType()===s.EventType.CallSelectAnswer){if(!n)return;if(e.getContent().party_id===n.ourPartyId)return;n.onSelectAnswerReceived(e)}else if(e.getType()===s.EventType.CallNegotiate){if(!n)return;if(e.getContent().party_id===n.ourPartyId)return;n.onNegotiateReceived(e)}else if(e.getType()===s.EventType.CallAssertedIdentity||e.getType()===s.EventType.CallAssertedIdentityPrefix){if(!n)return;if(e.getContent().party_id===n.ourPartyId)return;n.onAssertedIdentityReceived(e)}}}},15964:(e,t)=>{"use strict";let n;Object.defineProperty(t,"__esModule",{value:!0}),t.SDPStreamMetadataPurpose=void 0,t.SDPStreamMetadataPurpose=n,function(e){e.Usermedia="m.usermedia",e.Screenshare="m.screenshare"}(n||(t.SDPStreamMetadataPurpose=n={}))},49704:(e,t,n)=>{"use strict";var o=n(95318);Object.defineProperty(t,"__esModule",{value:!0}),t.CallFeed=t.CallFeedEvent=void 0;var r=o(n(17187));let i;t.CallFeedEvent=i,function(e){e.NewStream="new_stream"}(i||(t.CallFeedEvent=i={}));class a extends r.default{constructor(e,t,n,o,r){super(),this.stream=e,this.userId=t,this.purpose=n,this.client=o,this.roomId=r}getMember(){return this.client.getRoom(this.roomId).getMember(this.userId)}isLocal(){return this.userId===this.client.getUserId()}isAudioMuted(){return 0===this.stream.getAudioTracks().length}isVideoMuted(){return 0===this.stream.getVideoTracks().length}setNewStream(e){this.stream=e,this.emit(i.NewStream,this.stream)}}t.CallFeed=a},62318:(e,t,n)=>{"use strict";var o=n(35717),r=n(3349),i=n(89509).Buffer,a=new Array(16);function s(){r.call(this,64),this._a=1732584193,this._b=4023233417,this._c=2562383102,this._d=271733878}function u(e,t){return e<>>32-t}function c(e,t,n,o,r,i,a){return u(e+(t&n|~t&o)+r+i|0,a)+t|0}function l(e,t,n,o,r,i,a){return u(e+(t&o|n&~o)+r+i|0,a)+t|0}function d(e,t,n,o,r,i,a){return u(e+(t^n^o)+r+i|0,a)+t|0}function h(e,t,n,o,r,i,a){return u(e+(n^(t|~o))+r+i|0,a)+t|0}o(s,r),s.prototype._update=function(){for(var e=a,t=0;t<16;++t)e[t]=this._block.readInt32LE(4*t);var n=this._a,o=this._b,r=this._c,i=this._d;n=c(n,o,r,i,e[0],3614090360,7),i=c(i,n,o,r,e[1],3905402710,12),r=c(r,i,n,o,e[2],606105819,17),o=c(o,r,i,n,e[3],3250441966,22),n=c(n,o,r,i,e[4],4118548399,7),i=c(i,n,o,r,e[5],1200080426,12),r=c(r,i,n,o,e[6],2821735955,17),o=c(o,r,i,n,e[7],4249261313,22),n=c(n,o,r,i,e[8],1770035416,7),i=c(i,n,o,r,e[9],2336552879,12),r=c(r,i,n,o,e[10],4294925233,17),o=c(o,r,i,n,e[11],2304563134,22),n=c(n,o,r,i,e[12],1804603682,7),i=c(i,n,o,r,e[13],4254626195,12),r=c(r,i,n,o,e[14],2792965006,17),n=l(n,o=c(o,r,i,n,e[15],1236535329,22),r,i,e[1],4129170786,5),i=l(i,n,o,r,e[6],3225465664,9),r=l(r,i,n,o,e[11],643717713,14),o=l(o,r,i,n,e[0],3921069994,20),n=l(n,o,r,i,e[5],3593408605,5),i=l(i,n,o,r,e[10],38016083,9),r=l(r,i,n,o,e[15],3634488961,14),o=l(o,r,i,n,e[4],3889429448,20),n=l(n,o,r,i,e[9],568446438,5),i=l(i,n,o,r,e[14],3275163606,9),r=l(r,i,n,o,e[3],4107603335,14),o=l(o,r,i,n,e[8],1163531501,20),n=l(n,o,r,i,e[13],2850285829,5),i=l(i,n,o,r,e[2],4243563512,9),r=l(r,i,n,o,e[7],1735328473,14),n=d(n,o=l(o,r,i,n,e[12],2368359562,20),r,i,e[5],4294588738,4),i=d(i,n,o,r,e[8],2272392833,11),r=d(r,i,n,o,e[11],1839030562,16),o=d(o,r,i,n,e[14],4259657740,23),n=d(n,o,r,i,e[1],2763975236,4),i=d(i,n,o,r,e[4],1272893353,11),r=d(r,i,n,o,e[7],4139469664,16),o=d(o,r,i,n,e[10],3200236656,23),n=d(n,o,r,i,e[13],681279174,4),i=d(i,n,o,r,e[0],3936430074,11),r=d(r,i,n,o,e[3],3572445317,16),o=d(o,r,i,n,e[6],76029189,23),n=d(n,o,r,i,e[9],3654602809,4),i=d(i,n,o,r,e[12],3873151461,11),r=d(r,i,n,o,e[15],530742520,16),n=h(n,o=d(o,r,i,n,e[2],3299628645,23),r,i,e[0],4096336452,6),i=h(i,n,o,r,e[7],1126891415,10),r=h(r,i,n,o,e[14],2878612391,15),o=h(o,r,i,n,e[5],4237533241,21),n=h(n,o,r,i,e[12],1700485571,6),i=h(i,n,o,r,e[3],2399980690,10),r=h(r,i,n,o,e[10],4293915773,15),o=h(o,r,i,n,e[1],2240044497,21),n=h(n,o,r,i,e[8],1873313359,6),i=h(i,n,o,r,e[15],4264355552,10),r=h(r,i,n,o,e[6],2734768916,15),o=h(o,r,i,n,e[13],1309151649,21),n=h(n,o,r,i,e[4],4149444226,6),i=h(i,n,o,r,e[11],3174756917,10),r=h(r,i,n,o,e[2],718787259,15),o=h(o,r,i,n,e[9],3951481745,21),this._a=this._a+n|0,this._b=this._b+o|0,this._c=this._c+r|0,this._d=this._d+i|0},s.prototype._digest=function(){this._block[this._blockOffset++]=128,this._blockOffset>56&&(this._block.fill(0,this._blockOffset,64),this._update(),this._blockOffset=0),this._block.fill(0,this._blockOffset,56),this._block.writeUInt32LE(this._length[0],56),this._block.writeUInt32LE(this._length[1],60),this._update();var e=i.allocUnsafe(16);return e.writeInt32LE(this._a,0),e.writeInt32LE(this._b,4),e.writeInt32LE(this._c,8),e.writeInt32LE(this._d,12),e},e.exports=s},86630:(e,t,n)=>{"use strict";var o=n(62854);e.exports=function(e,t){return n=function(e){var t={};if(!e||!e.type)throw new Error("mdast-util-definitions expected node");return o(e,"definition",(function(e){var n=i(e.identifier);r.call(t,n)||(t[n]=e)})),t}(e),function(e){var t=e&&i(e);return t&&r.call(n,t)?n[t]:null};var n};var r={}.hasOwnProperty;function i(e){return e.toUpperCase()}},52962:(e,t,n)=>{"use strict";e.exports=function(e,t,n,o){var r,i;return"string"==typeof t||t&&"function"==typeof t.exec?i=[[t,n]]:(i=t,o=n),s(e,r=o||{},function e(t){var n=t[0];return function(o,i){var u,c,l,d,h=n[0],p=n[1],f=[],g=0,m=i.children.indexOf(o);for(h.lastIndex=0,c=h.exec(o.value);c&&(u=c.index,!1!==(d=p.apply(null,[].concat(c,{index:c.index,input:c.input})))&&(g!==u&&f.push({type:"text",value:o.value.slice(g,u)}),"string"==typeof d&&d.length>0&&(d={type:"text",value:d}),d&&(f=[].concat(f,d)),g=u+c[0].length),h.global);)c=h.exec(o.value);if(void 0===u?(f=[o],m--):(g1)for(l=e(t.slice(1)),u=-1;++u{"use strict";e.exports=e=>{if("string"!=typeof e)throw new TypeError("Expected a string");return e.replace(/[|\\{}()[\]^$+*?.]/g,"\\$&").replace(/-/g,"\\x2d")}},52524:(e,t,n)=>{"use strict";e.exports=function(e,t,n){return"string"!=typeof t&&(n=t,t=void 0),function(e){var t=e||{},n=function(e,t){for(var n=-1;++n-1&&(w.call(this,e),E.call(this,e))},link:y((function(){var e=this.stack[this.stack.length-1];f("inReference")?(e.type+="Reference",e.referenceType=f("referenceType")||"shortcut",delete e.url,delete e.title):(delete e.identifier,delete e.label,delete e.referenceType),l("referenceType")})),listItem:y(),listOrdered:y(),listUnordered:y(),paragraph:y(),referenceString:function(e){var t=this.resume();this.stack[this.stack.length-1].label=t,this.stack[this.stack.length-1].identifier=a(this.sliceSerialize(e)).toLowerCase(),l("referenceType","full")},resourceDestinationString:function(){var e=this.resume();this.stack[this.stack.length-1].url=e},resourceTitleString:function(){var e=this.resume();this.stack[this.stack.length-1].title=e},resource:function(){l("inReference")},setextHeading:y((function(){l("setextHeadingSlurpLineEnding")})),setextHeadingLineSequence:function(e){this.stack[this.stack.length-1].depth=61===this.sliceSerialize(e).charCodeAt(0)?1:2},setextHeadingText:function(){l("setextHeadingSlurpLineEnding",!0)},strong:y(),thematicBreak:y()}},t.mdastExtensions||[]),u={};return function(e){for(var t,o={type:"root",children:[]},a=[],s=[],u=-1,d={stack:[o],tokenStack:a,config:n,enter:F,exit:b,buffer:_,resume:v,setData:l,getData:f};++u{"use strict";e.exports=n(52524)},57824:(e,t,n)=>{var o=n(30932),r=n(52962),i=n(36996),a=n(10395);function s(e){this.config.enter.autolinkProtocol.call(this,e)}function u(e,t,n,r,i){var a,s,u="";return!!l(i)&&(/^w/i.test(t)&&(n=t+n,t="",u="http://"),!!function(e){var t=e.split(".");return!(t.length<2||t[t.length-1]&&(/_/.test(t[t.length-1])||!/[a-zA-Z\d]/.test(t[t.length-1]))||t[t.length-2]&&(/_/.test(t[t.length-2])||!/[a-zA-Z\d]/.test(t[t.length-2])))}(n)&&!!(a=function(e){var t,n,r,i=/[!"&'),.:;<>?\]}]+$/.exec(e);if(i)for(e=e.slice(0,i.index),t=(i=i[0]).indexOf(")"),n=o(e,"("),r=o(e,")");-1!==t&&n>r;)e+=i.slice(0,t+1),t=(i=i.slice(t+1)).indexOf(")"),r++;return[e,i]}(n+r))[0]&&(s={type:"link",title:null,url:u+t+a[0],children:[{type:"text",value:t+a[0]}]},a[1]&&(s=[s,{type:"text",value:a[1]}]),s))}function c(e,t,n,o){return!(!l(o,!0)||/[_-]$/.test(n))&&{type:"link",title:null,url:"mailto:"+t+"@"+n,children:[{type:"text",value:t+"@"+n}]}}function l(e,t){var n=e.input.charCodeAt(e.index-1);return(n!=n||a(n)||i(n))&&(!t||47!==n)}t.transforms=[function(e){r(e,[[/(https?:\/\/|www(?=\.))([-.\w]+)([^ \t\r\n]*)/i,u],[/([-.\w+]+)@([-\w]+(?:\.[-\w]+)+)/,c]],{ignore:["link","linkReference"]})}],t.enter={literalAutolink:function(e){this.enter({type:"link",title:null,url:"",children:[]},e)},literalAutolinkEmail:s,literalAutolinkHttp:s,literalAutolinkWww:s},t.exit={literalAutolink:function(e){this.exit(e)},literalAutolinkEmail:function(e){this.config.exit.autolinkEmail.call(this,e)},literalAutolinkHttp:function(e){this.config.exit.autolinkProtocol.call(this,e)},literalAutolinkWww:function(e){this.config.exit.data.call(this,e),this.stack[this.stack.length-1].url="http://"+this.sliceSerialize(e)}}},45574:(e,t)=>{var n="phrasing",o=["autolink","link","image","label"];t.unsafe=[{character:"@",before:"[+\\-.\\w]",after:"[\\-.\\w]",inConstruct:n,notInConstruct:o},{character:".",before:"[Ww]",after:"[\\-.\\w]",inConstruct:n,notInConstruct:o},{character:":",before:"[ps]",after:"\\/",inConstruct:n,notInConstruct:o}]},89828:(e,t)=>{t.canContainEols=["delete"],t.enter={strikethrough:function(e){this.enter({type:"delete",children:[]},e)}},t.exit={strikethrough:function(e){this.exit(e)}}},9888:(e,t,n)=>{var o=n(25362);function r(e,t,n){var r=n.enter("emphasis"),i=o(e,n,{before:"~",after:"~"});return r(),"~~"+i+"~~"}t.unsafe=[{character:"~",inConstruct:"phrasing"}],t.handlers={delete:r},r.peek=function(){return"~"}},4865:(e,t)=>{function n(e){this.exit(e)}function o(e){this.enter({type:"tableCell",children:[]},e)}function r(e,t){return"|"===t?t:e}t.enter={table:function(e){this.enter({type:"table",align:e._align,children:[]},e),this.setData("inTable",!0)},tableData:o,tableHeader:o,tableRow:function(e){this.enter({type:"tableRow",children:[]},e)}},t.exit={codeText:function(e){var t=this.resume();this.getData("inTable")&&(t=t.replace(/\\([\\|])/g,r)),this.stack[this.stack.length-1].value=t,this.exit(e)},table:function(e){this.exit(e),this.setData("inTable")},tableData:n,tableHeader:n,tableRow:n}},63046:(e,t,n)=>{var o=n(25362),r=n(11595),i=n(78234);e.exports=function(e){var t=e||{},n=t.tableCellPadding,a=t.tablePipeAlign,s=t.stringLength,u=n?" ":"|";return{unsafe:[{character:"\r",inConstruct:"tableCell"},{character:"\n",inConstruct:"tableCell"},{atBreak:!0,character:"|",after:"[\t :-]"},{character:"|",inConstruct:"tableCell"},{atBreak:!0,character:":",after:"-"},{atBreak:!0,character:"-",after:"[:|-]"}],handlers:{table:function(e,t,n){return l(function(e,t){for(var n=e.children,o=-1,r=n.length,i=[],a=t.enter("table");++o{function n(e){this.stack[this.stack.length-2].checked="taskListCheckValueChecked"===e.type}t.exit={taskListCheckValueChecked:n,taskListCheckValueUnchecked:n,paragraph:function(e){var t,n=this.stack[this.stack.length-2],o=this.stack[this.stack.length-1],r=n.children,i=o.children[0],a=-1;if(n&&"listItem"===n.type&&"boolean"==typeof n.checked&&i&&"text"===i.type){for(;++a{var o=n(48618);t.unsafe=[{atBreak:!0,character:"-",after:"[:|-]"}],t.handlers={listItem:function(e,t,n){var r=o(e,t,n),i=e.children[0];return"boolean"==typeof e.checked&&i&&"paragraph"===i.type&&(r=r.replace(/^(?:[*+-]|\d+\.)([\r\n]| {1,3})/,(function(t){return t+"["+(e.checked?"x":" ")+"] "}))),r}}},10438:(e,t,n)=>{var o=n(57824),r=n(89828),i=n(4865),a=n(29511),s={}.hasOwnProperty;function u(e,t){var n,o,r;for(n in t)o=s.call(e,n)?e[n]:e[n]={},r=t[n],"canContainEols"===n||"transforms"===n?e[n]=[].concat(o,r):Object.assign(o,r)}e.exports=function(e){for(var t={transforms:[],canContainEols:[]},n=e.length,o=-1;++o{var o=n(45574),r=n(9888),i=n(63046),a=n(94625),s=n(2564);e.exports=function(e){var t=s({handlers:{},join:[],unsafe:[],options:{}},{extensions:[o,r,i(e),a]});return Object.assign(t.options,{handlers:t.handlers,join:t.join,unsafe:t.unsafe})}},55288:(e,t,n)=>{"use strict";e.exports=n(31601)},95426:(e,t,n)=>{"use strict";e.exports=function(e,t){for(var n,r,i=t.children||[],a=i.length,s=[],u=-1;++u{"use strict";e.exports=function(e){for(var t,n,a,s,u=e.footnoteById,c=e.footnoteOrder,l=c.length,d=-1,h=[];++d{"use strict";e.exports=function(e,t){return e(t,"blockquote",o(r(e,t),!0))};var o=n(96115),r=n(95426)},13562:(e,t,n)=>{"use strict";e.exports=function(e,t){return[e(t,"br"),o("text","\n")]};var o=n(50914)},37891:(e,t,n)=>{"use strict";e.exports=function(e,t){var n,r=t.value?t.value+"\n":"",i=t.lang&&t.lang.match(/^[^ \t]+(?=[ \t]|$)/),a={};return i&&(a.className=["language-"+i]),n=e(t,"code",a,[o("text",r)]),t.meta&&(n.data={meta:t.meta}),e(t.position,"pre",[n])};var o=n(50914)},59381:(e,t,n)=>{"use strict";e.exports=function(e,t){return e(t,"del",o(e,t))};var o=n(95426)},80790:(e,t,n)=>{"use strict";e.exports=function(e,t){return e(t,"em",o(e,t))};var o=n(95426)},58235:(e,t,n)=>{"use strict";e.exports=function(e,t){var n=e.footnoteOrder,r=String(t.identifier);return-1===n.indexOf(r)&&n.push(r),e(t.position,"sup",{id:"fnref-"+r},[e(t,"a",{href:"#fn-"+r,className:["footnote-ref"]},[o("text",t.label||r)])])};var o=n(50914)},85758:(e,t,n)=>{"use strict";e.exports=function(e,t){for(var n=e.footnoteById,r=e.footnoteOrder,i=1;i in n;)i++;return i=String(i),r.push(i),n[i]={type:"footnoteDefinition",identifier:i,children:[{type:"paragraph",children:t.children}],position:t.position},o(e,{type:"footnoteReference",identifier:i,position:t.position})};var o=n(58235)},34890:(e,t,n)=>{"use strict";e.exports=function(e,t){return e(t,"h"+t.depth,o(e,t))};var o=n(95426)},92202:(e,t,n)=>{"use strict";e.exports=function(e,t){return e.dangerous?e.augment(t,o("raw",t.value)):null};var o=n(50914)},71454:(e,t,n)=>{"use strict";e.exports=function(e,t){var n,i=e.definition(t.identifier);return i?(n={src:o(i.url||""),alt:t.alt},null!==i.title&&void 0!==i.title&&(n.title=i.title),e(t,"img",n)):r(e,t)};var o=n(70729),r=n(713)},5037:(e,t,n)=>{"use strict";var o=n(70729);e.exports=function(e,t){var n={src:o(t.url),alt:t.alt};return null!==t.title&&void 0!==t.title&&(n.title=t.title),e(t,"img",n)}},44617:(e,t,n)=>{"use strict";function o(){return null}e.exports={blockquote:n(34590),break:n(13562),code:n(37891),delete:n(59381),emphasis:n(80790),footnoteReference:n(58235),footnote:n(85758),heading:n(34890),html:n(92202),imageReference:n(71454),image:n(5037),inlineCode:n(28409),linkReference:n(79266),link:n(20404),listItem:n(94463),list:n(47888),paragraph:n(68346),root:n(68100),strong:n(4970),table:n(72605),text:n(50989),thematicBreak:n(37552),toml:o,yaml:o,definition:o,footnoteDefinition:o}},28409:(e,t,n)=>{"use strict";e.exports=function(e,t){var n=t.value.replace(/\r?\n|\r/g," ");return e(t,"code",[o("text",n)])};var o=n(50914)},79266:(e,t,n)=>{"use strict";e.exports=function(e,t){var n,a=e.definition(t.identifier);return a?(n={href:o(a.url||"")},null!==a.title&&void 0!==a.title&&(n.title=a.title),e(t,"a",n,i(e,t))):r(e,t)};var o=n(70729),r=n(713),i=n(95426)},20404:(e,t,n)=>{"use strict";var o=n(70729),r=n(95426);e.exports=function(e,t){var n={href:o(t.url)};return null!==t.title&&void 0!==t.title&&(n.title=t.title),e(t,"a",n,r(e,t))}},94463:(e,t,n)=>{"use strict";e.exports=function(e,t,n){var a,s,u,c=r(e,t),l=c[0],d=n?function(e){for(var t=e.spread,n=e.children,o=n.length,r=-1;!t&&++r0&&l.children.unshift(o("text"," ")),l.children.unshift(e(null,"input",{type:"checkbox",checked:t.checked,disabled:!0})),h.className=["task-list-item"]),a=c.length,s=-1;++s1:t}},47888:(e,t,n)=>{"use strict";e.exports=function(e,t){var n,i,a={},s=t.ordered?"ol":"ul",u=-1;for("number"==typeof t.start&&1!==t.start&&(a.start=t.start),i=(n=r(e,t)).length;++u{"use strict";e.exports=function(e,t){return e(t,"p",o(e,t))};var o=n(95426)},68100:(e,t,n)=>{"use strict";e.exports=function(e,t){return e.augment(t,o("root",r(i(e,t))))};var o=n(50914),r=n(96115),i=n(95426)},4970:(e,t,n)=>{"use strict";e.exports=function(e,t){return e(t,"strong",o(e,t))};var o=n(95426)},72605:(e,t,n)=>{"use strict";e.exports=function(e,t){for(var n,a,s,u,c,l=t.children,d=l.length,h=t.align||[],p=h.length,f=[];d--;){for(a=l[d].children,u=0===d?"th":"td",n=p||a.length,s=[];n--;)c=a[n],s[n]=e(c,u,{align:h[n]},c?i(e,c):[]);f[d]=e(l[d],"tr",r(s,!0))}return e(t,"table",r([e(f[0].position,"thead",r([f[0]],!0))].concat(f[1]?e({start:o.start(f[1]),end:o.end(f[f.length-1])},"tbody",r(f.slice(1),!0)):[]),!0))};var o=n(77361),r=n(96115),i=n(95426)},50989:(e,t,n)=>{"use strict";e.exports=function(e,t){return e.augment(t,o("text",String(t.value).replace(/[ \t]*(\r?\n|\r)[ \t]*/g,"$1")))};var o=n(50914)},37552:e=>{"use strict";e.exports=function(e,t){return e(t,"hr")}},31601:(e,t,n)=>{"use strict";e.exports=function(e,t){var n=function(e,t){var n=t||{};void 0===n.allowDangerousHTML||h||(h=!0,console.warn("mdast-util-to-hast: deprecation: `allowDangerousHTML` is nonstandard, use `allowDangerousHtml` instead"));var o=n.allowDangerousHtml||n.allowDangerousHTML,u={};return p.dangerous=o,p.definition=s(e),p.footnoteById=u,p.footnoteOrder=[],p.augment=c,p.handlers=Object.assign({},l,n.handlers),p.unknownHandler=n.unknownHandler,p.passThrough=n.passThrough,r(e,"footnoteDefinition",(function(e){var t=String(e.identifier).toUpperCase();d.call(u,t)||(u[t]=e)})),p;function c(e,t){var n,o;return e&&e.data&&((n=e.data).hName&&("element"!==t.type&&(t={type:"element",tagName:"",properties:{},children:[]}),t.tagName=n.hName),"element"===t.type&&n.hProperties&&(t.properties=Object.assign({},t.properties,n.hProperties)),t.children&&n.hChildren&&(t.children=n.hChildren)),o=e&&e.position?e:{position:e},a(o)||(t.position={start:i.start(o),end:i.end(o)}),t}function p(e,t,n,o){return null==o&&"object"==typeof n&&"length"in n&&(o=n,n={}),c(e,{type:"element",tagName:t,properties:n||{},children:o||[]})}}(e,t),p=u(n,e),f=c(n);return f&&(p.children=p.children.concat(o("text","\n"),f)),p};var o=n(50914),r=n(62854),i=n(77361),a=n(61744),s=n(86630),u=n(60719),c=n(61696),l=n(44617),d={}.hasOwnProperty,h=!1},60719:(e,t,n)=>{"use strict";e.exports=function(e,t,n){var o,r=t&&t.type;if(!r)throw new Error("Expected node, got `"+t+"`");return("function"==typeof(o=i.call(e.handlers,r)?e.handlers[r]:e.passThrough&&e.passThrough.indexOf(r)>-1?s:e.unknownHandler)?o:a)(e,t,n)};var o=n(50914),r=n(95426),i={}.hasOwnProperty;function a(e,t){return function(e){var t=e.data||{};return!(i.call(t,"hName")||i.call(t,"hProperties")||i.call(t,"hChildren"))&&"value"in e}(t)?e.augment(t,o("text",t.value)):e(t,"div",r(e,t))}function s(e,t){var n;return t.children?((n=Object.assign({},t)).children=r(e,t),n):t}},713:(e,t,n)=>{"use strict";e.exports=function(e,t){var n,i,a,s=t.referenceType,u="]";return"collapsed"===s?u+="[]":"full"===s&&(u+="["+(t.label||t.identifier)+"]"),"imageReference"===t.type?o("text","!["+t.alt+u):((i=(n=r(e,t))[0])&&"text"===i.type?i.value="["+i.value:n.unshift(o("text","[")),(a=n[n.length-1])&&"text"===a.type?a.value+=u:n.push(o("text",u)),n)};var o=n(50914),r=n(95426)},96115:(e,t,n)=>{"use strict";e.exports=function(e,t){var n=[],r=-1,i=e.length;for(t&&n.push(o("text","\n"));++r0&&n.push(o("text","\n")),n};var o=n(50914)},2564:e=>{e.exports=function e(t,n){var o,r=-1;if(n.extensions)for(;++r{e.exports=r,r.peek=function(){return"`"};var o=n(84553);function r(e,t,n){for(var r,i,a,s,u=e.value||"",c="`",l=-1;new RegExp("(^|[^`])"+c+"([^`]|$)").test(u);)c+="`";for(/[^ \r\n]/.test(u)&&(/[ \r\n`]/.test(u.charAt(0))||/[ \r\n`]/.test(u.charAt(u.length-1)))&&(u=" "+u+" ");++l{e.exports=function(e,t,n){var u,c,l,d=r(n),h=i(n);return t&&t.ordered&&(d=(t.start>-1?t.start:1)+(!1===n.options.incrementListMarker?0:t.children.indexOf(e))+"."),u=d.length+1,("tab"===h||"mixed"===h&&(t&&t.spread||e.spread))&&(u=4*Math.ceil(u/4)),l=n.enter("listItem"),c=s(a(e,n),(function(e,t,n){return t?(n?"":o(" ",u))+e:(n?d:d+o(" ",u-d.length))+e})),l(),c};var o=n(96464),r=n(89400),i=n(56636),a=n(93493),s=n(92670)},89400:e=>{e.exports=function(e){var t=e.options.bullet||"*";if("*"!==t&&"+"!==t&&"-"!==t)throw new Error("Cannot serialize items with `"+t+"` for `options.bullet`, expected `*`, `+`, or `-`");return t}},56636:e=>{e.exports=function(e){var t=e.options.listItemIndent||"tab";if(1===t||"1"===t)return"one";if("tab"!==t&&"one"!==t&&"mixed"!==t)throw new Error("Cannot serialize items with `"+t+"` for `options.listItemIndent`, expected `tab`, `one`, or `mixed`");return t}},93493:(e,t,n)=>{e.exports=function(e,t){for(var n,r=e.children||[],i=[],a=-1;++a{e.exports=function(e,t,n){for(var o,r,i,a=e.children||[],s=[],u=-1,c=n.before;++u0&&("\r"===c||"\n"===c)&&"html"===i.type&&(s[s.length-1]=s[s.length-1].replace(/(\r?\n|\r)$/," "),c=" "),s.push(t.handle(i,e,t,{before:c,after:o})),c=s[s.length-1].slice(-1);return s.join("")}},92670:e=>{e.exports=function(e,n){for(var o,r=[],i=0,a=0;o=t.exec(e);)s(e.slice(i,o.index)),r.push(o[0]),i=o.index+o[0].length,a++;return s(e.slice(i)),r.join("");function s(e){r.push(n(e,a,!e))}};var t=/\r?\n|\r/g},84553:e=>{e.exports=function(e){var t,n;return e._compiled||(t=e.before?"(?:"+e.before+")":"",n=e.after?"(?:"+e.after+")":"",e.atBreak&&(t="[\\r\\n][\\t ]*"+t),e._compiled=new RegExp((t?"("+t+")":"")+(/[|\\{}()[\]^$+*?.-]/.test(e.character)?"\\":"")+e.character+(n||""),"g")),e._compiled}},4999:e=>{"use strict";function t(e){return e&&(e.value||e.alt||e.title||"children"in e&&n(e.children)||"length"in e&&n(e))||""}function n(e){for(var n=[],o=-1;++o{"use strict";var t={};function n(e,o,r){var i,a,s,u,c,l="";for("string"!=typeof o&&(r=o,o=n.defaultChars),void 0===r&&(r=!0),c=function(e){var n,o,r=t[e];if(r)return r;for(r=t[e]=[],n=0;n<128;n++)o=String.fromCharCode(n),/^[0-9a-z]$/i.test(o)?r.push(o):r.push("%"+("0"+n.toString(16).toUpperCase()).slice(-2));for(n=0;n=55296&&s<=57343){if(s>=55296&&s<=56319&&i+1=56320&&u<=57343){l+=encodeURIComponent(e[i]+e[i+1]),i++;continue}l+="%EF%BF%BD"}else l+=encodeURIComponent(e[i]);return l}n.defaultChars=";/?:@&=+$,-_.!~*'()#",n.componentChars="-_.!~*'()",e.exports=n},57539:(e,t,n)=>{e.exports=n(62346)},62346:(e,t,n)=>{var o=n(76734),r=n(46712),i=n(89696),a=n(17238),s=n(36996),u=n(10395),c={tokenize:function(e,t,n){return function(t){return e.consume(t),o};function o(t){return 87===t||t-32==87?(e.consume(t),r):n(t)}function r(t){return 87===t||t-32==87?(e.consume(t),i):n(t)}function i(t){return 46===t?(e.consume(t),s):n(t)}function s(e){return null===e||a(e)?n(e):t(e)}},partial:!0},l={tokenize:function(e,t,n){var o,r;return a;function a(t){return 38===t?e.check(p,l,c)(t):46===t||95===t?e.check(h,l,c)(t):i(t)||u(t)||45!==t&&s(t)?l(t):(e.consume(t),a)}function c(t){return 46===t?(r=o,o=void 0,e.consume(t),a):(95===t&&(o=!0),e.consume(t),a)}function l(e){return r||o?n(e):t(e)}},partial:!0},d={tokenize:function(e,t){var n=0;return o;function o(a){return 38===a?e.check(p,t,r)(a):(40===a&&n++,41===a?e.check(h,i,r)(a):b(a)?t(a):y(a)?e.check(h,t,r)(a):(e.consume(a),o))}function r(t){return e.consume(t),o}function i(e){return--n<0?t(e):r(e)}},partial:!0},h={tokenize:function(e,t,n){return function(t){return e.consume(t),o};function o(r){return y(r)?(e.consume(r),o):b(r)?t(r):n(r)}},partial:!0},p={tokenize:function(e,t,n){return function(t){return e.consume(t),r};function r(t){return o(t)?(e.consume(t),r):59===t?(e.consume(t),i):n(t)}function i(e){return b(e)?t(e):n(e)}},partial:!0},f={tokenize:function(e,t,n){var o=this;return function(t){return 87!==t&&t-32!=87||!w(o.previous)||D(o.events)?n(t):(e.enter("literalAutolink"),e.enter("literalAutolinkWww"),e.check(c,e.attempt(l,e.attempt(d,r),n),n)(t))};function r(n){return e.exit("literalAutolinkWww"),e.exit("literalAutolink"),t(n)}},previous:w},g={tokenize:function(e,t,n){var o=this;return function(t){return 72!==t&&t-32!=72||!E(o.previous)||D(o.events)?n(t):(e.enter("literalAutolink"),e.enter("literalAutolinkHttp"),e.consume(t),r)};function r(t){return 84===t||t-32==84?(e.consume(t),a):n(t)}function a(t){return 84===t||t-32==84?(e.consume(t),c):n(t)}function c(t){return 80===t||t-32==80?(e.consume(t),h):n(t)}function h(t){return 83===t||t-32==83?(e.consume(t),p):p(t)}function p(t){return 58===t?(e.consume(t),f):n(t)}function f(t){return 47===t?(e.consume(t),g):n(t)}function g(t){return 47===t?(e.consume(t),m):n(t)}function m(t){return i(t)||u(t)||s(t)?n(t):e.attempt(l,e.attempt(d,_),n)(t)}function _(n){return e.exit("literalAutolinkHttp"),e.exit("literalAutolink"),t(n)}},previous:E},m={tokenize:function(e,t,n){var o,i=this;return function(t){return v(t)&&k(i.previous)&&!D(i.events)?(e.enter("literalAutolink"),e.enter("literalAutolinkEmail"),a(t)):n(t)};function a(t){return v(t)?(e.consume(t),a):64===t?(e.consume(t),s):n(t)}function s(t){return 46===t?e.check(h,d,u)(t):45===t||95===t?e.check(h,n,c)(t):r(t)?(e.consume(t),s):d(t)}function u(t){return e.consume(t),o=!0,s}function c(t){return e.consume(t),l}function l(t){return 46===t?e.check(h,n,u)(t):s(t)}function d(r){return o?(e.exit("literalAutolinkEmail"),e.exit("literalAutolink"),t(r)):n(r)}},previous:k},_={};t.text=_;for(var F=48;F<123;)_[F]=m,58==++F?F=65:91===F&&(F=97);function y(e){return 33===e||34===e||39===e||41===e||42===e||44===e||46===e||58===e||59===e||60===e||63===e||95===e||126===e}function b(e){return null===e||e<0||32===e||60===e}function v(e){return 43===e||45===e||46===e||95===e||r(e)}function w(e){return null===e||e<0||32===e||40===e||42===e||95===e||126===e}function E(e){return null===e||!o(e)}function k(e){return 47!==e&&E(e)}function D(e){for(var t=e.length;t--;)if(("labelLink"===e[t][1].type||"labelImage"===e[t][1].type)&&!e[t][1]._balanced)return!0}_[43]=m,_[45]=m,_[46]=m,_[95]=m,_[72]=[m,g],_[104]=[m,g],_[87]=[m,f],_[119]=[m,f]},3490:(e,t,n)=>{e.exports=function(e){var t=(e||{}).singleTilde,n={tokenize:function(e,n,r){var i=this.previous,a=this.events,s=0;return function(t){return 126!==t||126===i&&"characterEscape"!==a[a.length-1][1].type?r(t):(e.enter("strikethroughSequenceTemporary"),u(t))};function u(a){var c,l,d=o(i);return 126===a?s>1?r(a):(e.consume(a),s++,u):s<2&&!t?r(a):(c=e.exit("strikethroughSequenceTemporary"),l=o(a),c._open=!l||2===l&&d,c._close=!d||2===d&&l,n(a))}},resolveAll:function(e,t){for(var n,o,s,u,c=-1;++c{e.exports=n(23993)},23993:(e,t,n)=>{t.flow={null:{tokenize:function(e,t,n){var a,s,u=[],c=0;return function(t){return null===t||-5===t||-4===t||-3===t?n(t):(e.enter("table")._align=u,e.enter("tableHead"),e.enter("tableRow"),124===t?l(t):(c++,e.enter("temporaryTableCellContent"),p(t)))};function l(t){return e.enter("tableCellDivider"),e.consume(t),e.exit("tableCellDivider"),a=!0,d}function d(t){return null===t||-5===t||-4===t||-3===t?function(t){return null===t?n(t):(e.exit("tableRow"),e.exit("tableHead"),e.enter("lineEnding"),e.consume(t),e.exit("lineEnding"),e.check(r,n,o(e,g,"linePrefix",4)))}(t):-2===t||-1===t||32===t?(e.enter("whitespace"),e.consume(t),h):(a&&(a=void 0,c++),124===t?l(t):(e.enter("temporaryTableCellContent"),p(t)))}function h(t){return-2===t||-1===t||32===t?(e.consume(t),h):(e.exit("whitespace"),d(t))}function p(t){return null===t||t<0||32===t||124===t?(e.exit("temporaryTableCellContent"),d(t)):(e.consume(t),92===t?f:p)}function f(t){return 92===t||124===t?(e.consume(t),p):p(t)}function g(t){return null===t||t<0||32===t?n(t):(e.enter("tableDelimiterRow"),m(t))}function m(t){return null===t||-5===t||-4===t||-3===t?v(t):-2===t||-1===t||32===t?(e.enter("whitespace"),e.consume(t),_):45===t?(e.enter("tableDelimiterFiller"),e.consume(t),s=!0,u.push(null),F):58===t?(e.enter("tableDelimiterAlignment"),e.consume(t),e.exit("tableDelimiterAlignment"),u.push("left"),y):124===t?(e.enter("tableCellDivider"),e.consume(t),e.exit("tableCellDivider"),m):n(t)}function _(t){return-2===t||-1===t||32===t?(e.consume(t),_):(e.exit("whitespace"),m(t))}function F(t){return 45===t?(e.consume(t),F):(e.exit("tableDelimiterFiller"),58===t?(e.enter("tableDelimiterAlignment"),e.consume(t),e.exit("tableDelimiterAlignment"),u[u.length-1]="left"===u[u.length-1]?"center":"right",b):m(t))}function y(t){return 45===t?(e.enter("tableDelimiterFiller"),e.consume(t),s=!0,F):n(t)}function b(t){return null===t||-5===t||-4===t||-3===t?v(t):-2===t||-1===t||32===t?(e.enter("whitespace"),e.consume(t),_):124===t?(e.enter("tableCellDivider"),e.consume(t),e.exit("tableCellDivider"),m):n(t)}function v(t){return e.exit("tableDelimiterRow"),s&&c===u.length?null===t?w(t):e.check(i,w,E)(t):n(t)}function w(n){return e.exit("table"),t(n)}function E(t){return e.enter("lineEnding"),e.consume(t),e.exit("lineEnding"),o(e,k,"linePrefix",4)}function k(t){return e.enter("tableBody"),D(t)}function D(t){return e.enter("tableRow"),124===t?S(t):(e.enter("temporaryTableCellContent"),A(t))}function S(t){return e.enter("tableCellDivider"),e.consume(t),e.exit("tableCellDivider"),x}function x(t){return null===t||-5===t||-4===t||-3===t?function(t){return e.exit("tableRow"),null===t?R(t):e.check(i,R,I)(t)}(t):-2===t||-1===t||32===t?(e.enter("whitespace"),e.consume(t),C):124===t?S(t):(e.enter("temporaryTableCellContent"),A(t))}function C(t){return-2===t||-1===t||32===t?(e.consume(t),C):(e.exit("whitespace"),x(t))}function A(t){return null===t||t<0||32===t||124===t?(e.exit("temporaryTableCellContent"),x(t)):(e.consume(t),92===t?T:A)}function T(t){return 92===t||124===t?(e.consume(t),A):A(t)}function R(t){return e.exit("tableBody"),w(t)}function I(t){return e.enter("lineEnding"),e.consume(t),e.exit("lineEnding"),o(e,D,"linePrefix",4)}},resolve:function(e,t){for(var n,o,r,i,a,s,u,c,l,d,h=e.length,p=-1;++p{e.exports=n(27224)},27224:(e,t,n)=>{var o=n(88367),r=n(52928),i=n(15096),a={tokenize:function(e,t,n){var o=this;return function(t){return 91===t&&null===o.previous&&o._gfmTasklistFirstContentOfListItem?(e.enter("taskListCheck"),e.enter("taskListCheckMarker"),e.consume(t),e.exit("taskListCheckMarker"),r):n(t)};function r(t){return-2===t||32===t?(e.enter("taskListCheckValueUnchecked"),e.consume(t),e.exit("taskListCheckValueUnchecked"),i):88===t||120===t?(e.enter("taskListCheckValueChecked"),e.consume(t),e.exit("taskListCheckValueChecked"),i):n(t)}function i(o){return 93===o?(e.enter("taskListCheckMarker"),e.consume(o),e.exit("taskListCheckMarker"),e.exit("taskListCheck"),e.check({tokenize:s},t,n)):n(o)}}};function s(e,t,n){var a=this;return r(e,(function(e){return i(a.events,"whitespace")&&null!==e&&!o(e)?t(e):n(e)}),"whitespace")}t.text={91:a}},82747:(e,t,n)=>{e.exports=n(2518)},2518:(e,t,n)=>{var o=n(12952),r=n(57539),i=n(3490),a=n(81286),s=n(5675);e.exports=function(e){return o([r,i(e),a,s])}},76734:(e,t,n)=>{"use strict";var o=n(2841)(/[A-Za-z]/);e.exports=o},46712:(e,t,n)=>{"use strict";var o=n(2841)(/[\dA-Za-z]/);e.exports=o},13571:(e,t,n)=>{"use strict";var o=n(2841)(/[#-'*+\--9=?A-Z^-~]/);e.exports=o},89696:e=>{"use strict";e.exports=function(e){return e<32||127===e}},73977:(e,t,n)=>{"use strict";var o=n(2841)(/\d/);e.exports=o},56238:(e,t,n)=>{"use strict";var o=n(2841)(/[\dA-Fa-f]/);e.exports=o},83074:(e,t,n)=>{"use strict";var o=n(2841)(/[!-/:-@[-`{-~]/);e.exports=o},88367:e=>{"use strict";e.exports=function(e){return e<0||32===e}},17238:e=>{"use strict";e.exports=function(e){return e<-2}},73654:e=>{"use strict";e.exports=function(e){return-2===e||-1===e||32===e}},36996:(e,t,n)=>{"use strict";var o=n(76830),r=n(2841)(o);e.exports=r},10395:(e,t,n)=>{"use strict";var o=n(2841)(/\s/);e.exports=o},99198:e=>{"use strict";var t=Object.assign;e.exports=t},93267:e=>{"use strict";var t=String.fromCharCode;e.exports=t},46706:e=>{"use strict";var t={}.hasOwnProperty;e.exports=t},57139:e=>{"use strict";e.exports=["address","article","aside","base","basefont","blockquote","body","caption","center","col","colgroup","dd","details","dialog","dir","div","dl","dt","fieldset","figcaption","figure","footer","form","frame","frameset","h1","h2","h3","h4","h5","h6","head","header","hr","html","iframe","legend","li","link","main","menu","menuitem","nav","noframes","ol","optgroup","option","p","param","section","source","summary","table","tbody","td","tfoot","th","thead","title","tr","track","ul"]},16871:e=>{"use strict";e.exports=["pre","script","style","textarea"]},21362:e=>{"use strict";var t=[].splice;e.exports=t},76830:e=>{"use strict";e.exports=/[!-\/:-@\[-`\{-~\xA1\xA7\xAB\xB6\xB7\xBB\xBF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061E\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u09FD\u0A76\u0AF0\u0C77\u0C84\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B60\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2010-\u2027\u2030-\u2043\u2045-\u2051\u2053-\u205E\u207D\u207E\u208D\u208E\u2308-\u230B\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E4F\u2E52\u3001-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65]/},36274:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});var o=n(97082),r=n(47542),i=n(1349),a=n(45485),s=n(49653),u=n(36713),c=n(46597),l=n(20431),d=n(60026),h=n(93865),p=n(65694),f=n(596),g=n(76872),m=n(28911),_=n(31294),F=n(36215),y=n(60534),b=n(92607),v=n(46931),w=n(15874),E=n(37039),k={42:v,43:v,45:v,48:v,49:v,50:v,51:v,52:v,53:v,54:v,55:v,56:v,57:v,62:a},D={91:h},S={"-2":l,"-1":l,32:l},x={35:f,42:E,45:[w,E],60:g,61:w,95:E,96:c,126:c},C={38:u,92:s},A={"-5":b,"-4":b,"-3":b,33:F,38:u,42:r,60:[i,m],91:y,92:[p,s],93:_,95:r,96:d},T={null:[r,o.resolver]};t.contentInitial=D,t.disable={null:[]},t.document=k,t.flow=x,t.flowInitial=S,t.insideSpan=T,t.string=C,t.text=A},13745:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});var o=n(17238),r=n(52928);t.tokenize=function(e){var t,n=e.attempt(this.parser.constructs.contentInitial,(function(t){if(null!==t)return e.enter("lineEnding"),e.consume(t),e.exit("lineEnding"),r(e,n,"linePrefix");e.consume(t)}),(function(t){return e.enter("paragraph"),i(t)}));return n;function i(n){var o=e.enter("chunkText",{contentType:"text",previous:t});return t&&(t.next=o),t=o,a(n)}function a(t){return null===t?(e.exit("chunkText"),e.exit("paragraph"),void e.consume(t)):o(t)?(e.consume(t),e.exit("chunkText"),i):(e.consume(t),a)}}},14201:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});var o=n(17238),r=n(52928),i=n(66532),a={tokenize:function(e,t,n){return r(e,e.attempt(this.parser.constructs.document,t,n),"linePrefix",this.parser.constructs.disable.null.indexOf("codeIndented")>-1?void 0:4)}},s={tokenize:function(e,t,n){return r(e,e.lazy(this.parser.constructs.flow,t,n),"linePrefix",this.parser.constructs.disable.null.indexOf("codeIndented")>-1?void 0:4)}};t.tokenize=function(e){var t,n,r,u=this,c=[],l=0,d={tokenize:function(e,o){var r=0;return t={},l;function l(o){return rt;)u.containerState=c[i][1],c[i][0].exit.call(u,e);c.length=t}}},22871:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});var o=n(64590),r=n(52928),i=n(66532);t.tokenize=function(e){var t=this,n=e.attempt(i,(function(o){if(null!==o)return e.enter("lineEndingBlank"),e.consume(o),e.exit("lineEndingBlank"),t.currentConstruct=void 0,n;e.consume(o)}),e.attempt(this.parser.constructs.flowInitial,a,r(e,e.attempt(this.parser.constructs.flow,a,e.attempt(o,a)),"linePrefix")));return n;function a(o){if(null!==o)return e.enter("lineEnding"),e.consume(o),e.exit("lineEnding"),t.currentConstruct=void 0,n;e.consume(o)}}},97082:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});var o=n(99198),r=n(75923),i=u("text"),a=u("string"),s={resolveAll:c()};function u(e){return{tokenize:function(t){var n=this,o=this.parser.constructs[e],r=t.attempt(o,i,a);return i;function i(e){return u(e)?r(e):a(e)}function a(e){if(null!==e)return t.enter("data"),t.consume(e),s;t.consume(e)}function s(e){return u(e)?(t.exit("data"),r(e)):(t.consume(e),s)}function u(e){var t=o[e],r=-1;if(null===e)return!0;if(t)for(;++r{"use strict";var o=n(13745),r=n(14201),i=n(22871),a=n(97082),s=n(12952),u=n(21388),c=n(28180),l=n(36274);e.exports=function(e){var t={defined:[],constructs:s([l].concat(c((e||{}).extensions))),content:n(o),document:n(r),flow:n(i),string:n(a.string),text:n(a.text)};return t;function n(e){return function(n){return u(t,e,n)}}}},61242:(e,t,n)=>{"use strict";var o=n(84423);e.exports=function(e){for(;!o(e););return e}},30162:e=>{"use strict";var t=/[\0\t\n\r]/g;e.exports=function(){var e,n=!0,o=1,r="";return function(i,a,s){var u,c,l,d,h,p=[];for(i=r+i.toString(a),l=0,r="",n&&(65279===i.charCodeAt(0)&&l++,n=void 0);l{"use strict";var o=n(78811),r=n(56808),i=n(19444),a=n(15644),s=n(58280),u=n(75923),c={name:"attention",tokenize:function(e,t){var n,o=i(this.previous);return function(t){return e.enter("attentionSequence"),n=t,r(t)};function r(a){var s,u,c,l;return a===n?(e.consume(a),r):(s=e.exit("attentionSequence"),c=!(u=i(a))||2===u&&o,l=!o||2===o&&u,s._open=42===n?c:c&&(o||!l),s._close=42===n?l:l&&(u||!c),t(a))}},resolveAll:function(e,t){for(var n,i,c,l,d,h,p,f,g=-1;++g1&&e[g][1].end.offset-e[g][1].start.offset>1?2:1)>1?"strongSequence":"emphasisSequence",start:a(u(e[n][1].end),-h),end:u(e[n][1].end)},d={type:h>1?"strongSequence":"emphasisSequence",start:u(e[g][1].start),end:a(u(e[g][1].start),h)},c={type:h>1?"strongText":"emphasisText",start:u(e[n][1].end),end:u(e[g][1].start)},i={type:h>1?"strong":"emphasis",start:u(l.start),end:u(d.end)},e[n][1].end=u(l.start),e[g][1].start=u(d.end),p=[],e[n][1].end.offset-e[n][1].start.offset&&(p=o(p,[["enter",e[n][1],t],["exit",e[n][1],t]])),p=o(p,[["enter",i,t],["enter",l,t],["exit",l,t],["enter",c,t]]),p=o(p,s(t.parser.constructs.insideSpan.null,e.slice(n+1,g),t)),p=o(p,[["exit",c,t],["enter",d,t],["exit",d,t],["exit",i,t]]),e[g][1].end.offset-e[g][1].start.offset?(f=2,p=o(p,[["enter",e[g][1],t],["exit",e[g][1],t]])):f=0,r(e,n-1,g-n+3,p),g=n+p.length-f-2;break}for(g=-1;++g{"use strict";var o=n(76734),r=n(46712),i=n(13571),a=n(89696),s={name:"autolink",tokenize:function(e,t,n){var s=1;return function(t){return e.enter("autolink"),e.enter("autolinkMarker"),e.consume(t),e.exit("autolinkMarker"),e.enter("autolinkProtocol"),u};function u(t){return o(t)?(e.consume(t),c):i(t)?h(t):n(t)}function c(e){return 43===e||45===e||46===e||r(e)?l(e):h(e)}function l(t){return 58===t?(e.consume(t),d):(43===t||45===t||46===t||r(t))&&s++<32?(e.consume(t),l):h(t)}function d(t){return 62===t?(e.exit("autolinkProtocol"),m(t)):32===t||60===t||a(t)?n(t):(e.consume(t),d)}function h(t){return 64===t?(e.consume(t),s=0,p):i(t)?(e.consume(t),h):n(t)}function p(e){return r(e)?f(e):n(e)}function f(t){return 46===t?(e.consume(t),s=0,p):62===t?(e.exit("autolinkProtocol").type="autolinkEmail",m(t)):g(t)}function g(t){return(45===t||r(t))&&s++<63?(e.consume(t),45===t?g:f):n(t)}function m(n){return e.enter("autolinkMarker"),e.consume(n),e.exit("autolinkMarker"),e.exit("autolink"),t}}};e.exports=s},45485:(e,t,n)=>{"use strict";var o=n(73654),r=n(52928),i={name:"blockQuote",tokenize:function(e,t,n){var r=this;return function(t){return 62===t?(r.containerState.open||(e.enter("blockQuote",{_container:!0}),r.containerState.open=!0),e.enter("blockQuotePrefix"),e.enter("blockQuoteMarker"),e.consume(t),e.exit("blockQuoteMarker"),i):n(t)};function i(n){return o(n)?(e.enter("blockQuotePrefixWhitespace"),e.consume(n),e.exit("blockQuotePrefixWhitespace"),e.exit("blockQuotePrefix"),t):(e.exit("blockQuotePrefix"),t(n))}},continuation:{tokenize:function(e,t,n){return r(e,e.attempt(i,t,n),"linePrefix",this.parser.constructs.disable.null.indexOf("codeIndented")>-1?void 0:4)}},exit:function(e){e.exit("blockQuote")}};e.exports=i},49653:(e,t,n)=>{"use strict";var o=n(83074),r={name:"characterEscape",tokenize:function(e,t,n){return function(t){return e.enter("characterEscape"),e.enter("escapeMarker"),e.consume(t),e.exit("escapeMarker"),r};function r(r){return o(r)?(e.enter("characterEscapeValue"),e.consume(r),e.exit("characterEscapeValue"),e.exit("characterEscape"),t):n(r)}}};e.exports=r},36713:(e,t,n)=>{"use strict";var o=n(89435),r=n(46712),i=n(73977),a=n(56238);function s(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var u=s(o),c={name:"characterReference",tokenize:function(e,t,n){var o,s,c=this,l=0;return function(t){return e.enter("characterReference"),e.enter("characterReferenceMarker"),e.consume(t),e.exit("characterReferenceMarker"),d};function d(t){return 35===t?(e.enter("characterReferenceMarkerNumeric"),e.consume(t),e.exit("characterReferenceMarkerNumeric"),h):(e.enter("characterReferenceValue"),o=31,s=r,p(t))}function h(t){return 88===t||120===t?(e.enter("characterReferenceMarkerHexadecimal"),e.consume(t),e.exit("characterReferenceMarkerHexadecimal"),e.enter("characterReferenceValue"),o=6,s=a,p):(e.enter("characterReferenceValue"),o=7,s=i,p(t))}function p(i){var a;return 59===i&&l?(a=e.exit("characterReferenceValue"),s!==r||u.default(c.sliceSerialize(a))?(e.enter("characterReferenceMarker"),e.consume(i),e.exit("characterReferenceMarker"),e.exit("characterReference"),t):n(i)):s(i)&&l++{"use strict";var o=n(17238),r=n(88367),i=n(15096),a=n(52928),s={name:"codeFenced",tokenize:function(e,t,n){var s,u=this,c={tokenize:function(e,t,n){var r=0;return a(e,(function(t){return e.enter("codeFencedFence"),e.enter("codeFencedFenceSequence"),i(t)}),"linePrefix",this.parser.constructs.disable.null.indexOf("codeIndented")>-1?void 0:4);function i(t){return t===s?(e.consume(t),r++,i):r{"use strict";var o=n(17238),r=n(56808),i=n(15096),a=n(52928),s={name:"codeIndented",tokenize:function(e,t,n){return e.attempt(u,r,n);function r(n){return null===n?t(n):o(n)?e.attempt(u,r,t)(n):(e.enter("codeFlowValue"),i(n))}function i(t){return null===t||o(t)?(e.exit("codeFlowValue"),r(t)):(e.consume(t),i)}},resolve:function(e,t){var n={type:"codeIndented",start:e[0][1].start,end:e[e.length-1][1].end};return r(e,0,0,[["enter",n,t]]),r(e,e.length,0,[["exit",n,t]]),e}},u={tokenize:function(e,t,n){var r=this;return a(e,(function s(u){return o(u)?(e.enter("lineEnding"),e.consume(u),e.exit("lineEnding"),a(e,s,"linePrefix",5)):i(r.events,"linePrefix")<4?n(u):t(u)}),"linePrefix",5)},partial:!0};e.exports=s},60026:(e,t,n)=>{"use strict";var o=n(17238),r={name:"codeText",tokenize:function(e,t,n){var r,i,a=0;return function(t){return e.enter("codeText"),e.enter("codeTextSequence"),s(t)};function s(t){return 96===t?(e.consume(t),a++,s):(e.exit("codeTextSequence"),u(t))}function u(t){return null===t?n(t):96===t?(i=e.enter("codeTextSequence"),r=0,l(t)):32===t?(e.enter("space"),e.consume(t),e.exit("space"),u):o(t)?(e.enter("lineEnding"),e.consume(t),e.exit("lineEnding"),u):(e.enter("codeTextData"),c(t))}function c(t){return null===t||32===t||96===t||o(t)?(e.exit("codeTextData"),u(t)):(e.consume(t),c)}function l(n){return 96===n?(e.consume(n),r++,l):r===a?(e.exit("codeTextSequence"),e.exit("codeText"),t(n)):(i.type="codeTextData",c(n))}},resolve:function(e){var t,n,o=e.length-4,r=3;if(!("lineEnding"!==e[r][1].type&&"space"!==e[r][1].type||"lineEnding"!==e[o][1].type&&"space"!==e[o][1].type))for(t=r;++t{"use strict";var o=n(17238),r=n(15096),i=n(84423),a=n(52928),s={tokenize:function(e,t){var n;return function(t){return e.enter("content"),n=e.enter("chunkContent",{contentType:"content"}),r(t)};function r(t){return null===t?i(t):o(t)?e.check(u,a,i)(t):(e.consume(t),r)}function i(n){return e.exit("chunkContent"),e.exit("content"),t(n)}function a(t){return e.consume(t),e.exit("chunkContent"),n=n.next=e.enter("chunkContent",{contentType:"content",previous:n}),r}},resolve:function(e){return i(e),e},interruptible:!0,lazy:!0},u={tokenize:function(e,t,n){var i=this;return function(t){return e.enter("lineEnding"),e.consume(t),e.exit("lineEnding"),a(e,s,"linePrefix")};function s(a){return null===a||o(a)?n(a):i.parser.constructs.disable.null.indexOf("codeIndented")>-1||r(i.events,"linePrefix")<4?e.interrupt(i.parser.constructs.flow,n,t)(a):t(a)}},partial:!0};e.exports=s},93865:(e,t,n)=>{"use strict";var o=n(17238),r=n(88367),i=n(35478),a=n(38229),s=n(97154),u=n(52928),c=n(31056),l=n(59283),d={name:"definition",tokenize:function(e,t,n){var r,l=this;return function(t){return e.enter("definition"),s.call(l,e,d,n,"definitionLabel","definitionLabelMarker","definitionLabelString")(t)};function d(t){return r=i(l.sliceSerialize(l.events[l.events.length-1][1]).slice(1,-1)),58===t?(e.enter("definitionMarker"),e.consume(t),e.exit("definitionMarker"),c(e,a(e,e.attempt(h,u(e,p,"whitespace"),u(e,p,"whitespace")),n,"definitionDestination","definitionDestinationLiteral","definitionDestinationLiteralMarker","definitionDestinationRaw","definitionDestinationString"))):n(t)}function p(i){return null===i||o(i)?(e.exit("definition"),l.parser.defined.indexOf(r)<0&&l.parser.defined.push(r),t(i)):n(i)}}},h={tokenize:function(e,t,n){return function(t){return r(t)?c(e,i)(t):n(t)};function i(t){return 34===t||39===t||40===t?l(e,u(e,a,"whitespace"),n,"definitionTitle","definitionTitleMarker","definitionTitleString")(t):n(t)}function a(e){return null===e||o(e)?t(e):n(e)}},partial:!0};e.exports=d},38229:(e,t,n)=>{"use strict";var o=n(89696),r=n(88367),i=n(17238);e.exports=function(e,t,n,a,s,u,c,l,d){var h=d||1/0,p=0;return function(t){return 60===t?(e.enter(a),e.enter(s),e.enter(u),e.consume(t),e.exit(u),f):o(t)||41===t?n(t):(e.enter(a),e.enter(c),e.enter(l),e.enter("chunkString",{contentType:"string"}),_(t))};function f(n){return 62===n?(e.enter(u),e.consume(n),e.exit(u),e.exit(s),e.exit(a),t):(e.enter(l),e.enter("chunkString",{contentType:"string"}),g(n))}function g(t){return 62===t?(e.exit("chunkString"),e.exit(l),f(t)):null===t||60===t||i(t)?n(t):(e.consume(t),92===t?m:g)}function m(t){return 60===t||62===t||92===t?(e.consume(t),g):g(t)}function _(i){return 40===i?++p>h?n(i):(e.consume(i),_):41===i?p--?(e.consume(i),_):(e.exit("chunkString"),e.exit(l),e.exit(c),e.exit(a),t(i)):null===i||r(i)?p?n(i):(e.exit("chunkString"),e.exit(l),e.exit(c),e.exit(a),t(i)):o(i)?n(i):(e.consume(i),92===i?F:_)}function F(t){return 40===t||41===t||92===t?(e.consume(t),_):_(t)}}},97154:(e,t,n)=>{"use strict";var o=n(17238),r=n(73654);e.exports=function(e,t,n,i,a,s){var u,c=this,l=0;return function(t){return e.enter(i),e.enter(a),e.consume(t),e.exit(a),e.enter(s),d};function d(r){return null===r||91===r||93===r&&!u||94===r&&!l&&"_hiddenFootnoteSupport"in c.parser.constructs||l>999?n(r):93===r?(e.exit(s),e.enter(a),e.consume(r),e.exit(a),e.exit(i),t):o(r)?(e.enter("lineEnding"),e.consume(r),e.exit("lineEnding"),d):(e.enter("chunkString",{contentType:"string"}),h(r))}function h(t){return null===t||91===t||93===t||o(t)||l++>999?(e.exit("chunkString"),d(t)):(e.consume(t),u=u||!r(t),92===t?p:h)}function p(t){return 91===t||92===t||93===t?(e.consume(t),l++,h):h(t)}}},52928:(e,t,n)=>{"use strict";var o=n(73654);e.exports=function(e,t,n,r){var i=r?r-1:1/0,a=0;return function(r){return o(r)?(e.enter(n),s(r)):t(r)};function s(r){return o(r)&&a++{"use strict";var o=n(17238),r=n(52928);e.exports=function(e,t,n,i,a,s){var u;return function(t){return e.enter(i),e.enter(a),e.consume(t),e.exit(a),u=40===t?41:t,c};function c(n){return n===u?(e.enter(a),e.consume(n),e.exit(a),e.exit(i),t):(e.enter(s),l(n))}function l(t){return t===u?(e.exit(s),c(u)):null===t?n(t):o(t)?(e.enter("lineEnding"),e.consume(t),e.exit("lineEnding"),r(e,l,"linePrefix")):(e.enter("chunkString",{contentType:"string"}),d(t))}function d(t){return t===u||null===t||o(t)?(e.exit("chunkString"),l(t)):(e.consume(t),92===t?h:d)}function h(t){return t===u||92===t?(e.consume(t),d):d(t)}}},31056:(e,t,n)=>{"use strict";var o=n(17238),r=n(73654),i=n(52928);e.exports=function(e,t){var n;return function a(s){return o(s)?(e.enter("lineEnding"),e.consume(s),e.exit("lineEnding"),n=!0,a):r(s)?i(e,a,n?"linePrefix":"lineSuffix")(s):t(s)}}},65694:(e,t,n)=>{"use strict";var o=n(17238),r={name:"hardBreakEscape",tokenize:function(e,t,n){return function(t){return e.enter("hardBreakEscape"),e.enter("escapeMarker"),e.consume(t),r};function r(r){return o(r)?(e.exit("escapeMarker"),e.exit("hardBreakEscape"),t(r)):n(r)}}};e.exports=r},596:(e,t,n)=>{"use strict";var o=n(17238),r=n(88367),i=n(73654),a=n(56808),s=n(52928),u={name:"headingAtx",tokenize:function(e,t,n){var a=this,u=0;return function(t){return e.enter("atxHeading"),e.enter("atxHeadingSequence"),c(t)};function c(o){return 35===o&&u++<6?(e.consume(o),c):null===o||r(o)?(e.exit("atxHeadingSequence"),a.interrupt?t(o):l(o)):n(o)}function l(n){return 35===n?(e.enter("atxHeadingSequence"),d(n)):null===n||o(n)?(e.exit("atxHeading"),t(n)):i(n)?s(e,l,"whitespace")(n):(e.enter("atxHeadingText"),h(n))}function d(t){return 35===t?(e.consume(t),d):(e.exit("atxHeadingSequence"),l(t))}function h(t){return null===t||35===t||r(t)?(e.exit("atxHeadingText"),l(t)):(e.consume(t),h)}},resolve:function(e,t){var n,o,r=e.length-2,i=3;return"whitespace"===e[i][1].type&&(i+=2),r-2>i&&"whitespace"===e[r][1].type&&(r-=2),"atxHeadingSequence"===e[r][1].type&&(i===r-1||r-4>i&&"whitespace"===e[r-2][1].type)&&(r-=i+1===r?2:4),r>i&&(n={type:"atxHeadingText",start:e[i][1].start,end:e[r][1].end},o={type:"chunkText",start:e[i][1].start,end:e[r][1].end,contentType:"text"},a(e,i,r-i+1,[["enter",n,t],["enter",o,t],["exit",o,t],["exit",n,t]])),e}};e.exports=u},76872:(e,t,n)=>{"use strict";var o=n(76734),r=n(46712),i=n(17238),a=n(88367),s=n(73654),u=n(93267),c=n(57139),l=n(16871),d=n(66532),h={name:"htmlFlow",tokenize:function(e,t,n){var d,h,f,g,m,_=this;return function(t){return e.enter("htmlFlow"),e.enter("htmlFlowData"),e.consume(t),F};function F(r){return 33===r?(e.consume(r),y):47===r?(e.consume(r),w):63===r?(e.consume(r),d=3,_.interrupt?t:z):o(r)?(e.consume(r),f=u(r),h=!0,E):n(r)}function y(r){return 45===r?(e.consume(r),d=2,b):91===r?(e.consume(r),d=5,f="CDATA[",g=0,v):o(r)?(e.consume(r),d=4,_.interrupt?t:z):n(r)}function b(o){return 45===o?(e.consume(o),_.interrupt?t:z):n(o)}function v(o){return o===f.charCodeAt(g++)?(e.consume(o),g===f.length?_.interrupt?t:B:v):n(o)}function w(t){return o(t)?(e.consume(t),f=u(t),E):n(t)}function E(o){return null===o||47===o||62===o||a(o)?47!==o&&h&&l.indexOf(f.toLowerCase())>-1?(d=1,_.interrupt?t(o):B(o)):c.indexOf(f.toLowerCase())>-1?(d=6,47===o?(e.consume(o),k):_.interrupt?t(o):B(o)):(d=7,_.interrupt?n(o):h?S(o):D(o)):45===o||r(o)?(e.consume(o),f+=u(o),E):n(o)}function k(o){return 62===o?(e.consume(o),_.interrupt?t:B):n(o)}function D(t){return s(t)?(e.consume(t),D):M(t)}function S(t){return 47===t?(e.consume(t),M):58===t||95===t||o(t)?(e.consume(t),x):s(t)?(e.consume(t),S):M(t)}function x(t){return 45===t||46===t||58===t||95===t||r(t)?(e.consume(t),x):C(t)}function C(t){return 61===t?(e.consume(t),A):s(t)?(e.consume(t),C):S(t)}function A(t){return null===t||60===t||61===t||62===t||96===t?n(t):34===t||39===t?(e.consume(t),m=t,T):s(t)?(e.consume(t),A):(m=void 0,R(t))}function T(t){return t===m?(e.consume(t),I):null===t||i(t)?n(t):(e.consume(t),T)}function R(t){return null===t||34===t||39===t||60===t||61===t||62===t||96===t||a(t)?C(t):(e.consume(t),R)}function I(e){return 47===e||62===e||s(e)?S(e):n(e)}function M(t){return 62===t?(e.consume(t),O):n(t)}function O(t){return s(t)?(e.consume(t),O):null===t||i(t)?B(t):n(t)}function B(t){return 45===t&&2===d?(e.consume(t),P):60===t&&1===d?(e.consume(t),U):62===t&&4===d?(e.consume(t),K):63===t&&3===d?(e.consume(t),z):93===t&&5===d?(e.consume(t),q):!i(t)||6!==d&&7!==d?null===t||i(t)?N(t):(e.consume(t),B):e.check(p,K,N)(t)}function N(t){return e.exit("htmlFlowData"),L(t)}function L(t){return null===t?G(t):i(t)?(e.enter("lineEnding"),e.consume(t),e.exit("lineEnding"),L):(e.enter("htmlFlowData"),B(t))}function P(t){return 45===t?(e.consume(t),z):B(t)}function U(t){return 47===t?(e.consume(t),f="",j):B(t)}function j(t){return 62===t&&l.indexOf(f.toLowerCase())>-1?(e.consume(t),K):o(t)&&f.length<8?(e.consume(t),f+=u(t),j):B(t)}function q(t){return 93===t?(e.consume(t),z):B(t)}function z(t){return 62===t?(e.consume(t),K):B(t)}function K(t){return null===t||i(t)?(e.exit("htmlFlowData"),G(t)):(e.consume(t),K)}function G(n){return e.exit("htmlFlow"),t(n)}},resolveTo:function(e){for(var t=e.length;t--&&("enter"!==e[t][0]||"htmlFlow"!==e[t][1].type););return t>1&&"linePrefix"===e[t-2][1].type&&(e[t][1].start=e[t-2][1].start,e[t+1][1].start=e[t-2][1].start,e.splice(t-2,2)),e},concrete:!0},p={tokenize:function(e,t,n){return function(o){return e.exit("htmlFlowData"),e.enter("lineEndingBlank"),e.consume(o),e.exit("lineEndingBlank"),e.attempt(d,t,n)}},partial:!0};e.exports=h},28911:(e,t,n)=>{"use strict";var o=n(76734),r=n(46712),i=n(17238),a=n(88367),s=n(73654),u=n(52928),c={name:"htmlText",tokenize:function(e,t,n){var c,l,d,h,p=this;return function(t){return e.enter("htmlText"),e.enter("htmlTextData"),e.consume(t),f};function f(t){return 33===t?(e.consume(t),g):47===t?(e.consume(t),C):63===t?(e.consume(t),S):o(t)?(e.consume(t),R):n(t)}function g(t){return 45===t?(e.consume(t),m):91===t?(e.consume(t),l="CDATA[",d=0,v):o(t)?(e.consume(t),D):n(t)}function m(t){return 45===t?(e.consume(t),_):n(t)}function _(t){return null===t||62===t?n(t):45===t?(e.consume(t),F):y(t)}function F(e){return null===e||62===e?n(e):y(e)}function y(t){return null===t?n(t):45===t?(e.consume(t),b):i(t)?(h=y,U(t)):(e.consume(t),y)}function b(t){return 45===t?(e.consume(t),q):y(t)}function v(t){return t===l.charCodeAt(d++)?(e.consume(t),d===l.length?w:v):n(t)}function w(t){return null===t?n(t):93===t?(e.consume(t),E):i(t)?(h=w,U(t)):(e.consume(t),w)}function E(t){return 93===t?(e.consume(t),k):w(t)}function k(t){return 62===t?q(t):93===t?(e.consume(t),k):w(t)}function D(t){return null===t||62===t?q(t):i(t)?(h=D,U(t)):(e.consume(t),D)}function S(t){return null===t?n(t):63===t?(e.consume(t),x):i(t)?(h=S,U(t)):(e.consume(t),S)}function x(e){return 62===e?q(e):S(e)}function C(t){return o(t)?(e.consume(t),A):n(t)}function A(t){return 45===t||r(t)?(e.consume(t),A):T(t)}function T(t){return i(t)?(h=T,U(t)):s(t)?(e.consume(t),T):q(t)}function R(t){return 45===t||r(t)?(e.consume(t),R):47===t||62===t||a(t)?I(t):n(t)}function I(t){return 47===t?(e.consume(t),q):58===t||95===t||o(t)?(e.consume(t),M):i(t)?(h=I,U(t)):s(t)?(e.consume(t),I):q(t)}function M(t){return 45===t||46===t||58===t||95===t||r(t)?(e.consume(t),M):O(t)}function O(t){return 61===t?(e.consume(t),B):i(t)?(h=O,U(t)):s(t)?(e.consume(t),O):I(t)}function B(t){return null===t||60===t||61===t||62===t||96===t?n(t):34===t||39===t?(e.consume(t),c=t,N):i(t)?(h=B,U(t)):s(t)?(e.consume(t),B):(e.consume(t),c=void 0,P)}function N(t){return t===c?(e.consume(t),L):null===t?n(t):i(t)?(h=N,U(t)):(e.consume(t),N)}function L(e){return 62===e||47===e||a(e)?I(e):n(e)}function P(t){return null===t||34===t||39===t||60===t||61===t||96===t?n(t):62===t||a(t)?I(t):(e.consume(t),P)}function U(t){return e.exit("htmlTextData"),e.enter("lineEnding"),e.consume(t),e.exit("lineEnding"),u(e,j,"linePrefix",p.parser.constructs.disable.null.indexOf("codeIndented")>-1?void 0:4)}function j(t){return e.enter("htmlTextData"),h(t)}function q(o){return 62===o?(e.consume(o),e.exit("htmlTextData"),e.exit("htmlText"),t):n(o)}}};e.exports=c},31294:(e,t,n)=>{"use strict";var o=n(88367),r=n(78811),i=n(56808),a=n(35478),s=n(58280),u=n(75923),c=n(38229),l=n(97154),d=n(59283),h=n(31056),p={name:"labelEnd",tokenize:function(e,t,n){for(var o,r,i=this,s=i.events.length;s--;)if(("labelImage"===i.events[s][1].type||"labelLink"===i.events[s][1].type)&&!i.events[s][1]._balanced){o=i.events[s][1];break}return function(t){return o?o._inactive?c(t):(r=i.parser.defined.indexOf(a(i.sliceSerialize({start:o.end,end:i.now()})))>-1,e.enter("labelEnd"),e.enter("labelMarker"),e.consume(t),e.exit("labelMarker"),e.exit("labelEnd"),u):n(t)};function u(n){return 40===n?e.attempt(f,t,r?t:c)(n):91===n?e.attempt(g,t,r?e.attempt(m,t,c):c)(n):r?t(n):c(n)}function c(e){return o._balanced=!0,n(e)}},resolveTo:function(e,t){for(var n,o,a,c,l,d,h,p=e.length,f=0;p--;)if(c=e[p][1],l){if("link"===c.type||"labelLink"===c.type&&c._inactive)break;"enter"===e[p][0]&&"labelLink"===c.type&&(c._inactive=!0)}else if(d){if("enter"===e[p][0]&&("labelImage"===c.type||"labelLink"===c.type)&&!c._balanced&&(l=p,"labelLink"!==c.type)){f=2;break}}else"labelEnd"===c.type&&(d=p);return n={type:"labelLink"===e[l][1].type?"link":"image",start:u(e[l][1].start),end:u(e[e.length-1][1].end)},o={type:"label",start:u(e[l][1].start),end:u(e[d][1].end)},a={type:"labelText",start:u(e[l+f+2][1].end),end:u(e[d-2][1].start)},h=r(h=[["enter",n,t],["enter",o,t]],e.slice(l+1,l+f+3)),h=r(h,[["enter",a,t]]),h=r(h,s(t.parser.constructs.insideSpan.null,e.slice(l+f+4,d-3),t)),h=r(h,[["exit",a,t],e[d-2],e[d-1],["exit",o,t]]),h=r(h,e.slice(d+1)),h=r(h,[["exit",n,t]]),i(e,l,e.length,h),e},resolveAll:function(e){for(var t,n=-1;++n{"use strict";var o={name:"labelStartImage",tokenize:function(e,t,n){var o=this;return function(t){return e.enter("labelImage"),e.enter("labelImageMarker"),e.consume(t),e.exit("labelImageMarker"),r};function r(t){return 91===t?(e.enter("labelMarker"),e.consume(t),e.exit("labelMarker"),e.exit("labelImage"),i):n(t)}function i(e){return 94===e&&"_hiddenFootnoteSupport"in o.parser.constructs?n(e):t(e)}},resolveAll:n(31294).resolveAll};e.exports=o},60534:(e,t,n)=>{"use strict";var o={name:"labelStartLink",tokenize:function(e,t,n){var o=this;return function(t){return e.enter("labelLink"),e.enter("labelMarker"),e.consume(t),e.exit("labelMarker"),e.exit("labelLink"),r};function r(e){return 94===e&&"_hiddenFootnoteSupport"in o.parser.constructs?n(e):t(e)}},resolveAll:n(31294).resolveAll};e.exports=o},92607:(e,t,n)=>{"use strict";var o=n(52928),r={name:"lineEnding",tokenize:function(e,t){return function(n){return e.enter("lineEnding"),e.consume(n),e.exit("lineEnding"),o(e,t,"linePrefix")}}};e.exports=r},46931:(e,t,n)=>{"use strict";var o=n(73977),r=n(73654),i=n(15096),a=n(18892),s=n(52928),u=n(66532),c=n(37039),l={name:"list",tokenize:function(e,t,n){var s=this,l=i(s.events,"linePrefix"),h=0;return function(t){var r=s.containerState.type||(42===t||43===t||45===t?"listUnordered":"listOrdered");if("listUnordered"===r?!s.containerState.marker||t===s.containerState.marker:o(t)){if(s.containerState.type||(s.containerState.type=r,e.enter(r,{_container:!0})),"listUnordered"===r)return e.enter("listItemPrefix"),42===t||45===t?e.check(c,n,f)(t):f(t);if(!s.interrupt||49===t)return e.enter("listItemPrefix"),e.enter("listItemValue"),p(t)}return n(t)};function p(t){return o(t)&&++h<10?(e.consume(t),p):(!s.interrupt||h<2)&&(s.containerState.marker?t===s.containerState.marker:41===t||46===t)?(e.exit("listItemValue"),f(t)):n(t)}function f(t){return e.enter("listItemMarker"),e.consume(t),e.exit("listItemMarker"),s.containerState.marker=s.containerState.marker||t,e.check(u,s.interrupt?n:g,e.attempt(d,_,m))}function g(e){return s.containerState.initialBlankLine=!0,l++,_(e)}function m(t){return r(t)?(e.enter("listItemPrefixWhitespace"),e.consume(t),e.exit("listItemPrefixWhitespace"),_):n(t)}function _(n){return s.containerState.size=l+a(s.sliceStream(e.exit("listItemPrefix"))),t(n)}},continuation:{tokenize:function(e,t,n){var o=this;return o.containerState._closeFlow=void 0,e.check(u,(function(n){return o.containerState.furtherBlankLines=o.containerState.furtherBlankLines||o.containerState.initialBlankLine,s(e,t,"listItemIndent",o.containerState.size+1)(n)}),(function(n){return o.containerState.furtherBlankLines||!r(n)?(o.containerState.furtherBlankLines=o.containerState.initialBlankLine=void 0,i(n)):(o.containerState.furtherBlankLines=o.containerState.initialBlankLine=void 0,e.attempt(h,t,i)(n))}));function i(r){return o.containerState._closeFlow=!0,o.interrupt=void 0,s(e,e.attempt(l,t,n),"linePrefix",o.parser.constructs.disable.null.indexOf("codeIndented")>-1?void 0:4)(r)}}},exit:function(e){e.exit(this.containerState.type)}},d={tokenize:function(e,t,n){var o=this;return s(e,(function(e){return r(e)||!i(o.events,"listItemPrefixWhitespace")?n(e):t(e)}),"listItemPrefixWhitespace",o.parser.constructs.disable.null.indexOf("codeIndented")>-1?void 0:5)},partial:!0},h={tokenize:function(e,t,n){var o=this;return s(e,(function(e){return i(o.events,"listItemIndent")===o.containerState.size?t(e):n(e)}),"listItemIndent",o.containerState.size+1)},partial:!0};e.exports=l},66532:(e,t,n)=>{"use strict";var o=n(17238),r=n(52928),i={tokenize:function(e,t,n){return r(e,(function(e){return null===e||o(e)?t(e):n(e)}),"linePrefix")},partial:!0};e.exports=i},15874:(e,t,n)=>{"use strict";var o=n(17238),r=n(75923),i=n(52928),a={name:"setextUnderline",tokenize:function(e,t,n){for(var r,a,s=this,u=s.events.length;u--;)if("lineEnding"!==s.events[u][1].type&&"linePrefix"!==s.events[u][1].type&&"content"!==s.events[u][1].type){a="paragraph"===s.events[u][1].type;break}return function(t){return s.lazy||!s.interrupt&&!a?n(t):(e.enter("setextHeadingLine"),e.enter("setextHeadingLineSequence"),r=t,c(t))};function c(t){return t===r?(e.consume(t),c):(e.exit("setextHeadingLineSequence"),i(e,l,"lineSuffix")(t))}function l(r){return null===r||o(r)?(e.exit("setextHeadingLine"),t(r)):n(r)}},resolveTo:function(e,t){for(var n,o,i,a,s=e.length;s--;)if("enter"===e[s][0]){if("content"===e[s][1].type){n=s;break}"paragraph"===e[s][1].type&&(o=s)}else"content"===e[s][1].type&&e.splice(s,1),i||"definition"!==e[s][1].type||(i=s);return a={type:"setextHeading",start:r(e[o][1].start),end:r(e[e.length-1][1].end)},e[o][1].type="setextHeadingText",i?(e.splice(o,0,["enter",a,t]),e.splice(i+1,0,["exit",e[n][1],t]),e[n][1].end=r(e[i][1].end)):e[n][1]=a,e.push(["exit",a,t]),e}};e.exports=a},37039:(e,t,n)=>{"use strict";var o=n(17238),r=n(73654),i=n(52928),a={name:"thematicBreak",tokenize:function(e,t,n){var a,s=0;return function(t){return e.enter("thematicBreak"),a=t,u(t)};function u(l){return l===a?(e.enter("thematicBreakSequence"),c(l)):r(l)?i(e,u,"whitespace")(l):s<3||null!==l&&!o(l)?n(l):(e.exit("thematicBreak"),t(l))}function c(t){return t===a?(e.consume(t),s++,c):(e.exit("thematicBreakSequence"),u(t))}}};e.exports=a},78811:(e,t,n)=>{"use strict";var o=n(56808);e.exports=function(e,t){return e.length?(o(e,e.length,0,t),e):t}},56808:(e,t,n)=>{"use strict";var o=n(21362);e.exports=function(e,t,n,r){var i,a=e.length,s=0;if(t=t<0?-t>a?0:a+t:t>a?a:t,n=n>0?n:0,r.length<1e4)(i=Array.from(r)).unshift(t,n),o.apply(e,i);else for(n&&o.apply(e,[t,n]);s{"use strict";var o=n(88367),r=n(36996),i=n(10395);e.exports=function(e){return null===e||o(e)||i(e)?1:r(e)?2:void 0}},12952:(e,t,n)=>{"use strict";var o=n(46706),r=n(56808),i=n(28180);function a(e,t){var n,r,a,u;for(n in t)for(u in r=o.call(e,n)?e[n]:e[n]={},a=t[n])r[u]=s(i(a[u]),o.call(r,u)?r[u]:[])}function s(e,t){for(var n=-1,o=[];++n{"use strict";var o=n(99198),r=n(17238),i=n(78811),a=n(56808),s=n(28180),u=n(58280),c=n(23082),l=n(75923),d=n(12774);e.exports=function(e,t,n){var h=n?l(n):{line:1,column:1,offset:0},p={},f=[],g=[],m=[],_={consume:function(e){r(e)?(h.line++,h.column=1,h.offset+=-3===e?2:1,S()):-1!==e&&(h.column++,h.offset++),h._bufferIndex<0?h._index++:(h._bufferIndex++,h._bufferIndex===g[h._index].length&&(h._bufferIndex=-1,h._index++)),F.previous=e},enter:function(e,t){var n=t||{};return n.type=e,n.start=v(),F.events.push(["enter",n,F]),m.push(n),n},exit:function(e){var t=m.pop();return t.end=v(),F.events.push(["exit",t,F]),t},attempt:k((function(e,t){D(e,t.from)})),check:k(E),interrupt:k(E,{interrupt:!0}),lazy:k(E,{lazy:!0})},F={previous:null,events:[],parser:e,sliceStream:b,sliceSerialize:function(e){return c(b(e))},now:v,defineSkip:function(e){p[e.line]=e.column,S()},write:function(e){return g=i(g,e),function(){for(var e,t;h._index-1?g():e.tokenize.call(t?o({},F,t):F,_,f,g)(n)}}function f(t){return e(c,l),r}function g(e){return l.restore(),++u{"use strict";e.exports=function(e){return null==e?[]:"length"in e?e:[e]}},15644:e=>{"use strict";e.exports=function(e,t){return e.column+=t,e.offset+=t,e._bufferIndex+=t,e}},35478:e=>{"use strict";e.exports=function(e){return e.replace(/[\t\n\r ]+/g," ").replace(/^ | $/g,"").toLowerCase().toUpperCase()}},15096:(e,t,n)=>{"use strict";var o=n(18892);e.exports=function(e,t){var n=e[e.length-1];return n&&n[1].type===t?o(n[2].sliceStream(n[1])):0}},2841:(e,t,n)=>{"use strict";var o=n(93267);e.exports=function(e){return function(t){return e.test(o(t))}}},58280:e=>{"use strict";e.exports=function(e,t,n){for(var o,r=[],i=-1;++i{"use strict";var o=n(93267);e.exports=function(e,t){var n=parseInt(e,t);return n<9||11===n||n>13&&n<32||n>126&&n<160||n>55295&&n<57344||n>64975&&n<65008||65535==(65535&n)||65534==(65535&n)||n>1114111?"�":o(n)}},23082:(e,t,n)=>{"use strict";var o=n(93267);e.exports=function(e){for(var t,n,r,i=-1,a=[];++i{"use strict";var o=n(99198);e.exports=function(e){return o({},e)}},18892:e=>{"use strict";e.exports=function(e){for(var t=-1,n=0;++t{"use strict";e.exports=function(e,t){var n,o=t.start._index,r=t.start._bufferIndex,i=t.end._index,a=t.end._bufferIndex;return o===i?n=[e[o].slice(r,a)]:(n=e.slice(o,i),r>-1&&(n[0]=n[0].slice(r)),a>0&&n.push(e[i].slice(0,a))),n}},84423:(e,t,n)=>{"use strict";var o=n(99198),r=n(56808),i=n(75923);function a(e,t){for(var n,o,i,a,s,u,c=e[t][1],l=e[t][2],d=t-1,h=[],p=c._tokenizer||l.parser[c.contentType](c.start),f=p.events,g=[],m={};c;){for(;e[++d][1]!==c;);h.push(d),c._tokenizer||(n=l.sliceStream(c),c.next||n.push(null),o&&p.defineSkip(c.start),c.isInFirstContentOfListItem&&(p._gfmTasklistFirstContentOfListItem=!0),p.write(n),c.isInFirstContentOfListItem&&(p._gfmTasklistFirstContentOfListItem=void 0)),o=c,c=c.next}for(c=o,i=f.length;i--;)"enter"===f[i][0]?a=!0:a&&f[i][1].type===f[i-1][1].type&&f[i][1].start.line!==f[i][1].end.line&&(_(f.slice(i+1,s)),c._tokenizer=c.next=void 0,c=c.previous,s=i+1);for(p.events=c._tokenizer=c.next=void 0,_(f.slice(0,s)),i=-1,u=0;++i{var o=n(96240),r=n(29931);function i(e){this.rand=e||new r.Rand}e.exports=i,i.create=function(e){return new i(e)},i.prototype._randbelow=function(e){var t=e.bitLength(),n=Math.ceil(t/8);do{var r=new o(this.rand.generate(n))}while(r.cmp(e)>=0);return r},i.prototype._randrange=function(e,t){var n=t.sub(e);return e.add(this._randbelow(n))},i.prototype.test=function(e,t,n){var r=e.bitLength(),i=o.mont(e),a=new o(1).toRed(i);t||(t=Math.max(1,r/48|0));for(var s=e.subn(1),u=0;!s.testn(u);u++);for(var c=e.shrn(u),l=s.toRed(i);t>0;t--){var d=this._randrange(new o(2),s);n&&n(d);var h=d.toRed(i).redPow(c);if(0!==h.cmp(a)&&0!==h.cmp(l)){for(var p=1;p0;t--){var l=this._randrange(new o(2),a),d=e.gcd(l);if(0!==d.cmpn(1))return d;var h=l.toRed(r).redPow(u);if(0!==h.cmp(i)&&0!==h.cmp(c)){for(var p=1;p=65&&n<=70?n-55:n>=97&&n<=102?n-87:n-48&15}function u(e,t,n){var o=s(e,n);return n-1>=t&&(o|=s(e,n-1)<<4),o}function c(e,t,n,o){for(var r=0,i=Math.min(e.length,n),a=t;a=49?s-49+10:s>=17?s-17+10:s}return r}i.isBN=function(e){return e instanceof i||null!==e&&"object"==typeof e&&e.constructor.wordSize===i.wordSize&&Array.isArray(e.words)},i.max=function(e,t){return e.cmp(t)>0?e:t},i.min=function(e,t){return e.cmp(t)<0?e:t},i.prototype._init=function(e,t,n){if("number"==typeof e)return this._initNumber(e,t,n);if("object"==typeof e)return this._initArray(e,t,n);"hex"===t&&(t=16),o(t===(0|t)&&t>=2&&t<=36);var r=0;"-"===(e=e.toString().replace(/\s+/g,""))[0]&&(r++,this.negative=1),r=0;r-=3)a=e[r]|e[r-1]<<8|e[r-2]<<16,this.words[i]|=a<>>26-s&67108863,(s+=24)>=26&&(s-=26,i++);else if("le"===n)for(r=0,i=0;r>>26-s&67108863,(s+=24)>=26&&(s-=26,i++);return this.strip()},i.prototype._parseHex=function(e,t,n){this.length=Math.ceil((e.length-t)/6),this.words=new Array(this.length);for(var o=0;o=t;o-=2)r=u(e,t,o)<=18?(i-=18,a+=1,this.words[a]|=r>>>26):i+=8;else for(o=(e.length-t)%2==0?t+1:t;o=18?(i-=18,a+=1,this.words[a]|=r>>>26):i+=8;this.strip()},i.prototype._parseBase=function(e,t,n){this.words=[0],this.length=1;for(var o=0,r=1;r<=67108863;r*=t)o++;o--,r=r/t|0;for(var i=e.length-n,a=i%o,s=Math.min(i,i-a)+n,u=0,l=n;l1&&0===this.words[this.length-1];)this.length--;return this._normSign()},i.prototype._normSign=function(){return 1===this.length&&0===this.words[0]&&(this.negative=0),this},i.prototype.inspect=function(){return(this.red?""};var l=["","0","00","000","0000","00000","000000","0000000","00000000","000000000","0000000000","00000000000","000000000000","0000000000000","00000000000000","000000000000000","0000000000000000","00000000000000000","000000000000000000","0000000000000000000","00000000000000000000","000000000000000000000","0000000000000000000000","00000000000000000000000","000000000000000000000000","0000000000000000000000000"],d=[0,0,25,16,12,11,10,9,8,8,7,7,7,7,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5],h=[0,0,33554432,43046721,16777216,48828125,60466176,40353607,16777216,43046721,1e7,19487171,35831808,62748517,7529536,11390625,16777216,24137569,34012224,47045881,64e6,4084101,5153632,6436343,7962624,9765625,11881376,14348907,17210368,20511149,243e5,28629151,33554432,39135393,45435424,52521875,60466176];function p(e,t,n){n.negative=t.negative^e.negative;var o=e.length+t.length|0;n.length=o,o=o-1|0;var r=0|e.words[0],i=0|t.words[0],a=r*i,s=67108863&a,u=a/67108864|0;n.words[0]=s;for(var c=1;c>>26,d=67108863&u,h=Math.min(c,t.length-1),p=Math.max(0,c-e.length+1);p<=h;p++){var f=c-p|0;l+=(a=(r=0|e.words[f])*(i=0|t.words[p])+d)/67108864|0,d=67108863&a}n.words[c]=0|d,u=0|l}return 0!==u?n.words[c]=0|u:n.length--,n.strip()}i.prototype.toString=function(e,t){var n;if(t=0|t||1,16===(e=e||10)||"hex"===e){n="";for(var r=0,i=0,a=0;a>>24-r&16777215)||a!==this.length-1?l[6-u.length]+u+n:u+n,(r+=2)>=26&&(r-=26,a--)}for(0!==i&&(n=i.toString(16)+n);n.length%t!=0;)n="0"+n;return 0!==this.negative&&(n="-"+n),n}if(e===(0|e)&&e>=2&&e<=36){var c=d[e],p=h[e];n="";var f=this.clone();for(f.negative=0;!f.isZero();){var g=f.modn(p).toString(e);n=(f=f.idivn(p)).isZero()?g+n:l[c-g.length]+g+n}for(this.isZero()&&(n="0"+n);n.length%t!=0;)n="0"+n;return 0!==this.negative&&(n="-"+n),n}o(!1,"Base should be between 2 and 36")},i.prototype.toNumber=function(){var e=this.words[0];return 2===this.length?e+=67108864*this.words[1]:3===this.length&&1===this.words[2]?e+=4503599627370496+67108864*this.words[1]:this.length>2&&o(!1,"Number can only safely store up to 53 bits"),0!==this.negative?-e:e},i.prototype.toJSON=function(){return this.toString(16)},i.prototype.toBuffer=function(e,t){return o(void 0!==a),this.toArrayLike(a,e,t)},i.prototype.toArray=function(e,t){return this.toArrayLike(Array,e,t)},i.prototype.toArrayLike=function(e,t,n){var r=this.byteLength(),i=n||Math.max(1,r);o(r<=i,"byte array longer than desired length"),o(i>0,"Requested array length <= 0"),this.strip();var a,s,u="le"===t,c=new e(i),l=this.clone();if(u){for(s=0;!l.isZero();s++)a=l.andln(255),l.iushrn(8),c[s]=a;for(;s=4096&&(n+=13,t>>>=13),t>=64&&(n+=7,t>>>=7),t>=8&&(n+=4,t>>>=4),t>=2&&(n+=2,t>>>=2),n+t},i.prototype._zeroBits=function(e){if(0===e)return 26;var t=e,n=0;return 0==(8191&t)&&(n+=13,t>>>=13),0==(127&t)&&(n+=7,t>>>=7),0==(15&t)&&(n+=4,t>>>=4),0==(3&t)&&(n+=2,t>>>=2),0==(1&t)&&n++,n},i.prototype.bitLength=function(){var e=this.words[this.length-1],t=this._countBits(e);return 26*(this.length-1)+t},i.prototype.zeroBits=function(){if(this.isZero())return 0;for(var e=0,t=0;te.length?this.clone().ior(e):e.clone().ior(this)},i.prototype.uor=function(e){return this.length>e.length?this.clone().iuor(e):e.clone().iuor(this)},i.prototype.iuand=function(e){var t;t=this.length>e.length?e:this;for(var n=0;ne.length?this.clone().iand(e):e.clone().iand(this)},i.prototype.uand=function(e){return this.length>e.length?this.clone().iuand(e):e.clone().iuand(this)},i.prototype.iuxor=function(e){var t,n;this.length>e.length?(t=this,n=e):(t=e,n=this);for(var o=0;oe.length?this.clone().ixor(e):e.clone().ixor(this)},i.prototype.uxor=function(e){return this.length>e.length?this.clone().iuxor(e):e.clone().iuxor(this)},i.prototype.inotn=function(e){o("number"==typeof e&&e>=0);var t=0|Math.ceil(e/26),n=e%26;this._expand(t),n>0&&t--;for(var r=0;r0&&(this.words[r]=~this.words[r]&67108863>>26-n),this.strip()},i.prototype.notn=function(e){return this.clone().inotn(e)},i.prototype.setn=function(e,t){o("number"==typeof e&&e>=0);var n=e/26|0,r=e%26;return this._expand(n+1),this.words[n]=t?this.words[n]|1<e.length?(n=this,o=e):(n=e,o=this);for(var r=0,i=0;i>>26;for(;0!==r&&i>>26;if(this.length=n.length,0!==r)this.words[this.length]=r,this.length++;else if(n!==this)for(;ie.length?this.clone().iadd(e):e.clone().iadd(this)},i.prototype.isub=function(e){if(0!==e.negative){e.negative=0;var t=this.iadd(e);return e.negative=1,t._normSign()}if(0!==this.negative)return this.negative=0,this.iadd(e),this.negative=1,this._normSign();var n,o,r=this.cmp(e);if(0===r)return this.negative=0,this.length=1,this.words[0]=0,this;r>0?(n=this,o=e):(n=e,o=this);for(var i=0,a=0;a>26,this.words[a]=67108863&t;for(;0!==i&&a>26,this.words[a]=67108863&t;if(0===i&&a>>13,p=0|a[1],f=8191&p,g=p>>>13,m=0|a[2],_=8191&m,F=m>>>13,y=0|a[3],b=8191&y,v=y>>>13,w=0|a[4],E=8191&w,k=w>>>13,D=0|a[5],S=8191&D,x=D>>>13,C=0|a[6],A=8191&C,T=C>>>13,R=0|a[7],I=8191&R,M=R>>>13,O=0|a[8],B=8191&O,N=O>>>13,L=0|a[9],P=8191&L,U=L>>>13,j=0|s[0],q=8191&j,z=j>>>13,K=0|s[1],G=8191&K,$=K>>>13,H=0|s[2],V=8191&H,W=H>>>13,Y=0|s[3],Z=8191&Y,X=Y>>>13,J=0|s[4],Q=8191&J,ee=J>>>13,te=0|s[5],ne=8191&te,oe=te>>>13,re=0|s[6],ie=8191&re,ae=re>>>13,se=0|s[7],ue=8191&se,ce=se>>>13,le=0|s[8],de=8191&le,he=le>>>13,pe=0|s[9],fe=8191&pe,ge=pe>>>13;n.negative=e.negative^t.negative,n.length=19;var me=(c+(o=Math.imul(d,q))|0)+((8191&(r=(r=Math.imul(d,z))+Math.imul(h,q)|0))<<13)|0;c=((i=Math.imul(h,z))+(r>>>13)|0)+(me>>>26)|0,me&=67108863,o=Math.imul(f,q),r=(r=Math.imul(f,z))+Math.imul(g,q)|0,i=Math.imul(g,z);var _e=(c+(o=o+Math.imul(d,G)|0)|0)+((8191&(r=(r=r+Math.imul(d,$)|0)+Math.imul(h,G)|0))<<13)|0;c=((i=i+Math.imul(h,$)|0)+(r>>>13)|0)+(_e>>>26)|0,_e&=67108863,o=Math.imul(_,q),r=(r=Math.imul(_,z))+Math.imul(F,q)|0,i=Math.imul(F,z),o=o+Math.imul(f,G)|0,r=(r=r+Math.imul(f,$)|0)+Math.imul(g,G)|0,i=i+Math.imul(g,$)|0;var Fe=(c+(o=o+Math.imul(d,V)|0)|0)+((8191&(r=(r=r+Math.imul(d,W)|0)+Math.imul(h,V)|0))<<13)|0;c=((i=i+Math.imul(h,W)|0)+(r>>>13)|0)+(Fe>>>26)|0,Fe&=67108863,o=Math.imul(b,q),r=(r=Math.imul(b,z))+Math.imul(v,q)|0,i=Math.imul(v,z),o=o+Math.imul(_,G)|0,r=(r=r+Math.imul(_,$)|0)+Math.imul(F,G)|0,i=i+Math.imul(F,$)|0,o=o+Math.imul(f,V)|0,r=(r=r+Math.imul(f,W)|0)+Math.imul(g,V)|0,i=i+Math.imul(g,W)|0;var ye=(c+(o=o+Math.imul(d,Z)|0)|0)+((8191&(r=(r=r+Math.imul(d,X)|0)+Math.imul(h,Z)|0))<<13)|0;c=((i=i+Math.imul(h,X)|0)+(r>>>13)|0)+(ye>>>26)|0,ye&=67108863,o=Math.imul(E,q),r=(r=Math.imul(E,z))+Math.imul(k,q)|0,i=Math.imul(k,z),o=o+Math.imul(b,G)|0,r=(r=r+Math.imul(b,$)|0)+Math.imul(v,G)|0,i=i+Math.imul(v,$)|0,o=o+Math.imul(_,V)|0,r=(r=r+Math.imul(_,W)|0)+Math.imul(F,V)|0,i=i+Math.imul(F,W)|0,o=o+Math.imul(f,Z)|0,r=(r=r+Math.imul(f,X)|0)+Math.imul(g,Z)|0,i=i+Math.imul(g,X)|0;var be=(c+(o=o+Math.imul(d,Q)|0)|0)+((8191&(r=(r=r+Math.imul(d,ee)|0)+Math.imul(h,Q)|0))<<13)|0;c=((i=i+Math.imul(h,ee)|0)+(r>>>13)|0)+(be>>>26)|0,be&=67108863,o=Math.imul(S,q),r=(r=Math.imul(S,z))+Math.imul(x,q)|0,i=Math.imul(x,z),o=o+Math.imul(E,G)|0,r=(r=r+Math.imul(E,$)|0)+Math.imul(k,G)|0,i=i+Math.imul(k,$)|0,o=o+Math.imul(b,V)|0,r=(r=r+Math.imul(b,W)|0)+Math.imul(v,V)|0,i=i+Math.imul(v,W)|0,o=o+Math.imul(_,Z)|0,r=(r=r+Math.imul(_,X)|0)+Math.imul(F,Z)|0,i=i+Math.imul(F,X)|0,o=o+Math.imul(f,Q)|0,r=(r=r+Math.imul(f,ee)|0)+Math.imul(g,Q)|0,i=i+Math.imul(g,ee)|0;var ve=(c+(o=o+Math.imul(d,ne)|0)|0)+((8191&(r=(r=r+Math.imul(d,oe)|0)+Math.imul(h,ne)|0))<<13)|0;c=((i=i+Math.imul(h,oe)|0)+(r>>>13)|0)+(ve>>>26)|0,ve&=67108863,o=Math.imul(A,q),r=(r=Math.imul(A,z))+Math.imul(T,q)|0,i=Math.imul(T,z),o=o+Math.imul(S,G)|0,r=(r=r+Math.imul(S,$)|0)+Math.imul(x,G)|0,i=i+Math.imul(x,$)|0,o=o+Math.imul(E,V)|0,r=(r=r+Math.imul(E,W)|0)+Math.imul(k,V)|0,i=i+Math.imul(k,W)|0,o=o+Math.imul(b,Z)|0,r=(r=r+Math.imul(b,X)|0)+Math.imul(v,Z)|0,i=i+Math.imul(v,X)|0,o=o+Math.imul(_,Q)|0,r=(r=r+Math.imul(_,ee)|0)+Math.imul(F,Q)|0,i=i+Math.imul(F,ee)|0,o=o+Math.imul(f,ne)|0,r=(r=r+Math.imul(f,oe)|0)+Math.imul(g,ne)|0,i=i+Math.imul(g,oe)|0;var we=(c+(o=o+Math.imul(d,ie)|0)|0)+((8191&(r=(r=r+Math.imul(d,ae)|0)+Math.imul(h,ie)|0))<<13)|0;c=((i=i+Math.imul(h,ae)|0)+(r>>>13)|0)+(we>>>26)|0,we&=67108863,o=Math.imul(I,q),r=(r=Math.imul(I,z))+Math.imul(M,q)|0,i=Math.imul(M,z),o=o+Math.imul(A,G)|0,r=(r=r+Math.imul(A,$)|0)+Math.imul(T,G)|0,i=i+Math.imul(T,$)|0,o=o+Math.imul(S,V)|0,r=(r=r+Math.imul(S,W)|0)+Math.imul(x,V)|0,i=i+Math.imul(x,W)|0,o=o+Math.imul(E,Z)|0,r=(r=r+Math.imul(E,X)|0)+Math.imul(k,Z)|0,i=i+Math.imul(k,X)|0,o=o+Math.imul(b,Q)|0,r=(r=r+Math.imul(b,ee)|0)+Math.imul(v,Q)|0,i=i+Math.imul(v,ee)|0,o=o+Math.imul(_,ne)|0,r=(r=r+Math.imul(_,oe)|0)+Math.imul(F,ne)|0,i=i+Math.imul(F,oe)|0,o=o+Math.imul(f,ie)|0,r=(r=r+Math.imul(f,ae)|0)+Math.imul(g,ie)|0,i=i+Math.imul(g,ae)|0;var Ee=(c+(o=o+Math.imul(d,ue)|0)|0)+((8191&(r=(r=r+Math.imul(d,ce)|0)+Math.imul(h,ue)|0))<<13)|0;c=((i=i+Math.imul(h,ce)|0)+(r>>>13)|0)+(Ee>>>26)|0,Ee&=67108863,o=Math.imul(B,q),r=(r=Math.imul(B,z))+Math.imul(N,q)|0,i=Math.imul(N,z),o=o+Math.imul(I,G)|0,r=(r=r+Math.imul(I,$)|0)+Math.imul(M,G)|0,i=i+Math.imul(M,$)|0,o=o+Math.imul(A,V)|0,r=(r=r+Math.imul(A,W)|0)+Math.imul(T,V)|0,i=i+Math.imul(T,W)|0,o=o+Math.imul(S,Z)|0,r=(r=r+Math.imul(S,X)|0)+Math.imul(x,Z)|0,i=i+Math.imul(x,X)|0,o=o+Math.imul(E,Q)|0,r=(r=r+Math.imul(E,ee)|0)+Math.imul(k,Q)|0,i=i+Math.imul(k,ee)|0,o=o+Math.imul(b,ne)|0,r=(r=r+Math.imul(b,oe)|0)+Math.imul(v,ne)|0,i=i+Math.imul(v,oe)|0,o=o+Math.imul(_,ie)|0,r=(r=r+Math.imul(_,ae)|0)+Math.imul(F,ie)|0,i=i+Math.imul(F,ae)|0,o=o+Math.imul(f,ue)|0,r=(r=r+Math.imul(f,ce)|0)+Math.imul(g,ue)|0,i=i+Math.imul(g,ce)|0;var ke=(c+(o=o+Math.imul(d,de)|0)|0)+((8191&(r=(r=r+Math.imul(d,he)|0)+Math.imul(h,de)|0))<<13)|0;c=((i=i+Math.imul(h,he)|0)+(r>>>13)|0)+(ke>>>26)|0,ke&=67108863,o=Math.imul(P,q),r=(r=Math.imul(P,z))+Math.imul(U,q)|0,i=Math.imul(U,z),o=o+Math.imul(B,G)|0,r=(r=r+Math.imul(B,$)|0)+Math.imul(N,G)|0,i=i+Math.imul(N,$)|0,o=o+Math.imul(I,V)|0,r=(r=r+Math.imul(I,W)|0)+Math.imul(M,V)|0,i=i+Math.imul(M,W)|0,o=o+Math.imul(A,Z)|0,r=(r=r+Math.imul(A,X)|0)+Math.imul(T,Z)|0,i=i+Math.imul(T,X)|0,o=o+Math.imul(S,Q)|0,r=(r=r+Math.imul(S,ee)|0)+Math.imul(x,Q)|0,i=i+Math.imul(x,ee)|0,o=o+Math.imul(E,ne)|0,r=(r=r+Math.imul(E,oe)|0)+Math.imul(k,ne)|0,i=i+Math.imul(k,oe)|0,o=o+Math.imul(b,ie)|0,r=(r=r+Math.imul(b,ae)|0)+Math.imul(v,ie)|0,i=i+Math.imul(v,ae)|0,o=o+Math.imul(_,ue)|0,r=(r=r+Math.imul(_,ce)|0)+Math.imul(F,ue)|0,i=i+Math.imul(F,ce)|0,o=o+Math.imul(f,de)|0,r=(r=r+Math.imul(f,he)|0)+Math.imul(g,de)|0,i=i+Math.imul(g,he)|0;var De=(c+(o=o+Math.imul(d,fe)|0)|0)+((8191&(r=(r=r+Math.imul(d,ge)|0)+Math.imul(h,fe)|0))<<13)|0;c=((i=i+Math.imul(h,ge)|0)+(r>>>13)|0)+(De>>>26)|0,De&=67108863,o=Math.imul(P,G),r=(r=Math.imul(P,$))+Math.imul(U,G)|0,i=Math.imul(U,$),o=o+Math.imul(B,V)|0,r=(r=r+Math.imul(B,W)|0)+Math.imul(N,V)|0,i=i+Math.imul(N,W)|0,o=o+Math.imul(I,Z)|0,r=(r=r+Math.imul(I,X)|0)+Math.imul(M,Z)|0,i=i+Math.imul(M,X)|0,o=o+Math.imul(A,Q)|0,r=(r=r+Math.imul(A,ee)|0)+Math.imul(T,Q)|0,i=i+Math.imul(T,ee)|0,o=o+Math.imul(S,ne)|0,r=(r=r+Math.imul(S,oe)|0)+Math.imul(x,ne)|0,i=i+Math.imul(x,oe)|0,o=o+Math.imul(E,ie)|0,r=(r=r+Math.imul(E,ae)|0)+Math.imul(k,ie)|0,i=i+Math.imul(k,ae)|0,o=o+Math.imul(b,ue)|0,r=(r=r+Math.imul(b,ce)|0)+Math.imul(v,ue)|0,i=i+Math.imul(v,ce)|0,o=o+Math.imul(_,de)|0,r=(r=r+Math.imul(_,he)|0)+Math.imul(F,de)|0,i=i+Math.imul(F,he)|0;var Se=(c+(o=o+Math.imul(f,fe)|0)|0)+((8191&(r=(r=r+Math.imul(f,ge)|0)+Math.imul(g,fe)|0))<<13)|0;c=((i=i+Math.imul(g,ge)|0)+(r>>>13)|0)+(Se>>>26)|0,Se&=67108863,o=Math.imul(P,V),r=(r=Math.imul(P,W))+Math.imul(U,V)|0,i=Math.imul(U,W),o=o+Math.imul(B,Z)|0,r=(r=r+Math.imul(B,X)|0)+Math.imul(N,Z)|0,i=i+Math.imul(N,X)|0,o=o+Math.imul(I,Q)|0,r=(r=r+Math.imul(I,ee)|0)+Math.imul(M,Q)|0,i=i+Math.imul(M,ee)|0,o=o+Math.imul(A,ne)|0,r=(r=r+Math.imul(A,oe)|0)+Math.imul(T,ne)|0,i=i+Math.imul(T,oe)|0,o=o+Math.imul(S,ie)|0,r=(r=r+Math.imul(S,ae)|0)+Math.imul(x,ie)|0,i=i+Math.imul(x,ae)|0,o=o+Math.imul(E,ue)|0,r=(r=r+Math.imul(E,ce)|0)+Math.imul(k,ue)|0,i=i+Math.imul(k,ce)|0,o=o+Math.imul(b,de)|0,r=(r=r+Math.imul(b,he)|0)+Math.imul(v,de)|0,i=i+Math.imul(v,he)|0;var xe=(c+(o=o+Math.imul(_,fe)|0)|0)+((8191&(r=(r=r+Math.imul(_,ge)|0)+Math.imul(F,fe)|0))<<13)|0;c=((i=i+Math.imul(F,ge)|0)+(r>>>13)|0)+(xe>>>26)|0,xe&=67108863,o=Math.imul(P,Z),r=(r=Math.imul(P,X))+Math.imul(U,Z)|0,i=Math.imul(U,X),o=o+Math.imul(B,Q)|0,r=(r=r+Math.imul(B,ee)|0)+Math.imul(N,Q)|0,i=i+Math.imul(N,ee)|0,o=o+Math.imul(I,ne)|0,r=(r=r+Math.imul(I,oe)|0)+Math.imul(M,ne)|0,i=i+Math.imul(M,oe)|0,o=o+Math.imul(A,ie)|0,r=(r=r+Math.imul(A,ae)|0)+Math.imul(T,ie)|0,i=i+Math.imul(T,ae)|0,o=o+Math.imul(S,ue)|0,r=(r=r+Math.imul(S,ce)|0)+Math.imul(x,ue)|0,i=i+Math.imul(x,ce)|0,o=o+Math.imul(E,de)|0,r=(r=r+Math.imul(E,he)|0)+Math.imul(k,de)|0,i=i+Math.imul(k,he)|0;var Ce=(c+(o=o+Math.imul(b,fe)|0)|0)+((8191&(r=(r=r+Math.imul(b,ge)|0)+Math.imul(v,fe)|0))<<13)|0;c=((i=i+Math.imul(v,ge)|0)+(r>>>13)|0)+(Ce>>>26)|0,Ce&=67108863,o=Math.imul(P,Q),r=(r=Math.imul(P,ee))+Math.imul(U,Q)|0,i=Math.imul(U,ee),o=o+Math.imul(B,ne)|0,r=(r=r+Math.imul(B,oe)|0)+Math.imul(N,ne)|0,i=i+Math.imul(N,oe)|0,o=o+Math.imul(I,ie)|0,r=(r=r+Math.imul(I,ae)|0)+Math.imul(M,ie)|0,i=i+Math.imul(M,ae)|0,o=o+Math.imul(A,ue)|0,r=(r=r+Math.imul(A,ce)|0)+Math.imul(T,ue)|0,i=i+Math.imul(T,ce)|0,o=o+Math.imul(S,de)|0,r=(r=r+Math.imul(S,he)|0)+Math.imul(x,de)|0,i=i+Math.imul(x,he)|0;var Ae=(c+(o=o+Math.imul(E,fe)|0)|0)+((8191&(r=(r=r+Math.imul(E,ge)|0)+Math.imul(k,fe)|0))<<13)|0;c=((i=i+Math.imul(k,ge)|0)+(r>>>13)|0)+(Ae>>>26)|0,Ae&=67108863,o=Math.imul(P,ne),r=(r=Math.imul(P,oe))+Math.imul(U,ne)|0,i=Math.imul(U,oe),o=o+Math.imul(B,ie)|0,r=(r=r+Math.imul(B,ae)|0)+Math.imul(N,ie)|0,i=i+Math.imul(N,ae)|0,o=o+Math.imul(I,ue)|0,r=(r=r+Math.imul(I,ce)|0)+Math.imul(M,ue)|0,i=i+Math.imul(M,ce)|0,o=o+Math.imul(A,de)|0,r=(r=r+Math.imul(A,he)|0)+Math.imul(T,de)|0,i=i+Math.imul(T,he)|0;var Te=(c+(o=o+Math.imul(S,fe)|0)|0)+((8191&(r=(r=r+Math.imul(S,ge)|0)+Math.imul(x,fe)|0))<<13)|0;c=((i=i+Math.imul(x,ge)|0)+(r>>>13)|0)+(Te>>>26)|0,Te&=67108863,o=Math.imul(P,ie),r=(r=Math.imul(P,ae))+Math.imul(U,ie)|0,i=Math.imul(U,ae),o=o+Math.imul(B,ue)|0,r=(r=r+Math.imul(B,ce)|0)+Math.imul(N,ue)|0,i=i+Math.imul(N,ce)|0,o=o+Math.imul(I,de)|0,r=(r=r+Math.imul(I,he)|0)+Math.imul(M,de)|0,i=i+Math.imul(M,he)|0;var Re=(c+(o=o+Math.imul(A,fe)|0)|0)+((8191&(r=(r=r+Math.imul(A,ge)|0)+Math.imul(T,fe)|0))<<13)|0;c=((i=i+Math.imul(T,ge)|0)+(r>>>13)|0)+(Re>>>26)|0,Re&=67108863,o=Math.imul(P,ue),r=(r=Math.imul(P,ce))+Math.imul(U,ue)|0,i=Math.imul(U,ce),o=o+Math.imul(B,de)|0,r=(r=r+Math.imul(B,he)|0)+Math.imul(N,de)|0,i=i+Math.imul(N,he)|0;var Ie=(c+(o=o+Math.imul(I,fe)|0)|0)+((8191&(r=(r=r+Math.imul(I,ge)|0)+Math.imul(M,fe)|0))<<13)|0;c=((i=i+Math.imul(M,ge)|0)+(r>>>13)|0)+(Ie>>>26)|0,Ie&=67108863,o=Math.imul(P,de),r=(r=Math.imul(P,he))+Math.imul(U,de)|0,i=Math.imul(U,he);var Me=(c+(o=o+Math.imul(B,fe)|0)|0)+((8191&(r=(r=r+Math.imul(B,ge)|0)+Math.imul(N,fe)|0))<<13)|0;c=((i=i+Math.imul(N,ge)|0)+(r>>>13)|0)+(Me>>>26)|0,Me&=67108863;var Oe=(c+(o=Math.imul(P,fe))|0)+((8191&(r=(r=Math.imul(P,ge))+Math.imul(U,fe)|0))<<13)|0;return c=((i=Math.imul(U,ge))+(r>>>13)|0)+(Oe>>>26)|0,Oe&=67108863,u[0]=me,u[1]=_e,u[2]=Fe,u[3]=ye,u[4]=be,u[5]=ve,u[6]=we,u[7]=Ee,u[8]=ke,u[9]=De,u[10]=Se,u[11]=xe,u[12]=Ce,u[13]=Ae,u[14]=Te,u[15]=Re,u[16]=Ie,u[17]=Me,u[18]=Oe,0!==c&&(u[19]=c,n.length++),n};function g(e,t,n){return(new m).mulp(e,t,n)}function m(e,t){this.x=e,this.y=t}Math.imul||(f=p),i.prototype.mulTo=function(e,t){var n=this.length+e.length;return 10===this.length&&10===e.length?f(this,e,t):n<63?p(this,e,t):n<1024?function(e,t,n){n.negative=t.negative^e.negative,n.length=e.length+t.length;for(var o=0,r=0,i=0;i>>26)|0)>>>26,a&=67108863}n.words[i]=s,o=a,a=r}return 0!==o?n.words[i]=o:n.length--,n.strip()}(this,e,t):g(this,e,t)},m.prototype.makeRBT=function(e){for(var t=new Array(e),n=i.prototype._countBits(e)-1,o=0;o>=1;return o},m.prototype.permute=function(e,t,n,o,r,i){for(var a=0;a>>=1)r++;return 1<>>=13,n[2*a+1]=8191&i,i>>>=13;for(a=2*t;a>=26,t+=r/67108864|0,t+=i>>>26,this.words[n]=67108863&i}return 0!==t&&(this.words[n]=t,this.length++),this},i.prototype.muln=function(e){return this.clone().imuln(e)},i.prototype.sqr=function(){return this.mul(this)},i.prototype.isqr=function(){return this.imul(this.clone())},i.prototype.pow=function(e){var t=function(e){for(var t=new Array(e.bitLength()),n=0;n>>r}return t}(e);if(0===t.length)return new i(1);for(var n=this,o=0;o=0);var t,n=e%26,r=(e-n)/26,i=67108863>>>26-n<<26-n;if(0!==n){var a=0;for(t=0;t>>26-n}a&&(this.words[t]=a,this.length++)}if(0!==r){for(t=this.length-1;t>=0;t--)this.words[t+r]=this.words[t];for(t=0;t=0),r=t?(t-t%26)/26:0;var i=e%26,a=Math.min((e-i)/26,this.length),s=67108863^67108863>>>i<a)for(this.length-=a,c=0;c=0&&(0!==l||c>=r);c--){var d=0|this.words[c];this.words[c]=l<<26-i|d>>>i,l=d&s}return u&&0!==l&&(u.words[u.length++]=l),0===this.length&&(this.words[0]=0,this.length=1),this.strip()},i.prototype.ishrn=function(e,t,n){return o(0===this.negative),this.iushrn(e,t,n)},i.prototype.shln=function(e){return this.clone().ishln(e)},i.prototype.ushln=function(e){return this.clone().iushln(e)},i.prototype.shrn=function(e){return this.clone().ishrn(e)},i.prototype.ushrn=function(e){return this.clone().iushrn(e)},i.prototype.testn=function(e){o("number"==typeof e&&e>=0);var t=e%26,n=(e-t)/26,r=1<=0);var t=e%26,n=(e-t)/26;if(o(0===this.negative,"imaskn works only with positive numbers"),this.length<=n)return this;if(0!==t&&n++,this.length=Math.min(n,this.length),0!==t){var r=67108863^67108863>>>t<=67108864;t++)this.words[t]-=67108864,t===this.length-1?this.words[t+1]=1:this.words[t+1]++;return this.length=Math.max(this.length,t+1),this},i.prototype.isubn=function(e){if(o("number"==typeof e),o(e<67108864),e<0)return this.iaddn(-e);if(0!==this.negative)return this.negative=0,this.iaddn(e),this.negative=1,this;if(this.words[0]-=e,1===this.length&&this.words[0]<0)this.words[0]=-this.words[0],this.negative=1;else for(var t=0;t>26)-(u/67108864|0),this.words[r+n]=67108863&i}for(;r>26,this.words[r+n]=67108863&i;if(0===s)return this.strip();for(o(-1===s),s=0,r=0;r>26,this.words[r]=67108863&i;return this.negative=1,this.strip()},i.prototype._wordDiv=function(e,t){var n=(this.length,e.length),o=this.clone(),r=e,a=0|r.words[r.length-1];0!=(n=26-this._countBits(a))&&(r=r.ushln(n),o.iushln(n),a=0|r.words[r.length-1]);var s,u=o.length-r.length;if("mod"!==t){(s=new i(null)).length=u+1,s.words=new Array(s.length);for(var c=0;c=0;d--){var h=67108864*(0|o.words[r.length+d])+(0|o.words[r.length+d-1]);for(h=Math.min(h/a|0,67108863),o._ishlnsubmul(r,h,d);0!==o.negative;)h--,o.negative=0,o._ishlnsubmul(r,1,d),o.isZero()||(o.negative^=1);s&&(s.words[d]=h)}return s&&s.strip(),o.strip(),"div"!==t&&0!==n&&o.iushrn(n),{div:s||null,mod:o}},i.prototype.divmod=function(e,t,n){return o(!e.isZero()),this.isZero()?{div:new i(0),mod:new i(0)}:0!==this.negative&&0===e.negative?(s=this.neg().divmod(e,t),"mod"!==t&&(r=s.div.neg()),"div"!==t&&(a=s.mod.neg(),n&&0!==a.negative&&a.iadd(e)),{div:r,mod:a}):0===this.negative&&0!==e.negative?(s=this.divmod(e.neg(),t),"mod"!==t&&(r=s.div.neg()),{div:r,mod:s.mod}):0!=(this.negative&e.negative)?(s=this.neg().divmod(e.neg(),t),"div"!==t&&(a=s.mod.neg(),n&&0!==a.negative&&a.isub(e)),{div:s.div,mod:a}):e.length>this.length||this.cmp(e)<0?{div:new i(0),mod:this}:1===e.length?"div"===t?{div:this.divn(e.words[0]),mod:null}:"mod"===t?{div:null,mod:new i(this.modn(e.words[0]))}:{div:this.divn(e.words[0]),mod:new i(this.modn(e.words[0]))}:this._wordDiv(e,t);var r,a,s},i.prototype.div=function(e){return this.divmod(e,"div",!1).div},i.prototype.mod=function(e){return this.divmod(e,"mod",!1).mod},i.prototype.umod=function(e){return this.divmod(e,"mod",!0).mod},i.prototype.divRound=function(e){var t=this.divmod(e);if(t.mod.isZero())return t.div;var n=0!==t.div.negative?t.mod.isub(e):t.mod,o=e.ushrn(1),r=e.andln(1),i=n.cmp(o);return i<0||1===r&&0===i?t.div:0!==t.div.negative?t.div.isubn(1):t.div.iaddn(1)},i.prototype.modn=function(e){o(e<=67108863);for(var t=(1<<26)%e,n=0,r=this.length-1;r>=0;r--)n=(t*n+(0|this.words[r]))%e;return n},i.prototype.idivn=function(e){o(e<=67108863);for(var t=0,n=this.length-1;n>=0;n--){var r=(0|this.words[n])+67108864*t;this.words[n]=r/e|0,t=r%e}return this.strip()},i.prototype.divn=function(e){return this.clone().idivn(e)},i.prototype.egcd=function(e){o(0===e.negative),o(!e.isZero());var t=this,n=e.clone();t=0!==t.negative?t.umod(e):t.clone();for(var r=new i(1),a=new i(0),s=new i(0),u=new i(1),c=0;t.isEven()&&n.isEven();)t.iushrn(1),n.iushrn(1),++c;for(var l=n.clone(),d=t.clone();!t.isZero();){for(var h=0,p=1;0==(t.words[0]&p)&&h<26;++h,p<<=1);if(h>0)for(t.iushrn(h);h-- >0;)(r.isOdd()||a.isOdd())&&(r.iadd(l),a.isub(d)),r.iushrn(1),a.iushrn(1);for(var f=0,g=1;0==(n.words[0]&g)&&f<26;++f,g<<=1);if(f>0)for(n.iushrn(f);f-- >0;)(s.isOdd()||u.isOdd())&&(s.iadd(l),u.isub(d)),s.iushrn(1),u.iushrn(1);t.cmp(n)>=0?(t.isub(n),r.isub(s),a.isub(u)):(n.isub(t),s.isub(r),u.isub(a))}return{a:s,b:u,gcd:n.iushln(c)}},i.prototype._invmp=function(e){o(0===e.negative),o(!e.isZero());var t=this,n=e.clone();t=0!==t.negative?t.umod(e):t.clone();for(var r,a=new i(1),s=new i(0),u=n.clone();t.cmpn(1)>0&&n.cmpn(1)>0;){for(var c=0,l=1;0==(t.words[0]&l)&&c<26;++c,l<<=1);if(c>0)for(t.iushrn(c);c-- >0;)a.isOdd()&&a.iadd(u),a.iushrn(1);for(var d=0,h=1;0==(n.words[0]&h)&&d<26;++d,h<<=1);if(d>0)for(n.iushrn(d);d-- >0;)s.isOdd()&&s.iadd(u),s.iushrn(1);t.cmp(n)>=0?(t.isub(n),a.isub(s)):(n.isub(t),s.isub(a))}return(r=0===t.cmpn(1)?a:s).cmpn(0)<0&&r.iadd(e),r},i.prototype.gcd=function(e){if(this.isZero())return e.abs();if(e.isZero())return this.abs();var t=this.clone(),n=e.clone();t.negative=0,n.negative=0;for(var o=0;t.isEven()&&n.isEven();o++)t.iushrn(1),n.iushrn(1);for(;;){for(;t.isEven();)t.iushrn(1);for(;n.isEven();)n.iushrn(1);var r=t.cmp(n);if(r<0){var i=t;t=n,n=i}else if(0===r||0===n.cmpn(1))break;t.isub(n)}return n.iushln(o)},i.prototype.invm=function(e){return this.egcd(e).a.umod(e)},i.prototype.isEven=function(){return 0==(1&this.words[0])},i.prototype.isOdd=function(){return 1==(1&this.words[0])},i.prototype.andln=function(e){return this.words[0]&e},i.prototype.bincn=function(e){o("number"==typeof e);var t=e%26,n=(e-t)/26,r=1<>>26,s&=67108863,this.words[a]=s}return 0!==i&&(this.words[a]=i,this.length++),this},i.prototype.isZero=function(){return 1===this.length&&0===this.words[0]},i.prototype.cmpn=function(e){var t,n=e<0;if(0!==this.negative&&!n)return-1;if(0===this.negative&&n)return 1;if(this.strip(),this.length>1)t=1;else{n&&(e=-e),o(e<=67108863,"Number is too big");var r=0|this.words[0];t=r===e?0:re.length)return 1;if(this.length=0;n--){var o=0|this.words[n],r=0|e.words[n];if(o!==r){or&&(t=1);break}}return t},i.prototype.gtn=function(e){return 1===this.cmpn(e)},i.prototype.gt=function(e){return 1===this.cmp(e)},i.prototype.gten=function(e){return this.cmpn(e)>=0},i.prototype.gte=function(e){return this.cmp(e)>=0},i.prototype.ltn=function(e){return-1===this.cmpn(e)},i.prototype.lt=function(e){return-1===this.cmp(e)},i.prototype.lten=function(e){return this.cmpn(e)<=0},i.prototype.lte=function(e){return this.cmp(e)<=0},i.prototype.eqn=function(e){return 0===this.cmpn(e)},i.prototype.eq=function(e){return 0===this.cmp(e)},i.red=function(e){return new E(e)},i.prototype.toRed=function(e){return o(!this.red,"Already a number in reduction context"),o(0===this.negative,"red works only with positives"),e.convertTo(this)._forceRed(e)},i.prototype.fromRed=function(){return o(this.red,"fromRed works only with numbers in reduction context"),this.red.convertFrom(this)},i.prototype._forceRed=function(e){return this.red=e,this},i.prototype.forceRed=function(e){return o(!this.red,"Already a number in reduction context"),this._forceRed(e)},i.prototype.redAdd=function(e){return o(this.red,"redAdd works only with red numbers"),this.red.add(this,e)},i.prototype.redIAdd=function(e){return o(this.red,"redIAdd works only with red numbers"),this.red.iadd(this,e)},i.prototype.redSub=function(e){return o(this.red,"redSub works only with red numbers"),this.red.sub(this,e)},i.prototype.redISub=function(e){return o(this.red,"redISub works only with red numbers"),this.red.isub(this,e)},i.prototype.redShl=function(e){return o(this.red,"redShl works only with red numbers"),this.red.shl(this,e)},i.prototype.redMul=function(e){return o(this.red,"redMul works only with red numbers"),this.red._verify2(this,e),this.red.mul(this,e)},i.prototype.redIMul=function(e){return o(this.red,"redMul works only with red numbers"),this.red._verify2(this,e),this.red.imul(this,e)},i.prototype.redSqr=function(){return o(this.red,"redSqr works only with red numbers"),this.red._verify1(this),this.red.sqr(this)},i.prototype.redISqr=function(){return o(this.red,"redISqr works only with red numbers"),this.red._verify1(this),this.red.isqr(this)},i.prototype.redSqrt=function(){return o(this.red,"redSqrt works only with red numbers"),this.red._verify1(this),this.red.sqrt(this)},i.prototype.redInvm=function(){return o(this.red,"redInvm works only with red numbers"),this.red._verify1(this),this.red.invm(this)},i.prototype.redNeg=function(){return o(this.red,"redNeg works only with red numbers"),this.red._verify1(this),this.red.neg(this)},i.prototype.redPow=function(e){return o(this.red&&!e.red,"redPow(normalNum)"),this.red._verify1(this),this.red.pow(this,e)};var _={k256:null,p224:null,p192:null,p25519:null};function F(e,t){this.name=e,this.p=new i(t,16),this.n=this.p.bitLength(),this.k=new i(1).iushln(this.n).isub(this.p),this.tmp=this._tmp()}function y(){F.call(this,"k256","ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f")}function b(){F.call(this,"p224","ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001")}function v(){F.call(this,"p192","ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff")}function w(){F.call(this,"25519","7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed")}function E(e){if("string"==typeof e){var t=i._prime(e);this.m=t.p,this.prime=t}else o(e.gtn(1),"modulus must be greater than 1"),this.m=e,this.prime=null}function k(e){E.call(this,e),this.shift=this.m.bitLength(),this.shift%26!=0&&(this.shift+=26-this.shift%26),this.r=new i(1).iushln(this.shift),this.r2=this.imod(this.r.sqr()),this.rinv=this.r._invmp(this.m),this.minv=this.rinv.mul(this.r).isubn(1).div(this.m),this.minv=this.minv.umod(this.r),this.minv=this.r.sub(this.minv)}F.prototype._tmp=function(){var e=new i(null);return e.words=new Array(Math.ceil(this.n/13)),e},F.prototype.ireduce=function(e){var t,n=e;do{this.split(n,this.tmp),t=(n=(n=this.imulK(n)).iadd(this.tmp)).bitLength()}while(t>this.n);var o=t0?n.isub(this.p):void 0!==n.strip?n.strip():n._strip(),n},F.prototype.split=function(e,t){e.iushrn(this.n,0,t)},F.prototype.imulK=function(e){return e.imul(this.k)},r(y,F),y.prototype.split=function(e,t){for(var n=4194303,o=Math.min(e.length,9),r=0;r>>22,i=a}i>>>=22,e.words[r-10]=i,0===i&&e.length>10?e.length-=10:e.length-=9},y.prototype.imulK=function(e){e.words[e.length]=0,e.words[e.length+1]=0,e.length+=2;for(var t=0,n=0;n>>=26,e.words[n]=r,t=o}return 0!==t&&(e.words[e.length++]=t),e},i._prime=function(e){if(_[e])return _[e];var t;if("k256"===e)t=new y;else if("p224"===e)t=new b;else if("p192"===e)t=new v;else{if("p25519"!==e)throw new Error("Unknown prime "+e);t=new w}return _[e]=t,t},E.prototype._verify1=function(e){o(0===e.negative,"red works only with positives"),o(e.red,"red works only with red numbers")},E.prototype._verify2=function(e,t){o(0==(e.negative|t.negative),"red works only with positives"),o(e.red&&e.red===t.red,"red works only with red numbers")},E.prototype.imod=function(e){return this.prime?this.prime.ireduce(e)._forceRed(this):e.umod(this.m)._forceRed(this)},E.prototype.neg=function(e){return e.isZero()?e.clone():this.m.sub(e)._forceRed(this)},E.prototype.add=function(e,t){this._verify2(e,t);var n=e.add(t);return n.cmp(this.m)>=0&&n.isub(this.m),n._forceRed(this)},E.prototype.iadd=function(e,t){this._verify2(e,t);var n=e.iadd(t);return n.cmp(this.m)>=0&&n.isub(this.m),n},E.prototype.sub=function(e,t){this._verify2(e,t);var n=e.sub(t);return n.cmpn(0)<0&&n.iadd(this.m),n._forceRed(this)},E.prototype.isub=function(e,t){this._verify2(e,t);var n=e.isub(t);return n.cmpn(0)<0&&n.iadd(this.m),n},E.prototype.shl=function(e,t){return this._verify1(e),this.imod(e.ushln(t))},E.prototype.imul=function(e,t){return this._verify2(e,t),this.imod(e.imul(t))},E.prototype.mul=function(e,t){return this._verify2(e,t),this.imod(e.mul(t))},E.prototype.isqr=function(e){return this.imul(e,e.clone())},E.prototype.sqr=function(e){return this.mul(e,e)},E.prototype.sqrt=function(e){if(e.isZero())return e.clone();var t=this.m.andln(3);if(o(t%2==1),3===t){var n=this.m.add(new i(1)).iushrn(2);return this.pow(e,n)}for(var r=this.m.subn(1),a=0;!r.isZero()&&0===r.andln(1);)a++,r.iushrn(1);o(!r.isZero());var s=new i(1).toRed(this),u=s.redNeg(),c=this.m.subn(1).iushrn(1),l=this.m.bitLength();for(l=new i(2*l*l).toRed(this);0!==this.pow(l,c).cmp(u);)l.redIAdd(u);for(var d=this.pow(l,r),h=this.pow(e,r.addn(1).iushrn(1)),p=this.pow(e,r),f=a;0!==p.cmp(s);){for(var g=p,m=0;0!==g.cmp(s);m++)g=g.redSqr();o(m=0;o--){for(var c=t.words[o],l=u-1;l>=0;l--){var d=c>>l&1;r!==n[0]&&(r=this.sqr(r)),0!==d||0!==a?(a<<=1,a|=d,(4==++s||0===o&&0===l)&&(r=this.mul(r,n[a]),s=0,a=0)):s=0}u=26}return r},E.prototype.convertTo=function(e){var t=e.umod(this.m);return t===e?t.clone():t},E.prototype.convertFrom=function(e){var t=e.clone();return t.red=null,t},i.mont=function(e){return new k(e)},r(k,E),k.prototype.convertTo=function(e){return this.imod(e.ushln(this.shift))},k.prototype.convertFrom=function(e){var t=this.imod(e.mul(this.rinv));return t.red=null,t},k.prototype.imul=function(e,t){if(e.isZero()||t.isZero())return e.words[0]=0,e.length=1,e;var n=e.imul(t),o=n.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m),r=n.isub(o).iushrn(this.shift),i=r;return r.cmp(this.m)>=0?i=r.isub(this.m):r.cmpn(0)<0&&(i=r.iadd(this.m)),i._forceRed(this)},k.prototype.mul=function(e,t){if(e.isZero()||t.isZero())return new i(0)._forceRed(this);var n=e.mul(t),o=n.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m),r=n.isub(o).iushrn(this.shift),a=r;return r.cmp(this.m)>=0?a=r.isub(this.m):r.cmpn(0)<0&&(a=r.iadd(this.m)),a._forceRed(this)},k.prototype.invm=function(e){return this.imod(e._invmp(this.m).mul(this.r2))._forceRed(this)}}(e=n.nmd(e),this)},79746:e=>{function t(e,t){if(!e)throw new Error(t||"Assertion failed")}e.exports=t,t.equal=function(e,t,n){if(e!=t)throw new Error(n||"Assertion failed: "+e+" != "+t)}},34504:(e,t)=>{"use strict";var n=t;function o(e){return 1===e.length?"0"+e:e}function r(e){for(var t="",n=0;n>8,a=255&r;i?n.push(i,a):n.push(a)}return n},n.zero2=o,n.toHex=r,n.encode=function(e,t){return"hex"===t?r(e):e}},27418:e=>{"use strict";var t=Object.getOwnPropertySymbols,n=Object.prototype.hasOwnProperty,o=Object.prototype.propertyIsEnumerable;function r(e){if(null==e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}e.exports=function(){try{if(!Object.assign)return!1;var e=new String("abc");if(e[5]="de","5"===Object.getOwnPropertyNames(e)[0])return!1;for(var t={},n=0;n<10;n++)t["_"+String.fromCharCode(n)]=n;if("0123456789"!==Object.getOwnPropertyNames(t).map((function(e){return t[e]})).join(""))return!1;var o={};return"abcdefghijklmnopqrst".split("").forEach((function(e){o[e]=e})),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},o)).join("")}catch(e){return!1}}()?Object.assign:function(e,i){for(var a,s,u=r(e),c=1;c{var o="function"==typeof Map&&Map.prototype,r=Object.getOwnPropertyDescriptor&&o?Object.getOwnPropertyDescriptor(Map.prototype,"size"):null,i=o&&r&&"function"==typeof r.get?r.get:null,a=o&&Map.prototype.forEach,s="function"==typeof Set&&Set.prototype,u=Object.getOwnPropertyDescriptor&&s?Object.getOwnPropertyDescriptor(Set.prototype,"size"):null,c=s&&u&&"function"==typeof u.get?u.get:null,l=s&&Set.prototype.forEach,d="function"==typeof WeakMap&&WeakMap.prototype?WeakMap.prototype.has:null,h="function"==typeof WeakSet&&WeakSet.prototype?WeakSet.prototype.has:null,p=Boolean.prototype.valueOf,f=Object.prototype.toString,g=Function.prototype.toString,m=String.prototype.match,_="function"==typeof BigInt?BigInt.prototype.valueOf:null,F=Object.getOwnPropertySymbols,y="function"==typeof Symbol?Symbol.prototype.toString:null,b=Object.prototype.propertyIsEnumerable,v=n(24654).custom,w=v&&S(v)?v:null;function E(e,t,n){var o="double"===(n.quoteStyle||t)?'"':"'";return o+e+o}function k(e){return String(e).replace(/"/g,""")}function D(e){return"[object Array]"===A(e)}function S(e){return"[object Symbol]"===A(e)}e.exports=function e(t,n,o,r){var s=n||{};if(C(s,"quoteStyle")&&"single"!==s.quoteStyle&&"double"!==s.quoteStyle)throw new TypeError('option "quoteStyle" must be "single" or "double"');if(C(s,"maxStringLength")&&("number"==typeof s.maxStringLength?s.maxStringLength<0&&s.maxStringLength!==1/0:null!==s.maxStringLength))throw new TypeError('option "maxStringLength", if provided, must be a positive integer, Infinity, or `null`');var u=!C(s,"customInspect")||s.customInspect;if("boolean"!=typeof u)throw new TypeError('option "customInspect", if provided, must be `true` or `false`');if(C(s,"indent")&&null!==s.indent&&"\t"!==s.indent&&!(parseInt(s.indent,10)===s.indent&&s.indent>0))throw new TypeError('options "indent" must be "\\t", an integer > 0, or `null`');if(void 0===t)return"undefined";if(null===t)return"null";if("boolean"==typeof t)return t?"true":"false";if("string"==typeof t)return R(t,s);if("number"==typeof t)return 0===t?1/0/t>0?"0":"-0":String(t);if("bigint"==typeof t)return String(t)+"n";var f=void 0===s.depth?5:s.depth;if(void 0===o&&(o=0),o>=f&&f>0&&"object"==typeof t)return D(t)?"[Array]":"[Object]";var F,b=function(e,t){var n;if("\t"===e.indent)n="\t";else{if(!("number"==typeof e.indent&&e.indent>0))return null;n=Array(e.indent+1).join(" ")}return{base:n,prev:Array(t+1).join(n)}}(s,o);if(void 0===r)r=[];else if(T(r,t)>=0)return"[Circular]";function v(t,n,i){if(n&&(r=r.slice()).push(n),i){var a={depth:s.depth};return C(s,"quoteStyle")&&(a.quoteStyle=s.quoteStyle),e(t,a,o+1,r)}return e(t,s,o+1,r)}if("function"==typeof t){var x=function(e){if(e.name)return e.name;var t=m.call(g.call(e),/^function\s*([\w$]+)/);return t?t[1]:null}(t),I=L(t,v);return"[Function"+(x?": "+x:" (anonymous)")+"]"+(I.length>0?" { "+I.join(", ")+" }":"")}if(S(t)){var P=y.call(t);return"object"==typeof t?M(P):P}if((F=t)&&"object"==typeof F&&("undefined"!=typeof HTMLElement&&F instanceof HTMLElement||"string"==typeof F.nodeName&&"function"==typeof F.getAttribute)){for(var U="<"+String(t.nodeName).toLowerCase(),j=t.attributes||[],q=0;q"}if(D(t)){if(0===t.length)return"[]";var z=L(t,v);return b&&!function(e){for(var t=0;t=0)return!1;return!0}(z)?"["+N(z,b)+"]":"[ "+z.join(", ")+" ]"}if(function(e){return"[object Error]"===A(e)}(t)){var K=L(t,v);return 0===K.length?"["+String(t)+"]":"{ ["+String(t)+"] "+K.join(", ")+" }"}if("object"==typeof t&&u){if(w&&"function"==typeof t[w])return t[w]();if("function"==typeof t.inspect)return t.inspect()}if(function(e){if(!i||!e||"object"!=typeof e)return!1;try{i.call(e);try{c.call(e)}catch(e){return!0}return e instanceof Map}catch(e){}return!1}(t)){var G=[];return a.call(t,(function(e,n){G.push(v(n,t,!0)+" => "+v(e,t))})),B("Map",i.call(t),G,b)}if(function(e){if(!c||!e||"object"!=typeof e)return!1;try{c.call(e);try{i.call(e)}catch(e){return!0}return e instanceof Set}catch(e){}return!1}(t)){var $=[];return l.call(t,(function(e){$.push(v(e,t))})),B("Set",c.call(t),$,b)}if(function(e){if(!d||!e||"object"!=typeof e)return!1;try{d.call(e,d);try{h.call(e,h)}catch(e){return!0}return e instanceof WeakMap}catch(e){}return!1}(t))return O("WeakMap");if(function(e){if(!h||!e||"object"!=typeof e)return!1;try{h.call(e,h);try{d.call(e,d)}catch(e){return!0}return e instanceof WeakSet}catch(e){}return!1}(t))return O("WeakSet");if(function(e){return"[object Number]"===A(e)}(t))return M(v(Number(t)));if(function(e){return"[object BigInt]"===A(e)}(t))return M(v(_.call(t)));if(function(e){return"[object Boolean]"===A(e)}(t))return M(p.call(t));if(function(e){return"[object String]"===A(e)}(t))return M(v(String(t)));if(!function(e){return"[object Date]"===A(e)}(t)&&!function(e){return"[object RegExp]"===A(e)}(t)){var H=L(t,v);return 0===H.length?"{}":b?"{"+N(H,b)+"}":"{ "+H.join(", ")+" }"}return String(t)};var x=Object.prototype.hasOwnProperty||function(e){return e in this};function C(e,t){return x.call(e,t)}function A(e){return f.call(e)}function T(e,t){if(e.indexOf)return e.indexOf(t);for(var n=0,o=e.length;nt.maxStringLength){var n=e.length-t.maxStringLength,o="... "+n+" more character"+(n>1?"s":"");return R(e.slice(0,t.maxStringLength),t)+o}return E(e.replace(/(['\\])/g,"\\$1").replace(/[\x00-\x1f]/g,I),"single",t)}function I(e){var t=e.charCodeAt(0),n={8:"b",9:"t",10:"n",12:"f",13:"r"}[t];return n?"\\"+n:"\\x"+(t<16?"0":"")+t.toString(16).toUpperCase()}function M(e){return"Object("+e+")"}function O(e){return e+" { ? }"}function B(e,t,n,o){return e+" ("+t+") {"+(o?N(n,o):n.join(", "))+"}"}function N(e,t){if(0===e.length)return"";var n="\n"+t.prev+t.base;return n+e.join(","+n)+"\n"+t.prev}function L(e,t){var n=D(e),o=[];if(n){o.length=e.length;for(var r=0;r{e.exports=function(e,t){return parseInt(e.toString(),t||8)}},93011:(e,t,n)=>{var o,r,i,a,s,u,c=(s={},i=(i="undefined"!=typeof document&&document.currentScript?document.currentScript.src:void 0)||"/index.js",u=function(t){var a,u,c;if(t=t||{},a||(a=void 0!==t?t:{}),a.ready=new Promise((function(e){u=e})),"undefined"!=typeof window)c=function(e){window.crypto.getRandomValues(e)};else{if(!e.exports)throw Error("Cannot find global to attach library to");var l=n(55835);c=function(e){var t=l.randomBytes(e.length);e.set(t)},process=n.g.process}if("undefined"!=typeof OLM_OPTIONS)for(var d in OLM_OPTIONS)OLM_OPTIONS.hasOwnProperty(d)&&(a[d]=OLM_OPTIONS[d]);a.onRuntimeInitialized=function(){Ce=a._olm_error(),s.PRIVATE_KEY_LENGTH=a._olm_pk_private_key_length(),o&&o()},a.onAbort=function(e){r&&r(e)};var h,p,f,g,m,_={};for(h in a)a.hasOwnProperty(h)&&(_[h]=a[h]);p="object"==typeof window,f="function"==typeof importScripts,g="object"==typeof process&&"object"==typeof process.versions&&"string"==typeof process.versions.node,m=!p&&!g&&!f;var F,y,b,v,w="";g?(w=f?n(26470).dirname(w)+"/":"//",F=function(e,t){return b||(b=n(23384)),v||(v=n(26470)),e=v.normalize(e),b.readFileSync(e,t?null:"utf8")},y=function(e){return(e=F(e,!0)).buffer||(e=new Uint8Array(e)),e.buffer||ne("Assertion failed: undefined"),e},1>0]=0;break;case"i16":U[e>>1]=0;break;case"i32":j[e>>2]=0;break;case"i64":ie=[0,1<=+X(0)?~~+J(0)>>>0:0],j[e>>2]=ie[0],j[e+4>>2]=ie[1];break;case"float":q[e>>2]=0;break;case"double":z[e>>3]=0;break;default:ne("invalid type for setValue: "+t)}}function x(e,t){switch("*"===(t=t||"i8").charAt(t.length-1)&&(t="i32"),t){case"i1":case"i8":return L[e>>0];case"i16":return U[e>>1];case"i32":case"i64":return j[e>>2];case"float":return q[e>>2];case"double":return z[e>>3];default:ne("invalid type for getValue: "+t)}return null}_=null,a.wasmBinary&&(E=a.wasmBinary),a.noExitRuntime&&a.noExitRuntime,"object"!=typeof WebAssembly&&ne("no native wasm support detected");var C,A=new WebAssembly.Table({initial:9,maximum:9,element:"anyfunc"}),T=!1,R="undefined"!=typeof TextDecoder?new TextDecoder("utf8"):void 0;function I(e,t){if(e){var n=P,o=e+t;for(t=e;n[t]&&!(t>=o);)++t;if(16(r=224==(240&r)?(15&r)<<12|i<<6|a:(7&r)<<18|i<<12|a<<6|63&n[e++])?o+=String.fromCharCode(r):(r-=65536,o+=String.fromCharCode(55296|r>>10,56320|1023&r))}}else o+=String.fromCharCode(r)}e=o}}else e="";return e}function M(e,t,n,o){if(!(0=a&&(a=65536+((1023&a)<<10)|1023&e.charCodeAt(++i)),127>=a){if(n>=o)break;t[n++]=a}else{if(2047>=a){if(n+1>=o)break;t[n++]=192|a>>6}else{if(65535>=a){if(n+2>=o)break;t[n++]=224|a>>12}else{if(n+3>=o)break;t[n++]=240|a>>18,t[n++]=128|a>>12&63}t[n++]=128|a>>6&63}t[n++]=128|63&a}}return t[n]=0,n-r}function O(e){for(var t=0,n=0;n=o&&(o=65536+((1023&o)<<10)|1023&e.charCodeAt(++n)),127>=o?++t:t=2047>=o?t+2:65535>=o?t+3:t+4}return t}function B(e,t){for(var n=0;n>0]=e.charCodeAt(n)}var N,L,P,U,j,q,z,K=a.INITIAL_MEMORY||262144;(C=a.wasmMemory?a.wasmMemory:new WebAssembly.Memory({initial:K/65536,maximum:K/65536}))&&(N=C.buffer),K=N.byteLength;var G=N;function $(e){for(;0{var o=n(52479);function r(e){var t=function(){return t.called?t.value:(t.called=!0,t.value=e.apply(this,arguments))};return t.called=!1,t}function i(e){var t=function(){if(t.called)throw new Error(t.onceError);return t.called=!0,t.value=e.apply(this,arguments)},n=e.name||"Function wrapped with `once`";return t.onceError=n+" shouldn't be called more than once",t.called=!1,t}e.exports=o(r),e.exports.strict=o(i),r.proto=r((function(){Object.defineProperty(Function.prototype,"once",{value:function(){return r(this)},configurable:!0}),Object.defineProperty(Function.prototype,"onceStrict",{value:function(){return i(this)},configurable:!0})}))},873:e=>{"use strict";e.exports=JSON.parse('{"2.16.840.1.101.3.4.1.1":"aes-128-ecb","2.16.840.1.101.3.4.1.2":"aes-128-cbc","2.16.840.1.101.3.4.1.3":"aes-128-ofb","2.16.840.1.101.3.4.1.4":"aes-128-cfb","2.16.840.1.101.3.4.1.21":"aes-192-ecb","2.16.840.1.101.3.4.1.22":"aes-192-cbc","2.16.840.1.101.3.4.1.23":"aes-192-ofb","2.16.840.1.101.3.4.1.24":"aes-192-cfb","2.16.840.1.101.3.4.1.41":"aes-256-ecb","2.16.840.1.101.3.4.1.42":"aes-256-cbc","2.16.840.1.101.3.4.1.43":"aes-256-ofb","2.16.840.1.101.3.4.1.44":"aes-256-cfb"}')},52818:(e,t,n)=>{"use strict";var o=n(39809);t.certificate=n(41934);var r=o.define("RSAPrivateKey",(function(){this.seq().obj(this.key("version").int(),this.key("modulus").int(),this.key("publicExponent").int(),this.key("privateExponent").int(),this.key("prime1").int(),this.key("prime2").int(),this.key("exponent1").int(),this.key("exponent2").int(),this.key("coefficient").int())}));t.RSAPrivateKey=r;var i=o.define("RSAPublicKey",(function(){this.seq().obj(this.key("modulus").int(),this.key("publicExponent").int())}));t.RSAPublicKey=i;var a=o.define("SubjectPublicKeyInfo",(function(){this.seq().obj(this.key("algorithm").use(s),this.key("subjectPublicKey").bitstr())}));t.PublicKey=a;var s=o.define("AlgorithmIdentifier",(function(){this.seq().obj(this.key("algorithm").objid(),this.key("none").null_().optional(),this.key("curve").objid().optional(),this.key("params").seq().obj(this.key("p").int(),this.key("q").int(),this.key("g").int()).optional())})),u=o.define("PrivateKeyInfo",(function(){this.seq().obj(this.key("version").int(),this.key("algorithm").use(s),this.key("subjectPrivateKey").octstr())}));t.PrivateKey=u;var c=o.define("EncryptedPrivateKeyInfo",(function(){this.seq().obj(this.key("algorithm").seq().obj(this.key("id").objid(),this.key("decrypt").seq().obj(this.key("kde").seq().obj(this.key("id").objid(),this.key("kdeparams").seq().obj(this.key("salt").octstr(),this.key("iters").int())),this.key("cipher").seq().obj(this.key("algo").objid(),this.key("iv").octstr()))),this.key("subjectPrivateKey").octstr())}));t.EncryptedPrivateKey=c;var l=o.define("DSAPrivateKey",(function(){this.seq().obj(this.key("version").int(),this.key("p").int(),this.key("q").int(),this.key("g").int(),this.key("pub_key").int(),this.key("priv_key").int())}));t.DSAPrivateKey=l,t.DSAparam=o.define("DSAparam",(function(){this.int()}));var d=o.define("ECPrivateKey",(function(){this.seq().obj(this.key("version").int(),this.key("privateKey").octstr(),this.key("parameters").optional().explicit(0).use(h),this.key("publicKey").optional().explicit(1).bitstr())}));t.ECPrivateKey=d;var h=o.define("ECParameters",(function(){this.choice({namedCurve:this.objid()})}));t.signature=o.define("signature",(function(){this.seq().obj(this.key("r").int(),this.key("s").int())}))},41934:(e,t,n)=>{"use strict";var o=n(39809),r=o.define("Time",(function(){this.choice({utcTime:this.utctime(),generalTime:this.gentime()})})),i=o.define("AttributeTypeValue",(function(){this.seq().obj(this.key("type").objid(),this.key("value").any())})),a=o.define("AlgorithmIdentifier",(function(){this.seq().obj(this.key("algorithm").objid(),this.key("parameters").optional(),this.key("curve").objid().optional())})),s=o.define("SubjectPublicKeyInfo",(function(){this.seq().obj(this.key("algorithm").use(a),this.key("subjectPublicKey").bitstr())})),u=o.define("RelativeDistinguishedName",(function(){this.setof(i)})),c=o.define("RDNSequence",(function(){this.seqof(u)})),l=o.define("Name",(function(){this.choice({rdnSequence:this.use(c)})})),d=o.define("Validity",(function(){this.seq().obj(this.key("notBefore").use(r),this.key("notAfter").use(r))})),h=o.define("Extension",(function(){this.seq().obj(this.key("extnID").objid(),this.key("critical").bool().def(!1),this.key("extnValue").octstr())})),p=o.define("TBSCertificate",(function(){this.seq().obj(this.key("version").explicit(0).int().optional(),this.key("serialNumber").int(),this.key("signature").use(a),this.key("issuer").use(l),this.key("validity").use(d),this.key("subject").use(l),this.key("subjectPublicKeyInfo").use(s),this.key("issuerUniqueID").implicit(1).bitstr().optional(),this.key("subjectUniqueID").implicit(2).bitstr().optional(),this.key("extensions").explicit(3).seqof(h).optional())})),f=o.define("X509Certificate",(function(){this.seq().obj(this.key("tbsCertificate").use(p),this.key("signatureAlgorithm").use(a),this.key("signatureValue").bitstr())}));e.exports=f},77631:(e,t,n)=>{var o=/Proc-Type: 4,ENCRYPTED[\n\r]+DEK-Info: AES-((?:128)|(?:192)|(?:256))-CBC,([0-9A-H]+)[\n\r]+([0-9A-z\n\r+/=]+)[\n\r]+/m,r=/^-----BEGIN ((?:.*? KEY)|CERTIFICATE)-----/m,i=/^-----BEGIN ((?:.*? KEY)|CERTIFICATE)-----([0-9A-z\n\r+/=]+)-----END \1-----$/m,a=n(13048),s=n(44696),u=n(89509).Buffer;e.exports=function(e,t){var n,c=e.toString(),l=c.match(o);if(l){var d="aes"+l[1],h=u.from(l[2],"hex"),p=u.from(l[3].replace(/[\r\n]/g,""),"base64"),f=a(t,h.slice(0,8),parseInt(l[1],10)).key,g=[],m=s.createDecipheriv(d,f,h);g.push(m.update(p)),g.push(m.final()),n=u.concat(g)}else{var _=c.match(i);n=u.from(_[2].replace(/[\r\n]/g,""),"base64")}return{tag:c.match(r)[1],data:n}}},70980:(e,t,n)=>{var o=n(52818),r=n(873),i=n(77631),a=n(44696),s=n(25632),u=n(89509).Buffer;function c(e){var t;"object"!=typeof e||u.isBuffer(e)||(t=e.passphrase,e=e.key),"string"==typeof e&&(e=u.from(e));var n,c,l=i(e,t),d=l.tag,h=l.data;switch(d){case"CERTIFICATE":c=o.certificate.decode(h,"der").tbsCertificate.subjectPublicKeyInfo;case"PUBLIC KEY":switch(c||(c=o.PublicKey.decode(h,"der")),n=c.algorithm.algorithm.join(".")){case"1.2.840.113549.1.1.1":return o.RSAPublicKey.decode(c.subjectPublicKey.data,"der");case"1.2.840.10045.2.1":return c.subjectPrivateKey=c.subjectPublicKey,{type:"ec",data:c};case"1.2.840.10040.4.1":return c.algorithm.params.pub_key=o.DSAparam.decode(c.subjectPublicKey.data,"der"),{type:"dsa",data:c.algorithm.params};default:throw new Error("unknown key id "+n)}case"ENCRYPTED PRIVATE KEY":h=function(e,t){var n=e.algorithm.decrypt.kde.kdeparams.salt,o=parseInt(e.algorithm.decrypt.kde.kdeparams.iters.toString(),10),i=r[e.algorithm.decrypt.cipher.algo.join(".")],c=e.algorithm.decrypt.cipher.iv,l=e.subjectPrivateKey,d=parseInt(i.split("-")[1],10)/8,h=s.pbkdf2Sync(t,n,o,d,"sha1"),p=a.createDecipheriv(i,h,c),f=[];return f.push(p.update(l)),f.push(p.final()),u.concat(f)}(h=o.EncryptedPrivateKey.decode(h,"der"),t);case"PRIVATE KEY":switch(n=(c=o.PrivateKey.decode(h,"der")).algorithm.algorithm.join(".")){case"1.2.840.113549.1.1.1":return o.RSAPrivateKey.decode(c.subjectPrivateKey,"der");case"1.2.840.10045.2.1":return{curve:c.algorithm.curve,privateKey:o.ECPrivateKey.decode(c.subjectPrivateKey,"der").privateKey};case"1.2.840.10040.4.1":return c.algorithm.params.priv_key=o.DSAparam.decode(c.subjectPrivateKey,"der"),{type:"dsa",params:c.algorithm.params};default:throw new Error("unknown key id "+n)}case"RSA PUBLIC KEY":return o.RSAPublicKey.decode(h,"der");case"RSA PRIVATE KEY":return o.RSAPrivateKey.decode(h,"der");case"DSA PRIVATE KEY":return{type:"dsa",params:o.DSAPrivateKey.decode(h,"der")};case"EC PRIVATE KEY":return{curve:(h=o.ECPrivateKey.decode(h,"der")).parameters.value,privateKey:h.privateKey};default:throw new Error("unknown key type "+d)}}e.exports=c,c.signature=o.signature},89435:e=>{"use strict";var t;e.exports=function(e){var n,o="&"+e+";";return(t=t||document.createElement("i")).innerHTML=o,(59!==(n=t.textContent).charCodeAt(n.length-1)||"semi"===e)&&(n!==o&&n)}},57574:(e,t,n)=>{"use strict";var o=n(16588),r=n(6852),i=n(46195),a=n(79480),s=n(7961),u=n(89435);e.exports=function(e,t){var n,i,a={};for(i in t||(t={}),h)n=t[i],a[i]=null==n?h[i]:n;return(a.position.indent||a.position.start)&&(a.indent=a.position.indent||[],a.position=a.position.start),function(e,t){var n,i,a,h,b,v,w,E,k,D,S,x,C,A,T,R,I,M,O,B,N=t.additional,L=t.nonTerminated,P=t.text,U=t.reference,j=t.warning,q=t.textContext,z=t.referenceContext,K=t.warningContext,G=t.position,$=t.indent||[],H=e.length,V=0,W=-1,Y=G.column||1,Z=G.line||1,X="",J=[];for("string"==typeof N&&(N=N.charCodeAt(0)),R=Q(),E=j?function(e,t){var n=Q();n.column+=t,n.offset+=t,j.call(K,F[e],n,e)}:d,V--,H++;++V=55296&&B<=57343||B>1114111?(E(7,M),v=l(65533)):v in r?(E(6,M),v=r[v]):(D="",y(v)&&E(6,M),v>65535&&(D+=l((v-=65536)>>>10|55296),v=56320|1023&v),v=D+l(v))):A!==p&&E(4,M)),v?(ee(),R=Q(),V=O-1,Y+=O-C+1,J.push(v),(I=Q()).offset++,U&&U.call(z,v,{start:R,end:I},e.slice(C-1,O)),R=I):(h=e.slice(C-1,O),X+=h,Y+=h.length,V=O-1)}else 10===b&&(Z++,W++,Y=0),b==b?(X+=l(b),Y++):ee();return J.join("");function Q(){return{line:Z,column:Y,offset:V+(G.offset||0)}}function ee(){X&&(J.push(X),P&&P.call(q,X,{start:R,end:Q()}),X="")}}(e,a)};var c={}.hasOwnProperty,l=String.fromCharCode,d=Function.prototype,h={warning:null,reference:null,text:null,warningContext:null,referenceContext:null,textContext:null,position:{},additional:null,attribute:!1,nonTerminated:!0},p="named",f="hexadecimal",g="decimal",m={hexadecimal:16,decimal:10},_={};_.named=s,_[g]=i,_[f]=a;var F={};function y(e){return e>=1&&e<=8||11===e||e>=13&&e<=31||e>=127&&e<=159||e>=64976&&e<=65007||65535==(65535&e)||65534==(65535&e)}F[1]="Named character references must be terminated by a semicolon",F[2]="Numeric character references must be terminated by a semicolon",F[3]="Named character references cannot be empty",F[4]="Numeric character references cannot be empty",F[5]="Named character references must be known",F[6]="Numeric character references cannot be disallowed",F[7]="Numeric character references cannot be outside the permissible Unicode range"},26470:e=>{"use strict";function t(e){if("string"!=typeof e)throw new TypeError("Path must be a string. Received "+JSON.stringify(e))}function n(e,t){for(var n,o="",r=0,i=-1,a=0,s=0;s<=e.length;++s){if(s2){var u=o.lastIndexOf("/");if(u!==o.length-1){-1===u?(o="",r=0):r=(o=o.slice(0,u)).length-1-o.lastIndexOf("/"),i=s,a=0;continue}}else if(2===o.length||1===o.length){o="",r=0,i=s,a=0;continue}t&&(o.length>0?o+="/..":o="..",r=2)}else o.length>0?o+="/"+e.slice(i+1,s):o=e.slice(i+1,s),r=s-i-1;i=s,a=0}else 46===n&&-1!==a?++a:a=-1}return o}var o={resolve:function(){for(var e,o="",r=!1,i=arguments.length-1;i>=-1&&!r;i--){var a;i>=0?a=arguments[i]:(void 0===e&&(e=process.cwd()),a=e),t(a),0!==a.length&&(o=a+"/"+o,r=47===a.charCodeAt(0))}return o=n(o,!r),r?o.length>0?"/"+o:"/":o.length>0?o:"."},normalize:function(e){if(t(e),0===e.length)return".";var o=47===e.charCodeAt(0),r=47===e.charCodeAt(e.length-1);return 0!==(e=n(e,!o)).length||o||(e="."),e.length>0&&r&&(e+="/"),o?"/"+e:e},isAbsolute:function(e){return t(e),e.length>0&&47===e.charCodeAt(0)},join:function(){if(0===arguments.length)return".";for(var e,n=0;n0&&(void 0===e?e=r:e+="/"+r)}return void 0===e?".":o.normalize(e)},relative:function(e,n){if(t(e),t(n),e===n)return"";if((e=o.resolve(e))===(n=o.resolve(n)))return"";for(var r=1;rc){if(47===n.charCodeAt(s+d))return n.slice(s+d+1);if(0===d)return n.slice(s+d)}else a>c&&(47===e.charCodeAt(r+d)?l=d:0===d&&(l=0));break}var h=e.charCodeAt(r+d);if(h!==n.charCodeAt(s+d))break;47===h&&(l=d)}var p="";for(d=r+l+1;d<=i;++d)d!==i&&47!==e.charCodeAt(d)||(0===p.length?p+="..":p+="/..");return p.length>0?p+n.slice(s+l):(s+=l,47===n.charCodeAt(s)&&++s,n.slice(s))},_makeLong:function(e){return e},dirname:function(e){if(t(e),0===e.length)return".";for(var n=e.charCodeAt(0),o=47===n,r=-1,i=!0,a=e.length-1;a>=1;--a)if(47===(n=e.charCodeAt(a))){if(!i){r=a;break}}else i=!1;return-1===r?o?"/":".":o&&1===r?"//":e.slice(0,r)},basename:function(e,n){if(void 0!==n&&"string"!=typeof n)throw new TypeError('"ext" argument must be a string');t(e);var o,r=0,i=-1,a=!0;if(void 0!==n&&n.length>0&&n.length<=e.length){if(n.length===e.length&&n===e)return"";var s=n.length-1,u=-1;for(o=e.length-1;o>=0;--o){var c=e.charCodeAt(o);if(47===c){if(!a){r=o+1;break}}else-1===u&&(a=!1,u=o+1),s>=0&&(c===n.charCodeAt(s)?-1==--s&&(i=o):(s=-1,i=u))}return r===i?i=u:-1===i&&(i=e.length),e.slice(r,i)}for(o=e.length-1;o>=0;--o)if(47===e.charCodeAt(o)){if(!a){r=o+1;break}}else-1===i&&(a=!1,i=o+1);return-1===i?"":e.slice(r,i)},extname:function(e){t(e);for(var n=-1,o=0,r=-1,i=!0,a=0,s=e.length-1;s>=0;--s){var u=e.charCodeAt(s);if(47!==u)-1===r&&(i=!1,r=s+1),46===u?-1===n?n=s:1!==a&&(a=1):-1!==n&&(a=-1);else if(!i){o=s+1;break}}return-1===n||-1===r||0===a||1===a&&n===r-1&&n===o+1?"":e.slice(n,r)},format:function(e){if(null===e||"object"!=typeof e)throw new TypeError('The "pathObject" argument must be of type Object. Received type '+typeof e);return function(e,t){var n=t.dir||t.root,o=t.base||(t.name||"")+(t.ext||"");return n?n===t.root?n+o:n+"/"+o:o}(0,e)},parse:function(e){t(e);var n={root:"",dir:"",base:"",ext:"",name:""};if(0===e.length)return n;var o,r=e.charCodeAt(0),i=47===r;i?(n.root="/",o=1):o=0;for(var a=-1,s=0,u=-1,c=!0,l=e.length-1,d=0;l>=o;--l)if(47!==(r=e.charCodeAt(l)))-1===u&&(c=!1,u=l+1),46===r?-1===a?a=l:1!==d&&(d=1):-1!==a&&(d=-1);else if(!c){s=l+1;break}return-1===a||-1===u||0===d||1===d&&a===u-1&&a===s+1?-1!==u&&(n.base=n.name=0===s&&i?e.slice(1,u):e.slice(s,u)):(0===s&&i?(n.name=e.slice(1,a),n.base=e.slice(1,u)):(n.name=e.slice(s,a),n.base=e.slice(s,u)),n.ext=e.slice(a,u)),s>0?n.dir=e.slice(0,s-1):i&&(n.dir="/"),n},sep:"/",delimiter:":",win32:null,posix:null};o.posix=o,e.exports=o},25632:(e,t,n)=>{t.pbkdf2=n(88638),t.pbkdf2Sync=n(91257)},88638:(e,t,n)=>{var o,r=n(89509).Buffer,i=n(77357),a=n(12368),s=n(91257),u=n(57777),c=n.g.crypto&&n.g.crypto.subtle,l={sha:"SHA-1","sha-1":"SHA-1",sha1:"SHA-1",sha256:"SHA-256","sha-256":"SHA-256",sha384:"SHA-384","sha-384":"SHA-384","sha-512":"SHA-512",sha512:"SHA-512"},d=[];function h(e,t,n,o,i){return c.importKey("raw",e,{name:"PBKDF2"},!1,["deriveBits"]).then((function(e){return c.deriveBits({name:"PBKDF2",salt:t,iterations:n,hash:{name:i}},e,o<<3)})).then((function(e){return r.from(e)}))}e.exports=function(e,t,p,f,g,m){"function"==typeof g&&(m=g,g=void 0);var _=l[(g=g||"sha1").toLowerCase()];if(!_||"function"!=typeof n.g.Promise)return process.nextTick((function(){var n;try{n=s(e,t,p,f,g)}catch(e){return m(e)}m(null,n)}));if(i(p,f),e=u(e,a,"Password"),t=u(t,a,"Salt"),"function"!=typeof m)throw new Error("No callback provided to pbkdf2");!function(e,t){e.then((function(e){process.nextTick((function(){t(null,e)}))}),(function(e){process.nextTick((function(){t(e)}))}))}(function(e){if(n.g.process&&!n.g.process.browser)return Promise.resolve(!1);if(!c||!c.importKey||!c.deriveBits)return Promise.resolve(!1);if(void 0!==d[e])return d[e];var t=h(o=o||r.alloc(8),o,10,128,e).then((function(){return!0})).catch((function(){return!1}));return d[e]=t,t}(_).then((function(n){return n?h(e,t,p,f,_):s(e,t,p,f,g)})),m)}},12368:e=>{var t;t=process.browser?"utf-8":process.version?parseInt(process.version.split(".")[0].slice(1),10)>=6?"utf-8":"binary":"utf-8",e.exports=t},77357:e=>{var t=Math.pow(2,30)-1;e.exports=function(e,n){if("number"!=typeof e)throw new TypeError("Iterations not a number");if(e<0)throw new TypeError("Bad iterations");if("number"!=typeof n)throw new TypeError("Key length not a number");if(n<0||n>t||n!=n)throw new TypeError("Bad key length")}},91257:(e,t,n)=>{var o=n(78028),r=n(79785),i=n(89072),a=n(89509).Buffer,s=n(77357),u=n(12368),c=n(57777),l=a.alloc(128),d={md5:16,sha1:20,sha224:28,sha256:32,sha384:48,sha512:64,rmd160:20,ripemd160:20};function h(e,t,n){var s=function(e){return"rmd160"===e||"ripemd160"===e?function(e){return(new r).update(e).digest()}:"md5"===e?o:function(t){return i(e).update(t).digest()}}(e),u="sha512"===e||"sha384"===e?128:64;t.length>u?t=s(t):t.length{var o=n(89509).Buffer;e.exports=function(e,t,n){if(o.isBuffer(e))return e;if("string"==typeof e)return o.from(e,t);if(ArrayBuffer.isView(e))return o.from(e.buffer);throw new TypeError(n+" must be a string, a Buffer, a typed array or a DataView")}},28325:(e,t,n)=>{var o=function(e){var t=/\blang(?:uage)?-([\w-]+)\b/i,n=0,o={manual:e.Prism&&e.Prism.manual,disableWorkerMessageHandler:e.Prism&&e.Prism.disableWorkerMessageHandler,util:{encode:function e(t){return t instanceof r?new r(t.type,e(t.content),t.alias):Array.isArray(t)?t.map(e):t.replace(/&/g,"&").replace(/=d.reach);E+=w.value.length,w=w.next){var k=w.value;if(t.length>e.length)return;if(!(k instanceof r)){var D,S=1;if(F){if(!(D=i(v,E,e,_)))break;var x=D.index,C=D.index+D[0].length,A=E;for(A+=w.value.length;x>=A;)A+=(w=w.next).value.length;if(E=A-=w.value.length,w.value instanceof r)continue;for(var T=w;T!==t.tail&&(Ad.reach&&(d.reach=O);var B=w.prev;I&&(B=u(t,B,I),E+=I.length),c(t,B,S),w=u(t,B,new r(h,m?o.tokenize(R,m):R,y,R)),M&&u(t,w,M),S>1&&a(e,t,n,w.prev,E,{cause:h+","+f,reach:O})}}}}}function s(){var e={value:null,prev:null,next:null},t={value:null,prev:e,next:null};e.next=t,this.head=e,this.tail=t,this.length=0}function u(e,t,n){var o=t.next,r={value:n,prev:t,next:o};return t.next=r,o.prev=r,e.length++,r}function c(e,t,n){for(var o=t.next,r=0;r"+i.content+""},!e.document)return e.addEventListener?(o.disableWorkerMessageHandler||e.addEventListener("message",(function(t){var n=JSON.parse(t.data),r=n.language,i=n.code,a=n.immediateClose;e.postMessage(o.highlight(i,o.languages[r],r)),a&&e.close()}),!1),o):o;var l=o.util.currentScript();function d(){o.manual||o.highlightAll()}if(l&&(o.filename=l.src,l.hasAttribute("data-manual")&&(o.manual=!0)),!o.manual){var h=document.readyState;"loading"===h||"interactive"===h&&l&&l.defer?document.addEventListener("DOMContentLoaded",d):window.requestAnimationFrame?window.requestAnimationFrame(d):window.setTimeout(d,16)}return o}("undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{});e.exports&&(e.exports=o),void 0!==n.g&&(n.g.Prism=o)},88212:e=>{"use strict";"undefined"==typeof process||!process.version||0===process.version.indexOf("v0.")||0===process.version.indexOf("v1.")&&0!==process.version.indexOf("v1.8.")?e.exports={nextTick:function(e,t,n,o){if("function"!=typeof e)throw new TypeError('"callback" argument must be a function');var r,i,a=arguments.length;switch(a){case 0:case 1:return process.nextTick(e);case 2:return process.nextTick((function(){e.call(null,t)}));case 3:return process.nextTick((function(){e.call(null,t,n)}));case 4:return process.nextTick((function(){e.call(null,t,n,o)}));default:for(r=new Array(a-1),i=0;i{"use strict";var o=n(50414);function r(){}function i(){}i.resetWarningCache=r,e.exports=function(){function e(e,t,n,r,i,a){if(a!==o){var s=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw s.name="Invariant Violation",s}}function t(){return e}e.isRequired=e;var n={array:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,elementType:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t,checkPropTypes:i,resetWarningCache:r};return n.PropTypes=n,n}},45697:(e,t,n)=>{e.exports=n(92703)()},50414:e=>{"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},99560:(e,t,n)=>{"use strict";var o=n(66632),r=n(98805),i=n(89750),a="data";e.exports=function(e,t){var n=o(t),h=t,p=i;return n in e.normal?e.property[e.normal[n]]:(n.length>4&&n.slice(0,4)===a&&s.test(t)&&("-"===t.charAt(4)?h=function(e){var t=e.slice(5).replace(u,d);return a+t.charAt(0).toUpperCase()+t.slice(1)}(t):t=function(e){var t=e.slice(4);return u.test(t)?e:("-"!==(t=t.replace(c,l)).charAt(0)&&(t="-"+t),a+t)}(t),p=r),new p(h,t))};var s=/^data[-\w.:]+$/i,u=/-[a-z]/g,c=/[A-Z]/g;function l(e){return"-"+e.toLowerCase()}function d(e){return e.charAt(1).toUpperCase()}},93934:e=>{"use strict";e.exports=JSON.parse('{"classId":"classID","dataType":"datatype","itemId":"itemID","strokeDashArray":"strokeDasharray","strokeDashOffset":"strokeDashoffset","strokeLineCap":"strokeLinecap","strokeLineJoin":"strokeLinejoin","strokeMiterLimit":"strokeMiterlimit","typeOf":"typeof","xLinkActuate":"xlinkActuate","xLinkArcRole":"xlinkArcrole","xLinkHref":"xlinkHref","xLinkRole":"xlinkRole","xLinkShow":"xlinkShow","xLinkTitle":"xlinkTitle","xLinkType":"xlinkType","xmlnsXLink":"xmlnsXlink"}')},97247:(e,t,n)=>{"use strict";var o=n(19940),r=n(8289),i=n(5812),a=n(94397),s=n(67716),u=n(61805);e.exports=o([i,r,a,s,u])},67716:(e,t,n)=>{"use strict";var o=n(17e3),r=n(17596),i=o.booleanish,a=o.number,s=o.spaceSeparated;e.exports=r({transform:function(e,t){return"role"===t?t:"aria-"+t.slice(4).toLowerCase()},properties:{ariaActiveDescendant:null,ariaAtomic:i,ariaAutoComplete:null,ariaBusy:i,ariaChecked:i,ariaColCount:a,ariaColIndex:a,ariaColSpan:a,ariaControls:s,ariaCurrent:null,ariaDescribedBy:s,ariaDetails:null,ariaDisabled:i,ariaDropEffect:s,ariaErrorMessage:null,ariaExpanded:i,ariaFlowTo:s,ariaGrabbed:i,ariaHasPopup:null,ariaHidden:i,ariaInvalid:null,ariaKeyShortcuts:null,ariaLabel:null,ariaLabelledBy:s,ariaLevel:a,ariaLive:null,ariaModal:i,ariaMultiLine:i,ariaMultiSelectable:i,ariaOrientation:null,ariaOwns:s,ariaPlaceholder:null,ariaPosInSet:a,ariaPressed:i,ariaReadOnly:i,ariaRelevant:null,ariaRequired:i,ariaRoleDescription:s,ariaRowCount:a,ariaRowIndex:a,ariaRowSpan:a,ariaSelected:i,ariaSetSize:a,ariaSort:null,ariaValueMax:a,ariaValueMin:a,ariaValueNow:a,ariaValueText:null,role:null}})},61805:(e,t,n)=>{"use strict";var o=n(17e3),r=n(17596),i=n(10855),a=o.boolean,s=o.overloadedBoolean,u=o.booleanish,c=o.number,l=o.spaceSeparated,d=o.commaSeparated;e.exports=r({space:"html",attributes:{acceptcharset:"accept-charset",classname:"class",htmlfor:"for",httpequiv:"http-equiv"},transform:i,mustUseProperty:["checked","multiple","muted","selected"],properties:{abbr:null,accept:d,acceptCharset:l,accessKey:l,action:null,allow:null,allowFullScreen:a,allowPaymentRequest:a,allowUserMedia:a,alt:null,as:null,async:a,autoCapitalize:null,autoComplete:l,autoFocus:a,autoPlay:a,capture:a,charSet:null,checked:a,cite:null,className:l,cols:c,colSpan:null,content:null,contentEditable:u,controls:a,controlsList:l,coords:c|d,crossOrigin:null,data:null,dateTime:null,decoding:null,default:a,defer:a,dir:null,dirName:null,disabled:a,download:s,draggable:u,encType:null,enterKeyHint:null,form:null,formAction:null,formEncType:null,formMethod:null,formNoValidate:a,formTarget:null,headers:l,height:c,hidden:a,high:c,href:null,hrefLang:null,htmlFor:l,httpEquiv:l,id:null,imageSizes:null,imageSrcSet:d,inputMode:null,integrity:null,is:null,isMap:a,itemId:null,itemProp:l,itemRef:l,itemScope:a,itemType:l,kind:null,label:null,lang:null,language:null,list:null,loading:null,loop:a,low:c,manifest:null,max:null,maxLength:c,media:null,method:null,min:null,minLength:c,multiple:a,muted:a,name:null,nonce:null,noModule:a,noValidate:a,onAbort:null,onAfterPrint:null,onAuxClick:null,onBeforePrint:null,onBeforeUnload:null,onBlur:null,onCancel:null,onCanPlay:null,onCanPlayThrough:null,onChange:null,onClick:null,onClose:null,onContextMenu:null,onCopy:null,onCueChange:null,onCut:null,onDblClick:null,onDrag:null,onDragEnd:null,onDragEnter:null,onDragExit:null,onDragLeave:null,onDragOver:null,onDragStart:null,onDrop:null,onDurationChange:null,onEmptied:null,onEnded:null,onError:null,onFocus:null,onFormData:null,onHashChange:null,onInput:null,onInvalid:null,onKeyDown:null,onKeyPress:null,onKeyUp:null,onLanguageChange:null,onLoad:null,onLoadedData:null,onLoadedMetadata:null,onLoadEnd:null,onLoadStart:null,onMessage:null,onMessageError:null,onMouseDown:null,onMouseEnter:null,onMouseLeave:null,onMouseMove:null,onMouseOut:null,onMouseOver:null,onMouseUp:null,onOffline:null,onOnline:null,onPageHide:null,onPageShow:null,onPaste:null,onPause:null,onPlay:null,onPlaying:null,onPopState:null,onProgress:null,onRateChange:null,onRejectionHandled:null,onReset:null,onResize:null,onScroll:null,onSecurityPolicyViolation:null,onSeeked:null,onSeeking:null,onSelect:null,onSlotChange:null,onStalled:null,onStorage:null,onSubmit:null,onSuspend:null,onTimeUpdate:null,onToggle:null,onUnhandledRejection:null,onUnload:null,onVolumeChange:null,onWaiting:null,onWheel:null,open:a,optimum:c,pattern:null,ping:l,placeholder:null,playsInline:a,poster:null,preload:null,readOnly:a,referrerPolicy:null,rel:l,required:a,reversed:a,rows:c,rowSpan:c,sandbox:l,scope:null,scoped:a,seamless:a,selected:a,shape:null,size:c,sizes:null,slot:null,span:c,spellCheck:u,src:null,srcDoc:null,srcLang:null,srcSet:d,start:c,step:null,style:null,tabIndex:c,target:null,title:null,translate:null,type:null,typeMustMatch:a,useMap:null,value:u,width:c,wrap:null,align:null,aLink:null,archive:l,axis:null,background:null,bgColor:null,border:c,borderColor:null,bottomMargin:c,cellPadding:null,cellSpacing:null,char:null,charOff:null,classId:null,clear:null,code:null,codeBase:null,codeType:null,color:null,compact:a,declare:a,event:null,face:null,frame:null,frameBorder:null,hSpace:c,leftMargin:c,link:null,longDesc:null,lowSrc:null,marginHeight:c,marginWidth:c,noResize:a,noHref:a,noShade:a,noWrap:a,object:null,profile:null,prompt:null,rev:null,rightMargin:c,rules:null,scheme:null,scrolling:u,standby:null,summary:null,text:null,topMargin:c,valueType:null,version:null,vAlign:null,vLink:null,vSpace:c,allowTransparency:null,autoCorrect:null,autoSave:null,disablePictureInPicture:a,disableRemotePlayback:a,prefix:null,property:null,results:c,security:null,unselectable:null}})},97421:(e,t,n)=>{"use strict";var o=n(17e3),r=n(17596),i=n(28740),a=o.boolean,s=o.number,u=o.spaceSeparated,c=o.commaSeparated,l=o.commaOrSpaceSeparated;e.exports=r({space:"svg",attributes:{accentHeight:"accent-height",alignmentBaseline:"alignment-baseline",arabicForm:"arabic-form",baselineShift:"baseline-shift",capHeight:"cap-height",className:"class",clipPath:"clip-path",clipRule:"clip-rule",colorInterpolation:"color-interpolation",colorInterpolationFilters:"color-interpolation-filters",colorProfile:"color-profile",colorRendering:"color-rendering",crossOrigin:"crossorigin",dataType:"datatype",dominantBaseline:"dominant-baseline",enableBackground:"enable-background",fillOpacity:"fill-opacity",fillRule:"fill-rule",floodColor:"flood-color",floodOpacity:"flood-opacity",fontFamily:"font-family",fontSize:"font-size",fontSizeAdjust:"font-size-adjust",fontStretch:"font-stretch",fontStyle:"font-style",fontVariant:"font-variant",fontWeight:"font-weight",glyphName:"glyph-name",glyphOrientationHorizontal:"glyph-orientation-horizontal",glyphOrientationVertical:"glyph-orientation-vertical",hrefLang:"hreflang",horizAdvX:"horiz-adv-x",horizOriginX:"horiz-origin-x",horizOriginY:"horiz-origin-y",imageRendering:"image-rendering",letterSpacing:"letter-spacing",lightingColor:"lighting-color",markerEnd:"marker-end",markerMid:"marker-mid",markerStart:"marker-start",navDown:"nav-down",navDownLeft:"nav-down-left",navDownRight:"nav-down-right",navLeft:"nav-left",navNext:"nav-next",navPrev:"nav-prev",navRight:"nav-right",navUp:"nav-up",navUpLeft:"nav-up-left",navUpRight:"nav-up-right",onAbort:"onabort",onActivate:"onactivate",onAfterPrint:"onafterprint",onBeforePrint:"onbeforeprint",onBegin:"onbegin",onCancel:"oncancel",onCanPlay:"oncanplay",onCanPlayThrough:"oncanplaythrough",onChange:"onchange",onClick:"onclick",onClose:"onclose",onCopy:"oncopy",onCueChange:"oncuechange",onCut:"oncut",onDblClick:"ondblclick",onDrag:"ondrag",onDragEnd:"ondragend",onDragEnter:"ondragenter",onDragExit:"ondragexit",onDragLeave:"ondragleave",onDragOver:"ondragover",onDragStart:"ondragstart",onDrop:"ondrop",onDurationChange:"ondurationchange",onEmptied:"onemptied",onEnd:"onend",onEnded:"onended",onError:"onerror",onFocus:"onfocus",onFocusIn:"onfocusin",onFocusOut:"onfocusout",onHashChange:"onhashchange",onInput:"oninput",onInvalid:"oninvalid",onKeyDown:"onkeydown",onKeyPress:"onkeypress",onKeyUp:"onkeyup",onLoad:"onload",onLoadedData:"onloadeddata",onLoadedMetadata:"onloadedmetadata",onLoadStart:"onloadstart",onMessage:"onmessage",onMouseDown:"onmousedown",onMouseEnter:"onmouseenter",onMouseLeave:"onmouseleave",onMouseMove:"onmousemove",onMouseOut:"onmouseout",onMouseOver:"onmouseover",onMouseUp:"onmouseup",onMouseWheel:"onmousewheel",onOffline:"onoffline",onOnline:"ononline",onPageHide:"onpagehide",onPageShow:"onpageshow",onPaste:"onpaste",onPause:"onpause",onPlay:"onplay",onPlaying:"onplaying",onPopState:"onpopstate",onProgress:"onprogress",onRateChange:"onratechange",onRepeat:"onrepeat",onReset:"onreset",onResize:"onresize",onScroll:"onscroll",onSeeked:"onseeked",onSeeking:"onseeking",onSelect:"onselect",onShow:"onshow",onStalled:"onstalled",onStorage:"onstorage",onSubmit:"onsubmit",onSuspend:"onsuspend",onTimeUpdate:"ontimeupdate",onToggle:"ontoggle",onUnload:"onunload",onVolumeChange:"onvolumechange",onWaiting:"onwaiting",onZoom:"onzoom",overlinePosition:"overline-position",overlineThickness:"overline-thickness",paintOrder:"paint-order",panose1:"panose-1",pointerEvents:"pointer-events",referrerPolicy:"referrerpolicy",renderingIntent:"rendering-intent",shapeRendering:"shape-rendering",stopColor:"stop-color",stopOpacity:"stop-opacity",strikethroughPosition:"strikethrough-position",strikethroughThickness:"strikethrough-thickness",strokeDashArray:"stroke-dasharray",strokeDashOffset:"stroke-dashoffset",strokeLineCap:"stroke-linecap",strokeLineJoin:"stroke-linejoin",strokeMiterLimit:"stroke-miterlimit",strokeOpacity:"stroke-opacity",strokeWidth:"stroke-width",tabIndex:"tabindex",textAnchor:"text-anchor",textDecoration:"text-decoration",textRendering:"text-rendering",typeOf:"typeof",underlinePosition:"underline-position",underlineThickness:"underline-thickness",unicodeBidi:"unicode-bidi",unicodeRange:"unicode-range",unitsPerEm:"units-per-em",vAlphabetic:"v-alphabetic",vHanging:"v-hanging",vIdeographic:"v-ideographic",vMathematical:"v-mathematical",vectorEffect:"vector-effect",vertAdvY:"vert-adv-y",vertOriginX:"vert-origin-x",vertOriginY:"vert-origin-y",wordSpacing:"word-spacing",writingMode:"writing-mode",xHeight:"x-height",playbackOrder:"playbackorder",timelineBegin:"timelinebegin"},transform:i,properties:{about:l,accentHeight:s,accumulate:null,additive:null,alignmentBaseline:null,alphabetic:s,amplitude:s,arabicForm:null,ascent:s,attributeName:null,attributeType:null,azimuth:s,bandwidth:null,baselineShift:null,baseFrequency:null,baseProfile:null,bbox:null,begin:null,bias:s,by:null,calcMode:null,capHeight:s,className:u,clip:null,clipPath:null,clipPathUnits:null,clipRule:null,color:null,colorInterpolation:null,colorInterpolationFilters:null,colorProfile:null,colorRendering:null,content:null,contentScriptType:null,contentStyleType:null,crossOrigin:null,cursor:null,cx:null,cy:null,d:null,dataType:null,defaultAction:null,descent:s,diffuseConstant:s,direction:null,display:null,dur:null,divisor:s,dominantBaseline:null,download:a,dx:null,dy:null,edgeMode:null,editable:null,elevation:s,enableBackground:null,end:null,event:null,exponent:s,externalResourcesRequired:null,fill:null,fillOpacity:s,fillRule:null,filter:null,filterRes:null,filterUnits:null,floodColor:null,floodOpacity:null,focusable:null,focusHighlight:null,fontFamily:null,fontSize:null,fontSizeAdjust:null,fontStretch:null,fontStyle:null,fontVariant:null,fontWeight:null,format:null,fr:null,from:null,fx:null,fy:null,g1:c,g2:c,glyphName:c,glyphOrientationHorizontal:null,glyphOrientationVertical:null,glyphRef:null,gradientTransform:null,gradientUnits:null,handler:null,hanging:s,hatchContentUnits:null,hatchUnits:null,height:null,href:null,hrefLang:null,horizAdvX:s,horizOriginX:s,horizOriginY:s,id:null,ideographic:s,imageRendering:null,initialVisibility:null,in:null,in2:null,intercept:s,k:s,k1:s,k2:s,k3:s,k4:s,kernelMatrix:l,kernelUnitLength:null,keyPoints:null,keySplines:null,keyTimes:null,kerning:null,lang:null,lengthAdjust:null,letterSpacing:null,lightingColor:null,limitingConeAngle:s,local:null,markerEnd:null,markerMid:null,markerStart:null,markerHeight:null,markerUnits:null,markerWidth:null,mask:null,maskContentUnits:null,maskUnits:null,mathematical:null,max:null,media:null,mediaCharacterEncoding:null,mediaContentEncodings:null,mediaSize:s,mediaTime:null,method:null,min:null,mode:null,name:null,navDown:null,navDownLeft:null,navDownRight:null,navLeft:null,navNext:null,navPrev:null,navRight:null,navUp:null,navUpLeft:null,navUpRight:null,numOctaves:null,observer:null,offset:null,onAbort:null,onActivate:null,onAfterPrint:null,onBeforePrint:null,onBegin:null,onCancel:null,onCanPlay:null,onCanPlayThrough:null,onChange:null,onClick:null,onClose:null,onCopy:null,onCueChange:null,onCut:null,onDblClick:null,onDrag:null,onDragEnd:null,onDragEnter:null,onDragExit:null,onDragLeave:null,onDragOver:null,onDragStart:null,onDrop:null,onDurationChange:null,onEmptied:null,onEnd:null,onEnded:null,onError:null,onFocus:null,onFocusIn:null,onFocusOut:null,onHashChange:null,onInput:null,onInvalid:null,onKeyDown:null,onKeyPress:null,onKeyUp:null,onLoad:null,onLoadedData:null,onLoadedMetadata:null,onLoadStart:null,onMessage:null,onMouseDown:null,onMouseEnter:null,onMouseLeave:null,onMouseMove:null,onMouseOut:null,onMouseOver:null,onMouseUp:null,onMouseWheel:null,onOffline:null,onOnline:null,onPageHide:null,onPageShow:null,onPaste:null,onPause:null,onPlay:null,onPlaying:null,onPopState:null,onProgress:null,onRateChange:null,onRepeat:null,onReset:null,onResize:null,onScroll:null,onSeeked:null,onSeeking:null,onSelect:null,onShow:null,onStalled:null,onStorage:null,onSubmit:null,onSuspend:null,onTimeUpdate:null,onToggle:null,onUnload:null,onVolumeChange:null,onWaiting:null,onZoom:null,opacity:null,operator:null,order:null,orient:null,orientation:null,origin:null,overflow:null,overlay:null,overlinePosition:s,overlineThickness:s,paintOrder:null,panose1:null,path:null,pathLength:s,patternContentUnits:null,patternTransform:null,patternUnits:null,phase:null,ping:u,pitch:null,playbackOrder:null,pointerEvents:null,points:null,pointsAtX:s,pointsAtY:s,pointsAtZ:s,preserveAlpha:null,preserveAspectRatio:null,primitiveUnits:null,propagate:null,property:l,r:null,radius:null,referrerPolicy:null,refX:null,refY:null,rel:l,rev:l,renderingIntent:null,repeatCount:null,repeatDur:null,requiredExtensions:l,requiredFeatures:l,requiredFonts:l,requiredFormats:l,resource:null,restart:null,result:null,rotate:null,rx:null,ry:null,scale:null,seed:null,shapeRendering:null,side:null,slope:null,snapshotTime:null,specularConstant:s,specularExponent:s,spreadMethod:null,spacing:null,startOffset:null,stdDeviation:null,stemh:null,stemv:null,stitchTiles:null,stopColor:null,stopOpacity:null,strikethroughPosition:s,strikethroughThickness:s,string:null,stroke:null,strokeDashArray:l,strokeDashOffset:null,strokeLineCap:null,strokeLineJoin:null,strokeMiterLimit:s,strokeOpacity:s,strokeWidth:null,style:null,surfaceScale:s,syncBehavior:null,syncBehaviorDefault:null,syncMaster:null,syncTolerance:null,syncToleranceDefault:null,systemLanguage:l,tabIndex:s,tableValues:null,target:null,targetX:s,targetY:s,textAnchor:null,textDecoration:null,textRendering:null,textLength:null,timelineBegin:null,title:null,transformBehavior:null,type:null,typeOf:l,to:null,transform:null,u1:null,u2:null,underlinePosition:s,underlineThickness:s,unicode:null,unicodeBidi:null,unicodeRange:null,unitsPerEm:s,values:null,vAlphabetic:s,vMathematical:s,vectorEffect:null,vHanging:s,vIdeographic:s,version:null,vertAdvY:s,vertOriginX:s,vertOriginY:s,viewBox:null,viewTarget:null,visibility:null,width:null,widths:null,wordSpacing:null,writingMode:null,x:null,x1:null,x2:null,xChannelSelector:null,xHeight:s,y:null,y1:null,y2:null,yChannelSelector:null,z:null,zoomAndPan:null}})},10855:(e,t,n)=>{"use strict";var o=n(28740);e.exports=function(e,t){return o(e,t.toLowerCase())}},28740:e=>{"use strict";e.exports=function(e,t){return t in e?e[t]:t}},17596:(e,t,n)=>{"use strict";var o=n(66632),r=n(99607),i=n(98805);e.exports=function(e){var t,n,a=e.space,s=e.mustUseProperty||[],u=e.attributes||{},c=e.properties,l=e.transform,d={},h={};for(t in c)n=new i(t,l(u,t),c[t],a),-1!==s.indexOf(t)&&(n.mustUseProperty=!0),d[t]=n,h[o(t)]=t,h[o(n.attribute)]=t;return new r(d,h,a)}},98805:(e,t,n)=>{"use strict";var o=n(89750),r=n(17e3);e.exports=s,s.prototype=new o,s.prototype.defined=!0;var i=["boolean","booleanish","overloadedBoolean","number","commaSeparated","spaceSeparated","commaOrSpaceSeparated"],a=i.length;function s(e,t,n,s){var c,l=-1;for(u(this,"space",s),o.call(this,e,t);++l{"use strict";e.exports=n;var t=n.prototype;function n(e,t){this.property=e,this.attribute=t}t.space=null,t.attribute=null,t.property=null,t.boolean=!1,t.booleanish=!1,t.overloadedBoolean=!1,t.number=!1,t.commaSeparated=!1,t.spaceSeparated=!1,t.commaOrSpaceSeparated=!1,t.mustUseProperty=!1,t.defined=!1},19940:(e,t,n)=>{"use strict";var o=n(13351),r=n(99607);e.exports=function(e){for(var t,n,i=e.length,a=[],s=[],u=-1;++u{"use strict";e.exports=n;var t=n.prototype;function n(e,t,n){this.property=e,this.normal=t,n&&(this.space=n)}t.space=null,t.normal={},t.property={}},17e3:(e,t)=>{"use strict";var n=0;function o(){return Math.pow(2,++n)}t.boolean=o(),t.booleanish=o(),t.overloadedBoolean=o(),t.number=o(),t.spaceSeparated=o(),t.commaSeparated=o(),t.commaOrSpaceSeparated=o()},8289:(e,t,n)=>{"use strict";var o=n(17596);e.exports=o({space:"xlink",transform:function(e,t){return"xlink:"+t.slice(5).toLowerCase()},properties:{xLinkActuate:null,xLinkArcRole:null,xLinkHref:null,xLinkRole:null,xLinkShow:null,xLinkTitle:null,xLinkType:null}})},5812:(e,t,n)=>{"use strict";var o=n(17596);e.exports=o({space:"xml",transform:function(e,t){return"xml:"+t.slice(3).toLowerCase()},properties:{xmlLang:null,xmlBase:null,xmlSpace:null}})},94397:(e,t,n)=>{"use strict";var o=n(17596),r=n(10855);e.exports=o({space:"xmlns",attributes:{xmlnsxlink:"xmlns:xlink"},transform:r,properties:{xmlns:null,xmlnsXLink:null}})},13351:e=>{e.exports=function(){for(var e={},n=0;n{"use strict";e.exports=function(e){return e.toLowerCase()}},11218:(e,t,n)=>{"use strict";var o=n(19940),r=n(8289),i=n(5812),a=n(94397),s=n(67716),u=n(97421);e.exports=o([i,r,a,s,u])},90233:function(e){var t;t=function(){var e="function"==typeof Object.defineProperty?function(e,t,n){return Object.defineProperty(e,t,n),e}:function(e,t,n){return e[t]=n.value,e};return function(t,n,o,r){var i;if(r=function(e,t){var n="object"==typeof t,o=!n&&"string"==typeof t,r=function(e){return n?!!t[e]:!!o&&t.indexOf(e[0])>-1};return{enumerable:r("enumerable"),configurable:r("configurable"),writable:r("writable"),value:e}}(o,r),"object"==typeof n){for(i in n)Object.hasOwnProperty.call(n,i)&&(r.value=n[i],e(t,i,r));return t}return e(t,n,r)}},e.exports?e.exports=t():this.prr=t()},7900:(e,t,n)=>{t.publicEncrypt=n(16559),t.privateDecrypt=n(26138),t.privateEncrypt=function(e,n){return t.publicEncrypt(e,n,!0)},t.publicDecrypt=function(e,n){return t.privateDecrypt(e,n,!0)}},99199:(e,t,n)=>{var o=n(23482),r=n(89509).Buffer;function i(e){var t=r.allocUnsafe(4);return t.writeUInt32BE(e,0),t}e.exports=function(e,t){for(var n,a=r.alloc(0),s=0;a.length=65&&n<=70?n-55:n>=97&&n<=102?n-87:n-48&15}function u(e,t,n){var o=s(e,n);return n-1>=t&&(o|=s(e,n-1)<<4),o}function c(e,t,n,o){for(var r=0,i=Math.min(e.length,n),a=t;a=49?s-49+10:s>=17?s-17+10:s}return r}i.isBN=function(e){return e instanceof i||null!==e&&"object"==typeof e&&e.constructor.wordSize===i.wordSize&&Array.isArray(e.words)},i.max=function(e,t){return e.cmp(t)>0?e:t},i.min=function(e,t){return e.cmp(t)<0?e:t},i.prototype._init=function(e,t,n){if("number"==typeof e)return this._initNumber(e,t,n);if("object"==typeof e)return this._initArray(e,t,n);"hex"===t&&(t=16),o(t===(0|t)&&t>=2&&t<=36);var r=0;"-"===(e=e.toString().replace(/\s+/g,""))[0]&&(r++,this.negative=1),r=0;r-=3)a=e[r]|e[r-1]<<8|e[r-2]<<16,this.words[i]|=a<>>26-s&67108863,(s+=24)>=26&&(s-=26,i++);else if("le"===n)for(r=0,i=0;r>>26-s&67108863,(s+=24)>=26&&(s-=26,i++);return this.strip()},i.prototype._parseHex=function(e,t,n){this.length=Math.ceil((e.length-t)/6),this.words=new Array(this.length);for(var o=0;o=t;o-=2)r=u(e,t,o)<=18?(i-=18,a+=1,this.words[a]|=r>>>26):i+=8;else for(o=(e.length-t)%2==0?t+1:t;o=18?(i-=18,a+=1,this.words[a]|=r>>>26):i+=8;this.strip()},i.prototype._parseBase=function(e,t,n){this.words=[0],this.length=1;for(var o=0,r=1;r<=67108863;r*=t)o++;o--,r=r/t|0;for(var i=e.length-n,a=i%o,s=Math.min(i,i-a)+n,u=0,l=n;l1&&0===this.words[this.length-1];)this.length--;return this._normSign()},i.prototype._normSign=function(){return 1===this.length&&0===this.words[0]&&(this.negative=0),this},i.prototype.inspect=function(){return(this.red?""};var l=["","0","00","000","0000","00000","000000","0000000","00000000","000000000","0000000000","00000000000","000000000000","0000000000000","00000000000000","000000000000000","0000000000000000","00000000000000000","000000000000000000","0000000000000000000","00000000000000000000","000000000000000000000","0000000000000000000000","00000000000000000000000","000000000000000000000000","0000000000000000000000000"],d=[0,0,25,16,12,11,10,9,8,8,7,7,7,7,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5],h=[0,0,33554432,43046721,16777216,48828125,60466176,40353607,16777216,43046721,1e7,19487171,35831808,62748517,7529536,11390625,16777216,24137569,34012224,47045881,64e6,4084101,5153632,6436343,7962624,9765625,11881376,14348907,17210368,20511149,243e5,28629151,33554432,39135393,45435424,52521875,60466176];function p(e,t,n){n.negative=t.negative^e.negative;var o=e.length+t.length|0;n.length=o,o=o-1|0;var r=0|e.words[0],i=0|t.words[0],a=r*i,s=67108863&a,u=a/67108864|0;n.words[0]=s;for(var c=1;c>>26,d=67108863&u,h=Math.min(c,t.length-1),p=Math.max(0,c-e.length+1);p<=h;p++){var f=c-p|0;l+=(a=(r=0|e.words[f])*(i=0|t.words[p])+d)/67108864|0,d=67108863&a}n.words[c]=0|d,u=0|l}return 0!==u?n.words[c]=0|u:n.length--,n.strip()}i.prototype.toString=function(e,t){var n;if(t=0|t||1,16===(e=e||10)||"hex"===e){n="";for(var r=0,i=0,a=0;a>>24-r&16777215)||a!==this.length-1?l[6-u.length]+u+n:u+n,(r+=2)>=26&&(r-=26,a--)}for(0!==i&&(n=i.toString(16)+n);n.length%t!=0;)n="0"+n;return 0!==this.negative&&(n="-"+n),n}if(e===(0|e)&&e>=2&&e<=36){var c=d[e],p=h[e];n="";var f=this.clone();for(f.negative=0;!f.isZero();){var g=f.modn(p).toString(e);n=(f=f.idivn(p)).isZero()?g+n:l[c-g.length]+g+n}for(this.isZero()&&(n="0"+n);n.length%t!=0;)n="0"+n;return 0!==this.negative&&(n="-"+n),n}o(!1,"Base should be between 2 and 36")},i.prototype.toNumber=function(){var e=this.words[0];return 2===this.length?e+=67108864*this.words[1]:3===this.length&&1===this.words[2]?e+=4503599627370496+67108864*this.words[1]:this.length>2&&o(!1,"Number can only safely store up to 53 bits"),0!==this.negative?-e:e},i.prototype.toJSON=function(){return this.toString(16)},i.prototype.toBuffer=function(e,t){return o(void 0!==a),this.toArrayLike(a,e,t)},i.prototype.toArray=function(e,t){return this.toArrayLike(Array,e,t)},i.prototype.toArrayLike=function(e,t,n){var r=this.byteLength(),i=n||Math.max(1,r);o(r<=i,"byte array longer than desired length"),o(i>0,"Requested array length <= 0"),this.strip();var a,s,u="le"===t,c=new e(i),l=this.clone();if(u){for(s=0;!l.isZero();s++)a=l.andln(255),l.iushrn(8),c[s]=a;for(;s=4096&&(n+=13,t>>>=13),t>=64&&(n+=7,t>>>=7),t>=8&&(n+=4,t>>>=4),t>=2&&(n+=2,t>>>=2),n+t},i.prototype._zeroBits=function(e){if(0===e)return 26;var t=e,n=0;return 0==(8191&t)&&(n+=13,t>>>=13),0==(127&t)&&(n+=7,t>>>=7),0==(15&t)&&(n+=4,t>>>=4),0==(3&t)&&(n+=2,t>>>=2),0==(1&t)&&n++,n},i.prototype.bitLength=function(){var e=this.words[this.length-1],t=this._countBits(e);return 26*(this.length-1)+t},i.prototype.zeroBits=function(){if(this.isZero())return 0;for(var e=0,t=0;te.length?this.clone().ior(e):e.clone().ior(this)},i.prototype.uor=function(e){return this.length>e.length?this.clone().iuor(e):e.clone().iuor(this)},i.prototype.iuand=function(e){var t;t=this.length>e.length?e:this;for(var n=0;ne.length?this.clone().iand(e):e.clone().iand(this)},i.prototype.uand=function(e){return this.length>e.length?this.clone().iuand(e):e.clone().iuand(this)},i.prototype.iuxor=function(e){var t,n;this.length>e.length?(t=this,n=e):(t=e,n=this);for(var o=0;oe.length?this.clone().ixor(e):e.clone().ixor(this)},i.prototype.uxor=function(e){return this.length>e.length?this.clone().iuxor(e):e.clone().iuxor(this)},i.prototype.inotn=function(e){o("number"==typeof e&&e>=0);var t=0|Math.ceil(e/26),n=e%26;this._expand(t),n>0&&t--;for(var r=0;r0&&(this.words[r]=~this.words[r]&67108863>>26-n),this.strip()},i.prototype.notn=function(e){return this.clone().inotn(e)},i.prototype.setn=function(e,t){o("number"==typeof e&&e>=0);var n=e/26|0,r=e%26;return this._expand(n+1),this.words[n]=t?this.words[n]|1<e.length?(n=this,o=e):(n=e,o=this);for(var r=0,i=0;i>>26;for(;0!==r&&i>>26;if(this.length=n.length,0!==r)this.words[this.length]=r,this.length++;else if(n!==this)for(;ie.length?this.clone().iadd(e):e.clone().iadd(this)},i.prototype.isub=function(e){if(0!==e.negative){e.negative=0;var t=this.iadd(e);return e.negative=1,t._normSign()}if(0!==this.negative)return this.negative=0,this.iadd(e),this.negative=1,this._normSign();var n,o,r=this.cmp(e);if(0===r)return this.negative=0,this.length=1,this.words[0]=0,this;r>0?(n=this,o=e):(n=e,o=this);for(var i=0,a=0;a>26,this.words[a]=67108863&t;for(;0!==i&&a>26,this.words[a]=67108863&t;if(0===i&&a>>13,p=0|a[1],f=8191&p,g=p>>>13,m=0|a[2],_=8191&m,F=m>>>13,y=0|a[3],b=8191&y,v=y>>>13,w=0|a[4],E=8191&w,k=w>>>13,D=0|a[5],S=8191&D,x=D>>>13,C=0|a[6],A=8191&C,T=C>>>13,R=0|a[7],I=8191&R,M=R>>>13,O=0|a[8],B=8191&O,N=O>>>13,L=0|a[9],P=8191&L,U=L>>>13,j=0|s[0],q=8191&j,z=j>>>13,K=0|s[1],G=8191&K,$=K>>>13,H=0|s[2],V=8191&H,W=H>>>13,Y=0|s[3],Z=8191&Y,X=Y>>>13,J=0|s[4],Q=8191&J,ee=J>>>13,te=0|s[5],ne=8191&te,oe=te>>>13,re=0|s[6],ie=8191&re,ae=re>>>13,se=0|s[7],ue=8191&se,ce=se>>>13,le=0|s[8],de=8191&le,he=le>>>13,pe=0|s[9],fe=8191&pe,ge=pe>>>13;n.negative=e.negative^t.negative,n.length=19;var me=(c+(o=Math.imul(d,q))|0)+((8191&(r=(r=Math.imul(d,z))+Math.imul(h,q)|0))<<13)|0;c=((i=Math.imul(h,z))+(r>>>13)|0)+(me>>>26)|0,me&=67108863,o=Math.imul(f,q),r=(r=Math.imul(f,z))+Math.imul(g,q)|0,i=Math.imul(g,z);var _e=(c+(o=o+Math.imul(d,G)|0)|0)+((8191&(r=(r=r+Math.imul(d,$)|0)+Math.imul(h,G)|0))<<13)|0;c=((i=i+Math.imul(h,$)|0)+(r>>>13)|0)+(_e>>>26)|0,_e&=67108863,o=Math.imul(_,q),r=(r=Math.imul(_,z))+Math.imul(F,q)|0,i=Math.imul(F,z),o=o+Math.imul(f,G)|0,r=(r=r+Math.imul(f,$)|0)+Math.imul(g,G)|0,i=i+Math.imul(g,$)|0;var Fe=(c+(o=o+Math.imul(d,V)|0)|0)+((8191&(r=(r=r+Math.imul(d,W)|0)+Math.imul(h,V)|0))<<13)|0;c=((i=i+Math.imul(h,W)|0)+(r>>>13)|0)+(Fe>>>26)|0,Fe&=67108863,o=Math.imul(b,q),r=(r=Math.imul(b,z))+Math.imul(v,q)|0,i=Math.imul(v,z),o=o+Math.imul(_,G)|0,r=(r=r+Math.imul(_,$)|0)+Math.imul(F,G)|0,i=i+Math.imul(F,$)|0,o=o+Math.imul(f,V)|0,r=(r=r+Math.imul(f,W)|0)+Math.imul(g,V)|0,i=i+Math.imul(g,W)|0;var ye=(c+(o=o+Math.imul(d,Z)|0)|0)+((8191&(r=(r=r+Math.imul(d,X)|0)+Math.imul(h,Z)|0))<<13)|0;c=((i=i+Math.imul(h,X)|0)+(r>>>13)|0)+(ye>>>26)|0,ye&=67108863,o=Math.imul(E,q),r=(r=Math.imul(E,z))+Math.imul(k,q)|0,i=Math.imul(k,z),o=o+Math.imul(b,G)|0,r=(r=r+Math.imul(b,$)|0)+Math.imul(v,G)|0,i=i+Math.imul(v,$)|0,o=o+Math.imul(_,V)|0,r=(r=r+Math.imul(_,W)|0)+Math.imul(F,V)|0,i=i+Math.imul(F,W)|0,o=o+Math.imul(f,Z)|0,r=(r=r+Math.imul(f,X)|0)+Math.imul(g,Z)|0,i=i+Math.imul(g,X)|0;var be=(c+(o=o+Math.imul(d,Q)|0)|0)+((8191&(r=(r=r+Math.imul(d,ee)|0)+Math.imul(h,Q)|0))<<13)|0;c=((i=i+Math.imul(h,ee)|0)+(r>>>13)|0)+(be>>>26)|0,be&=67108863,o=Math.imul(S,q),r=(r=Math.imul(S,z))+Math.imul(x,q)|0,i=Math.imul(x,z),o=o+Math.imul(E,G)|0,r=(r=r+Math.imul(E,$)|0)+Math.imul(k,G)|0,i=i+Math.imul(k,$)|0,o=o+Math.imul(b,V)|0,r=(r=r+Math.imul(b,W)|0)+Math.imul(v,V)|0,i=i+Math.imul(v,W)|0,o=o+Math.imul(_,Z)|0,r=(r=r+Math.imul(_,X)|0)+Math.imul(F,Z)|0,i=i+Math.imul(F,X)|0,o=o+Math.imul(f,Q)|0,r=(r=r+Math.imul(f,ee)|0)+Math.imul(g,Q)|0,i=i+Math.imul(g,ee)|0;var ve=(c+(o=o+Math.imul(d,ne)|0)|0)+((8191&(r=(r=r+Math.imul(d,oe)|0)+Math.imul(h,ne)|0))<<13)|0;c=((i=i+Math.imul(h,oe)|0)+(r>>>13)|0)+(ve>>>26)|0,ve&=67108863,o=Math.imul(A,q),r=(r=Math.imul(A,z))+Math.imul(T,q)|0,i=Math.imul(T,z),o=o+Math.imul(S,G)|0,r=(r=r+Math.imul(S,$)|0)+Math.imul(x,G)|0,i=i+Math.imul(x,$)|0,o=o+Math.imul(E,V)|0,r=(r=r+Math.imul(E,W)|0)+Math.imul(k,V)|0,i=i+Math.imul(k,W)|0,o=o+Math.imul(b,Z)|0,r=(r=r+Math.imul(b,X)|0)+Math.imul(v,Z)|0,i=i+Math.imul(v,X)|0,o=o+Math.imul(_,Q)|0,r=(r=r+Math.imul(_,ee)|0)+Math.imul(F,Q)|0,i=i+Math.imul(F,ee)|0,o=o+Math.imul(f,ne)|0,r=(r=r+Math.imul(f,oe)|0)+Math.imul(g,ne)|0,i=i+Math.imul(g,oe)|0;var we=(c+(o=o+Math.imul(d,ie)|0)|0)+((8191&(r=(r=r+Math.imul(d,ae)|0)+Math.imul(h,ie)|0))<<13)|0;c=((i=i+Math.imul(h,ae)|0)+(r>>>13)|0)+(we>>>26)|0,we&=67108863,o=Math.imul(I,q),r=(r=Math.imul(I,z))+Math.imul(M,q)|0,i=Math.imul(M,z),o=o+Math.imul(A,G)|0,r=(r=r+Math.imul(A,$)|0)+Math.imul(T,G)|0,i=i+Math.imul(T,$)|0,o=o+Math.imul(S,V)|0,r=(r=r+Math.imul(S,W)|0)+Math.imul(x,V)|0,i=i+Math.imul(x,W)|0,o=o+Math.imul(E,Z)|0,r=(r=r+Math.imul(E,X)|0)+Math.imul(k,Z)|0,i=i+Math.imul(k,X)|0,o=o+Math.imul(b,Q)|0,r=(r=r+Math.imul(b,ee)|0)+Math.imul(v,Q)|0,i=i+Math.imul(v,ee)|0,o=o+Math.imul(_,ne)|0,r=(r=r+Math.imul(_,oe)|0)+Math.imul(F,ne)|0,i=i+Math.imul(F,oe)|0,o=o+Math.imul(f,ie)|0,r=(r=r+Math.imul(f,ae)|0)+Math.imul(g,ie)|0,i=i+Math.imul(g,ae)|0;var Ee=(c+(o=o+Math.imul(d,ue)|0)|0)+((8191&(r=(r=r+Math.imul(d,ce)|0)+Math.imul(h,ue)|0))<<13)|0;c=((i=i+Math.imul(h,ce)|0)+(r>>>13)|0)+(Ee>>>26)|0,Ee&=67108863,o=Math.imul(B,q),r=(r=Math.imul(B,z))+Math.imul(N,q)|0,i=Math.imul(N,z),o=o+Math.imul(I,G)|0,r=(r=r+Math.imul(I,$)|0)+Math.imul(M,G)|0,i=i+Math.imul(M,$)|0,o=o+Math.imul(A,V)|0,r=(r=r+Math.imul(A,W)|0)+Math.imul(T,V)|0,i=i+Math.imul(T,W)|0,o=o+Math.imul(S,Z)|0,r=(r=r+Math.imul(S,X)|0)+Math.imul(x,Z)|0,i=i+Math.imul(x,X)|0,o=o+Math.imul(E,Q)|0,r=(r=r+Math.imul(E,ee)|0)+Math.imul(k,Q)|0,i=i+Math.imul(k,ee)|0,o=o+Math.imul(b,ne)|0,r=(r=r+Math.imul(b,oe)|0)+Math.imul(v,ne)|0,i=i+Math.imul(v,oe)|0,o=o+Math.imul(_,ie)|0,r=(r=r+Math.imul(_,ae)|0)+Math.imul(F,ie)|0,i=i+Math.imul(F,ae)|0,o=o+Math.imul(f,ue)|0,r=(r=r+Math.imul(f,ce)|0)+Math.imul(g,ue)|0,i=i+Math.imul(g,ce)|0;var ke=(c+(o=o+Math.imul(d,de)|0)|0)+((8191&(r=(r=r+Math.imul(d,he)|0)+Math.imul(h,de)|0))<<13)|0;c=((i=i+Math.imul(h,he)|0)+(r>>>13)|0)+(ke>>>26)|0,ke&=67108863,o=Math.imul(P,q),r=(r=Math.imul(P,z))+Math.imul(U,q)|0,i=Math.imul(U,z),o=o+Math.imul(B,G)|0,r=(r=r+Math.imul(B,$)|0)+Math.imul(N,G)|0,i=i+Math.imul(N,$)|0,o=o+Math.imul(I,V)|0,r=(r=r+Math.imul(I,W)|0)+Math.imul(M,V)|0,i=i+Math.imul(M,W)|0,o=o+Math.imul(A,Z)|0,r=(r=r+Math.imul(A,X)|0)+Math.imul(T,Z)|0,i=i+Math.imul(T,X)|0,o=o+Math.imul(S,Q)|0,r=(r=r+Math.imul(S,ee)|0)+Math.imul(x,Q)|0,i=i+Math.imul(x,ee)|0,o=o+Math.imul(E,ne)|0,r=(r=r+Math.imul(E,oe)|0)+Math.imul(k,ne)|0,i=i+Math.imul(k,oe)|0,o=o+Math.imul(b,ie)|0,r=(r=r+Math.imul(b,ae)|0)+Math.imul(v,ie)|0,i=i+Math.imul(v,ae)|0,o=o+Math.imul(_,ue)|0,r=(r=r+Math.imul(_,ce)|0)+Math.imul(F,ue)|0,i=i+Math.imul(F,ce)|0,o=o+Math.imul(f,de)|0,r=(r=r+Math.imul(f,he)|0)+Math.imul(g,de)|0,i=i+Math.imul(g,he)|0;var De=(c+(o=o+Math.imul(d,fe)|0)|0)+((8191&(r=(r=r+Math.imul(d,ge)|0)+Math.imul(h,fe)|0))<<13)|0;c=((i=i+Math.imul(h,ge)|0)+(r>>>13)|0)+(De>>>26)|0,De&=67108863,o=Math.imul(P,G),r=(r=Math.imul(P,$))+Math.imul(U,G)|0,i=Math.imul(U,$),o=o+Math.imul(B,V)|0,r=(r=r+Math.imul(B,W)|0)+Math.imul(N,V)|0,i=i+Math.imul(N,W)|0,o=o+Math.imul(I,Z)|0,r=(r=r+Math.imul(I,X)|0)+Math.imul(M,Z)|0,i=i+Math.imul(M,X)|0,o=o+Math.imul(A,Q)|0,r=(r=r+Math.imul(A,ee)|0)+Math.imul(T,Q)|0,i=i+Math.imul(T,ee)|0,o=o+Math.imul(S,ne)|0,r=(r=r+Math.imul(S,oe)|0)+Math.imul(x,ne)|0,i=i+Math.imul(x,oe)|0,o=o+Math.imul(E,ie)|0,r=(r=r+Math.imul(E,ae)|0)+Math.imul(k,ie)|0,i=i+Math.imul(k,ae)|0,o=o+Math.imul(b,ue)|0,r=(r=r+Math.imul(b,ce)|0)+Math.imul(v,ue)|0,i=i+Math.imul(v,ce)|0,o=o+Math.imul(_,de)|0,r=(r=r+Math.imul(_,he)|0)+Math.imul(F,de)|0,i=i+Math.imul(F,he)|0;var Se=(c+(o=o+Math.imul(f,fe)|0)|0)+((8191&(r=(r=r+Math.imul(f,ge)|0)+Math.imul(g,fe)|0))<<13)|0;c=((i=i+Math.imul(g,ge)|0)+(r>>>13)|0)+(Se>>>26)|0,Se&=67108863,o=Math.imul(P,V),r=(r=Math.imul(P,W))+Math.imul(U,V)|0,i=Math.imul(U,W),o=o+Math.imul(B,Z)|0,r=(r=r+Math.imul(B,X)|0)+Math.imul(N,Z)|0,i=i+Math.imul(N,X)|0,o=o+Math.imul(I,Q)|0,r=(r=r+Math.imul(I,ee)|0)+Math.imul(M,Q)|0,i=i+Math.imul(M,ee)|0,o=o+Math.imul(A,ne)|0,r=(r=r+Math.imul(A,oe)|0)+Math.imul(T,ne)|0,i=i+Math.imul(T,oe)|0,o=o+Math.imul(S,ie)|0,r=(r=r+Math.imul(S,ae)|0)+Math.imul(x,ie)|0,i=i+Math.imul(x,ae)|0,o=o+Math.imul(E,ue)|0,r=(r=r+Math.imul(E,ce)|0)+Math.imul(k,ue)|0,i=i+Math.imul(k,ce)|0,o=o+Math.imul(b,de)|0,r=(r=r+Math.imul(b,he)|0)+Math.imul(v,de)|0,i=i+Math.imul(v,he)|0;var xe=(c+(o=o+Math.imul(_,fe)|0)|0)+((8191&(r=(r=r+Math.imul(_,ge)|0)+Math.imul(F,fe)|0))<<13)|0;c=((i=i+Math.imul(F,ge)|0)+(r>>>13)|0)+(xe>>>26)|0,xe&=67108863,o=Math.imul(P,Z),r=(r=Math.imul(P,X))+Math.imul(U,Z)|0,i=Math.imul(U,X),o=o+Math.imul(B,Q)|0,r=(r=r+Math.imul(B,ee)|0)+Math.imul(N,Q)|0,i=i+Math.imul(N,ee)|0,o=o+Math.imul(I,ne)|0,r=(r=r+Math.imul(I,oe)|0)+Math.imul(M,ne)|0,i=i+Math.imul(M,oe)|0,o=o+Math.imul(A,ie)|0,r=(r=r+Math.imul(A,ae)|0)+Math.imul(T,ie)|0,i=i+Math.imul(T,ae)|0,o=o+Math.imul(S,ue)|0,r=(r=r+Math.imul(S,ce)|0)+Math.imul(x,ue)|0,i=i+Math.imul(x,ce)|0,o=o+Math.imul(E,de)|0,r=(r=r+Math.imul(E,he)|0)+Math.imul(k,de)|0,i=i+Math.imul(k,he)|0;var Ce=(c+(o=o+Math.imul(b,fe)|0)|0)+((8191&(r=(r=r+Math.imul(b,ge)|0)+Math.imul(v,fe)|0))<<13)|0;c=((i=i+Math.imul(v,ge)|0)+(r>>>13)|0)+(Ce>>>26)|0,Ce&=67108863,o=Math.imul(P,Q),r=(r=Math.imul(P,ee))+Math.imul(U,Q)|0,i=Math.imul(U,ee),o=o+Math.imul(B,ne)|0,r=(r=r+Math.imul(B,oe)|0)+Math.imul(N,ne)|0,i=i+Math.imul(N,oe)|0,o=o+Math.imul(I,ie)|0,r=(r=r+Math.imul(I,ae)|0)+Math.imul(M,ie)|0,i=i+Math.imul(M,ae)|0,o=o+Math.imul(A,ue)|0,r=(r=r+Math.imul(A,ce)|0)+Math.imul(T,ue)|0,i=i+Math.imul(T,ce)|0,o=o+Math.imul(S,de)|0,r=(r=r+Math.imul(S,he)|0)+Math.imul(x,de)|0,i=i+Math.imul(x,he)|0;var Ae=(c+(o=o+Math.imul(E,fe)|0)|0)+((8191&(r=(r=r+Math.imul(E,ge)|0)+Math.imul(k,fe)|0))<<13)|0;c=((i=i+Math.imul(k,ge)|0)+(r>>>13)|0)+(Ae>>>26)|0,Ae&=67108863,o=Math.imul(P,ne),r=(r=Math.imul(P,oe))+Math.imul(U,ne)|0,i=Math.imul(U,oe),o=o+Math.imul(B,ie)|0,r=(r=r+Math.imul(B,ae)|0)+Math.imul(N,ie)|0,i=i+Math.imul(N,ae)|0,o=o+Math.imul(I,ue)|0,r=(r=r+Math.imul(I,ce)|0)+Math.imul(M,ue)|0,i=i+Math.imul(M,ce)|0,o=o+Math.imul(A,de)|0,r=(r=r+Math.imul(A,he)|0)+Math.imul(T,de)|0,i=i+Math.imul(T,he)|0;var Te=(c+(o=o+Math.imul(S,fe)|0)|0)+((8191&(r=(r=r+Math.imul(S,ge)|0)+Math.imul(x,fe)|0))<<13)|0;c=((i=i+Math.imul(x,ge)|0)+(r>>>13)|0)+(Te>>>26)|0,Te&=67108863,o=Math.imul(P,ie),r=(r=Math.imul(P,ae))+Math.imul(U,ie)|0,i=Math.imul(U,ae),o=o+Math.imul(B,ue)|0,r=(r=r+Math.imul(B,ce)|0)+Math.imul(N,ue)|0,i=i+Math.imul(N,ce)|0,o=o+Math.imul(I,de)|0,r=(r=r+Math.imul(I,he)|0)+Math.imul(M,de)|0,i=i+Math.imul(M,he)|0;var Re=(c+(o=o+Math.imul(A,fe)|0)|0)+((8191&(r=(r=r+Math.imul(A,ge)|0)+Math.imul(T,fe)|0))<<13)|0;c=((i=i+Math.imul(T,ge)|0)+(r>>>13)|0)+(Re>>>26)|0,Re&=67108863,o=Math.imul(P,ue),r=(r=Math.imul(P,ce))+Math.imul(U,ue)|0,i=Math.imul(U,ce),o=o+Math.imul(B,de)|0,r=(r=r+Math.imul(B,he)|0)+Math.imul(N,de)|0,i=i+Math.imul(N,he)|0;var Ie=(c+(o=o+Math.imul(I,fe)|0)|0)+((8191&(r=(r=r+Math.imul(I,ge)|0)+Math.imul(M,fe)|0))<<13)|0;c=((i=i+Math.imul(M,ge)|0)+(r>>>13)|0)+(Ie>>>26)|0,Ie&=67108863,o=Math.imul(P,de),r=(r=Math.imul(P,he))+Math.imul(U,de)|0,i=Math.imul(U,he);var Me=(c+(o=o+Math.imul(B,fe)|0)|0)+((8191&(r=(r=r+Math.imul(B,ge)|0)+Math.imul(N,fe)|0))<<13)|0;c=((i=i+Math.imul(N,ge)|0)+(r>>>13)|0)+(Me>>>26)|0,Me&=67108863;var Oe=(c+(o=Math.imul(P,fe))|0)+((8191&(r=(r=Math.imul(P,ge))+Math.imul(U,fe)|0))<<13)|0;return c=((i=Math.imul(U,ge))+(r>>>13)|0)+(Oe>>>26)|0,Oe&=67108863,u[0]=me,u[1]=_e,u[2]=Fe,u[3]=ye,u[4]=be,u[5]=ve,u[6]=we,u[7]=Ee,u[8]=ke,u[9]=De,u[10]=Se,u[11]=xe,u[12]=Ce,u[13]=Ae,u[14]=Te,u[15]=Re,u[16]=Ie,u[17]=Me,u[18]=Oe,0!==c&&(u[19]=c,n.length++),n};function g(e,t,n){return(new m).mulp(e,t,n)}function m(e,t){this.x=e,this.y=t}Math.imul||(f=p),i.prototype.mulTo=function(e,t){var n=this.length+e.length;return 10===this.length&&10===e.length?f(this,e,t):n<63?p(this,e,t):n<1024?function(e,t,n){n.negative=t.negative^e.negative,n.length=e.length+t.length;for(var o=0,r=0,i=0;i>>26)|0)>>>26,a&=67108863}n.words[i]=s,o=a,a=r}return 0!==o?n.words[i]=o:n.length--,n.strip()}(this,e,t):g(this,e,t)},m.prototype.makeRBT=function(e){for(var t=new Array(e),n=i.prototype._countBits(e)-1,o=0;o>=1;return o},m.prototype.permute=function(e,t,n,o,r,i){for(var a=0;a>>=1)r++;return 1<>>=13,n[2*a+1]=8191&i,i>>>=13;for(a=2*t;a>=26,t+=r/67108864|0,t+=i>>>26,this.words[n]=67108863&i}return 0!==t&&(this.words[n]=t,this.length++),this},i.prototype.muln=function(e){return this.clone().imuln(e)},i.prototype.sqr=function(){return this.mul(this)},i.prototype.isqr=function(){return this.imul(this.clone())},i.prototype.pow=function(e){var t=function(e){for(var t=new Array(e.bitLength()),n=0;n>>r}return t}(e);if(0===t.length)return new i(1);for(var n=this,o=0;o=0);var t,n=e%26,r=(e-n)/26,i=67108863>>>26-n<<26-n;if(0!==n){var a=0;for(t=0;t>>26-n}a&&(this.words[t]=a,this.length++)}if(0!==r){for(t=this.length-1;t>=0;t--)this.words[t+r]=this.words[t];for(t=0;t=0),r=t?(t-t%26)/26:0;var i=e%26,a=Math.min((e-i)/26,this.length),s=67108863^67108863>>>i<a)for(this.length-=a,c=0;c=0&&(0!==l||c>=r);c--){var d=0|this.words[c];this.words[c]=l<<26-i|d>>>i,l=d&s}return u&&0!==l&&(u.words[u.length++]=l),0===this.length&&(this.words[0]=0,this.length=1),this.strip()},i.prototype.ishrn=function(e,t,n){return o(0===this.negative),this.iushrn(e,t,n)},i.prototype.shln=function(e){return this.clone().ishln(e)},i.prototype.ushln=function(e){return this.clone().iushln(e)},i.prototype.shrn=function(e){return this.clone().ishrn(e)},i.prototype.ushrn=function(e){return this.clone().iushrn(e)},i.prototype.testn=function(e){o("number"==typeof e&&e>=0);var t=e%26,n=(e-t)/26,r=1<=0);var t=e%26,n=(e-t)/26;if(o(0===this.negative,"imaskn works only with positive numbers"),this.length<=n)return this;if(0!==t&&n++,this.length=Math.min(n,this.length),0!==t){var r=67108863^67108863>>>t<=67108864;t++)this.words[t]-=67108864,t===this.length-1?this.words[t+1]=1:this.words[t+1]++;return this.length=Math.max(this.length,t+1),this},i.prototype.isubn=function(e){if(o("number"==typeof e),o(e<67108864),e<0)return this.iaddn(-e);if(0!==this.negative)return this.negative=0,this.iaddn(e),this.negative=1,this;if(this.words[0]-=e,1===this.length&&this.words[0]<0)this.words[0]=-this.words[0],this.negative=1;else for(var t=0;t>26)-(u/67108864|0),this.words[r+n]=67108863&i}for(;r>26,this.words[r+n]=67108863&i;if(0===s)return this.strip();for(o(-1===s),s=0,r=0;r>26,this.words[r]=67108863&i;return this.negative=1,this.strip()},i.prototype._wordDiv=function(e,t){var n=(this.length,e.length),o=this.clone(),r=e,a=0|r.words[r.length-1];0!=(n=26-this._countBits(a))&&(r=r.ushln(n),o.iushln(n),a=0|r.words[r.length-1]);var s,u=o.length-r.length;if("mod"!==t){(s=new i(null)).length=u+1,s.words=new Array(s.length);for(var c=0;c=0;d--){var h=67108864*(0|o.words[r.length+d])+(0|o.words[r.length+d-1]);for(h=Math.min(h/a|0,67108863),o._ishlnsubmul(r,h,d);0!==o.negative;)h--,o.negative=0,o._ishlnsubmul(r,1,d),o.isZero()||(o.negative^=1);s&&(s.words[d]=h)}return s&&s.strip(),o.strip(),"div"!==t&&0!==n&&o.iushrn(n),{div:s||null,mod:o}},i.prototype.divmod=function(e,t,n){return o(!e.isZero()),this.isZero()?{div:new i(0),mod:new i(0)}:0!==this.negative&&0===e.negative?(s=this.neg().divmod(e,t),"mod"!==t&&(r=s.div.neg()),"div"!==t&&(a=s.mod.neg(),n&&0!==a.negative&&a.iadd(e)),{div:r,mod:a}):0===this.negative&&0!==e.negative?(s=this.divmod(e.neg(),t),"mod"!==t&&(r=s.div.neg()),{div:r,mod:s.mod}):0!=(this.negative&e.negative)?(s=this.neg().divmod(e.neg(),t),"div"!==t&&(a=s.mod.neg(),n&&0!==a.negative&&a.isub(e)),{div:s.div,mod:a}):e.length>this.length||this.cmp(e)<0?{div:new i(0),mod:this}:1===e.length?"div"===t?{div:this.divn(e.words[0]),mod:null}:"mod"===t?{div:null,mod:new i(this.modn(e.words[0]))}:{div:this.divn(e.words[0]),mod:new i(this.modn(e.words[0]))}:this._wordDiv(e,t);var r,a,s},i.prototype.div=function(e){return this.divmod(e,"div",!1).div},i.prototype.mod=function(e){return this.divmod(e,"mod",!1).mod},i.prototype.umod=function(e){return this.divmod(e,"mod",!0).mod},i.prototype.divRound=function(e){var t=this.divmod(e);if(t.mod.isZero())return t.div;var n=0!==t.div.negative?t.mod.isub(e):t.mod,o=e.ushrn(1),r=e.andln(1),i=n.cmp(o);return i<0||1===r&&0===i?t.div:0!==t.div.negative?t.div.isubn(1):t.div.iaddn(1)},i.prototype.modn=function(e){o(e<=67108863);for(var t=(1<<26)%e,n=0,r=this.length-1;r>=0;r--)n=(t*n+(0|this.words[r]))%e;return n},i.prototype.idivn=function(e){o(e<=67108863);for(var t=0,n=this.length-1;n>=0;n--){var r=(0|this.words[n])+67108864*t;this.words[n]=r/e|0,t=r%e}return this.strip()},i.prototype.divn=function(e){return this.clone().idivn(e)},i.prototype.egcd=function(e){o(0===e.negative),o(!e.isZero());var t=this,n=e.clone();t=0!==t.negative?t.umod(e):t.clone();for(var r=new i(1),a=new i(0),s=new i(0),u=new i(1),c=0;t.isEven()&&n.isEven();)t.iushrn(1),n.iushrn(1),++c;for(var l=n.clone(),d=t.clone();!t.isZero();){for(var h=0,p=1;0==(t.words[0]&p)&&h<26;++h,p<<=1);if(h>0)for(t.iushrn(h);h-- >0;)(r.isOdd()||a.isOdd())&&(r.iadd(l),a.isub(d)),r.iushrn(1),a.iushrn(1);for(var f=0,g=1;0==(n.words[0]&g)&&f<26;++f,g<<=1);if(f>0)for(n.iushrn(f);f-- >0;)(s.isOdd()||u.isOdd())&&(s.iadd(l),u.isub(d)),s.iushrn(1),u.iushrn(1);t.cmp(n)>=0?(t.isub(n),r.isub(s),a.isub(u)):(n.isub(t),s.isub(r),u.isub(a))}return{a:s,b:u,gcd:n.iushln(c)}},i.prototype._invmp=function(e){o(0===e.negative),o(!e.isZero());var t=this,n=e.clone();t=0!==t.negative?t.umod(e):t.clone();for(var r,a=new i(1),s=new i(0),u=n.clone();t.cmpn(1)>0&&n.cmpn(1)>0;){for(var c=0,l=1;0==(t.words[0]&l)&&c<26;++c,l<<=1);if(c>0)for(t.iushrn(c);c-- >0;)a.isOdd()&&a.iadd(u),a.iushrn(1);for(var d=0,h=1;0==(n.words[0]&h)&&d<26;++d,h<<=1);if(d>0)for(n.iushrn(d);d-- >0;)s.isOdd()&&s.iadd(u),s.iushrn(1);t.cmp(n)>=0?(t.isub(n),a.isub(s)):(n.isub(t),s.isub(a))}return(r=0===t.cmpn(1)?a:s).cmpn(0)<0&&r.iadd(e),r},i.prototype.gcd=function(e){if(this.isZero())return e.abs();if(e.isZero())return this.abs();var t=this.clone(),n=e.clone();t.negative=0,n.negative=0;for(var o=0;t.isEven()&&n.isEven();o++)t.iushrn(1),n.iushrn(1);for(;;){for(;t.isEven();)t.iushrn(1);for(;n.isEven();)n.iushrn(1);var r=t.cmp(n);if(r<0){var i=t;t=n,n=i}else if(0===r||0===n.cmpn(1))break;t.isub(n)}return n.iushln(o)},i.prototype.invm=function(e){return this.egcd(e).a.umod(e)},i.prototype.isEven=function(){return 0==(1&this.words[0])},i.prototype.isOdd=function(){return 1==(1&this.words[0])},i.prototype.andln=function(e){return this.words[0]&e},i.prototype.bincn=function(e){o("number"==typeof e);var t=e%26,n=(e-t)/26,r=1<>>26,s&=67108863,this.words[a]=s}return 0!==i&&(this.words[a]=i,this.length++),this},i.prototype.isZero=function(){return 1===this.length&&0===this.words[0]},i.prototype.cmpn=function(e){var t,n=e<0;if(0!==this.negative&&!n)return-1;if(0===this.negative&&n)return 1;if(this.strip(),this.length>1)t=1;else{n&&(e=-e),o(e<=67108863,"Number is too big");var r=0|this.words[0];t=r===e?0:re.length)return 1;if(this.length=0;n--){var o=0|this.words[n],r=0|e.words[n];if(o!==r){or&&(t=1);break}}return t},i.prototype.gtn=function(e){return 1===this.cmpn(e)},i.prototype.gt=function(e){return 1===this.cmp(e)},i.prototype.gten=function(e){return this.cmpn(e)>=0},i.prototype.gte=function(e){return this.cmp(e)>=0},i.prototype.ltn=function(e){return-1===this.cmpn(e)},i.prototype.lt=function(e){return-1===this.cmp(e)},i.prototype.lten=function(e){return this.cmpn(e)<=0},i.prototype.lte=function(e){return this.cmp(e)<=0},i.prototype.eqn=function(e){return 0===this.cmpn(e)},i.prototype.eq=function(e){return 0===this.cmp(e)},i.red=function(e){return new E(e)},i.prototype.toRed=function(e){return o(!this.red,"Already a number in reduction context"),o(0===this.negative,"red works only with positives"),e.convertTo(this)._forceRed(e)},i.prototype.fromRed=function(){return o(this.red,"fromRed works only with numbers in reduction context"),this.red.convertFrom(this)},i.prototype._forceRed=function(e){return this.red=e,this},i.prototype.forceRed=function(e){return o(!this.red,"Already a number in reduction context"),this._forceRed(e)},i.prototype.redAdd=function(e){return o(this.red,"redAdd works only with red numbers"),this.red.add(this,e)},i.prototype.redIAdd=function(e){return o(this.red,"redIAdd works only with red numbers"),this.red.iadd(this,e)},i.prototype.redSub=function(e){return o(this.red,"redSub works only with red numbers"),this.red.sub(this,e)},i.prototype.redISub=function(e){return o(this.red,"redISub works only with red numbers"),this.red.isub(this,e)},i.prototype.redShl=function(e){return o(this.red,"redShl works only with red numbers"),this.red.shl(this,e)},i.prototype.redMul=function(e){return o(this.red,"redMul works only with red numbers"),this.red._verify2(this,e),this.red.mul(this,e)},i.prototype.redIMul=function(e){return o(this.red,"redMul works only with red numbers"),this.red._verify2(this,e),this.red.imul(this,e)},i.prototype.redSqr=function(){return o(this.red,"redSqr works only with red numbers"),this.red._verify1(this),this.red.sqr(this)},i.prototype.redISqr=function(){return o(this.red,"redISqr works only with red numbers"),this.red._verify1(this),this.red.isqr(this)},i.prototype.redSqrt=function(){return o(this.red,"redSqrt works only with red numbers"),this.red._verify1(this),this.red.sqrt(this)},i.prototype.redInvm=function(){return o(this.red,"redInvm works only with red numbers"),this.red._verify1(this),this.red.invm(this)},i.prototype.redNeg=function(){return o(this.red,"redNeg works only with red numbers"),this.red._verify1(this),this.red.neg(this)},i.prototype.redPow=function(e){return o(this.red&&!e.red,"redPow(normalNum)"),this.red._verify1(this),this.red.pow(this,e)};var _={k256:null,p224:null,p192:null,p25519:null};function F(e,t){this.name=e,this.p=new i(t,16),this.n=this.p.bitLength(),this.k=new i(1).iushln(this.n).isub(this.p),this.tmp=this._tmp()}function y(){F.call(this,"k256","ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f")}function b(){F.call(this,"p224","ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001")}function v(){F.call(this,"p192","ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff")}function w(){F.call(this,"25519","7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed")}function E(e){if("string"==typeof e){var t=i._prime(e);this.m=t.p,this.prime=t}else o(e.gtn(1),"modulus must be greater than 1"),this.m=e,this.prime=null}function k(e){E.call(this,e),this.shift=this.m.bitLength(),this.shift%26!=0&&(this.shift+=26-this.shift%26),this.r=new i(1).iushln(this.shift),this.r2=this.imod(this.r.sqr()),this.rinv=this.r._invmp(this.m),this.minv=this.rinv.mul(this.r).isubn(1).div(this.m),this.minv=this.minv.umod(this.r),this.minv=this.r.sub(this.minv)}F.prototype._tmp=function(){var e=new i(null);return e.words=new Array(Math.ceil(this.n/13)),e},F.prototype.ireduce=function(e){var t,n=e;do{this.split(n,this.tmp),t=(n=(n=this.imulK(n)).iadd(this.tmp)).bitLength()}while(t>this.n);var o=t0?n.isub(this.p):void 0!==n.strip?n.strip():n._strip(),n},F.prototype.split=function(e,t){e.iushrn(this.n,0,t)},F.prototype.imulK=function(e){return e.imul(this.k)},r(y,F),y.prototype.split=function(e,t){for(var n=4194303,o=Math.min(e.length,9),r=0;r>>22,i=a}i>>>=22,e.words[r-10]=i,0===i&&e.length>10?e.length-=10:e.length-=9},y.prototype.imulK=function(e){e.words[e.length]=0,e.words[e.length+1]=0,e.length+=2;for(var t=0,n=0;n>>=26,e.words[n]=r,t=o}return 0!==t&&(e.words[e.length++]=t),e},i._prime=function(e){if(_[e])return _[e];var t;if("k256"===e)t=new y;else if("p224"===e)t=new b;else if("p192"===e)t=new v;else{if("p25519"!==e)throw new Error("Unknown prime "+e);t=new w}return _[e]=t,t},E.prototype._verify1=function(e){o(0===e.negative,"red works only with positives"),o(e.red,"red works only with red numbers")},E.prototype._verify2=function(e,t){o(0==(e.negative|t.negative),"red works only with positives"),o(e.red&&e.red===t.red,"red works only with red numbers")},E.prototype.imod=function(e){return this.prime?this.prime.ireduce(e)._forceRed(this):e.umod(this.m)._forceRed(this)},E.prototype.neg=function(e){return e.isZero()?e.clone():this.m.sub(e)._forceRed(this)},E.prototype.add=function(e,t){this._verify2(e,t);var n=e.add(t);return n.cmp(this.m)>=0&&n.isub(this.m),n._forceRed(this)},E.prototype.iadd=function(e,t){this._verify2(e,t);var n=e.iadd(t);return n.cmp(this.m)>=0&&n.isub(this.m),n},E.prototype.sub=function(e,t){this._verify2(e,t);var n=e.sub(t);return n.cmpn(0)<0&&n.iadd(this.m),n._forceRed(this)},E.prototype.isub=function(e,t){this._verify2(e,t);var n=e.isub(t);return n.cmpn(0)<0&&n.iadd(this.m),n},E.prototype.shl=function(e,t){return this._verify1(e),this.imod(e.ushln(t))},E.prototype.imul=function(e,t){return this._verify2(e,t),this.imod(e.imul(t))},E.prototype.mul=function(e,t){return this._verify2(e,t),this.imod(e.mul(t))},E.prototype.isqr=function(e){return this.imul(e,e.clone())},E.prototype.sqr=function(e){return this.mul(e,e)},E.prototype.sqrt=function(e){if(e.isZero())return e.clone();var t=this.m.andln(3);if(o(t%2==1),3===t){var n=this.m.add(new i(1)).iushrn(2);return this.pow(e,n)}for(var r=this.m.subn(1),a=0;!r.isZero()&&0===r.andln(1);)a++,r.iushrn(1);o(!r.isZero());var s=new i(1).toRed(this),u=s.redNeg(),c=this.m.subn(1).iushrn(1),l=this.m.bitLength();for(l=new i(2*l*l).toRed(this);0!==this.pow(l,c).cmp(u);)l.redIAdd(u);for(var d=this.pow(l,r),h=this.pow(e,r.addn(1).iushrn(1)),p=this.pow(e,r),f=a;0!==p.cmp(s);){for(var g=p,m=0;0!==g.cmp(s);m++)g=g.redSqr();o(m=0;o--){for(var c=t.words[o],l=u-1;l>=0;l--){var d=c>>l&1;r!==n[0]&&(r=this.sqr(r)),0!==d||0!==a?(a<<=1,a|=d,(4==++s||0===o&&0===l)&&(r=this.mul(r,n[a]),s=0,a=0)):s=0}u=26}return r},E.prototype.convertTo=function(e){var t=e.umod(this.m);return t===e?t.clone():t},E.prototype.convertFrom=function(e){var t=e.clone();return t.red=null,t},i.mont=function(e){return new k(e)},r(k,E),k.prototype.convertTo=function(e){return this.imod(e.ushln(this.shift))},k.prototype.convertFrom=function(e){var t=this.imod(e.mul(this.rinv));return t.red=null,t},k.prototype.imul=function(e,t){if(e.isZero()||t.isZero())return e.words[0]=0,e.length=1,e;var n=e.imul(t),o=n.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m),r=n.isub(o).iushrn(this.shift),i=r;return r.cmp(this.m)>=0?i=r.isub(this.m):r.cmpn(0)<0&&(i=r.iadd(this.m)),i._forceRed(this)},k.prototype.mul=function(e,t){if(e.isZero()||t.isZero())return new i(0)._forceRed(this);var n=e.mul(t),o=n.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m),r=n.isub(o).iushrn(this.shift),a=r;return r.cmp(this.m)>=0?a=r.isub(this.m):r.cmpn(0)<0&&(a=r.iadd(this.m)),a._forceRed(this)},k.prototype.invm=function(e){return this.imod(e._invmp(this.m).mul(this.r2))._forceRed(this)}}(e=n.nmd(e),this)},26138:(e,t,n)=>{var o=n(70980),r=n(99199),i=n(57859),a=n(92144),s=n(23663),u=n(23482),c=n(84818),l=n(89509).Buffer;e.exports=function(e,t,n){var d;d=e.padding?e.padding:n?1:4;var h,p=o(e),f=p.modulus.byteLength();if(t.length>f||new a(t).cmp(p.modulus)>=0)throw new Error("decryption error");h=n?c(new a(t),p):s(t,p);var g=l.alloc(f-h.length);if(h=l.concat([g,h],f),4===d)return function(e,t){var n=e.modulus.byteLength(),o=u("sha1").update(l.alloc(0)).digest(),a=o.length;if(0!==t[0])throw new Error("decryption error");var s=t.slice(1,a+1),c=t.slice(a+1),d=i(s,r(c,a)),h=i(c,r(d,n-a-1));if(function(e,t){e=l.from(e),t=l.from(t);var n=0,o=e.length;e.length!==t.length&&(n++,o=Math.min(e.length,t.length));for(var r=-1;++r=t.length){i++;break}var a=t.slice(2,r-1);if(("0002"!==o.toString("hex")&&!n||"0001"!==o.toString("hex")&&n)&&i++,a.length<8&&i++,i)throw new Error("decryption error");return t.slice(r)}(0,h,n);if(3===d)return h;throw new Error("unknown padding")}},16559:(e,t,n)=>{var o=n(70980),r=n(61798),i=n(23482),a=n(99199),s=n(57859),u=n(92144),c=n(84818),l=n(23663),d=n(89509).Buffer;e.exports=function(e,t,n){var h;h=e.padding?e.padding:n?1:4;var p,f=o(e);if(4===h)p=function(e,t){var n=e.modulus.byteLength(),o=t.length,c=i("sha1").update(d.alloc(0)).digest(),l=c.length,h=2*l;if(o>n-h-2)throw new Error("message too long");var p=d.alloc(n-o-h-2),f=n-l-1,g=r(l),m=s(d.concat([c,p,d.alloc(1,1),t],f),a(g,f)),_=s(g,a(m,l));return new u(d.concat([d.alloc(1),_,m],n))}(f,t);else if(1===h)p=function(e,t,n){var o,i=t.length,a=e.modulus.byteLength();if(i>a-11)throw new Error("message too long");return o=n?d.alloc(a-i-3,255):function(e){for(var t,n=d.allocUnsafe(e),o=0,i=r(2*e),a=0;o=0)throw new Error("data too long for modulus")}return n?l(p,f):c(p,f)}},84818:(e,t,n)=>{var o=n(92144),r=n(89509).Buffer;e.exports=function(e,t){return r.from(e.toRed(o.mont(t.modulus)).redPow(new o(t.publicExponent)).fromRed().toArray())}},57859:e=>{e.exports=function(e,t){for(var n=e.length,o=-1;++o{"use strict";var t=String.prototype.replace,n=/%20/g,o="RFC3986";e.exports={default:o,formatters:{RFC1738:function(e){return t.call(e,n,"+")},RFC3986:function(e){return String(e)}},RFC1738:"RFC1738",RFC3986:o}},80129:(e,t,n)=>{"use strict";var o=n(58261),r=n(55235),i=n(55798);e.exports={formats:i,parse:r,stringify:o}},55235:(e,t,n)=>{"use strict";var o=n(12769),r=Object.prototype.hasOwnProperty,i=Array.isArray,a={allowDots:!1,allowPrototypes:!1,allowSparse:!1,arrayLimit:20,charset:"utf-8",charsetSentinel:!1,comma:!1,decoder:o.decode,delimiter:"&",depth:5,ignoreQueryPrefix:!1,interpretNumericEntities:!1,parameterLimit:1e3,parseArrays:!0,plainObjects:!1,strictNullHandling:!1},s=function(e){return e.replace(/&#(\d+);/g,(function(e,t){return String.fromCharCode(parseInt(t,10))}))},u=function(e,t){return e&&"string"==typeof e&&t.comma&&e.indexOf(",")>-1?e.split(","):e},c=function(e,t,n,o){if(e){var i=n.allowDots?e.replace(/\.([^.[]+)/g,"[$1]"):e,a=/(\[[^[\]]*])/g,s=n.depth>0&&/(\[[^[\]]*])/.exec(i),c=s?i.slice(0,s.index):i,l=[];if(c){if(!n.plainObjects&&r.call(Object.prototype,c)&&!n.allowPrototypes)return;l.push(c)}for(var d=0;n.depth>0&&null!==(s=a.exec(i))&&d=0;--i){var a,s=e[i];if("[]"===s&&n.parseArrays)a=[].concat(r);else{a=n.plainObjects?Object.create(null):{};var c="["===s.charAt(0)&&"]"===s.charAt(s.length-1)?s.slice(1,-1):s,l=parseInt(c,10);n.parseArrays||""!==c?!isNaN(l)&&s!==c&&String(l)===c&&l>=0&&n.parseArrays&&l<=n.arrayLimit?(a=[])[l]=r:a[c]=r:a={0:r}}r=a}return r}(l,t,n,o)}};e.exports=function(e,t){var n=function(e){if(!e)return a;if(null!==e.decoder&&void 0!==e.decoder&&"function"!=typeof e.decoder)throw new TypeError("Decoder has to be a function.");if(void 0!==e.charset&&"utf-8"!==e.charset&&"iso-8859-1"!==e.charset)throw new TypeError("The charset option must be either utf-8, iso-8859-1, or undefined");var t=void 0===e.charset?a.charset:e.charset;return{allowDots:void 0===e.allowDots?a.allowDots:!!e.allowDots,allowPrototypes:"boolean"==typeof e.allowPrototypes?e.allowPrototypes:a.allowPrototypes,allowSparse:"boolean"==typeof e.allowSparse?e.allowSparse:a.allowSparse,arrayLimit:"number"==typeof e.arrayLimit?e.arrayLimit:a.arrayLimit,charset:t,charsetSentinel:"boolean"==typeof e.charsetSentinel?e.charsetSentinel:a.charsetSentinel,comma:"boolean"==typeof e.comma?e.comma:a.comma,decoder:"function"==typeof e.decoder?e.decoder:a.decoder,delimiter:"string"==typeof e.delimiter||o.isRegExp(e.delimiter)?e.delimiter:a.delimiter,depth:"number"==typeof e.depth||!1===e.depth?+e.depth:a.depth,ignoreQueryPrefix:!0===e.ignoreQueryPrefix,interpretNumericEntities:"boolean"==typeof e.interpretNumericEntities?e.interpretNumericEntities:a.interpretNumericEntities,parameterLimit:"number"==typeof e.parameterLimit?e.parameterLimit:a.parameterLimit,parseArrays:!1!==e.parseArrays,plainObjects:"boolean"==typeof e.plainObjects?e.plainObjects:a.plainObjects,strictNullHandling:"boolean"==typeof e.strictNullHandling?e.strictNullHandling:a.strictNullHandling}}(t);if(""===e||null==e)return n.plainObjects?Object.create(null):{};for(var l="string"==typeof e?function(e,t){var n,c={},l=t.ignoreQueryPrefix?e.replace(/^\?/,""):e,d=t.parameterLimit===1/0?void 0:t.parameterLimit,h=l.split(t.delimiter,d),p=-1,f=t.charset;if(t.charsetSentinel)for(n=0;n-1&&(m=i(m)?[m]:m),r.call(c,g)?c[g]=o.combine(c[g],m):c[g]=m}return c}(e,n):e,d=n.plainObjects?Object.create(null):{},h=Object.keys(l),p=0;p{"use strict";var o=n(37478),r=n(12769),i=n(55798),a=Object.prototype.hasOwnProperty,s={brackets:function(e){return e+"[]"},comma:"comma",indices:function(e,t){return e+"["+t+"]"},repeat:function(e){return e}},u=Array.isArray,c=Array.prototype.push,l=function(e,t){c.apply(e,u(t)?t:[t])},d=Date.prototype.toISOString,h=i.default,p={addQueryPrefix:!1,allowDots:!1,charset:"utf-8",charsetSentinel:!1,delimiter:"&",encode:!0,encoder:r.encode,encodeValuesOnly:!1,format:h,formatter:i.formatters[h],indices:!1,serializeDate:function(e){return d.call(e)},skipNulls:!1,strictNullHandling:!1},f=function e(t,n,i,a,s,c,d,h,f,g,m,_,F,y,b){var v,w=t;if(b.has(t))throw new RangeError("Cyclic object value");if("function"==typeof d?w=d(n,w):w instanceof Date?w=g(w):"comma"===i&&u(w)&&(w=r.maybeMap(w,(function(e){return e instanceof Date?g(e):e}))),null===w){if(a)return c&&!F?c(n,p.encoder,y,"key",m):n;w=""}if("string"==typeof(v=w)||"number"==typeof v||"boolean"==typeof v||"symbol"==typeof v||"bigint"==typeof v||r.isBuffer(w))return c?[_(F?n:c(n,p.encoder,y,"key",m))+"="+_(c(w,p.encoder,y,"value",m))]:[_(n)+"="+_(String(w))];var E,k=[];if(void 0===w)return k;if("comma"===i&&u(w))E=[{value:w.length>0?w.join(",")||null:void 0}];else if(u(d))E=d;else{var D=Object.keys(w);E=h?D.sort(h):D}for(var S=0;S0?b+y:""}},12769:(e,t,n)=>{"use strict";var o=n(55798),r=Object.prototype.hasOwnProperty,i=Array.isArray,a=function(){for(var e=[],t=0;t<256;++t)e.push("%"+((t<16?"0":"")+t.toString(16)).toUpperCase());return e}(),s=function(e,t){for(var n=t&&t.plainObjects?Object.create(null):{},o=0;o1;){var t=e.pop(),n=t.obj[t.prop];if(i(n)){for(var o=[],r=0;r=48&&l<=57||l>=65&&l<=90||l>=97&&l<=122||i===o.RFC1738&&(40===l||41===l)?u+=s.charAt(c):l<128?u+=a[l]:l<2048?u+=a[192|l>>6]+a[128|63&l]:l<55296||l>=57344?u+=a[224|l>>12]+a[128|l>>6&63]+a[128|63&l]:(c+=1,l=65536+((1023&l)<<10|1023&s.charCodeAt(c)),u+=a[240|l>>18]+a[128|l>>12&63]+a[128|l>>6&63]+a[128|63&l])}return u},isBuffer:function(e){return!(!e||"object"!=typeof e||!(e.constructor&&e.constructor.isBuffer&&e.constructor.isBuffer(e)))},isRegExp:function(e){return"[object RegExp]"===Object.prototype.toString.call(e)},maybeMap:function(e,t){if(i(e)){for(var n=[],o=0;o{"use strict";function t(e,t){return Object.prototype.hasOwnProperty.call(e,t)}e.exports=function(e,n,o,r){n=n||"&",o=o||"=";var i={};if("string"!=typeof e||0===e.length)return i;var a=/\+/g;e=e.split(n);var s=1e3;r&&"number"==typeof r.maxKeys&&(s=r.maxKeys);var u=e.length;s>0&&u>s&&(u=s);for(var c=0;c=0?(l=f.substr(0,g),d=f.substr(g+1)):(l=f,d=""),h=decodeURIComponent(l),p=decodeURIComponent(d),t(i,h)?Array.isArray(i[h])?i[h].push(p):i[h]=[i[h],p]:i[h]=p}return i}},12361:e=>{"use strict";var t=function(e){switch(typeof e){case"string":return e;case"boolean":return e?"true":"false";case"number":return isFinite(e)?e:"";default:return""}};e.exports=function(e,n,o,r){return n=n||"&",o=o||"=",null===e&&(e=void 0),"object"==typeof e?Object.keys(e).map((function(r){var i=encodeURIComponent(t(r))+o;return Array.isArray(e[r])?e[r].map((function(e){return i+encodeURIComponent(t(e))})).join(n):i+encodeURIComponent(t(e[r]))})).join(n):r?encodeURIComponent(t(r))+o+encodeURIComponent(t(e)):""}},17673:(e,t,n)=>{"use strict";t.decode=t.parse=n(62587),t.encode=t.stringify=n(12361)},61798:(e,t,n)=>{"use strict";var o=65536,r=n(89509).Buffer,i=n.g.crypto||n.g.msCrypto;i&&i.getRandomValues?e.exports=function(e,t){if(e>4294967295)throw new RangeError("requested too many random bytes");var n=r.allocUnsafe(e);if(e>0)if(e>o)for(var a=0;a{"use strict";function o(){throw new Error("secure random number generation not supported by this browser\nuse chrome, FireFox or Internet Explorer 11")}var r=n(89509),i=n(61798),a=r.Buffer,s=r.kMaxLength,u=n.g.crypto||n.g.msCrypto,c=Math.pow(2,32)-1;function l(e,t){if("number"!=typeof e||e!=e)throw new TypeError("offset must be a number");if(e>c||e<0)throw new TypeError("offset must be a uint32");if(e>s||e>t)throw new RangeError("offset out of range")}function d(e,t,n){if("number"!=typeof e||e!=e)throw new TypeError("size must be a number");if(e>c||e<0)throw new TypeError("size must be a uint32");if(e+t>n||e>s)throw new RangeError("buffer too small")}function h(e,t,n,o){if(process.browser){var r=e.buffer,a=new Uint8Array(r,t,n);return u.getRandomValues(a),o?void process.nextTick((function(){o(null,e)})):e}if(!o)return i(n).copy(e,t),e;i(n,(function(n,r){if(n)return o(n);r.copy(e,t),o(null,e)}))}u&&u.getRandomValues||!process.browser?(t.randomFill=function(e,t,o,r){if(!(a.isBuffer(e)||e instanceof n.g.Uint8Array))throw new TypeError('"buf" argument must be a Buffer or Uint8Array');if("function"==typeof t)r=t,t=0,o=e.length;else if("function"==typeof o)r=o,o=e.length-t;else if("function"!=typeof r)throw new TypeError('"cb" argument must be a function');return l(t,e.length),d(o,t,e.length),h(e,t,o,r)},t.randomFillSync=function(e,t,o){if(void 0===t&&(t=0),!(a.isBuffer(e)||e instanceof n.g.Uint8Array))throw new TypeError('"buf" argument must be a Buffer or Uint8Array');return l(t,e.length),void 0===o&&(o=e.length-t),d(o,t,e.length),h(e,t,o)}):(t.randomFill=o,t.randomFillSync=o)},4857:function(e,t,n){"use strict";var o,r=this&&this.__extends||(o=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n])},function(e,t){function n(){this.constructor=e}o(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}),i=this&&this.__assign||Object.assign||function(e){for(var t,n=1,o=arguments.length;n{"use strict";var o=n(4857);t.Z=o.TextareaAutosize},64448:(e,t,n)=>{"use strict";var o=n(67294),r=n(27418),i=n(63840);function a(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n
    ")})),l=function(){var t=/(?:)/,r=t.exec;t.exec=function(){return r.apply(this,arguments)};var n="ab".split(t);return 2===n.length&&"a"===n[0]&&"b"===n[1]}();t.exports=function(t,r,n){var h=a(t),v=!o((function(){var r={};return r[h]=function(){return 7},7!=""[t](r)})),p=v?!o((function(){var r=!1,n=/a/;return n.exec=function(){return r=!0,null},"split"===t&&(n.constructor={},n.constructor[s]=function(){return n}),n[h](""),!r})):void 0;if(!v||!p||"replace"===t&&!f||"split"===t&&!l){var g=/./[h],d=n(u,h,""[t],(function(t,r,n,e,i){return r.exec===c?v&&!i?{done:!0,value:g.call(r,n,e)}:{done:!0,value:t.call(n,r,e)}:{done:!1}})),y=d[0],x=d[1];e(String.prototype,t,y),i(RegExp.prototype,h,2==r?function(t,r){return x.call(t,this,r)}:function(t){return x.call(t,this)})}}},53218:(t,r,n)=>{"use strict";var e=n(27007);t.exports=function(){var t=e(this),r="";return t.global&&(r+="g"),t.ignoreCase&&(r+="i"),t.multiline&&(r+="m"),t.unicode&&(r+="u"),t.sticky&&(r+="y"),r}},13325:(t,r,n)=>{"use strict";var e=n(4302),i=n(55286),o=n(10875),u=n(741),a=n(86314)("isConcatSpreadable");t.exports=function t(r,n,c,s,f,l,h,v){for(var p,g,d=f,y=0,x=!!h&&u(h,v,3);y0)d=t(r,n,p,o(p.length),d,l-1)-1;else{if(d>=9007199254740991)throw TypeError();r[d]=p}d++}y++}return d}},3531:(t,r,n)=>{var e=n(741),i=n(28851),o=n(86555),u=n(27007),a=n(10875),c=n(69002),s={},f={},l=t.exports=function(t,r,n,l,h){var v,p,g,d,y=h?function(){return t}:c(t),x=e(n,l,r?2:1),b=0;if("function"!=typeof y)throw TypeError(t+" is not iterable!");if(o(y)){for(v=a(t.length);v>b;b++)if((d=r?x(u(p=t[b])[0],p[1]):x(t[b]))===s||d===f)return d}else for(g=y.call(t);!(p=g.next()).done;)if((d=i(g,x,p.value,r))===s||d===f)return d};l.BREAK=s,l.RETURN=f},40018:(t,r,n)=>{t.exports=n(3825)("native-function-to-string",Function.toString)},3816:t=>{var r=t.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=r)},79181:t=>{var r={}.hasOwnProperty;t.exports=function(t,n){return r.call(t,n)}},87728:(t,r,n)=>{var e=n(99275),i=n(90681);t.exports=n(67057)?function(t,r,n){return e.f(t,r,i(1,n))}:function(t,r,n){return t[r]=n,t}},40639:(t,r,n)=>{var e=n(3816).document;t.exports=e&&e.documentElement},1734:(t,r,n)=>{t.exports=!n(67057)&&!n(74253)((function(){return 7!=Object.defineProperty(n(62457)("div"),"a",{get:function(){return 7}}).a}))},40266:(t,r,n)=>{var e=n(55286),i=n(27375).set;t.exports=function(t,r,n){var o,u=r.constructor;return u!==n&&"function"==typeof u&&(o=u.prototype)!==n.prototype&&e(o)&&i&&i(t,o),t}},97242:t=>{t.exports=function(t,r,n){var e=void 0===n;switch(r.length){case 0:return e?t():t.call(n);case 1:return e?t(r[0]):t.call(n,r[0]);case 2:return e?t(r[0],r[1]):t.call(n,r[0],r[1]);case 3:return e?t(r[0],r[1],r[2]):t.call(n,r[0],r[1],r[2]);case 4:return e?t(r[0],r[1],r[2],r[3]):t.call(n,r[0],r[1],r[2],r[3])}return t.apply(n,r)}},49797:(t,r,n)=>{var e=n(92032);t.exports=Object("z").propertyIsEnumerable(0)?Object:function(t){return"String"==e(t)?t.split(""):Object(t)}},86555:(t,r,n)=>{var e=n(87234),i=n(86314)("iterator"),o=Array.prototype;t.exports=function(t){return void 0!==t&&(e.Array===t||o[i]===t)}},4302:(t,r,n)=>{var e=n(92032);t.exports=Array.isArray||function(t){return"Array"==e(t)}},18367:(t,r,n)=>{var e=n(55286),i=Math.floor;t.exports=function(t){return!e(t)&&isFinite(t)&&i(t)===t}},55286:t=>{t.exports=function(t){return"object"==typeof t?null!==t:"function"==typeof t}},55364:(t,r,n)=>{var e=n(55286),i=n(92032),o=n(86314)("match");t.exports=function(t){var r;return e(t)&&(void 0!==(r=t[o])?!!r:"RegExp"==i(t))}},28851:(t,r,n)=>{var e=n(27007);t.exports=function(t,r,n,i){try{return i?r(e(n)[0],n[1]):r(n)}catch(r){var o=t.return;throw void 0!==o&&e(o.call(t)),r}}},49988:(t,r,n)=>{"use strict";var e=n(42503),i=n(90681),o=n(22943),u={};n(87728)(u,n(86314)("iterator"),(function(){return this})),t.exports=function(t,r,n){t.prototype=e(u,{next:i(1,n)}),o(t,r+" Iterator")}},42923:(t,r,n)=>{"use strict";var e=n(4461),i=n(42985),o=n(77234),u=n(87728),a=n(87234),c=n(49988),s=n(22943),f=n(468),l=n(86314)("iterator"),h=!([].keys&&"next"in[].keys()),v="keys",p="values",g=function(){return this};t.exports=function(t,r,n,d,y,x,b){c(n,r,d);var m,S,w,_=function(t){if(!h&&t in P)return P[t];switch(t){case v:case p:return function(){return new n(this,t)}}return function(){return new n(this,t)}},E=r+" Iterator",O=y==p,M=!1,P=t.prototype,F=P[l]||P["@@iterator"]||y&&P[y],A=F||_(y),I=y?O?_("entries"):A:void 0,j="Array"==r&&P.entries||F;if(j&&(w=f(j.call(new t)))!==Object.prototype&&w.next&&(s(w,E,!0),e||"function"==typeof w[l]||u(w,l,g)),O&&F&&F.name!==p&&(M=!0,A=function(){return F.call(this)}),e&&!b||!h&&!M&&P[l]||u(P,l,A),a[r]=A,a[E]=g,y)if(m={values:O?A:_(p),keys:x?A:_(v),entries:I},b)for(S in m)S in P||o(P,S,m[S]);else i(i.P+i.F*(h||M),r,m);return m}},7462:(t,r,n)=>{var e=n(86314)("iterator"),i=!1;try{var o=[7][e]();o.return=function(){i=!0},Array.from(o,(function(){throw 2}))}catch(t){}t.exports=function(t,r){if(!r&&!i)return!1;var n=!1;try{var o=[7],u=o[e]();u.next=function(){return{done:n=!0}},o[e]=function(){return u},t(o)}catch(t){}return n}},15436:t=>{t.exports=function(t,r){return{value:r,done:!!t}}},87234:t=>{t.exports={}},4461:t=>{t.exports=!1},13086:t=>{var r=Math.expm1;t.exports=!r||r(10)>22025.465794806718||r(10)<22025.465794806718||-2e-17!=r(-2e-17)?function(t){return 0==(t=+t)?t:t>-1e-6&&t<1e-6?t+t*t/2:Math.exp(t)-1}:r},34934:(t,r,n)=>{var e=n(61801),i=Math.pow,o=i(2,-52),u=i(2,-23),a=i(2,127)*(2-u),c=i(2,-126);t.exports=Math.fround||function(t){var r,n,i=Math.abs(t),s=e(t);return ia||n!=n?s*(1/0):s*n}},46206:t=>{t.exports=Math.log1p||function(t){return(t=+t)>-1e-8&&t<1e-8?t-t*t/2:Math.log(1+t)}},68757:t=>{t.exports=Math.scale||function(t,r,n,e,i){return 0===arguments.length||t!=t||r!=r||n!=n||e!=e||i!=i?NaN:t===1/0||t===-1/0?t:(t-r)*(i-e)/(n-r)+e}},61801:t=>{t.exports=Math.sign||function(t){return 0==(t=+t)||t!=t?t:t<0?-1:1}},84728:(t,r,n)=>{var e=n(93953)("meta"),i=n(55286),o=n(79181),u=n(99275).f,a=0,c=Object.isExtensible||function(){return!0},s=!n(74253)((function(){return c(Object.preventExtensions({}))})),f=function(t){u(t,e,{value:{i:"O"+ ++a,w:{}}})},l=t.exports={KEY:e,NEED:!1,fastKey:function(t,r){if(!i(t))return"symbol"==typeof t?t:("string"==typeof t?"S":"P")+t;if(!o(t,e)){if(!c(t))return"F";if(!r)return"E";f(t)}return t[e].i},getWeak:function(t,r){if(!o(t,e)){if(!c(t))return!0;if(!r)return!1;f(t)}return t[e].w},onFreeze:function(t){return s&&l.NEED&&c(t)&&!o(t,e)&&f(t),t}}},50133:(t,r,n)=>{var e=n(88416),i=n(42985),o=n(3825)("metadata"),u=o.store||(o.store=new(n(30147))),a=function(t,r,n){var i=u.get(t);if(!i){if(!n)return;u.set(t,i=new e)}var o=i.get(r);if(!o){if(!n)return;i.set(r,o=new e)}return o};t.exports={store:u,map:a,has:function(t,r,n){var e=a(r,n,!1);return void 0!==e&&e.has(t)},get:function(t,r,n){var e=a(r,n,!1);return void 0===e?void 0:e.get(t)},set:function(t,r,n,e){a(n,e,!0).set(t,r)},keys:function(t,r){var n=a(t,r,!1),e=[];return n&&n.forEach((function(t,r){e.push(r)})),e},key:function(t){return void 0===t||"symbol"==typeof t?t:String(t)},exp:function(t){i(i.S,"Reflect",t)}}},14351:(t,r,n)=>{var e=n(3816),i=n(74193).set,o=e.MutationObserver||e.WebKitMutationObserver,u=e.process,a=e.Promise,c="process"==n(92032)(u);t.exports=function(){var t,r,n,s=function(){var e,i;for(c&&(e=u.domain)&&e.exit();t;){i=t.fn,t=t.next;try{i()}catch(e){throw t?n():r=void 0,e}}r=void 0,e&&e.enter()};if(c)n=function(){u.nextTick(s)};else if(!o||e.navigator&&e.navigator.standalone)if(a&&a.resolve){var f=a.resolve(void 0);n=function(){f.then(s)}}else n=function(){i.call(e,s)};else{var l=!0,h=document.createTextNode("");new o(s).observe(h,{characterData:!0}),n=function(){h.data=l=!l}}return function(e){var i={fn:e,next:void 0};r&&(r.next=i),t||(t=i,n()),r=i}}},43499:(t,r,n)=>{"use strict";var e=n(24963);function i(t){var r,n;this.promise=new t((function(t,e){if(void 0!==r||void 0!==n)throw TypeError("Bad Promise constructor");r=t,n=e})),this.resolve=e(r),this.reject=e(n)}t.exports.f=function(t){return new i(t)}},35345:(t,r,n)=>{"use strict";var e=n(67057),i=n(47184),o=n(64548),u=n(14682),a=n(20508),c=n(49797),s=Object.assign;t.exports=!s||n(74253)((function(){var t={},r={},n=Symbol(),e="abcdefghijklmnopqrst";return t[n]=7,e.split("").forEach((function(t){r[t]=t})),7!=s({},t)[n]||Object.keys(s({},r)).join("")!=e}))?function(t,r){for(var n=a(t),s=arguments.length,f=1,l=o.f,h=u.f;s>f;)for(var v,p=c(arguments[f++]),g=l?i(p).concat(l(p)):i(p),d=g.length,y=0;d>y;)v=g[y++],e&&!h.call(p,v)||(n[v]=p[v]);return n}:s},42503:(t,r,n)=>{var e=n(27007),i=n(35588),o=n(74430),u=n(69335)("IE_PROTO"),a=function(){},c=function(){var t,r=n(62457)("iframe"),e=o.length;for(r.style.display="none",n(40639).appendChild(r),r.src="javascript:",(t=r.contentWindow.document).open(),t.write(" +
    + + + + + diff --git a/package-lock.json b/package-lock.json index 39b592c07..b60abb5c5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,7 +14,6 @@ "@khanacademy/simple-markdown": "0.8.6", "@matrix-org/olm": "3.2.14", "@tippyjs/react": "4.2.6", - "babel-polyfill": "6.26.0", "blurhash": "2.0.4", "browser-encrypt-attachment": "0.3.0", "dateformat": "5.0.3", @@ -41,38 +40,24 @@ "twemoji": "14.0.2" }, "devDependencies": { - "@babel/core": "7.20.5", - "@babel/preset-env": "7.20.2", - "@babel/preset-react": "7.18.6", - "assert": "2.0.0", - "babel-loader": "8.3.0", - "browserify-fs": "1.0.0", - "buffer": "6.0.3", - "clean-webpack-plugin": "4.0.0", - "copy-webpack-plugin": "11.0.0", - "crypto-browserify": "3.12.0", - "css-loader": "6.7.2", - "css-minimizer-webpack-plugin": "4.2.2", + "@rollup/plugin-wasm": "6.1.1", + "@types/react": "18.0.26", + "@types/react-dom": "18.0.9", + "@typescript-eslint/eslint-plugin": "5.46.1", + "@typescript-eslint/parser": "5.46.1", + "@vitejs/plugin-react": "3.0.0", "eslint": "8.29.0", "eslint-config-airbnb": "19.0.4", + "eslint-config-prettier": "8.5.0", "eslint-plugin-import": "2.26.0", "eslint-plugin-jsx-a11y": "6.6.1", "eslint-plugin-react": "7.31.11", "eslint-plugin-react-hooks": "4.6.0", - "html-loader": "4.2.0", - "html-webpack-plugin": "5.5.0", - "mini-css-extract-plugin": "2.7.2", - "path-browserify": "1.0.1", + "prettier": "2.8.1", "sass": "1.56.2", - "sass-loader": "13.2.0", - "stream-browserify": "3.0.0", - "style-loader": "3.3.1", - "url": "0.11.0", - "util": "0.12.5", - "webpack": "5.75.0", - "webpack-cli": "5.0.1", - "webpack-dev-server": "4.11.1", - "webpack-merge": "5.8.0" + "typescript": "4.9.4", + "vite": "4.0.1", + "vite-plugin-static-copy": "0.13.0" }, "engines": { "node": ">=16.0.0" @@ -170,31 +155,6 @@ "node": ">=6.0.0" } }, - "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz", - "integrity": "sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==", - "dev": true, - "dependencies": { - "@babel/types": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.18.9.tgz", - "integrity": "sha512-yFQ0YCHoIqarl8BCRwBL8ulYUaZpz3bNsA7oFepAzee+8/+ImtADXNOmO5vJvsPff3qi+hvpkY/NYBTrBQgdNw==", - "dev": true, - "dependencies": { - "@babel/helper-explode-assignable-expression": "^7.18.6", - "@babel/types": "^7.18.9" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-compilation-targets": { "version": "7.20.0", "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.0.tgz", @@ -213,60 +173,6 @@ "@babel/core": "^7.0.0" } }, - "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.20.5.tgz", - "integrity": "sha512-3RCdA/EmEaikrhayahwToF0fpweU/8o2p8vhc1c/1kftHOdTKuC65kik/TLc+qfbS8JKw4qqJbne4ovICDhmww==", - "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", - "@babel/helper-member-expression-to-functions": "^7.18.9", - "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/helper-replace-supers": "^7.19.1", - "@babel/helper-split-export-declaration": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.20.5.tgz", - "integrity": "sha512-m68B1lkg3XDGX5yCvGO0kPx3v9WIYLnzjKfPcQiwntEQa5ZeRkPmo2X/ISJc8qxWGfwUr+kvZAeEzAwLec2r2w==", - "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "regexpu-core": "^5.2.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz", - "integrity": "sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww==", - "dev": true, - "dependencies": { - "@babel/helper-compilation-targets": "^7.17.7", - "@babel/helper-plugin-utils": "^7.16.7", - "debug": "^4.1.1", - "lodash.debounce": "^4.0.8", - "resolve": "^1.14.2", - "semver": "^6.1.2" - }, - "peerDependencies": { - "@babel/core": "^7.4.0-0" - } - }, "node_modules/@babel/helper-environment-visitor": { "version": "7.18.9", "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", @@ -276,18 +182,6 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/helper-explode-assignable-expression": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.18.6.tgz", - "integrity": "sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg==", - "dev": true, - "dependencies": { - "@babel/types": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-function-name": { "version": "7.19.0", "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", @@ -313,18 +207,6 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.18.9.tgz", - "integrity": "sha512-RxifAh2ZoVU67PyKIO4AMi1wTenGfMR/O/ae0CCRqwgBAt5v7xjdtRw7UoSbsreKrQn5t7r89eruK/9JjYHuDg==", - "dev": true, - "dependencies": { - "@babel/types": "^7.18.9" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-module-imports": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", @@ -356,18 +238,6 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz", - "integrity": "sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==", - "dev": true, - "dependencies": { - "@babel/types": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-plugin-utils": { "version": "7.20.2", "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz", @@ -377,40 +247,6 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/helper-remap-async-to-generator": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz", - "integrity": "sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA==", - "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-wrap-function": "^7.18.9", - "@babel/types": "^7.18.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-replace-supers": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.19.1.tgz", - "integrity": "sha512-T7ahH7wV0Hfs46SFh5Jz3s0B6+o8g3c+7TMxu7xKfmHikg7EAZ3I2Qk9LFhjxXq8sL7UkP5JflezNwoZa8WvWw==", - "dev": true, - "dependencies": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-member-expression-to-functions": "^7.18.9", - "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/traverse": "^7.19.1", - "@babel/types": "^7.19.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-simple-access": { "version": "7.20.2", "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", @@ -423,18 +259,6 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.20.0.tgz", - "integrity": "sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg==", - "dev": true, - "dependencies": { - "@babel/types": "^7.20.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-split-export-declaration": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", @@ -474,21 +298,6 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/helper-wrap-function": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.20.5.tgz", - "integrity": "sha512-bYMxIWK5mh+TgXGVqAtnu5Yn1un+v8DDZtqyzKRLUzrh70Eal2O3aZ7aPYiMADO4uKlkzOiRiZ6GX5q3qxvW9Q==", - "dev": true, - "dependencies": { - "@babel/helper-function-name": "^7.19.0", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.20.5", - "@babel/types": "^7.20.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helpers": { "version": "7.20.6", "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.6.tgz", @@ -529,10 +338,10 @@ "node": ">=6.0.0" } }, - "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "node_modules/@babel/plugin-transform-react-jsx-self": { "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.18.6.tgz", - "integrity": "sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ==", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.18.6.tgz", + "integrity": "sha512-A0LQGx4+4Jv7u/tWzoJF7alZwnBDQd6cGLh9P+Ttk4dpiL+J5p7NSNv/9tlEFFJDq3kjxOavWmbm6t0Gk+A3Ig==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.18.6" @@ -540,343 +349,14 @@ "engines": { "node": ">=6.9.0" }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.18.9.tgz", - "integrity": "sha512-AHrP9jadvH7qlOj6PINbgSuphjQUAK7AOT7DPjBo9EHoLhQTnnK5u45e1Hd4DbSQEO9nqPWtQ89r+XEOWFScKg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9", - "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9", - "@babel/plugin-proposal-optional-chaining": "^7.18.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.13.0" - } - }, - "node_modules/@babel/plugin-proposal-async-generator-functions": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.20.1.tgz", - "integrity": "sha512-Gh5rchzSwE4kC+o/6T8waD0WHEQIsDmjltY8WnWRXHUdH8axZhuH86Ov9M72YhJfDrZseQwuuWaaIT/TmePp3g==", - "dev": true, - "dependencies": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/helper-remap-async-to-generator": "^7.18.9", - "@babel/plugin-syntax-async-generators": "^7.8.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-class-properties": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz", - "integrity": "sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==", - "dev": true, - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-proposal-class-static-block": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.18.6.tgz", - "integrity": "sha512-+I3oIiNxrCpup3Gi8n5IGMwj0gOCAjcJUSQEcotNnCCPMEnixawOQ+KeJPlgfjzx+FKQ1QSyZOWe7wmoJp7vhw==", - "dev": true, - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-class-static-block": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.12.0" - } - }, - "node_modules/@babel/plugin-proposal-dynamic-import": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.18.6.tgz", - "integrity": "sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-dynamic-import": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-export-namespace-from": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.18.9.tgz", - "integrity": "sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-json-strings": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.18.6.tgz", - "integrity": "sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-json-strings": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-logical-assignment-operators": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.18.9.tgz", - "integrity": "sha512-128YbMpjCrP35IOExw2Fq+x55LMP42DzhOhX2aNNIdI9avSWl2PI0yuBWarr3RYpZBSPtabfadkH2yeRiMD61Q==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz", - "integrity": "sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-numeric-separator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz", - "integrity": "sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-numeric-separator": "^7.10.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-object-rest-spread": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.2.tgz", - "integrity": "sha512-Ks6uej9WFK+fvIMesSqbAto5dD8Dz4VuuFvGJFKgIGSkJuRGcrwGECPA1fDgQK3/DbExBJpEkTeYeB8geIFCSQ==", - "dev": true, - "dependencies": { - "@babel/compat-data": "^7.20.1", - "@babel/helper-compilation-targets": "^7.20.0", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.20.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-optional-catch-binding": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.18.6.tgz", - "integrity": "sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-optional-chaining": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.18.9.tgz", - "integrity": "sha512-v5nwt4IqBXihxGsW2QmCWMDS3B3bzGIk/EQVZz2ei7f3NJl8NzAJVvUmpDW5q1CRNY+Beb/k58UAH1Km1N411w==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9", - "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9", - "@babel/plugin-syntax-optional-chaining": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-private-methods": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz", - "integrity": "sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==", - "dev": true, - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-private-property-in-object": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.20.5.tgz", - "integrity": "sha512-Vq7b9dUA12ByzB4EjQTPo25sFhY+08pQDBSZRtUAkj7lb7jahaHR5igera16QZ+3my1nYR4dKsNdYj5IjPHilQ==", - "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-create-class-features-plugin": "^7.20.5", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-unicode-property-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz", - "integrity": "sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==", - "dev": true, - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-class-static-block": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", - "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-dynamic-import": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", - "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-export-namespace-from": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", - "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-assertions": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.20.0.tgz", - "integrity": "sha512-IUh1vakzNoWalR8ch/areW7qFopR2AEw03JlG7BbrDqmQ4X3q9uuipQwSGrUn7oGiemKjtSLDhNtQHzMHr1JdQ==", + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.19.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.19.6.tgz", + "integrity": "sha512-RpAi004QyMNisst/pvSanoRdJ4q+jMCWyk9zdw/CyLB9j8RXEahodR6l2GyttDRyEVWZtbN+TpLiHJ3t34LbsQ==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.19.0" @@ -888,831 +368,6 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz", - "integrity": "sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-private-property-in-object": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", - "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-arrow-functions": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.18.6.tgz", - "integrity": "sha512-9S9X9RUefzrsHZmKMbDXxweEH+YlE8JJEuat9FdvW9Qh1cw7W64jELCtWNkPBPX5En45uy28KGvA/AySqUh8CQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-async-to-generator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.18.6.tgz", - "integrity": "sha512-ARE5wZLKnTgPW7/1ftQmSi1CmkqqHo2DNmtztFhvgtOWSDfq0Cq9/9L+KnZNYSNrydBekhW3rwShduf59RoXag==", - "dev": true, - "dependencies": { - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-remap-async-to-generator": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-block-scoped-functions": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.18.6.tgz", - "integrity": "sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.20.5.tgz", - "integrity": "sha512-WvpEIW9Cbj9ApF3yJCjIEEf1EiNJLtXagOrL5LNWEZOo3jv8pmPoYTSNJQvqej8OavVlgOoOPw6/htGZro6IkA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-classes": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.20.2.tgz", - "integrity": "sha512-9rbPp0lCVVoagvtEyQKSo5L8oo0nQS/iif+lwlAz29MccX2642vWDlSZK+2T2buxbopotId2ld7zZAzRfz9j1g==", - "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-compilation-targets": "^7.20.0", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", - "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-replace-supers": "^7.19.1", - "@babel/helper-split-export-declaration": "^7.18.6", - "globals": "^11.1.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-computed-properties": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.18.9.tgz", - "integrity": "sha512-+i0ZU1bCDymKakLxn5srGHrsAPRELC2WIbzwjLhHW9SIE1cPYkLCL0NlnXMZaM1vhfgA2+M7hySk42VBvrkBRw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.20.2.tgz", - "integrity": "sha512-mENM+ZHrvEgxLTBXUiQ621rRXZes3KWUv6NdQlrnr1TkWVw+hUjQBZuP2X32qKlrlG2BzgR95gkuCRSkJl8vIw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-dotall-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.18.6.tgz", - "integrity": "sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg==", - "dev": true, - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-duplicate-keys": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.18.9.tgz", - "integrity": "sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-exponentiation-operator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.18.6.tgz", - "integrity": "sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw==", - "dev": true, - "dependencies": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-for-of": { - "version": "7.18.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.18.8.tgz", - "integrity": "sha512-yEfTRnjuskWYo0k1mHUqrVWaZwrdq8AYbfrpqULOJOaucGSp4mNMVps+YtA8byoevxS/urwU75vyhQIxcCgiBQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-function-name": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.18.9.tgz", - "integrity": "sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ==", - "dev": true, - "dependencies": { - "@babel/helper-compilation-targets": "^7.18.9", - "@babel/helper-function-name": "^7.18.9", - "@babel/helper-plugin-utils": "^7.18.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-literals": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.18.9.tgz", - "integrity": "sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-member-expression-literals": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.18.6.tgz", - "integrity": "sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-amd": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.19.6.tgz", - "integrity": "sha512-uG3od2mXvAtIFQIh0xrpLH6r5fpSQN04gIVovl+ODLdUMANokxQLZnPBHcjmv3GxRjnqwLuHvppjjcelqUFZvg==", - "dev": true, - "dependencies": { - "@babel/helper-module-transforms": "^7.19.6", - "@babel/helper-plugin-utils": "^7.19.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.19.6.tgz", - "integrity": "sha512-8PIa1ym4XRTKuSsOUXqDG0YaOlEuTVvHMe5JCfgBMOtHvJKw/4NGovEGN33viISshG/rZNVrACiBmPQLvWN8xQ==", - "dev": true, - "dependencies": { - "@babel/helper-module-transforms": "^7.19.6", - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/helper-simple-access": "^7.19.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.19.6.tgz", - "integrity": "sha512-fqGLBepcc3kErfR9R3DnVpURmckXP7gj7bAlrTQyBxrigFqszZCkFkcoxzCp2v32XmwXLvbw+8Yq9/b+QqksjQ==", - "dev": true, - "dependencies": { - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-module-transforms": "^7.19.6", - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/helper-validator-identifier": "^7.19.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-umd": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.18.6.tgz", - "integrity": "sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ==", - "dev": true, - "dependencies": { - "@babel/helper-module-transforms": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.20.5.tgz", - "integrity": "sha512-mOW4tTzi5iTLnw+78iEq3gr8Aoq4WNRGpmSlrogqaiCBoR1HFhpU4JkpQFOHfeYx3ReVIFWOQJS4aZBRvuZ6mA==", - "dev": true, - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.20.5", - "@babel/helper-plugin-utils": "^7.20.2" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-transform-new-target": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.18.6.tgz", - "integrity": "sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-object-super": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.18.6.tgz", - "integrity": "sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-replace-supers": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-parameters": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.20.5.tgz", - "integrity": "sha512-h7plkOmcndIUWXZFLgpbrh2+fXAi47zcUX7IrOQuZdLD0I0KvjJ6cvo3BEcAOsDOcZhVKGJqv07mkSqK0y2isQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-property-literals": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.18.6.tgz", - "integrity": "sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-react-display-name": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.18.6.tgz", - "integrity": "sha512-TV4sQ+T013n61uMoygyMRm+xf04Bd5oqFpv2jAEQwSZ8NwQA7zeRPg1LMVg2PWi3zWBz+CLKD+v5bcpZ/BS0aA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-react-jsx": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.19.0.tgz", - "integrity": "sha512-UVEvX3tXie3Szm3emi1+G63jyw1w5IcMY0FSKM+CRnKRI5Mr1YbCNgsSTwoTwKphQEG9P+QqmuRFneJPZuHNhg==", - "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/plugin-syntax-jsx": "^7.18.6", - "@babel/types": "^7.19.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-react-jsx-development": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.18.6.tgz", - "integrity": "sha512-SA6HEjwYFKF7WDjWcMcMGUimmw/nhNRDWxr+KaLSCrkD/LMDBvWRmHAYgE1HDeF8KUuI8OAu+RT6EOtKxSW2qA==", - "dev": true, - "dependencies": { - "@babel/plugin-transform-react-jsx": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-react-pure-annotations": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.18.6.tgz", - "integrity": "sha512-I8VfEPg9r2TRDdvnHgPepTKvuRomzA8+u+nhY7qSI1fR2hRNebasZEETLyM5mAUr0Ku56OkXJ0I7NHJnO6cJiQ==", - "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.20.5.tgz", - "integrity": "sha512-kW/oO7HPBtntbsahzQ0qSE3tFvkFwnbozz3NWFhLGqH75vLEg+sCGngLlhVkePlCs3Jv0dBBHDzCHxNiFAQKCQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2", - "regenerator-transform": "^0.15.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-reserved-words": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.18.6.tgz", - "integrity": "sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-shorthand-properties": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.18.6.tgz", - "integrity": "sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-spread": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.19.0.tgz", - "integrity": "sha512-RsuMk7j6n+r752EtzyScnWkQyuJdli6LdO5Klv8Yx0OfPVTcQkIUfS8clx5e9yHXzlnhOZF3CbQ8C2uP5j074w==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-sticky-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.18.6.tgz", - "integrity": "sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-template-literals": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.9.tgz", - "integrity": "sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-typeof-symbol": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.18.9.tgz", - "integrity": "sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-unicode-escapes": { - "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.10.tgz", - "integrity": "sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-unicode-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.18.6.tgz", - "integrity": "sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA==", - "dev": true, - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/preset-env": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.20.2.tgz", - "integrity": "sha512-1G0efQEWR1EHkKvKHqbG+IN/QdgwfByUpM5V5QroDzGV2t3S/WXNQd693cHiHTlCFMpr9B6FkPFXDA2lQcKoDg==", - "dev": true, - "dependencies": { - "@babel/compat-data": "^7.20.1", - "@babel/helper-compilation-targets": "^7.20.0", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-validator-option": "^7.18.6", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.18.6", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.18.9", - "@babel/plugin-proposal-async-generator-functions": "^7.20.1", - "@babel/plugin-proposal-class-properties": "^7.18.6", - "@babel/plugin-proposal-class-static-block": "^7.18.6", - "@babel/plugin-proposal-dynamic-import": "^7.18.6", - "@babel/plugin-proposal-export-namespace-from": "^7.18.9", - "@babel/plugin-proposal-json-strings": "^7.18.6", - "@babel/plugin-proposal-logical-assignment-operators": "^7.18.9", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6", - "@babel/plugin-proposal-numeric-separator": "^7.18.6", - "@babel/plugin-proposal-object-rest-spread": "^7.20.2", - "@babel/plugin-proposal-optional-catch-binding": "^7.18.6", - "@babel/plugin-proposal-optional-chaining": "^7.18.9", - "@babel/plugin-proposal-private-methods": "^7.18.6", - "@babel/plugin-proposal-private-property-in-object": "^7.18.6", - "@babel/plugin-proposal-unicode-property-regex": "^7.18.6", - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-class-properties": "^7.12.13", - "@babel/plugin-syntax-class-static-block": "^7.14.5", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3", - "@babel/plugin-syntax-import-assertions": "^7.20.0", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5", - "@babel/plugin-syntax-top-level-await": "^7.14.5", - "@babel/plugin-transform-arrow-functions": "^7.18.6", - "@babel/plugin-transform-async-to-generator": "^7.18.6", - "@babel/plugin-transform-block-scoped-functions": "^7.18.6", - "@babel/plugin-transform-block-scoping": "^7.20.2", - "@babel/plugin-transform-classes": "^7.20.2", - "@babel/plugin-transform-computed-properties": "^7.18.9", - "@babel/plugin-transform-destructuring": "^7.20.2", - "@babel/plugin-transform-dotall-regex": "^7.18.6", - "@babel/plugin-transform-duplicate-keys": "^7.18.9", - "@babel/plugin-transform-exponentiation-operator": "^7.18.6", - "@babel/plugin-transform-for-of": "^7.18.8", - "@babel/plugin-transform-function-name": "^7.18.9", - "@babel/plugin-transform-literals": "^7.18.9", - "@babel/plugin-transform-member-expression-literals": "^7.18.6", - "@babel/plugin-transform-modules-amd": "^7.19.6", - "@babel/plugin-transform-modules-commonjs": "^7.19.6", - "@babel/plugin-transform-modules-systemjs": "^7.19.6", - "@babel/plugin-transform-modules-umd": "^7.18.6", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.19.1", - "@babel/plugin-transform-new-target": "^7.18.6", - "@babel/plugin-transform-object-super": "^7.18.6", - "@babel/plugin-transform-parameters": "^7.20.1", - "@babel/plugin-transform-property-literals": "^7.18.6", - "@babel/plugin-transform-regenerator": "^7.18.6", - "@babel/plugin-transform-reserved-words": "^7.18.6", - "@babel/plugin-transform-shorthand-properties": "^7.18.6", - "@babel/plugin-transform-spread": "^7.19.0", - "@babel/plugin-transform-sticky-regex": "^7.18.6", - "@babel/plugin-transform-template-literals": "^7.18.9", - "@babel/plugin-transform-typeof-symbol": "^7.18.9", - "@babel/plugin-transform-unicode-escapes": "^7.18.10", - "@babel/plugin-transform-unicode-regex": "^7.18.6", - "@babel/preset-modules": "^0.1.5", - "@babel/types": "^7.20.2", - "babel-plugin-polyfill-corejs2": "^0.3.3", - "babel-plugin-polyfill-corejs3": "^0.6.0", - "babel-plugin-polyfill-regenerator": "^0.4.1", - "core-js-compat": "^3.25.1", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/preset-modules": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.5.tgz", - "integrity": "sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", - "@babel/plugin-transform-dotall-regex": "^7.4.4", - "@babel/types": "^7.4.4", - "esutils": "^2.0.2" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/preset-react": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.18.6.tgz", - "integrity": "sha512-zXr6atUmyYdiWRVLOZahakYmOBHtWc2WGCkP8PYTgZi0iJXDY2CN180TdrIW4OGOAdLc7TifzDIvtx6izaRIzg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-validator-option": "^7.18.6", - "@babel/plugin-transform-react-display-name": "^7.18.6", - "@babel/plugin-transform-react-jsx": "^7.18.6", - "@babel/plugin-transform-react-jsx-development": "^7.18.6", - "@babel/plugin-transform-react-pure-annotations": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, "node_modules/@babel/runtime": { "version": "7.20.6", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.6.tgz", @@ -1797,13 +452,356 @@ "node": ">=6.9.0" } }, - "node_modules/@discoveryjs/json-ext": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", - "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", + "node_modules/@esbuild/android-arm": { + "version": "0.16.9", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.16.9.tgz", + "integrity": "sha512-kW5ccqWHVOOTGUkkJbtfoImtqu3kA1PFkivM+9QPFSHphPfPBlBalX9eDRqPK+wHCqKhU48/78T791qPgC9e9A==", + "cpu": [ + "arm" + ], "dev": true, + "optional": true, + "os": [ + "android" + ], "engines": { - "node": ">=10.0.0" + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.16.9", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.16.9.tgz", + "integrity": "sha512-ndIAZJUeLx4O+4AJbFQCurQW4VRUXjDsUvt1L+nP8bVELOWdmdCEOtlIweCUE6P+hU0uxYbEK2AEP0n5IVQvhg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.16.9", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.16.9.tgz", + "integrity": "sha512-UbMcJB4EHrAVOnknQklREPgclNU2CPet2h+sCBCXmF2mfoYWopBn/CfTfeyOkb/JglOcdEADqAljFndMKnFtOw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.16.9", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.16.9.tgz", + "integrity": "sha512-d7D7/nrt4CxPul98lx4PXhyNZwTYtbdaHhOSdXlZuu5zZIznjqtMqLac8Bv+IuT6SVHiHUwrkL6ywD7mOgLW+A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.16.9", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.16.9.tgz", + "integrity": "sha512-LZc+Wlz06AkJYtwWsBM3x2rSqTG8lntDuftsUNQ3fCx9ZttYtvlDcVtgb+NQ6t9s6K5No5zutN3pcjZEC2a4iQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.16.9", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.16.9.tgz", + "integrity": "sha512-gIj0UQZlQo93CHYouHKkpzP7AuruSaMIm1etcWIxccFEVqCN1xDr6BWlN9bM+ol/f0W9w3hx3HDuEwcJVtGneQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.16.9", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.16.9.tgz", + "integrity": "sha512-GNors4vaMJ7lzGOuhzNc7jvgsQZqErGA8rsW+nck8N1nYu86CvsJW2seigVrQQWOV4QzEP8Zf3gm+QCjA2hnBQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.16.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.16.9.tgz", + "integrity": "sha512-cNx1EF99c2t1Ztn0lk9N+MuwBijGF8mH6nx9GFsB3e0lpUpPkCE/yt5d+7NP9EwJf5uzqdjutgVYoH1SNqzudA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.16.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.16.9.tgz", + "integrity": "sha512-YPxQunReYp8RQ1FvexFrOEqqf+nLbS3bKVZF5FRT2uKM7Wio7BeATqAwO02AyrdSEntt3I5fhFsujUChIa8CZg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.16.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.16.9.tgz", + "integrity": "sha512-zb12ixDIKNwFpIqR00J88FFitVwOEwO78EiUi8wi8FXlmSc3GtUuKV/BSO+730Kglt0B47+ZrJN1BhhOxZaVrw==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.16.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.16.9.tgz", + "integrity": "sha512-X8te4NLxtHiNT6H+4Pfm5RklzItA1Qy4nfyttihGGX+Koc53Ar20ViC+myY70QJ8PDEOehinXZj/F7QK3A+MKQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.16.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.16.9.tgz", + "integrity": "sha512-ZqyMDLt02c5smoS3enlF54ndK5zK4IpClLTxF0hHfzHJlfm4y8IAkIF8LUW0W7zxcKy7oAwI7BRDqeVvC120SA==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.16.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.16.9.tgz", + "integrity": "sha512-k+ca5W5LDBEF3lfDwMV6YNXwm4wEpw9krMnNvvlNz3MrKSD2Eb2c861O0MaKrZkG/buTQAP4vkavbLwgIe6xjg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.16.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.16.9.tgz", + "integrity": "sha512-GuInVdogjmg9DhgkEmNipHkC+3tzkanPJzgzTC2ihsvrruLyFoR1YrTGixblNSMPudQLpiqkcwGwwe0oqfrvfA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.16.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.16.9.tgz", + "integrity": "sha512-49wQ0aYkvwXonGsxc7LuuLNICMX8XtO92Iqmug5Qau0kpnV6SP34jk+jIeu4suHwAbSbRhVFtDv75yRmyfQcHw==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.16.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.16.9.tgz", + "integrity": "sha512-Nx4oKEAJ6EcQlt4dK7qJyuZUoXZG7CAeY22R7rqZijFzwFfMOD+gLP56uV7RrV86jGf8PeRY8TBsRmOcZoG42w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.16.9", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.16.9.tgz", + "integrity": "sha512-d0WnpgJ+FTiMZXEQ1NOv9+0gvEhttbgKEvVqWWAtl1u9AvlspKXbodKHzQ5MLP6YV1y52Xp+p8FMYqj8ykTahg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.16.9", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.16.9.tgz", + "integrity": "sha512-jccK11278dvEscHFfMk5EIPjF4wv1qGD0vps7mBV1a6TspdR36O28fgPem/SA/0pcsCPHjww5ouCLwP+JNAFlw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.16.9", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.16.9.tgz", + "integrity": "sha512-OetwTSsv6mIDLqN7I7I2oX9MmHGwG+AP+wKIHvq+6sIHwcPPJqRx+DJB55jy9JG13CWcdcQno/7V5MTJ5a0xfQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.16.9", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.16.9.tgz", + "integrity": "sha512-tKSSSK6unhxbGbHg+Cc+JhRzemkcsX0tPBvG0m5qsWbkShDK9c+/LSb13L18LWVdOQZwuA55Vbakxmt6OjBDOQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.16.9", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.16.9.tgz", + "integrity": "sha512-ZTQ5vhNS5gli0KK8I6/s6+LwXmNEfq1ftjnSVyyNm33dBw8zDpstqhGXYUbZSWWLvkqiRRjgxgmoncmi6Yy7Ng==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.16.9", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.16.9.tgz", + "integrity": "sha512-C4ZX+YFIp6+lPrru3tpH6Gaapy8IBRHw/e7l63fzGDhn/EaiGpQgbIlT5paByyy+oMvRFQoxxyvC4LE0AjJMqQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" } }, "node_modules/@eslint/eslintrc": { @@ -1887,105 +885,6 @@ "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", "dev": true }, - "node_modules/@jest/schemas": { - "version": "29.0.0", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.0.0.tgz", - "integrity": "sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA==", - "dev": true, - "dependencies": { - "@sinclair/typebox": "^0.24.1" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/types": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.3.1.tgz", - "integrity": "sha512-d0S0jmmTpjnhCmNpApgX3jrUZgZ22ivKJRvL2lli5hpCRoNnp1f85r2/wpKfXuYu8E7Jjh1hGfhPyup1NM5AmA==", - "dev": true, - "dependencies": { - "@jest/schemas": "^29.0.0", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/types/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@jest/types/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@jest/types/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@jest/types/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/@jest/types/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/types/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/@jridgewell/gen-mapping": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", @@ -2017,30 +916,6 @@ "node": ">=6.0.0" } }, - "node_modules/@jridgewell/source-map": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz", - "integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==", - "dev": true, - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" - } - }, - "node_modules/@jridgewell/source-map/node_modules/@jridgewell/gen-mapping": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", - "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", - "dev": true, - "dependencies": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.4.14", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", @@ -2069,12 +944,6 @@ "react-dom": "16.14.0" } }, - "node_modules/@leichtgewicht/ip-codec": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz", - "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==", - "dev": true - }, "node_modules/@matrix-org/olm": { "version": "3.2.14", "resolved": "https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.14.tgz", @@ -2139,11 +1008,22 @@ "resolved": "https://registry.npmjs.org/@react-dnd/shallowequal/-/shallowequal-3.0.1.tgz", "integrity": "sha512-XjDVbs3ZU16CO1h5Q3Ew2RPJqmZBDE/EVf1LYp6ePEffs3V/MX9ZbL5bJr8qiK5SbGmUMuDoaFgyKacYz8prRA==" }, - "node_modules/@sinclair/typebox": { - "version": "0.24.51", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.51.tgz", - "integrity": "sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA==", - "dev": true + "node_modules/@rollup/plugin-wasm": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-wasm/-/plugin-wasm-6.1.1.tgz", + "integrity": "sha512-dccyb8OvtpY21KiYjaNmibWlQJd/kBg+IVP24x9l1dsIRXBmGqLt+wsPjU296FNO8ap0SSEsTpi/7AfrlvQvBQ==", + "dev": true, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } }, "node_modules/@tippyjs/react": { "version": "4.2.6", @@ -2157,156 +1037,11 @@ "react-dom": ">=16.8" } }, - "node_modules/@trysound/sax": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", - "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", - "dev": true, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/@types/body-parser": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", - "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", - "dev": true, - "dependencies": { - "@types/connect": "*", - "@types/node": "*" - } - }, - "node_modules/@types/bonjour": { - "version": "3.5.10", - "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.10.tgz", - "integrity": "sha512-p7ienRMiS41Nu2/igbJxxLDWrSZ0WxM8UQgCeO9KhoVF7cOVFkrKsiDr1EsJIla8vV3oEEjGcz11jc5yimhzZw==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/connect": { - "version": "3.4.35", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", - "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/connect-history-api-fallback": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.3.5.tgz", - "integrity": "sha512-h8QJa8xSb1WD4fpKBDcATDNGXghFj6/3GRWG6dhmRcu0RX1Ubasur2Uvx5aeEwlf0MwblEC2bMzzMQntxnw/Cw==", - "dev": true, - "dependencies": { - "@types/express-serve-static-core": "*", - "@types/node": "*" - } - }, - "node_modules/@types/eslint": { - "version": "8.4.10", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.10.tgz", - "integrity": "sha512-Sl/HOqN8NKPmhWo2VBEPm0nvHnu2LL3v9vKo8MEq0EtbJ4eVzGPl41VNPvn5E1i5poMk4/XD8UriLHpJvEP/Nw==", - "dev": true, - "dependencies": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "node_modules/@types/eslint-scope": { - "version": "3.7.4", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.4.tgz", - "integrity": "sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==", - "dev": true, - "dependencies": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, - "node_modules/@types/estree": { - "version": "0.0.51", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.51.tgz", - "integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==", - "dev": true - }, "node_modules/@types/events": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==" }, - "node_modules/@types/express": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.15.tgz", - "integrity": "sha512-Yv0k4bXGOH+8a+7bELd2PqHQsuiANB+A8a4gnQrkRWzrkKlb6KHaVvyXhqs04sVW/OWlbPyYxRgYlIXLfrufMQ==", - "dev": true, - "dependencies": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.31", - "@types/qs": "*", - "@types/serve-static": "*" - } - }, - "node_modules/@types/express-serve-static-core": { - "version": "4.17.31", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.31.tgz", - "integrity": "sha512-DxMhY+NAsTwMMFHBTtJFNp5qiHKJ7TeqOo23zVEM9alT1Ml27Q3xcTH0xwxn7Q0BbMcVEJOs/7aQtUWupUQN3Q==", - "dev": true, - "dependencies": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*" - } - }, - "node_modules/@types/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", - "dev": true, - "dependencies": { - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "node_modules/@types/html-minifier-terser": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", - "integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==", - "dev": true - }, - "node_modules/@types/http-proxy": { - "version": "1.17.9", - "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.9.tgz", - "integrity": "sha512-QsbSjA/fSk7xB+UXlCT3wHBy5ai9wOcNDWwZAtud+jXhwOM3l+EYZh8Lng4+/6n8uar0J7xILzqftJdJ/Wdfkw==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/istanbul-lib-coverage": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", - "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", - "dev": true - }, - "node_modules/@types/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "*" - } - }, - "node_modules/@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, "node_modules/@types/json-schema": { "version": "7.0.11", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", @@ -2319,41 +1054,11 @@ "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", "dev": true }, - "node_modules/@types/mime": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz", - "integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==", - "dev": true - }, - "node_modules/@types/minimatch": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", - "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", - "dev": true - }, - "node_modules/@types/node": { - "version": "18.11.15", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.15.tgz", - "integrity": "sha512-VkhBbVo2+2oozlkdHXLrb3zjsRkpdnaU2bXmX8Wgle3PUi569eLRaHGlgETQHR7lLL1w7GiG3h9SnePhxNDecw==", - "dev": true - }, "node_modules/@types/prop-types": { "version": "15.7.5", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==" }, - "node_modules/@types/qs": { - "version": "6.9.7", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", - "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", - "dev": true - }, - "node_modules/@types/range-parser": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", - "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==", - "dev": true - }, "node_modules/@types/react": { "version": "18.0.26", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.26.tgz", @@ -2364,6 +1069,15 @@ "csstype": "^3.0.2" } }, + "node_modules/@types/react-dom": { + "version": "18.0.9", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.0.9.tgz", + "integrity": "sha512-qnVvHxASt/H7i+XG1U1xMiY5t+IHcPGUK7TDMDzom08xa7e86eCeKOiLZezwCKVxJn6NEiiy2ekgX8aQssjIKg==", + "dev": true, + "dependencies": { + "@types/react": "*" + } + }, "node_modules/@types/retry": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", @@ -2379,289 +1093,283 @@ "resolved": "https://registry.npmjs.org/@types/sdp-transform/-/sdp-transform-2.4.5.tgz", "integrity": "sha512-GVO0gnmbyO3Oxm2HdPsYUNcyihZE3GyCY8ysMYHuQGfLhGZq89Nm4lSzULWTzZoyHtg+VO/IdrnxZHPnPSGnAg==" }, - "node_modules/@types/serve-index": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.1.tgz", - "integrity": "sha512-d/Hs3nWDxNL2xAczmOVZNj92YZCS6RGxfBPjKzuu/XirCgXdpKEb88dYNbrYGint6IVWLNP+yonwVAuRC0T2Dg==", - "dev": true, - "dependencies": { - "@types/express": "*" - } - }, - "node_modules/@types/serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-z5xyF6uh8CbjAu9760KDKsH2FcDxZ2tFCsA4HIMWE6IkiYMXfVoa+4f9KX+FN0ZLsaMw1WNG2ETLA6N+/YA+cg==", - "dev": true, - "dependencies": { - "@types/mime": "*", - "@types/node": "*" - } - }, - "node_modules/@types/sockjs": { - "version": "0.3.33", - "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.33.tgz", - "integrity": "sha512-f0KEEe05NvUnat+boPTZ0dgaLZ4SfSouXUgv5noUiefG2ajgKjmETo9ZJyuqsl7dfl2aHlLJUiki6B4ZYldiiw==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/ws": { - "version": "8.5.3", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.3.tgz", - "integrity": "sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/yargs": { - "version": "17.0.17", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.17.tgz", - "integrity": "sha512-72bWxFKTK6uwWJAVT+3rF6Jo6RTojiJ27FQo8Rf60AL+VZbzoVPnMFhKsUnbjR8A3BTCYQ7Mv3hnl8T0A+CX9g==", - "dev": true, - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/@types/yargs-parser": { - "version": "21.0.0", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz", - "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", + "node_modules/@types/semver": { + "version": "7.3.13", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz", + "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==", "dev": true }, - "node_modules/@webassemblyjs/ast": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz", - "integrity": "sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==", + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "5.46.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.46.1.tgz", + "integrity": "sha512-YpzNv3aayRBwjs4J3oz65eVLXc9xx0PDbIRisHj+dYhvBn02MjYOD96P8YGiWEIFBrojaUjxvkaUpakD82phsA==", "dev": true, "dependencies": { - "@webassemblyjs/helper-numbers": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1" - } - }, - "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz", - "integrity": "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==", - "dev": true - }, - "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz", - "integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==", - "dev": true - }, - "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz", - "integrity": "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==", - "dev": true - }, - "node_modules/@webassemblyjs/helper-numbers": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz", - "integrity": "sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==", - "dev": true, - "dependencies": { - "@webassemblyjs/floating-point-hex-parser": "1.11.1", - "@webassemblyjs/helper-api-error": "1.11.1", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz", - "integrity": "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==", - "dev": true - }, - "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz", - "integrity": "sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1" - } - }, - "node_modules/@webassemblyjs/ieee754": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz", - "integrity": "sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==", - "dev": true, - "dependencies": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "node_modules/@webassemblyjs/leb128": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz", - "integrity": "sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==", - "dev": true, - "dependencies": { - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/utf8": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz", - "integrity": "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==", - "dev": true - }, - "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz", - "integrity": "sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/helper-wasm-section": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1", - "@webassemblyjs/wasm-opt": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1", - "@webassemblyjs/wast-printer": "1.11.1" - } - }, - "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz", - "integrity": "sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/ieee754": "1.11.1", - "@webassemblyjs/leb128": "1.11.1", - "@webassemblyjs/utf8": "1.11.1" - } - }, - "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz", - "integrity": "sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1" - } - }, - "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz", - "integrity": "sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-api-error": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/ieee754": "1.11.1", - "@webassemblyjs/leb128": "1.11.1", - "@webassemblyjs/utf8": "1.11.1" - } - }, - "node_modules/@webassemblyjs/wast-printer": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz", - "integrity": "sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webpack-cli/configtest": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.0.1.tgz", - "integrity": "sha512-njsdJXJSiS2iNbQVS0eT8A/KPnmyH4pv1APj2K0d1wrZcBLw+yppxOy4CGqa0OxDJkzfL/XELDhD8rocnIwB5A==", - "dev": true, + "@typescript-eslint/scope-manager": "5.46.1", + "@typescript-eslint/type-utils": "5.46.1", + "@typescript-eslint/utils": "5.46.1", + "debug": "^4.3.4", + "ignore": "^5.2.0", + "natural-compare-lite": "^1.4.0", + "regexpp": "^3.2.0", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, "engines": { - "node": ">=14.15.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "webpack": "5.x.x", - "webpack-cli": "5.x.x" - } - }, - "node_modules/@webpack-cli/info": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.1.tgz", - "integrity": "sha512-fE1UEWTwsAxRhrJNikE7v4EotYflkEhBL7EbajfkPlf6E37/2QshOy/D48Mw8G5XMFlQtS6YV42vtbG9zBpIQA==", - "dev": true, - "engines": { - "node": ">=14.15.0" - }, - "peerDependencies": { - "webpack": "5.x.x", - "webpack-cli": "5.x.x" - } - }, - "node_modules/@webpack-cli/serve": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.1.tgz", - "integrity": "sha512-0G7tNyS+yW8TdgHwZKlDWYXFA6OJQnoLCQvYKkQP0Q2X205PSQ6RNUj0M+1OB/9gRQaUZ/ccYfaxd0nhaWKfjw==", - "dev": true, - "engines": { - "node": ">=14.15.0" - }, - "peerDependencies": { - "webpack": "5.x.x", - "webpack-cli": "5.x.x" + "@typescript-eslint/parser": "^5.0.0", + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" }, "peerDependenciesMeta": { - "webpack-dev-server": { + "typescript": { "optional": true } } }, - "node_modules/@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true - }, - "node_modules/@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", - "dev": true - }, - "node_modules/abstract-leveldown": { - "version": "0.12.4", - "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-0.12.4.tgz", - "integrity": "sha512-TOod9d5RDExo6STLMGa+04HGkl+TlMfbDnTyN93/ETJ9DpQ0DaYLqcMZlbXvdc4W3vVo1Qrl+WhSp8zvDsJ+jA==", + "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dev": true, "dependencies": { - "xtend": "~3.0.0" - } - }, - "node_modules/abstract-leveldown/node_modules/xtend": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-3.0.0.tgz", - "integrity": "sha512-sp/sT9OALMjRW1fKDlPeuSZlDQpkqReA0pyJukniWbTGoEKefHxhGJynE3PNhUMlcM8qWIjPwecwCw4LArS5Eg==", - "dev": true, - "engines": { - "node": ">=0.4" - } - }, - "node_modules/accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "dev": true, - "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" }, "engines": { - "node": ">= 0.6" + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "5.46.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.46.1.tgz", + "integrity": "sha512-RelQ5cGypPh4ySAtfIMBzBGyrNerQcmfA1oJvPj5f+H4jI59rl9xxpn4bonC0tQvUKOEN7eGBFWxFLK3Xepneg==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "5.46.1", + "@typescript-eslint/types": "5.46.1", + "@typescript-eslint/typescript-estree": "5.46.1", + "debug": "^4.3.4" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "5.46.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.46.1.tgz", + "integrity": "sha512-iOChVivo4jpwUdrJZyXSMrEIM/PvsbbDOX1y3UCKjSgWn+W89skxWaYXACQfxmIGhPVpRWK/VWPYc+bad6smIA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.46.1", + "@typescript-eslint/visitor-keys": "5.46.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "5.46.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.46.1.tgz", + "integrity": "sha512-V/zMyfI+jDmL1ADxfDxjZ0EMbtiVqj8LUGPAGyBkXXStWmCUErMpW873zEHsyguWCuq2iN4BrlWUkmuVj84yng==", + "dev": true, + "dependencies": { + "@typescript-eslint/typescript-estree": "5.46.1", + "@typescript-eslint/utils": "5.46.1", + "debug": "^4.3.4", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "5.46.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.46.1.tgz", + "integrity": "sha512-Z5pvlCaZgU+93ryiYUwGwLl9AQVB/PQ1TsJ9NZ/gHzZjN7g9IAn6RSDkpCV8hqTwAiaj6fmCcKSQeBPlIpW28w==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "5.46.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.46.1.tgz", + "integrity": "sha512-j9W4t67QiNp90kh5Nbr1w92wzt+toiIsaVPnEblB2Ih2U9fqBTyqV9T3pYWZBRt6QoMh/zVWP59EpuCjc4VRBg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.46.1", + "@typescript-eslint/visitor-keys": "5.46.1", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "5.46.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.46.1.tgz", + "integrity": "sha512-RBdBAGv3oEpFojaCYT4Ghn4775pdjvwfDOfQ2P6qzNVgQOVrnSPe5/Pb88kv7xzYQjoio0eKHKB9GJ16ieSxvA==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "@types/semver": "^7.3.12", + "@typescript-eslint/scope-manager": "5.46.1", + "@typescript-eslint/types": "5.46.1", + "@typescript-eslint/typescript-estree": "5.46.1", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0", + "semver": "^7.3.7" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "5.46.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.46.1.tgz", + "integrity": "sha512-jczZ9noovXwy59KjRTk1OftT78pwygdcmCuBf8yMoWt/8O8l+6x2LSEze0E4TeepXK4MezW3zGSyoDRZK7Y9cg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.46.1", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@vitejs/plugin-react": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-3.0.0.tgz", + "integrity": "sha512-1mvyPc0xYW5G8CHQvJIJXLoMjl5Ct3q2g5Y2s6Ccfgwm45y48LBvsla7az+GkkAtYikWQ4Lxqcsq5RHLcZgtNQ==", + "dev": true, + "dependencies": { + "@babel/core": "^7.20.5", + "@babel/plugin-transform-react-jsx-self": "^7.18.6", + "@babel/plugin-transform-react-jsx-source": "^7.19.6", + "magic-string": "^0.27.0", + "react-refresh": "^0.14.0" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "vite": "^4.0.0" } }, "node_modules/acorn": { @@ -2676,15 +1384,6 @@ "node": ">=0.4.0" } }, - "node_modules/acorn-import-assertions": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz", - "integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==", - "dev": true, - "peerDependencies": { - "acorn": "^8" - } - }, "node_modules/acorn-jsx": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", @@ -2710,71 +1409,11 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/ajv-formats": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", - "dev": true, - "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } - } - }, - "node_modules/ajv-formats/node_modules/ajv": { - "version": "8.11.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.2.tgz", - "integrity": "sha512-E4bfmKAhGiSTvMfL1Myyycaub+cUEU2/IvpylXkUu7CHBkBj1f/ikdzbD7YQ6FKUbixDxeYvB/xY4fvyroDlQg==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ajv-formats/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, - "node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "dev": true, - "peerDependencies": { - "ajv": "^6.9.1" - } - }, "node_modules/another-json": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/another-json/-/another-json-0.2.0.tgz", "integrity": "sha512-/Ndrl68UQLhnCdsAzEXLMFuOR546o2qbYRqCglaNHbjXrwG1ayTcdwr3zkSGOGtGXDyR5X9nCFfnyG2AFJIsqg==" }, - "node_modules/ansi-html-community": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", - "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", - "dev": true, - "engines": [ - "node >= 0.8.0" - ], - "bin": { - "ansi-html": "bin/ansi-html" - } - }, "node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", @@ -2828,12 +1467,6 @@ "node": ">=6.0" } }, - "node_modules/array-flatten": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", - "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==", - "dev": true - }, "node_modules/array-includes": { "version": "3.1.6", "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.6.tgz", @@ -2854,24 +1487,12 @@ } }, "node_modules/array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==", - "dev": true, - "dependencies": { - "array-uniq": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, "node_modules/array.prototype.flat": { @@ -2928,36 +1549,6 @@ "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" }, - "node_modules/asn1.js": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", - "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", - "dev": true, - "dependencies": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "safer-buffer": "^2.1.0" - } - }, - "node_modules/asn1.js/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, - "node_modules/assert": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/assert/-/assert-2.0.0.tgz", - "integrity": "sha512-se5Cd+js9dXJnu6Ag2JFc00t+HmHOen+8Q+L7O9zI0PqQXr20uk2J0XQqMxZEeo5U50o8Nvmmx7dZrl+Ufr35A==", - "dev": true, - "dependencies": { - "es6-object-assign": "^1.1.0", - "is-nan": "^1.2.1", - "object-is": "^1.0.1", - "util": "^0.12.0" - } - }, "node_modules/ast-types-flow": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", @@ -2969,18 +1560,6 @@ "resolved": "https://registry.npmjs.org/autosize/-/autosize-4.0.4.tgz", "integrity": "sha512-5yxLQ22O0fCRGoxGfeLSNt3J8LB1v+umtpMnPW6XjkTWXKoN0AmXAIhelJcDtFT/Y/wYWmfE+oqU10Q0b8FhaQ==" }, - "node_modules/available-typed-arrays": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/axe-core": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.6.0.tgz", @@ -2996,88 +1575,6 @@ "integrity": "sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA==", "dev": true }, - "node_modules/babel-loader": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.3.0.tgz", - "integrity": "sha512-H8SvsMF+m9t15HNLMipppzkC+Y2Yq+v3SonZyU70RBL/h1gxPkH08Ot8pEE9Z4Kd+czyWJClmFS8qzIP9OZ04Q==", - "dev": true, - "dependencies": { - "find-cache-dir": "^3.3.1", - "loader-utils": "^2.0.0", - "make-dir": "^3.1.0", - "schema-utils": "^2.6.5" - }, - "engines": { - "node": ">= 8.9" - }, - "peerDependencies": { - "@babel/core": "^7.0.0", - "webpack": ">=2" - } - }, - "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz", - "integrity": "sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q==", - "dev": true, - "dependencies": { - "@babel/compat-data": "^7.17.7", - "@babel/helper-define-polyfill-provider": "^0.3.3", - "semver": "^6.1.1" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.6.0.tgz", - "integrity": "sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA==", - "dev": true, - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.3.3", - "core-js-compat": "^3.25.1" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.1.tgz", - "integrity": "sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw==", - "dev": true, - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.3.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/babel-polyfill": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.26.0.tgz", - "integrity": "sha512-F2rZGQnAdaHWQ8YAoeRbukc7HS9QgdgeyJ0rQDd485v9opwuPvjpPFcOOT/WmkKTdgy9ESgSPXDcTNpzrGr6iQ==", - "dependencies": { - "babel-runtime": "^6.26.0", - "core-js": "^2.5.0", - "regenerator-runtime": "^0.10.5" - } - }, - "node_modules/babel-runtime": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g==", - "dependencies": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" - } - }, - "node_modules/babel-runtime/node_modules/regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" - }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -3089,41 +1586,6 @@ "resolved": "https://registry.npmjs.org/base-x/-/base-x-4.0.0.tgz", "integrity": "sha512-FuwxlW4H5kh37X/oW59pwTzzTKRzfrrQwhmyspRM7swOEZcHtDZSCt45U6oKgtuFE+WYPblePMVIPR4RZrh/hw==" }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/batch": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", - "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", - "dev": true - }, - "node_modules/big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "dev": true, - "engines": { - "node": "*" - } - }, "node_modules/binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", @@ -3133,110 +1595,11 @@ "node": ">=8" } }, - "node_modules/bl": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/bl/-/bl-0.8.2.tgz", - "integrity": "sha512-pfqikmByp+lifZCS0p6j6KreV6kNU6Apzpm2nKOk+94cZb/jvle55+JxWiByUQ0Wo/+XnDXEy5MxxKMb6r0VIw==", - "dev": true, - "dependencies": { - "readable-stream": "~1.0.26" - } - }, - "node_modules/bl/node_modules/readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==", - "dev": true, - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "node_modules/bl/node_modules/string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", - "dev": true - }, "node_modules/blurhash": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/blurhash/-/blurhash-2.0.4.tgz", "integrity": "sha512-r/As72u2FbucLoK5NTegM/GucxJc3d8GvHc4ngo13IO/nt2HU4gONxNLq1XPN6EM/V8Y9URIa7PcSz2RZu553A==" }, - "node_modules/bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true - }, - "node_modules/body-parser": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", - "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", - "dev": true, - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.1", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/body-parser/node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/body-parser/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/body-parser/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/bonjour-service": { - "version": "1.0.14", - "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.0.14.tgz", - "integrity": "sha512-HIMbgLnk1Vqvs6B4Wq5ep7mxvj9sGz5d1JJyDNSGNIdA/w2MCz6GTjWTdjqOJV1bEPj+6IkxDvWNFKEBxNt4kQ==", - "dev": true, - "dependencies": { - "array-flatten": "^2.1.2", - "dns-equal": "^1.0.0", - "fast-deep-equal": "^3.1.3", - "multicast-dns": "^7.2.5" - } - }, - "node_modules/boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", - "dev": true - }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -3259,92 +1622,11 @@ "node": ">=8" } }, - "node_modules/brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==", - "dev": true - }, "node_modules/browser-encrypt-attachment": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/browser-encrypt-attachment/-/browser-encrypt-attachment-0.3.0.tgz", "integrity": "sha512-L7siI766UCH6+arP9yT5wpA5AFxnmGbKiGSsxEVACl1tE0pvDJeQvMmbY2UmJiuffrr0ZJ2+U6Om46wQBqh1Lw==" }, - "node_modules/browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dev": true, - "dependencies": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "dev": true, - "dependencies": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "node_modules/browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "dev": true, - "dependencies": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/browserify-fs": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/browserify-fs/-/browserify-fs-1.0.0.tgz", - "integrity": "sha512-8LqHRPuAEKvyTX34R6tsw4bO2ro6j9DmlYBhiYWHRM26Zv2cBw1fJOU0NeUQ0RkXkPn/PFBjhA0dm4AgaBurTg==", - "dev": true, - "dependencies": { - "level-filesystem": "^1.0.1", - "level-js": "^2.1.3", - "levelup": "^0.18.2" - } - }, - "node_modules/browserify-rsa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", - "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", - "dev": true, - "dependencies": { - "bn.js": "^5.0.0", - "randombytes": "^2.0.1" - } - }, - "node_modules/browserify-sign": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", - "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", - "dev": true, - "dependencies": { - "bn.js": "^5.1.1", - "browserify-rsa": "^4.0.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.3", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.5", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - } - }, "node_modules/browserslist": { "version": "4.21.4", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", @@ -3381,51 +1663,6 @@ "base-x": "^4.0.0" } }, - "node_modules/buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "node_modules/buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==", - "dev": true - }, - "node_modules/bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/call-bind": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", @@ -3447,34 +1684,6 @@ "node": ">=6" } }, - "node_modules/camel-case": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", - "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", - "dev": true, - "dependencies": { - "pascal-case": "^3.1.2", - "tslib": "^2.0.3" - } - }, - "node_modules/camel-case/node_modules/tslib": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", - "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==", - "dev": true - }, - "node_modules/caniuse-api": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", - "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", - "dev": true, - "dependencies": { - "browserslist": "^4.0.0", - "caniuse-lite": "^1.0.0", - "lodash.memoize": "^4.1.2", - "lodash.uniq": "^4.5.0" - } - }, "node_modules/caniuse-lite": { "version": "1.0.30001439", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001439.tgz", @@ -3544,96 +1753,6 @@ "node": ">= 6" } }, - "node_modules/chrome-trace-event": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", - "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", - "dev": true, - "engines": { - "node": ">=6.0" - } - }, - "node_modules/ci-info": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.7.0.tgz", - "integrity": "sha512-2CpRNYmImPx+RXKLq6jko/L07phmS9I02TyqkcNU20GCF/GgaWvc58hPtjxDX8lPpkdwc9sNh72V9k00S7ezog==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dev": true, - "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/clean-css": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.2.0.tgz", - "integrity": "sha512-2639sWGa43EMmG7fn8mdVuBSs6HuWaSor+ZPoFWzenBc6oN+td8YhTfghWXZ25G1NiiSvz8bOFBS7PdSbTiqEA==", - "dev": true, - "dependencies": { - "source-map": "~0.6.0" - }, - "engines": { - "node": ">= 10.0" - } - }, - "node_modules/clean-webpack-plugin": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/clean-webpack-plugin/-/clean-webpack-plugin-4.0.0.tgz", - "integrity": "sha512-WuWE1nyTNAyW5T7oNyys2EN0cfP2fdRxhxnIQWiAp0bMabPdHhoGxM8A6YL2GhqwgrPnnaemVE7nv5XJ2Fhh2w==", - "dev": true, - "dependencies": { - "del": "^4.1.1" - }, - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "webpack": ">=4.0.0 <6.0.0" - } - }, - "node_modules/clone": { - "version": "0.1.19", - "resolved": "https://registry.npmjs.org/clone/-/clone-0.1.19.tgz", - "integrity": "sha512-IO78I0y6JcSpEPHzK4obKdsL7E7oLdRVDVOLwr2Hkbjsb+Eoz0dxW6tef0WizoKu0gLC4oZSZuEF4U2K6w1WQw==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/clone-deep": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", - "dev": true, - "dependencies": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/clone-deep/node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -3649,84 +1768,6 @@ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "dev": true }, - "node_modules/colord": { - "version": "2.9.3", - "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", - "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==", - "dev": true - }, - "node_modules/colorette": { - "version": "2.0.19", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz", - "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==", - "dev": true - }, - "node_modules/commander": { - "version": "9.4.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-9.4.1.tgz", - "integrity": "sha512-5EEkTNyHNGFPD2H+c/dXXfQZYa/scCKasxWcXJaWnNJ99pnQN9Vnmqow+p+PlFPE63Q6mThaZws1T+HxfpgtPw==", - "dev": true, - "engines": { - "node": "^12.20.0 || >=14" - } - }, - "node_modules/commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", - "dev": true - }, - "node_modules/compressible": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", - "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", - "dev": true, - "dependencies": { - "mime-db": ">= 1.43.0 < 2" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/compression": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", - "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", - "dev": true, - "dependencies": { - "accepts": "~1.3.5", - "bytes": "3.0.0", - "compressible": "~2.0.16", - "debug": "2.6.9", - "on-headers": "~1.0.2", - "safe-buffer": "5.1.2", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/compression/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/compression/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/compression/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, "node_modules/computed-style": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/computed-style/-/computed-style-0.1.4.tgz", @@ -3738,84 +1779,12 @@ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, - "node_modules/concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "engines": [ - "node >= 0.8" - ], - "dependencies": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "node_modules/concat-stream/node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true - }, - "node_modules/concat-stream/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/concat-stream/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "node_modules/concat-stream/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, "node_modules/confusing-browser-globals": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz", "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==", "dev": true }, - "node_modules/connect-history-api-fallback": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", - "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==", - "dev": true, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "dev": true, - "dependencies": { - "safe-buffer": "5.2.1" - }, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/content-type": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", @@ -3830,118 +1799,6 @@ "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", "dev": true }, - "node_modules/cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", - "dev": true - }, - "node_modules/copy-webpack-plugin": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-11.0.0.tgz", - "integrity": "sha512-fX2MWpamkW0hZxMEg0+mYnA40LTosOSa5TqZ9GYIBzyJa9C3QUaMPSE2xAi/buNr8u89SfD9wHSQVBzrRa/SOQ==", - "dev": true, - "dependencies": { - "fast-glob": "^3.2.11", - "glob-parent": "^6.0.1", - "globby": "^13.1.1", - "normalize-path": "^3.0.0", - "schema-utils": "^4.0.0", - "serialize-javascript": "^6.0.0" - }, - "engines": { - "node": ">= 14.15.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.1.0" - } - }, - "node_modules/copy-webpack-plugin/node_modules/ajv": { - "version": "8.11.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.2.tgz", - "integrity": "sha512-E4bfmKAhGiSTvMfL1Myyycaub+cUEU2/IvpylXkUu7CHBkBj1f/ikdzbD7YQ6FKUbixDxeYvB/xY4fvyroDlQg==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/copy-webpack-plugin/node_modules/ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" - } - }, - "node_modules/copy-webpack-plugin/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, - "node_modules/copy-webpack-plugin/node_modules/schema-utils": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", - "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==", - "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.8.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.0.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/core-js": { - "version": "2.6.12", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz", - "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==", - "deprecated": "core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js.", - "hasInstallScript": true - }, - "node_modules/core-js-compat": { - "version": "3.26.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.26.1.tgz", - "integrity": "sha512-622/KzTudvXCDLRw70iHW4KKs1aGpcRcowGWyYJr2DEBfRrd6hNJybxSWJFuZYD4ma86xhrwDDHxmDaIq4EA8A==", - "dev": true, - "dependencies": { - "browserslist": "^4.21.4" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, "node_modules/core-js-pure": { "version": "3.26.1", "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.26.1.tgz", @@ -3953,55 +1810,6 @@ "url": "https://opencollective.com/core-js" } }, - "node_modules/core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true - }, - "node_modules/create-ecdh": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", - "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", - "dev": true, - "dependencies": { - "bn.js": "^4.1.0", - "elliptic": "^6.5.3" - } - }, - "node_modules/create-ecdh/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, - "node_modules/create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dev": true, - "dependencies": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "node_modules/create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dev": true, - "dependencies": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, "node_modules/cross-fetch": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz", @@ -4024,371 +1832,6 @@ "node": ">= 8" } }, - "node_modules/crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "dev": true, - "dependencies": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - }, - "engines": { - "node": "*" - } - }, - "node_modules/css-declaration-sorter": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.3.1.tgz", - "integrity": "sha512-fBffmak0bPAnyqc/HO8C3n2sHrp9wcqQz6ES9koRF2/mLOVAx9zIQ3Y7R29sYCteTPqMCwns4WYQoCX91Xl3+w==", - "dev": true, - "engines": { - "node": "^10 || ^12 || >=14" - }, - "peerDependencies": { - "postcss": "^8.0.9" - } - }, - "node_modules/css-loader": { - "version": "6.7.2", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.7.2.tgz", - "integrity": "sha512-oqGbbVcBJkm8QwmnNzrFrWTnudnRZC+1eXikLJl0n4ljcfotgRifpg2a1lKy8jTrc4/d9A/ap1GFq1jDKG7J+Q==", - "dev": true, - "dependencies": { - "icss-utils": "^5.1.0", - "postcss": "^8.4.18", - "postcss-modules-extract-imports": "^3.0.0", - "postcss-modules-local-by-default": "^4.0.0", - "postcss-modules-scope": "^3.0.0", - "postcss-modules-values": "^4.0.0", - "postcss-value-parser": "^4.2.0", - "semver": "^7.3.8" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.0.0" - } - }, - "node_modules/css-loader/node_modules/semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/css-minimizer-webpack-plugin": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-4.2.2.tgz", - "integrity": "sha512-s3Of/4jKfw1Hj9CxEO1E5oXhQAxlayuHO2y/ML+C6I9sQ7FdzfEV6QgMLN3vI+qFsjJGIAFLKtQK7t8BOXAIyA==", - "dev": true, - "dependencies": { - "cssnano": "^5.1.8", - "jest-worker": "^29.1.2", - "postcss": "^8.4.17", - "schema-utils": "^4.0.0", - "serialize-javascript": "^6.0.0", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">= 14.15.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.0.0" - }, - "peerDependenciesMeta": { - "@parcel/css": { - "optional": true - }, - "@swc/css": { - "optional": true - }, - "clean-css": { - "optional": true - }, - "csso": { - "optional": true - }, - "esbuild": { - "optional": true - }, - "lightningcss": { - "optional": true - } - } - }, - "node_modules/css-minimizer-webpack-plugin/node_modules/ajv": { - "version": "8.11.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.2.tgz", - "integrity": "sha512-E4bfmKAhGiSTvMfL1Myyycaub+cUEU2/IvpylXkUu7CHBkBj1f/ikdzbD7YQ6FKUbixDxeYvB/xY4fvyroDlQg==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/css-minimizer-webpack-plugin/node_modules/ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" - } - }, - "node_modules/css-minimizer-webpack-plugin/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, - "node_modules/css-minimizer-webpack-plugin/node_modules/schema-utils": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", - "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==", - "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.8.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.0.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/css-select": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", - "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", - "dev": true, - "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^6.0.1", - "domhandler": "^4.3.1", - "domutils": "^2.8.0", - "nth-check": "^2.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/css-select/node_modules/dom-serializer": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", - "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", - "dev": true, - "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.0", - "entities": "^2.0.0" - }, - "funding": { - "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" - } - }, - "node_modules/css-select/node_modules/domhandler": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", - "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", - "dev": true, - "dependencies": { - "domelementtype": "^2.2.0" - }, - "engines": { - "node": ">= 4" - }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" - } - }, - "node_modules/css-select/node_modules/domutils": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", - "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", - "dev": true, - "dependencies": { - "dom-serializer": "^1.0.1", - "domelementtype": "^2.2.0", - "domhandler": "^4.2.0" - }, - "funding": { - "url": "https://github.com/fb55/domutils?sponsor=1" - } - }, - "node_modules/css-select/node_modules/entities": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", - "dev": true, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/css-tree": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", - "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", - "dev": true, - "dependencies": { - "mdn-data": "2.0.14", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/css-what": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", - "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", - "dev": true, - "engines": { - "node": ">= 6" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/cssesc": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", - "dev": true, - "bin": { - "cssesc": "bin/cssesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/cssnano": { - "version": "5.1.14", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.1.14.tgz", - "integrity": "sha512-Oou7ihiTocbKqi0J1bB+TRJIQX5RMR3JghA8hcWSw9mjBLQ5Y3RWqEDoYG3sRNlAbCIXpqMoZGbq5KDR3vdzgw==", - "dev": true, - "dependencies": { - "cssnano-preset-default": "^5.2.13", - "lilconfig": "^2.0.3", - "yaml": "^1.10.2" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/cssnano" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/cssnano-preset-default": { - "version": "5.2.13", - "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.2.13.tgz", - "integrity": "sha512-PX7sQ4Pb+UtOWuz8A1d+Rbi+WimBIxJTRyBdgGp1J75VU0r/HFQeLnMYgHiCAp6AR4rqrc7Y4R+1Rjk3KJz6DQ==", - "dev": true, - "dependencies": { - "css-declaration-sorter": "^6.3.1", - "cssnano-utils": "^3.1.0", - "postcss-calc": "^8.2.3", - "postcss-colormin": "^5.3.0", - "postcss-convert-values": "^5.1.3", - "postcss-discard-comments": "^5.1.2", - "postcss-discard-duplicates": "^5.1.0", - "postcss-discard-empty": "^5.1.1", - "postcss-discard-overridden": "^5.1.0", - "postcss-merge-longhand": "^5.1.7", - "postcss-merge-rules": "^5.1.3", - "postcss-minify-font-values": "^5.1.0", - "postcss-minify-gradients": "^5.1.1", - "postcss-minify-params": "^5.1.4", - "postcss-minify-selectors": "^5.2.1", - "postcss-normalize-charset": "^5.1.0", - "postcss-normalize-display-values": "^5.1.0", - "postcss-normalize-positions": "^5.1.1", - "postcss-normalize-repeat-style": "^5.1.1", - "postcss-normalize-string": "^5.1.0", - "postcss-normalize-timing-functions": "^5.1.0", - "postcss-normalize-unicode": "^5.1.1", - "postcss-normalize-url": "^5.1.0", - "postcss-normalize-whitespace": "^5.1.1", - "postcss-ordered-values": "^5.1.3", - "postcss-reduce-initial": "^5.1.1", - "postcss-reduce-transforms": "^5.1.0", - "postcss-svgo": "^5.1.0", - "postcss-unique-selectors": "^5.1.1" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/cssnano-utils": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-3.1.0.tgz", - "integrity": "sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==", - "dev": true, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/csso": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", - "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", - "dev": true, - "dependencies": { - "css-tree": "^1.1.2" - }, - "engines": { - "node": ">=8.0.0" - } - }, "node_modules/csstype": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz", @@ -4439,36 +1882,6 @@ "node": ">=0.10.0" } }, - "node_modules/default-gateway": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", - "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", - "dev": true, - "dependencies": { - "execa": "^5.0.0" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/deferred-leveldown": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-0.2.0.tgz", - "integrity": "sha512-+WCbb4+ez/SZ77Sdy1iadagFiVzMB89IKOBhglgnUkVxOxRWmmFsz8UDSNWh4Rhq+3wr/vMFlYj+rdEwWUDdng==", - "dev": true, - "dependencies": { - "abstract-leveldown": "~0.12.1" - } - }, - "node_modules/define-lazy-prop": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", - "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/define-properties": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", @@ -4485,101 +1898,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/del": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz", - "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==", - "dev": true, - "dependencies": { - "@types/glob": "^7.1.1", - "globby": "^6.1.0", - "is-path-cwd": "^2.0.0", - "is-path-in-cwd": "^2.0.0", - "p-map": "^2.0.0", - "pify": "^4.0.1", - "rimraf": "^2.6.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/del/node_modules/globby": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", - "integrity": "sha512-KVbFv2TQtbzCoxAnfD6JcHZTYCzyliEaaeM/gH8qQdkKr5s0OP9scEgvdcngyk7AVdY6YVW/TJHd+lQ/Df3Daw==", - "dev": true, - "dependencies": { - "array-union": "^1.0.1", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/del/node_modules/globby/node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/des.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", - "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "node_modules/destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", - "dev": true, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/detect-node": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", - "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", - "dev": true - }, - "node_modules/diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "dev": true, - "dependencies": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - } - }, - "node_modules/diffie-hellman/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -4602,24 +1920,6 @@ "redux": "^4.1.2" } }, - "node_modules/dns-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", - "integrity": "sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg==", - "dev": true - }, - "node_modules/dns-packet": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.4.0.tgz", - "integrity": "sha512-EgqGeaBB8hLiHLZtp/IbaDQTL8pZ0+IvwzSHA6d7VyMDM+B9hgddEMa9xjK5oYnw0ci0JQ6g2XCD7/f6cafU6g==", - "dev": true, - "dependencies": { - "@leichtgewicht/ip-codec": "^2.0.1" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -4632,15 +1932,6 @@ "node": ">=6.0.0" } }, - "node_modules/dom-converter": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", - "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", - "dev": true, - "dependencies": { - "utila": "~0.4" - } - }, "node_modules/dom-serializer": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", @@ -4692,55 +1983,12 @@ "url": "https://github.com/fb55/domutils?sponsor=1" } }, - "node_modules/dot-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", - "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", - "dev": true, - "dependencies": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "node_modules/dot-case/node_modules/tslib": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", - "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==", - "dev": true - }, - "node_modules/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", - "dev": true - }, "node_modules/electron-to-chromium": { "version": "1.4.284", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz", "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==", "dev": true }, - "node_modules/elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", - "dev": true, - "dependencies": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "node_modules/elliptic/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, "node_modules/emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", @@ -4759,37 +2007,6 @@ "emojibase": "*" } }, - "node_modules/emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/enhanced-resolve": { - "version": "5.12.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.12.0.tgz", - "integrity": "sha512-QHTXI/sZQmko1cbDoNAa3mJ5qhWUUNAq3vR0/YiD379fWQrcfuoX1+HW2S0MTt7XmoPLapdaDKUtelUSPic7hQ==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - }, - "engines": { - "node": ">=10.13.0" - } - }, "node_modules/entities": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz", @@ -4801,30 +2018,6 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, - "node_modules/envinfo": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz", - "integrity": "sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==", - "dev": true, - "bin": { - "envinfo": "dist/cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/errno": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", - "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", - "dev": true, - "dependencies": { - "prr": "~1.0.1" - }, - "bin": { - "errno": "cli.js" - } - }, "node_modules/es-abstract": { "version": "1.20.5", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.5.tgz", @@ -4864,12 +2057,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/es-module-lexer": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.9.3.tgz", - "integrity": "sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==", - "dev": true - }, "node_modules/es-shim-unscopables": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", @@ -4896,11 +2083,42 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/es6-object-assign": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/es6-object-assign/-/es6-object-assign-1.1.0.tgz", - "integrity": "sha512-MEl9uirslVwqQU369iHNWZXsI8yaZYGg/D65aOgZkeyFJwHYSxilf7rQzXKI7DdDuBPrBXbfk3sl9hJhmd5AUw==", - "dev": true + "node_modules/esbuild": { + "version": "0.16.9", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.16.9.tgz", + "integrity": "sha512-gkH83yHyijMSZcZFs1IWew342eMdFuWXmQo3zkDPTre25LIPBJsXryg02M3u8OpTwCJdBkdaQwqKkDLnAsAeLQ==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/android-arm": "0.16.9", + "@esbuild/android-arm64": "0.16.9", + "@esbuild/android-x64": "0.16.9", + "@esbuild/darwin-arm64": "0.16.9", + "@esbuild/darwin-x64": "0.16.9", + "@esbuild/freebsd-arm64": "0.16.9", + "@esbuild/freebsd-x64": "0.16.9", + "@esbuild/linux-arm": "0.16.9", + "@esbuild/linux-arm64": "0.16.9", + "@esbuild/linux-ia32": "0.16.9", + "@esbuild/linux-loong64": "0.16.9", + "@esbuild/linux-mips64el": "0.16.9", + "@esbuild/linux-ppc64": "0.16.9", + "@esbuild/linux-riscv64": "0.16.9", + "@esbuild/linux-s390x": "0.16.9", + "@esbuild/linux-x64": "0.16.9", + "@esbuild/netbsd-x64": "0.16.9", + "@esbuild/openbsd-x64": "0.16.9", + "@esbuild/sunos-x64": "0.16.9", + "@esbuild/win32-arm64": "0.16.9", + "@esbuild/win32-ia32": "0.16.9", + "@esbuild/win32-x64": "0.16.9" + } }, "node_modules/escalade": { "version": "3.1.1", @@ -4911,12 +2129,6 @@ "node": ">=6" } }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", - "dev": true - }, "node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", @@ -5022,6 +2234,18 @@ "eslint-plugin-import": "^2.25.2" } }, + "node_modules/eslint-config-prettier": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz", + "integrity": "sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==", + "dev": true, + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, "node_modules/eslint-import-resolver-node": { "version": "0.3.6", "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", @@ -5423,21 +2647,6 @@ "node": ">=0.10.0" } }, - "node_modules/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", - "dev": true - }, "node_modules/events": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", @@ -5446,107 +2655,11 @@ "node": ">=0.8.x" } }, - "node_modules/evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dev": true, - "dependencies": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "node_modules/execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, "node_modules/exenv": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/exenv/-/exenv-1.2.2.tgz", "integrity": "sha512-Z+ktTxTwv9ILfgKCk32OX3n/doe+OcLTRtqK9pcL+JsP3J1/VW8Uvl4ZjLlKqeW4rzK4oesDOGMEMRIZqtP4Iw==" }, - "node_modules/express": { - "version": "4.18.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", - "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", - "dev": true, - "dependencies": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.1", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.5.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.2.0", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.7", - "qs": "6.11.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/express/node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", - "dev": true - }, - "node_modules/express/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/express/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -5592,15 +2705,6 @@ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, - "node_modules/fastest-levenshtein": { - "version": "1.0.16", - "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", - "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", - "dev": true, - "engines": { - "node": ">= 4.9.1" - } - }, "node_modules/fastq": { "version": "1.14.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.14.0.tgz", @@ -5610,18 +2714,6 @@ "reusify": "^1.0.4" } }, - "node_modules/faye-websocket": { - "version": "0.11.4", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", - "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", - "dev": true, - "dependencies": { - "websocket-driver": ">=0.5.1" - }, - "engines": { - "node": ">=0.8.0" - } - }, "node_modules/fbemitter": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/fbemitter/-/fbemitter-3.0.0.tgz", @@ -5678,56 +2770,6 @@ "node": ">=8" } }, - "node_modules/finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", - "dev": true, - "dependencies": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/finalhandler/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/finalhandler/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/find-cache-dir": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", - "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", - "dev": true, - "dependencies": { - "commondir": "^1.0.1", - "make-dir": "^3.0.2", - "pkg-dir": "^4.1.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/avajs/find-cache-dir?sponsor=1" - } - }, "node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -5790,41 +2832,6 @@ "react": "^15.0.2 || ^16.0.0 || ^17.0.0" } }, - "node_modules/follow-redirects": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", - "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, - "node_modules/for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "dev": true, - "dependencies": { - "is-callable": "^1.1.3" - } - }, - "node_modules/foreach": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.6.tgz", - "integrity": "sha512-k6GAGDyqLe9JaebCsFCoudPPWfihKu8pylYXRlqP1J7ms39iPoTtk2fviNglIeQEwdh0bQeKJ01ZPyuyQvKzwg==", - "dev": true - }, "node_modules/formik": { "version": "2.2.9", "resolved": "https://registry.npmjs.org/formik/-/formik-2.2.9.tgz", @@ -5848,24 +2855,6 @@ "react": ">=16.8.0" } }, - "node_modules/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/fs-extra": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", @@ -5887,12 +2876,6 @@ "graceful-fs": "^4.1.6" } }, - "node_modules/fs-monkey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.3.tgz", - "integrity": "sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q==", - "dev": true - }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -5945,33 +2928,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/fwd-stream": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/fwd-stream/-/fwd-stream-1.0.4.tgz", - "integrity": "sha512-q2qaK2B38W07wfPSQDKMiKOD5Nzv2XyuvQlrmh1q0pxyHNanKHq8lwQ6n9zHucAwA5EbzRJKEgds2orn88rYTg==", - "dev": true, - "dependencies": { - "readable-stream": "~1.0.26-4" - } - }, - "node_modules/fwd-stream/node_modules/readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==", - "dev": true, - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "node_modules/fwd-stream/node_modules/string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", - "dev": true - }, "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -5994,18 +2950,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/get-symbol-description": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", @@ -6054,12 +2998,6 @@ "node": ">=10.13.0" } }, - "node_modules/glob-to-regexp": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", - "dev": true - }, "node_modules/globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", @@ -6070,19 +3008,20 @@ } }, "node_modules/globby": { - "version": "13.1.3", - "resolved": "https://registry.npmjs.org/globby/-/globby-13.1.3.tgz", - "integrity": "sha512-8krCNHXvlCgHDpegPzleMq07yMYTO2sXKASmZmquEYWEmCx6J5UTRbp5RwMJkTJGtcQ44YpiUYUiN0b9mzy8Bw==", + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dev": true, "dependencies": { + "array-union": "^2.1.0", "dir-glob": "^3.0.1", - "fast-glob": "^3.2.11", + "fast-glob": "^3.2.9", "ignore": "^5.2.0", "merge2": "^1.4.1", - "slash": "^4.0.0" + "slash": "^3.0.0" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -6111,12 +3050,6 @@ "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", "dev": true }, - "node_modules/handle-thing": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", - "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", - "dev": true - }, "node_modules/has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -6184,50 +3117,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "node_modules/he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true, - "bin": { - "he": "bin/he" - } - }, - "node_modules/hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", - "dev": true, - "dependencies": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, "node_modules/hoist-non-react-statics": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", @@ -6236,54 +3125,6 @@ "react-is": "^16.7.0" } }, - "node_modules/hpack.js": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", - "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", - "dev": true, - "dependencies": { - "inherits": "^2.0.1", - "obuf": "^1.0.0", - "readable-stream": "^2.0.1", - "wbuf": "^1.1.0" - } - }, - "node_modules/hpack.js/node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true - }, - "node_modules/hpack.js/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/hpack.js/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "node_modules/hpack.js/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, "node_modules/html-dom-parser": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/html-dom-parser/-/html-dom-parser-3.1.2.tgz", @@ -6293,53 +3134,6 @@ "htmlparser2": "8.0.1" } }, - "node_modules/html-entities": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.3.3.tgz", - "integrity": "sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA==", - "dev": true - }, - "node_modules/html-loader": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/html-loader/-/html-loader-4.2.0.tgz", - "integrity": "sha512-OxCHD3yt+qwqng2vvcaPApCEvbx+nXWu+v69TYHx1FO8bffHn/JjHtE3TTQZmHjwvnJe4xxzuecetDVBrQR1Zg==", - "dev": true, - "dependencies": { - "html-minifier-terser": "^7.0.0", - "parse5": "^7.0.0" - }, - "engines": { - "node": ">= 14.15.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.0.0" - } - }, - "node_modules/html-minifier-terser": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-7.1.0.tgz", - "integrity": "sha512-BvPO2S7Ip0Q5qt+Y8j/27Vclj6uHC6av0TMoDn7/bJPhMWHI2UtR2e/zEgJn3/qYAmxumrGp9q4UHurL6mtW9Q==", - "dev": true, - "dependencies": { - "camel-case": "^4.1.2", - "clean-css": "5.2.0", - "commander": "^9.4.1", - "entities": "^4.4.0", - "param-case": "^3.0.4", - "relateurl": "^0.2.7", - "terser": "^5.15.1" - }, - "bin": { - "html-minifier-terser": "cli.js" - }, - "engines": { - "node": "^14.13.1 || >=16.0.0" - } - }, "node_modules/html-react-parser": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/html-react-parser/-/html-react-parser-3.0.4.tgz", @@ -6354,71 +3148,6 @@ "react": "0.14 || 15 || 16 || 17 || 18" } }, - "node_modules/html-webpack-plugin": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.5.0.tgz", - "integrity": "sha512-sy88PC2cRTVxvETRgUHFrL4No3UxvcH8G1NepGhqaTT+GXN2kTamqasot0inS5hXeg1cMbFDt27zzo9p35lZVw==", - "dev": true, - "dependencies": { - "@types/html-minifier-terser": "^6.0.0", - "html-minifier-terser": "^6.0.2", - "lodash": "^4.17.21", - "pretty-error": "^4.0.0", - "tapable": "^2.0.0" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/html-webpack-plugin" - }, - "peerDependencies": { - "webpack": "^5.20.0" - } - }, - "node_modules/html-webpack-plugin/node_modules/clean-css": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.1.tgz", - "integrity": "sha512-lCr8OHhiWCTw4v8POJovCoh4T7I9U11yVsPjMWWnnMmp9ZowCxyad1Pathle/9HjaDp+fdQKjO9fQydE6RHTZg==", - "dev": true, - "dependencies": { - "source-map": "~0.6.0" - }, - "engines": { - "node": ">= 10.0" - } - }, - "node_modules/html-webpack-plugin/node_modules/commander": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", - "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", - "dev": true, - "engines": { - "node": ">= 12" - } - }, - "node_modules/html-webpack-plugin/node_modules/html-minifier-terser": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", - "integrity": "sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==", - "dev": true, - "dependencies": { - "camel-case": "^4.1.2", - "clean-css": "^5.2.2", - "commander": "^8.3.0", - "he": "^1.2.0", - "param-case": "^3.0.4", - "relateurl": "^0.2.7", - "terser": "^5.10.0" - }, - "bin": { - "html-minifier-terser": "cli.js" - }, - "engines": { - "node": ">=12" - } - }, "node_modules/htmlparser2": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.1.tgz", @@ -6437,131 +3166,6 @@ "entities": "^4.3.0" } }, - "node_modules/http-deceiver": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", - "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==", - "dev": true - }, - "node_modules/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "dev": true, - "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/http-parser-js": { - "version": "0.5.8", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", - "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==", - "dev": true - }, - "node_modules/http-proxy": { - "version": "1.18.1", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", - "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", - "dev": true, - "dependencies": { - "eventemitter3": "^4.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/http-proxy-middleware": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz", - "integrity": "sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==", - "dev": true, - "dependencies": { - "@types/http-proxy": "^1.17.8", - "http-proxy": "^1.18.1", - "is-glob": "^4.0.1", - "is-plain-obj": "^3.0.0", - "micromatch": "^4.0.2" - }, - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "@types/express": "^4.17.13" - }, - "peerDependenciesMeta": { - "@types/express": { - "optional": true - } - } - }, - "node_modules/human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "dev": true, - "engines": { - "node": ">=10.17.0" - } - }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/icss-utils": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", - "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", - "dev": true, - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/idb-wrapper": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/idb-wrapper/-/idb-wrapper-1.7.2.tgz", - "integrity": "sha512-zfNREywMuf0NzDo9mVsL0yegjsirJxHpKHvWcyRozIqQy89g0a3U+oBPOCN4cc0oCiOuYgZHimzaW/R46G1Mpg==", - "dev": true - }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, "node_modules/ignore": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.1.tgz", @@ -6593,25 +3197,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/import-local": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", - "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", - "dev": true, - "dependencies": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - }, - "bin": { - "import-local-fixture": "fixtures/cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", @@ -6621,12 +3206,6 @@ "node": ">=0.8.19" } }, - "node_modules/indexof": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", - "integrity": "sha512-i0G7hLJ1z0DE8dsqJa2rycj9dBmNKgXBvotXtZYXakU9oivfB9Uj2ZBC27qqef2U58/ZLwalxa1X/RDCdkHtVg==", - "dev": true - }, "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -6662,49 +3241,6 @@ "node": ">= 0.4" } }, - "node_modules/interpret": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", - "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", - "dev": true, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/ipaddr.js": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.0.1.tgz", - "integrity": "sha512-1qTgH9NG+IIJ4yfKs2e6Pp1bZg8wbDbKHT21HrLIeYBTRLgMYKnMTPAuI3Lcs61nfx5h1xlXnbJtH1kX5/d/ng==", - "dev": true, - "engines": { - "node": ">= 10" - } - }, - "node_modules/is": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/is/-/is-0.2.7.tgz", - "integrity": "sha512-ajQCouIvkcSnl2iRdK70Jug9mohIHVX9uKpoWnl115ov0R5mzBvRrXxrnHbsA+8AdwCwc/sfw7HXmd4I5EJBdQ==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/is-arguments": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", - "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-bigint": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", @@ -6784,21 +3320,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", - "dev": true, - "bin": { - "is-docker": "cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -6808,21 +3329,6 @@ "node": ">=0.10.0" } }, - "node_modules/is-generator-function": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", - "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", - "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", @@ -6835,22 +3341,6 @@ "node": ">=0.10.0" } }, - "node_modules/is-nan": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz", - "integrity": "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-negative-zero": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", @@ -6887,45 +3377,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-object": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/is-object/-/is-object-0.1.2.tgz", - "integrity": "sha512-GkfZZlIZtpkFrqyAXPQSRBMsaHAw+CgoKe2HXAkjd/sfoI9+hS8PT4wg2rJxdQyUKr7N2vHJbg7/jQtE5l5vBQ==", - "dev": true - }, - "node_modules/is-path-cwd": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", - "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/is-path-in-cwd": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz", - "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==", - "dev": true, - "dependencies": { - "is-path-inside": "^2.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/is-path-in-cwd/node_modules/is-path-inside": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", - "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", - "dev": true, - "dependencies": { - "path-is-inside": "^1.0.2" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/is-path-inside": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", @@ -6935,18 +3386,6 @@ "node": ">=8" } }, - "node_modules/is-plain-obj": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", - "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/is-plain-object": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", @@ -6983,18 +3422,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/is-string": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", @@ -7025,25 +3452,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-typed-array": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz", - "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==", - "dev": true, - "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-weakref": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", @@ -7056,171 +3464,12 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "dev": true, - "dependencies": { - "is-docker": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", - "dev": true - }, - "node_modules/isbuffer": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/isbuffer/-/isbuffer-0.0.0.tgz", - "integrity": "sha512-xU+NoHp+YtKQkaM2HsQchYn0sltxMxew0HavMfHbjnucBoTSGbw745tL+Z7QBANleWM1eEQMenEpi174mIeS4g==", - "dev": true - }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, - "node_modules/isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/jest-util": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.3.1.tgz", - "integrity": "sha512-7YOVZaiX7RJLv76ZfHt4nbNEzzTRiMW/IiOG7ZOKmTXmoGBxUDefgMAxQubu6WPVqP5zSzAdZG0FfLcC7HOIFQ==", - "dev": true, - "dependencies": { - "@jest/types": "^29.3.1", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-util/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-util/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-util/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-util/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/jest-util/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-util/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-worker": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.3.1.tgz", - "integrity": "sha512-lY4AnnmsEWeiXirAIA0c9SDPbuCBq8IYuDVL8PMm0MZ2PEs2yPvRA/J64QBXuZp7CYKrDM/rmNrc9/i3KJQncw==", - "dev": true, - "dependencies": { - "@types/node": "*", - "jest-util": "^29.3.1", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-worker/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-worker/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, "node_modules/js-sdsl": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.2.0.tgz", @@ -7260,12 +3509,6 @@ "node": ">=4" } }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true - }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -7337,24 +3580,6 @@ "node": ">= 12" } }, - "node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/klona": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.5.tgz", - "integrity": "sha512-pJiBpiXMbt7dkzXe8Ghj/u4FfXOOa98fPW+bihOJ4SjnoijweJrNThJfd3ifXpXhREjpoF2mZVH1GfS9LV3kHQ==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, "node_modules/language-subtag-registry": { "version": "0.3.22", "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz", @@ -7370,211 +3595,6 @@ "language-subtag-registry": "^0.3.20" } }, - "node_modules/level-blobs": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/level-blobs/-/level-blobs-0.1.7.tgz", - "integrity": "sha512-n0iYYCGozLd36m/Pzm206+brIgXP8mxPZazZ6ZvgKr+8YwOZ8/PPpYC5zMUu2qFygRN8RO6WC/HH3XWMW7RMVg==", - "dev": true, - "dependencies": { - "level-peek": "1.0.6", - "once": "^1.3.0", - "readable-stream": "^1.0.26-4" - } - }, - "node_modules/level-blobs/node_modules/readable-stream": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==", - "dev": true, - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "node_modules/level-blobs/node_modules/string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", - "dev": true - }, - "node_modules/level-filesystem": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/level-filesystem/-/level-filesystem-1.2.0.tgz", - "integrity": "sha512-PhXDuCNYpngpxp3jwMT9AYBMgOvB6zxj3DeuIywNKmZqFj2djj9XfT2XDVslfqmo0Ip79cAd3SBy3FsfOZPJ1g==", - "dev": true, - "dependencies": { - "concat-stream": "^1.4.4", - "errno": "^0.1.1", - "fwd-stream": "^1.0.4", - "level-blobs": "^0.1.7", - "level-peek": "^1.0.6", - "level-sublevel": "^5.2.0", - "octal": "^1.0.0", - "once": "^1.3.0", - "xtend": "^2.2.0" - } - }, - "node_modules/level-fix-range": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/level-fix-range/-/level-fix-range-1.0.2.tgz", - "integrity": "sha512-9llaVn6uqBiSlBP+wKiIEoBa01FwEISFgHSZiyec2S0KpyLUkGR4afW/FCZ/X8y+QJvzS0u4PGOlZDdh1/1avQ==", - "dev": true - }, - "node_modules/level-hooks": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/level-hooks/-/level-hooks-4.5.0.tgz", - "integrity": "sha512-fxLNny/vL/G4PnkLhWsbHnEaRi+A/k8r5EH/M77npZwYL62RHi2fV0S824z3QdpAk6VTgisJwIRywzBHLK4ZVA==", - "dev": true, - "dependencies": { - "string-range": "~1.2" - } - }, - "node_modules/level-js": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/level-js/-/level-js-2.2.4.tgz", - "integrity": "sha512-lZtjt4ZwHE00UMC1vAb271p9qzg8vKlnDeXfIesH3zL0KxhHRDjClQLGLWhyR0nK4XARnd4wc/9eD1ffd4PshQ==", - "dev": true, - "dependencies": { - "abstract-leveldown": "~0.12.0", - "idb-wrapper": "^1.5.0", - "isbuffer": "~0.0.0", - "ltgt": "^2.1.2", - "typedarray-to-buffer": "~1.0.0", - "xtend": "~2.1.2" - } - }, - "node_modules/level-js/node_modules/object-keys": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz", - "integrity": "sha512-ncrLw+X55z7bkl5PnUvHwFK9FcGuFYo9gtjws2XtSzL+aZ8tm830P60WJ0dSmFVaSalWieW5MD7kEdnXda9yJw==", - "dev": true - }, - "node_modules/level-js/node_modules/xtend": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz", - "integrity": "sha512-vMNKzr2rHP9Dp/e1NQFnLQlwlhp9L/LfvnsVdHxN1f+uggyVI3i08uD14GPvCToPkdsRfyPqIyYGmIk58V98ZQ==", - "dev": true, - "dependencies": { - "object-keys": "~0.4.0" - }, - "engines": { - "node": ">=0.4" - } - }, - "node_modules/level-peek": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/level-peek/-/level-peek-1.0.6.tgz", - "integrity": "sha512-TKEzH5TxROTjQxWMczt9sizVgnmJ4F3hotBI48xCTYvOKd/4gA/uY0XjKkhJFo6BMic8Tqjf6jFMLWeg3MAbqQ==", - "dev": true, - "dependencies": { - "level-fix-range": "~1.0.2" - } - }, - "node_modules/level-sublevel": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/level-sublevel/-/level-sublevel-5.2.3.tgz", - "integrity": "sha512-tO8jrFp+QZYrxx/Gnmjawuh1UBiifpvKNAcm4KCogesWr1Nm2+ckARitf+Oo7xg4OHqMW76eAqQ204BoIlscjA==", - "dev": true, - "dependencies": { - "level-fix-range": "2.0", - "level-hooks": ">=4.4.0 <5", - "string-range": "~1.2.1", - "xtend": "~2.0.4" - } - }, - "node_modules/level-sublevel/node_modules/level-fix-range": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/level-fix-range/-/level-fix-range-2.0.0.tgz", - "integrity": "sha512-WrLfGWgwWbYPrHsYzJau+5+te89dUbENBg3/lsxOs4p2tYOhCHjbgXxBAj4DFqp3k/XBwitcRXoCh8RoCogASA==", - "dev": true, - "dependencies": { - "clone": "~0.1.9" - } - }, - "node_modules/level-sublevel/node_modules/object-keys": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.2.0.tgz", - "integrity": "sha512-XODjdR2pBh/1qrjPcbSeSgEtKbYo7LqYNq64/TPuCf7j9SfDD3i21yatKoIy39yIWNvVM59iutfQQpCv1RfFzA==", - "deprecated": "Please update to the latest object-keys", - "dev": true, - "dependencies": { - "foreach": "~2.0.1", - "indexof": "~0.0.1", - "is": "~0.2.6" - } - }, - "node_modules/level-sublevel/node_modules/xtend": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.0.6.tgz", - "integrity": "sha512-fOZg4ECOlrMl+A6Msr7EIFcON1L26mb4NY5rurSkOex/TWhazOrg6eXD/B0XkuiYcYhQDWLXzQxLMVJ7LXwokg==", - "dev": true, - "dependencies": { - "is-object": "~0.1.2", - "object-keys": "~0.2.0" - }, - "engines": { - "node": ">=0.4" - } - }, - "node_modules/levelup": { - "version": "0.18.6", - "resolved": "https://registry.npmjs.org/levelup/-/levelup-0.18.6.tgz", - "integrity": "sha512-uB0auyRqIVXx+hrpIUtol4VAPhLRcnxcOsd2i2m6rbFIDarO5dnrupLOStYYpEcu8ZT087Z9HEuYw1wjr6RL6Q==", - "dev": true, - "dependencies": { - "bl": "~0.8.1", - "deferred-leveldown": "~0.2.0", - "errno": "~0.1.1", - "prr": "~0.0.0", - "readable-stream": "~1.0.26", - "semver": "~2.3.1", - "xtend": "~3.0.0" - } - }, - "node_modules/levelup/node_modules/prr": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/prr/-/prr-0.0.0.tgz", - "integrity": "sha512-LmUECmrW7RVj6mDWKjTXfKug7TFGdiz9P18HMcO4RHL+RW7MCOGNvpj5j47Rnp6ne6r4fZ2VzyUWEpKbg+tsjQ==", - "dev": true - }, - "node_modules/levelup/node_modules/readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==", - "dev": true, - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "node_modules/levelup/node_modules/semver": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-2.3.2.tgz", - "integrity": "sha512-abLdIKCosKfpnmhS52NCTjO4RiLspDfsn37prjzGrp9im5DPJOgh82Os92vtwGh6XdQryKI/7SREZnV+aqiXrA==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/levelup/node_modules/string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", - "dev": true - }, - "node_modules/levelup/node_modules/xtend": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-3.0.0.tgz", - "integrity": "sha512-sp/sT9OALMjRW1fKDlPeuSZlDQpkqReA0pyJukniWbTGoEKefHxhGJynE3PNhUMlcM8qWIjPwecwCw4LArS5Eg==", - "dev": true, - "engines": { - "node": ">=0.4" - } - }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -7588,15 +3608,6 @@ "node": ">= 0.8.0" } }, - "node_modules/lilconfig": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.6.tgz", - "integrity": "sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg==", - "dev": true, - "engines": { - "node": ">=10" - } - }, "node_modules/line-height": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/line-height/-/line-height-0.3.1.tgz", @@ -7621,29 +3632,6 @@ "resolved": "https://registry.npmjs.org/linkifyjs/-/linkifyjs-4.0.2.tgz", "integrity": "sha512-/VSoCZiglX0VMsXmL5PN3lRg45M86lrD9PskdkA2abWaTKap1bIcJ11LS4EE55bcUl9ZOR4eZ792UtQ9E/5xLA==" }, - "node_modules/loader-runner": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", - "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", - "dev": true, - "engines": { - "node": ">=6.11.5" - } - }, - "node_modules/loader-utils": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", - "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", - "dev": true, - "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - }, - "engines": { - "node": ">=8.9.0" - } - }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -7669,30 +3657,12 @@ "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" }, - "node_modules/lodash.debounce": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", - "dev": true - }, - "node_modules/lodash.memoize": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", - "dev": true - }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, - "node_modules/lodash.uniq": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", - "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==", - "dev": true - }, "node_modules/loglevel": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.8.1.tgz", @@ -7716,21 +3686,6 @@ "loose-envify": "cli.js" } }, - "node_modules/lower-case": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", - "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", - "dev": true, - "dependencies": { - "tslib": "^2.0.3" - } - }, - "node_modules/lower-case/node_modules/tslib": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", - "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==", - "dev": true - }, "node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -7743,25 +3698,16 @@ "node": ">=10" } }, - "node_modules/ltgt": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz", - "integrity": "sha512-AI2r85+4MquTw9ZYqabu4nMwy9Oftlfa/e/52t9IjtfG+mGBbTNdAoZ3RQKLHR6r0wQnwZnPIEh/Ya6XTWAKNA==", - "dev": true - }, - "node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "node_modules/magic-string": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.27.0.tgz", + "integrity": "sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==", "dev": true, "dependencies": { - "semver": "^6.0.0" + "@jridgewell/sourcemap-codec": "^1.4.13" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=12" } }, "node_modules/matrix-events-sdk": { @@ -7800,56 +3746,6 @@ "events": "^3.2.0" } }, - "node_modules/md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dev": true, - "dependencies": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/mdn-data": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", - "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", - "dev": true - }, - "node_modules/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/memfs": { - "version": "3.4.12", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.4.12.tgz", - "integrity": "sha512-BcjuQn6vfqP+k100e0E9m61Hyqa//Brp+I3f0OBmN0ATHlFA8vx3Lt8z57R3u2bPqe3WGDBC+nF72fTH7isyEw==", - "dev": true, - "dependencies": { - "fs-monkey": "^1.0.3" - }, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", - "dev": true - }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true - }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -7859,15 +3755,6 @@ "node": ">= 8" } }, - "node_modules/methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/micromatch": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", @@ -7881,151 +3768,6 @@ "node": ">=8.6" } }, - "node_modules/miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "dev": true, - "dependencies": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - }, - "bin": { - "miller-rabin": "bin/miller-rabin" - } - }, - "node_modules/miller-rabin/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, - "node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "dev": true, - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/mini-css-extract-plugin": { - "version": "2.7.2", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.7.2.tgz", - "integrity": "sha512-EdlUizq13o0Pd+uCp+WO/JpkLvHRVGt97RqfeGhXqAcorYo1ypJSpkV+WDT0vY/kmh/p7wRdJNJtuyK540PXDw==", - "dev": true, - "dependencies": { - "schema-utils": "^4.0.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.0.0" - } - }, - "node_modules/mini-css-extract-plugin/node_modules/ajv": { - "version": "8.11.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.2.tgz", - "integrity": "sha512-E4bfmKAhGiSTvMfL1Myyycaub+cUEU2/IvpylXkUu7CHBkBj1f/ikdzbD7YQ6FKUbixDxeYvB/xY4fvyroDlQg==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/mini-css-extract-plugin/node_modules/ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" - } - }, - "node_modules/mini-css-extract-plugin/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, - "node_modules/mini-css-extract-plugin/node_modules/schema-utils": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", - "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==", - "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.8.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.0.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true - }, - "node_modules/minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==", - "dev": true - }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -8053,19 +3795,6 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, - "node_modules/multicast-dns": { - "version": "7.2.5", - "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", - "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", - "dev": true, - "dependencies": { - "dns-packet": "^5.2.2", - "thunky": "^1.0.2" - }, - "bin": { - "multicast-dns": "cli.js" - } - }, "node_modules/nanoid": { "version": "3.3.4", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", @@ -8083,35 +3812,10 @@ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, - "node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true - }, - "node_modules/no-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", - "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", - "dev": true, - "dependencies": { - "lower-case": "^2.0.2", - "tslib": "^2.0.3" - } - }, - "node_modules/no-case/node_modules/tslib": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", - "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==", + "node_modules/natural-compare-lite": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", + "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", "dev": true }, "node_modules/node-fetch": { @@ -8133,15 +3837,6 @@ } } }, - "node_modules/node-forge": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", - "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", - "dev": true, - "engines": { - "node": ">= 6.13.0" - } - }, "node_modules/node-releases": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.7.tgz", @@ -8157,42 +3852,6 @@ "node": ">=0.10.0" } }, - "node_modules/normalize-url": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", - "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dev": true, - "dependencies": { - "path-key": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/nth-check": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", - "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", - "dev": true, - "dependencies": { - "boolbase": "^1.0.0" - }, - "funding": { - "url": "https://github.com/fb55/nth-check?sponsor=1" - } - }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -8209,22 +3868,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/object-is": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", - "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/object-keys": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", @@ -8313,39 +3956,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/obuf": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", - "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", - "dev": true - }, - "node_modules/octal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/octal/-/octal-1.0.0.tgz", - "integrity": "sha512-nnda7W8d+A3vEIY+UrDQzzboPf1vhs4JYVhff5CDkq9QNoZY7Xrxeo/htox37j9dZf7yNHevZzqtejWgy1vCqQ==", - "dev": true - }, - "node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "dev": true, - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/on-headers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", - "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -8355,38 +3965,6 @@ "wrappy": "1" } }, - "node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/open": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/open/-/open-8.4.0.tgz", - "integrity": "sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q==", - "dev": true, - "dependencies": { - "define-lazy-prop": "^2.0.0", - "is-docker": "^2.1.1", - "is-wsl": "^2.2.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/optionator": { "version": "0.9.1", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", @@ -8434,15 +4012,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/p-map": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", - "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/p-retry": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", @@ -8455,31 +4024,6 @@ "node": ">=8" } }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/param-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", - "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", - "dev": true, - "dependencies": { - "dot-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "node_modules/param-case/node_modules/tslib": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", - "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==", - "dev": true - }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -8492,67 +4036,11 @@ "node": ">=6" } }, - "node_modules/parse-asn1": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", - "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", - "dev": true, - "dependencies": { - "asn1.js": "^5.2.0", - "browserify-aes": "^1.0.0", - "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3", - "safe-buffer": "^5.1.1" - } - }, "node_modules/parse-srcset": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/parse-srcset/-/parse-srcset-1.0.2.tgz", "integrity": "sha512-/2qh0lav6CmI15FzA3i/2Bzk2zCgQhGMkvhOhKNcBVQ1ldgpbfiNTVslmooUmWJcADi1f1kIeynbDRVzNlfR6Q==" }, - "node_modules/parse5": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", - "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", - "dev": true, - "dependencies": { - "entities": "^4.4.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "node_modules/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/pascal-case": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", - "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", - "dev": true, - "dependencies": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "node_modules/pascal-case/node_modules/tslib": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", - "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==", - "dev": true - }, - "node_modules/path-browserify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", - "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", - "dev": true - }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -8571,12 +4059,6 @@ "node": ">=0.10.0" } }, - "node_modules/path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==", - "dev": true - }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", @@ -8592,12 +4074,6 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, - "node_modules/path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", - "dev": true - }, "node_modules/path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", @@ -8607,22 +4083,6 @@ "node": ">=8" } }, - "node_modules/pbkdf2": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", - "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", - "dev": true, - "dependencies": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - }, - "engines": { - "node": ">=0.12" - } - }, "node_modules/picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", @@ -8640,100 +4100,6 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==", - "dev": true, - "dependencies": { - "pinkie": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "dependencies": { - "find-up": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-dir/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/postcss": { "version": "8.4.20", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.20.tgz", @@ -8757,489 +4123,6 @@ "node": "^10 || ^12 || >=14" } }, - "node_modules/postcss-calc": { - "version": "8.2.4", - "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-8.2.4.tgz", - "integrity": "sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q==", - "dev": true, - "dependencies": { - "postcss-selector-parser": "^6.0.9", - "postcss-value-parser": "^4.2.0" - }, - "peerDependencies": { - "postcss": "^8.2.2" - } - }, - "node_modules/postcss-colormin": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-5.3.0.tgz", - "integrity": "sha512-WdDO4gOFG2Z8n4P8TWBpshnL3JpmNmJwdnfP2gbk2qBA8PWwOYcmjmI/t3CmMeL72a7Hkd+x/Mg9O2/0rD54Pg==", - "dev": true, - "dependencies": { - "browserslist": "^4.16.6", - "caniuse-api": "^3.0.0", - "colord": "^2.9.1", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-convert-values": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-5.1.3.tgz", - "integrity": "sha512-82pC1xkJZtcJEfiLw6UXnXVXScgtBrjlO5CBmuDQc+dlb88ZYheFsjTn40+zBVi3DkfF7iezO0nJUPLcJK3pvA==", - "dev": true, - "dependencies": { - "browserslist": "^4.21.4", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-discard-comments": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.1.2.tgz", - "integrity": "sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ==", - "dev": true, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-discard-duplicates": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.1.0.tgz", - "integrity": "sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==", - "dev": true, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-discard-empty": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.1.1.tgz", - "integrity": "sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==", - "dev": true, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-discard-overridden": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz", - "integrity": "sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==", - "dev": true, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-merge-longhand": { - "version": "5.1.7", - "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-5.1.7.tgz", - "integrity": "sha512-YCI9gZB+PLNskrK0BB3/2OzPnGhPkBEwmwhfYk1ilBHYVAZB7/tkTHFBAnCrvBBOmeYyMYw3DMjT55SyxMBzjQ==", - "dev": true, - "dependencies": { - "postcss-value-parser": "^4.2.0", - "stylehacks": "^5.1.1" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-merge-rules": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-5.1.3.tgz", - "integrity": "sha512-LbLd7uFC00vpOuMvyZop8+vvhnfRGpp2S+IMQKeuOZZapPRY4SMq5ErjQeHbHsjCUgJkRNrlU+LmxsKIqPKQlA==", - "dev": true, - "dependencies": { - "browserslist": "^4.21.4", - "caniuse-api": "^3.0.0", - "cssnano-utils": "^3.1.0", - "postcss-selector-parser": "^6.0.5" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-minify-font-values": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-5.1.0.tgz", - "integrity": "sha512-el3mYTgx13ZAPPirSVsHqFzl+BBBDrXvbySvPGFnQcTI4iNslrPaFq4muTkLZmKlGk4gyFAYUBMH30+HurREyA==", - "dev": true, - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-minify-gradients": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-5.1.1.tgz", - "integrity": "sha512-VGvXMTpCEo4qHTNSa9A0a3D+dxGFZCYwR6Jokk+/3oB6flu2/PnPXAh2x7x52EkY5xlIHLm+Le8tJxe/7TNhzw==", - "dev": true, - "dependencies": { - "colord": "^2.9.1", - "cssnano-utils": "^3.1.0", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-minify-params": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-5.1.4.tgz", - "integrity": "sha512-+mePA3MgdmVmv6g+30rn57USjOGSAyuxUmkfiWpzalZ8aiBkdPYjXWtHuwJGm1v5Ojy0Z0LaSYhHaLJQB0P8Jw==", - "dev": true, - "dependencies": { - "browserslist": "^4.21.4", - "cssnano-utils": "^3.1.0", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-minify-selectors": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-5.2.1.tgz", - "integrity": "sha512-nPJu7OjZJTsVUmPdm2TcaiohIwxP+v8ha9NehQ2ye9szv4orirRU3SDdtUmKH+10nzn0bAyOXZ0UEr7OpvLehg==", - "dev": true, - "dependencies": { - "postcss-selector-parser": "^6.0.5" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-modules-extract-imports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", - "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", - "dev": true, - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-modules-local-by-default": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz", - "integrity": "sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ==", - "dev": true, - "dependencies": { - "icss-utils": "^5.0.0", - "postcss-selector-parser": "^6.0.2", - "postcss-value-parser": "^4.1.0" - }, - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-modules-scope": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz", - "integrity": "sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==", - "dev": true, - "dependencies": { - "postcss-selector-parser": "^6.0.4" - }, - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-modules-values": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", - "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", - "dev": true, - "dependencies": { - "icss-utils": "^5.0.0" - }, - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-normalize-charset": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz", - "integrity": "sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==", - "dev": true, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-normalize-display-values": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-5.1.0.tgz", - "integrity": "sha512-WP4KIM4o2dazQXWmFaqMmcvsKmhdINFblgSeRgn8BJ6vxaMyaJkwAzpPpuvSIoG/rmX3M+IrRZEz2H0glrQNEA==", - "dev": true, - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-normalize-positions": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-5.1.1.tgz", - "integrity": "sha512-6UpCb0G4eofTCQLFVuI3EVNZzBNPiIKcA1AKVka+31fTVySphr3VUgAIULBhxZkKgwLImhzMR2Bw1ORK+37INg==", - "dev": true, - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-normalize-repeat-style": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.1.1.tgz", - "integrity": "sha512-mFpLspGWkQtBcWIRFLmewo8aC3ImN2i/J3v8YCFUwDnPu3Xz4rLohDO26lGjwNsQxB3YF0KKRwspGzE2JEuS0g==", - "dev": true, - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-normalize-string": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-5.1.0.tgz", - "integrity": "sha512-oYiIJOf4T9T1N4i+abeIc7Vgm/xPCGih4bZz5Nm0/ARVJ7K6xrDlLwvwqOydvyL3RHNf8qZk6vo3aatiw/go3w==", - "dev": true, - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-normalize-timing-functions": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.1.0.tgz", - "integrity": "sha512-DOEkzJ4SAXv5xkHl0Wa9cZLF3WCBhF3o1SKVxKQAa+0pYKlueTpCgvkFAHfk+Y64ezX9+nITGrDZeVGgITJXjg==", - "dev": true, - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-normalize-unicode": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-5.1.1.tgz", - "integrity": "sha512-qnCL5jzkNUmKVhZoENp1mJiGNPcsJCs1aaRmURmeJGES23Z/ajaln+EPTD+rBeNkSryI+2WTdW+lwcVdOikrpA==", - "dev": true, - "dependencies": { - "browserslist": "^4.21.4", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-normalize-url": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-5.1.0.tgz", - "integrity": "sha512-5upGeDO+PVthOxSmds43ZeMeZfKH+/DKgGRD7TElkkyS46JXAUhMzIKiCa7BabPeIy3AQcTkXwVVN7DbqsiCew==", - "dev": true, - "dependencies": { - "normalize-url": "^6.0.1", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-normalize-whitespace": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.1.1.tgz", - "integrity": "sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA==", - "dev": true, - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-ordered-values": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-5.1.3.tgz", - "integrity": "sha512-9UO79VUhPwEkzbb3RNpqqghc6lcYej1aveQteWY+4POIwlqkYE21HKWaLDF6lWNuqCobEAyTovVhtI32Rbv2RQ==", - "dev": true, - "dependencies": { - "cssnano-utils": "^3.1.0", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-reduce-initial": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.1.1.tgz", - "integrity": "sha512-//jeDqWcHPuXGZLoolFrUXBDyuEGbr9S2rMo19bkTIjBQ4PqkaO+oI8wua5BOUxpfi97i3PCoInsiFIEBfkm9w==", - "dev": true, - "dependencies": { - "browserslist": "^4.21.4", - "caniuse-api": "^3.0.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-reduce-transforms": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-5.1.0.tgz", - "integrity": "sha512-2fbdbmgir5AvpW9RLtdONx1QoYG2/EtqpNQbFASDlixBbAYuTcJ0dECwlqNqH7VbaUnEnh8SrxOe2sRIn24XyQ==", - "dev": true, - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-selector-parser": { - "version": "6.0.11", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.11.tgz", - "integrity": "sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g==", - "dev": true, - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-svgo": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-5.1.0.tgz", - "integrity": "sha512-D75KsH1zm5ZrHyxPakAxJWtkyXew5qwS70v56exwvw542d9CRtTo78K0WeFxZB4G7JXKKMbEZtZayTGdIky/eA==", - "dev": true, - "dependencies": { - "postcss-value-parser": "^4.2.0", - "svgo": "^2.7.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-unique-selectors": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-5.1.1.tgz", - "integrity": "sha512-5JiODlELrz8L2HwxfPnhOWZYWDxVHWL83ufOv84NrcgipI7TaeRsatAhK4Tr2/ZiYldpK/wBvw5BD3qfaK96GA==", - "dev": true, - "dependencies": { - "postcss-selector-parser": "^6.0.5" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-value-parser": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", - "dev": true - }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -9249,22 +4132,21 @@ "node": ">= 0.8.0" } }, - "node_modules/pretty-error": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz", - "integrity": "sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==", + "node_modules/prettier": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.1.tgz", + "integrity": "sha512-lqGoSJBQNJidqCHE80vqZJHWHRFoNYsSpP9AjFhlhi9ODCJA541svILes/+/1GM3VaL/abZi7cpFzOpdR9UPKg==", "dev": true, - "dependencies": { - "lodash": "^4.17.20", - "renderkid": "^3.0.0" + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" } }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, "node_modules/promise": { "version": "7.3.1", "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", @@ -9283,54 +4165,6 @@ "react-is": "^16.13.1" } }, - "node_modules/proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "dev": true, - "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/proxy-addr/node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==", - "dev": true - }, - "node_modules/public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "dev": true, - "dependencies": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/public-encrypt/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, "node_modules/punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", @@ -9354,16 +4188,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==", - "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.", - "dev": true, - "engines": { - "node": ">=0.4.x" - } - }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -9384,58 +4208,6 @@ } ] }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, - "node_modules/randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "dev": true, - "dependencies": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/raw-body": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", - "dev": true, - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/raw-body/node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/react": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", @@ -9583,18 +4355,13 @@ "resolved": "https://registry.npmjs.org/react-property/-/react-property-2.0.0.tgz", "integrity": "sha512-kzmNjIgU32mO4mmH5+iUyrqlpFQhF8K2k7eZ4fdLSOPFrD1XgEuSBv9LDEgxRXTMBqMd8ppT0x6TIzqE5pdGdw==" }, - "node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "node_modules/react-refresh": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.0.tgz", + "integrity": "sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==", "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, "engines": { - "node": ">= 6" + "node": ">=0.10.0" } }, "node_modules/readdirp": { @@ -9609,18 +4376,6 @@ "node": ">=8.10.0" } }, - "node_modules/rechoir": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", - "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", - "dev": true, - "dependencies": { - "resolve": "^1.20.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, "node_modules/redux": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.0.tgz", @@ -9629,38 +4384,6 @@ "@babel/runtime": "^7.9.2" } }, - "node_modules/regenerate": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", - "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", - "dev": true - }, - "node_modules/regenerate-unicode-properties": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz", - "integrity": "sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==", - "dev": true, - "dependencies": { - "regenerate": "^1.4.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/regenerator-runtime": { - "version": "0.10.5", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz", - "integrity": "sha512-02YopEIhAgiBHWeoTiA8aitHDt8z6w+rQqNuIftlM+ZtvSl/brTouaU7DW6GO/cHtvxJvS4Hwv2ibKdxIRi24w==" - }, - "node_modules/regenerator-transform": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.1.tgz", - "integrity": "sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.8.4" - } - }, "node_modules/regexp.prototype.flags": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", @@ -9690,158 +4413,6 @@ "url": "https://github.com/sponsors/mysticatea" } }, - "node_modules/regexpu-core": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.2.2.tgz", - "integrity": "sha512-T0+1Zp2wjF/juXMrMxHxidqGYn8U4R+zleSJhX9tQ1PUsS8a9UtYfbsF9LdiVgNX3kiX8RNaKM42nfSgvFJjmw==", - "dev": true, - "dependencies": { - "regenerate": "^1.4.2", - "regenerate-unicode-properties": "^10.1.0", - "regjsgen": "^0.7.1", - "regjsparser": "^0.9.1", - "unicode-match-property-ecmascript": "^2.0.0", - "unicode-match-property-value-ecmascript": "^2.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/regjsgen": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.7.1.tgz", - "integrity": "sha512-RAt+8H2ZEzHeYWxZ3H2z6tF18zyyOnlcdaafLrm21Bguj7uZy6ULibiAFdXEtKQY4Sy7wDTwDiOazasMLc4KPA==", - "dev": true - }, - "node_modules/regjsparser": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", - "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", - "dev": true, - "dependencies": { - "jsesc": "~0.5.0" - }, - "bin": { - "regjsparser": "bin/parser" - } - }, - "node_modules/regjsparser/node_modules/jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", - "dev": true, - "bin": { - "jsesc": "bin/jsesc" - } - }, - "node_modules/relateurl": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", - "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/renderkid": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-3.0.0.tgz", - "integrity": "sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==", - "dev": true, - "dependencies": { - "css-select": "^4.1.3", - "dom-converter": "^0.2.0", - "htmlparser2": "^6.1.0", - "lodash": "^4.17.21", - "strip-ansi": "^6.0.1" - } - }, - "node_modules/renderkid/node_modules/dom-serializer": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", - "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", - "dev": true, - "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.0", - "entities": "^2.0.0" - }, - "funding": { - "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" - } - }, - "node_modules/renderkid/node_modules/domhandler": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", - "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", - "dev": true, - "dependencies": { - "domelementtype": "^2.2.0" - }, - "engines": { - "node": ">= 4" - }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" - } - }, - "node_modules/renderkid/node_modules/domutils": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", - "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", - "dev": true, - "dependencies": { - "dom-serializer": "^1.0.1", - "domelementtype": "^2.2.0", - "domhandler": "^4.2.0" - }, - "funding": { - "url": "https://github.com/fb55/domutils?sponsor=1" - } - }, - "node_modules/renderkid/node_modules/entities": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", - "dev": true, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/renderkid/node_modules/htmlparser2": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", - "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", - "dev": true, - "funding": [ - "https://github.com/fb55/htmlparser2?sponsor=1", - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^4.0.0", - "domutils": "^2.5.2", - "entities": "^2.0.0" - } - }, - "node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", - "dev": true - }, "node_modules/resolve": { "version": "1.22.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", @@ -9859,27 +4430,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "dev": true, - "dependencies": { - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-cwd/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -9907,26 +4457,20 @@ "node": ">=0.10.0" } }, - "node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "node_modules/rollup": { + "version": "3.7.5", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.7.5.tgz", + "integrity": "sha512-z0ZbqHBtS/et2EEUKMrAl2CoSdwN7ZPzL17UMiKN9RjjqHShTlv7F9J6ZJZJNREYjBh3TvBrdfjkFDIXFNeuiQ==", "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, - "dependencies": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=14.18.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" } }, "node_modules/run-parallel": { @@ -9952,26 +4496,6 @@ "queue-microtask": "^1.2.2" } }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, "node_modules/safe-regex-test": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", @@ -9986,12 +4510,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, "node_modules/sanitize-html": { "version": "2.8.0", "resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-2.8.0.tgz", @@ -10041,44 +4559,6 @@ "node": ">=12.0.0" } }, - "node_modules/sass-loader": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-13.2.0.tgz", - "integrity": "sha512-JWEp48djQA4nbZxmgC02/Wh0eroSUutulROUusYJO9P9zltRbNN80JCBHqRGzjd4cmZCa/r88xgfkjGD0TXsHg==", - "dev": true, - "dependencies": { - "klona": "^2.0.4", - "neo-async": "^2.6.2" - }, - "engines": { - "node": ">= 14.15.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "fibers": ">= 3.1.0", - "node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0", - "sass": "^1.3.0", - "sass-embedded": "*", - "webpack": "^5.0.0" - }, - "peerDependenciesMeta": { - "fibers": { - "optional": true - }, - "node-sass": { - "optional": true - }, - "sass": { - "optional": true - }, - "sass-embedded": { - "optional": true - } - } - }, "node_modules/scheduler": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", @@ -10088,24 +4568,6 @@ "object-assign": "^4.1.1" } }, - "node_modules/schema-utils": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", - "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", - "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.5", - "ajv": "^6.12.4", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 8.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, "node_modules/sdp-transform": { "version": "2.14.1", "resolved": "https://registry.npmjs.org/sdp-transform/-/sdp-transform-2.14.1.tgz", @@ -10114,24 +4576,6 @@ "sdp-verify": "checker.js" } }, - "node_modules/select-hose": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", - "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==", - "dev": true - }, - "node_modules/selfsigned": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.1.1.tgz", - "integrity": "sha512-GSL3aowiF7wa/WtSFwnUrludWFoNhftq8bUkH9pkzjpN2XSPOAYEgg6e0sS9s0rZwgJzJiQRPU18A6clnoW5wQ==", - "dev": true, - "dependencies": { - "node-forge": "^1" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", @@ -10141,189 +4585,11 @@ "semver": "bin/semver.js" } }, - "node_modules/send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", - "dev": true, - "dependencies": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/send/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/send/node_modules/debug/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/send/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, - "node_modules/serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", - "dev": true, - "dependencies": { - "randombytes": "^2.1.0" - } - }, - "node_modules/serve-index": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", - "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", - "dev": true, - "dependencies": { - "accepts": "~1.3.4", - "batch": "0.6.1", - "debug": "2.6.9", - "escape-html": "~1.0.3", - "http-errors": "~1.6.2", - "mime-types": "~2.1.17", - "parseurl": "~1.3.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/serve-index/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/serve-index/node_modules/depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/serve-index/node_modules/http-errors": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", - "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", - "dev": true, - "dependencies": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.0", - "statuses": ">= 1.4.0 < 2" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/serve-index/node_modules/inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", - "dev": true - }, - "node_modules/serve-index/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/serve-index/node_modules/setprototypeof": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", - "dev": true - }, - "node_modules/serve-index/node_modules/statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", - "dev": true, - "dependencies": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.18.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, "node_modules/setimmediate": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==" }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", - "dev": true - }, - "node_modules/sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, - "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - }, - "bin": { - "sha.js": "bin.js" - } - }, - "node_modules/shallow-clone": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", - "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -10358,42 +4624,13 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, "node_modules/slash": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", - "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true, "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/sockjs": { - "version": "0.3.24", - "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", - "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", - "dev": true, - "dependencies": { - "faye-websocket": "^0.11.3", - "uuid": "^8.3.2", - "websocket-driver": "^0.7.4" - } - }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, "node_modules/source-map-js": { @@ -10404,87 +4641,6 @@ "node": ">=0.10.0" } }, - "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/spdy": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", - "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", - "dev": true, - "dependencies": { - "debug": "^4.1.0", - "handle-thing": "^2.0.0", - "http-deceiver": "^1.2.7", - "select-hose": "^2.0.0", - "spdy-transport": "^3.0.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/spdy-transport": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", - "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", - "dev": true, - "dependencies": { - "debug": "^4.1.0", - "detect-node": "^2.0.4", - "hpack.js": "^2.1.6", - "obuf": "^1.1.2", - "readable-stream": "^3.0.6", - "wbuf": "^1.7.3" - } - }, - "node_modules/stable": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", - "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", - "deprecated": "Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility", - "dev": true - }, - "node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/stream-browserify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-3.0.0.tgz", - "integrity": "sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==", - "dev": true, - "dependencies": { - "inherits": "~2.0.4", - "readable-stream": "^3.5.0" - } - }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/string-range": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/string-range/-/string-range-1.2.2.tgz", - "integrity": "sha512-tYft6IFi8SjplJpxCUxyqisD3b+R2CSkomrtJYCkvuf1KuCAWgz7YXt4O0jip7efpfCemwHEzTEAO8EuOYgh3w==", - "dev": true - }, "node_modules/string.prototype.matchall": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.8.tgz", @@ -10553,15 +4709,6 @@ "node": ">=4" } }, - "node_modules/strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -10574,22 +4721,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/style-loader": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.3.1.tgz", - "integrity": "sha512-GPcQ+LDJbrcxHORTRes6Jy2sfvK2kS6hpSfI/fXhPt+spVzxF6LJ1dHLN9zIGmVaaP044YKaIatFaufENRiDoQ==", - "dev": true, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.0.0" - } - }, "node_modules/style-to-js": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/style-to-js/-/style-to-js-1.1.1.tgz", @@ -10606,22 +4737,6 @@ "inline-style-parser": "0.1.1" } }, - "node_modules/stylehacks": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.1.tgz", - "integrity": "sha512-sBpcd5Hx7G6seo7b1LkpttvTz7ikD0LlH5RmdcBNb6fFR0Fl7LQwHDFr300q4cwUqi+IYrFGmsIHieMBfnN/Bw==", - "dev": true, - "dependencies": { - "browserslist": "^4.21.4", - "postcss-selector-parser": "^6.0.4" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, "node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -10646,171 +4761,12 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/svgo": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz", - "integrity": "sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==", - "dev": true, - "dependencies": { - "@trysound/sax": "0.2.0", - "commander": "^7.2.0", - "css-select": "^4.1.3", - "css-tree": "^1.1.3", - "csso": "^4.2.0", - "picocolors": "^1.0.0", - "stable": "^0.1.8" - }, - "bin": { - "svgo": "bin/svgo" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/svgo/node_modules/commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "dev": true, - "engines": { - "node": ">= 10" - } - }, - "node_modules/tapable": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", - "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/terser": { - "version": "5.16.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.16.1.tgz", - "integrity": "sha512-xvQfyfA1ayT0qdK47zskQgRZeWLoOQ8JQ6mIgRGVNwZKdQMU+5FkCBjmv4QjcrTzyZquRw2FVtlJSRUmMKQslw==", - "dev": true, - "dependencies": { - "@jridgewell/source-map": "^0.3.2", - "acorn": "^8.5.0", - "commander": "^2.20.0", - "source-map-support": "~0.5.20" - }, - "bin": { - "terser": "bin/terser" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/terser-webpack-plugin": { - "version": "5.3.6", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.6.tgz", - "integrity": "sha512-kfLFk+PoLUQIbLmB1+PZDMRSZS99Mp+/MHqDNmMA6tOItzRt+Npe3E+fsMs5mfcM0wCtrrdU387UnV+vnSffXQ==", - "dev": true, - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.14", - "jest-worker": "^27.4.5", - "schema-utils": "^3.1.1", - "serialize-javascript": "^6.0.0", - "terser": "^5.14.1" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.1.0" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "esbuild": { - "optional": true - }, - "uglify-js": { - "optional": true - } - } - }, - "node_modules/terser-webpack-plugin/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/terser-webpack-plugin/node_modules/jest-worker": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", - "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", - "dev": true, - "dependencies": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/terser-webpack-plugin/node_modules/schema-utils": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", - "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", - "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/terser-webpack-plugin/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/terser/node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, - "node_modules/thunky": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", - "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", - "dev": true - }, "node_modules/tiny-warning": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", @@ -10845,15 +4801,6 @@ "node": ">=8.0" } }, - "node_modules/toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "dev": true, - "engines": { - "node": ">=0.6" - } - }, "node_modules/tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", @@ -10888,6 +4835,21 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, + "node_modules/tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "dependencies": { + "tslib": "^1.8.1" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + } + }, "node_modules/twemoji": { "version": "14.0.2", "resolved": "https://registry.npmjs.org/twemoji/-/twemoji-14.0.2.tgz", @@ -10928,31 +4890,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "node_modules/typescript": { + "version": "4.9.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz", + "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==", "dev": true, - "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" }, "engines": { - "node": ">= 0.6" + "node": ">=4.2.0" } }, - "node_modules/typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", - "dev": true - }, - "node_modules/typedarray-to-buffer": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-1.0.4.tgz", - "integrity": "sha512-vjMKrfSoUDN8/Vnqitw2FmstOfuJ73G6CrSEKnf11A6RmasVxHqfeBcnTb6RsL4pTMuV5Zsv9IiHRphMZyckUw==", - "dev": true - }, "node_modules/ua-parser-js": { "version": "0.7.32", "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.32.tgz", @@ -10991,46 +4941,6 @@ "resolved": "https://registry.npmjs.org/unhomoglyph/-/unhomoglyph-1.0.6.tgz", "integrity": "sha512-7uvcWI3hWshSADBu4JpnyYbTVc7YlhF5GDW/oPD5AxIxl34k4wXR3WDkPnzLxkN32LiTCTKMQLtKVZiwki3zGg==" }, - "node_modules/unicode-canonical-property-names-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", - "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-match-property-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", - "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", - "dev": true, - "dependencies": { - "unicode-canonical-property-names-ecmascript": "^2.0.0", - "unicode-property-aliases-ecmascript": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-match-property-value-ecmascript": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", - "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-property-aliases-ecmascript": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", - "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", @@ -11039,15 +4949,6 @@ "node": ">= 4.0.0" } }, - "node_modules/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/update-browserslist-db": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", @@ -11083,72 +4984,106 @@ "punycode": "^2.1.0" } }, - "node_modules/url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha512-kbailJa29QrtXnxgq+DdCEGlbTeYM2eJUxsz6vjZavrCYPMIFHMKQmSKYAIuUK2i7hgPm28a8piX5NTUtM/LKQ==", + "node_modules/vite": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.0.1.tgz", + "integrity": "sha512-kZQPzbDau35iWOhy3CpkrRC7It+HIHtulAzBhMqzGHKRf/4+vmh8rPDDdv98SWQrFWo6//3ozwsRmwQIPZsK9g==", "dev": true, "dependencies": { - "punycode": "1.3.2", - "querystring": "0.2.0" - } - }, - "node_modules/url/node_modules/punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==", - "dev": true - }, - "node_modules/util": { - "version": "0.12.5", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", - "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "is-arguments": "^1.0.4", - "is-generator-function": "^1.0.7", - "is-typed-array": "^1.1.3", - "which-typed-array": "^1.1.2" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true - }, - "node_modules/utila": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", - "integrity": "sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==", - "dev": true - }, - "node_modules/utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", - "dev": true, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "dev": true, + "esbuild": "^0.16.3", + "postcss": "^8.4.20", + "resolve": "^1.22.1", + "rollup": "^3.7.0" + }, "bin": { - "uuid": "dist/bin/uuid" + "vite": "bin/vite.js" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + }, + "peerDependencies": { + "@types/node": ">= 14", + "less": "*", + "sass": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } } }, - "node_modules/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "node_modules/vite-plugin-static-copy": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/vite-plugin-static-copy/-/vite-plugin-static-copy-0.13.0.tgz", + "integrity": "sha512-cln+fvKMgwNBjxQ59QVblmExZrc9gGEdRmfqcPOOGpxT5KInfpkGMvmK4L+kCAeHHSSGNU1bM7BA9PQgaAJc6g==", + "dev": true, + "dependencies": { + "chokidar": "^3.5.3", + "fast-glob": "^3.2.11", + "fs-extra": "^11.1.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "vite": "^3.0.0 || ^4.0.0" + } + }, + "node_modules/vite-plugin-static-copy/node_modules/fs-extra": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.1.0.tgz", + "integrity": "sha512-0rcTq621PD5jM/e0a3EJoGC/1TC5ZBCERW82LQuwfGnCa1V8w7dpYH1yNu+SLb6E5dkeCBzKEyLGlFrnr+dUyw==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/vite-plugin-static-copy/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/vite-plugin-static-copy/node_modules/universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", "dev": true, "engines": { - "node": ">= 0.8" + "node": ">= 10.0.0" } }, "node_modules/warning": { @@ -11159,409 +5094,11 @@ "loose-envify": "^1.0.0" } }, - "node_modules/watchpack": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", - "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", - "dev": true, - "dependencies": { - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.1.2" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/wbuf": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", - "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", - "dev": true, - "dependencies": { - "minimalistic-assert": "^1.0.0" - } - }, "node_modules/webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" }, - "node_modules/webpack": { - "version": "5.75.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.75.0.tgz", - "integrity": "sha512-piaIaoVJlqMsPtX/+3KTTO6jfvrSYgauFVdt8cr9LTHKmcq/AMd4mhzsiP7ZF/PGRNPGA8336jldh9l2Kt2ogQ==", - "dev": true, - "dependencies": { - "@types/eslint-scope": "^3.7.3", - "@types/estree": "^0.0.51", - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/wasm-edit": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1", - "acorn": "^8.7.1", - "acorn-import-assertions": "^1.7.6", - "browserslist": "^4.14.5", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.10.0", - "es-module-lexer": "^0.9.0", - "eslint-scope": "5.1.1", - "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.9", - "json-parse-even-better-errors": "^2.3.1", - "loader-runner": "^4.2.0", - "mime-types": "^2.1.27", - "neo-async": "^2.6.2", - "schema-utils": "^3.1.0", - "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.1.3", - "watchpack": "^2.4.0", - "webpack-sources": "^3.2.3" - }, - "bin": { - "webpack": "bin/webpack.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependenciesMeta": { - "webpack-cli": { - "optional": true - } - } - }, - "node_modules/webpack-cli": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.0.1.tgz", - "integrity": "sha512-S3KVAyfwUqr0Mo/ur3NzIp6jnerNpo7GUO6so51mxLi1spqsA17YcMXy0WOIJtBSnj748lthxC6XLbNKh/ZC+A==", - "dev": true, - "dependencies": { - "@discoveryjs/json-ext": "^0.5.0", - "@webpack-cli/configtest": "^2.0.1", - "@webpack-cli/info": "^2.0.1", - "@webpack-cli/serve": "^2.0.1", - "colorette": "^2.0.14", - "commander": "^9.4.1", - "cross-spawn": "^7.0.3", - "envinfo": "^7.7.3", - "fastest-levenshtein": "^1.0.12", - "import-local": "^3.0.2", - "interpret": "^3.1.1", - "rechoir": "^0.8.0", - "webpack-merge": "^5.7.3" - }, - "bin": { - "webpack-cli": "bin/cli.js" - }, - "engines": { - "node": ">=14.15.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "5.x.x" - }, - "peerDependenciesMeta": { - "@webpack-cli/generators": { - "optional": true - }, - "webpack-bundle-analyzer": { - "optional": true - }, - "webpack-dev-server": { - "optional": true - } - } - }, - "node_modules/webpack-dev-middleware": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.3.tgz", - "integrity": "sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA==", - "dev": true, - "dependencies": { - "colorette": "^2.0.10", - "memfs": "^3.4.3", - "mime-types": "^2.1.31", - "range-parser": "^1.2.1", - "schema-utils": "^4.0.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^4.0.0 || ^5.0.0" - } - }, - "node_modules/webpack-dev-middleware/node_modules/ajv": { - "version": "8.11.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.2.tgz", - "integrity": "sha512-E4bfmKAhGiSTvMfL1Myyycaub+cUEU2/IvpylXkUu7CHBkBj1f/ikdzbD7YQ6FKUbixDxeYvB/xY4fvyroDlQg==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/webpack-dev-middleware/node_modules/ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" - } - }, - "node_modules/webpack-dev-middleware/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, - "node_modules/webpack-dev-middleware/node_modules/schema-utils": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", - "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==", - "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.8.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.0.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/webpack-dev-server": { - "version": "4.11.1", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.11.1.tgz", - "integrity": "sha512-lILVz9tAUy1zGFwieuaQtYiadImb5M3d+H+L1zDYalYoDl0cksAB1UNyuE5MMWJrG6zR1tXkCP2fitl7yoUJiw==", - "dev": true, - "dependencies": { - "@types/bonjour": "^3.5.9", - "@types/connect-history-api-fallback": "^1.3.5", - "@types/express": "^4.17.13", - "@types/serve-index": "^1.9.1", - "@types/serve-static": "^1.13.10", - "@types/sockjs": "^0.3.33", - "@types/ws": "^8.5.1", - "ansi-html-community": "^0.0.8", - "bonjour-service": "^1.0.11", - "chokidar": "^3.5.3", - "colorette": "^2.0.10", - "compression": "^1.7.4", - "connect-history-api-fallback": "^2.0.0", - "default-gateway": "^6.0.3", - "express": "^4.17.3", - "graceful-fs": "^4.2.6", - "html-entities": "^2.3.2", - "http-proxy-middleware": "^2.0.3", - "ipaddr.js": "^2.0.1", - "open": "^8.0.9", - "p-retry": "^4.5.0", - "rimraf": "^3.0.2", - "schema-utils": "^4.0.0", - "selfsigned": "^2.1.1", - "serve-index": "^1.9.1", - "sockjs": "^0.3.24", - "spdy": "^4.0.2", - "webpack-dev-middleware": "^5.3.1", - "ws": "^8.4.2" - }, - "bin": { - "webpack-dev-server": "bin/webpack-dev-server.js" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^4.37.0 || ^5.0.0" - }, - "peerDependenciesMeta": { - "webpack-cli": { - "optional": true - } - } - }, - "node_modules/webpack-dev-server/node_modules/ajv": { - "version": "8.11.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.2.tgz", - "integrity": "sha512-E4bfmKAhGiSTvMfL1Myyycaub+cUEU2/IvpylXkUu7CHBkBj1f/ikdzbD7YQ6FKUbixDxeYvB/xY4fvyroDlQg==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/webpack-dev-server/node_modules/ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" - } - }, - "node_modules/webpack-dev-server/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, - "node_modules/webpack-dev-server/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/webpack-dev-server/node_modules/schema-utils": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", - "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==", - "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.8.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.0.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/webpack-merge": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.8.0.tgz", - "integrity": "sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q==", - "dev": true, - "dependencies": { - "clone-deep": "^4.0.1", - "wildcard": "^2.0.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/webpack-sources": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", - "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", - "dev": true, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/webpack/node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/webpack/node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/webpack/node_modules/schema-utils": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", - "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", - "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/websocket-driver": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", - "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", - "dev": true, - "dependencies": { - "http-parser-js": ">=0.5.1", - "safe-buffer": ">=5.1.0", - "websocket-extensions": ">=0.1.1" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/websocket-extensions": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", - "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, "node_modules/whatwg-url": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", @@ -11602,32 +5139,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/which-typed-array": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz", - "integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==", - "dev": true, - "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0", - "is-typed-array": "^1.1.10" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/wildcard": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz", - "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==", - "dev": true - }, "node_modules/word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", @@ -11643,51 +5154,12 @@ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "dev": true }, - "node_modules/ws": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", - "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", - "dev": true, - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/xtend": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.2.0.tgz", - "integrity": "sha512-SLt5uylT+4aoXxXuwtQp5ZnMMzhDb1Xkg4pEqc00WUJCQifPfV9Ub1VrNhp9kXkrjZD2I2Hl8WnjP37jzZLPZw==", - "dev": true, - "engines": { - "node": ">=0.4" - } - }, "node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, - "node_modules/yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", - "dev": true, - "engines": { - "node": ">= 6" - } - }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/package.json b/package.json index 3ff04ccca..5ba7933d8 100644 --- a/package.json +++ b/package.json @@ -7,8 +7,13 @@ "node": ">=16.0.0" }, "scripts": { - "start": "webpack serve --config ./webpack.dev.js --open", - "build": "webpack --config ./webpack.prod.js" + "start": "vite", + "build": "vite build", + "lint": "yarn check:eslint && yarn check:prettier", + "check:eslint": "eslint src/*", + "check:prettier": "prettier --check .", + "fix:prettier": "prettier --write .", + "typecheck": "tsc --noEmit" }, "keywords": [], "author": "Ajay Bura", @@ -19,7 +24,6 @@ "@khanacademy/simple-markdown": "0.8.6", "@matrix-org/olm": "3.2.14", "@tippyjs/react": "4.2.6", - "babel-polyfill": "6.26.0", "blurhash": "2.0.4", "browser-encrypt-attachment": "0.3.0", "dateformat": "5.0.3", @@ -46,37 +50,23 @@ "twemoji": "14.0.2" }, "devDependencies": { - "@babel/core": "7.20.5", - "@babel/preset-env": "7.20.2", - "@babel/preset-react": "7.18.6", - "assert": "2.0.0", - "babel-loader": "8.3.0", - "browserify-fs": "1.0.0", - "buffer": "6.0.3", - "clean-webpack-plugin": "4.0.0", - "copy-webpack-plugin": "11.0.0", - "crypto-browserify": "3.12.0", - "css-loader": "6.7.2", - "css-minimizer-webpack-plugin": "4.2.2", + "@rollup/plugin-wasm": "6.1.1", + "@types/react": "18.0.26", + "@types/react-dom": "18.0.9", + "@typescript-eslint/eslint-plugin": "5.46.1", + "@typescript-eslint/parser": "5.46.1", + "@vitejs/plugin-react": "3.0.0", "eslint": "8.29.0", "eslint-config-airbnb": "19.0.4", + "eslint-config-prettier": "8.5.0", "eslint-plugin-import": "2.26.0", "eslint-plugin-jsx-a11y": "6.6.1", "eslint-plugin-react": "7.31.11", "eslint-plugin-react-hooks": "4.6.0", - "html-loader": "4.2.0", - "html-webpack-plugin": "5.5.0", - "mini-css-extract-plugin": "2.7.2", - "path-browserify": "1.0.1", + "prettier": "2.8.1", "sass": "1.56.2", - "sass-loader": "13.2.0", - "stream-browserify": "3.0.0", - "style-loader": "3.3.1", - "url": "0.11.0", - "util": "0.12.5", - "webpack": "5.75.0", - "webpack-cli": "5.0.1", - "webpack-dev-server": "4.11.1", - "webpack-merge": "5.8.0" + "typescript": "4.9.4", + "vite": "4.0.1", + "vite-plugin-static-copy": "0.13.0" } } diff --git a/public/index.html b/public/index.html deleted file mode 100644 index 34a000375..000000000 --- a/public/index.html +++ /dev/null @@ -1,50 +0,0 @@ - - - - - - - Cinny - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - - - - \ No newline at end of file diff --git a/public/manifest.json b/public/manifest.json index 21ae4f0dc..f1d4a8827 100644 --- a/public/manifest.json +++ b/public/manifest.json @@ -11,49 +11,49 @@ "theme_color": "#fff", "icons": [ { - "src": "android-chrome-36x36.png", + "src": "/public/android/android-chrome-36x36.png", "sizes": "36x36", "type": "image/png" }, { - "src": "android-chrome-48x48.png", + "src": "/public/android/android-chrome-48x48.png", "sizes": "48x48", "type": "image/png" }, { - "src": "android-chrome-72x72.png", + "src": "/public/android/android-chrome-72x72.png", "sizes": "72x72", "type": "image/png" }, { - "src": "android-chrome-96x96.png", + "src": "/public/android/android-chrome-96x96.png", "sizes": "96x96", "type": "image/png" }, { - "src": "android-chrome-144x144.png", + "src": "/public/android/android-chrome-144x144.png", "sizes": "144x144", "type": "image/png" }, { - "src": "android-chrome-192x192.png", + "src": "/public/android/android-chrome-192x192.png", "sizes": "192x192", "type": "image/png" }, { - "src": "android-chrome-256x256.png", + "src": "/public/android/android-chrome-256x256.png", "sizes": "256x256", "type": "image/png" }, { - "src": "android-chrome-384x384.png", + "src": "/public/android/android-chrome-384x384.png", "sizes": "384x384", "type": "image/png" }, { - "src": "android-chrome-512x512.png", + "src": "/public/android/android-chrome-512x512.png", "sizes": "512x512", "type": "image/png" } ] -} \ No newline at end of file +} diff --git a/src/client/initMatrix.js b/src/client/initMatrix.js index cd9615738..420f3154e 100644 --- a/src/client/initMatrix.js +++ b/src/client/initMatrix.js @@ -1,5 +1,6 @@ import EventEmitter from 'events'; import * as sdk from 'matrix-js-sdk'; +import Olm from '@matrix-org/olm'; // import { logger } from 'matrix-js-sdk/lib/logger'; import { secret } from './state/auth'; @@ -10,7 +11,7 @@ import Notifications from './state/Notifications'; import { cryptoCallbacks } from './state/secretStorageKeys'; import navigation from './state/navigation'; -global.Olm = require('@matrix-org/olm'); +global.Olm = Olm; // logger.disableAll(); @@ -78,7 +79,7 @@ class InitMatrix extends EventEmitter { this.emit('init_loading_finished'); this.notifications._initNoti(); } else { - this.notifications._initNoti(); + this.notifications?._initNoti(); } }, RECONNECTING: () => { diff --git a/src/index.jsx b/src/index.jsx index 55f8656b1..a252f6f05 100644 --- a/src/index.jsx +++ b/src/index.jsx @@ -9,7 +9,4 @@ import App from './app/pages/App'; settings.applyTheme(); -ReactDom.render( - , - document.getElementById('root'), -); +ReactDom.render(, document.getElementById('root')); diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 000000000..e109a97cc --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,14 @@ +{ + "compilerOptions": { + "sourceMap": true, + "jsx": "react", + "target": "ES6", + "allowJs": true, + "esModuleInterop": true, + "moduleResolution": "Node", + "outDir": "dist", + "skipLibCheck": true + }, + "exclude": ["node_modules", "dist"], + "include": ["src"] +} diff --git a/vite.config.js b/vite.config.js new file mode 100644 index 000000000..b46913be7 --- /dev/null +++ b/vite.config.js @@ -0,0 +1,44 @@ +import { defineConfig } from 'vite'; +import react from '@vitejs/plugin-react'; +import { wasm } from '@rollup/plugin-wasm'; +import { viteStaticCopy } from 'vite-plugin-static-copy'; + +const copyFiles = { + targets: [ + { + src: 'node_modules/@matrix-org/olm/olm.wasm', + dest: '', + }, + { + src: '_redirects', + dest: '', + }, + { + src: 'config.json', + dest: '', + }, + { + src: 'public/res/android', + dest: 'public/', + } + ], +} + +export default defineConfig({ + appType: 'spa', + publicDir: false, + server: { + port: 8080, + host: true, + }, + plugins: [ + viteStaticCopy(copyFiles), + wasm(), + react(), + ], + build: { + outDir: 'dist', + sourcemap: true, + copyPublicDir: false, + }, +}); diff --git a/webpack.common.js b/webpack.common.js deleted file mode 100644 index bbf6871b4..000000000 --- a/webpack.common.js +++ /dev/null @@ -1,66 +0,0 @@ -const HtmlWebpackPlugin = require('html-webpack-plugin'); -const CopyPlugin = require("copy-webpack-plugin"); -const webpack = require('webpack'); - -module.exports = { - entry: { - polyfill: 'babel-polyfill', - main: './src/index.jsx' - }, - resolve: { - extensions: ['.js', '.jsx'], - fallback: { - 'crypto': require.resolve('crypto-browserify'), - 'path': require.resolve('path-browserify'), - 'fs': require.resolve('browserify-fs'), - 'stream': require.resolve('stream-browserify'), - 'util': require.resolve('util/'), - 'assert': require.resolve('assert/'), - 'url': require.resolve('url/'), - 'buffer': require.resolve('buffer'), - } - }, - node: { - global: true, - }, - module: { - rules: [ - { - test: /\.jsx?$/, - exclude: /node_modules/, - use: { - loader: 'babel-loader', - options: { - presets: ['@babel/preset-env', '@babel/preset-react'], - }, - }, - }, - { - test: /\.html$/, - use: ['html-loader'], - }, - { - test: /\.(png|jpe?g|gif|otf|ttf|woff|woff2|ogg)$/, - type: 'asset/resource', - }, - { - test: /\.svg$/, - type: 'asset/inline', - } - ], - }, - plugins: [ - new HtmlWebpackPlugin({ template: './public/index.html' }), - new CopyPlugin({ - patterns: [ - { from: 'node_modules/@matrix-org/olm/olm.wasm' }, - { from: '_redirects' }, - { from: 'config.json' }, - { from: 'public/res/android'} - ], - }), - new webpack.ProvidePlugin({ - Buffer: ['buffer', 'Buffer'], - }), - ], -}; diff --git a/webpack.dev.js b/webpack.dev.js deleted file mode 100644 index 2cfa2df74..000000000 --- a/webpack.dev.js +++ /dev/null @@ -1,27 +0,0 @@ -const path = require('path'); -const common = require('./webpack.common'); -const { merge } = require('webpack-merge'); - -module.exports = merge(common, { - mode: 'development', - output: { - path: path.resolve(__dirname, 'dist'), - filename: '[name].bundle.js', - publicPath: '/', - }, - devServer: { - historyApiFallback: true, - }, - module: { - rules: [ - { - test: /\.s?css$/, - use: [ - 'style-loader', - 'css-loader', - 'sass-loader', - ], - }, - ], - }, -}); diff --git a/webpack.prod.js b/webpack.prod.js deleted file mode 100644 index eea1eb873..000000000 --- a/webpack.prod.js +++ /dev/null @@ -1,39 +0,0 @@ -const path = require('path'); -const common = require('./webpack.common'); -const { merge } = require('webpack-merge'); -const MiniCssExtractPlugin = require('mini-css-extract-plugin'); -const CssMinimizerPlugin = require('css-minimizer-webpack-plugin'); -const { CleanWebpackPlugin } = require('clean-webpack-plugin'); - -module.exports = merge(common, { - mode: 'production', - output: { - path: path.resolve(__dirname, 'dist'), - filename: '[name].[contenthash].bundle.js', - }, - optimization: { - minimize: true, - minimizer: [ - '...', - new CssMinimizerPlugin(), - ], - }, - module: { - rules: [ - { - test: /\.s?css$/, - use: [ - MiniCssExtractPlugin.loader, - 'css-loader', - 'sass-loader', - ], - }, - ], - }, - plugins: [ - new CleanWebpackPlugin(), - new MiniCssExtractPlugin({ - filename: '[name].[contenthash].bundle.css', - }), - ], -}); From e5e3f5f0a3542ce9b0c0205d176b4e05adc602e1 Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Sat, 14 Jan 2023 18:51:42 +0530 Subject: [PATCH 0999/1531] Add jsdelivr cdn for twemoji --- src/app/organisms/emoji-board/EmojiBoard.jsx | 209 ++++++++++--------- src/app/organisms/room/RoomViewCmdBar.jsx | 39 ++-- src/util/twemojify.jsx | 9 +- 3 files changed, 137 insertions(+), 120 deletions(-) diff --git a/src/app/organisms/emoji-board/EmojiBoard.jsx b/src/app/organisms/emoji-board/EmojiBoard.jsx index d9762323c..84c413064 100644 --- a/src/app/organisms/emoji-board/EmojiBoard.jsx +++ b/src/app/organisms/emoji-board/EmojiBoard.jsx @@ -13,6 +13,7 @@ import cons from '../../../client/state/cons'; import navigation from '../../../client/state/navigation'; import AsyncSearch from '../../../util/AsyncSearch'; import { addRecentEmoji, getRecentEmojis } from './recent'; +import { TWEMOJI_BASE_URL } from '../../../util/twemojify'; import Text from '../../atoms/text/Text'; import RawIcon from '../../atoms/system-icons/RawIcon'; @@ -46,45 +47,49 @@ const EmojiGroup = React.memo(({ name, groupEmojis }) => { const emoji = groupEmojis[emojiIndex]; emojiRow.push( - { - emoji.hexcode - // This is a unicode emoji, and should be rendered with twemoji - ? parse(twemoji.parse( - emoji.unicode, - { - attributes: () => ({ - unicode: emoji.unicode, - shortcodes: emoji.shortcodes?.toString(), - hexcode: emoji.hexcode, - loading: 'lazy', - }), - }, - )) - // This is a custom emoji, and should be render as an mxc - : ( - {emoji.shortcode} - ) - } - , + {emoji.hexcode ? ( + // This is a unicode emoji, and should be rendered with twemoji + parse( + twemoji.parse(emoji.unicode, { + attributes: () => ({ + unicode: emoji.unicode, + shortcodes: emoji.shortcodes?.toString(), + hexcode: emoji.hexcode, + loading: 'lazy', + }), + base: TWEMOJI_BASE_URL, + }) + ) + ) : ( + // This is a custom emoji, and should be render as an mxc + {emoji.shortcode} + )} + ); } - emojiBoard.push(
    {emojiRow}
    ); + emojiBoard.push( +
    + {emojiRow} +
    + ); } return emojiBoard; } return (
    - {name} + + {name} + {groupEmojis.length !== 0 &&
    {getEmojiBoard()}
    }
    ); @@ -92,17 +97,16 @@ const EmojiGroup = React.memo(({ name, groupEmojis }) => { EmojiGroup.propTypes = { name: PropTypes.string.isRequired, - groupEmojis: PropTypes.arrayOf(PropTypes.shape({ - length: PropTypes.number, - unicode: PropTypes.string, - hexcode: PropTypes.string, - mxc: PropTypes.string, - shortcode: PropTypes.string, - shortcodes: PropTypes.oneOfType([ - PropTypes.string, - PropTypes.arrayOf(PropTypes.string), - ]), - })).isRequired, + groupEmojis: PropTypes.arrayOf( + PropTypes.shape({ + length: PropTypes.number, + unicode: PropTypes.string, + hexcode: PropTypes.string, + mxc: PropTypes.string, + shortcode: PropTypes.string, + shortcodes: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.string)]), + }) + ).isRequired, }; const asyncSearch = new AsyncSearch(); @@ -128,7 +132,13 @@ function SearchedEmoji() { if (searchedEmojis === null) return false; - return ; + return ( + + ); } function EmojiBoard({ onSelect, searchRef }) { @@ -146,7 +156,10 @@ function EmojiBoard({ onSelect, searchRef }) { if (typeof shortcodes === 'undefined') shortcodes = undefined; else shortcodes = shortcodes.split(','); return { - unicode, hexcode, shortcodes, mxc, + unicode, + hexcode, + shortcodes, + mxc, }; } @@ -211,10 +224,9 @@ function EmojiBoard({ onSelect, searchRef }) { const parentIds = initMatrix.roomList.getAllParentSpaces(room.roomId); const parentRooms = [...parentIds].map((id) => mx.getRoom(id)); if (room) { - const packs = getRelevantPacks( - room.client, - [room, ...parentRooms], - ).filter((pack) => pack.getEmojis().length !== 0); + const packs = getRelevantPacks(room.client, [room, ...parentRooms]).filter( + (pack) => pack.getEmojis().length !== 0 + ); // Set an index for each pack so that we know where to jump when the user uses the nav for (let i = 0; i < packs.length; i += 1) { @@ -263,44 +275,41 @@ function EmojiBoard({ onSelect, searchRef }) { /> )}
    - { - availableEmojis.map((pack) => { - const src = initMatrix.matrixClient - .mxcUrlToHttp(pack.avatarUrl ?? pack.getEmojis()[0].mxc); - return ( - openGroup(recentOffset + pack.packIndex)} - src={src} - key={pack.packIndex} - tooltip={pack.displayName ?? 'Unknown'} - tooltipPlacement="left" - isImage - /> - ); - }) - } + {availableEmojis.map((pack) => { + const src = initMatrix.matrixClient.mxcUrlToHttp( + pack.avatarUrl ?? pack.getEmojis()[0].mxc + ); + return ( + openGroup(recentOffset + pack.packIndex)} + src={src} + key={pack.packIndex} + tooltip={pack.displayName ?? 'Unknown'} + tooltipPlacement="left" + isImage + /> + ); + })}
    - { - [ - [0, EmojiIC, 'Smilies'], - [1, DogIC, 'Animals'], - [2, CupIC, 'Food'], - [3, BallIC, 'Activities'], - [4, PhotoIC, 'Travel'], - [5, BulbIC, 'Objects'], - [6, PeaceIC, 'Symbols'], - [7, FlagIC, 'Flags'], - ].map(([indx, ico, name]) => ( - openGroup(recentOffset + availableEmojis.length + indx)} - key={indx} - src={ico} - tooltip={name} - tooltipPlacement="left" - /> - )) - } + {[ + [0, EmojiIC, 'Smilies'], + [1, DogIC, 'Animals'], + [2, CupIC, 'Food'], + [3, BallIC, 'Activities'], + [4, PhotoIC, 'Travel'], + [5, BulbIC, 'Objects'], + [6, PeaceIC, 'Symbols'], + [7, FlagIC, 'Flags'], + ].map(([indx, ico, name]) => ( + openGroup(recentOffset + availableEmojis.length + indx)} + key={indx} + src={ico} + tooltip={name} + tooltipPlacement="left" + /> + ))}
    @@ -313,27 +322,25 @@ function EmojiBoard({ onSelect, searchRef }) {
    - {recentEmojis.length > 0 && } - { - availableEmojis.map((pack) => ( - - )) - } - { - emojiGroups.map((group) => ( - - )) - } + {recentEmojis.length > 0 && ( + + )} + {availableEmojis.map((pack) => ( + + ))} + {emojiGroups.map((group) => ( + + ))}
    -
    { parse(twemoji.parse('🙂')) }
    +
    {parse(twemoji.parse('🙂', { base: TWEMOJI_BASE_URL }))}
    :slight_smile:
    diff --git a/src/app/organisms/room/RoomViewCmdBar.jsx b/src/app/organisms/room/RoomViewCmdBar.jsx index 8c390a068..0d21123bd 100644 --- a/src/app/organisms/room/RoomViewCmdBar.jsx +++ b/src/app/organisms/room/RoomViewCmdBar.jsx @@ -5,7 +5,7 @@ import './RoomViewCmdBar.scss'; import parse from 'html-react-parser'; import twemoji from 'twemoji'; -import { twemojify } from '../../../util/twemojify'; +import { twemojify, TWEMOJI_BASE_URL } from '../../../util/twemojify'; import initMatrix from '../../../client/initMatrix'; import { getEmojiForCompletion } from '../emoji-board/custom-emoji'; @@ -31,7 +31,7 @@ CmdItem.propTypes = { function renderSuggestions({ prefix, option, suggestions }, fireCmd) { function renderCmdSuggestions(cmdPrefix, cmds) { - const cmdOptString = (typeof option === 'string') ? `/${option}` : '/?'; + const cmdOptString = typeof option === 'string' ? `/${option}` : '/?'; return cmds.map((cmd) => ( ({ unicode: emoji.unicode, shortcodes: emoji.shortcodes?.toString(), }), - }, - )); + base: TWEMOJI_BASE_URL, + }) + ); } // Render a custom emoji @@ -87,10 +87,12 @@ function renderSuggestions({ prefix, option, suggestions }, fireCmd) { return emos.map((emoji) => ( fireCmd({ - prefix: emPrefix, - result: emoji, - })} + onClick={() => + fireCmd({ + prefix: emPrefix, + result: emoji, + }) + } > {renderEmoji(emoji)} {`:${emoji.shortcode}:`} @@ -187,10 +189,13 @@ function RoomViewCmdBar({ roomId, roomTimeline, viewEvent }) { }); }, '@': () => { - const members = mx.getRoom(roomId).getJoinedMembers().map((member) => ({ - name: member.name, - userId: member.userId.slice(1), - })); + const members = mx + .getRoom(roomId) + .getJoinedMembers() + .map((member) => ({ + name: member.name, + userId: member.userId.slice(1), + })); asyncSearch.setup(members, { keys: ['name', 'userId'], limit: 20 }); const endIndex = members.length > 20 ? 20 : members.length; setCmd({ prefix, suggestions: members.slice(0, endIndex) }); @@ -277,9 +282,7 @@ function RoomViewCmdBar({ roomId, roomTimeline, viewEvent }) {
    -
    - { renderSuggestions(cmd, fireCmd) } -
    +
    {renderSuggestions(cmd, fireCmd)}
    diff --git a/src/util/twemojify.jsx b/src/util/twemojify.jsx index 0a4fede73..abe82a664 100644 --- a/src/util/twemojify.jsx +++ b/src/util/twemojify.jsx @@ -6,6 +6,8 @@ import parse from 'html-react-parser'; import twemoji from 'twemoji'; import { sanitizeText } from './sanitize'; +export const TWEMOJI_BASE_URL = 'https://cdn.jsdelivr.net/gh/twitter/twemoji@14.0.2/assets/'; + const Math = lazy(() => import('../app/atoms/math/Math')); const mathOptions = { @@ -38,11 +40,16 @@ const mathOptions = { export function twemojify(text, opts, linkify = false, sanitize = true, maths = false) { if (typeof text !== 'string') return text; let content = text; + const options = opts ?? { base: TWEMOJI_BASE_URL }; + if (!options.base) { + options.base = TWEMOJI_BASE_URL; + } if (sanitize) { content = sanitizeText(content); } - content = twemoji.parse(content, opts); + + content = twemoji.parse(content, options); if (linkify) { content = linkifyHtml(content, { target: '_blank', From 9a34daa2bc2d3d0a2a1ebadb419b916c7ba1bedd Mon Sep 17 00:00:00 2001 From: Stefano Pigozzi Date: Sun, 15 Jan 2023 05:14:16 +0100 Subject: [PATCH 1000/1531] Set `accept` attribute to `image/*` in ImageUpload (#989) That way, browsers will suggest to the users to upload an image file instead of any kind of file. The behaviour is in-line with Element's, which specifies the same attribute when selecting an avatar. Please note that it does not prevent users from uploading non-image files as avatars, as browsers interpret that attribute as a mere suggestion, which can be bypassed in the file select dialog. Partially fixes #982. --- src/app/molecules/image-upload/ImageUpload.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/molecules/image-upload/ImageUpload.jsx b/src/app/molecules/image-upload/ImageUpload.jsx index 34d0d4be1..53fc7e161 100644 --- a/src/app/molecules/image-upload/ImageUpload.jsx +++ b/src/app/molecules/image-upload/ImageUpload.jsx @@ -74,7 +74,7 @@ function ImageUpload({ {uploadPromise ? 'Cancel' : 'Remove'} )} - + ); } From 38bbc1c6f5b4eca8a6052cbce0d72df7434fe2b4 Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Sun, 15 Jan 2023 09:52:58 +0530 Subject: [PATCH 1001/1531] Vite plugin to add svg as inline data (#1072) * add vite plugin to add svg as inline data * Add node types package --- package-lock.json | 17 +++++++++++++++++ package.json | 2 ++ src/app/atoms/system-icons/RawIcon.jsx | 12 +++++------- vite.config.js | 2 ++ viteSvgLoader.ts | 16 ++++++++++++++++ 5 files changed, 42 insertions(+), 7 deletions(-) create mode 100644 viteSvgLoader.ts diff --git a/package-lock.json b/package-lock.json index b60abb5c5..673ba846b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -41,6 +41,7 @@ }, "devDependencies": { "@rollup/plugin-wasm": "6.1.1", + "@types/node": "18.11.18", "@types/react": "18.0.26", "@types/react-dom": "18.0.9", "@typescript-eslint/eslint-plugin": "5.46.1", @@ -53,6 +54,7 @@ "eslint-plugin-jsx-a11y": "6.6.1", "eslint-plugin-react": "7.31.11", "eslint-plugin-react-hooks": "4.6.0", + "mini-svg-data-uri": "1.4.4", "prettier": "2.8.1", "sass": "1.56.2", "typescript": "4.9.4", @@ -1054,6 +1056,12 @@ "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", "dev": true }, + "node_modules/@types/node": { + "version": "18.11.18", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.18.tgz", + "integrity": "sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA==", + "dev": true + }, "node_modules/@types/prop-types": { "version": "15.7.5", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", @@ -3768,6 +3776,15 @@ "node": ">=8.6" } }, + "node_modules/mini-svg-data-uri": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/mini-svg-data-uri/-/mini-svg-data-uri-1.4.4.tgz", + "integrity": "sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==", + "dev": true, + "bin": { + "mini-svg-data-uri": "cli.js" + } + }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", diff --git a/package.json b/package.json index 5ba7933d8..8ea3c31ce 100644 --- a/package.json +++ b/package.json @@ -51,6 +51,7 @@ }, "devDependencies": { "@rollup/plugin-wasm": "6.1.1", + "@types/node": "18.11.18", "@types/react": "18.0.26", "@types/react-dom": "18.0.9", "@typescript-eslint/eslint-plugin": "5.46.1", @@ -63,6 +64,7 @@ "eslint-plugin-jsx-a11y": "6.6.1", "eslint-plugin-react": "7.31.11", "eslint-plugin-react-hooks": "4.6.0", + "mini-svg-data-uri": "1.4.4", "prettier": "2.8.1", "sass": "1.56.2", "typescript": "4.9.4", diff --git a/src/app/atoms/system-icons/RawIcon.jsx b/src/app/atoms/system-icons/RawIcon.jsx index 08acc66bb..a6697f4f4 100644 --- a/src/app/atoms/system-icons/RawIcon.jsx +++ b/src/app/atoms/system-icons/RawIcon.jsx @@ -2,20 +2,18 @@ import React from 'react'; import PropTypes from 'prop-types'; import './RawIcon.scss'; -function RawIcon({ - color, size, src, isImage, -}) { +function RawIcon({ color, size, src, isImage }) { const style = {}; if (color !== null) style.backgroundColor = color; if (isImage) { style.backgroundColor = 'transparent'; - style.backgroundImage = `url(${src})`; + style.backgroundImage = `url("${src}")`; } else { - style.WebkitMaskImage = `url(${src})`; - style.maskImage = `url(${src})`; + style.WebkitMaskImage = `url("${src}")`; + style.maskImage = `url("${src}")`; } - return ; + return ; } RawIcon.defaultProps = { diff --git a/vite.config.js b/vite.config.js index b46913be7..7ca1baff1 100644 --- a/vite.config.js +++ b/vite.config.js @@ -2,6 +2,7 @@ import { defineConfig } from 'vite'; import react from '@vitejs/plugin-react'; import { wasm } from '@rollup/plugin-wasm'; import { viteStaticCopy } from 'vite-plugin-static-copy'; +import { svgLoader } from './viteSvgLoader'; const copyFiles = { targets: [ @@ -33,6 +34,7 @@ export default defineConfig({ }, plugins: [ viteStaticCopy(copyFiles), + svgLoader(), wasm(), react(), ], diff --git a/viteSvgLoader.ts b/viteSvgLoader.ts new file mode 100644 index 000000000..a119e3ed3 --- /dev/null +++ b/viteSvgLoader.ts @@ -0,0 +1,16 @@ +import svgToMiniDataURI from 'mini-svg-data-uri'; +import type { Plugin } from 'rollup'; +import fs from 'fs'; + +// TODO: remove this once https://github.com/vitejs/vite/pull/2909 gets merged +export const svgLoader = (): Plugin => ({ + name: 'vite-svg-patch-plugin', + transform: (code, id) => { + if (id.endsWith('.svg')) { + const extractedSvg = fs.readFileSync(id, 'utf8'); + const datauri = svgToMiniDataURI.toSrcset(extractedSvg); + return `export default "${datauri}"`; + } + return code; + }, +}); From 4ea14c853ee7b9c1a211a08e386fb323870e2ec2 Mon Sep 17 00:00:00 2001 From: Krishan <33421343+kfiven@users.noreply.github.com> Date: Sun, 15 Jan 2023 16:16:40 +1100 Subject: [PATCH 1002/1531] Release v2.2.3 --- package-lock.json | 4 ++-- package.json | 2 +- src/client/state/cons.js | 10 ++++++++-- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 673ba846b..ffea90a93 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "cinny", - "version": "2.2.2", + "version": "2.2.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "cinny", - "version": "2.2.2", + "version": "2.2.3", "license": "MIT", "dependencies": { "@fontsource/inter": "4.5.14", diff --git a/package.json b/package.json index 8ea3c31ce..4082853ce 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cinny", - "version": "2.2.2", + "version": "2.2.3", "description": "Yet another matrix client", "main": "index.js", "engines": { diff --git a/src/client/state/cons.js b/src/client/state/cons.js index 785047d78..584eaba46 100644 --- a/src/client/state/cons.js +++ b/src/client/state/cons.js @@ -1,5 +1,5 @@ const cons = { - version: '2.2.2', + version: '2.2.3', secretKey: { ACCESS_TOKEN: 'cinny_access_token', DEVICE_ID: 'cinny_device_id', @@ -12,7 +12,13 @@ const cons = { HOME: 'home', DIRECTS: 'dm', }, - supportEventTypes: ['m.room.create', 'm.room.message', 'm.room.encrypted', 'm.room.member', 'm.sticker'], + supportEventTypes: [ + 'm.room.create', + 'm.room.message', + 'm.room.encrypted', + 'm.room.member', + 'm.sticker', + ], notifs: { DEFAULT: 'default', ALL_MESSAGES: 'all_messages', From 3ad143228d544ff1d6a0645284a63a444ae1d537 Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Mon, 30 Jan 2023 15:20:13 +1100 Subject: [PATCH 1003/1531] Use relative paths for build (#1094) --- vite.config.js | 1 + 1 file changed, 1 insertion(+) diff --git a/vite.config.js b/vite.config.js index 7ca1baff1..f4f588e5e 100644 --- a/vite.config.js +++ b/vite.config.js @@ -28,6 +28,7 @@ const copyFiles = { export default defineConfig({ appType: 'spa', publicDir: false, + base: "", server: { port: 8080, host: true, From 374d2d1962c92cb75c747c7cfa1d86f2fd7ef736 Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Mon, 30 Jan 2023 15:20:53 +1100 Subject: [PATCH 1004/1531] Add node polyfills (#1093) * Add node polyfills * remove unused polyfill * enable fs in node polyfill * remove polyfill aliases and crypto * Fix build error * Fix buffer injection --- package-lock.json | 138 ++++++++++++++++++++++++++++++++++++++++++++++ package.json | 3 + vite.config.js | 21 +++++++ 3 files changed, 162 insertions(+) diff --git a/package-lock.json b/package-lock.json index ffea90a93..80aea6cb2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -40,6 +40,8 @@ "twemoji": "14.0.2" }, "devDependencies": { + "@esbuild-plugins/node-globals-polyfill": "0.2.3", + "@rollup/plugin-inject": "5.0.3", "@rollup/plugin-wasm": "6.1.1", "@types/node": "18.11.18", "@types/react": "18.0.26", @@ -47,6 +49,7 @@ "@typescript-eslint/eslint-plugin": "5.46.1", "@typescript-eslint/parser": "5.46.1", "@vitejs/plugin-react": "3.0.0", + "buffer": "6.0.3", "eslint": "8.29.0", "eslint-config-airbnb": "19.0.4", "eslint-config-prettier": "8.5.0", @@ -454,6 +457,15 @@ "node": ">=6.9.0" } }, + "node_modules/@esbuild-plugins/node-globals-polyfill": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@esbuild-plugins/node-globals-polyfill/-/node-globals-polyfill-0.2.3.tgz", + "integrity": "sha512-r3MIryXDeXDOZh7ih1l/yE9ZLORCd5e8vWg02azWRGj5SPTuoh69A2AIyn0Z31V/kHBfZ4HgWJ+OK3GTTwLmnw==", + "dev": true, + "peerDependencies": { + "esbuild": "*" + } + }, "node_modules/@esbuild/android-arm": { "version": "0.16.9", "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.16.9.tgz", @@ -1010,6 +1022,34 @@ "resolved": "https://registry.npmjs.org/@react-dnd/shallowequal/-/shallowequal-3.0.1.tgz", "integrity": "sha512-XjDVbs3ZU16CO1h5Q3Ew2RPJqmZBDE/EVf1LYp6ePEffs3V/MX9ZbL5bJr8qiK5SbGmUMuDoaFgyKacYz8prRA==" }, + "node_modules/@rollup/plugin-inject": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@rollup/plugin-inject/-/plugin-inject-5.0.3.tgz", + "integrity": "sha512-411QlbL+z2yXpRWFXSmw/teQRMkXcAAC8aYTemc15gwJRpvEVDQwoe+N/HTFD8RFG8+88Bme9DK2V9CVm7hJdA==", + "dev": true, + "dependencies": { + "@rollup/pluginutils": "^5.0.1", + "estree-walker": "^2.0.2", + "magic-string": "^0.27.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-inject/node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true + }, "node_modules/@rollup/plugin-wasm": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/@rollup/plugin-wasm/-/plugin-wasm-6.1.1.tgz", @@ -1027,6 +1067,34 @@ } } }, + "node_modules/@rollup/pluginutils": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.2.tgz", + "integrity": "sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==", + "dev": true, + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/pluginutils/node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true + }, "node_modules/@tippyjs/react": { "version": "4.2.6", "resolved": "https://registry.npmjs.org/@tippyjs/react/-/react-4.2.6.tgz", @@ -1039,6 +1107,12 @@ "react-dom": ">=16.8" } }, + "node_modules/@types/estree": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.0.tgz", + "integrity": "sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==", + "dev": true + }, "node_modules/@types/events": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", @@ -1594,6 +1668,26 @@ "resolved": "https://registry.npmjs.org/base-x/-/base-x-4.0.0.tgz", "integrity": "sha512-FuwxlW4H5kh37X/oW59pwTzzTKRzfrrQwhmyspRM7swOEZcHtDZSCt45U6oKgtuFE+WYPblePMVIPR4RZrh/hw==" }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", @@ -1671,6 +1765,30 @@ "base-x": "^4.0.0" } }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, "node_modules/call-bind": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", @@ -3174,6 +3292,26 @@ "entities": "^4.3.0" } }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/ignore": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.1.tgz", diff --git a/package.json b/package.json index 4082853ce..a0e7bacef 100644 --- a/package.json +++ b/package.json @@ -50,6 +50,8 @@ "twemoji": "14.0.2" }, "devDependencies": { + "@esbuild-plugins/node-globals-polyfill": "0.2.3", + "@rollup/plugin-inject": "5.0.3", "@rollup/plugin-wasm": "6.1.1", "@types/node": "18.11.18", "@types/react": "18.0.26", @@ -57,6 +59,7 @@ "@typescript-eslint/eslint-plugin": "5.46.1", "@typescript-eslint/parser": "5.46.1", "@vitejs/plugin-react": "3.0.0", + "buffer": "6.0.3", "eslint": "8.29.0", "eslint-config-airbnb": "19.0.4", "eslint-config-prettier": "8.5.0", diff --git a/vite.config.js b/vite.config.js index f4f588e5e..979e9aa0b 100644 --- a/vite.config.js +++ b/vite.config.js @@ -2,6 +2,8 @@ import { defineConfig } from 'vite'; import react from '@vitejs/plugin-react'; import { wasm } from '@rollup/plugin-wasm'; import { viteStaticCopy } from 'vite-plugin-static-copy'; +import { NodeGlobalsPolyfillPlugin } from '@esbuild-plugins/node-globals-polyfill'; +import inject from '@rollup/plugin-inject'; import { svgLoader } from './viteSvgLoader'; const copyFiles = { @@ -39,9 +41,28 @@ export default defineConfig({ wasm(), react(), ], + optimizeDeps: { + esbuildOptions: { + define: { + global: 'globalThis' + }, + plugins: [ + // Enable esbuild polyfill plugins + NodeGlobalsPolyfillPlugin({ + process: false, + buffer: true, + }), + ] + } + }, build: { outDir: 'dist', sourcemap: true, copyPublicDir: false, + rollupOptions: { + plugins: [ + inject({ Buffer: ['buffer', 'Buffer'] }) + ] + } }, }); From a6fb44e1abe9ad48136dee8e7d053e639f37bedc Mon Sep 17 00:00:00 2001 From: Krishan <33421343+kfiven@users.noreply.github.com> Date: Mon, 30 Jan 2023 15:27:17 +1100 Subject: [PATCH 1005/1531] Release v2.2.4 --- package-lock.json | 4 ++-- package.json | 2 +- src/client/state/cons.js | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 80aea6cb2..bef7acdd2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "cinny", - "version": "2.2.3", + "version": "2.2.4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "cinny", - "version": "2.2.3", + "version": "2.2.4", "license": "MIT", "dependencies": { "@fontsource/inter": "4.5.14", diff --git a/package.json b/package.json index a0e7bacef..7e026b7b0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cinny", - "version": "2.2.3", + "version": "2.2.4", "description": "Yet another matrix client", "main": "index.js", "engines": { diff --git a/src/client/state/cons.js b/src/client/state/cons.js index 584eaba46..86ddab98d 100644 --- a/src/client/state/cons.js +++ b/src/client/state/cons.js @@ -1,5 +1,5 @@ const cons = { - version: '2.2.3', + version: '2.2.4', secretKey: { ACCESS_TOKEN: 'cinny_access_token', DEVICE_ID: 'cinny_device_id', From 44318d1ecd19700f010079d0836db7955fc23005 Mon Sep 17 00:00:00 2001 From: Krishan <33421343+kfiven@users.noreply.github.com> Date: Mon, 30 Jan 2023 15:46:56 +1100 Subject: [PATCH 1006/1531] Replace deprecated 'set-output' with '$GITHUB_OUTPUT' --- .github/workflows/prod-deploy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/prod-deploy.yml b/.github/workflows/prod-deploy.yml index fa09008a3..5f8a77cf4 100644 --- a/.github/workflows/prod-deploy.yml +++ b/.github/workflows/prod-deploy.yml @@ -36,7 +36,7 @@ jobs: timeout-minutes: 1 - name: Get version from tag id: vars - run: echo ::set-output name=tag::${GITHUB_REF#refs/*/} + run: echo "tag=${GITHUB_REF#refs/*/}" >> $GITHUB_OUTPUT - name: Create tar.gz run: tar -czvf cinny-${{ steps.vars.outputs.tag }}.tar.gz dist - name: Sign tar.gz From 78951a3bc4fe499e68b2d709cdfb46e23b187e01 Mon Sep 17 00:00:00 2001 From: Krishan <33421343+kfiven@users.noreply.github.com> Date: Wed, 8 Feb 2023 17:13:05 +1100 Subject: [PATCH 1007/1531] Rename LICENSE to LICENSE.md --- LICENSE => LICENSE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename LICENSE => LICENSE.md (99%) diff --git a/LICENSE b/LICENSE.md similarity index 99% rename from LICENSE rename to LICENSE.md index 1f7a28414..7d151b3c0 100644 --- a/LICENSE +++ b/LICENSE.md @@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. \ No newline at end of file +SOFTWARE. From e33a887055db2c62946940264977f1a74984b620 Mon Sep 17 00:00:00 2001 From: Krishan <33421343+kfiven@users.noreply.github.com> Date: Fri, 24 Feb 2023 17:28:04 +0530 Subject: [PATCH 1008/1531] Change license to AGPLv3 (#1115) * Add CLA github action * Change license to AGPLv3 --- .github/workflows/cla.yml | 36 +++ LICENSE | 661 ++++++++++++++++++++++++++++++++++++++ LICENSE.md | 21 -- README.md | 9 - package-lock.json | 2 +- package.json | 2 +- public/res/LICENSE | 395 ----------------------- public/res/README.md | 7 - 8 files changed, 699 insertions(+), 434 deletions(-) create mode 100644 .github/workflows/cla.yml create mode 100644 LICENSE delete mode 100644 LICENSE.md delete mode 100644 public/res/LICENSE delete mode 100644 public/res/README.md diff --git a/.github/workflows/cla.yml b/.github/workflows/cla.yml new file mode 100644 index 000000000..b433b8d94 --- /dev/null +++ b/.github/workflows/cla.yml @@ -0,0 +1,36 @@ +name: 'CLA Assistant' +on: + issue_comment: + types: [created] + pull_request_target: + types: [opened, closed, synchronize] + +jobs: + CLAssistant: + runs-on: ubuntu-latest + steps: + - name: 'CLA Assistant' + if: (github.event.comment.body == 'recheck' || github.event.comment.body == 'I have read the CLA Document and I hereby sign the CLA') || github.event_name == 'pull_request_target' + # Beta Release + uses: cla-assistant/github-action@v2.2.1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # the below token should have repo scope and must be manually added by you in the repository's secret + PERSONAL_ACCESS_TOKEN: ${{ secrets.CLA_PAT }} + with: + path-to-signatures: 'signatures.json' + path-to-document: 'https://github.com/cinnyapp/cla/blob/main/cla.md' # e.g. a CLA or a DCO document + # branch should not be protected + branch: 'main' + allowlist: ajbura,bot* + + #below are the optional inputs - If the optional inputs are not given, then default values will be taken + remote-organization-name: cinnyapp + remote-repository-name: cla + #create-file-commit-message: 'For example: Creating file for storing CLA Signatures' + #signed-commit-message: 'For example: $contributorName has signed the CLA in #$pullRequestNo' + #custom-notsigned-prcomment: 'pull request comment with Introductory message to ask new contributors to sign' + #custom-pr-sign-comment: 'The signature to be committed in order to sign the CLA' + #custom-allsigned-prcomment: 'pull request comment when all contributors has signed, defaults to **CLA Assistant Lite bot** All Contributors have signed the CLA.' + #lock-pullrequest-aftermerge: false - if you don't want this bot to automatically lock the pull request after merging (default - true) + #use-dco-flag: true - If you are using DCO instead of CLA diff --git a/LICENSE b/LICENSE new file mode 100644 index 000000000..bae94e189 --- /dev/null +++ b/LICENSE @@ -0,0 +1,661 @@ + GNU AFFERO GENERAL PUBLIC LICENSE + Version 3, 19 November 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU Affero General Public License is a free, copyleft license for +software and other kinds of works, specifically designed to ensure +cooperation with the community in the case of network server software. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +our General Public Licenses are intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + Developers that use our General Public Licenses protect your rights +with two steps: (1) assert copyright on the software, and (2) offer +you this License which gives you legal permission to copy, distribute +and/or modify the software. + + A secondary benefit of defending all users' freedom is that +improvements made in alternate versions of the program, if they +receive widespread use, become available for other developers to +incorporate. Many developers of free software are heartened and +encouraged by the resulting cooperation. However, in the case of +software used on network servers, this result may fail to come about. +The GNU General Public License permits making a modified version and +letting the public access it on a server without ever releasing its +source code to the public. + + The GNU Affero General Public License is designed specifically to +ensure that, in such cases, the modified source code becomes available +to the community. It requires the operator of a network server to +provide the source code of the modified version running there to the +users of that server. Therefore, public use of a modified version, on +a publicly accessible server, gives the public access to the source +code of the modified version. + + An older license, called the Affero General Public License and +published by Affero, was designed to accomplish similar goals. This is +a different license, not a version of the Affero GPL, but Affero has +released a new version of the Affero GPL which permits relicensing under +this license. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU Affero General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Remote Network Interaction; Use with the GNU General Public License. + + Notwithstanding any other provision of this License, if you modify the +Program, your modified version must prominently offer all users +interacting with it remotely through a computer network (if your version +supports such interaction) an opportunity to receive the Corresponding +Source of your version by providing access to the Corresponding Source +from a network server at no charge, through some standard or customary +means of facilitating copying of software. This Corresponding Source +shall include the Corresponding Source for any work covered by version 3 +of the GNU General Public License that is incorporated pursuant to the +following paragraph. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the work with which it is combined will remain governed by version +3 of the GNU General Public License. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU Affero General Public License from time to time. Such new versions +will be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU Affero General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU Affero General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU Affero General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If your software can interact with users remotely through a computer +network, you should also make sure that it provides a way for users to +get its source. For example, if your program is a web application, its +interface could display a "Source" link that leads users to an archive +of the code. There are many ways you could offer source, and different +solutions will be better for different programs; see section 13 for the +specific requirements. + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU AGPL, see +. \ No newline at end of file diff --git a/LICENSE.md b/LICENSE.md deleted file mode 100644 index 7d151b3c0..000000000 --- a/LICENSE.md +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2021-present Ajay Bura (ajbura) - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/README.md b/README.md index acf766299..0db8ab6c7 100644 --- a/README.md +++ b/README.md @@ -110,12 +110,3 @@ docker run -p 8080:80 cinny:latest ``` This will forward your `localhost` port 8080 to the container's port 80. You can visit the app in your browser by navigating to `http://localhost:8080`. - - -## License - -Copyright (c) 2021-present Ajay Bura (ajbura) - -Code licensed under the MIT License: - -Graphics licensed under CC-BY 4.0: diff --git a/package-lock.json b/package-lock.json index bef7acdd2..e004ee5c1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,7 +7,7 @@ "": { "name": "cinny", "version": "2.2.4", - "license": "MIT", + "license": "AGPL-3.0-only", "dependencies": { "@fontsource/inter": "4.5.14", "@fontsource/roboto": "4.5.8", diff --git a/package.json b/package.json index 7e026b7b0..0ff2338bc 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ }, "keywords": [], "author": "Ajay Bura", - "license": "MIT", + "license": "AGPL-3.0-only", "dependencies": { "@fontsource/inter": "4.5.14", "@fontsource/roboto": "4.5.8", diff --git a/public/res/LICENSE b/public/res/LICENSE deleted file mode 100644 index 4ea99c213..000000000 --- a/public/res/LICENSE +++ /dev/null @@ -1,395 +0,0 @@ -Attribution 4.0 International - -======================================================================= - -Creative Commons Corporation ("Creative Commons") is not a law firm and -does not provide legal services or legal advice. Distribution of -Creative Commons public licenses does not create a lawyer-client or -other relationship. Creative Commons makes its licenses and related -information available on an "as-is" basis. Creative Commons gives no -warranties regarding its licenses, any material licensed under their -terms and conditions, or any related information. Creative Commons -disclaims all liability for damages resulting from their use to the -fullest extent possible. - -Using Creative Commons Public Licenses - -Creative Commons public licenses provide a standard set of terms and -conditions that creators and other rights holders may use to share -original works of authorship and other material subject to copyright -and certain other rights specified in the public license below. The -following considerations are for informational purposes only, are not -exhaustive, and do not form part of our licenses. - - Considerations for licensors: Our public licenses are - intended for use by those authorized to give the public - permission to use material in ways otherwise restricted by - copyright and certain other rights. Our licenses are - irrevocable. Licensors should read and understand the terms - and conditions of the license they choose before applying it. - Licensors should also secure all rights necessary before - applying our licenses so that the public can reuse the - material as expected. Licensors should clearly mark any - material not subject to the license. This includes other CC- - licensed material, or material used under an exception or - limitation to copyright. More considerations for licensors: - wiki.creativecommons.org/Considerations_for_licensors - - Considerations for the public: By using one of our public - licenses, a licensor grants the public permission to use the - licensed material under specified terms and conditions. If - the licensor's permission is not necessary for any reason--for - example, because of any applicable exception or limitation to - copyright--then that use is not regulated by the license. Our - licenses grant only permissions under copyright and certain - other rights that a licensor has authority to grant. Use of - the licensed material may still be restricted for other - reasons, including because others have copyright or other - rights in the material. A licensor may make special requests, - such as asking that all changes be marked or described. - Although not required by our licenses, you are encouraged to - respect those requests where reasonable. More considerations - for the public: - wiki.creativecommons.org/Considerations_for_licensees - -======================================================================= - -Creative Commons Attribution 4.0 International Public License - -By exercising the Licensed Rights (defined below), You accept and agree -to be bound by the terms and conditions of this Creative Commons -Attribution 4.0 International Public License ("Public License"). To the -extent this Public License may be interpreted as a contract, You are -granted the Licensed Rights in consideration of Your acceptance of -these terms and conditions, and the Licensor grants You such rights in -consideration of benefits the Licensor receives from making the -Licensed Material available under these terms and conditions. - - -Section 1 -- Definitions. - - a. Adapted Material means material subject to Copyright and Similar - Rights that is derived from or based upon the Licensed Material - and in which the Licensed Material is translated, altered, - arranged, transformed, or otherwise modified in a manner requiring - permission under the Copyright and Similar Rights held by the - Licensor. For purposes of this Public License, where the Licensed - Material is a musical work, performance, or sound recording, - Adapted Material is always produced where the Licensed Material is - synched in timed relation with a moving image. - - b. Adapter's License means the license You apply to Your Copyright - and Similar Rights in Your contributions to Adapted Material in - accordance with the terms and conditions of this Public License. - - c. Copyright and Similar Rights means copyright and/or similar rights - closely related to copyright including, without limitation, - performance, broadcast, sound recording, and Sui Generis Database - Rights, without regard to how the rights are labeled or - categorized. For purposes of this Public License, the rights - specified in Section 2(b)(1)-(2) are not Copyright and Similar - Rights. - - d. Effective Technological Measures means those measures that, in the - absence of proper authority, may not be circumvented under laws - fulfilling obligations under Article 11 of the WIPO Copyright - Treaty adopted on December 20, 1996, and/or similar international - agreements. - - e. Exceptions and Limitations means fair use, fair dealing, and/or - any other exception or limitation to Copyright and Similar Rights - that applies to Your use of the Licensed Material. - - f. Licensed Material means the artistic or literary work, database, - or other material to which the Licensor applied this Public - License. - - g. Licensed Rights means the rights granted to You subject to the - terms and conditions of this Public License, which are limited to - all Copyright and Similar Rights that apply to Your use of the - Licensed Material and that the Licensor has authority to license. - - h. Licensor means the individual(s) or entity(ies) granting rights - under this Public License. - - i. Share means to provide material to the public by any means or - process that requires permission under the Licensed Rights, such - as reproduction, public display, public performance, distribution, - dissemination, communication, or importation, and to make material - available to the public including in ways that members of the - public may access the material from a place and at a time - individually chosen by them. - - j. Sui Generis Database Rights means rights other than copyright - resulting from Directive 96/9/EC of the European Parliament and of - the Council of 11 March 1996 on the legal protection of databases, - as amended and/or succeeded, as well as other essentially - equivalent rights anywhere in the world. - - k. You means the individual or entity exercising the Licensed Rights - under this Public License. Your has a corresponding meaning. - - -Section 2 -- Scope. - - a. License grant. - - 1. Subject to the terms and conditions of this Public License, - the Licensor hereby grants You a worldwide, royalty-free, - non-sublicensable, non-exclusive, irrevocable license to - exercise the Licensed Rights in the Licensed Material to: - - a. reproduce and Share the Licensed Material, in whole or - in part; and - - b. produce, reproduce, and Share Adapted Material. - - 2. Exceptions and Limitations. For the avoidance of doubt, where - Exceptions and Limitations apply to Your use, this Public - License does not apply, and You do not need to comply with - its terms and conditions. - - 3. Term. The term of this Public License is specified in Section - 6(a). - - 4. Media and formats; technical modifications allowed. The - Licensor authorizes You to exercise the Licensed Rights in - all media and formats whether now known or hereafter created, - and to make technical modifications necessary to do so. The - Licensor waives and/or agrees not to assert any right or - authority to forbid You from making technical modifications - necessary to exercise the Licensed Rights, including - technical modifications necessary to circumvent Effective - Technological Measures. For purposes of this Public License, - simply making modifications authorized by this Section 2(a) - (4) never produces Adapted Material. - - 5. Downstream recipients. - - a. Offer from the Licensor -- Licensed Material. Every - recipient of the Licensed Material automatically - receives an offer from the Licensor to exercise the - Licensed Rights under the terms and conditions of this - Public License. - - b. No downstream restrictions. You may not offer or impose - any additional or different terms or conditions on, or - apply any Effective Technological Measures to, the - Licensed Material if doing so restricts exercise of the - Licensed Rights by any recipient of the Licensed - Material. - - 6. No endorsement. Nothing in this Public License constitutes or - may be construed as permission to assert or imply that You - are, or that Your use of the Licensed Material is, connected - with, or sponsored, endorsed, or granted official status by, - the Licensor or others designated to receive attribution as - provided in Section 3(a)(1)(A)(i). - - b. Other rights. - - 1. Moral rights, such as the right of integrity, are not - licensed under this Public License, nor are publicity, - privacy, and/or other similar personality rights; however, to - the extent possible, the Licensor waives and/or agrees not to - assert any such rights held by the Licensor to the limited - extent necessary to allow You to exercise the Licensed - Rights, but not otherwise. - - 2. Patent and trademark rights are not licensed under this - Public License. - - 3. To the extent possible, the Licensor waives any right to - collect royalties from You for the exercise of the Licensed - Rights, whether directly or through a collecting society - under any voluntary or waivable statutory or compulsory - licensing scheme. In all other cases the Licensor expressly - reserves any right to collect such royalties. - - -Section 3 -- License Conditions. - -Your exercise of the Licensed Rights is expressly made subject to the -following conditions. - - a. Attribution. - - 1. If You Share the Licensed Material (including in modified - form), You must: - - a. retain the following if it is supplied by the Licensor - with the Licensed Material: - - i. identification of the creator(s) of the Licensed - Material and any others designated to receive - attribution, in any reasonable manner requested by - the Licensor (including by pseudonym if - designated); - - ii. a copyright notice; - - iii. a notice that refers to this Public License; - - iv. a notice that refers to the disclaimer of - warranties; - - v. a URI or hyperlink to the Licensed Material to the - extent reasonably practicable; - - b. indicate if You modified the Licensed Material and - retain an indication of any previous modifications; and - - c. indicate the Licensed Material is licensed under this - Public License, and include the text of, or the URI or - hyperlink to, this Public License. - - 2. You may satisfy the conditions in Section 3(a)(1) in any - reasonable manner based on the medium, means, and context in - which You Share the Licensed Material. For example, it may be - reasonable to satisfy the conditions by providing a URI or - hyperlink to a resource that includes the required - information. - - 3. If requested by the Licensor, You must remove any of the - information required by Section 3(a)(1)(A) to the extent - reasonably practicable. - - 4. If You Share Adapted Material You produce, the Adapter's - License You apply must not prevent recipients of the Adapted - Material from complying with this Public License. - - -Section 4 -- Sui Generis Database Rights. - -Where the Licensed Rights include Sui Generis Database Rights that -apply to Your use of the Licensed Material: - - a. for the avoidance of doubt, Section 2(a)(1) grants You the right - to extract, reuse, reproduce, and Share all or a substantial - portion of the contents of the database; - - b. if You include all or a substantial portion of the database - contents in a database in which You have Sui Generis Database - Rights, then the database in which You have Sui Generis Database - Rights (but not its individual contents) is Adapted Material; and - - c. You must comply with the conditions in Section 3(a) if You Share - all or a substantial portion of the contents of the database. - -For the avoidance of doubt, this Section 4 supplements and does not -replace Your obligations under this Public License where the Licensed -Rights include other Copyright and Similar Rights. - - -Section 5 -- Disclaimer of Warranties and Limitation of Liability. - - a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE - EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS - AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF - ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, - IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, - WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR - PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, - ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT - KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT - ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. - - b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE - TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, - NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, - INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, - COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR - USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN - ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR - DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR - IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. - - c. The disclaimer of warranties and limitation of liability provided - above shall be interpreted in a manner that, to the extent - possible, most closely approximates an absolute disclaimer and - waiver of all liability. - - -Section 6 -- Term and Termination. - - a. This Public License applies for the term of the Copyright and - Similar Rights licensed here. However, if You fail to comply with - this Public License, then Your rights under this Public License - terminate automatically. - - b. Where Your right to use the Licensed Material has terminated under - Section 6(a), it reinstates: - - 1. automatically as of the date the violation is cured, provided - it is cured within 30 days of Your discovery of the - violation; or - - 2. upon express reinstatement by the Licensor. - - For the avoidance of doubt, this Section 6(b) does not affect any - right the Licensor may have to seek remedies for Your violations - of this Public License. - - c. For the avoidance of doubt, the Licensor may also offer the - Licensed Material under separate terms or conditions or stop - distributing the Licensed Material at any time; however, doing so - will not terminate this Public License. - - d. Sections 1, 5, 6, 7, and 8 survive termination of this Public - License. - - -Section 7 -- Other Terms and Conditions. - - a. The Licensor shall not be bound by any additional or different - terms or conditions communicated by You unless expressly agreed. - - b. Any arrangements, understandings, or agreements regarding the - Licensed Material not stated herein are separate from and - independent of the terms and conditions of this Public License. - - -Section 8 -- Interpretation. - - a. For the avoidance of doubt, this Public License does not, and - shall not be interpreted to, reduce, limit, restrict, or impose - conditions on any use of the Licensed Material that could lawfully - be made without permission under this Public License. - - b. To the extent possible, if any provision of this Public License is - deemed unenforceable, it shall be automatically reformed to the - minimum extent necessary to make it enforceable. If the provision - cannot be reformed, it shall be severed from this Public License - without affecting the enforceability of the remaining terms and - conditions. - - c. No term or condition of this Public License will be waived and no - failure to comply consented to unless expressly agreed to by the - Licensor. - - d. Nothing in this Public License constitutes or may be interpreted - as a limitation upon, or waiver of, any privileges and immunities - that apply to the Licensor or You, including from the legal - processes of any jurisdiction or authority. - - -======================================================================= - -Creative Commons is not a party to its public -licenses. Notwithstanding, Creative Commons may elect to apply one of -its public licenses to material it publishes and in those instances -will be considered the “Licensor.” The text of the Creative Commons -public licenses is dedicated to the public domain under the CC0 Public -Domain Dedication. Except for the limited purpose of indicating that -material is shared under a Creative Commons public license or as -otherwise permitted by the Creative Commons policies published at -creativecommons.org/policies, Creative Commons does not authorize the -use of the trademark "Creative Commons" or any other trademark or logo -of Creative Commons without its prior written consent including, -without limitation, in connection with any unauthorized modifications -to any of its public licenses or any other arrangements, -understandings, or agreements concerning use of licensed material. For -the avoidance of doubt, this paragraph does not form part of the -public licenses. - -Creative Commons may be contacted at creativecommons.org. diff --git a/public/res/README.md b/public/res/README.md deleted file mode 100644 index 4e4f7c7a2..000000000 --- a/public/res/README.md +++ /dev/null @@ -1,7 +0,0 @@ -Copyright (c) 2021-present Ajay Bura (ajbura) - -Graphic content is licensed under a -Creative Commons Attribution 4.0 International License. - -You should have received a copy of the license along with this -work. If not, see ;. \ No newline at end of file From e446fc47ce6e3632b089682142e6e058712b1a6e Mon Sep 17 00:00:00 2001 From: Krishan <33421343+kfiven@users.noreply.github.com> Date: Sun, 26 Feb 2023 14:22:05 +0530 Subject: [PATCH 1009/1531] Add screenshot in readme (#1140) --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 0db8ab6c7..0d4a38ac2 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,8 @@ A Matrix client focusing primarily on simple, elegant and secure interface. The - [Roadmap](https://github.com/ajbura/cinny/projects/11) - [Contributing](./CONTRIBUTING.md) + + ## Getting started Web app is available at https://app.cinny.in and gets updated on each new release. The `dev` branch is continuously deployed at https://dev.cinny.in but keep in mind that it could have things broken. From 863612d1a1aadcde90ee8612150eacd2c32a28b9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 29 Mar 2023 14:17:00 +1100 Subject: [PATCH 1010/1531] fix(deps): update dependency matrix-js-sdk to v24 (#1175) * fix(deps): update dependency matrix-js-sdk to v24 * Update build-pull-request.yml * Update netlify-dev.yml * Update prod-deploy.yml --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Krishan <33421343+kfiven@users.noreply.github.com> --- .github/workflows/build-pull-request.yml | 2 + .github/workflows/netlify-dev.yml | 2 + .github/workflows/prod-deploy.yml | 2 + package-lock.json | 58 +++++++++++++----------- package.json | 2 +- 5 files changed, 38 insertions(+), 28 deletions(-) diff --git a/.github/workflows/build-pull-request.yml b/.github/workflows/build-pull-request.yml index 5eac02ebd..5be042932 100644 --- a/.github/workflows/build-pull-request.yml +++ b/.github/workflows/build-pull-request.yml @@ -21,6 +21,8 @@ jobs: - name: Install dependencies run: npm ci - name: Build app + env: + NODE_OPTIONS: "--max_old_space_size=4096" run: npm run build - name: Upload artifact uses: actions/upload-artifact@v3.1.1 diff --git a/.github/workflows/netlify-dev.yml b/.github/workflows/netlify-dev.yml index 6f26247b5..12785f460 100644 --- a/.github/workflows/netlify-dev.yml +++ b/.github/workflows/netlify-dev.yml @@ -20,6 +20,8 @@ jobs: - name: Install dependencies run: npm ci - name: Build app + env: + NODE_OPTIONS: "--max_old_space_size=4096" run: npm run build - name: Deploy to Netlify uses: nwtgck/actions-netlify@5da65c9f74c7961c5501a3ba329b8d0912f39c03 diff --git a/.github/workflows/prod-deploy.yml b/.github/workflows/prod-deploy.yml index 5f8a77cf4..8d72a86e9 100644 --- a/.github/workflows/prod-deploy.yml +++ b/.github/workflows/prod-deploy.yml @@ -19,6 +19,8 @@ jobs: - name: Install dependencies run: npm ci - name: Build app + env: + NODE_OPTIONS: "--max_old_space_size=4096" run: npm run build - name: Deploy to Netlify uses: nwtgck/actions-netlify@5da65c9f74c7961c5501a3ba329b8d0912f39c03 diff --git a/package-lock.json b/package-lock.json index e004ee5c1..1fe6213e6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25,7 +25,7 @@ "katex": "0.16.4", "linkify-html": "4.0.2", "linkifyjs": "4.0.2", - "matrix-js-sdk": "22.0.0", + "matrix-js-sdk": "24.0.0", "prop-types": "15.8.1", "react": "17.0.2", "react-autosize-textarea": "7.1.0", @@ -958,6 +958,14 @@ "react-dom": "16.14.0" } }, + "node_modules/@matrix-org/matrix-sdk-crypto-js": { + "version": "0.1.0-alpha.5", + "resolved": "https://registry.npmjs.org/@matrix-org/matrix-sdk-crypto-js/-/matrix-sdk-crypto-js-0.1.0-alpha.5.tgz", + "integrity": "sha512-2KjAgWNGfuGLNjJwsrs6gGX157vmcTfNrA4u249utgnMPbJl7QwuUqh1bGxQ0PpK06yvZjgPlkna0lTbuwtuQw==", + "engines": { + "node": ">= 10" + } + }, "node_modules/@matrix-org/olm": { "version": "3.2.14", "resolved": "https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.14.tgz", @@ -1170,11 +1178,6 @@ "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==" }, - "node_modules/@types/sdp-transform": { - "version": "2.4.5", - "resolved": "https://registry.npmjs.org/@types/sdp-transform/-/sdp-transform-2.4.5.tgz", - "integrity": "sha512-GVO0gnmbyO3Oxm2HdPsYUNcyihZE3GyCY8ysMYHuQGfLhGZq89Nm4lSzULWTzZoyHtg+VO/IdrnxZHPnPSGnAg==" - }, "node_modules/@types/semver": { "version": "7.3.13", "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz", @@ -1793,6 +1796,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, "dependencies": { "function-bind": "^1.1.1", "get-intrinsic": "^1.0.2" @@ -3025,7 +3029,8 @@ "node_modules/function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true }, "node_modules/function.prototype.name": { "version": "1.1.5", @@ -3067,6 +3072,7 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", + "dev": true, "dependencies": { "function-bind": "^1.1.1", "has": "^1.0.3", @@ -3180,6 +3186,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, "dependencies": { "function-bind": "^1.1.1" }, @@ -3221,6 +3228,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, "engines": { "node": ">= 0.4" }, @@ -3862,12 +3870,12 @@ "integrity": "sha512-1QEOsXO+bhyCroIe2/A5OwaxHvBm7EsSQ46DEDn8RBIfQwN5HWBpFvyWWR4QY0KHPPnnJdI99wgRiAl7Ad5qaA==" }, "node_modules/matrix-js-sdk": { - "version": "22.0.0", - "resolved": "https://registry.npmjs.org/matrix-js-sdk/-/matrix-js-sdk-22.0.0.tgz", - "integrity": "sha512-mpKqeD3nCobjGiUiATUyEoP44n+AzDW5cSeBTIBY5fPhj0AkzLJhblHt40vzSOJazj8tT0PhsSzhEIR9hGzYGA==", + "version": "24.0.0", + "resolved": "https://registry.npmjs.org/matrix-js-sdk/-/matrix-js-sdk-24.0.0.tgz", + "integrity": "sha512-AOhO036ziDf6lwYoauj5DES/RJ6RDTq+vrK2yO/GW/8n+bAXhkjWc9AA/WcTK/9SkNHS46ZanmolkhS1n8WniQ==", "dependencies": { "@babel/runtime": "^7.12.5", - "@types/sdp-transform": "^2.4.5", + "@matrix-org/matrix-sdk-crypto-js": "^0.1.0-alpha.3", "another-json": "^0.2.0", "bs58": "^5.0.0", "content-type": "^1.0.4", @@ -3875,9 +3883,9 @@ "matrix-events-sdk": "0.0.1", "matrix-widget-api": "^1.0.0", "p-retry": "4", - "qs": "^6.9.6", "sdp-transform": "^2.14.1", - "unhomoglyph": "^1.0.6" + "unhomoglyph": "^1.0.6", + "uuid": "9" }, "engines": { "node": ">=16.0.0" @@ -4019,6 +4027,7 @@ "version": "1.12.2", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", + "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -4329,20 +4338,6 @@ "node": ">=6" } }, - "node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", - "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -4770,6 +4765,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, "dependencies": { "call-bind": "^1.0.0", "get-intrinsic": "^1.0.2", @@ -5139,6 +5135,14 @@ "punycode": "^2.1.0" } }, + "node_modules/uuid": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", + "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/vite": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/vite/-/vite-4.0.1.tgz", diff --git a/package.json b/package.json index 0ff2338bc..b98f28902 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "katex": "0.16.4", "linkify-html": "4.0.2", "linkifyjs": "4.0.2", - "matrix-js-sdk": "22.0.0", + "matrix-js-sdk": "24.0.0", "prop-types": "15.8.1", "react": "17.0.2", "react-autosize-textarea": "7.1.0", From 8524472d3874516f5a12ce0c2d242ccfe3ecea59 Mon Sep 17 00:00:00 2001 From: Krishan <33421343+kfiven@users.noreply.github.com> Date: Wed, 29 Mar 2023 14:30:52 +1100 Subject: [PATCH 1011/1531] Release v2.2.5 (#1176) * Update package.json * Update package-lock.json * Update cons.js --- package-lock.json | 4 ++-- package.json | 2 +- src/client/state/cons.js | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1fe6213e6..8c8f776ba 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "cinny", - "version": "2.2.4", + "version": "2.2.5", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "cinny", - "version": "2.2.4", + "version": "2.2.5", "license": "AGPL-3.0-only", "dependencies": { "@fontsource/inter": "4.5.14", diff --git a/package.json b/package.json index b98f28902..dd23454c6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cinny", - "version": "2.2.4", + "version": "2.2.5", "description": "Yet another matrix client", "main": "index.js", "engines": { diff --git a/src/client/state/cons.js b/src/client/state/cons.js index 86ddab98d..ae39c3171 100644 --- a/src/client/state/cons.js +++ b/src/client/state/cons.js @@ -1,5 +1,5 @@ const cons = { - version: '2.2.4', + version: '2.2.5', secretKey: { ACCESS_TOKEN: 'cinny_access_token', DEVICE_ID: 'cinny_device_id', From cfddaaae1368e9f240520d178e1f1fea2b5e3d50 Mon Sep 17 00:00:00 2001 From: Krishan <33421343+kfiven@users.noreply.github.com> Date: Wed, 29 Mar 2023 21:57:05 +1100 Subject: [PATCH 1012/1531] Fix docker build failing (#1177) --- Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Dockerfile b/Dockerfile index 968ca1d11..af9abbd9a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,6 +6,7 @@ WORKDIR /src COPY .npmrc package.json package-lock.json /src/ RUN npm ci COPY . /src/ +ENV NODE_OPTIONS=--max_old_space_size=4096 RUN npm run build From f6694031a1581af171ffe1658138dfcf344d6c6c Mon Sep 17 00:00:00 2001 From: Krishan <33421343+kfiven@users.noreply.github.com> Date: Wed, 29 Mar 2023 22:02:01 +1100 Subject: [PATCH 1013/1531] Release v2.2.6 (#1178) * Update package.json * Update package-lock.json * Update cons.js --- package-lock.json | 4 ++-- package.json | 2 +- src/client/state/cons.js | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8c8f776ba..2cca1d0c6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "cinny", - "version": "2.2.5", + "version": "2.2.6", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "cinny", - "version": "2.2.5", + "version": "2.2.6", "license": "AGPL-3.0-only", "dependencies": { "@fontsource/inter": "4.5.14", diff --git a/package.json b/package.json index dd23454c6..a37b6242c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cinny", - "version": "2.2.5", + "version": "2.2.6", "description": "Yet another matrix client", "main": "index.js", "engines": { diff --git a/src/client/state/cons.js b/src/client/state/cons.js index ae39c3171..8d9fda543 100644 --- a/src/client/state/cons.js +++ b/src/client/state/cons.js @@ -1,5 +1,5 @@ const cons = { - version: '2.2.5', + version: '2.2.6', secretKey: { ACCESS_TOKEN: 'cinny_access_token', DEVICE_ID: 'cinny_device_id', From dcad1840c428933392eaafdb3a4da63484fdd36a Mon Sep 17 00:00:00 2001 From: Bo Date: Thu, 30 Mar 2023 16:42:33 +0200 Subject: [PATCH 1014/1531] fix: Fixed small typo an cross signing reset modal (#1112) --- src/app/organisms/settings/CrossSigning.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/organisms/settings/CrossSigning.jsx b/src/app/organisms/settings/CrossSigning.jsx index 9213e9dae..563e31522 100644 --- a/src/app/organisms/settings/CrossSigning.jsx +++ b/src/app/organisms/settings/CrossSigning.jsx @@ -188,7 +188,7 @@ function CrossSigningReset() { {twemojify('✋🧑‍🚒🤚')} Resetting cross-signing keys is permanent. - Anyone you have verified with will see security alerts and your message backup will lost. + Anyone you have verified with will see security alerts and your message backup will be lost. You almost certainly do not want to do this, unless you have lost Security Key or Phrase and every session you can cross-sign from. From da92ce3a46ab4f702f518c728437b1fb574ef0fc Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Sun, 16 Apr 2023 22:22:01 +1000 Subject: [PATCH 1015/1531] fix: spoiler hidden link click (#1199) --- src/app/organisms/room/RoomViewContent.jsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/app/organisms/room/RoomViewContent.jsx b/src/app/organisms/room/RoomViewContent.jsx index 745ece822..74bc7e268 100644 --- a/src/app/organisms/room/RoomViewContent.jsx +++ b/src/app/organisms/room/RoomViewContent.jsx @@ -114,6 +114,7 @@ function handleOnClickCapture(e) { const spoiler = nativeEvent.composedPath().find((el) => el?.hasAttribute?.('data-mx-spoiler')); if (spoiler) { + if (!spoiler.classList.contains('data-mx-spoiler--visible')) e.preventDefault(); spoiler.classList.toggle('data-mx-spoiler--visible'); } } From 2055d7a07fdd0a1faf25deb3be040f6de7932023 Mon Sep 17 00:00:00 2001 From: Thumbscrew Date: Sun, 28 May 2023 16:54:10 +0100 Subject: [PATCH 1016/1531] add document.hasFocus check for incoming room events (#1252) --- src/app/organisms/room/RoomViewContent.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/organisms/room/RoomViewContent.jsx b/src/app/organisms/room/RoomViewContent.jsx index 74bc7e268..0a9256ceb 100644 --- a/src/app/organisms/room/RoomViewContent.jsx +++ b/src/app/organisms/room/RoomViewContent.jsx @@ -358,7 +358,7 @@ function useEventArrive(roomTimeline, readUptoEvtStore, timelineScrollRef, event const isViewingLive = roomTimeline.isServingLiveTimeline() && limit.length >= tLength - 1; const isAttached = timelineScroll.bottom < SCROLL_TRIGGER_POS; - if (isViewingLive && isAttached) { + if (isViewingLive && isAttached && document.hasFocus()) { limit.setFrom(tLength - limit.maxEvents); trySendReadReceipt(event); setEvent(event); From 0b06bed1db9fee695407ad8088500e7266921751 Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Mon, 12 Jun 2023 21:15:23 +1000 Subject: [PATCH 1017/1531] Refactor state & Custom editor (#1190) * Fix eslint * Enable ts strict mode * install folds, jotai & immer * Enable immer map/set * change cross-signing alert anim to 30 iteration * Add function to access matrix client * Add new types * Add disposable util * Add room utils * Add mDirect list atom * Add invite list atom * add room list atom * add utils for jotai atoms * Add room id to parents atom * Add mute list atom * Add room to unread atom * Use hook to bind atoms with sdk * Add settings atom * Add settings hook * Extract set settings hook * Add Sidebar components * WIP * Add bind atoms hook * Fix init muted room list atom * add navigation atoms * Add custom editor * Fix hotkeys * Update folds * Add editor output function * Add matrix client context * Add tooltip to editor toolbar items * WIP - Add editor to room input * Refocus editor on toolbar item click * Add Mentions - WIP * update folds * update mention focus outline * rename emoji element type * Add auto complete menu * add autocomplete query functions * add index file for editor * fix bug in getPrevWord function * Show room mention autocomplete * Add async search function * add use async search hook * use async search in room mention autocomplete * remove folds prefer font for now * allow number array in async search * reset search with empty query * Autocomplete unknown room mention * Autocomplete first room mention on tab * fix roomAliasFromQueryText * change mention color to primary * add isAlive hook * add getMxIdLocalPart to mx utils * fix getRoomAvatarUrl size * fix types * add room members hook * fix bug in room mention * add user mention autocomplete * Fix async search giving prev result after no match * update folds * add twemoji font * add use state provider hook * add prevent scroll with arrow key util * add ts to custom-emoji and emoji files * add types * add hook for emoji group labels * add hook for emoji group icons * add emoji board with basic emoji * add emojiboard in room input * select multiple emoji with shift press * display custom emoji in emojiboard * Add emoji preview * focus element on hover * update folds * position emojiboard properly * convert recent-emoji.js to ts * add use recent emoji hook * add io.element.recent_emoji to account data evt * Render recent emoji in emoji board * show custom emoji from parent spaces * show room emoji * improve emoji sidebar * update folds * fix pack avatar and name fallback in emoji board * add stickers to emoji board * fix bug in emoji preview * Add sticker icon in room input * add debounce hook * add search in emoji board * Optimize emoji board * fix emoji board sidebar divider * sync emojiboard sidebar with scroll & update ui * Add use throttle hook * support custom emoji in editor * remove duplicate emoji selection function * fix emoji and mention spacing * add emoticon autocomplete in editor * fix string * makes emoji size relative to font size in editor * add option to render link element * add spoiler in editor * fix sticker in emoji board search using wrong type * render custom placeholder * update hotkey for block quote and block code * add terminate search function in async search * add getImageInfo to matrix utils * send stickers * add resize observer hook * move emoji board component hooks in hooks dir * prevent editor expand hides room timeline * send typing notifications * improve emoji style and performance * fix imports * add on paste param to editor * add selectFile utils * add file picker hook * add file paste handler hook * add file drop handler * update folds * Add file upload card * add bytes to size util * add blurHash util * add await to js lib * add browser-encrypt-attachment types * add list atom * convert mimetype file to ts * add matrix types * add matrix file util * add file related dom utils * add common utils * add upload atom * add room input draft atom * add upload card renderer component * add upload board component * add support for file upload in editor * send files with message / enter * fix circular deps * store editor toolbar state in local store * move msg content util to separate file * store msg draft on room switch * fix following member not updating on msg sent * add theme for folds component * fix system default theme * Add reply support in editor * prevent initMatrix to init multiple time * add state event hooks * add async callback hook * Show tombstone info for tombstone room * fix room tombstone component border * add power level hook * Add room input placeholder component * Show input placeholder for muted member --- .eslintrc.js | 2 + index.html | 2 +- package-lock.json | 764 ++++++++++++---- package.json | 19 +- public/font/Twemoji.Mozilla.v.7.0.woff2 | Bin 0 -> 472228 bytes public/font/Twemoji.Mozilla.v0.7.0.ttf | Bin 0 -> 1474284 bytes src/app/components/UseStateProvider.tsx | 9 + src/app/components/editor/Editor.css.ts | 63 ++ src/app/components/editor/Editor.preview.tsx | 82 ++ src/app/components/editor/Editor.tsx | 151 +++ src/app/components/editor/Elements.css.ts | 142 +++ src/app/components/editor/Elements.tsx | 254 ++++++ src/app/components/editor/Toolbar.tsx | 247 +++++ .../autocomplete/AutocompleteMenu.css.tsx | 35 + .../editor/autocomplete/AutocompleteMenu.tsx | 40 + .../autocomplete/EmoticonAutocomplete.tsx | 129 +++ .../autocomplete/RoomMentionAutocomplete.tsx | 181 ++++ .../autocomplete/UserMentionAutocomplete.tsx | 191 ++++ .../editor/autocomplete/autocompleteQuery.ts | 46 + .../components/editor/autocomplete/index.ts | 5 + src/app/components/editor/common.ts | 194 ++++ src/app/components/editor/index.ts | 7 + src/app/components/editor/keyboard.ts | 40 + src/app/components/editor/output.ts | 95 ++ src/app/components/editor/slate.d.ts | 107 +++ .../components/emoji-board/EmojiBoard.css.tsx | 134 +++ src/app/components/emoji-board/EmojiBoard.tsx | 860 ++++++++++++++++++ src/app/components/emoji-board/index.ts | 1 + .../emoji-board/useEmojiGroupIcons.ts | 21 + .../emoji-board/useEmojiGroupLabels.ts | 19 + src/app/components/sidebar/Sidebar.css.ts | 111 +++ src/app/components/sidebar/Sidebar.tsx | 8 + src/app/components/sidebar/SidebarAvatar.tsx | 75 ++ src/app/components/sidebar/SidebarContent.tsx | 21 + src/app/components/sidebar/SidebarStack.tsx | 10 + .../sidebar/SidebarStackSeparator.tsx | 13 + src/app/components/sidebar/index.ts | 5 + .../upload-board/UploadBoard.css.ts | 46 + .../components/upload-board/UploadBoard.tsx | 145 +++ src/app/components/upload-board/index.ts | 1 + .../components/upload-card/UploadCard.css.ts | 24 + src/app/components/upload-card/UploadCard.tsx | 63 ++ .../upload-card/UploadCardRenderer.tsx | 89 ++ src/app/components/upload-card/index.ts | 2 + src/app/hooks/useAlive.ts | 15 + src/app/hooks/useAsyncCallback.ts | 70 ++ src/app/hooks/useAsyncSearch.ts | 81 ++ src/app/hooks/useDebounce.ts | 34 + src/app/hooks/useFileDrop.ts | 66 ++ src/app/hooks/useFilePasteHandler.ts | 11 + src/app/hooks/useFilePicker.ts | 15 + src/app/hooks/useForceUpdate.ts | 9 + src/app/hooks/useImagePacks.ts | 48 + src/app/hooks/useKeyDown.ts | 10 + src/app/hooks/useMatrixClient.ts | 12 + src/app/hooks/usePowerLevels.ts | 86 ++ src/app/hooks/useRecentEmoji.ts | 23 + src/app/hooks/useResizeObserver.ts | 24 + src/app/hooks/useRoomMembers.ts | 34 + src/app/hooks/useStateEvent.ts | 32 + src/app/hooks/useStateEventCallback.ts | 17 + src/app/hooks/useStateEvents.ts | 28 + src/app/hooks/useThrottle.ts | 41 + src/app/hooks/useTypingStatusUpdater.ts | 42 + .../following-members/FollowingMembers.jsx | 38 +- src/app/organisms/drag-drop/DragDrop.jsx | 24 - src/app/organisms/drag-drop/DragDrop.scss | 12 - src/app/organisms/navigation/SideBar.scss | 16 +- src/app/organisms/navigation/Sidebar1.tsx | 125 +++ src/app/organisms/room/Room.jsx | 12 +- src/app/organisms/room/RoomInput.tsx | 539 +++++++++++ .../room/RoomInputPlaceholder.css.ts | 10 + .../organisms/room/RoomInputPlaceholder.tsx | 11 + src/app/organisms/room/RoomTombstone.css.ts | 7 + src/app/organisms/room/RoomTombstone.tsx | 67 ++ src/app/organisms/room/RoomView.jsx | 60 +- src/app/organisms/room/RoomView.scss | 9 +- src/app/organisms/room/RoomViewContent.jsx | 21 +- src/app/organisms/room/msgContent.ts | 148 +++ src/app/pages/App.jsx | 9 +- src/app/plugins/custom-emoji.ts | 293 ++++++ src/app/plugins/emoji.ts | 104 +++ src/app/plugins/recent-emoji.ts | 44 + src/app/state/hooks/inviteList.ts | 63 ++ src/app/state/hooks/roomList.ts | 54 ++ src/app/state/hooks/settings.ts | 34 + src/app/state/hooks/useBindAtoms.ts | 16 + src/app/state/inviteList.ts | 32 + src/app/state/list.ts | 33 + src/app/state/mDirectList.ts | 47 + src/app/state/mutedRoomList.ts | 101 ++ src/app/state/roomInputDrafts.ts | 48 + src/app/state/roomList.ts | 31 + src/app/state/roomToParents.ts | 120 +++ src/app/state/roomToUnread.ts | 219 +++++ src/app/state/selectedRoom.ts | 3 + src/app/state/selectedTab.ts | 8 + src/app/state/settings.ts | 49 + src/app/state/tabToRoom.ts | 34 + src/app/state/upload.ts | 146 +++ src/app/state/utils.ts | 64 ++ src/app/templates/client/Client.jsx | 114 +-- src/app/utils/AsyncSearch.ts | 102 +++ src/app/utils/blurHash.ts | 19 + src/app/utils/common.ts | 32 + src/app/utils/disposable.ts | 8 + src/app/utils/dom.ts | 133 +++ src/app/utils/key-symbol.ts | 6 + src/app/utils/keyboard.ts | 25 + src/app/utils/matrix.ts | 118 +++ src/app/utils/mimeTypes.ts | 47 + src/app/utils/room.ts | 265 ++++++ src/app/utils/sanitize.ts | 10 + src/app/utils/user-agent.ts | 5 + src/client/initMatrix.js | 5 + src/client/mx.ts | 7 + src/client/state/RoomList.js | 6 - src/client/state/settings.js | 24 +- src/colors.css.ts | 238 +++++ src/ext.d.ts | 23 + src/index.jsx | 10 + src/index.scss | 107 +-- src/types/matrix/accountData.ts | 12 + src/types/matrix/common.ts | 22 + src/types/matrix/room.ts | 61 ++ src/util/sanitize.js | 2 +- tsconfig.json | 3 +- vite.config.js | 2 + 128 files changed, 8799 insertions(+), 409 deletions(-) create mode 100644 public/font/Twemoji.Mozilla.v.7.0.woff2 create mode 100644 public/font/Twemoji.Mozilla.v0.7.0.ttf create mode 100644 src/app/components/UseStateProvider.tsx create mode 100644 src/app/components/editor/Editor.css.ts create mode 100644 src/app/components/editor/Editor.preview.tsx create mode 100644 src/app/components/editor/Editor.tsx create mode 100644 src/app/components/editor/Elements.css.ts create mode 100644 src/app/components/editor/Elements.tsx create mode 100644 src/app/components/editor/Toolbar.tsx create mode 100644 src/app/components/editor/autocomplete/AutocompleteMenu.css.tsx create mode 100644 src/app/components/editor/autocomplete/AutocompleteMenu.tsx create mode 100644 src/app/components/editor/autocomplete/EmoticonAutocomplete.tsx create mode 100644 src/app/components/editor/autocomplete/RoomMentionAutocomplete.tsx create mode 100644 src/app/components/editor/autocomplete/UserMentionAutocomplete.tsx create mode 100644 src/app/components/editor/autocomplete/autocompleteQuery.ts create mode 100644 src/app/components/editor/autocomplete/index.ts create mode 100644 src/app/components/editor/common.ts create mode 100644 src/app/components/editor/index.ts create mode 100644 src/app/components/editor/keyboard.ts create mode 100644 src/app/components/editor/output.ts create mode 100644 src/app/components/editor/slate.d.ts create mode 100644 src/app/components/emoji-board/EmojiBoard.css.tsx create mode 100644 src/app/components/emoji-board/EmojiBoard.tsx create mode 100644 src/app/components/emoji-board/index.ts create mode 100644 src/app/components/emoji-board/useEmojiGroupIcons.ts create mode 100644 src/app/components/emoji-board/useEmojiGroupLabels.ts create mode 100644 src/app/components/sidebar/Sidebar.css.ts create mode 100644 src/app/components/sidebar/Sidebar.tsx create mode 100644 src/app/components/sidebar/SidebarAvatar.tsx create mode 100644 src/app/components/sidebar/SidebarContent.tsx create mode 100644 src/app/components/sidebar/SidebarStack.tsx create mode 100644 src/app/components/sidebar/SidebarStackSeparator.tsx create mode 100644 src/app/components/sidebar/index.ts create mode 100644 src/app/components/upload-board/UploadBoard.css.ts create mode 100644 src/app/components/upload-board/UploadBoard.tsx create mode 100644 src/app/components/upload-board/index.ts create mode 100644 src/app/components/upload-card/UploadCard.css.ts create mode 100644 src/app/components/upload-card/UploadCard.tsx create mode 100644 src/app/components/upload-card/UploadCardRenderer.tsx create mode 100644 src/app/components/upload-card/index.ts create mode 100644 src/app/hooks/useAlive.ts create mode 100644 src/app/hooks/useAsyncCallback.ts create mode 100644 src/app/hooks/useAsyncSearch.ts create mode 100644 src/app/hooks/useDebounce.ts create mode 100644 src/app/hooks/useFileDrop.ts create mode 100644 src/app/hooks/useFilePasteHandler.ts create mode 100644 src/app/hooks/useFilePicker.ts create mode 100644 src/app/hooks/useForceUpdate.ts create mode 100644 src/app/hooks/useImagePacks.ts create mode 100644 src/app/hooks/useKeyDown.ts create mode 100644 src/app/hooks/useMatrixClient.ts create mode 100644 src/app/hooks/usePowerLevels.ts create mode 100644 src/app/hooks/useRecentEmoji.ts create mode 100644 src/app/hooks/useResizeObserver.ts create mode 100644 src/app/hooks/useRoomMembers.ts create mode 100644 src/app/hooks/useStateEvent.ts create mode 100644 src/app/hooks/useStateEventCallback.ts create mode 100644 src/app/hooks/useStateEvents.ts create mode 100644 src/app/hooks/useThrottle.ts create mode 100644 src/app/hooks/useTypingStatusUpdater.ts delete mode 100644 src/app/organisms/drag-drop/DragDrop.jsx delete mode 100644 src/app/organisms/drag-drop/DragDrop.scss create mode 100644 src/app/organisms/navigation/Sidebar1.tsx create mode 100644 src/app/organisms/room/RoomInput.tsx create mode 100644 src/app/organisms/room/RoomInputPlaceholder.css.ts create mode 100644 src/app/organisms/room/RoomInputPlaceholder.tsx create mode 100644 src/app/organisms/room/RoomTombstone.css.ts create mode 100644 src/app/organisms/room/RoomTombstone.tsx create mode 100644 src/app/organisms/room/msgContent.ts create mode 100644 src/app/plugins/custom-emoji.ts create mode 100644 src/app/plugins/emoji.ts create mode 100644 src/app/plugins/recent-emoji.ts create mode 100644 src/app/state/hooks/inviteList.ts create mode 100644 src/app/state/hooks/roomList.ts create mode 100644 src/app/state/hooks/settings.ts create mode 100644 src/app/state/hooks/useBindAtoms.ts create mode 100644 src/app/state/inviteList.ts create mode 100644 src/app/state/list.ts create mode 100644 src/app/state/mDirectList.ts create mode 100644 src/app/state/mutedRoomList.ts create mode 100644 src/app/state/roomInputDrafts.ts create mode 100644 src/app/state/roomList.ts create mode 100644 src/app/state/roomToParents.ts create mode 100644 src/app/state/roomToUnread.ts create mode 100644 src/app/state/selectedRoom.ts create mode 100644 src/app/state/selectedTab.ts create mode 100644 src/app/state/settings.ts create mode 100644 src/app/state/tabToRoom.ts create mode 100644 src/app/state/upload.ts create mode 100644 src/app/state/utils.ts create mode 100644 src/app/utils/AsyncSearch.ts create mode 100644 src/app/utils/blurHash.ts create mode 100644 src/app/utils/common.ts create mode 100644 src/app/utils/disposable.ts create mode 100644 src/app/utils/dom.ts create mode 100644 src/app/utils/key-symbol.ts create mode 100644 src/app/utils/keyboard.ts create mode 100644 src/app/utils/matrix.ts create mode 100644 src/app/utils/mimeTypes.ts create mode 100644 src/app/utils/room.ts create mode 100644 src/app/utils/sanitize.ts create mode 100644 src/app/utils/user-agent.ts create mode 100644 src/client/mx.ts create mode 100644 src/colors.css.ts create mode 100644 src/ext.d.ts create mode 100644 src/types/matrix/accountData.ts create mode 100644 src/types/matrix/common.ts create mode 100644 src/types/matrix/room.ts diff --git a/.eslintrc.js b/.eslintrc.js index e8f9224ea..704374182 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -27,6 +27,7 @@ module.exports = { rules: { 'linebreak-style': 0, 'no-underscore-dangle': 0, + "no-shadow": "off", "import/prefer-default-export": "off", "import/extensions": "off", @@ -55,5 +56,6 @@ module.exports = { "react-hooks/exhaustive-deps": "error", "@typescript-eslint/no-unused-vars": "error", + "@typescript-eslint/no-shadow": "error" }, }; diff --git a/index.html b/index.html index af1a6268f..36c5740ae 100644 --- a/index.html +++ b/index.html @@ -27,7 +27,7 @@ - + diff --git a/package-lock.json b/package-lock.json index 2cca1d0c6..626752477 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,14 +14,25 @@ "@khanacademy/simple-markdown": "0.8.6", "@matrix-org/olm": "3.2.14", "@tippyjs/react": "4.2.6", + "@vanilla-extract/css": "1.9.3", + "@vanilla-extract/recipes": "0.3.0", + "@vanilla-extract/vite-plugin": "3.7.1", + "await-to-js": "3.0.0", "blurhash": "2.0.4", "browser-encrypt-attachment": "0.3.0", + "classnames": "2.3.2", "dateformat": "5.0.3", + "emojibase": "6.1.0", "emojibase-data": "7.0.1", "file-saver": "2.0.5", "flux": "4.0.3", + "focus-trap-react": "10.0.2", + "folds": "1.2.1", "formik": "2.2.9", "html-react-parser": "3.0.4", + "immer": "9.0.16", + "is-hotkey": "0.2.0", + "jotai": "1.12.0", "katex": "0.16.4", "linkify-html": "4.0.2", "linkifyjs": "4.0.2", @@ -36,8 +47,11 @@ "react-google-recaptcha": "2.1.0", "react-modal": "3.16.1", "sanitize-html": "2.8.0", + "slate": "0.90.0", + "slate-react": "0.90.0", "tippy.js": "6.3.7", - "twemoji": "14.0.2" + "twemoji": "14.0.2", + "ua-parser-js": "1.0.35" }, "devDependencies": { "@esbuild-plugins/node-globals-polyfill": "0.2.3", @@ -46,6 +60,7 @@ "@types/node": "18.11.18", "@types/react": "18.0.26", "@types/react-dom": "18.0.9", + "@types/ua-parser-js": "0.7.36", "@typescript-eslint/eslint-plugin": "5.46.1", "@typescript-eslint/parser": "5.46.1", "@vitejs/plugin-react": "3.0.0", @@ -61,7 +76,7 @@ "prettier": "2.8.1", "sass": "1.56.2", "typescript": "4.9.4", - "vite": "4.0.1", + "vite": "4.0.4", "vite-plugin-static-copy": "0.13.0" }, "engines": { @@ -72,7 +87,6 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", - "dev": true, "dependencies": { "@jridgewell/gen-mapping": "^0.1.0", "@jridgewell/trace-mapping": "^0.3.9" @@ -85,7 +99,6 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", - "dev": true, "dependencies": { "@babel/highlight": "^7.18.6" }, @@ -94,34 +107,32 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.5.tgz", - "integrity": "sha512-KZXo2t10+/jxmkhNXc7pZTqRvSOIvVv/+lJwHS+B2rErwOyjuVRh60yVpb7liQ1U5t7lLJ1bz+t8tSypUZdm0g==", - "dev": true, + "version": "7.20.10", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.10.tgz", + "integrity": "sha512-sEnuDPpOJR/fcafHMjpcpGN5M2jbUGUHwmuWKM/YdPzeEDJg8bgmbcWQFUfE32MQjti1koACvoPVsDe8Uq+idg==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.5.tgz", - "integrity": "sha512-UdOWmk4pNWTm/4DlPUl/Pt4Gz4rcEMb7CY0Y3eJl5Yz1vI8ZJGmHWaVE55LoxRjdpx0z259GE9U5STA9atUinQ==", - "dev": true, + "version": "7.20.12", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.12.tgz", + "integrity": "sha512-XsMfHovsUYHFMdrIHkZphTN/2Hzzi78R08NuHfDBehym2VsPDL6Zn/JAD/JQdnRvbSsbQc4mVaU1m6JgtTEElg==", "dependencies": { "@ampproject/remapping": "^2.1.0", "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.20.5", - "@babel/helper-compilation-targets": "^7.20.0", - "@babel/helper-module-transforms": "^7.20.2", - "@babel/helpers": "^7.20.5", - "@babel/parser": "^7.20.5", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.20.5", - "@babel/types": "^7.20.5", + "@babel/generator": "^7.20.7", + "@babel/helper-compilation-targets": "^7.20.7", + "@babel/helper-module-transforms": "^7.20.11", + "@babel/helpers": "^7.20.7", + "@babel/parser": "^7.20.7", + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.20.12", + "@babel/types": "^7.20.7", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", - "json5": "^2.2.1", + "json5": "^2.2.2", "semver": "^6.3.0" }, "engines": { @@ -133,12 +144,11 @@ } }, "node_modules/@babel/generator": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.5.tgz", - "integrity": "sha512-jl7JY2Ykn9S0yj4DQP82sYvPU+T3g0HFcWTqDLqiuA9tGRNIj9VfbtXGAYTTkyNEnQk1jkMGOdYka8aG/lulCA==", - "dev": true, + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.7.tgz", + "integrity": "sha512-7wqMOJq8doJMZmP4ApXTzLxSr7+oO2jroJURrVEp6XShrQUObV8Tq/D0NCcoYg2uHqUrjzO0zwBjoYzelxK+sw==", "dependencies": { - "@babel/types": "^7.20.5", + "@babel/types": "^7.20.7", "@jridgewell/gen-mapping": "^0.3.2", "jsesc": "^2.5.1" }, @@ -150,7 +160,6 @@ "version": "0.3.2", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", - "dev": true, "dependencies": { "@jridgewell/set-array": "^1.0.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -161,14 +170,14 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.0.tgz", - "integrity": "sha512-0jp//vDGp9e8hZzBc6N/KwA5ZK3Wsm/pfm4CrY7vzegkVxc65SgSn6wYOnwHe9Js9HRQ1YTCKLGPzDtaS3RoLQ==", - "dev": true, + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz", + "integrity": "sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==", "dependencies": { - "@babel/compat-data": "^7.20.0", + "@babel/compat-data": "^7.20.5", "@babel/helper-validator-option": "^7.18.6", "browserslist": "^4.21.3", + "lru-cache": "^5.1.1", "semver": "^6.3.0" }, "engines": { @@ -178,11 +187,23 @@ "@babel/core": "^7.0.0" } }, + "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + }, "node_modules/@babel/helper-environment-visitor": { "version": "7.18.9", "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", - "dev": true, "engines": { "node": ">=6.9.0" } @@ -191,7 +212,6 @@ "version": "7.19.0", "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", - "dev": true, "dependencies": { "@babel/template": "^7.18.10", "@babel/types": "^7.19.0" @@ -204,7 +224,6 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", - "dev": true, "dependencies": { "@babel/types": "^7.18.6" }, @@ -216,7 +235,6 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", - "dev": true, "dependencies": { "@babel/types": "^7.18.6" }, @@ -225,19 +243,18 @@ } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.2.tgz", - "integrity": "sha512-zvBKyJXRbmK07XhMuujYoJ48B5yvvmM6+wcpv6Ivj4Yg6qO7NOZOSnvZN9CRl1zz1Z4cKf8YejmCMh8clOoOeA==", - "dev": true, + "version": "7.20.11", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.11.tgz", + "integrity": "sha512-uRy78kN4psmji1s2QtbtcCSaj/LILFDp0f/ymhpQH5QY3nljUZCaNWz9X1dEj/8MBdBEFECs7yRhKn8i7NjZgg==", "dependencies": { "@babel/helper-environment-visitor": "^7.18.9", "@babel/helper-module-imports": "^7.18.6", "@babel/helper-simple-access": "^7.20.2", "@babel/helper-split-export-declaration": "^7.18.6", "@babel/helper-validator-identifier": "^7.19.1", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.20.1", - "@babel/types": "^7.20.2" + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.20.10", + "@babel/types": "^7.20.7" }, "engines": { "node": ">=6.9.0" @@ -247,7 +264,6 @@ "version": "7.20.2", "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz", "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==", - "dev": true, "engines": { "node": ">=6.9.0" } @@ -256,7 +272,6 @@ "version": "7.20.2", "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", - "dev": true, "dependencies": { "@babel/types": "^7.20.2" }, @@ -268,7 +283,6 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", - "dev": true, "dependencies": { "@babel/types": "^7.18.6" }, @@ -280,7 +294,6 @@ "version": "7.19.4", "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", - "dev": true, "engines": { "node": ">=6.9.0" } @@ -289,7 +302,6 @@ "version": "7.19.1", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", - "dev": true, "engines": { "node": ">=6.9.0" } @@ -298,20 +310,18 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==", - "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.20.6", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.6.tgz", - "integrity": "sha512-Pf/OjgfgFRW5bApskEz5pvidpim7tEDPlFtKcNRXWmfHGn9IEI2W2flqRQXTFb7gIPTyK++N6rVHuwKut4XK6w==", - "dev": true, + "version": "7.20.13", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.13.tgz", + "integrity": "sha512-nzJ0DWCL3gB5RCXbUO3KIMMsBY2Eqbx8mBpKGE/02PgyRQFcPQLbkQ1vyy596mZLaP+dAfD+R4ckASzNVmW3jg==", "dependencies": { - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.20.5", - "@babel/types": "^7.20.5" + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.20.13", + "@babel/types": "^7.20.7" }, "engines": { "node": ">=6.9.0" @@ -321,7 +331,6 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", - "dev": true, "dependencies": { "@babel/helper-validator-identifier": "^7.18.6", "chalk": "^2.0.0", @@ -332,10 +341,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.5.tgz", - "integrity": "sha512-r27t/cy/m9uKLXQNWWebeCUHgnAZq0CpG1OwKRxzJMP1vpSU4bSIK2hq+/cp0bQxetkXx38n09rNu8jVkcK/zA==", - "dev": true, + "version": "7.20.13", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.13.tgz", + "integrity": "sha512-gFDLKMfpiXCsjt4za2JA9oTMn70CeseCehb11kRZgvd7+F67Hih3OHOK24cRrWECJ/ljfPGac6ygXAs/C8kIvw==", "bin": { "parser": "bin/babel-parser.js" }, @@ -343,6 +351,20 @@ "node": ">=6.0.0" } }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.20.0.tgz", + "integrity": "sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.19.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/plugin-transform-react-jsx-self": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.18.6.tgz", @@ -409,33 +431,31 @@ "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" }, "node_modules/@babel/template": { - "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", - "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", - "dev": true, + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz", + "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==", "dependencies": { "@babel/code-frame": "^7.18.6", - "@babel/parser": "^7.18.10", - "@babel/types": "^7.18.10" + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.5.tgz", - "integrity": "sha512-WM5ZNN3JITQIq9tFZaw1ojLU3WgWdtkxnhM1AegMS+PvHjkM5IXjmYEGY7yukz5XS4sJyEf2VzWjI8uAavhxBQ==", - "dev": true, + "version": "7.20.13", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.13.tgz", + "integrity": "sha512-kMJXfF0T6DIS9E8cgdLCSAL+cuCK+YEZHWiLK0SXpTo8YRj5lpJu3CDNKiIBCne4m9hhTIqUg6SYTAI39tAiVQ==", "dependencies": { "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.20.5", + "@babel/generator": "^7.20.7", "@babel/helper-environment-visitor": "^7.18.9", "@babel/helper-function-name": "^7.19.0", "@babel/helper-hoist-variables": "^7.18.6", "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.20.5", - "@babel/types": "^7.20.5", + "@babel/parser": "^7.20.13", + "@babel/types": "^7.20.7", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -444,10 +464,9 @@ } }, "node_modules/@babel/types": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.5.tgz", - "integrity": "sha512-c9fst/h2/dcF7H+MJKZ2T0KjEQ8hY/BNnDk/H3XY8C4Aw/eWQXWn/lWntHF9ooUBnGmEvbfGrTgLWc+um0YDUg==", - "dev": true, + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.7.tgz", + "integrity": "sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg==", "dependencies": { "@babel/helper-string-parser": "^7.19.4", "@babel/helper-validator-identifier": "^7.19.1", @@ -457,6 +476,11 @@ "node": ">=6.9.0" } }, + "node_modules/@emotion/hash": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.0.tgz", + "integrity": "sha512-14FtKiHhy2QoPIzdTcvh//8OyBlknNs2nXRwIhG904opCby3l+9Xaf/wuPvICBF0rc1ZCNBd3nKe9cd2mecVkQ==" + }, "node_modules/@esbuild-plugins/node-globals-polyfill": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/@esbuild-plugins/node-globals-polyfill/-/node-globals-polyfill-0.2.3.tgz", @@ -473,7 +497,6 @@ "cpu": [ "arm" ], - "dev": true, "optional": true, "os": [ "android" @@ -489,7 +512,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "android" @@ -505,7 +527,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "android" @@ -521,7 +542,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "darwin" @@ -537,7 +557,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "darwin" @@ -553,7 +572,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "freebsd" @@ -569,7 +587,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "freebsd" @@ -585,7 +602,6 @@ "cpu": [ "arm" ], - "dev": true, "optional": true, "os": [ "linux" @@ -601,7 +617,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -617,7 +632,6 @@ "cpu": [ "ia32" ], - "dev": true, "optional": true, "os": [ "linux" @@ -633,7 +647,6 @@ "cpu": [ "loong64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -649,7 +662,6 @@ "cpu": [ "mips64el" ], - "dev": true, "optional": true, "os": [ "linux" @@ -665,7 +677,6 @@ "cpu": [ "ppc64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -681,7 +692,6 @@ "cpu": [ "riscv64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -697,7 +707,6 @@ "cpu": [ "s390x" ], - "dev": true, "optional": true, "os": [ "linux" @@ -713,7 +722,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -729,7 +737,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "netbsd" @@ -745,7 +752,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "openbsd" @@ -761,7 +767,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "sunos" @@ -777,7 +782,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "win32" @@ -793,7 +797,6 @@ "cpu": [ "ia32" ], - "dev": true, "optional": true, "os": [ "win32" @@ -809,7 +812,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "win32" @@ -903,7 +905,6 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", - "dev": true, "dependencies": { "@jridgewell/set-array": "^1.0.0", "@jridgewell/sourcemap-codec": "^1.4.10" @@ -916,7 +917,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", - "dev": true, "engines": { "node": ">=6.0.0" } @@ -925,7 +925,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", - "dev": true, "engines": { "node": ">=6.0.0" } @@ -933,19 +932,22 @@ "node_modules/@jridgewell/sourcemap-codec": { "version": "1.4.14", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", - "dev": true + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.17", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", - "dev": true, "dependencies": { "@jridgewell/resolve-uri": "3.1.0", "@jridgewell/sourcemap-codec": "1.4.14" } }, + "node_modules/@juggle/resize-observer": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@juggle/resize-observer/-/resize-observer-3.4.0.tgz", + "integrity": "sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA==" + }, "node_modules/@khanacademy/simple-markdown": { "version": "0.8.6", "resolved": "https://registry.npmjs.org/@khanacademy/simple-markdown/-/simple-markdown-0.8.6.tgz", @@ -1126,6 +1128,11 @@ "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==" }, + "node_modules/@types/is-hotkey": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/@types/is-hotkey/-/is-hotkey-0.1.7.tgz", + "integrity": "sha512-yB5C7zcOM7idwYZZ1wKQ3pTfjA9BbvFqRWvKB46GFddxnJtHwi/b9y84ykQtxQPg5qhdpg4Q/kWU3EGoCTmLzQ==" + }, "node_modules/@types/json-schema": { "version": "7.0.11", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", @@ -1138,6 +1145,11 @@ "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", "dev": true }, + "node_modules/@types/lodash": { + "version": "4.14.191", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.191.tgz", + "integrity": "sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ==" + }, "node_modules/@types/node": { "version": "18.11.18", "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.18.tgz", @@ -1184,6 +1196,12 @@ "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==", "dev": true }, + "node_modules/@types/ua-parser-js": { + "version": "0.7.36", + "resolved": "https://registry.npmjs.org/@types/ua-parser-js/-/ua-parser-js-0.7.36.tgz", + "integrity": "sha512-N1rW+njavs70y2cApeIw1vLMYXRwfBy+7trgavGuuTfOd7j1Yh7QTRc/yqsPl6ncokt72ZXuxEU0PiCp9bSwNQ==", + "dev": true + }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "5.46.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.46.1.tgz", @@ -1438,6 +1456,148 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@vanilla-extract/babel-plugin-debug-ids": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@vanilla-extract/babel-plugin-debug-ids/-/babel-plugin-debug-ids-1.0.1.tgz", + "integrity": "sha512-ynyKqsJiMzM1/yiIJ6QdqpWKlK4IMJJWREpPtaemZrE1xG1B4E/Nfa6YazuDWjDkCJC1tRIpEGnVs+pMIjUxyw==", + "dependencies": { + "@babel/core": "^7.20.7" + } + }, + "node_modules/@vanilla-extract/css": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/@vanilla-extract/css/-/css-1.9.3.tgz", + "integrity": "sha512-vitcD8usEOTWDLAnbtnZ46YbHADAp3Es+3xyHsMDMZOEWk03FhD+PbR58kdwtGpr258+hMryCYtQPeFh5lWFbA==", + "dependencies": { + "@emotion/hash": "^0.9.0", + "@vanilla-extract/private": "^1.0.3", + "ahocorasick": "1.0.2", + "chalk": "^4.1.1", + "css-what": "^5.0.1", + "cssesc": "^3.0.0", + "csstype": "^3.0.7", + "deep-object-diff": "^1.1.0", + "deepmerge": "^4.2.2", + "media-query-parser": "^2.0.2", + "outdent": "^0.8.0" + } + }, + "node_modules/@vanilla-extract/css/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@vanilla-extract/css/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@vanilla-extract/css/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@vanilla-extract/css/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/@vanilla-extract/css/node_modules/deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@vanilla-extract/css/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/@vanilla-extract/css/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@vanilla-extract/integration": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@vanilla-extract/integration/-/integration-6.0.2.tgz", + "integrity": "sha512-LwfXlh0THeNvVXdA3iWFYvJs1mvEP1PkfQD/7S6Purry7L8iDizDV/87FgWBJ79FnTmYIvMrc7BOQsUajNj9VQ==", + "dependencies": { + "@babel/core": "^7.20.7", + "@babel/plugin-syntax-typescript": "^7.20.0", + "@vanilla-extract/babel-plugin-debug-ids": "^1.0.1", + "@vanilla-extract/css": "^1.9.3", + "esbuild": "^0.16.3", + "eval": "0.1.6", + "find-up": "^5.0.0", + "javascript-stringify": "^2.0.1", + "lodash": "^4.17.21", + "outdent": "^0.8.0" + } + }, + "node_modules/@vanilla-extract/private": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@vanilla-extract/private/-/private-1.0.3.tgz", + "integrity": "sha512-17kVyLq3ePTKOkveHxXuIJZtGYs+cSoev7BlP+Lf4916qfDhk/HBjvlYDe8egrea7LNPHKwSZJK/bzZC+Q6AwQ==" + }, + "node_modules/@vanilla-extract/recipes": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@vanilla-extract/recipes/-/recipes-0.3.0.tgz", + "integrity": "sha512-7wXrgfq1oldKdBfCKen4XmSlDmQR+4o0CQ3WnnLfhQaEtI65xJ774yyQF6dD2CC+hHdW2LFKVXgH5NZRbMQ8Sg==", + "peerDependencies": { + "@vanilla-extract/css": "^1.0.0" + } + }, + "node_modules/@vanilla-extract/vite-plugin": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/@vanilla-extract/vite-plugin/-/vite-plugin-3.7.1.tgz", + "integrity": "sha512-KFeTSEJKtJDfQhUJh4jGmrJDLCU59DSA3YKZSdys4jTOLZ1ZFsKzDP2pnFwH/24Oc2ebK+EV5x3OPlWxvRYthg==", + "dependencies": { + "@vanilla-extract/integration": "^6.0.2", + "outdent": "^0.8.0", + "postcss": "^8.3.6", + "postcss-load-config": "^3.1.0" + }, + "peerDependencies": { + "vite": "^2.2.3 || ^3.0.0 || ^4.0.3" + } + }, "node_modules/@vitejs/plugin-react": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-3.0.0.tgz", @@ -1478,6 +1638,11 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, + "node_modules/ahocorasick": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/ahocorasick/-/ahocorasick-1.0.2.tgz", + "integrity": "sha512-hCOfMzbFx5IDutmWLAt6MZwOUjIfSM9G9FyVxytmE4Rs/5YDPWQrD/+IR1w+FweD9H2oOZEnv36TmkjhNURBVA==" + }, "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -1512,7 +1677,6 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, "dependencies": { "color-convert": "^1.9.0" }, @@ -1645,6 +1809,14 @@ "resolved": "https://registry.npmjs.org/autosize/-/autosize-4.0.4.tgz", "integrity": "sha512-5yxLQ22O0fCRGoxGfeLSNt3J8LB1v+umtpMnPW6XjkTWXKoN0AmXAIhelJcDtFT/Y/wYWmfE+oqU10Q0b8FhaQ==" }, + "node_modules/await-to-js": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/await-to-js/-/await-to-js-3.0.0.tgz", + "integrity": "sha512-zJAaP9zxTcvTHRlejau3ZOY4V7SRpiByf3/dxx2uyKxxor19tpmpV2QRsTKikckwhaPmr2dVpxxMr7jOCYVp5g==", + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/axe-core": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.6.0.tgz", @@ -1736,7 +1908,6 @@ "version": "4.21.4", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", - "dev": true, "funding": [ { "type": "opencollective", @@ -1815,10 +1986,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001439", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001439.tgz", - "integrity": "sha512-1MgUzEkoMO6gKfXflStpYgZDlFM7M/ck/bgfVCACO5vnAf0fXoNVHdWtqGU+MYca+4bL9Z5bpOVmR33cWW9G2A==", - "dev": true, + "version": "1.0.30001446", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001446.tgz", + "integrity": "sha512-fEoga4PrImGcwUUGEol/PoFCSBnSkA9drgdkxXkJLsUBOnJ8rs3zDv6ApqYXGQFOyMPsjh79naWhF4DAxbF8rw==", "funding": [ { "type": "opencollective", @@ -1834,7 +2004,6 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -1883,11 +2052,15 @@ "node": ">= 6" } }, + "node_modules/classnames": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz", + "integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==" + }, "node_modules/color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, "dependencies": { "color-name": "1.1.3" } @@ -1895,8 +2068,12 @@ "node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/compute-scroll-into-view": { + "version": "1.0.20", + "resolved": "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-1.0.20.tgz", + "integrity": "sha512-UCB0ioiyj8CRjtrvaceBLqqhZCVP+1B8+NWQhmdsm0VXOJtobBCf1dBQmebCCo34qZmUwZfIH2MZLqNHazrfjg==" }, "node_modules/computed-style": { "version": "0.1.4", @@ -1926,8 +2103,7 @@ "node_modules/convert-source-map": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", - "dev": true + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" }, "node_modules/core-js-pure": { "version": "3.26.1", @@ -1962,6 +2138,28 @@ "node": ">= 8" } }, + "node_modules/css-what": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-5.1.0.tgz", + "integrity": "sha512-arSMRWIIFY0hV8pIxZMEfmMI47Wj3R/aWpZDDxWYCPEiOMv6tfOrnpDtgxBYPEQD4V0Y/958+1TdC3iWTFcUPw==", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/csstype": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz", @@ -1985,7 +2183,6 @@ "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, "dependencies": { "ms": "2.1.2" }, @@ -2004,6 +2201,11 @@ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, + "node_modules/deep-object-diff": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/deep-object-diff/-/deep-object-diff-1.1.9.tgz", + "integrity": "sha512-Rn+RuwkmkDwCi2/oXOFS9Gsr5lJZu/yTGpK7wAaAIE75CC+LCGEZHpY6VQJa/RoJcrmaA/docWJZvYohlNkWPA==" + }, "node_modules/deepmerge": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.2.1.tgz", @@ -2040,6 +2242,18 @@ "node": ">=8" } }, + "node_modules/direction": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/direction/-/direction-1.0.4.tgz", + "integrity": "sha512-GYqKi1aH7PJXxdhTeZBFrg8vUBeKXi+cNprXsC1kpJcbcVnV9wBsrOu1cQEdG0WeQwlfHiy3XvnKfIrJ2R0NzQ==", + "bin": { + "direction": "cli.js" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/dnd-core": { "version": "15.1.2", "resolved": "https://registry.npmjs.org/dnd-core/-/dnd-core-15.1.2.tgz", @@ -2116,8 +2330,7 @@ "node_modules/electron-to-chromium": { "version": "1.4.284", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz", - "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==", - "dev": true + "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==" }, "node_modules/emoji-regex": { "version": "9.2.2", @@ -2125,6 +2338,15 @@ "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", "dev": true }, + "node_modules/emojibase": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/emojibase/-/emojibase-6.1.0.tgz", + "integrity": "sha512-1GkKJPXP6tVkYJHOBSJHoGOr/6uaDxZ9xJ6H7m6PfdGXTmQgbALHLWaVRY4Gi/qf5x/gT/NUXLPuSHYLqtLtrQ==", + "funding": { + "type": "ko-fi", + "url": "https://ko-fi.com/milesjohnson" + } + }, "node_modules/emojibase-data": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/emojibase-data/-/emojibase-data-7.0.1.tgz", @@ -2217,7 +2439,6 @@ "version": "0.16.9", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.16.9.tgz", "integrity": "sha512-gkH83yHyijMSZcZFs1IWew342eMdFuWXmQo3zkDPTre25LIPBJsXryg02M3u8OpTwCJdBkdaQwqKkDLnAsAeLQ==", - "dev": true, "hasInstallScript": true, "bin": { "esbuild": "bin/esbuild" @@ -2254,7 +2475,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true, "engines": { "node": ">=6" } @@ -2263,7 +2483,6 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, "engines": { "node": ">=0.8.0" } @@ -2777,6 +2996,17 @@ "node": ">=0.10.0" } }, + "node_modules/eval": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/eval/-/eval-0.1.6.tgz", + "integrity": "sha512-o0XUw+5OGkXw4pJZzQoXUk+H87DHuC+7ZE//oSrRGtatTmr12oTnLfg6QOq9DyTt0c/p4TwzgmkKrBzWTSizyQ==", + "dependencies": { + "require-like": ">= 0.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/events": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", @@ -2871,6 +3101,24 @@ "resolved": "https://registry.npmjs.org/fbjs-css-vars/-/fbjs-css-vars-1.0.2.tgz", "integrity": "sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ==" }, + "node_modules/fbjs/node_modules/ua-parser-js": { + "version": "0.7.35", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.35.tgz", + "integrity": "sha512-veRf7dawaj9xaWEu9HoTVn5Pggtc/qj+kqTOFvNiN1l0YdxwC1kvel57UCjThjGa3BHBihE8/UJAHI+uQHmd/g==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/ua-parser-js" + }, + { + "type": "paypal", + "url": "https://paypal.me/faisalman" + } + ], + "engines": { + "node": "*" + } + }, "node_modules/file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -2904,7 +3152,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" @@ -2962,6 +3209,40 @@ "react": "^15.0.2 || ^16.0.0 || ^17.0.0" } }, + "node_modules/focus-trap": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-7.2.0.tgz", + "integrity": "sha512-v4wY6HDDYvzkBy4735kW5BUEuw6Yz9ABqMYLuTNbzAFPcBOGiGHwwcNVMvUz4G0kgSYh13wa/7TG3XwTeT4O/A==", + "dependencies": { + "tabbable": "^6.0.1" + } + }, + "node_modules/focus-trap-react": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/focus-trap-react/-/focus-trap-react-10.0.2.tgz", + "integrity": "sha512-MnN2cmdgpY7NY74ePOio4kbO5A3ILhrg1g5OGbgIQjcWEv1hhcbh6e98K0a+df88hNbE+4i9r8ji9aQnHou6GA==", + "dependencies": { + "focus-trap": "^7.2.0", + "tabbable": "^6.0.1" + }, + "peerDependencies": { + "prop-types": "^15.8.1", + "react": ">=16.3.0", + "react-dom": ">=16.3.0" + } + }, + "node_modules/folds": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/folds/-/folds-1.2.1.tgz", + "integrity": "sha512-BCV5oFCndiGFp1HyeSnbDKmTSbu1yfAtAIF6znPvLthuI/QG4516bBUr6+MyNUQWx/IAkj1bdQL/cdD+jEZWCw==", + "peerDependencies": { + "@vanilla-extract/css": "^1.9.2", + "@vanilla-extract/recipes": "^0.3.0", + "classnames": "^2.3.2", + "react": "^17.0.0", + "react-dom": "^17.0.0" + } + }, "node_modules/formik": { "version": "2.2.9", "resolved": "https://registry.npmjs.org/formik/-/formik-2.2.9.tgz", @@ -3063,7 +3344,6 @@ "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true, "engines": { "node": ">=6.9.0" } @@ -3134,7 +3414,6 @@ "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true, "engines": { "node": ">=4" } @@ -3207,7 +3486,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, "engines": { "node": ">=4" } @@ -3329,6 +3607,15 @@ "node": ">= 4" } }, + "node_modules/immer": { + "version": "9.0.16", + "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.16.tgz", + "integrity": "sha512-qenGE7CstVm1NrHQbMh8YaSzTZTFNP3zPqr3YU0S0UY441j4bJTg4A2Hh5KAhwgaiU6ZZ1Ar6y/2f4TblnMReQ==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/immer" + } + }, "node_modules/immutable": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.1.0.tgz", @@ -3495,6 +3782,11 @@ "node": ">=0.10.0" } }, + "node_modules/is-hotkey": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/is-hotkey/-/is-hotkey-0.2.0.tgz", + "integrity": "sha512-UknnZK4RakDmTgz4PI1wIph5yxSs/mvChWs9ifnlXsKuXgWmOkY/hAE0H/k2MIqH0RlRye0i1oC07MCRSD28Mw==" + }, "node_modules/is-negative-zero": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", @@ -3624,6 +3916,64 @@ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, + "node_modules/javascript-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/javascript-stringify/-/javascript-stringify-2.1.0.tgz", + "integrity": "sha512-JVAfqNPTvNq3sB/VHQJAFxN/sPgKnsKrCwyRt15zwNCdrMMJDdcEOdubuy+DuJYYdm0ox1J4uzEuYKkN+9yhVg==" + }, + "node_modules/jotai": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/jotai/-/jotai-1.12.0.tgz", + "integrity": "sha512-IhyBmjxU1sE2Ni/MUK7gQAb8QvCM6yd1/K5jtQzgQBmmjCjgfXZkkk1rYlQAIRp2KoQk0Y+yzhm1f5cZ7kegnw==", + "engines": { + "node": ">=12.20.0" + }, + "peerDependencies": { + "@babel/core": "*", + "@babel/template": "*", + "jotai-immer": "*", + "jotai-optics": "*", + "jotai-redux": "*", + "jotai-tanstack-query": "*", + "jotai-urql": "*", + "jotai-valtio": "*", + "jotai-xstate": "*", + "jotai-zustand": "*", + "react": ">=16.8" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "@babel/template": { + "optional": true + }, + "jotai-immer": { + "optional": true + }, + "jotai-optics": { + "optional": true + }, + "jotai-redux": { + "optional": true + }, + "jotai-tanstack-query": { + "optional": true + }, + "jotai-urql": { + "optional": true + }, + "jotai-valtio": { + "optional": true + }, + "jotai-xstate": { + "optional": true + }, + "jotai-zustand": { + "optional": true + } + } + }, "node_modules/js-sdsl": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.2.0.tgz", @@ -3655,7 +4005,6 @@ "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true, "bin": { "jsesc": "bin/jsesc" }, @@ -3676,10 +4025,9 @@ "dev": true }, "node_modules/json5": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", - "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", - "dev": true, + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "bin": { "json5": "lib/cli.js" }, @@ -3762,6 +4110,14 @@ "node": ">= 0.8.0" } }, + "node_modules/lilconfig": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.6.tgz", + "integrity": "sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg==", + "engines": { + "node": ">=10" + } + }, "node_modules/line-height": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/line-height/-/line-height-0.3.1.tgz", @@ -3790,7 +4146,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, "dependencies": { "p-locate": "^5.0.0" }, @@ -3900,6 +4255,14 @@ "events": "^3.2.0" } }, + "node_modules/media-query-parser": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/media-query-parser/-/media-query-parser-2.0.2.tgz", + "integrity": "sha512-1N4qp+jE0pL5Xv4uEcwVUhIkwdUO3S/9gML90nqKA7v7FcOS5vUtatfzok9S9U1EJU8dHWlcv95WLnKmmxZI9w==", + "dependencies": { + "@babel/runtime": "^7.12.5" + } + }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -3955,8 +4318,7 @@ "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/nanoid": { "version": "3.3.4", @@ -4001,10 +4363,9 @@ } }, "node_modules/node-releases": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.7.tgz", - "integrity": "sha512-EJ3rzxL9pTWPjk5arA0s0dgXpnyiAbJDE6wHT62g7VsgrgQgmmZ+Ru++M1BFofncWja+Pnn3rEr3fieRySAdKQ==", - "dev": true + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.8.tgz", + "integrity": "sha512-dFSmB8fFHEH/s81Xi+Y/15DQY6VHW81nXRj86EMSL3lmuTmK1e+aT4wrFCkTbm+gSwkw4KpX+rT/pMM2c1mF+A==" }, "node_modules/normalize-path": { "version": "3.0.0", @@ -4146,11 +4507,15 @@ "node": ">= 0.8.0" } }, + "node_modules/outdent": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/outdent/-/outdent-0.8.0.tgz", + "integrity": "sha512-KiOAIsdpUTcAXuykya5fnVVT+/5uS0Q1mrkRHcF89tpieSmY33O/tmc54CqwA+bfhbtEfZUNLHaPUiB9X3jt1A==" + }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, "dependencies": { "yocto-queue": "^0.1.0" }, @@ -4165,7 +4530,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, "dependencies": { "p-limit": "^3.0.2" }, @@ -4209,7 +4573,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, "engines": { "node": ">=8" } @@ -4287,6 +4650,34 @@ "node": "^10 || ^12 || >=14" } }, + "node_modules/postcss-load-config": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-3.1.4.tgz", + "integrity": "sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==", + "dependencies": { + "lilconfig": "^2.0.5", + "yaml": "^1.10.2" + }, + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": ">=8.0.9", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "postcss": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -4563,6 +4954,14 @@ "url": "https://github.com/sponsors/mysticatea" } }, + "node_modules/require-like": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/require-like/-/require-like-0.1.2.tgz", + "integrity": "sha512-oyrU88skkMtDdauHDuKVrgR+zuItqr6/c//FXzvmxRGMexSDc6hNvJInGW3LL46n+8b50RykrvwSUIIQH2LQ5A==", + "engines": { + "node": "*" + } + }, "node_modules/resolve": { "version": "1.22.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", @@ -4718,6 +5117,14 @@ "object-assign": "^4.1.1" } }, + "node_modules/scroll-into-view-if-needed": { + "version": "2.2.31", + "resolved": "https://registry.npmjs.org/scroll-into-view-if-needed/-/scroll-into-view-if-needed-2.2.31.tgz", + "integrity": "sha512-dGCXy99wZQivjmjIqihaBQNjryrz5rueJY7eHfTdyWEiR4ttYpsajb14rn9s5d4DY4EcY6+4+U/maARBXJedkA==", + "dependencies": { + "compute-scroll-into-view": "^1.0.20" + } + }, "node_modules/sdp-transform": { "version": "2.14.1", "resolved": "https://registry.npmjs.org/sdp-transform/-/sdp-transform-2.14.1.tgz", @@ -4730,7 +5137,6 @@ "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, "bin": { "semver": "bin/semver.js" } @@ -4784,6 +5190,42 @@ "node": ">=8" } }, + "node_modules/slate": { + "version": "0.90.0", + "resolved": "https://registry.npmjs.org/slate/-/slate-0.90.0.tgz", + "integrity": "sha512-dv8idv0JjYyHiAJcVKf5yWKPDMTDi+PSZyfjsnquEI8VB5nmTVGjeJab06lc3o69O7aN05ROwO9/OY8mU1IUPA==", + "dependencies": { + "immer": "^9.0.6", + "is-plain-object": "^5.0.0", + "tiny-warning": "^1.0.3" + } + }, + "node_modules/slate-react": { + "version": "0.90.0", + "resolved": "https://registry.npmjs.org/slate-react/-/slate-react-0.90.0.tgz", + "integrity": "sha512-z6pGd6jjU5VazLxlDi6zL3a6yaPBPJ+A2VyIlE/h/rvDywaLYGvk0xcrA9NrK71Dr47HK5ZN2zFEZNleh6wlPA==", + "dependencies": { + "@juggle/resize-observer": "^3.4.0", + "@types/is-hotkey": "^0.1.1", + "@types/lodash": "^4.14.149", + "direction": "^1.0.3", + "is-hotkey": "^0.1.6", + "is-plain-object": "^5.0.0", + "lodash": "^4.17.4", + "scroll-into-view-if-needed": "^2.2.20", + "tiny-invariant": "1.0.6" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0", + "slate": ">=0.65.3" + } + }, + "node_modules/slate-react/node_modules/is-hotkey": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/is-hotkey/-/is-hotkey-0.1.8.tgz", + "integrity": "sha512-qs3NZ1INIS+H+yeo7cD9pDfwYV/jqRh1JG9S9zYrNudkoUQg7OL7ziXqRKu+InFjUIDoP2o6HIkLYMh1pcWgyQ==" + }, "node_modules/source-map-js": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", @@ -4892,7 +5334,6 @@ "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, "dependencies": { "has-flag": "^3.0.0" }, @@ -4912,12 +5353,22 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/tabbable": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.0.1.tgz", + "integrity": "sha512-SYJSIgeyXW7EuX1ytdneO5e8jip42oHWg9xl/o3oTYhmXusZVgiA+VlPvjIN+kHii9v90AmzTZEBcsEvuAY+TA==" + }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, + "node_modules/tiny-invariant": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.0.6.tgz", + "integrity": "sha512-FOyLWWVjG+aC0UqG76V53yAWdXfH8bO6FNmyZOuUrzDzK8DI3/JRY25UD7+g49JWM1LXwymsKERB+DzI0dTEQA==" + }, "node_modules/tiny-warning": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", @@ -4935,7 +5386,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "dev": true, "engines": { "node": ">=4" } @@ -5055,9 +5505,9 @@ } }, "node_modules/ua-parser-js": { - "version": "0.7.32", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.32.tgz", - "integrity": "sha512-f9BESNVhzlhEFf2CHMSj40NWOjYPl1YKYbrvIr/hFTDEmLq7SRbWvm7FcdcpCYT95zrOhC7gZSxjdnnTpBcwVw==", + "version": "1.0.35", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.35.tgz", + "integrity": "sha512-fKnGuqmTBnIE+/KXSzCn4db8RTigUzw1AN0DmdU6hJovUTbYJKyqj+8Mt1c4VfRDnOVJnENmfYkIPZ946UrSAA==", "funding": [ { "type": "opencollective", @@ -5104,7 +5554,6 @@ "version": "1.0.10", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", - "dev": true, "funding": [ { "type": "opencollective", @@ -5144,9 +5593,9 @@ } }, "node_modules/vite": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.0.1.tgz", - "integrity": "sha512-kZQPzbDau35iWOhy3CpkrRC7It+HIHtulAzBhMqzGHKRf/4+vmh8rPDDdv98SWQrFWo6//3ozwsRmwQIPZsK9g==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.0.4.tgz", + "integrity": "sha512-xevPU7M8FU0i/80DMR+YhgrzR5KS2ORy1B4xcX/cXLsvnUWvfHuqMmVU6N0YiJ4JWGRJJsLCgjEzKjG9/GKoSw==", "dev": true, "dependencies": { "esbuild": "^0.16.3", @@ -5319,11 +5768,18 @@ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, + "node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "engines": { + "node": ">= 6" + } + }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, "engines": { "node": ">=10" }, diff --git a/package.json b/package.json index a37b6242c..38be28dff 100644 --- a/package.json +++ b/package.json @@ -24,14 +24,25 @@ "@khanacademy/simple-markdown": "0.8.6", "@matrix-org/olm": "3.2.14", "@tippyjs/react": "4.2.6", + "@vanilla-extract/css": "1.9.3", + "@vanilla-extract/recipes": "0.3.0", + "@vanilla-extract/vite-plugin": "3.7.1", + "await-to-js": "3.0.0", "blurhash": "2.0.4", "browser-encrypt-attachment": "0.3.0", + "classnames": "2.3.2", "dateformat": "5.0.3", + "emojibase": "6.1.0", "emojibase-data": "7.0.1", "file-saver": "2.0.5", "flux": "4.0.3", + "focus-trap-react": "10.0.2", + "folds": "1.2.1", "formik": "2.2.9", "html-react-parser": "3.0.4", + "immer": "9.0.16", + "is-hotkey": "0.2.0", + "jotai": "1.12.0", "katex": "0.16.4", "linkify-html": "4.0.2", "linkifyjs": "4.0.2", @@ -46,8 +57,11 @@ "react-google-recaptcha": "2.1.0", "react-modal": "3.16.1", "sanitize-html": "2.8.0", + "slate": "0.90.0", + "slate-react": "0.90.0", "tippy.js": "6.3.7", - "twemoji": "14.0.2" + "twemoji": "14.0.2", + "ua-parser-js": "1.0.35" }, "devDependencies": { "@esbuild-plugins/node-globals-polyfill": "0.2.3", @@ -56,6 +70,7 @@ "@types/node": "18.11.18", "@types/react": "18.0.26", "@types/react-dom": "18.0.9", + "@types/ua-parser-js": "0.7.36", "@typescript-eslint/eslint-plugin": "5.46.1", "@typescript-eslint/parser": "5.46.1", "@vitejs/plugin-react": "3.0.0", @@ -71,7 +86,7 @@ "prettier": "2.8.1", "sass": "1.56.2", "typescript": "4.9.4", - "vite": "4.0.1", + "vite": "4.0.4", "vite-plugin-static-copy": "0.13.0" } } diff --git a/public/font/Twemoji.Mozilla.v.7.0.woff2 b/public/font/Twemoji.Mozilla.v.7.0.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..b3b20e9aa3883ab4d49696b074e94533a04b028d GIT binary patch literal 472228 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

    A{1jlFoA)JNTyYH8Bqw6_oi%_SaYNDTv-1u$U) z|5&`mqHM7>B1hj1$BK%$W5?(e+ac4LL)Tlr{`;0%OdFLkbh%T~t&VJRsd^KMhoByJmCI2_h43k$-&)xN#ofAnz_^3Gd!u&&wyDSWW`? z*mZLF(IEc9#7v#jBumBQ@)>aHp$9$Q97pAR^h_XDN3>s*I4eB0t}y_)a}F&yHUWL! ztSAgFNG{jXPS)f)ofmh%W=s*pmUX#QwWRVBS>oRI8QlLB!6fmMMs#sSlx&~L`1c4f zE}QZdFcK8bD#iJgf>?dC@EL*~7lO=6Z{tb}qzWCV-Sj<*To)g#&}UVvg!!t$1r^00 zd8w&YCWQ5JZDu1iY>B)|L`>|XtT|u(W&$9h^kxZQ?|&DkVOpDZ5C)k4Q)MBWG)``N z6A?Lv!>zlRQ}Wvx9I6$*gp6VPrhd8#OtQra;Zh*O3$-U&@mS6!r?sN$`5uMMU=DdL zHKcJR9fbaVru)!=W*}3qfGa{aM|T*!1-z6NIAlB)$gd@q<{4$Jxj+eprrfzT;E}A+ z4jQbzc`%8W*Si(}PxOD>??W1e_x|!0lk7Yiy@9Ux8a<1*8go@QB4*FJf)Yj~ub9Jk z^}ka-Z4@w3Kya{=N*NJkHsw0ZqY;1-xxj|{*kr^f9l&ytS4(NSCwvVka&X8R`kr}; z!47uk7R&Csp073lK$Azr_R*M!4m~LnYkCm+TR?z$X-Uyvwhgw)90lzC77pgzJVY-p zTyz$AXAxbu_myQc`OBRFO_6|{BmU~@q~Wh|6cq|nem}9#@CW_ILZKYTT{0S@WX=f- zxxM#UFN)!>#>6S^;At6Sl;Z4FP;++Pd+XIyH~Qr0>*%`>E7TTI7~&Z>2hH|UmH2Mt z?b!b>ewA?9KOXIB;CQE@aQ27WC3tFi30!{SP?_{e36Yr`X;e+0rz?%f)UnfOhY_MA z4K}mzC{lICe6c^m8I#yb0|41IcxD0xoDStglEu;5UK7vt6)iCmnJ@e2G2O*X0=w3V zVp(imY`*!oKiA0lGwO4!WnZSr+qy-V-q(m6m3V3l0Z#iy59bTL|0SxQVYxJ$WsUNp zE_OZkY?qxRF;FLg&kN@~?Y56lIep&Sd?9$aQvY8^f4gyP6Sua2Eqe6L%F6Qft79*m ze>dBkk)~#;n74KIHZ+3H=H(YW9Jd_D-g?~VTsh<|SJIq}(u{12`XotcB5aUZ8mUcV zlFaob{UeRC&1Ud*n6_r`P5o9qscu5#4|OUL(F*dXI(<6T&%ZT6SXZzZGT};+oBK$G zgH_GzyqQZafFRGM^HG)>hl10G>rqk<4E`o*Ak=;3F(!SP-sD4dGxb`h_Y?o`9>HGy z9DQZ*Ce07c8Kn$_8>aj~A9yNmTO$W}w0w{S!;Q2fjG0p4xf8#%W)eO3pJPuKB+v*= zx13TKO~STAt%zi{H`*^mSE`9xEbqIvnr(~=-Q_#yYG#521rO+Re{Sg0NHFvmu_7sp zo?HkhUix^r;aC(N)$-&0B@CN0&}p_34!h~GagF2TwlaRE!gzqIb%bpzdOC!GoPs6N>{49dpd{Iud@{ z^-Cq=;R8JhVtxc%TDqMVlNS4fH7bNpprcZbk^u-w>AKNeZ7PS=dKL71h+S1L8qam6 zxATj$vq?A({40eC>f=%idJpWRISE8FJ~Yhr-`m%UV)lM=`rEnAbp3I$v$faliLr!< z!kyl#dSU`{+?hYD@Qum$nx<1_D-DMyzo;XEvl{9Vzz9AlWeJ^kgUygQsauDEHN9+p zo+d01iKb#qr}u@_>L3LB#R~a#>}BR=H98C35IEGhUcy>H8LoCX{3x#Ghmo{H&_7ds z7*8GlQ#Ym|<>W?-!kuW0^$R3Z3~`E6d-7rFH^*aYyG^M*eH>1Xk#9&T+G#M6E1q@w)&s(||W{b5rP7)5gx1>11|EA`P^q;0x zkT$+GCh%9-N*gBps%LSz#gl&tAG4)`;e>KA=F}Unzc*LOIm@v0^emz@j9*%*je>y& z#G8HR@Nn@0#-b<^mWzqJQ+0n)mH}xX!!Av|cgCBl9>!#NY&XKPLz`GH4L@alaaV59 zU1qRr{rb(f>dlU@TFA=km=h>gM+GjD;!F?^~KNN(?J?=}~S?DnPlK@&_*06h( zxvJM<((7zJlq?zy1`(#k)?8ZK4+e@hXU(>M7vpyh`^8zW=gIY}FV`QYx>IIVkgj%C zg7EU0?{KLz%$#fQZY1mPpe1{u^`us6 zK#cD7^{}H-u6Z%Ewc?7`;?9 z6#>6if%q;Og3jLGO3}xR{{~zT9REOK^DHRUup6yiZ!XmmZ6U%NH7Q(M!@Cr z7XMPYyNi}k360wVcb#|$GU3`(ScbuwDy&&7*$LSY13#|qUn#qV5B|cH|N4S`_?$3* z+ppL?ImyfnTsi6w?#?V@jqCJy=~#wi)^QkdSgf7y%sexHw5ZR!)1K|z5yofThpHDR zGq#T?$ko=SFz+Red!E#$q{F$_MvciJjdATUWDNTvi{yT)1x0p81jt&2brHl_=e4AUIfhB{)%F!}t#+^qMJ9@cz6)U_f%WKDu?aV?YTEKh6?Aw>Wb~D^g zBBd8MWkC2yG2LLf0fBSmLItTIic}Ihc=qs)+Y(@kGGt7N4BWN$DT2jwL-3m!B7$UO zG!t7+16FfWN~SGEt+BnV$PvL2U*mm@wO;cKY{z$AVTX^YiX3e* zuK|+5shpqGn0Z~$&UpclL0X+GrUp4f?ebRf2^2|%OFFn2F3H^iW(@ySnj4TOX4cz_EN%Lt_ zjJ2$vanyZWcN*0S>AL*MfNsnaRm*r;Gb&AgE^8+%_rE1Kk7b!DD;mnU7eT+3fU0y3 z*s&1AC=som<0E@PgT_IC&zF*Nx%`n%jN)&^mAFm*uVskd>?})IdufD(B`+n_b=x0j zlLU`p|1rHD2tTkZJ)S%5H$6f(JK$oiDiwu(Eb?Sv2ARtHS%$CuI5F!?(Fs9fnN_K3 zI0Xg3Cv_5wRH$Oyo@hi~oGM$wN=XI$$WVO#na*-#TaNw!Z^c^ZSik?t*N-nYDFRGf zzHxDsg&uSNOCSq+w?hB}Ah@qH(3ZG6W9~w4Gl0v;ikaEq5b zljZD3XgW^5LP8GLzc~#F1Q}N9`cm2t4-VI%%3HK#PP4PjB{CconP+x7lJd5v)Lw;ofT*up#RnAmJ3w|;%V9x~G z;jmW+oOgifO1mqlYlZ#b(f7rf)J{n|2~p1^%(3$|L@6IQdZGa2&)MHR9(uxLOV?DH z$fhhxdy6MP5^lbC{2R?fO0VT{Im ztTNt2q02W6Fe!*Wl!SYgL@0{A`IgfzYD>*J@I*{fFelua@q{%Sx!?hwxO^XRlN(Oz zjeuw&wWgfe&;fG4&2FJxXapa1SimPPhH{KV(A%<_GOe z{$e6yI$RUWnZW@8LcVtEVL?)C1#nBr>M1Wi{;A;SAYqGyQ=>+L`7{8aKhlHi10m{u ze#d^-tq&6}#wR%@UOZAWoGCtEe>QfbWeEHDutcBtLJ{xfS#nmDO!7KNN-zIh=Wk@Z z%-1UDof61er!5mZIL`t%z6W0B^|1BRYMwikQzWYdk?+;LE4MxCmYC08G*uc=_$QYp zk_5N_TMoC0xN+z@OLeCj>3t1t3YLOg@7P{n!DL8C(=(PK7o4i{^&4!+Gf&HlaRKIt zWCVhldhypMvsBz%6MST5_Jz`D@NcPJp+dd|Er;C{Rv6QSvztjAc>n9dX8td*4IV#dnF-E=vuBR2()x}$C?)f5qUzejDxj`k zHOVxC%39{j7QK)#3nr?;lx};j+2!)KZ*o|$T`YKao9obaa?%Bgj%yOCKKm=@*=kU@ z@4whyq{yQ)JF-a9W0f>jpCgs2jeb|Q{^FuMbK9lCjkcSfUX zmNBqZ47VED&*0J-znfxzF7zLz7(L$A94NJ9K9=*lT_=GP^(up<2Ne<-Zt{c?f733VAGAaH8i@%vB`$BL@I>~obtD<*uDWAvo+I%j^X=x#qs~mI;{fHr z&sxYc{P`ofb$BP~08sR^2FxKe471L9Y>ybMfxwG?*4e)So%nCotpon^#vY)DzaV0h z4I>x7R(uPe`OnXcK6icjnzU=ji0U}o-D(tkZaVbD#Hbc-LjdJHI}u2H`>??A}t0>-ee5h&YzG=aFuAJG|)bNpwwe~nvyw!mdFz}O3w zT`qhmFszo-5-Lt%HZU~IrExBl4-qINKV(Ci&JR8tWW)KP0a&_lsgNW>r>wKlJksv!pU^ zHM24Gi+(7>{n-q>U=&Uc|CPVoE-YQkx^>j9=9_ZSmCzAy<%hULKu-Jm7Ck*=v1{*Q z9Nua;vl}tx!=0jg3eIexbwa*nM|M)gf`n>NPkEXh=`FpkjX>m+%oqZ=`UYaNs^ym5 zSGCk?y8_X`2n$@JzsE_-gfwh8eX<`|GhonXbIkLe*|~LJ9P(cyiuwtryTN}~2QVBV zGlLf-THf)w05L$$zv7VIyJBQvbMwCP}LT7rad&!Q`9)1MBK4gjv9f=exN(!Bcrv0SO@mTd?0Et&y%Q zPcyAC*+1c6BMTG#^&Y}sNEZu6`>X9a*b zkKe~=$)0=IBSFY2)DI&7)GX#Z!Tc-dYaG4pjTCiGc!8gs2pz+v4;|~17qb_NDmf)& z_~aM(KTnLO7TypQ2achz9yR!l@4D1`q-R2xm|rW;aY)W-1Sp%Q_oz$|s)9#Ak4dH0g6hnrN(#Ozvaf91yCzK|Azlje46ck>;Jo7k)53*H}J6KsUzVc4-tc* zD_!GX$ai301e%5+rL+#iQMKWDo_A|);Qpa%RD(!5Lqay09GCx7^yqVK^GxIMVF>ky zALhsZ(Yyd*1wf-M2h?GkS!ag+8j2ATxz1Us`rvFD2#SW~l7u5|p|ZlNNiiQG%3I7! z_vMmYB!(vv2ni$f+)SNo!alP=^q3_Q<pn_^4=cG5~Z-DyRyBX(O!$6>FU^%1+i zSJ)aW{pThn;)zA9lFlr1Hw0j!DNgT}9McM5ivnFwETZ6g+e5$F0uS~9sMcEVJTr0D z+p)wV^LS<;gquQ9QJ0*WsFQx#Byk>*upSF$CJX@}Y!cZN1d`bl6^2d#td9>&y`8ec zaXw9aWTFC?Ys4vVg!?{P;Au>p0-y?jg5w>@0T?0#9?PZ9UMrb|wTkW|cK5oA%)(l& zvEn&Ms+3Yn0X&h|W)|AoSwOo)oPr<{k~T4k2h11|-dB1>WSSW!AkjGyx0b(~vH+;# z6;!|9+bStL$@aafT6R*wFUYHy=U6l5^`zvZ)^Y zOk@ry-eH?WmsFc*SDGFB9JRX`hU~CdFAYqkq)opc)-5F+qFxYgKQa#?4R$kTlXBW7 z>P=7HF8^F>$Pgyb;x z@e(H2u$4tOaZqpZbn=Q71-@b~#vj=XF{1VvC_7E{!WyVMdI|!XQe(<|I^+bvOf3OS zPkR75ntI(+VZxYUK-i!p^&{uH#017LBsoYbPpr?RBPtT86jBO)+a|6i#R3V269i70Si)0Cby08_6lEOn%;8_R zL6i%dr4G)QMG_&g$%PcKY_%h`lE*5~Tatxv`DV;P1iDBKuky0t?j(*EbyrY403)8^ z2MUwY8#h=1v%p(vN$x;J<=!qm7?{HmLe6tE-`wjE9v~vmW7@5+dpsz=P68cXI>NWp znnR4<2TL@G+A=MnZ~8uT4NXoY~8=K}~D zJ!=a)Y_V1ookm34h5zHaqHBLZ2h`RQr1)+7WN%7+4b6yXffsBiOUnxcw6z8hYUltc z8Vcs1&|VFTv=W5{)tulmEohE@f;95P>ok%o;&=oxNzCWoOtR|5;_Ul+x~T0ykyK>{I=)<1LeE9Q!7EMsTbigh@a z71+wwHV|rpu?!ZQ8*B=!e4CM^@l^gOONn^L`hlAO^}qVl!5yRMXf#ATCq)$qOkioI zXgTEfgqZ>J4!~A9uvwXrpQoX5_!ClVs7TD-y2V6xVah{fmn25*I1-{aoNb~=Y)NDfuwme`QxI*7Wxh}ft0sfYzg zt%-lebY_X^(kwbMGSyTTCMPsB=U6d^XhlN#n=LOaGV{?ahe_!0XR>Wg&zv~c0I{OR z?jdlm;*}T#D`dIO@Qm5-K6BoFCNmd^qaXur!8bKJ7h(5JI=?;AdLB*mb@^3F0!o0< zaO&`FR=D+=mb&>J*_(;pX#2p`MJ8FZjA&cYtDwwU>H@PUI!5Bg5ar0*3HBhbC$j?; zwd7m|gjCaa0Aui#9fa=z%oX`vqNP6?W5#1A^ZN{pO0z^7DtN5w$m~RFC+@V(iwQ=} zO#jw9V4>g2?~HXmi8Oepo9{z%Mq;vu!zv%OpfQbSy-5U3hiq)&YJp9|kS?|VPJIlf zU9-FeZSb>l8r(^2VMr_ow{ioe7^@&Dwftwen(QN`OS1#zGCD% z^|P*lmBQxAsg;F^R>I0}WB{m&<`s70moDXx)nMh5?r&JwUcr-6e=2V9C9aKL&bn}H zAD-(N{2pJ^1sPa*=EPc*uf)X2P+*GRxY3twR<~&h3f_;yeVGjhR)UJKTw05r$6pZ( zebe3AmHAy|prRR{WtX1G#J|m?WOAGd(KLQzwC`#R{x&arGxnhtR%3PHzzz23{YZbr z;X8R7Q)#xbZVTZ$IuYNo(Y+F*IWs{le@#ASDFPoY`b|sOLIRW3KJ{m3En2(vTs-aP z|1PZD%KL3J(~wi|=IAyi$fjC(-p1+!{)72c3H?8wMwfObPnZcPSuyzkIMH8gPWjL| zF#D#Dq6ohfnhaeQez}^w$&Bqco92`ih5qH5hc5iORh!7D$#<3n2vy;N^TjF&Sfv1eyNyi?G|7;fnZJD;mw z{9cSArq8uXT&Y~I^!aseU04b3NDON(9#SFMRaArC0c0#J-0wViz*!7rxL6Ag=LmLE zD>+NsiU#N-?#hNdj#C#HH`?-Ha*i2%1lfvH$Yy3b6q<_g;G1+OW*G3qs`a~kYA@U_ zEy=@Mx#yj=j$*GgvrIMl;Fa$U6>KJ1(t$DEUjvEjb@bRkG&(j?NIRK3Y{@VsGBE7$ z=vZNLm>i={iN+3t;&zrCOX6rU8aOr?@4pZaj7%mY$K-&JA-~}jn2HJ6K(xks_AQ;$_Nc`YRHnA8LR(_;< z;G?K-rAxnu-&SwlS!H^YxqJQvKa&8VO>0JaVqT-i3KPwui!k}DEL30qpqo#f-h(*rg|$2(15wS=|UzlDY)5GpG3 z2o5vVbZBn>4v|X1sCk@DoB5lwVHyustQ7sszRp& z`S3fU+KL=Ld#zWO1_d^(ox>kU(`}MraeDo2`4KNxTW^!ZX{U_U zT3SSgcbfZ9VIkK^L2bg+1qxt25`*@6uvj4GdfBuovqvdQsa6>nV`>~3C1X-EiZdrX*rJ%$TT!zt<6`oE@Fwm-A0@kiFO z6JI&%oO-eGspR9ehk1QZkM1GpXTk z2h)SHyVn}cM=G^*D%Oa_DM=@>9BO6rC58%ybHAxVg(mwC;ny!>`1CtjQXs7VMA4X% znqSz*OgzSLz8Xff)TY6eV#9bk|Jycq@>cIi$d9J{^vVX9u>_Bs`sdSA1MTEp`VF z?=)BNIodoh=k($B2UPSW{HY}JKfq!Vj=PXnbqobMIRMyUo&WMZLNH7S??%l5C>xlD z0dbG&!C^L}BXgElOt~tBUOw`=&9Prh%Is$oVZ)7GJRJtGEDSU3%uu-eH;Z@kH<`|; zt*)m<4tx0{?c%`wLkrW* z0pE(cV0YO*Jqr=8@M|i<2Dr-)^4;x}XW>q2q@TgT@%VkACvuo61B!;M66#AIl58%A zRYvI|hpsoS&)6ApZ!^XkcVkWi`-*e#PSaL#G&%L}#<)6lr=_C6eS2DEe}U|0h)LVG zh(Q2UsWeTgi1IvKOgt)N`Xt8=+oYV~A)h7>5nHv#MET#rkI8ECAfLMv$csabCDU_H z@=+_>!_3#>>qk1o34OA_1mMK9uT4^-u8UqvthE&p1t)Kij0rk-t1a)1q&{$%7gpBC zAC_L2FS+LMy$>fl_3dtKw>m6*%HOY#Z`QT;rFrhPPc-Z}Ns|a=SFWdw2>mPRxf$OW z#tz5%fAj7e!Np!6LvX4*t54qH!(q3AHZ6NNT<&|55HrsR`mdF2oORP-)`4Gh0dJhC ztIU_C?I${M_G?faY~(&?p#u$?mDh710Y81gY0CU72MkVPN)J5C z0tIgqPwJ%0k$WdUEnkTS;?SFsKJdINpYuUBUpp|nZ#_&A0 z>bz0XrS{BdAdH@z3>1y%slnjPI`M@rs)S`0q6;y$D|# z3H$X`d67teX$R^2ZL$+P_6^()WoUen+llhS1MeWzA?nzB8~fB0fdN^RW9xx+5~)B>HXX{&JT`SCMr3cMHpfp;WNsv{#5fcr4}z-F z{tHtLi!TI~282X~U|a5HtG8Vw&>V+AOCtx9d~zgez!~H4e>VS3k4??oSNYYwc#ndk)X)pnU?{qDn4!yx-CA z@Q}`{+s-ZP}hkz0y@g1*A#4F`LJpOJoNFZ1LDXA2_N36^ zj;?^2Ye_VACk%pQ3`TG$c*%kWKj348c+SQ^!ZfBTiyG46CwI#L|NhNAe%ZX&*Cf@_KJmjYFAUQ%CvuYUQNcA4=2Hx zEY-oZXhKF%;TvBhGIZ))hA58KDv0WY9a$1;T(u6509w#czXga4vE@*GjQ*5RGRPtP zg?K~d08LH0&BniYpBCAnKx2@yk7zi1+oLKoZ9@Z%uz9VcUk5M-ZK!~?Ljdy%eEiQ}MwZFZbK=OK*7FTm zyt2%x;(NY?+y!rwcIP5lFK(-2^@UK1XdGS?kxP)G6+cEl?hn6)xD zKMQMHSvs{fEbH=Ydr8UWG_v>_iCo|!0o>5w>M*7uckyKRsL{-}&S8j|IXY2jqCG&1 zZgR?5j1LE>K`*MHwUtD@@U{;)Mvto}xN32PunVMAX3roT5L8bbGEGnGip_kk20`0n zc|Wk%HSdfbSNZGRSc~)qi0|#RX6r8yYm?rMno|O%p~7G2dkv0cYRA{c-?Ihzp6g|& zGu3${Zwc=6-!+(X##s+h>jno1d?4_aZa+?CSW(=vi=VJvg6jzj9c@Ny8F7 zhEj$4XET$Ws6r$_hTt9!V<}7~0U_1>w|otZ{Q1s~zO=Z^qCV-xJM%H7?i`>i$kKG) z3L)F~u&YIQeg6kwkhX{f_53hOw= z43fY=sAdO*+~}NXD1121PEiDACfsvKa=bpt%uYwxHo2J@7bb%eh!**f^7`P|(7@QR znFi56WmX$&!}}0d;$vPT14utH?j)tNl`()TtMP3jg_~h(1f^HDFw%HC4x`2fH`vq{ z_t9@Mo%IkDSt6h_o~`?-T?>O-%QF9E(*g6xI}$sD?m%-ME)MMjb*m>!8HkU_omux zi?rOzEg^KTq^bKnJDu#;ink{H)VenJvwSQtx2>bsio=SU&ubKUEdi6)zHl%8w$T5u zgaGZk#!GZd@)-E1)w++wOZRwajC0r_;>()0L*Ll*@i`FZ@whG=eTsU&Xp zH0fu>g%!5BA=GXJ(YD%MNdQclL9O>onV;RA%M-o;Q3h2ZEWgS1N1{0_uqs4xhLpeU zs$gJ?sst!Y&0|gdzj750sdAjwk;!IF^RBTfWf@{M8xdxJB4vlNSb-0^onM$OCWEoc zS{(2eJU7!lz{f&=hJaJeB+`M(584IzC3=MPSwd%jaTkfbOQjn>*rdT|X@yXK!h;u)7%@ALT1!AecXu39+=<{;-;#7;_!O+O9Q>c zY{1<14Km_hBaOn^j#@P7aMk(-S)7E z)7e~N1TK&$0M!5>>zM@zC}@NXnnE-%l+7z*1=|yvMct5Lyl0_jf08j~Iy8A1p(5QH z?sPjNskZUZE?%epI}W?cX>KsLV6|*7@_s`JEvzoOkw%#!0Z1CW*Eg*G9TUD4wvSVx zE(WqzSD2j;F5QRTI8iQ^V7#A+%g3R*m)sS&soUF|v}+RE^FZnpM*@(t%X~;qqe`=% zNYeSV;VOy8S9)X(FvX4J8T4pp!$GK7V6Z#^1$5R+MB?8cTkD_{u1 z1Jfg|P_@yr3rvi)C?EtW)`EK4C=gCfrm(5HDDC?hRP-w1)ApFTQV}o8*ZGoOxIC|k zv%DilkUWYgdA?74`d&+t=KMopZrwo-=-nU=L*+BRlR` zS;W=VFJm$LzTSO&^-&VY86ms~f=482i4ez8R463ZZBd4O;ua5KSi}c098aHR`O_Ga z1>{%jdoyNoZs*|sYIrwPO0JTgzKO+X?RhB;n8~Syml;e%$&+0_bR{oG`yXcke%1wW ze=>TDeJew7=FL+wYfXIiT?^j3IiG99LBWVnxw;xFS=sDWan|>kfe;pj^n~)%YHhOm z>GE7$5-X)?3MD|)#)6t#>h-dayFU9irPl$XWPMX$g?enShvlvK_!vZ@#oUQjm3C~L z5ivOtoGUlj9sHZwA|g^GjNghDcu*p&!9QzgX<-1HwF?8BF*!`aO zIJ8W^@UIZuIeonREq0?wOC2+nR9fUvl4|3gg7Y9~p65J0*hOj(M6BcyG4X|T8lJYe zzBh}+P6^}(2#cPgl>%;MaL6zAa1aQt>#Sdz^UuQXZh8-d3n#q=mwERano_d%H`4l8 zkMe797UlC6rRm$g+FCl-P*HKq$L+*ZnB4RfnyIv7aG(U)>2Ekc6%|9@D*3|D8#e&g zxc{Asq&pd0XRYmFvOV_EgvD9@2tBay)^N$GKX<1lEqSD8a!^LjH!_1l_ETT-4 z9E(Wvfa(^JrnjTEMWlO@eU6{aNMOojcV=z^(f$HGnFNZK_5j*X4Q?S^0XQ|F6=PS9 zxDB~VXVJ@4np2VD-{MUoZZZX$?4ww>on|t;4e01wjhzt3PG^#9k8?B&uT`o9&-Z6r z$)9eH5x$}`(>g+Yv1v%>^!iJDy15#O*URy_!`T3}cFa7u z+dq3*W(6taDmlfZnP|kB`&ksFTI+#U5N5iXLs*tY-g;qS(GQg?u3V$Q6*pP&*-)lR z`U4+v(8+p@Up~)_w9iU&+CW@w@1)lPdE<5w6P4x$p`BPKh zWgBY#op048DQK7oZDCG?U0L48Iq2nSk$KR{VhitZ^~Bh#<`dKTsee{2+~C0?(~%Ct z62JKSMQ>FE| zY(2~KAuS{o+1}=IN~T9*47^^1@yh6>g#C_%nDF&+Mwc^)W*UoEKzmm_8EsE|Ch_rU zvz-m>(c}A-ou~^VSBKY5s$rt+C^q6Zg6f;TvD-lbewaIKFfv(y`_lzLW^A;B(%u7; z&{t)~4|9a6i4Qv2FD4$&gLh9Oo7ww=bk1$eQ+@pp5iKGo(dAX*+4yO#1f3e!O-wrl z_JTW3MGr(O^>(i3iAv*c+1nTJ-+zgGTxD%b)mEg+qt_;SxTx&H$QMk5Yp6ec$CJyW zQ4EQldF0|VVL>n}?IZm!BAqg&A8mIOe}yRB|N6x{c=)(rXI0zG8fkfI7e-9_rL92v z^!ZNz?x4Sa-!6V+(*MWdqPy+Q8Yt0DlcTL!;1D0Hb6I@TTY=tVlXzlBoW(ppP^pPH z*zvoRMy5MKr?#ZdnVUb?6*a~X4zJk~tFwoU?IX+FPjoBjP0A_FX`pHpSNchmiOHrS z;gnOUnt!;6qCf**Sc%3$tDGJyR?Icn0{IIAj5ZMvS_zIQ?Xpu>QoO7|^2N*q;m7RgC z;EPPvqj#%a#Cznb&^mcgJut5}^QO(H@BvG)!y#2xVBv z-~(1Zw_{Oz4E1{jl!ye>Wlq1ZW7OY6Ykl`7%-t)GPhE-b-<|OgA#ANK&ODUj>3gJP z_F>-4d#k$Z$8~deP=BAiIkbg_zo%~uE|i_~-k7vLn+16Abe#x3PI~j4-l)jg>&B;J zs2IULs2WyomoA+xYG-xh?W29b0l$+*LsfifE21>(9b(#=Ker8X^t7^;)503y;C1O{ z6=**FY4B+b#M;rLyPpr-{U>S1#<~)VI{ZNpId0Y%o=1$nE~E15y*DgL%&@memR|T83t{PM1#W?L{Jd4{RwGj zrhj3KXwboMZe3|y(sdau+N-{%I;G{j&qI|_f8Gh{m#i0SmCiDU&r9~%AKqw}+LZ%Q zi+Hjn54#a^jlW$aqcdCSOg`>^wQufdUFb4R$?@l{3f@aY?>!w|{j(A1TOBGMv?MR@ zk69!}(6;rQd`{l{LrJGp+WhaeLd!H8Hr8xt6xa$C%{bg`l5_ku;36_RskjGSmJuQg6ZYGNv}=t{ZG!Bg8;pDDfzWGGf0 z{3%>!gTrREmICwBZ>kLCd*@6SePQq{+m(juAd>uiGQEGh_<31X@?~)95{wlYwqVB> z4O(5Oib{;ep~n#_jVgW^>?GPYucE(YUm*q3$@AJ$rNo6NPjfB+Qv}z*Mej-)HZKL|`d2;(UbIEbOqNoea}kuvMN50C0*P zOy-fP7m}^=YOH=K3GBTJPyMvEcsn&;dS9|$7=5ggy^%rnM}4)M_~?L5z>)bO@sGfJ>{J$EbB9W^|ByC~K?;9JcqO{H{iXbK4U@%{weK zv?g;*gpn!XyKi}s2GmZ#+XFY4pB44p2=znrG}Iz7JWp>K;)+MMn2oK+-8d8BENtsd z{E5Heh275Qy)P|1z&n)o?VC=o*?DT4JcWGa>3$!tmm7BYVljhg{OobmGWY3;x)+T= zsr|M$_hd0t?r_dpb|S{&VnFjb>pQ|NZMKbx>O1kyan$Ll3_L#)o>OEKm-nE}r#xN)Y7C!h-8*nR+1PEs>GG3I`^RC#1w=W_u`K1F=&YOM zVaaCFb!m{LrJDFy(WNMR4(8MZWUa%ixEzH&=Qw`mtDHj7uh ziwn(|$r$F~(4OrT2gAM&Lo}l7#Q%3%!>HWrzcCN$b>7#X0{M{3oQo--cSUT<7 z&z{LoORq0_OFVsg>{Siy1-7Q^3J-$hmLBYS@+fzV;|KhcJmjzy?iR_NYj-DlhhFT2 z{Vsc0FV1HD;6ig^oWW#J`sAq@D>|KSa297s+(e&2a4bfPpmayN3BLm=FW?W+eF5}p zlWugDMOe$|rvJ}qA1F3KX-x-HuQvLw+Hqw+x_6=Eu}(?#ib_~v*I;Ec8d{lI30f&W z;!4dy_`zqdpEygnGjOkR!>eeQ77KnBj?>tax?m{SK%hb4S?`MubW~QLRh zXG|kRxU;j?^}a{6dL>euXv^(*y|q80$5IU40VG!Whm0VuZmG%( z@jkK$S`c_lD_ZAEFQ*Ah1N4{`O|$kN7=$4;Lv6>$dFV9j8ueAf`P5M_#612ryGF?Q zp>^&l4gy~p<}#fj#>dq1D(8r0uyn+gPL~Xomj|zMK2R~FY z%RJF68I$z&f6|TNRsGQ``)7qaFk{q!s_rdwXJBV-(!)hjJBX(gvfg?-kV8ipsk81$ z$pvmO;}?0UQaio52yN|AmE&05v{kBb5(w|@m=l_IycG&mbJkDid(N%oO?@QYQeJsr z;2fOKcJ9nUl<-{zyvUv+f(RsxOB`~bfgY8h!$d^0u$_F zJAp6TnoLE`_Nuv!kEH<;U_}DTMwgUYYbxA0+nzMdxErw`790+$;xDchDc4Dy zy(ID#>;PcKs7P2JFp(HIN4QT!vpfkos)zetPFljHa_)wHZA_5UxCwct{2Oj?1l zvgjQov75{US_K4U(~+UyiQ`tZ2~ST>nM2)%P$lJgZj%1PJMk@vP9AK2;O5ujvo?Lb z7APUZjE!Ne2!Y4u$6hb+BdUze zjOf~hm;{&=3A5m^Vx(EZ!xBP}(U1{3DS)b#?DNM61qUXiW%!HQNc_{Gp_aCeT?>l! z_gj@D*SpN%_}&P@Qj0*E zC9XmKM9+QIE%@RVA|`dP$Xt>AU3OyYZ|znI*kWhq;d~TjXok!PVNQ{gxrwQ%=chL@ zjdY|D{V%SaC!2!xs6oe~ajm5rUUkk;j!)yMgdkFjlA{Z7|HwqE<{n!Bm@16aZGkt9 zQp38Bt9pQ9)dQspDl zPEx7N6iG>UtWw@qj{(`c7K)syBn`#ct8<$>WywK|w~`Oc6G;sM5n(2=-O8_&DACH= ziyzESMO*Qt7>6at|5Roy?i}H3h`^E*wh`F3mA{Vp*~-c*>77p?qcEm$JMJ8hF;&Hi z;cyg^&Y#Z=bfH?^cN{i{Rd#0l=>_V$4%;qleTLmAhzICDnY>#t+elDHYJ(w{1_$vJClz;gOKv4Ha&h%x*doiqH zThFpjW zZJmC&6Mfz?#N^a1-e3$3-rZ$GVUAgMp1z=p*Gtd+Jw8*?ZU{ZNXg|@qG-`bRa7-7z z#3pW=g+YvE)KbcF)8iK#PN-?P#Ps=gaqZif3H4dIy2uFOX9J2$7`Hpf!GrJ1!2%De zCe){W)En-887MqwB_-VK9j_AtmWe0b__5E-oXfxkQ`{2Mh5Ou4H8DMUpPMQa`Z#u& zwR#v9x-1E$?3lZmI#>?gwJTcj{RGkxfMKy~u=zat07SHoZx zQ<4?#KU0t6Qiud~{^1M}M%y#-hqAi(%_x#DBu40!YhfuBWb^p&ocu5zSZHF#bg&&S z$M-LRfdxol8>Oa66rC~4Z&U|J&B;dp`OJ#9|Mr%O-O1pnMhle>Vif9MBI(R5=6W%N z3X?nTmOqWCNIRG>cD+gaWvedjsboy$Vr?{=ablcDes3JNV7o@bTC3G-3mUfiuh}rY zj_=my);y0%JA4)ymknm_DTH5H_l??*6-H_^>jLLPRZYhkIFmqtw9LS}MUF*`?QhgM z`kdFYNJ90v78xq4?uxM5A*>$}W&oFR2+0(FWC?wRFsWDY;4!H;66yU z^}3z-l%$}bW>t(ukf4++s$t3|4~8n;oel8S(_?G;f5E96saW{f((#uB}!18Ib-eo!;Vn>ueC6I3^M7NYoA#N!D*y)qWkTPhp#sLs~p_m;o|t6R&guA&nyfn-P3Rmr#7JT?)6;XJ&JSS zrk)hGW1Rmk+psv5{)q+9CQ4-)DG(`vL?}#Dpop1pznOj2?5Yu;P7QaP;L|5O@A?MB*_*DyAi;)2c-LTMtFez-=n89yfKO`@Kh^=B#ExG=FDZ;&WRq&a7I{=e5W`w zz*41Al?@Y@)sT_elII8m47_}AC@S3TB2nQ{1fo=3?j?YsUqA~@0NhUl!3*-dTlUQM zH9cG?)PK+&juJ*len%o!2)f#R=3@R=DVwf*cN|24UK@E$wCd2>7~Rw+dY$m8A{n@3 z+jtJ<6TR;W%GnhW!ruABO}fvHOLk}L+N$GJ_7PgpOC;T}L+53?eJyn&J3t6{#pPm@ zLcmWtgfP(9r3--9Ttd(-z}%q}+Dot>5&n6My4m*tSM@iVRh z`02OZ^8sQ2I;5qPvj8X@o)A28mb2^h`@OFzL2N7Av?aK=7JDpf=a2N0g_9sp9<3G(F4(-0x+e zn2pSLP-k2z_&`Wh$*dv-YfT=G_L@(RFvuI)HEJg!oONtlN$37dCWHluW<@<<{A83S9=7MS6 zbF*p4p-w;T!312#%hRC=5%!73UA3cn0@5D10Mfy!UJrkbz8}@SJa@BG7A+OZWV!iv z2|6hekL5*yeaoGyeK)4f#CQ>PJNUba+?5P4orA~zUi8__Y-=qK4Pg!tnX&I$@ltDR z^eYc)>vY`EQoZVW!zag4(MLGT>X#2j5hg1?eC$py|HGd*cJ+HoF0It3md-LnC1*O| z!r;Cumg%3X5*Sa3HMfHEhf!;GvS*otd-;qugSAn0Hw^6~!*>+F)1_V-f%TKIJ-EGE z<$)L{70D3I)+$h7+s@-=K4U3YzOV6<=EIW8A(*-JB8(T}D~ z61!2PAdlczR0o>pQ`-BatF!rqeaFY{1r}QX^Iol_@_vIEj7C(Q@b)TeA<9uN7xz#F z2g)^NO3DQ=lFj) z`N_l%Qld`Ffx(}}cFJ5qxhw7|?AaF~$Pzl-r!90xaVSCuBv7jh{^V8~XC29ce!oZ8 zNxVW}xz;Jsv0bz!M8Uk?U_!oFV$8laE-e50F8cNL!Pb=R3wtz zjXPKR;H8R9ECbAh=!VN2|5`ILI}e>l-4DB9?%v&59dyoL+C>CeoGmi+wJ;{8n;Y+U z<8yb3e)X@|)sb!kY}To5auxje8&niuc?>gC%0_-1$X|tbu<968MxY`uXks5JH;M@+ z!j3VjyS@~CdHEpy|BAQ7`eS z+%Lz(S|S6wO4V*X;UU&qk$vuEv_V^u`kF#WGU!)de{Af;o%UppHuvXCE}yn{{KCz< zgIDgp4zi3iJaMSw<~Mw<>LqKXH05e2)8?)c&cMHgeVf5$e_W~vMoal1p=uvj}fui*u=h`ZEQ z8Uo~~hT6t-0eUO6-JoL0-z|+pPd;1c|`+%CO z1R%wPkJB5dz|+)cE={r%AG-jMaG^?vvv^saOw;W(LfK%{u5nvlZmsdqU|3jN>##9> z#iXK$S_+)u?o9l(JPG)|-g;da1*N^^#v^b1OzoK1I;z2DcTS_UorzDDiQP*QlBKg) zu}Dk4>P5^&VraLv8YkgLw7uW;XkoL^+*#B01h(h-og1yZo8El*q;~srLuYwN#pXDK zV>m6CY=~_lkqfYy`Jhr~CpK>BV!Glhuskj0k^(`*bCe-mbe5ECid;u1(Ln%+Oa;5% zYcc-c*cud13}6!ff)0XDt59|XVE%U8^2V5tVHoU${CKQ&eG(fb9U%@HBmwCEzHP6% z`OlEUl4>rPL_AkY6jIcL6t2jCih7ymn7-Or8JT?e{rw#cB~5LQ;OodmNw zYPHHMdWnK%gG+&W1@i8JBUdT6YJ2aFS(kQ9tQp_c{bq5%bp}iIp=;Qo25{;SN5VuV zLK@)vm#4EX!YD!o@4g?0<&OQZEF8xgp!+_RZTEO^4^5F1rQPJATth2hzX-gOvm`6i zS9lH8FEZ(@d!^O7+AQ6j+MJiV-#%GlQ|~7u`IIMuOIaC=A|E8-L@^LtP*+Tn!@;!a z<1V^VffcSW?G0l&dA_X`V9jgX~#0P@2~d7z3f4mmAw`-2b17n z_C#;T(y((lY_ql{PUut<^-g}8qr+*qWFD(hu`!u%s4cvSpR?n4(V8lF5 BJBb*1>4gaO=;GR7QlSkI#biw-{_XPvr6AD z6L3OYAd`r$y3f!79LDZmUp16#`9GCRbkwNf&eE3XF;*>U3P5m%Wz<>e2w z^O%1t$=;=r#o6RVU~ZL``W~i}83u#L@OFE%YWzr!hgf~6z)w{Wjn)aZ1pee)|cqG zYgq1;g8${4J+fBqd`=cGX3zHCS!?dZ{!`G{RBURfiP{LAOV_K#yvjO)LAB z=RK=xS7>$~ZU(Q<^Q*XO#La_f58213Cdab?L8cWwRBel~sUe14-md#tjh$v(C7;~0 zcXqa%Z#z}@T-oE8Wf(WD)H=1>oHNsH1eSlt>{c^Hr}!CAIT|jF3>F85&VMm5G&Q`v zJlGwxgl6X4jO;}4XrxWj(F;9LO9|2hPcBI?ZS#-7n$K~$r(6b`@dWGEfktuiH)?5Z z&%Ug!h}4sfl@cVg(c$sw!B&PiGG=ZEH0z>wW%`W>SN0IR8wxi-r|v$m;1HavH=1gs z9AEX&z7w5x_&k?KoFxuYMEWs7!g?1;dXL37yQPvNDedu~gWpbX!&yr0Bl-#BsUTJH zRAWBSTl+vax9aH;S(_*cm(gw>+mn6;Wt^K&A{#Pe-}HpwNxi0Wbc^;uFb}|l3zI4}0dT9b<8KA^6pxaaLa+5RAfJz8q9)rUK|83`;jCc7gZDO*?R#ze!7y9rseb#O zTeyH*t2~GKW1d6nP(?7_)OMsor6AeN{nu~SrgtLFWA%EB>+mJa9TC|a25#Ur*s9lS z1|yRI3;hRS$#!o^ZIP1YDbAz*`LpaUoB{Sn^4OJ;oO9CoYqm6Ry)2S?6nmw?FX1QI z@b4bn8LSQL%!$f78$)j=y0`Ix&COumt;IzU6~zK0dr@9!j*83%Wj17bsc2JB2xY3_ zg}DTU!WQR924L=jygt^izS9uiR1En+(c<8Vd!lCVIz>B z=a%&v3!X%jBFVhd(B^Z&^LwGtI8(|y)0tcp!rw5SJCcDhPBpW&ZYfD0qZXOqdJrxz zx8A+tPlC{h?_^Ra{*AcyHp|Nl zqgl%>@c{b5d; z5XT+4^n(q>S@L@%53mL?oSbhqC~um#I~9P)+$pHFg}nx4S0fTs1eW}t%B6>;G$tf< z4Z|{94v!`Kbm_F(Qm@B(9-j3Ui^RTovOTb-cCZm|)VEVHQ;xuau5Gn@cO;hTDypKe z3T(ns{aR<(yqh-yq%fM?o2D4mAFbcsbJ&D*bUh$sLRbcJlre+G>-)qz;M%STR%kg7 z95zooL8cW<3*aiH1eG8LvRK6K_vgWtf^16FG@8>vWW~ucx zdkt*svj-A}dTcg(bZfM0wqbR%m&_;W6vOfyk?aX!(oK&v;;+PKl8~1TqWgsx z%X_2jHsQ6RT$SQx`Nt|?1y+S~L>m0e;ep0bOy~&-IN0UsNeqG=P3G>Xh9m&^d`c>L z)+B|DhVwC10yUdUm5>6PQE<)`>Sd~njyReH?ao1v3^@fOlA04c4A)p~5Bq=9iIKpuc&+EJ~ihnU8@(iTCiQ z6w_4le}!}x>#8SGB}U8sdWCgFWq43aU=pszfh*em{a2o!fjLZ}VC|-?TWKj?perfK zjdjHktq}2S3c;Kz=;pF7%LS4Rp{ZCggqw5bY{WTLRZOl{Bu^dz*c43E3HuzriN=Xb zG8={n6F1DhTYL+4W4t7N6ol5Lp?*3lh(_qyF+q5qNZ}Q|;g;`Rvk=I7#{*DDuPbBW z2V*M~$+Gkt*4we*_O#_WI3Fn1)IbNRccYsH6V%0(0*AMh$`A@Jc`#k8I_ju&`M8e) z{C1Hf(NO?_onpit7E~Vb6E6`7hX6Ahx4atKPKcN$(=EDFzRC6%*9^~A%Onb>El=}ZGfnrswk=<*NQ|S*c4qj>Q`W@< zRq#M}`n8Z(WOp5$sWe{a2wuQyDhr04@M_s~;=dnCR?` zEYb3?<8t5ROG8u@v>{y5<1LJJ3(FR(+|UVyr7CKZ4`?fyec2eJsScaDHK|k?qY8mP zWW#Qcy{m4>^@8n^LW=1hSx1jS>yN@fO&}~Sv};t%w%IRN^xY3wxI*2o5KSQn+nY4!sVOoU+_U)+r^MNyyJ!AI{4 zWg>iM{KY>Xv_0*Xcm}_p`Q_8P&zZi=nXBw=jNks0$_#sDuTlrRCc<1nVGb)x)Kk*N z7g?~saFYe)FJkUV`pAth)OMq}f5H8K=&L6bCH?_tb^W7rYWH=j zN1{tG;mfq1BhRUPlaS37ew7_-S1UDK@WzT!RpQd)SXjgr+1ij23!#td04iWp#`=Wz-oGN8i8UvXe+s^EMlrjZC$zxRjsXj0lVg_jSV`#ZOu-~oQ3{j7LPWf#6f7Fa!z++EFyjga?l6^Rp<~Ys!04+ zpgFn(bwcpRZ_+Jw?=X;Y6R*5&G;W74NP<8tI;_sN1%kl!hADCnpzWrrcc?cO1?KC6 zx{cw&0QyvO+Ya<-xbwS&1e9DBfp+Id5O$1;JSE>#U*=3xe51REiL`0u00i*<MSo}v1l?u`!GhoYE&^66? z)rp(yPUi2>aeC(~H7wAOaXJU=rUd^Na0k|NDHy2hCV8~OqWZT!*lTu}%8tPFB4;!< z;q7Bf%_!F?H_H}@eP!_eXZH^>2tPmOaTIx&2tNlhBwPSWcP%S#He&*77EZtDQdLixEi|CiL#|vZ83J1cj7b{HTkg zD>~s^PMu?Fh0o227YQJB^NT+pyJLSAK=IeIZKU*)msDMz>+Je;Ls(l%Iyf?SWeRIByfOaAjQpNnO%>gV59`H!Z=B!i}g$P)EWo>H+=iy2*IBED(;jBze}A9m`u~yp`obtOk3?PI z?pGUEuujHQC3Pg`S1802A?@17`|?W+@GQS8`?lwXV8;yAHU%D&I{p^(Xt%jP)rr$} z{G)zExT8MQBRn;9)4^` zKAkSR^YIwyC7M4vyqHY{1?wNc${{$zC$Wq+&3Rmg>ltsraEy9kokFCZo#Wzf6=8>V zm_0+VCPM|Do=&PyE>?eZ&SX_ABhr4GiU&cOJ58P%>76dLp(Hw_TMsstiMKb&cxYH| z{VeRgFAw^oy%n`YH|;1Cs7~DKgdOi|rqRh8HIT5q{$00Y*WL(z8R@F30w2RveebX_ zx~brY&1Ow!qwvNNZ1S>~Mv*#enQl%U0B#k0%lF6dM~vv<5W};`q!8SQ3SCTh5!xbWeE|C6J`{)>g&72i3eFY-WQ?tGqDj- zei2>k4Ine=(w=7PmGM>?=)At4hI4aiy(!U}G^|mnE+p7w)6B{wtlXs7rWj!t5oA-k z$qrf?%!E*pgrcZTv`)M}>*(Wyy#F3n<$SV6sFEEe+R%@;aV`dw!ckqRuqh*NZVaE` z%h7b2A_-!_2G_@2Z0rR(Mi;=Khz(m-#-GPDaumNUMaE9$F-e=H_I97CYBDiH-@ExN zuW@x{;TvAnvvN&dhxj=sx6s%f!K|rNVo5wR2oZq;4mtgD#Vqe!!m}|@BKz;nGE}WhgQim zqCgDcfu%zzpC<5Wf58YZ8T7WZ*$Bentf5UNEDoLwE-fA>D}BoDfmO|K5q{8o|qL zm1?5j@Y1|-s(RTjdQ|k*{2kVkaAweOg8CLk9k6 zUGB+cz5@0(} z?u++fe!~u_n!}<6=7*9T@jUnsdyH2|Mk3nDS{|vg`u(v;Y?Qm-1!)GhNMf?O$CTb} z=RB_;_O2XQMu5XHA+L;*$rcw|lCK(w3uY{41t2gwMs~MHdl9SS&n^kn*@%c3QVrchvoVH(nXls~61PFDE?S3rgsvE?nZA;}C$%ZB7FCJ=JPR=JJ>-~8Mf zo!9y1_sS>EyB!5<;F+f?aW(#)tX9a?bP!ga`b?8 zWP6x9qE7@5-ldx$gb5^o;Mt6g z-e~TSg?!a;bm_-afK|J4GlflqXusd|HsAy1rDIKqlEX8 zk&#*&irYV%*fYX)b6B|8#T>)ug4UeYLNNKf(%f1hB$1brF(tmr66v^3b`lI@(fH-% zMtY*_d+ImF7Cf=FP~OU`{y%=eDYWYwKLPWz0Kgw!vs|sg?HRIa=}X3xK-?}ZZOta7 zDXU4rshgOM3v>4V@|aS;cjUA-T#XgWt(+f;d@a4|+h3S+?Q*Tmab{OEQMbgo6n#&; zqLjL-I3~S2FX^rG612itV(~NpG{N537f0qb5RYH(c#-c+E#(9HRUzQ8N<|QvYRpe8 z=M9GPX$If89g>$zv(_^EmP1cipnxFtGnTo-9EYUY zo^5~R89y;ir25IBJBfWR-U1JipkBc{DibE}+Bq20=w|(eJO|nv8JH}^7s0k&l-$JT z$k6T1p}h_LsTo7>-73F@N;1d1PP_^GI_&Z929CJJgvi0lgYvUGnGo~$<7xLq)+IoX zeNa~>=%?wsTd_d=edYd_*^7FJjvE`Ihw7-|j`MhD79bpcEHRtinCCW3S*1Va3j6lx zt$CM?64-4`EK!kq3?ZOv4?E;HNm$%+rc!&#*vs9#zAGmMFEr1`V`D0XEY-89{G3`t z#s`$v`iAOe zH$=cH#9)9!j94w5yTzyM7CGbu=|SeW$D} z4MXtiyACu<>pH#H;g#HtKn;Cw@5R-+&9eYq7D2ESg;GFg`yIw0pC}GBdBEqVZ@vyLiI$avf${c)1ZNHArdi4#-x%Ox>-L zL-5@5iRB|4U0}m5TeAJ$V}!-58@d0u5rfkl{&vUGn;^AG;jqgYgj z+$TuWx$iblYGn9KUmoedA-G6gb7h5;+mSQ?4?oxTG=rOi;^+oN=QLN3PjYS6fs3M<)^Pw z?XaaxtnBov?o04aH+nntn#MGvBpK;fg@7R-Y;wH!1l_&c`$MH@AF-iKRp$G6a>bh` z%FeCeH)f%(%wGtFkY3Q$PXySl*8JXb(gqLW1?E%skPUpy7FpG@IT5WXh#ztr%v0X1 zyTHks`%Q)648;H|2RI=t;p>*VP4Bh-!PXp7?ibm28qM21Ic@GE_Zu24ANy8x8rRf8 z$bEEy5pl>$$RJ{2la8-|eZs|HiBUx1ADG4)C;QTNiqUQfSglxbji!h#^^!u#91qS6 zlSC9lXi7v}PIs^Iq*xJ-nQ8}@amwb%l4AH984Vg6s^JkkOEH3miK-t_xBqS6>&3BY zx2igqT_d7`$#b^W3fNnCnGWL9r9eHF*4s{MQ&84*b#Yik$bFt3y)=vVGCq34?n93$)WXI)-b+0_lf(sE$j$khVviC%iqE}IXT;FTlwN1Mknefc@-w?h- zV6tRX+t0Bj5^%JEzIAeviF^t25`2XMzpdAwc+`? z1_d31GOR#sDhgyL#Z2Ti>>p2KH!!14)no!+Vn8KB$FUSnM#2LO*>KL1Z0+!(%1tw@ zO*jMT!bozU;1@$0V)=BNu)>9EgkSP_3^Dyr5oru9%;C0gp1I$e7Tu&$1?McwbSc5h zf2@D|nW`^lL$|fz=KYDJkiM>Z1=qHu&&OZZN%YCf@6liEn9y3=%*aSJ$RzF-IyGsQ zL9$P>#roc{>|v8oaaM5oO}qSgecepSo}ASv6z87@ioVWIdQ4>rDGRi^6Mj#LTaLojHOB- zD9cP#V~CwVjFdqf|4@S)yX!)0159SjTV%|R$0!ObqLQ1Fe!x3dC2`|=5l)Bb!q_m} z9k=Lu4hO{(;TftHmbY*JYMp^wTj<{I!srqKB=d4!(}x@~!fF5fwUDr8!G%Zi#V`rW zo9(H!Y5cL;FvvRVixt5mJ~QjFjg_x=kH8B3FoI zG008Zw9VjQ)`me5f;he>e^Zhq6FKhEJ0kxgOv&A zRbi2U6*-N9L9tXO9J^qShhz?VYN`_gOP+0SWs>w@{OCH;iyy1P_vw7hS#QMA>pvnI z%$&=5#3X*LQ7HlW#hN!)ZM~+f@1kYS6c4Mc!AQvekY2O-oM&R0hY^JdgCOm{z%xpo z(}Pngt}wzaxYLri-+3Cdz}s>Fl=5{Xmm6A_Q_IV^ZI&pKBsS1;x={!YP6r4En=|s` zS>_Au;)m86LW|{0_KhIn@S6*}BIkDj*LETduR%^&n^+i7b2)TQw+uz|TqXRDva4{& zJafhjT1$Za)x57|r>aoDCt$?1iw}Y%0iZQ&Y-6|;SGN)6^c*frVNA;qML@E3Z^BIU zdqeVt>-hW9#ZOB4m*xCYF_WY2k`HeKpjZOK@sm4Hdfz}26|+ekYgLPa$z6GAW{Lr9 z_CAM-Qp56HCQx>ibt8wF5XxEVD2cIIgKLkNEK(wUo>5=AK1cwpUi%VEZ2o4R2tVXb z5f4=uHnPPLaUlbreXle|{V)0{HX_b=Yj+xR_K<(epX2&9A>`=bDU{%)rN%F+g{CI_ zQ?vEf{A8*2wAT{uyk2bCv-M&y!tKvT8m41=`mrsp01TAY$yL7HTC*2Vk0~uBgO+DO zdOrsJ;KRHIF#4CB^>HU5T~bB-!m&`|B&w^G*M##G*N*p>=-RJHUb+;0oQHBTjNZ*d ztet!j!&K4*VzmXwsbzoyMVrzbRu4hD5PT&ig^on&ZW|Y4&%HX?UVbk|jX<4gOR9B| zHvvtdk+jwdOAF2+y^`X&bJu&D%d@{6JzvU?h@)kqr9REx_Fn=m7tbdhRx#eorzp?x zY(|s_3_MNZx9^0n2j=?JNzXUhkDv7P_fi$j`xiMh^0ZtBO^0>de~=&jFKntx_rY&@ zliUwH_tc9w7@eM~(a&zG`WuwbG|>F5|y;s_w5I7|ZufkLANJP>C-!X*)|hsos*bKS|HD(T62 zOU0(H1`$W$|4##V$CbcIioDZSWeZma>=ayU?$QQHxi|#Mu=nwtgt9g%FcD z2Q@Y`Abv0UcRp%t@K@J*;Q`G@86Qwx#hNoUa;43n0S|)Z-AFa-wWUBu<)9exxkUoF ze1$=fhH9J<>(WUbKQu8V%pz(u;FE;8wiHwz)Q?p80drb*0L2~aTsCXdtd zK4Vkx7>xHP8xblmgkwIfD6HwN@HAa_v(UuzJz+k4C}MZL@hY zkt@DQcBn1OHR9OxZ!MN+^=Uw7Rk#h+bid5_yxDlj4~F$}k{AO}|M$($)ma`1hcPD+ zf1)P{WTfV)U@$o=^5`d8RJJE6sBp*nen$M!Og*Kz4G{K$elf0G{BUd(O`3Z{5%2gE zP~oWdZ^iEpo(5gLewAnV6fHY1cv*o~6yd+lpl2l>0v&i9^DE1nqzO1xhYqo`Yn5R? zNawD>?e>8xuNP6i3~b_yX)L@(Z&SP^^Pu-i!<*}^rRx`)x1OwLw>TE;Sx>f6GW*Te z^7X6Dn@`?Ur+wC&X=heM;W$qnlVz7OaH_m(l3{uwLnv2Z)=T&FfqEaTAD6N>OG`!S zo66wA&RG0&JyN!+-CkLq?l|5Si-B$Vv9!{;eA}t?B8QEhWbk(WP>|PCX^JV#t4ERf z)+Q_>L*Ku^i}C6chZ)q|7qF<{L4(2?bpU#2`eJBN4NV{SA*Q zf6GmL4vc_NY?pubpd#dIctBgDm<@^$3*+r22kDe3TO;I=?B7Q$6JDnj)l_mLO;d9d zRNjVX3P01Co)x19oJ1Br5nnbCxBWBDaLmpkf5%%4_R=GHUPXJFR!vDw6CNv?0XQ-y zdXmT|xiak=>J#Oy*iM<;UANHe3>fhgqCJ_D8JU#EnLMq{ldDeZ1TijF9W{T9qQmlh z3aM1`pW!w4=jD=)a^>afyivcjy0AK-cYPPfuJdOvmJJSnNB0>*=}cmQ5h*XMgo)a} z$Y!DX^-7Etx)PL?jH_6l^Ioon>|UuAT%D5ZH_z$u5P7!r`?!4XTK`UI>i#~jum7uY z5iABLU)&hERGjwR@45NO<_?87NS)VG10k&tzj!+TR;8y)yA@63LWen|0U3kVjh%m4 zF~{{_OLLJCJm1&&Pwn1T`}PGK;QGtuYrF-%ny!Cd5yUrPUu!7Cb2%Z2_y^UKH(NCY z3A5%k^GYZzX??mz7pz`)@a+kL^7QyJtb{+VPI-|G?Od ze`o&s&leebm-}AXS3IL#We;JOyU2>`u3KWUe=OUHO-!AK5#CxqkrOv0k`x!>A<@B| zwXjj)S^O$5YbnAgBJ_+_`og*xWXJd8WJs#EN?^OY|uUF-UQgSQ_?yS^qGnmCpL={;WhC&@mN!wW4LUx8)<$yY?9^X%- zH^&YaA5?UYU=v_2ik!3t6fw~l5VbZr!Lgpq4*;nA(sx@oI70KMz)3jz1l2I@Me)J#oMMMdQ=;y`3fR!V~l7t0By8x$rr&$TU0w zp%Z4}$HUv;GwH*EIAJS6@6tZRAx{uOc=95Q6d>5(z}+|1_lxhzLbjYB-U2|_uP&Sz z2;s^7!?#F4?$Xv6tJ>Sqya%k zK`z}hzkF_rEAw)7gNvUv0XO`i$TC=+`jiSJ+@3n&up|Cv%fb1NAm^++*#lcZQE2o=)1yM34;vC`cqD= z&8J~GnoqrAZFjg@GOKrbYt1c0 zMSZ)%fHt#ts;G%MUn@Uq>y=h1TFzBk=3!Kdex#S~2mlGaw1filYzuY!Z(zpMEFYM& z^s25aLZtla744tVUD;uhh>MH!LVdg zX&!Sn*b}00Gu=)x1;L|HS(Ru>9_P#2Z9?iU8IO9`mXrHL*AK#OOcn7Uir}I;bLdh} zLhO%i%;dY4`Aecw%O`Z(-gMvPiMA@uOGzN1D}>G3>x5qtve zxaHq1B#xtKaG;PBlHo!M zbOR1kfm`wdWZ{-b3Li4X7>H4vENbn%=gzc+s~ z(bePMS8?+AtJl2qe+-O%ZSJNy8v@N}@nh47!|cLs+Zt!{7at#95mLt-_xv8OhUBi< z^32;}v3S7<%MSpN;u%jk8xG)jzW67Eu{!W&s9YtTtmpId#b!jDA-uvlEsf7NQeYcc zy=c7f`4r(0j+jO$bgDXpKB6Ow?Y=B-a0aV|IWyB@97^G2SjWYDM8Jdf43B^_he(UY zxI|AbDxDDdjxihrQy-@mmn>DlWY3&=g3gCPYmoHD#Pp(Iu`oiB$L|7~x^xcfSejK`J_?&jxWjIQpC4=Ufs=Ws_Dwv zGF_bkc(F3O4`%FV+IV~$v?K>O$7Z+5UN)PR1H>0hZ}3Hs=!MaV%}*9|a*eg{146fq zS={rbbW*<@pr|o>hEGH6q(n1>g25c~zzRR6ffA~_3qej|1K2d{fS|O@>iMW~i?p3_ zUQdRVa%C<$#`eUAz5#tB9%kP4Nw#R?Gqm)ee0d^m-6j@Ak^J4HKgEndBaDX0r7J`( zfU6W@dk)afiE#HKdb%i3T(u<2VCgf7n$@|FxW`;w0GmyxR6t-!a9(;MLEh%c_xIr9 z#*k#+Xaf=n5*edUW+qn`kfnqwX+_#*%KpJWE5C84exVU2yy+~?9}`~%KR7CkUCLea zrk`~l|6hcWlK}q=BrRa*J2V;rQd|VCwJ8R~>C9~>k zPl{R@zwUX^+hJ7fQsc_h_3Q))I~O9+O4UKpFaFcltSHNPGF`PJEJ3vE;< zH)0K!tS^K`ksL)VWlT&YuPaD!*}YfXiT$&6*e_09kO_JEvF3N3m_u;7mr^#fwf|jJ zm2vBKxF?bMmHq!_lNtUbQb=|CIq2Nis$7#D5IcyilJK%?I&j=TFCi1#27I>2yH>uV zqBn6n0a^p)ua@V0gMtxleE(v?i$DH~5@<}wl%nUJbcv`k@+&|8kH1=x_lM7_J58x; zW(hr&lH{?O8W7R`jtZ5S8lY%y;ow0yJbZZ?BRpxcqtK>IJsRcmk(~|r+vF~;2a%QF z!w8pyy9Dv#v;0Jv=wDM;p(*?5L+>!=RGy{d9Lc`DmcOh3mz5T73=AEIqA}r1-@%dX z9m1$+gk0bW8%n-0aR1oolnQ@&*gFUz=zL7n8kE)%a{N7@Bndcl*Xf{B!()(a*w&!$ zxY<%U2~w@#sX(Q(B#MGT&gVyEH^I??OR8|7ngD6xYELghZWyGr5d3Ku=|UsGciEVm(Aw?P3>K`!taQUJ66&y zVvp#t{G+zuht7VGxZuA^mI<1t6H?|yJ*ja)bpu++4LlANGuOHr71tyn0UmQd@HdeF$i(Zzf*Hv^0AN1r)q~}8+jvnT z>Yni6b3A1HOCBWJt2^kO%^ts}`-n^_$!IVOcPH72 zV;t$9l_W8l0slvPW_$zWS*4FGl0>y7{OWh`cj>zg0Lq_kFn#T z@kx2@Ht!a8E@u7NS?0iT_nYmJse5^1E9fBH%YuRE;Kp$5HuQe; zR!@?PLAvTYv^bfm)1k;rB%_aR5GDg4;pZI!Lt>4YJP8I9w9p5ri-L*Q-Jq>6SCa~A zHO?ta#Ac9E0ac-c83dun-yH}A^=Sl4MJ`71>By&UEE?-E*)-#+U!7FcW$H}iTCie4 zHExjOp7q5eV=Rj^I+TD5O@vbFN)mHcprOH;mhyJi2Zi5xP5Y3m9Bpp zkm5&dHL4~9ThFLVbBJKmH?wOhFQWcQM>J-}n&IG)HO)NzrtcdeKduZYPkxke*Nmu6 zG89aR;LTz)uO9cHW zW5Z4n0Dh_ctw2Z+Evn77CuHJNu2jKRbd2NVpqEM8+7(GkVxN%oq~Wk7Cc`@9*zYg7-3uWy)XM#D?ez$wK_;0hH-`1oX-v>&3x^C)!e_U2uE?) z6tx8bZPoaRvI_1ySPgpYN3LkT;r<4c!+CVRB@_Ug;8oJ2Mtyy1OX33&<5{1>T8j5L z^egNlBH=ZE8Vd5B$9x^#xb2rf>_I+5fJkeSs)aB*zJdPU>*L{b#j~uz4|S*( zva^}ASYQourfrPU-GbGVp9-v1M5!Ui##3$Sb)oYHrAhjEPwR}CskWKRuC2EWsT!0f zp@_=BOOb$dHg1bnPqKMBDvHT0OtI7To@<~J!%^w!8|vRie2FU^%0I(Rll z=!dE2j^Swj5N6<)T#_!EOnz%u)c8g#9H=Vn(ZEW+0_oK989s$eaE- zk-pd=$49f~2~10+x3){Qm~Km7wH@2+s70}4(#eR;sB}yE!XB7bd()r8Oc6LUN6>?n5bn=CkUND(~hEQY2wMvlSG?P4QQJ(INSiM`^)7qossm|Fw zEzOyXK3{1443QL-j4}w%zzjfJ$g$OjsXU#GPfWKFS(7cpeojA$zr>}>nPkNR3kTU{ zMOQ|YN5zvVSGDLdZ`D`2BBxvVDrFNb4yLlzOD$D$G?OMeBXq#^H&}G-)R73&A#k_zaO*sk6s0JyHC5?-s_If z+!~(<*MwqUX!u82^1WouUu7^m)(h;t2T58QR`k>uv2F-=vB+>6@^vs!^8dT`NE&5o|$HH z<{)u<`ey2*m;UzR$_oE>`B%!QeBuV9esdBI$-qMV-iMF8@OM`(rrE4MY4a-Q zEOkgt+{|!lU;t&LA=M&RP9?GEHB~zRr|7G9xM?HUUV}(b;eR^zWwZj%YhW@w{igFGBz`}4npH5GPqqrE*fJmPxRX#NE z>dNE-kapU{RMA-9w9EAhl$<@w!|Z;hl#?1dCpS>qK-5?1)6)+eUJKn*8Z$ z0M@(9WlD-0>t=tk_&SRaibS%d6B7%6$fJ^=q^e(OcFy>7M!-5;=68O(-6vm>B7yMO zibPGKj1AQvxE{}(6-E}FRzD!^neL$6CJod(a5DTiLHdU0R0JO2Mxl{dGY(}8i^gF$LJ5s`X}H|LCLIO z%OIcpGn6Wlr)RBe>464jSZw1oMk+a0O9&uhulK_t72fa^ilEg5LG$b|xmV4fhY+3n3(6dc+VT8%&Nm5uyp6K40DV@Ei&&{cR zVjk-w^PtK7J|-kB({k^$j_w=3r)UT2Ls?qhj=z04@G0B=gw%m)Zz>#6^d8~g-&b+h zz9MU+4PjzTK;^yRXQ&L<4jpd!a9}y~Jl_l{--6~$lSnXQ7WyxK1 zobiNb8Jh~vd0Luz9Ed{djI`}RV-t8MJ=9vr>A^@J$*=R({jSsOFu$Mm0)tB}yEgi;Q4qfm-HsiokL|JA|06HX z-wa|OF#BV{A7&Y0vBj~tQv};WjmHVMHkvC1&d0k)Nwu|ZyxK8mI*-qyTvs;PT#HgN z)$rBRPS&0s{iUtPc(AW%dz|S_RV92>AT-tXH*q0hC!0CwgA+9r%U@7sZH%v&T^xeY z8tl*qA&J06h*vsx<8r{a!}isqpIIt^u& z&B5WB?%2KLvQDy!GP{KLKm{Xk&05$Us9iR#$YgDq03%FR_0z*Ied~kU0dUWwwTJ^);|UKZKEkRxEb}O zB7a8*73bja;lisL9gt6NJ^8NAk}9pUmGkE%lsXD$*~8{`XOIyd7n)p43vhk-fXviy z=)ZoNyB~dCcPSXS%^I$J%}uOQ4X{3AZX$M%MNdi@nqG~vt^`-dpu-18kfNm>5)?yR zz0KhB&HF-sar@b_W>pU)TQguOF;M(a>KvOGw6w0>!XYQUYkvGb_nun6nCd$#L)|<2 zfC`K2!+tVbPb6@$aQXxGLdZLa-UL}#c}kUK#SG^tbl9(2MC8|xB=Bgfn;(xcyJ{V| z$`|W9h}bWrO=ljL0$jj$Na`qsDcr7%IIF!F19dDGMj^~7=hIs<;}~#<@fk$BI$(O`ZH$fDT?=U!O4~BSp`U1RybC z(Yv@?c2ZA9u6CdRE;3;>{sJW^@y%&~y`+F2wlD!GLMDSqQ71tfg?u#ePR|vXXsHld z_g1#&^BjuDYdz&CFLhf)VQ6nRp4Q(?CLt+gVLG#aYK@;gUVKk7C&J#VU^GrL5MmbH zRt3jOSTao{t+U_dzQigHZ21IQ&j~B7U=c|$;I$oInR3~9DrVj_B7}@A%(>nnVUmrJ zV6M)|F9yDv)+f@0d9$Y4H~7^evGE*4i3}Wqc9h zd`QGOQ-LZ4NqSE0tW#x;s2C2^s5flGEk3wl`$=4XPLD6AQ>{Q`ib(kqHiYe@bj8fi z(^>UwNbM=d$|KsGhTOdBBjA(zuJ+~hM~8U+5~7C2SOU6VqgyTrUFJO_#xm9Z;L9`CF&W38F9`N-|rQ581Nj9IZpw`L;w$fRpeI2`u~FSz*cAPiXeDt4^5Ylqx}5+w zK*+ytzqHA&vTY0-c1e|k4E{45$q_e!k!(LKqqP$0Ko2a%v*#Wi4b>fh~5GZj5}rfN}D9H1`wq4NTtP@Cx6t&=KwaBYTvN_ z;1E@o=_S}(?PN7mbWK@unw8pR5*e-M+@FKt-5wvujURR1 z(5gt;D=B!5JlEF%Nm^@cmMYy=N@4lmf%nR(6XR``pu%9e&7+2!%$NB}Rd&Uq@^lMu=k>i%V>CIn(K8*_?dM~XREjC#A z74ICdW*}hk?LvrX#8(yL)R_l%W*5!)OZm^iZ=XOaJXb0T7Ub76b>2GLzXhIYe_;+b zs!eAdmXd7>9$w7$7;X|mV-5Y5DQ&4~#+Q-UD!RNSQS%rN$g!^UIFifDn4 zm0Jnk@jGlK0r?krgKAepKT|iKyl%@kJ8U1lPxzpr>sh5N6z-1huvFvREG0L4c3;`D ze)x22sg|I1-n|?xw=^8hUg1Y`^Zi4QA7%d!JhFzI`qh~IMNs_P*GOT@GZ8Yb|u(m<81;ohDtY#;cSq;X>0OXb=^7q-(LNNti zIE@bxWIVW&w+{5YWmoi-&TJmeY5;F9S5=gWE#A1i`M@c9xBkxkY|}T(uVjIaVcJzK zbYJr~eh}ViQCOext*idyYtT7|3cNlOJiWpF8AreS{Q-?(@NkYx-#^)A@;aTjKNwse z;3DdIXXRq{=UbPt)JI=6e-6J=Fr>=Qw#?ddgb?_Ye%4ViRFI*6FHeV4(zG{zkEmDZ z?vVB0%3#NK{{SF%%cOA1nWJf;%K{`AFi(7XuZEn#&MQvv$;uJF;x~7RD=)>(XO1us zH)TF-k{%~iuxyA26Upn^@o#*d@E0oOHP#C}EHJU>@sIwWn$e}f_2AFy00Qh~A&1F6 z!Y>i^lR=z{N4?o%%*QVu2-d?ppSi%SsJcb3?sODXr2vsy?C}}UhPP!L`Om1qbkX6l zi~&{#Evwpou07pDz$5^4S}}EI@Xh7D!DKaAPPb1CO}u9&S|I*QvQSN=;!2?sFw5+c zFhUsF>gl16Rn6pift#_Ck-e{z{Q7$+hHYHSA6=m3cDRvgUQ#R!RJf%AgOM16H$uO1 z>@mihA|bE|t%!ne!91%b9juUA63z#|EA}V~x?5!4&_V+Icpwk47w&vyqXh zy4@*#1v0hDrY$X``z4TpOn-DH8k+)+Gl@XGPdjv2doJS>@}7W=%zv*Yzco=O73hC|G9yFu^CPkns<3++2S;;@Cpl2lPL)R4rUPaJ)ug=sX4pvb!T!#|jW|l?Y z5zj<+^9OPVCs}9sb8OKluh)F+WBZFV%mIZR>V{_7*B}9WSB`W~0Ag=OJt46kBou4) zlsKC%Ar-#c^3odFp1N}-Tp_V9&OTq;^);PBQ@Ih(!ODTXUX!K}(q1aB_!i-rC~8zH zLCP2~EF5xQIs+3fCQ6U51>x*l1%}8(N=y$OLilEAeU1|3L957AT8%5=`ckFy^756VrKxc<3=&z?pc1%Ct^!hL?fvOG| zmf)v`x-n?sgH^(y&zmuZ15UCm6598fy0A!TG;mosHYKu?NOZd0eV_p1G5!J_sY$Ny z&s2)0Jn>nN zR3KZ18D9KoYOoVa7*m&0QcvHLNuJT)ba3xWo}-xzB>)TYWI@~SnVnqNf4xVkAS}y+ z2)Xe2yPX2VgrNd=NBg-w(Yc8VdgDe!$iuRI!IYqH#G~W5dyP@*$7n;F_NBM`eVlO( z?d>X8Rxg+-t(O8688CHc5@+d_J^JGi6f|Tl1r^@x2EIe$%+{R(D>)ElN!AqTjgieS z=pu2shijXzpw1(Qwk8PgGM+buk0Z+GLNs^d8gF%9y5)~0Za#Cg8sSjC&}x_XhweX; z(J0;s!E|sLh?(p;sUk-5e<`>UL{SXO+6{eoSEf47%BQ074Rr(uKtzCyYO00>_PjC@=M(zw-~ADxIn9iI4n6eOF4t*cg%6sO zsNv47no9zQa8?W1AGt*vP2@Yzy#BjK#qGz6$?HrGWGH!6 zR|DFW&G>eo+Y^cO#;M&l0$Z=cxT_a}i{_MaiC=$fW%FtvElHL^uPA1A#whU!du{l} z-B?ds+-QKS$Jd=3FU@77hR@|`y3%_9;{}{-T#QCHPyC3F@zWsD)L01r1D%@SdNr`x zNLQ97EAvP!+j_K701WEhIO>nb*QqeX;KGg11L!+;vHi~5tmE?KbzhlY7F-Hkr{+bK z^vlqoS_?l{10c@_Gj7T;K-c`qrxfA8{aT4Te*6+Z0RTR8{taVB{-qy!@GL)WdFqvW z$l+=1n3m@>3#72@OnHrc>-{G(6*U@t!4`Q*9_k3)kPLpE+C#|IW|~ztDx&W$6`Lwqm&UNproFmcTG1o= zS+7L6OOsAd+hD|wtTOvpTj&PJyp5OADgqHx>5 z4_eC8AU0Xlz>gcscsnQsPo+2q=NioQ+?U1s)Fi+UrExwPA1d9an1;gcKE1e&@zJa^ zeMUMG@As>@l@9wsyo2d2Q4>ARd#?I&3FiKmD#QL*z(p6oEHCh7y%S&lgY=mDALPlr zdh2>?n*K|GdZRh`)$Mh_{pc3&%NS<897~C0k3cCWyiXD-sOV?Z8^nXF41%r;Z>OBm zw_6gI224-#29puaP&sSN`~!x9ZZne?KfJjg@taDv_U|}XS*ZuKOogwzb8CUhZqBBl z&)#*$SxmNEPhd}7ad;c$Z{@#=Hg#-#Fr>Bw!~dg+W{*oN8{z*o!=tKBj;O)E;{^8$ z;}4E3J|)5^b2ZB|*yB>8`Jq+@Erjf1lpNb~YAIE$T(P5g%(K>}Cl$RUtCfv2Op(R$ zR*&ha=5C|cuT!?ZcSj>-o-v^hcdZQx`^vo-S&Kt-j>R~9Pl|c!Ir~Ig1VLysu@Bv| zVmg8a5TI01m>%poN?-ehVbRDuE-vzX8mt^^-B7$yF6$T*yC?&(2F0Eb8x_Ik8=-iv73YMZD�&3hdf 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

      X-EN*-!E9CY{9<*X%6F{E>nqqF- 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

      #Bb~CIkbqiug1N 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 Ry;jh#DfR&mB23!%mI2ST+I;{3 literal 0 HcmV?d00001 diff --git a/public/font/Twemoji.Mozilla.v0.7.0.ttf b/public/font/Twemoji.Mozilla.v0.7.0.ttf new file mode 100644 index 0000000000000000000000000000000000000000..9f45178e9deffd5c71d15ab8dea6132202063282 GIT binary patch literal 1474284 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 z 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%0DM5I25y4t1!SL4tP*TK>1w=` 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 z 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 literal 0 HcmV?d00001 diff --git a/src/app/components/UseStateProvider.tsx b/src/app/components/UseStateProvider.tsx new file mode 100644 index 000000000..21e5b3cad --- /dev/null +++ b/src/app/components/UseStateProvider.tsx @@ -0,0 +1,9 @@ +import { Dispatch, ReactElement, SetStateAction, useState } from 'react'; + +type UseStateProviderProps = { + initial: T | (() => T); + children: (value: T, setter: Dispatch>) => ReactElement; +}; +export function UseStateProvider({ initial, children }: UseStateProviderProps) { + return children(...useState(initial)); +} diff --git a/src/app/components/editor/Editor.css.ts b/src/app/components/editor/Editor.css.ts new file mode 100644 index 000000000..034ded79a --- /dev/null +++ b/src/app/components/editor/Editor.css.ts @@ -0,0 +1,63 @@ +import { style } from '@vanilla-extract/css'; +import { color, config, DefaultReset, toRem } from 'folds'; + +export const Editor = style([ + DefaultReset, + { + backgroundColor: color.SurfaceVariant.Container, + color: color.SurfaceVariant.OnContainer, + boxShadow: `inset 0 0 0 ${config.borderWidth.B300} ${color.SurfaceVariant.ContainerLine}`, + borderRadius: config.radii.R400, + overflow: 'hidden', + }, +]); + +export const EditorOptions = style([ + DefaultReset, + { + padding: config.space.S200, + }, +]); + +export const EditorTextareaScroll = style({}); + +export const EditorTextarea = style([ + DefaultReset, + { + flexGrow: 1, + height: '100%', + padding: `${toRem(13)} 0`, + selectors: { + [`${EditorTextareaScroll}:first-child &`]: { + paddingLeft: toRem(13), + }, + [`${EditorTextareaScroll}:last-child &`]: { + paddingRight: toRem(13), + }, + }, + }, +]); + +export const EditorPlaceholder = style([ + DefaultReset, + { + position: 'absolute', + zIndex: 1, + opacity: config.opacity.Placeholder, + pointerEvents: 'none', + userSelect: 'none', + + selectors: { + '&:not(:first-child)': { + display: 'none', + }, + }, + }, +]); + +export const EditorToolbar = style([ + DefaultReset, + { + padding: config.space.S100, + }, +]); diff --git a/src/app/components/editor/Editor.preview.tsx b/src/app/components/editor/Editor.preview.tsx new file mode 100644 index 000000000..ad67dc127 --- /dev/null +++ b/src/app/components/editor/Editor.preview.tsx @@ -0,0 +1,82 @@ +import React, { useState } from 'react'; +import FocusTrap from 'focus-trap-react'; +import { + config, + Icon, + IconButton, + Icons, + Line, + Modal, + Overlay, + OverlayBackdrop, + OverlayCenter, +} from 'folds'; + +import { CustomEditor, useEditor } from './Editor'; +import { Toolbar } from './Toolbar'; + +export function EditorPreview() { + const [open, setOpen] = useState(false); + const editor = useEditor(); + const [toolbar, setToolbar] = useState(false); + + return ( + <> + setOpen(!open)}> + + + }> + + setOpen(false), + clickOutsideDeactivates: true, + }} + > + +

      + + + + + + ); +} diff --git a/src/app/components/editor/Editor.tsx b/src/app/components/editor/Editor.tsx new file mode 100644 index 000000000..edf1ac6d8 --- /dev/null +++ b/src/app/components/editor/Editor.tsx @@ -0,0 +1,151 @@ +/* eslint-disable no-param-reassign */ +import React, { + ClipboardEventHandler, + KeyboardEventHandler, + ReactNode, + forwardRef, + useCallback, + useState, +} from 'react'; + +import { Box, Scroll, Text } from 'folds'; +import { Descendant, Editor, createEditor } from 'slate'; +import { + Slate, + Editable, + withReact, + RenderLeafProps, + RenderElementProps, + RenderPlaceholderProps, +} from 'slate-react'; +import { BlockType, RenderElement, RenderLeaf } from './Elements'; +import { CustomElement } from './slate'; +import * as css from './Editor.css'; +import { toggleKeyboardShortcut } from './keyboard'; + +const initialValue: CustomElement[] = [ + { + type: BlockType.Paragraph, + children: [{ text: '' }], + }, +]; + +const withInline = (editor: Editor): Editor => { + const { isInline } = editor; + + editor.isInline = (element) => + [BlockType.Mention, BlockType.Emoticon, BlockType.Link].includes(element.type) || + isInline(element); + + return editor; +}; + +const withVoid = (editor: Editor): Editor => { + const { isVoid } = editor; + + editor.isVoid = (element) => + [BlockType.Mention, BlockType.Emoticon].includes(element.type) || isVoid(element); + + return editor; +}; + +export const useEditor = (): Editor => { + const [editor] = useState(withInline(withVoid(withReact(createEditor())))); + return editor; +}; + +export type EditorChangeHandler = ((value: Descendant[]) => void) | undefined; +type CustomEditorProps = { + top?: ReactNode; + bottom?: ReactNode; + before?: ReactNode; + after?: ReactNode; + maxHeight?: string; + editor: Editor; + placeholder?: string; + onKeyDown?: KeyboardEventHandler; + onChange?: EditorChangeHandler; + onPaste?: ClipboardEventHandler; +}; +export const CustomEditor = forwardRef( + ( + { + top, + bottom, + before, + after, + maxHeight = '50vh', + editor, + placeholder, + onKeyDown, + onChange, + onPaste, + }, + ref + ) => { + const renderElement = useCallback( + (props: RenderElementProps) => , + [] + ); + + const renderLeaf = useCallback((props: RenderLeafProps) => , []); + + const handleKeydown: KeyboardEventHandler = useCallback( + (evt) => { + onKeyDown?.(evt); + toggleKeyboardShortcut(editor, evt); + }, + [editor, onKeyDown] + ); + + const renderPlaceholder = useCallback(({ attributes, children }: RenderPlaceholderProps) => { + // drop style attribute as we use our custom placeholder css. + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { style, ...props } = attributes; + return ( + + {children} + + ); + }, []); + + return ( +
      + + {top} + + {before && ( + + {before} + + )} + + + + {after && ( + + {after} + + )} + + {bottom} + +
      + ); + } +); diff --git a/src/app/components/editor/Elements.css.ts b/src/app/components/editor/Elements.css.ts new file mode 100644 index 000000000..99d037dd2 --- /dev/null +++ b/src/app/components/editor/Elements.css.ts @@ -0,0 +1,142 @@ +import { style } from '@vanilla-extract/css'; +import { recipe } from '@vanilla-extract/recipes'; +import { color, config, DefaultReset, toRem } from 'folds'; + +const MarginBottom = style({ + marginBottom: config.space.S200, + selectors: { + '&:last-child': { + marginBottom: 0, + }, + }, +}); + +export const Paragraph = style([MarginBottom]); + +export const Heading = style([MarginBottom]); + +export const BlockQuote = style([ + DefaultReset, + MarginBottom, + { + paddingLeft: config.space.S200, + borderLeft: `${config.borderWidth.B700} solid ${color.SurfaceVariant.ContainerLine}`, + fontStyle: 'italic', + }, +]); + +const BaseCode = style({ + fontFamily: 'monospace', + color: color.Warning.OnContainer, + background: color.Warning.Container, + border: `${config.borderWidth.B300} solid ${color.Warning.ContainerLine}`, + borderRadius: config.radii.R300, +}); + +export const Code = style([ + DefaultReset, + BaseCode, + { + padding: `0 ${config.space.S100}`, + }, +]); +export const Spoiler = style([ + DefaultReset, + { + padding: `0 ${config.space.S100}`, + backgroundColor: color.SurfaceVariant.ContainerActive, + borderRadius: config.radii.R300, + }, +]); + +export const CodeBlock = style([DefaultReset, BaseCode, MarginBottom]); +export const CodeBlockInternal = style({ + padding: `${config.space.S200} ${config.space.S200} 0`, +}); + +export const List = style([ + DefaultReset, + MarginBottom, + { + padding: `0 ${config.space.S100}`, + paddingLeft: config.space.S600, + }, +]); + +export const InlineChromiumBugfix = style({ + fontSize: 0, + lineHeight: 0, +}); + +export const Mention = recipe({ + base: [ + DefaultReset, + { + backgroundColor: color.Secondary.Container, + color: color.Secondary.OnContainer, + boxShadow: `0 0 0 ${config.borderWidth.B300} ${color.Secondary.ContainerLine}`, + padding: `0 ${toRem(2)}`, + borderRadius: config.radii.R300, + fontWeight: config.fontWeight.W500, + }, + ], + variants: { + highlight: { + true: { + backgroundColor: color.Primary.Container, + color: color.Primary.OnContainer, + boxShadow: `0 0 0 ${config.borderWidth.B300} ${color.Primary.ContainerLine}`, + }, + }, + focus: { + true: { + boxShadow: `0 0 0 ${config.borderWidth.B300} ${color.SurfaceVariant.OnContainer}`, + }, + }, + }, +}); + +export const EmoticonBase = style([ + DefaultReset, + { + display: 'inline-block', + padding: '0.05rem', + height: '1em', + verticalAlign: 'middle', + }, +]); + +export const Emoticon = recipe({ + base: [ + DefaultReset, + { + display: 'inline-flex', + justifyContent: 'center', + alignItems: 'center', + + height: '1em', + minWidth: '1em', + fontSize: '1.47em', + lineHeight: '1em', + verticalAlign: 'middle', + position: 'relative', + top: '-0.25em', + borderRadius: config.radii.R300, + }, + ], + variants: { + focus: { + true: { + boxShadow: `0 0 0 ${config.borderWidth.B300} ${color.SurfaceVariant.OnContainer}`, + }, + }, + }, +}); + +export const EmoticonImg = style([ + DefaultReset, + { + height: '1em', + cursor: 'default', + }, +]); diff --git a/src/app/components/editor/Elements.tsx b/src/app/components/editor/Elements.tsx new file mode 100644 index 000000000..59893e539 --- /dev/null +++ b/src/app/components/editor/Elements.tsx @@ -0,0 +1,254 @@ +import { Scroll, Text } from 'folds'; +import React from 'react'; +import { RenderElementProps, RenderLeafProps, useFocused, useSelected } from 'slate-react'; + +import * as css from './Elements.css'; +import { EmoticonElement, LinkElement, MentionElement } from './slate'; +import { useMatrixClient } from '../../hooks/useMatrixClient'; + +export enum MarkType { + Bold = 'bold', + Italic = 'italic', + Underline = 'underline', + StrikeThrough = 'strikeThrough', + Code = 'code', + Spoiler = 'spoiler', +} + +export enum BlockType { + Paragraph = 'paragraph', + Heading = 'heading', + CodeLine = 'code-line', + CodeBlock = 'code-block', + QuoteLine = 'quote-line', + BlockQuote = 'block-quote', + ListItem = 'list-item', + OrderedList = 'ordered-list', + UnorderedList = 'unordered-list', + Mention = 'mention', + Emoticon = 'emoticon', + Link = 'link', +} + +// Put this at the start and end of an inline component to work around this Chromium bug: +// https://bugs.chromium.org/p/chromium/issues/detail?id=1249405 +function InlineChromiumBugfix() { + return ( + + {String.fromCodePoint(160) /* Non-breaking space */} + + ); +} + +function RenderMentionElement({ + attributes, + element, + children, +}: { element: MentionElement } & RenderElementProps) { + const selected = useSelected(); + const focused = useFocused(); + + return ( + + {element.name} + {children} + + ); +} + +function RenderEmoticonElement({ + attributes, + element, + children, +}: { element: EmoticonElement } & RenderElementProps) { + const mx = useMatrixClient(); + const selected = useSelected(); + const focused = useFocused(); + + return ( + + + {element.key.startsWith('mxc://') ? ( + {element.shortcode} + ) : ( + element.key + )} + {children} + + + ); +} + +function RenderLinkElement({ + attributes, + element, + children, +}: { element: LinkElement } & RenderElementProps) { + return ( +
      + + {children} + + ); +} + +export function RenderElement({ attributes, element, children }: RenderElementProps) { + switch (element.type) { + case BlockType.Paragraph: + return ( + + {children} + + ); + case BlockType.Heading: + if (element.level === 1) + return ( + + {children} + + ); + if (element.level === 2) + return ( + + {children} + + ); + if (element.level === 3) + return ( + + {children} + + ); + return ( + + {children} + + ); + case BlockType.CodeLine: + return
      {children}
      ; + case BlockType.CodeBlock: + return ( + + +
      {children}
      +
      +
      + ); + case BlockType.QuoteLine: + return
      {children}
      ; + case BlockType.BlockQuote: + return ( + + {children} + + ); + case BlockType.ListItem: + return ( + + {children} + + ); + case BlockType.OrderedList: + return ( +
        + {children} +
      + ); + case BlockType.UnorderedList: + return ( +
        + {children} +
      + ); + case BlockType.Mention: + return ( + + {children} + + ); + case BlockType.Emoticon: + return ( + + {children} + + ); + case BlockType.Link: + return ( + + {children} + + ); + default: + return ( + + {children} + + ); + } +} + +export function RenderLeaf({ attributes, leaf, children }: RenderLeafProps) { + let child = children; + if (leaf.bold) + child = ( + + + {child} + + ); + if (leaf.italic) + child = ( + + + {child} + + ); + if (leaf.underline) + child = ( + + + {child} + + ); + if (leaf.strikeThrough) + child = ( + + + {child} + + ); + if (leaf.code) + child = ( + + + {child} + + ); + if (leaf.spoiler) + child = ( + + + {child} + + ); + + if (child !== children) return child; + + return {child}; +} diff --git a/src/app/components/editor/Toolbar.tsx b/src/app/components/editor/Toolbar.tsx new file mode 100644 index 000000000..a84fca229 --- /dev/null +++ b/src/app/components/editor/Toolbar.tsx @@ -0,0 +1,247 @@ +import FocusTrap from 'focus-trap-react'; +import { + Badge, + Box, + config, + Icon, + IconButton, + Icons, + IconSrc, + Line, + Menu, + PopOut, + Text, + Tooltip, + TooltipProvider, + toRem, +} from 'folds'; +import React, { ReactNode, useState } from 'react'; +import { ReactEditor, useSlate } from 'slate-react'; +import { isBlockActive, isMarkActive, toggleBlock, toggleMark } from './common'; +import * as css from './Editor.css'; +import { BlockType, MarkType } from './Elements'; +import { HeadingLevel } from './slate'; +import { isMacOS } from '../../utils/user-agent'; +import { KeySymbol } from '../../utils/key-symbol'; + +function BtnTooltip({ text, shortCode }: { text: string; shortCode?: string }) { + return ( + + + {text} + {shortCode && ( + + + {shortCode} + + + )} + + + ); +} + +type MarkButtonProps = { format: MarkType; icon: IconSrc; tooltip: ReactNode }; +export function MarkButton({ format, icon, tooltip }: MarkButtonProps) { + const editor = useSlate(); + + const handleClick = () => { + toggleMark(editor, format); + ReactEditor.focus(editor); + }; + + return ( + + {(triggerRef) => ( + + + + )} + + ); +} + +type BlockButtonProps = { + format: BlockType; + icon: IconSrc; + tooltip: ReactNode; +}; +export function BlockButton({ format, icon, tooltip }: BlockButtonProps) { + const editor = useSlate(); + + const handleClick = () => { + toggleBlock(editor, format, { level: 1 }); + ReactEditor.focus(editor); + }; + + return ( + + {(triggerRef) => ( + + + + )} + + ); +} + +export function HeadingBlockButton() { + const editor = useSlate(); + const [level, setLevel] = useState(1); + const [open, setOpen] = useState(false); + const isActive = isBlockActive(editor, BlockType.Heading); + + const handleMenuSelect = (selectedLevel: HeadingLevel) => { + setOpen(false); + setLevel(selectedLevel); + toggleBlock(editor, BlockType.Heading, { level: selectedLevel }); + ReactEditor.focus(editor); + }; + + return ( + setOpen(false), + clickOutsideDeactivates: true, + isKeyForward: (evt: KeyboardEvent) => + evt.key === 'ArrowDown' || evt.key === 'ArrowRight', + isKeyBackward: (evt: KeyboardEvent) => evt.key === 'ArrowUp' || evt.key === 'ArrowLeft', + }} + > + + + handleMenuSelect(1)} size="300" radii="300"> + + + handleMenuSelect(2)} size="300" radii="300"> + + + handleMenuSelect(3)} size="300" radii="300"> + + + + + + } + > + {(ref) => ( + (isActive ? toggleBlock(editor, BlockType.Heading) : setOpen(!open))} + aria-pressed={isActive} + size="300" + radii="300" + > + + + + )} + + ); +} + +export function Toolbar() { + const editor = useSlate(); + const allowInline = !isBlockActive(editor, BlockType.CodeBlock); + const modKey = isMacOS() ? KeySymbol.Command : 'Ctrl'; + + return ( + + + + + } + /> + + } + /> + + } + /> + + } + /> + + {allowInline && ( + <> + + + } + /> + } + /> + } + /> + + } + /> + } + /> + } + /> + + + )} + + ); +} diff --git a/src/app/components/editor/autocomplete/AutocompleteMenu.css.tsx b/src/app/components/editor/autocomplete/AutocompleteMenu.css.tsx new file mode 100644 index 000000000..98f653edd --- /dev/null +++ b/src/app/components/editor/autocomplete/AutocompleteMenu.css.tsx @@ -0,0 +1,35 @@ +import { style } from '@vanilla-extract/css'; +import { DefaultReset, config } from 'folds'; + +export const AutocompleteMenuBase = style([ + DefaultReset, + { + position: 'relative', + }, +]); + +export const AutocompleteMenuContainer = style([ + DefaultReset, + { + position: 'absolute', + bottom: config.space.S200, + left: 0, + right: 0, + zIndex: config.zIndex.Max, + }, +]); + +export const AutocompleteMenu = style([ + DefaultReset, + { + maxHeight: '30vh', + height: '100%', + display: 'flex', + flexDirection: 'column', + }, +]); + +export const AutocompleteMenuHeader = style([ + DefaultReset, + { padding: `0 ${config.space.S300}`, flexShrink: 0 }, +]); diff --git a/src/app/components/editor/autocomplete/AutocompleteMenu.tsx b/src/app/components/editor/autocomplete/AutocompleteMenu.tsx new file mode 100644 index 000000000..d89cda094 --- /dev/null +++ b/src/app/components/editor/autocomplete/AutocompleteMenu.tsx @@ -0,0 +1,40 @@ +import React, { ReactNode } from 'react'; +import FocusTrap from 'focus-trap-react'; +import isHotkey from 'is-hotkey'; +import { Header, Menu, Scroll, config } from 'folds'; + +import * as css from './AutocompleteMenu.css'; +import { preventScrollWithArrowKey } from '../../../utils/keyboard'; + +type AutocompleteMenuProps = { + requestClose: () => void; + headerContent: ReactNode; + children: ReactNode; +}; +export function AutocompleteMenu({ headerContent, requestClose, children }: AutocompleteMenuProps) { + return ( +
      +
      + requestClose(), + clickOutsideDeactivates: true, + allowOutsideClick: true, + isKeyForward: (evt: KeyboardEvent) => isHotkey('arrowdown', evt), + isKeyBackward: (evt: KeyboardEvent) => isHotkey('arrowup', evt), + }} + > + +
      + {headerContent} +
      + +
      {children}
      +
      +
      +
      +
      +
      + ); +} diff --git a/src/app/components/editor/autocomplete/EmoticonAutocomplete.tsx b/src/app/components/editor/autocomplete/EmoticonAutocomplete.tsx new file mode 100644 index 000000000..e5af3fa10 --- /dev/null +++ b/src/app/components/editor/autocomplete/EmoticonAutocomplete.tsx @@ -0,0 +1,129 @@ +import React, { KeyboardEvent as ReactKeyboardEvent, useEffect, useMemo } from 'react'; +import { Editor } from 'slate'; +import { Box, MenuItem, Text, toRem } from 'folds'; +import { Room } from 'matrix-js-sdk'; + +import { AutocompleteQuery } from './autocompleteQuery'; +import { AutocompleteMenu } from './AutocompleteMenu'; +import { useMatrixClient } from '../../../hooks/useMatrixClient'; +import { + SearchItemStrGetter, + UseAsyncSearchOptions, + useAsyncSearch, +} from '../../../hooks/useAsyncSearch'; +import { onTabPress } from '../../../utils/keyboard'; +import { createEmoticonElement, moveCursor, replaceWithElement } from '../common'; +import { useRecentEmoji } from '../../../hooks/useRecentEmoji'; +import { useRelevantImagePacks } from '../../../hooks/useImagePacks'; +import { IEmoji, emojis } from '../../../plugins/emoji'; +import { ExtendedPackImage, PackUsage } from '../../../plugins/custom-emoji'; +import { useKeyDown } from '../../../hooks/useKeyDown'; + +type EmoticonCompleteHandler = (key: string, shortcode: string) => void; + +type EmoticonSearchItem = ExtendedPackImage | IEmoji; + +type EmoticonAutocompleteProps = { + imagePackRooms: Room[]; + editor: Editor; + query: AutocompleteQuery; + requestClose: () => void; +}; + +const SEARCH_OPTIONS: UseAsyncSearchOptions = { + limit: 20, + matchOptions: { + contain: true, + }, +}; + +const getEmoticonStr: SearchItemStrGetter = (emoticon) => [ + `:${emoticon.shortcode}:`, +]; + +export function EmoticonAutocomplete({ + imagePackRooms, + editor, + query, + requestClose, +}: EmoticonAutocompleteProps) { + const mx = useMatrixClient(); + + const imagePacks = useRelevantImagePacks(mx, PackUsage.Emoticon, imagePackRooms); + const recentEmoji = useRecentEmoji(mx, 20); + + const searchList = useMemo(() => { + const list: Array = []; + return list.concat( + imagePacks.flatMap((pack) => pack.getImagesFor(PackUsage.Emoticon)), + emojis + ); + }, [imagePacks]); + + const [result, search] = useAsyncSearch(searchList, getEmoticonStr, SEARCH_OPTIONS); + const autoCompleteEmoticon = result ? result.items : recentEmoji; + + useEffect(() => { + search(query.text); + }, [query.text, search]); + + const handleAutocomplete: EmoticonCompleteHandler = (key, shortcode) => { + const emoticonEl = createEmoticonElement(key, shortcode); + replaceWithElement(editor, query.range, emoticonEl); + moveCursor(editor, true); + requestClose(); + }; + + useKeyDown(window, (evt: KeyboardEvent) => { + onTabPress(evt, () => { + if (autoCompleteEmoticon.length === 0) return; + const emoticon = autoCompleteEmoticon[0]; + const key = 'url' in emoticon ? emoticon.url : emoticon.unicode; + handleAutocomplete(key, emoticon.shortcode); + }); + }); + + return autoCompleteEmoticon.length === 0 ? null : ( + Emojis} requestClose={requestClose}> + {autoCompleteEmoticon.map((emoticon) => { + const isCustomEmoji = 'url' in emoticon; + const key = isCustomEmoji ? emoticon.url : emoticon.unicode; + return ( + ) => + onTabPress(evt, () => handleAutocomplete(key, emoticon.shortcode)) + } + onClick={() => handleAutocomplete(key, emoticon.shortcode)} + before={ + isCustomEmoji ? ( + + ) : ( + + {key} + + ) + } + > + + :{emoticon.shortcode}: + + + ); + })} + + ); +} diff --git a/src/app/components/editor/autocomplete/RoomMentionAutocomplete.tsx b/src/app/components/editor/autocomplete/RoomMentionAutocomplete.tsx new file mode 100644 index 000000000..2edfb8bc4 --- /dev/null +++ b/src/app/components/editor/autocomplete/RoomMentionAutocomplete.tsx @@ -0,0 +1,181 @@ +import React, { KeyboardEvent as ReactKeyboardEvent, useCallback, useEffect, useMemo } from 'react'; +import { Editor } from 'slate'; +import { Avatar, AvatarFallback, AvatarImage, Icon, Icons, MenuItem, Text, color } from 'folds'; +import { MatrixClient } from 'matrix-js-sdk'; + +import { createMentionElement, moveCursor, replaceWithElement } from '../common'; +import { getRoomAvatarUrl, joinRuleToIconSrc } from '../../../utils/room'; +import { roomIdByActivity } from '../../../../util/sort'; +import initMatrix from '../../../../client/initMatrix'; +import { useMatrixClient } from '../../../hooks/useMatrixClient'; +import { AutocompleteQuery } from './autocompleteQuery'; +import { AutocompleteMenu } from './AutocompleteMenu'; +import { getMxIdServer, validMxId } from '../../../utils/matrix'; +import { UseAsyncSearchOptions, useAsyncSearch } from '../../../hooks/useAsyncSearch'; +import { onTabPress } from '../../../utils/keyboard'; +import { useKeyDown } from '../../../hooks/useKeyDown'; + +type MentionAutoCompleteHandler = (roomAliasOrId: string, name: string) => void; + +const roomAliasFromQueryText = (mx: MatrixClient, text: string) => + validMxId(`#${text}`) + ? `#${text}` + : `#${text}${text.endsWith(':') ? '' : ':'}${getMxIdServer(mx.getUserId() ?? '')}`; + +function UnknownRoomMentionItem({ + query, + handleAutocomplete, +}: { + query: AutocompleteQuery; + handleAutocomplete: MentionAutoCompleteHandler; +}) { + const mx = useMatrixClient(); + const roomAlias: string = roomAliasFromQueryText(mx, query.text); + + return ( + ) => + onTabPress(evt, () => handleAutocomplete(roomAlias, roomAlias)) + } + onClick={() => handleAutocomplete(roomAlias, roomAlias)} + before={ + + + + } + > + + {roomAlias} + + + ); +} + +type RoomMentionAutocompleteProps = { + roomId: string; + editor: Editor; + query: AutocompleteQuery; + requestClose: () => void; +}; + +const SEARCH_OPTIONS: UseAsyncSearchOptions = { + limit: 20, + matchOptions: { + contain: true, + }, +}; + +export function RoomMentionAutocomplete({ + roomId, + editor, + query, + requestClose, +}: RoomMentionAutocompleteProps) { + const mx = useMatrixClient(); + const dms: Set = initMatrix.roomList?.directs ?? new Set(); + + const allRoomId: string[] = useMemo(() => { + const { spaces = [], rooms = [], directs = [] } = initMatrix.roomList ?? {}; + return [...spaces, ...rooms, ...directs].sort(roomIdByActivity); + }, []); + + const [result, search] = useAsyncSearch( + allRoomId, + useCallback( + (rId) => { + const r = mx.getRoom(rId); + if (!r) return 'Unknown Room'; + const alias = r.getCanonicalAlias(); + if (alias) return [r.name, alias]; + return r.name; + }, + [mx] + ), + SEARCH_OPTIONS + ); + + const autoCompleteRoomIds = result ? result.items : allRoomId.slice(0, 20); + + useEffect(() => { + search(query.text); + }, [query.text, search]); + + const handleAutocomplete: MentionAutoCompleteHandler = (roomAliasOrId, name) => { + const mentionEl = createMentionElement( + roomAliasOrId, + name.startsWith('#') ? name : `#${name}`, + roomId === roomAliasOrId || mx.getRoom(roomId)?.getCanonicalAlias() === roomAliasOrId + ); + replaceWithElement(editor, query.range, mentionEl); + moveCursor(editor, true); + requestClose(); + }; + + useKeyDown(window, (evt: KeyboardEvent) => { + onTabPress(evt, () => { + if (autoCompleteRoomIds.length === 0) { + const alias = roomAliasFromQueryText(mx, query.text); + handleAutocomplete(alias, alias); + return; + } + const rId = autoCompleteRoomIds[0]; + const name = mx.getRoom(rId)?.name ?? rId; + handleAutocomplete(rId, name); + }); + }); + + return ( + Rooms} requestClose={requestClose}> + {autoCompleteRoomIds.length === 0 ? ( + + ) : ( + autoCompleteRoomIds.map((rId) => { + const room = mx.getRoom(rId); + if (!room) return null; + const dm = dms.has(room.roomId); + const avatarUrl = getRoomAvatarUrl(mx, room); + const iconSrc = !dm && joinRuleToIconSrc(Icons, room.getJoinRule(), room.isSpaceRoom()); + + return ( + ) => + onTabPress(evt, () => handleAutocomplete(rId, room.name)) + } + onClick={() => handleAutocomplete(rId, room.name)} + after={ + + {room.getCanonicalAlias() ?? ''} + + } + before={ + + {iconSrc && } + {avatarUrl && !iconSrc && } + {!avatarUrl && !iconSrc && ( + + {room.name[0]} + + )} + + } + > + + {room.name} + + + ); + }) + )} + + ); +} diff --git a/src/app/components/editor/autocomplete/UserMentionAutocomplete.tsx b/src/app/components/editor/autocomplete/UserMentionAutocomplete.tsx new file mode 100644 index 000000000..10088ada6 --- /dev/null +++ b/src/app/components/editor/autocomplete/UserMentionAutocomplete.tsx @@ -0,0 +1,191 @@ +import React, { useEffect, KeyboardEvent as ReactKeyboardEvent } from 'react'; +import { Editor } from 'slate'; +import { Avatar, AvatarFallback, AvatarImage, MenuItem, Text, color } from 'folds'; +import { MatrixClient, RoomMember } from 'matrix-js-sdk'; + +import { AutocompleteQuery } from './autocompleteQuery'; +import { AutocompleteMenu } from './AutocompleteMenu'; +import { useRoomMembers } from '../../../hooks/useRoomMembers'; +import { useMatrixClient } from '../../../hooks/useMatrixClient'; +import { + SearchItemStrGetter, + UseAsyncSearchOptions, + useAsyncSearch, +} from '../../../hooks/useAsyncSearch'; +import { onTabPress } from '../../../utils/keyboard'; +import { createMentionElement, moveCursor, replaceWithElement } from '../common'; +import { useKeyDown } from '../../../hooks/useKeyDown'; +import { getMxIdLocalPart, getMxIdServer, validMxId } from '../../../utils/matrix'; + +type MentionAutoCompleteHandler = (userId: string, name: string) => void; + +const userIdFromQueryText = (mx: MatrixClient, text: string) => + validMxId(`@${text}`) + ? `@${text}` + : `@${text}${text.endsWith(':') ? '' : ':'}${getMxIdServer(mx.getUserId() ?? '')}`; + +function UnknownMentionItem({ + query, + userId, + name, + handleAutocomplete, +}: { + query: AutocompleteQuery; + userId: string; + name: string; + handleAutocomplete: MentionAutoCompleteHandler; +}) { + return ( + ) => + onTabPress(evt, () => handleAutocomplete(userId, name)) + } + onClick={() => handleAutocomplete(userId, name)} + before={ + + + {query.text[0]} + + + } + > + + {name} + + + ); +} + +type UserMentionAutocompleteProps = { + roomId: string; + editor: Editor; + query: AutocompleteQuery; + requestClose: () => void; +}; + +const SEARCH_OPTIONS: UseAsyncSearchOptions = { + limit: 20, + matchOptions: { + contain: true, + }, +}; + +const getRoomMemberStr: SearchItemStrGetter = (roomMember) => [ + roomMember.name, + getMxIdLocalPart(roomMember.userId) ?? roomMember.userId, + roomMember.userId, +]; + +export function UserMentionAutocomplete({ + roomId, + editor, + query, + requestClose, +}: UserMentionAutocompleteProps) { + const mx = useMatrixClient(); + const room = mx.getRoom(roomId); + const roomAliasOrId = room?.getCanonicalAlias() || roomId; + const members = useRoomMembers(mx, roomId); + + const [result, search] = useAsyncSearch(members, getRoomMemberStr, SEARCH_OPTIONS); + const autoCompleteMembers = result ? result.items : members.slice(0, 20); + + useEffect(() => { + search(query.text); + }, [query.text, search]); + + const handleAutocomplete: MentionAutoCompleteHandler = (uId, name) => { + const mentionEl = createMentionElement( + uId, + name.startsWith('@') ? name : `@${name}`, + mx.getUserId() === uId || roomAliasOrId === uId + ); + replaceWithElement(editor, query.range, mentionEl); + moveCursor(editor, true); + requestClose(); + }; + + useKeyDown(window, (evt: KeyboardEvent) => { + onTabPress(evt, () => { + if (query.text === 'room') { + handleAutocomplete(roomAliasOrId, '@room'); + return; + } + if (autoCompleteMembers.length === 0) { + const userId = userIdFromQueryText(mx, query.text); + handleAutocomplete(userId, userId); + return; + } + const roomMember = autoCompleteMembers[0]; + handleAutocomplete(roomMember.userId, roomMember.name); + }); + }); + + return ( + Mentions} requestClose={requestClose}> + {query.text === 'room' && ( + + )} + {autoCompleteMembers.length === 0 ? ( + + ) : ( + autoCompleteMembers.map((roomMember) => { + const avatarUrl = roomMember.getAvatarUrl(mx.baseUrl, 32, 32, 'crop', undefined, false); + return ( + ) => + onTabPress(evt, () => handleAutocomplete(roomMember.userId, roomMember.name)) + } + onClick={() => handleAutocomplete(roomMember.userId, roomMember.name)} + after={ + + {roomMember.userId} + + } + before={ + + {avatarUrl ? ( + + ) : ( + + {roomMember.name[0] || roomMember.userId[1]} + + )} + + } + > + + {roomMember.name} + + + ); + }) + )} + + ); +} diff --git a/src/app/components/editor/autocomplete/autocompleteQuery.ts b/src/app/components/editor/autocomplete/autocompleteQuery.ts new file mode 100644 index 000000000..348b44655 --- /dev/null +++ b/src/app/components/editor/autocomplete/autocompleteQuery.ts @@ -0,0 +1,46 @@ +import { BaseRange, Editor } from 'slate'; + +export enum AutocompletePrefix { + RoomMention = '#', + UserMention = '@', + Emoticon = ':', +} +export const AUTOCOMPLETE_PREFIXES: readonly AutocompletePrefix[] = [ + AutocompletePrefix.RoomMention, + AutocompletePrefix.UserMention, + AutocompletePrefix.Emoticon, +]; + +export type AutocompleteQuery = { + range: BaseRange; + prefix: TPrefix; + text: string; +}; + +export const getAutocompletePrefix = ( + editor: Editor, + queryRange: BaseRange, + validPrefixes: readonly TPrefix[] +): TPrefix | undefined => { + const world = Editor.string(editor, queryRange); + const prefix = world[0] as TPrefix | undefined; + if (!prefix) return undefined; + return validPrefixes.includes(prefix) ? prefix : undefined; +}; + +export const getAutocompleteQueryText = (editor: Editor, queryRange: BaseRange): string => + Editor.string(editor, queryRange).slice(1); + +export const getAutocompleteQuery = ( + editor: Editor, + queryRange: BaseRange, + validPrefixes: readonly TPrefix[] +): AutocompleteQuery | undefined => { + const prefix = getAutocompletePrefix(editor, queryRange, validPrefixes); + if (!prefix) return undefined; + return { + range: queryRange, + prefix, + text: getAutocompleteQueryText(editor, queryRange), + }; +}; diff --git a/src/app/components/editor/autocomplete/index.ts b/src/app/components/editor/autocomplete/index.ts new file mode 100644 index 000000000..be6a74428 --- /dev/null +++ b/src/app/components/editor/autocomplete/index.ts @@ -0,0 +1,5 @@ +export * from './AutocompleteMenu'; +export * from './autocompleteQuery'; +export * from './RoomMentionAutocomplete'; +export * from './UserMentionAutocomplete'; +export * from './EmoticonAutocomplete'; diff --git a/src/app/components/editor/common.ts b/src/app/components/editor/common.ts new file mode 100644 index 000000000..c9cf086c2 --- /dev/null +++ b/src/app/components/editor/common.ts @@ -0,0 +1,194 @@ +import { BasePoint, BaseRange, Editor, Element, Point, Range, Transforms } from 'slate'; +import { BlockType, MarkType } from './Elements'; +import { EmoticonElement, FormattedText, HeadingLevel, LinkElement, MentionElement } from './slate'; + +export const isMarkActive = (editor: Editor, format: MarkType) => { + const marks = Editor.marks(editor); + return marks ? marks[format] === true : false; +}; + +export const toggleMark = (editor: Editor, format: MarkType) => { + const isActive = isMarkActive(editor, format); + + if (isActive) { + Editor.removeMark(editor, format); + } else { + Editor.addMark(editor, format, true); + } +}; + +export const isBlockActive = (editor: Editor, format: BlockType) => { + const [match] = Editor.nodes(editor, { + match: (node) => Element.isElement(node) && node.type === format, + }); + + return !!match; +}; + +type BlockOption = { level: HeadingLevel }; +const NESTED_BLOCK = [ + BlockType.OrderedList, + BlockType.UnorderedList, + BlockType.BlockQuote, + BlockType.CodeBlock, +]; + +export const toggleBlock = (editor: Editor, format: BlockType, option?: BlockOption) => { + const isActive = isBlockActive(editor, format); + + Transforms.unwrapNodes(editor, { + match: (node) => Element.isElement(node) && NESTED_BLOCK.includes(node.type), + split: true, + }); + + if (isActive) { + Transforms.setNodes(editor, { + type: BlockType.Paragraph, + }); + return; + } + + if (format === BlockType.OrderedList || format === BlockType.UnorderedList) { + Transforms.setNodes(editor, { + type: BlockType.ListItem, + }); + const block = { + type: format, + children: [], + }; + Transforms.wrapNodes(editor, block); + return; + } + if (format === BlockType.CodeBlock) { + Transforms.setNodes(editor, { + type: BlockType.CodeLine, + }); + const block = { + type: format, + children: [], + }; + Transforms.wrapNodes(editor, block); + return; + } + + if (format === BlockType.BlockQuote) { + Transforms.setNodes(editor, { + type: BlockType.QuoteLine, + }); + const block = { + type: format, + children: [], + }; + Transforms.wrapNodes(editor, block); + return; + } + + if (format === BlockType.Heading) { + Transforms.setNodes(editor, { + type: format, + level: option?.level ?? 1, + }); + } + + Transforms.setNodes(editor, { + type: format, + }); +}; + +export const resetEditor = (editor: Editor) => { + Transforms.delete(editor, { + at: { + anchor: Editor.start(editor, []), + focus: Editor.end(editor, []), + }, + }); + + toggleBlock(editor, BlockType.Paragraph); +}; + +export const createMentionElement = ( + id: string, + name: string, + highlight: boolean +): MentionElement => ({ + type: BlockType.Mention, + id, + highlight, + name, + children: [{ text: '' }], +}); + +export const createEmoticonElement = (key: string, shortcode: string): EmoticonElement => ({ + type: BlockType.Emoticon, + key, + shortcode, + children: [{ text: '' }], +}); + +export const createLinkElement = ( + href: string, + children: string | FormattedText[] +): LinkElement => ({ + type: BlockType.Link, + href, + children: typeof children === 'string' ? [{ text: children }] : children, +}); + +export const replaceWithElement = (editor: Editor, selectRange: BaseRange, element: Element) => { + Transforms.select(editor, selectRange); + Transforms.insertNodes(editor, element); +}; + +export const moveCursor = (editor: Editor, withSpace?: boolean) => { + // without timeout it works properly when we select autocomplete with Tab or Space + setTimeout(() => { + Transforms.move(editor); + if (withSpace) editor.insertText(' '); + }, 1); +}; + +interface PointUntilCharOptions { + match: (char: string) => boolean; + reverse?: boolean; +} +export const getPointUntilChar = ( + editor: Editor, + cursorPoint: BasePoint, + options: PointUntilCharOptions +): BasePoint | undefined => { + let targetPoint: BasePoint | undefined; + let prevPoint: BasePoint | undefined; + let char: string | undefined; + + const pointItr = Editor.positions(editor, { + at: { + anchor: Editor.start(editor, []), + focus: Editor.point(editor, cursorPoint, { edge: 'start' }), + }, + unit: 'character', + reverse: options.reverse, + }); + + // eslint-disable-next-line no-restricted-syntax + for (const point of pointItr) { + if (!Point.equals(point, cursorPoint) && prevPoint) { + char = Editor.string(editor, { anchor: point, focus: prevPoint }); + + if (options.match(char)) break; + targetPoint = point; + } + prevPoint = point; + } + return targetPoint; +}; + +export const getPrevWorldRange = (editor: Editor): BaseRange | undefined => { + const { selection } = editor; + if (!selection || !Range.isCollapsed(selection)) return undefined; + const [cursorPoint] = Range.edges(selection); + const worldStartPoint = getPointUntilChar(editor, cursorPoint, { + reverse: true, + match: (char) => char === ' ', + }); + return worldStartPoint && Editor.range(editor, worldStartPoint, cursorPoint); +}; diff --git a/src/app/components/editor/index.ts b/src/app/components/editor/index.ts new file mode 100644 index 000000000..76ccf5624 --- /dev/null +++ b/src/app/components/editor/index.ts @@ -0,0 +1,7 @@ +export * from './autocomplete'; +export * from './common'; +export * from './Editor'; +export * from './Elements'; +export * from './keyboard'; +export * from './output'; +export * from './Toolbar'; diff --git a/src/app/components/editor/keyboard.ts b/src/app/components/editor/keyboard.ts new file mode 100644 index 000000000..52217dd56 --- /dev/null +++ b/src/app/components/editor/keyboard.ts @@ -0,0 +1,40 @@ +import { isHotkey } from 'is-hotkey'; +import { KeyboardEvent } from 'react'; +import { Editor } from 'slate'; +import { isBlockActive, toggleBlock, toggleMark } from './common'; +import { BlockType, MarkType } from './Elements'; + +export const INLINE_HOTKEYS: Record = { + 'mod+b': MarkType.Bold, + 'mod+i': MarkType.Italic, + 'mod+u': MarkType.Underline, + 'mod+shift+u': MarkType.StrikeThrough, + 'mod+[': MarkType.Code, + 'mod+h': MarkType.Spoiler, +}; +const INLINE_KEYS = Object.keys(INLINE_HOTKEYS); + +export const BLOCK_HOTKEYS: Record = { + 'mod+shift+0': BlockType.OrderedList, + 'mod+shift+8': BlockType.UnorderedList, + "mod+shift+'": BlockType.BlockQuote, + 'mod+shift+;': BlockType.CodeBlock, +}; +const BLOCK_KEYS = Object.keys(BLOCK_HOTKEYS); + +export const toggleKeyboardShortcut = (editor: Editor, event: KeyboardEvent) => { + BLOCK_KEYS.forEach((hotkey) => { + if (isHotkey(hotkey, event)) { + event.preventDefault(); + toggleBlock(editor, BLOCK_HOTKEYS[hotkey]); + } + }); + + if (!isBlockActive(editor, BlockType.CodeBlock)) + INLINE_KEYS.forEach((hotkey) => { + if (isHotkey(hotkey, event)) { + event.preventDefault(); + toggleMark(editor, INLINE_HOTKEYS[hotkey]); + } + }); +}; diff --git a/src/app/components/editor/output.ts b/src/app/components/editor/output.ts new file mode 100644 index 000000000..091dab794 --- /dev/null +++ b/src/app/components/editor/output.ts @@ -0,0 +1,95 @@ +import { Descendant, Text } from 'slate'; +import { sanitizeText } from '../../utils/sanitize'; +import { BlockType } from './Elements'; +import { CustomElement, FormattedText } from './slate'; + +const textToCustomHtml = (node: FormattedText): string => { + let string = sanitizeText(node.text); + if (node.bold) string = `${string}`; + if (node.italic) string = `${string}`; + if (node.underline) string = `${string}`; + if (node.strikeThrough) string = `${string}`; + if (node.code) string = `${string}`; + if (node.spoiler) string = `${string}`; + return string; +}; + +const elementToCustomHtml = (node: CustomElement, children: string): string => { + switch (node.type) { + case BlockType.Paragraph: + return `

      ${children}

      `; + case BlockType.Heading: + return `${children}`; + case BlockType.CodeLine: + return `${children}\n`; + case BlockType.CodeBlock: + return `
      ${children}
      `; + case BlockType.QuoteLine: + return `

      ${children}

      `; + case BlockType.BlockQuote: + return `
      ${children}
      `; + case BlockType.ListItem: + return `
    • ${children}

    • `; + case BlockType.OrderedList: + return `
        ${children}
      `; + case BlockType.UnorderedList: + return `
        ${children}
      `; + case BlockType.Mention: + return `${node.name}`; + case BlockType.Emoticon: + return node.key.startsWith('mxc://') + ? `${node.shortcode}` + : node.key; + case BlockType.Link: + return `${node.children}`; + default: + return children; + } +}; + +export const toMatrixCustomHTML = (node: Descendant | Descendant[]): string => { + if (Array.isArray(node)) return node.map((n) => toMatrixCustomHTML(n)).join(''); + if (Text.isText(node)) return textToCustomHtml(node); + + const children = node.children.map((n) => toMatrixCustomHTML(n)).join(''); + return elementToCustomHtml(node, children); +}; + +const elementToPlainText = (node: CustomElement, children: string): string => { + switch (node.type) { + case BlockType.Paragraph: + return `${children}\n`; + case BlockType.Heading: + return `${children}\n`; + case BlockType.CodeLine: + return `${children}\n`; + case BlockType.CodeBlock: + return `${children}\n`; + case BlockType.QuoteLine: + return `| ${children}\n`; + case BlockType.BlockQuote: + return `${children}\n`; + case BlockType.ListItem: + return `- ${children}\n`; + case BlockType.OrderedList: + return `${children}\n`; + case BlockType.UnorderedList: + return `${children}\n`; + case BlockType.Mention: + return node.id; + case BlockType.Emoticon: + return node.key.startsWith('mxc://') ? `:${node.shortcode}:` : node.key; + case BlockType.Link: + return `[${node.children}](${node.href})`; + default: + return children; + } +}; + +export const toPlainText = (node: Descendant | Descendant[]): string => { + if (Array.isArray(node)) return node.map((n) => toPlainText(n)).join(''); + if (Text.isText(node)) return sanitizeText(node.text); + + const children = node.children.map((n) => toPlainText(n)).join(''); + return elementToPlainText(node, children); +}; diff --git a/src/app/components/editor/slate.d.ts b/src/app/components/editor/slate.d.ts new file mode 100644 index 000000000..a321904bf --- /dev/null +++ b/src/app/components/editor/slate.d.ts @@ -0,0 +1,107 @@ +import { BaseEditor } from 'slate'; +import { ReactEditor } from 'slate-react'; +import { BlockType } from './Elements'; + +export type HeadingLevel = 1 | 2 | 3; + +export type Editor = BaseEditor & ReactEditor; + +export type Text = { + text: string; +}; + +export type FormattedText = Text & { + bold?: boolean; + italic?: boolean; + underline?: boolean; + strikeThrough?: boolean; + code?: boolean; + spoiler?: boolean; +}; + +export type LinkElement = { + type: BlockType.Link; + href: string; + children: FormattedText[]; +}; +export type SpoilerElement = { + type: 'spoiler'; + alert?: string; + children: FormattedText[]; +}; +export type MentionElement = { + type: BlockType.Mention; + id: string; + highlight: boolean; + name: string; + children: Text[]; +}; +export type EmoticonElement = { + type: BlockType.Emoticon; + key: string; + shortcode: string; + children: Text[]; +}; + +export type ParagraphElement = { + type: BlockType.Paragraph; + children: FormattedText[]; +}; +export type HeadingElement = { + type: BlockType.Heading; + level: HeadingLevel; + children: FormattedText[]; +}; +export type CodeLineElement = { + type: BlockType.CodeLine; + children: Text[]; +}; +export type CodeBlockElement = { + type: BlockType.CodeBlock; + children: CodeLineElement[]; +}; +export type QuoteLineElement = { + type: BlockType.QuoteLine; + children: FormattedText[]; +}; +export type BlockQuoteElement = { + type: BlockType.BlockQuote; + children: QuoteLineElement[]; +}; +export type ListItemElement = { + type: BlockType.ListItem; + children: FormattedText[]; +}; +export type OrderedListElement = { + type: BlockType.OrderedList; + children: ListItemElement[]; +}; +export type UnorderedListElement = { + type: BlockType.UnorderedList; + children: ListItemElement[]; +}; + +export type CustomElement = + | LinkElement + // | SpoilerElement + | MentionElement + | EmoticonElement + | ParagraphElement + | HeadingElement + | CodeLineElement + | CodeBlockElement + | QuoteLineElement + | BlockQuoteElement + | ListItemElement + | OrderedListElement + | UnorderedListElement; + +export type CustomEditor = BaseEditor & ReactEditor; + +declare module 'slate' { + interface CustomTypes { + Editor: BaseEditor & ReactEditor; + Element: CustomElement; + Text: FormattedText & Text; + } +} diff --git a/src/app/components/emoji-board/EmojiBoard.css.tsx b/src/app/components/emoji-board/EmojiBoard.css.tsx new file mode 100644 index 000000000..0fefc5b95 --- /dev/null +++ b/src/app/components/emoji-board/EmojiBoard.css.tsx @@ -0,0 +1,134 @@ +import { style } from '@vanilla-extract/css'; +import { DefaultReset, FocusOutline, color, config, toRem } from 'folds'; + +export const Base = style({ + maxWidth: toRem(432), + width: `calc(100vw - 2 * ${config.space.S400})`, + height: toRem(450), + backgroundColor: color.Surface.Container, + color: color.Surface.OnContainer, + border: `${config.borderWidth.B300} solid ${color.SurfaceVariant.ContainerLine}`, + borderRadius: config.radii.R400, + boxShadow: config.shadow.E200, + overflow: 'hidden', +}); + +export const Sidebar = style({ + width: toRem(54), + backgroundColor: color.Surface.Container, + color: color.Surface.OnContainer, + position: 'relative', +}); + +export const SidebarContent = style({ + padding: `${config.space.S200} 0`, +}); + +export const SidebarStack = style({ + width: '100%', + backgroundColor: color.Surface.Container, +}); + +export const NativeEmojiSidebarStack = style({ + position: 'sticky', + bottom: '-67%', + zIndex: 1, +}); + +export const SidebarDivider = style({ + width: toRem(18), +}); + +export const Header = style({ + padding: config.space.S300, + paddingBottom: 0, +}); + +export const EmojiBoardTab = style({ + cursor: 'pointer', +}); + +export const Footer = style({ + padding: config.space.S200, + margin: config.space.S300, + marginTop: 0, + minHeight: toRem(40), + + borderRadius: config.radii.R400, + backgroundColor: color.SurfaceVariant.Container, + color: color.SurfaceVariant.OnContainer, +}); + +export const EmojiGroup = style({ + padding: `${config.space.S300} 0`, +}); + +export const EmojiGroupLabel = style({ + position: 'sticky', + top: config.space.S200, + zIndex: 1, + + margin: 'auto', + padding: `${config.space.S100} ${config.space.S200}`, + borderRadius: config.radii.Pill, + backgroundColor: color.SurfaceVariant.Container, + color: color.SurfaceVariant.OnContainer, +}); + +export const EmojiGroupContent = style([ + DefaultReset, + { + padding: `0 ${config.space.S200}`, + }, +]); + +export const EmojiPreview = style([ + DefaultReset, + { + width: toRem(32), + height: toRem(32), + fontSize: toRem(32), + lineHeight: toRem(32), + }, +]); + +export const EmojiItem = style([ + DefaultReset, + FocusOutline, + { + width: toRem(48), + height: toRem(48), + fontSize: toRem(32), + lineHeight: toRem(32), + borderRadius: config.radii.R400, + cursor: 'pointer', + + ':hover': { + backgroundColor: color.Surface.ContainerHover, + }, + }, +]); + +export const StickerItem = style([ + EmojiItem, + { + width: toRem(112), + height: toRem(112), + }, +]); + +export const CustomEmojiImg = style([ + DefaultReset, + { + width: toRem(32), + height: toRem(32), + }, +]); + +export const StickerImg = style([ + DefaultReset, + { + width: toRem(96), + height: toRem(96), + }, +]); diff --git a/src/app/components/emoji-board/EmojiBoard.tsx b/src/app/components/emoji-board/EmojiBoard.tsx new file mode 100644 index 000000000..c5f5038c5 --- /dev/null +++ b/src/app/components/emoji-board/EmojiBoard.tsx @@ -0,0 +1,860 @@ +import React, { + ChangeEventHandler, + FocusEventHandler, + MouseEventHandler, + UIEventHandler, + ReactNode, + memo, + useCallback, + useEffect, + useMemo, + useRef, +} from 'react'; +import { + Badge, + Box, + Icon, + IconButton, + Icons, + Input, + Line, + Scroll, + Text, + Tooltip, + TooltipProvider, + as, + config, + toRem, +} from 'folds'; +import FocusTrap from 'focus-trap-react'; +import isHotkey from 'is-hotkey'; +import classNames from 'classnames'; +import { MatrixClient, Room } from 'matrix-js-sdk'; +import { atom, useAtomValue, useSetAtom } from 'jotai'; + +import * as css from './EmojiBoard.css'; +import { EmojiGroupId, IEmoji, IEmojiGroup, emojiGroups, emojis } from '../../plugins/emoji'; +import { IEmojiGroupLabels, useEmojiGroupLabels } from './useEmojiGroupLabels'; +import { IEmojiGroupIcons, useEmojiGroupIcons } from './useEmojiGroupIcons'; +import { preventScrollWithArrowKey } from '../../utils/keyboard'; +import { useRelevantImagePacks } from '../../hooks/useImagePacks'; +import { useMatrixClient } from '../../hooks/useMatrixClient'; +import { useRecentEmoji } from '../../hooks/useRecentEmoji'; +import { ExtendedPackImage, ImagePack, PackUsage } from '../../plugins/custom-emoji'; +import { isUserId } from '../../utils/matrix'; +import { editableActiveElement, inVisibleScrollArea, targetFromEvent } from '../../utils/dom'; +import { useAsyncSearch, UseAsyncSearchOptions } from '../../hooks/useAsyncSearch'; +import { useDebounce } from '../../hooks/useDebounce'; +import { useThrottle } from '../../hooks/useThrottle'; + +const RECENT_GROUP_ID = 'recent_group'; +const SEARCH_GROUP_ID = 'search_group'; + +export enum EmojiBoardTab { + Emoji = 'Emoji', + Sticker = 'Sticker', +} + +enum EmojiType { + Emoji = 'emoji', + CustomEmoji = 'customEmoji', + Sticker = 'sticker', +} + +export type EmojiItemInfo = { + type: EmojiType; + data: string; + shortcode: string; +}; + +const getDOMGroupId = (id: string): string => `EmojiBoardGroup-${id}`; + +const getEmojiItemInfo = (element: Element): EmojiItemInfo | undefined => { + const type = element.getAttribute('data-emoji-type') as EmojiType | undefined; + const data = element.getAttribute('data-emoji-data'); + const shortcode = element.getAttribute('data-emoji-shortcode'); + + if (type && data && shortcode) + return { + type, + data, + shortcode, + }; + return undefined; +}; + +const activeGroupIdAtom = atom(undefined); + +function Sidebar({ children }: { children: ReactNode }) { + return ( + + + + {children} + + + + ); +} + +const SidebarStack = as<'div'>(({ className, children, ...props }, ref) => ( + + {children} + +)); +function SidebarDivider() { + return ; +} + +function Header({ children }: { children: ReactNode }) { + return ( + + {children} + + ); +} + +function Content({ children }: { children: ReactNode }) { + return {children}; +} + +function Footer({ children }: { children: ReactNode }) { + return ( + + {children} + + ); +} + +const EmojiBoardLayout = as< + 'div', + { + header: ReactNode; + sidebar?: ReactNode; + footer?: ReactNode; + children: ReactNode; + } +>(({ className, header, sidebar, footer, children, ...props }, ref) => ( + + + {header} + {children} + {footer} + + + {sidebar} + +)); + +function EmojiBoardTabs({ + tab, + onTabChange, +}: { + tab: EmojiBoardTab; + onTabChange: (tab: EmojiBoardTab) => void; +}) { + return ( + + onTabChange(EmojiBoardTab.Emoji)} + > + + Emoji + + + onTabChange(EmojiBoardTab.Sticker)} + > + + Sticker + + + + ); +} + +export function SidebarBtn({ + active, + label, + id, + onItemClick, + children, +}: { + active?: boolean; + label: string; + id: T; + onItemClick: (id: T) => void; + children: ReactNode; +}) { + return ( + + {label} + + } + > + {(ref) => ( + onItemClick(id)} + size="400" + radii="300" + variant="Surface" + > + {children} + + )} + + ); +} + +export const EmojiGroup = as< + 'div', + { + id: string; + label: string; + children: ReactNode; + } +>(({ className, id, label, children, ...props }, ref) => ( + + + {label} + +
      + + {children} + +
      +
      +)); + +export function EmojiItem({ + label, + type, + data, + shortcode, + children, +}: { + label: string; + type: EmojiType; + data: string; + shortcode: string; + children: ReactNode; +}) { + return ( + + {children} + + ); +} + +export function StickerItem({ + label, + type, + data, + shortcode, + children, +}: { + label: string; + type: EmojiType; + data: string; + shortcode: string; + children: ReactNode; +}) { + return ( + + {children} + + ); +} + +function RecentEmojiSidebarStack({ onItemClick }: { onItemClick: (id: string) => void }) { + const activeGroupId = useAtomValue(activeGroupIdAtom); + + return ( + + onItemClick(RECENT_GROUP_ID)} + > + + + + ); +} + +function ImagePackSidebarStack({ + mx, + packs, + usage, + onItemClick, +}: { + mx: MatrixClient; + packs: ImagePack[]; + usage: PackUsage; + onItemClick: (id: string) => void; +}) { + const activeGroupId = useAtomValue(activeGroupIdAtom); + return ( + + {usage === PackUsage.Emoticon && } + {packs.map((pack) => { + let label = pack.displayName; + if (!label) label = isUserId(pack.id) ? 'Personal Pack' : mx.getRoom(pack.id)?.name; + return ( + + {label + + ); + })} + + ); +} + +function NativeEmojiSidebarStack({ + groups, + icons, + labels, + onItemClick, +}: { + groups: IEmojiGroup[]; + icons: IEmojiGroupIcons; + labels: IEmojiGroupLabels; + onItemClick: (id: EmojiGroupId) => void; +}) { + const activeGroupId = useAtomValue(activeGroupIdAtom); + return ( + + + {groups.map((group) => ( + + + + ))} + + ); +} + +export function RecentEmojiGroup({ + label, + id, + emojis: recentEmojis, +}: { + label: string; + id: string; + emojis: IEmoji[]; +}) { + return ( + + {recentEmojis.map((emoji) => ( + + {emoji.unicode} + + ))} + + ); +} + +export function SearchEmojiGroup({ + mx, + tab, + label, + id, + emojis: searchResult, +}: { + mx: MatrixClient; + tab: EmojiBoardTab; + label: string; + id: string; + emojis: Array; +}) { + return ( + + {tab === EmojiBoardTab.Emoji + ? searchResult.map((emoji) => + 'unicode' in emoji ? ( + + {emoji.unicode} + + ) : ( + + {emoji.body + + ) + ) + : searchResult.map((emoji) => + 'unicode' in emoji ? null : ( + + {emoji.body + + ) + )} + + ); +} + +export const CustomEmojiGroups = memo( + ({ mx, groups }: { mx: MatrixClient; groups: ImagePack[] }) => ( + <> + {groups.map((pack) => ( + + {pack.getEmojis().map((image) => ( + + {image.body + + ))} + + ))} + + ) +); + +export const StickerGroups = memo(({ mx, groups }: { mx: MatrixClient; groups: ImagePack[] }) => ( + <> + {groups.length === 0 && ( + + + + No Sticker Packs! + + Add stickers from user, room or space settings. + + + + )} + {groups.map((pack) => ( + + {pack.getStickers().map((image) => ( + + {image.body + + ))} + + ))} + +)); + +export const NativeEmojiGroups = memo( + ({ groups, labels }: { groups: IEmojiGroup[]; labels: IEmojiGroupLabels }) => ( + <> + {groups.map((emojiGroup) => ( + + {emojiGroup.emojis.map((emoji) => ( + + {emoji.unicode} + + ))} + + ))} + + ) +); + +const getSearchListItemStr = (item: ExtendedPackImage | IEmoji) => `:${item.shortcode}:`; +const SEARCH_OPTIONS: UseAsyncSearchOptions = { + limit: 26, + matchOptions: { + contain: true, + }, +}; + +export function EmojiBoard({ + tab = EmojiBoardTab.Emoji, + onTabChange, + imagePackRooms, + requestClose, + returnFocusOnDeactivate, + onEmojiSelect, + onCustomEmojiSelect, + onStickerSelect, +}: { + tab?: EmojiBoardTab; + onTabChange?: (tab: EmojiBoardTab) => void; + imagePackRooms: Room[]; + requestClose: () => void; + returnFocusOnDeactivate?: boolean; + onEmojiSelect?: (unicode: string, shortcode: string) => void; + onCustomEmojiSelect?: (mxc: string, shortcode: string) => void; + onStickerSelect?: (mxc: string, shortcode: string) => void; +}) { + const emojiTab = tab === EmojiBoardTab.Emoji; + const stickerTab = tab === EmojiBoardTab.Sticker; + const usage = emojiTab ? PackUsage.Emoticon : PackUsage.Sticker; + + const setActiveGroupId = useSetAtom(activeGroupIdAtom); + const mx = useMatrixClient(); + const emojiGroupLabels = useEmojiGroupLabels(); + const emojiGroupIcons = useEmojiGroupIcons(); + const imagePacks = useRelevantImagePacks(mx, usage, imagePackRooms); + const recentEmojis = useRecentEmoji(mx, 21); + + const contentScrollRef = useRef(null); + const emojiPreviewRef = useRef(null); + const emojiPreviewTextRef = useRef(null); + + const searchList = useMemo(() => { + let list: Array = []; + list = list.concat(imagePacks.flatMap((pack) => pack.getImagesFor(usage))); + if (emojiTab) list = list.concat(emojis); + return list; + }, [emojiTab, usage, imagePacks]); + + const [result, search] = useAsyncSearch(searchList, getSearchListItemStr, SEARCH_OPTIONS); + + const handleOnChange: ChangeEventHandler = useDebounce( + useCallback( + (evt) => { + const term = evt.target.value; + search(term); + }, + [search] + ), + { wait: 200 } + ); + + const syncActiveGroupId = useCallback(() => { + const targetEl = contentScrollRef.current; + if (!targetEl) return; + const groupEls = [...targetEl.querySelectorAll('div[data-group-id]')] as HTMLElement[]; + const groupEl = groupEls.find((el) => inVisibleScrollArea(targetEl, el)); + const groupId = groupEl?.getAttribute('data-group-id') ?? undefined; + setActiveGroupId(groupId); + }, [setActiveGroupId]); + + const handleOnScroll: UIEventHandler = useThrottle(syncActiveGroupId, { + wait: 500, + }); + + const handleScrollToGroup = (groupId: string) => { + setActiveGroupId(groupId); + const groupElement = document.getElementById(getDOMGroupId(groupId)); + groupElement?.scrollIntoView(); + }; + + const handleEmojiClick: MouseEventHandler = (evt) => { + const targetEl = targetFromEvent(evt.nativeEvent, 'button'); + if (!targetEl) return; + const emojiInfo = getEmojiItemInfo(targetEl); + if (!emojiInfo) return; + if (emojiInfo.type === EmojiType.Emoji) { + onEmojiSelect?.(emojiInfo.data, emojiInfo.shortcode); + if (!evt.altKey && !evt.shiftKey) requestClose(); + } + if (emojiInfo.type === EmojiType.CustomEmoji) { + onCustomEmojiSelect?.(emojiInfo.data, emojiInfo.shortcode); + if (!evt.altKey && !evt.shiftKey) requestClose(); + } + if (emojiInfo.type === EmojiType.Sticker) { + onStickerSelect?.(emojiInfo.data, emojiInfo.shortcode); + if (!evt.altKey && !evt.shiftKey) requestClose(); + } + }; + + const handleEmojiPreview = useCallback( + (element: HTMLButtonElement) => { + const emojiInfo = getEmojiItemInfo(element); + if (!emojiInfo || !emojiPreviewTextRef.current) return; + if (emojiInfo.type === EmojiType.Emoji && emojiPreviewRef.current) { + emojiPreviewRef.current.textContent = emojiInfo.data; + } else if (emojiInfo.type === EmojiType.CustomEmoji && emojiPreviewRef.current) { + const img = document.createElement('img'); + img.className = css.CustomEmojiImg; + img.setAttribute('src', mx.mxcUrlToHttp(emojiInfo.data) || emojiInfo.data); + img.setAttribute('alt', emojiInfo.shortcode); + emojiPreviewRef.current.textContent = ''; + emojiPreviewRef.current.appendChild(img); + } + emojiPreviewTextRef.current.textContent = `:${emojiInfo.shortcode}:`; + }, + [mx] + ); + + const throttleEmojiHover = useThrottle(handleEmojiPreview, { + wait: 200, + immediate: true, + }); + + const handleEmojiHover: MouseEventHandler = (evt) => { + const targetEl = targetFromEvent(evt.nativeEvent, 'button') as HTMLButtonElement | undefined; + if (!targetEl) return; + throttleEmojiHover(targetEl); + }; + + const handleEmojiFocus: FocusEventHandler = (evt) => { + const targetEl = evt.target as HTMLButtonElement; + handleEmojiPreview(targetEl); + }; + + // Reset scroll top on search and tab change + useEffect(() => { + syncActiveGroupId(); + contentScrollRef.current?.scrollTo({ + top: 0, + }); + }, [result, emojiTab, syncActiveGroupId]); + + return ( + + !editableActiveElement() && isHotkey(['arrowdown', 'arrowright'], evt), + isKeyBackward: (evt: KeyboardEvent) => + !editableActiveElement() && isHotkey(['arrowup', 'arrowleft'], evt), + }} + > + + + {onTabChange && } + } + onChange={handleOnChange} + autoFocus + /> + + + } + sidebar={ + + {emojiTab && recentEmojis.length > 0 && ( + + )} + {imagePacks.length > 0 && ( + + )} + {emojiTab && ( + + )} + + } + footer={ + emojiTab ? ( +
      + + 😃 + + + :smiley: + +
      + ) : ( + imagePacks.length > 0 && ( +
      + + :smiley: + +
      + ) + ) + } + > + + + + {result && ( + + )} + {emojiTab && recentEmojis.length > 0 && ( + + )} + {emojiTab && } + {stickerTab && } + {emojiTab && } + + + +
      +
      + ); +} diff --git a/src/app/components/emoji-board/index.ts b/src/app/components/emoji-board/index.ts new file mode 100644 index 000000000..430cec07b --- /dev/null +++ b/src/app/components/emoji-board/index.ts @@ -0,0 +1 @@ +export * from './EmojiBoard'; diff --git a/src/app/components/emoji-board/useEmojiGroupIcons.ts b/src/app/components/emoji-board/useEmojiGroupIcons.ts new file mode 100644 index 000000000..bef737410 --- /dev/null +++ b/src/app/components/emoji-board/useEmojiGroupIcons.ts @@ -0,0 +1,21 @@ +import { useMemo } from 'react'; +import { IconSrc, Icons } from 'folds'; + +import { EmojiGroupId } from '../../plugins/emoji'; + +export type IEmojiGroupIcons = Record; + +export const useEmojiGroupIcons = (): IEmojiGroupIcons => + useMemo( + () => ({ + [EmojiGroupId.People]: Icons.Smile, + [EmojiGroupId.Nature]: Icons.Leaf, + [EmojiGroupId.Food]: Icons.Cup, + [EmojiGroupId.Activity]: Icons.Ball, + [EmojiGroupId.Travel]: Icons.Photo, + [EmojiGroupId.Object]: Icons.Bulb, + [EmojiGroupId.Symbol]: Icons.Peace, + [EmojiGroupId.Flag]: Icons.Flag, + }), + [] + ); diff --git a/src/app/components/emoji-board/useEmojiGroupLabels.ts b/src/app/components/emoji-board/useEmojiGroupLabels.ts new file mode 100644 index 000000000..a1e5cf2c0 --- /dev/null +++ b/src/app/components/emoji-board/useEmojiGroupLabels.ts @@ -0,0 +1,19 @@ +import { useMemo } from 'react'; +import { EmojiGroupId } from '../../plugins/emoji'; + +export type IEmojiGroupLabels = Record; + +export const useEmojiGroupLabels = (): IEmojiGroupLabels => + useMemo( + () => ({ + [EmojiGroupId.People]: 'Smileys & People', + [EmojiGroupId.Nature]: 'Animals & Nature', + [EmojiGroupId.Food]: 'Food & Drinks', + [EmojiGroupId.Activity]: 'Activity', + [EmojiGroupId.Travel]: 'Travel & Places', + [EmojiGroupId.Object]: 'Objects', + [EmojiGroupId.Symbol]: 'Symbols', + [EmojiGroupId.Flag]: 'Flags', + }), + [] + ); diff --git a/src/app/components/sidebar/Sidebar.css.ts b/src/app/components/sidebar/Sidebar.css.ts new file mode 100644 index 000000000..e62ed6f55 --- /dev/null +++ b/src/app/components/sidebar/Sidebar.css.ts @@ -0,0 +1,111 @@ +import { style } from '@vanilla-extract/css'; +import { recipe, RecipeVariants } from '@vanilla-extract/recipes'; +import { color, config, DefaultReset, toRem } from 'folds'; + +export const Sidebar = style([ + DefaultReset, + { + width: toRem(66), + backgroundColor: color.Background.Container, + borderRight: `${config.borderWidth.B300} solid ${color.Background.ContainerLine}`, + + display: 'flex', + flexDirection: 'column', + color: color.Background.OnContainer, + }, +]); + +export const SidebarStack = style([ + DefaultReset, + { + width: '100%', + display: 'flex', + flexDirection: 'column', + justifyContent: 'center', + alignItems: 'center', + gap: config.space.S300, + padding: `${config.space.S300} 0`, + }, +]); + +const PUSH_X = 2; +export const SidebarAvatarBox = recipe({ + base: [ + DefaultReset, + { + display: 'flex', + alignItems: 'center', + position: 'relative', + transition: 'transform 200ms cubic-bezier(0, 0.8, 0.67, 0.97)', + + selectors: { + '&:hover': { + transform: `translateX(${toRem(PUSH_X)})`, + }, + '&::before': { + content: '', + display: 'none', + position: 'absolute', + left: toRem(-11.5 - PUSH_X), + width: toRem(3 + PUSH_X), + height: toRem(16), + borderRadius: `0 ${toRem(4)} ${toRem(4)} 0`, + background: 'CurrentColor', + transition: 'height 200ms linear', + }, + '&:hover::before': { + display: 'block', + width: toRem(3), + }, + }, + }, + ], + variants: { + active: { + true: { + selectors: { + '&::before': { + display: 'block', + height: toRem(24), + }, + '&:hover::before': { + width: toRem(3 + PUSH_X), + }, + }, + }, + }, + }, +}); + +export type SidebarAvatarBoxVariants = RecipeVariants; + +export const SidebarBadgeBox = recipe({ + base: [ + DefaultReset, + { + position: 'absolute', + zIndex: 1, + }, + ], + variants: { + hasCount: { + true: { + top: toRem(-6), + right: toRem(-6), + }, + false: { + top: toRem(-2), + right: toRem(-2), + }, + }, + }, + defaultVariants: { + hasCount: false, + }, +}); + +export type SidebarBadgeBoxVariants = RecipeVariants; + +export const SidebarBadgeOutline = style({ + boxShadow: `0 0 0 ${config.borderWidth.B500} ${color.Background.Container}`, +}); diff --git a/src/app/components/sidebar/Sidebar.tsx b/src/app/components/sidebar/Sidebar.tsx new file mode 100644 index 000000000..7caf1b21b --- /dev/null +++ b/src/app/components/sidebar/Sidebar.tsx @@ -0,0 +1,8 @@ +import classNames from 'classnames'; +import { as } from 'folds'; +import React from 'react'; +import * as css from './Sidebar.css'; + +export const Sidebar = as<'div'>(({ as: AsSidebar = 'div', className, ...props }, ref) => ( + +)); diff --git a/src/app/components/sidebar/SidebarAvatar.tsx b/src/app/components/sidebar/SidebarAvatar.tsx new file mode 100644 index 000000000..86665f7e1 --- /dev/null +++ b/src/app/components/sidebar/SidebarAvatar.tsx @@ -0,0 +1,75 @@ +import classNames from 'classnames'; +import { as, Avatar, Box, color, config, Text, Tooltip, TooltipProvider } from 'folds'; +import React, { forwardRef, MouseEventHandler, ReactNode } from 'react'; +import * as css from './Sidebar.css'; + +const SidebarAvatarBox = as<'div', css.SidebarAvatarBoxVariants>( + ({ as: AsSidebarAvatarBox = 'div', className, active, ...props }, ref) => ( + + ) +); + +export const SidebarAvatar = forwardRef< + HTMLDivElement, + css.SidebarAvatarBoxVariants & + css.SidebarBadgeBoxVariants & { + outlined?: boolean; + avatarChildren: ReactNode; + tooltip: ReactNode | string; + notificationBadge?: (badgeClassName: string) => ReactNode; + onClick?: MouseEventHandler; + onContextMenu?: MouseEventHandler; + } +>( + ( + { + active, + hasCount, + outlined, + avatarChildren, + tooltip, + notificationBadge, + onClick, + onContextMenu, + }, + ref + ) => ( + + + {tooltip} + + } + > + {(avRef) => ( + + {avatarChildren} + + )} + + {notificationBadge && ( + + {notificationBadge(css.SidebarBadgeOutline)} + + )} + + ) +); diff --git a/src/app/components/sidebar/SidebarContent.tsx b/src/app/components/sidebar/SidebarContent.tsx new file mode 100644 index 000000000..4f4058718 --- /dev/null +++ b/src/app/components/sidebar/SidebarContent.tsx @@ -0,0 +1,21 @@ +import React, { ReactNode } from 'react'; +import { Box, Scroll } from 'folds'; + +type SidebarContentProps = { + scrollable: ReactNode; + sticky: ReactNode; +}; +export function SidebarContent({ scrollable, sticky }: SidebarContentProps) { + return ( + <> + + + {scrollable} + + + + {sticky} + + + ); +} diff --git a/src/app/components/sidebar/SidebarStack.tsx b/src/app/components/sidebar/SidebarStack.tsx new file mode 100644 index 000000000..c0e976c8e --- /dev/null +++ b/src/app/components/sidebar/SidebarStack.tsx @@ -0,0 +1,10 @@ +import React from 'react'; +import classNames from 'classnames'; +import { as } from 'folds'; +import * as css from './Sidebar.css'; + +export const SidebarStack = as<'div'>( + ({ as: AsSidebarStack = 'div', className, ...props }, ref) => ( + + ) +); diff --git a/src/app/components/sidebar/SidebarStackSeparator.tsx b/src/app/components/sidebar/SidebarStackSeparator.tsx new file mode 100644 index 000000000..110341ca5 --- /dev/null +++ b/src/app/components/sidebar/SidebarStackSeparator.tsx @@ -0,0 +1,13 @@ +import React from 'react'; +import { Line, toRem } from 'folds'; + +export function SidebarStackSeparator() { + return ( + + ); +} diff --git a/src/app/components/sidebar/index.ts b/src/app/components/sidebar/index.ts new file mode 100644 index 000000000..f744628ec --- /dev/null +++ b/src/app/components/sidebar/index.ts @@ -0,0 +1,5 @@ +export * from './Sidebar'; +export * from './SidebarAvatar'; +export * from './SidebarContent'; +export * from './SidebarStack'; +export * from './SidebarStackSeparator'; diff --git a/src/app/components/upload-board/UploadBoard.css.ts b/src/app/components/upload-board/UploadBoard.css.ts new file mode 100644 index 000000000..80c1b264d --- /dev/null +++ b/src/app/components/upload-board/UploadBoard.css.ts @@ -0,0 +1,46 @@ +import { style } from '@vanilla-extract/css'; +import { DefaultReset, color, config, toRem } from 'folds'; + +export const UploadBoardBase = style([ + DefaultReset, + { + position: 'relative', + pointerEvents: 'none', + }, +]); + +export const UploadBoardContainer = style([ + DefaultReset, + { + position: 'absolute', + bottom: config.space.S200, + left: 0, + right: 0, + zIndex: config.zIndex.Max, + }, +]); + +export const UploadBoard = style({ + maxWidth: toRem(400), + width: '100%', + maxHeight: toRem(450), + height: '100%', + backgroundColor: color.Surface.Container, + color: color.Surface.OnContainer, + borderRadius: config.radii.R400, + boxShadow: config.shadow.E200, + border: `${config.borderWidth.B300} solid ${color.Surface.ContainerLine}`, + overflow: 'hidden', + pointerEvents: 'all', +}); + +export const UploadBoardHeaderContent = style({ + height: '100%', + padding: `0 ${config.space.S200}`, +}); + +export const UploadBoardContent = style({ + padding: config.space.S200, + paddingBottom: 0, + paddingRight: 0, +}); diff --git a/src/app/components/upload-board/UploadBoard.tsx b/src/app/components/upload-board/UploadBoard.tsx new file mode 100644 index 000000000..42f3899f2 --- /dev/null +++ b/src/app/components/upload-board/UploadBoard.tsx @@ -0,0 +1,145 @@ +import React, { MutableRefObject, ReactNode, useImperativeHandle, useRef } from 'react'; +import { Badge, Box, Chip, Header, Icon, Icons, Spinner, Text, as, percent } from 'folds'; +import classNames from 'classnames'; +import { useAtomValue } from 'jotai'; + +import * as css from './UploadBoard.css'; +import { TUploadFamilyObserverAtom, Upload, UploadStatus, UploadSuccess } from '../../state/upload'; + +type UploadBoardProps = { + header: ReactNode; +}; +export const UploadBoard = as<'div', UploadBoardProps>(({ header, children, ...props }, ref) => ( + + + + + {children} + + + {header} + + + + +)); + +export type UploadBoardImperativeHandlers = { handleSend: () => Promise }; + +type UploadBoardHeaderProps = { + open: boolean; + onToggle: () => void; + uploadFamilyObserverAtom: TUploadFamilyObserverAtom; + onCancel: (uploads: Upload[]) => void; + onSend: (uploads: UploadSuccess[]) => Promise; + imperativeHandlerRef: MutableRefObject; +}; + +export function UploadBoardHeader({ + open, + onToggle, + uploadFamilyObserverAtom, + onCancel, + onSend, + imperativeHandlerRef, +}: UploadBoardHeaderProps) { + const sendingRef = useRef(false); + const uploads = useAtomValue(uploadFamilyObserverAtom); + + const isSuccess = uploads.every((upload) => upload.status === UploadStatus.Success); + const isError = uploads.some((upload) => upload.status === UploadStatus.Error); + const progress = uploads.reduce( + (acc, upload) => { + acc.total += upload.file.size; + if (upload.status === UploadStatus.Loading) { + acc.loaded += upload.progress.loaded; + } + if (upload.status === UploadStatus.Success) { + acc.loaded += upload.file.size; + } + return acc; + }, + { loaded: 0, total: 0 } + ); + + const handleSend = async () => { + if (sendingRef.current) return; + sendingRef.current = true; + await onSend( + uploads.filter((upload) => upload.status === UploadStatus.Success) as UploadSuccess[] + ); + sendingRef.current = false; + }; + + useImperativeHandle(imperativeHandlerRef, () => ({ + handleSend, + })); + const handleCancel = () => onCancel(uploads); + + return ( +
      + + + Files + + + {isSuccess && ( + } + > + Send + + )} + {isError && !open && ( + + Upload Failed + + )} + {!isSuccess && !isError && !open && ( + <> + + {Math.round(percent(0, progress.total, progress.loaded))}% + + + + )} + {!isSuccess && open && ( + } + > + {uploads.length === 1 ? 'Remove' : 'Remove All'} + + )} + +
      + ); +} + +export const UploadBoardContent = as<'div'>(({ className, children, ...props }, ref) => ( + + {children} + +)); diff --git a/src/app/components/upload-board/index.ts b/src/app/components/upload-board/index.ts new file mode 100644 index 000000000..24ae780c9 --- /dev/null +++ b/src/app/components/upload-board/index.ts @@ -0,0 +1 @@ +export * from './UploadBoard'; diff --git a/src/app/components/upload-card/UploadCard.css.ts b/src/app/components/upload-card/UploadCard.css.ts new file mode 100644 index 000000000..20ac00e3c --- /dev/null +++ b/src/app/components/upload-card/UploadCard.css.ts @@ -0,0 +1,24 @@ +import { style } from '@vanilla-extract/css'; +import { RecipeVariants, recipe } from '@vanilla-extract/recipes'; +import { RadiiVariant, color, config } from 'folds'; + +export const UploadCard = recipe({ + base: { + padding: config.space.S300, + backgroundColor: color.SurfaceVariant.Container, + color: color.SurfaceVariant.OnContainer, + }, + variants: { + radii: RadiiVariant, + }, + defaultVariants: { + radii: '400', + }, +}); + +export type UploadCardVariant = RecipeVariants; + +export const UploadCardError = style({ + padding: `0 ${config.space.S100}`, + color: color.Critical.Main, +}); diff --git a/src/app/components/upload-card/UploadCard.tsx b/src/app/components/upload-card/UploadCard.tsx new file mode 100644 index 000000000..ae7b71b88 --- /dev/null +++ b/src/app/components/upload-card/UploadCard.tsx @@ -0,0 +1,63 @@ +import { Badge, Box, Icon, Icons, ProgressBar, Text, percent } from 'folds'; +import React, { ReactNode, forwardRef } from 'react'; + +import * as css from './UploadCard.css'; +import { bytesToSize } from '../../utils/common'; + +type UploadCardProps = { + before?: ReactNode; + children: ReactNode; + after?: ReactNode; + bottom?: ReactNode; +}; + +export const UploadCard = forwardRef( + ({ before, after, children, bottom, radii }, ref) => ( + + + {before} + + {children} + + {after} + + {bottom} + + ) +); + +type UploadCardProgressProps = { + sentBytes: number; + totalBytes: number; +}; + +export function UploadCardProgress({ sentBytes, totalBytes }: UploadCardProgressProps) { + return ( + + + + + {`${Math.round(percent(0, totalBytes, sentBytes))}%`} + + + + {bytesToSize(sentBytes)} / {bytesToSize(totalBytes)} + + + + + ); +} + +type UploadCardErrorProps = { + children: ReactNode; +}; + +export function UploadCardError({ children }: UploadCardErrorProps) { + return ( + + + {children} + + ); +} diff --git a/src/app/components/upload-card/UploadCardRenderer.tsx b/src/app/components/upload-card/UploadCardRenderer.tsx new file mode 100644 index 000000000..949f5d645 --- /dev/null +++ b/src/app/components/upload-card/UploadCardRenderer.tsx @@ -0,0 +1,89 @@ +import React from 'react'; +import { Chip, Icon, IconButton, Icons, Text, color } from 'folds'; +import { UploadCard, UploadCardError, UploadCardProgress } from './UploadCard'; +import { TUploadAtom, UploadStatus, useBindUploadAtom } from '../../state/upload'; +import { useMatrixClient } from '../../hooks/useMatrixClient'; +import { TUploadContent } from '../../utils/matrix'; +import { getFileTypeIcon } from '../../utils/common'; + +type UploadCardRendererProps = { + file: TUploadContent; + isEncrypted?: boolean; + uploadAtom: TUploadAtom; + onRemove: (file: TUploadContent) => void; +}; +export function UploadCardRenderer({ + file, + isEncrypted, + uploadAtom, + onRemove, +}: UploadCardRendererProps) { + const mx = useMatrixClient(); + const { upload, startUpload, cancelUpload } = useBindUploadAtom( + mx, + file, + uploadAtom, + isEncrypted + ); + + if (upload.status === UploadStatus.Idle) startUpload(); + + const removeUpload = () => { + cancelUpload(); + onRemove(file); + }; + + return ( + } + after={ + <> + {upload.status === UploadStatus.Error && ( + + Retry + + )} + + + + + } + bottom={ + <> + {upload.status === UploadStatus.Idle && ( + + )} + {upload.status === UploadStatus.Loading && ( + + )} + {upload.status === UploadStatus.Error && ( + + {upload.error.message} + + )} + + } + > + + {file.name} + + {upload.status === UploadStatus.Success && ( + + )} + + ); +} diff --git a/src/app/components/upload-card/index.ts b/src/app/components/upload-card/index.ts new file mode 100644 index 000000000..3e7a5e397 --- /dev/null +++ b/src/app/components/upload-card/index.ts @@ -0,0 +1,2 @@ +export * from './UploadCard'; +export * from './UploadCardRenderer'; diff --git a/src/app/hooks/useAlive.ts b/src/app/hooks/useAlive.ts new file mode 100644 index 000000000..0bfbce8d7 --- /dev/null +++ b/src/app/hooks/useAlive.ts @@ -0,0 +1,15 @@ +import { useCallback, useEffect, useRef } from 'react'; + +export const useAlive = (): (() => boolean) => { + const aliveRef = useRef(true); + + useEffect(() => { + aliveRef.current = true; + return () => { + aliveRef.current = false; + }; + }, []); + + const alive = useCallback(() => aliveRef.current, []); + return alive; +}; diff --git a/src/app/hooks/useAsyncCallback.ts b/src/app/hooks/useAsyncCallback.ts new file mode 100644 index 000000000..18b63ecc6 --- /dev/null +++ b/src/app/hooks/useAsyncCallback.ts @@ -0,0 +1,70 @@ +import { useCallback, useState } from 'react'; +import { useAlive } from './useAlive'; + +export enum AsyncStatus { + Idle = 'idle', + Loading = 'loading', + Success = 'success', + Error = 'error', +} + +export type AsyncIdle = { + status: AsyncStatus.Idle; +}; + +export type AsyncLoading = { + status: AsyncStatus.Loading; +}; + +export type AsyncSuccess = { + status: AsyncStatus.Success; + data: T; +}; + +export type AsyncError = { + status: AsyncStatus.Error; + error: unknown; +}; + +export type AsyncState = AsyncIdle | AsyncLoading | AsyncSuccess | AsyncError; + +export type AsyncCallback = (...args: TArgs) => Promise; + +export const useAsyncCallback = ( + asyncCallback: AsyncCallback +): [AsyncState, AsyncCallback] => { + const [state, setState] = useState>({ + status: AsyncStatus.Idle, + }); + const alive = useAlive(); + + const callback: AsyncCallback = useCallback( + async (...args) => { + setState({ + status: AsyncStatus.Loading, + }); + + try { + const data = await asyncCallback(...args); + if (alive()) { + setState({ + status: AsyncStatus.Success, + data, + }); + } + return data; + } catch (e) { + if (alive()) { + setState({ + status: AsyncStatus.Error, + error: e, + }); + } + throw e; + } + }, + [asyncCallback, alive] + ); + + return [state, callback]; +}; diff --git a/src/app/hooks/useAsyncSearch.ts b/src/app/hooks/useAsyncSearch.ts new file mode 100644 index 000000000..b083a19ab --- /dev/null +++ b/src/app/hooks/useAsyncSearch.ts @@ -0,0 +1,81 @@ +import { useCallback, useEffect, useMemo, useState } from 'react'; +import { + MatchHandler, + AsyncSearch, + AsyncSearchHandler, + AsyncSearchOption, + MatchQueryOption, + NormalizeOption, + normalize, + matchQuery, + ResultHandler, +} from '../utils/AsyncSearch'; + +export type UseAsyncSearchOptions = AsyncSearchOption & { + matchOptions?: MatchQueryOption; + normalizeOptions?: NormalizeOption; +}; + +export type SearchItemStrGetter = ( + searchItem: TSearchItem +) => string | string[]; + +export type UseAsyncSearchResult = { + query: string; + items: TSearchItem[]; +}; + +export const useAsyncSearch = ( + list: TSearchItem[], + getItemStr: SearchItemStrGetter, + options?: UseAsyncSearchOptions +): [UseAsyncSearchResult | undefined, AsyncSearchHandler] => { + const [result, setResult] = useState>(); + + const [searchCallback, terminateSearch] = useMemo(() => { + setResult(undefined); + + const handleMatch: MatchHandler = (item, query) => { + const itemStr = getItemStr(item); + if (Array.isArray(itemStr)) + return !!itemStr.find((i) => + matchQuery(normalize(i, options?.normalizeOptions), query, options?.matchOptions) + ); + return matchQuery( + normalize(itemStr, options?.normalizeOptions), + query, + options?.matchOptions + ); + }; + + const handleResult: ResultHandler = (results, query) => + setResult({ + query, + items: results, + }); + + return AsyncSearch(list, handleMatch, handleResult, options); + }, [list, options, getItemStr]); + + const searchHandler: AsyncSearchHandler = useCallback( + (query) => { + const normalizedQuery = normalize(query, options?.normalizeOptions); + if (!normalizedQuery) { + setResult(undefined); + return; + } + searchCallback(normalizedQuery); + }, + [searchCallback, options?.normalizeOptions] + ); + + useEffect( + () => () => { + // terminate any ongoing search request on unmount. + terminateSearch(); + }, + [terminateSearch] + ); + + return [result, searchHandler]; +}; diff --git a/src/app/hooks/useDebounce.ts b/src/app/hooks/useDebounce.ts new file mode 100644 index 000000000..5f33976a3 --- /dev/null +++ b/src/app/hooks/useDebounce.ts @@ -0,0 +1,34 @@ +import { useCallback, useRef } from 'react'; + +export interface DebounceOptions { + wait?: number; + immediate?: boolean; +} +export type DebounceCallback = (...args: T) => void; + +export function useDebounce( + callback: DebounceCallback, + options?: DebounceOptions +): DebounceCallback { + const timeoutIdRef = useRef(); + const { wait, immediate } = options ?? {}; + + const debounceCallback = useCallback( + (...cbArgs: T) => { + if (timeoutIdRef.current) { + clearTimeout(timeoutIdRef.current); + timeoutIdRef.current = undefined; + } else if (immediate) { + callback(...cbArgs); + } + + timeoutIdRef.current = window.setTimeout(() => { + callback(...cbArgs); + timeoutIdRef.current = undefined; + }, wait); + }, + [callback, wait, immediate] + ); + + return debounceCallback; +} diff --git a/src/app/hooks/useFileDrop.ts b/src/app/hooks/useFileDrop.ts new file mode 100644 index 000000000..bead203f9 --- /dev/null +++ b/src/app/hooks/useFileDrop.ts @@ -0,0 +1,66 @@ +import { useCallback, DragEventHandler, RefObject, useState, useEffect, useRef } from 'react'; +import { getDataTransferFiles } from '../utils/dom'; + +export const useFileDropHandler = (onDrop: (file: File[]) => void): DragEventHandler => + useCallback( + (evt) => { + const files = getDataTransferFiles(evt.dataTransfer); + if (files) onDrop(files); + }, + [onDrop] + ); + +export const useFileDropZone = ( + zoneRef: RefObject, + onDrop: (file: File[]) => void +): boolean => { + const dragStateRef = useRef<'start' | 'leave' | 'over'>(); + const [active, setActive] = useState(false); + + useEffect(() => { + const target = zoneRef.current; + const handleDrop = (evt: DragEvent) => { + evt.preventDefault(); + dragStateRef.current = undefined; + setActive(false); + if (!evt.dataTransfer) return; + const files = getDataTransferFiles(evt.dataTransfer); + if (files) onDrop(files); + }; + + target?.addEventListener('drop', handleDrop); + return () => { + target?.removeEventListener('drop', handleDrop); + }; + }, [zoneRef, onDrop]); + + useEffect(() => { + const target = zoneRef.current; + const handleDragEnter = (evt: DragEvent) => { + if (evt.dataTransfer?.types.includes('Files')) { + dragStateRef.current = 'start'; + setActive(true); + } + }; + const handleDragLeave = () => { + if (dragStateRef.current !== 'over') return; + dragStateRef.current = 'leave'; + setActive(false); + }; + const handleDragOver = (evt: DragEvent) => { + evt.preventDefault(); + dragStateRef.current = 'over'; + }; + + target?.addEventListener('dragenter', handleDragEnter); + target?.addEventListener('dragleave', handleDragLeave); + target?.addEventListener('dragover', handleDragOver); + return () => { + target?.removeEventListener('dragenter', handleDragEnter); + target?.removeEventListener('dragleave', handleDragLeave); + target?.removeEventListener('dragover', handleDragOver); + }; + }, [zoneRef]); + + return active; +}; diff --git a/src/app/hooks/useFilePasteHandler.ts b/src/app/hooks/useFilePasteHandler.ts new file mode 100644 index 000000000..0f63b7505 --- /dev/null +++ b/src/app/hooks/useFilePasteHandler.ts @@ -0,0 +1,11 @@ +import { useCallback, ClipboardEventHandler } from 'react'; +import { getDataTransferFiles } from '../utils/dom'; + +export const useFilePasteHandler = (onPaste: (file: File[]) => void): ClipboardEventHandler => + useCallback( + (evt) => { + const files = getDataTransferFiles(evt.clipboardData); + if (files) onPaste(files); + }, + [onPaste] + ); diff --git a/src/app/hooks/useFilePicker.ts b/src/app/hooks/useFilePicker.ts new file mode 100644 index 000000000..e772d6609 --- /dev/null +++ b/src/app/hooks/useFilePicker.ts @@ -0,0 +1,15 @@ +import { useCallback } from 'react'; +import { selectFile } from '../utils/dom'; + +export const useFilePicker = ( + onSelect: (file: M extends true ? File[] : File) => void, + multiple?: M +) => + useCallback( + async (accept: string) => { + const file = await selectFile(accept, multiple); + if (!file) return; + onSelect(file); + }, + [multiple, onSelect] + ); diff --git a/src/app/hooks/useForceUpdate.ts b/src/app/hooks/useForceUpdate.ts new file mode 100644 index 000000000..0691aa922 --- /dev/null +++ b/src/app/hooks/useForceUpdate.ts @@ -0,0 +1,9 @@ +import { useReducer } from 'react'; + +const reducer = (prevCount: number): number => prevCount + 1; + +export const useForceUpdate = (): [number, () => void] => { + const [state, dispatch] = useReducer(reducer, 0); + + return [state, dispatch]; +}; diff --git a/src/app/hooks/useImagePacks.ts b/src/app/hooks/useImagePacks.ts new file mode 100644 index 000000000..ab988e36b --- /dev/null +++ b/src/app/hooks/useImagePacks.ts @@ -0,0 +1,48 @@ +import { ClientEvent, MatrixClient, MatrixEvent, Room, RoomStateEvent } from 'matrix-js-sdk'; +import { useEffect, useMemo } from 'react'; +import { getRelevantPacks, ImagePack, PackUsage } from '../plugins/custom-emoji'; +import { AccountDataEvent } from '../../types/matrix/accountData'; +import { StateEvent } from '../../types/matrix/room'; +import { useForceUpdate } from './useForceUpdate'; + +export const useRelevantImagePacks = ( + mx: MatrixClient, + usage: PackUsage, + rooms: Room[] +): ImagePack[] => { + const [forceCount, forceUpdate] = useForceUpdate(); + + const relevantPacks = useMemo( + () => getRelevantPacks(mx, rooms).filter((pack) => pack.getImagesFor(usage).length > 0), + // eslint-disable-next-line react-hooks/exhaustive-deps + [mx, usage, rooms, forceCount] + ); + + useEffect(() => { + const handleUpdate = (event: MatrixEvent) => { + if ( + event.getType() === AccountDataEvent.PoniesEmoteRooms || + event.getType() === AccountDataEvent.PoniesUserEmotes + ) { + forceUpdate(); + } + const eventRoomId = event.getRoomId(); + if ( + eventRoomId && + event.getType() === StateEvent.PoniesRoomEmotes && + rooms.find((room) => room.roomId === eventRoomId) + ) { + forceUpdate(); + } + }; + + mx.on(ClientEvent.AccountData, handleUpdate); + mx.on(RoomStateEvent.Events, handleUpdate); + return () => { + mx.removeListener(ClientEvent.AccountData, handleUpdate); + mx.removeListener(RoomStateEvent.Events, handleUpdate); + }; + }, [mx, rooms, forceUpdate]); + + return relevantPacks; +}; diff --git a/src/app/hooks/useKeyDown.ts b/src/app/hooks/useKeyDown.ts new file mode 100644 index 000000000..c754d88cd --- /dev/null +++ b/src/app/hooks/useKeyDown.ts @@ -0,0 +1,10 @@ +import { useEffect } from 'react'; + +export const useKeyDown = (target: Window, callback: (evt: KeyboardEvent) => void) => { + useEffect(() => { + target.addEventListener('keydown', callback); + return () => { + target.removeEventListener('keydown', callback); + }; + }, [target, callback]); +}; diff --git a/src/app/hooks/useMatrixClient.ts b/src/app/hooks/useMatrixClient.ts new file mode 100644 index 000000000..5ff6d90dd --- /dev/null +++ b/src/app/hooks/useMatrixClient.ts @@ -0,0 +1,12 @@ +import { createContext, useContext } from 'react'; +import { MatrixClient } from 'matrix-js-sdk'; + +const MatrixClientContext = createContext(null); + +export const MatrixClientProvider = MatrixClientContext.Provider; + +export function useMatrixClient(): MatrixClient { + const mx = useContext(MatrixClientContext); + if (!mx) throw new Error('MatrixClient not initialized!'); + return mx; +} diff --git a/src/app/hooks/usePowerLevels.ts b/src/app/hooks/usePowerLevels.ts new file mode 100644 index 000000000..8f999d484 --- /dev/null +++ b/src/app/hooks/usePowerLevels.ts @@ -0,0 +1,86 @@ +import { Room } from 'matrix-js-sdk'; +import { useCallback } from 'react'; +import { useStateEvent } from './useStateEvent'; +import { StateEvent } from '../../types/matrix/room'; + +enum DefaultPowerLevels { + usersDefault = 0, + stateDefault = 50, + eventsDefault = 0, + invite = 0, + redact = 50, + kick = 50, + ban = 50, + historical = 0, +} + +interface IPowerLevels { + users_default?: number; + state_default?: number; + events_default?: number; + historical?: number; + invite?: number; + redact?: number; + kick?: number; + ban?: number; + + events?: Record; + users?: Record; + notifications?: Record; +} + +export function usePowerLevels(room: Room) { + const powerLevelsEvent = useStateEvent(room, StateEvent.RoomPowerLevels); + const powerLevels: IPowerLevels = powerLevelsEvent?.getContent() ?? DefaultPowerLevels; + + const getPowerLevel = useCallback( + (userId: string) => { + const { users_default: usersDefault, users } = powerLevels; + if (users && typeof users[userId] === 'number') { + return users[userId]; + } + return usersDefault ?? DefaultPowerLevels.usersDefault; + }, + [powerLevels] + ); + + const canSendEvent = useCallback( + (eventType: string | undefined, powerLevel: number) => { + const { events, events_default: eventsDefault } = powerLevels; + if (events && eventType && typeof events[eventType] === 'string') { + return powerLevel >= events[eventType]; + } + return powerLevel >= (eventsDefault ?? DefaultPowerLevels.eventsDefault); + }, + [powerLevels] + ); + + const canSendStateEvent = useCallback( + (eventType: string | undefined, powerLevel: number) => { + const { events, state_default: stateDefault } = powerLevels; + if (events && eventType && typeof events[eventType] === 'number') { + return powerLevel >= events[eventType]; + } + return powerLevel >= (stateDefault ?? DefaultPowerLevels.stateDefault); + }, + [powerLevels] + ); + + const canDoAction = useCallback( + (action: 'invite' | 'redact' | 'kick' | 'ban' | 'historical', powerLevel: number) => { + const requiredPL = powerLevels[action]; + if (typeof requiredPL === 'number') { + return powerLevel >= requiredPL; + } + return powerLevel >= DefaultPowerLevels[action]; + }, + [powerLevels] + ); + + return { + getPowerLevel, + canSendEvent, + canSendStateEvent, + canDoAction, + }; +} diff --git a/src/app/hooks/useRecentEmoji.ts b/src/app/hooks/useRecentEmoji.ts new file mode 100644 index 000000000..926075f51 --- /dev/null +++ b/src/app/hooks/useRecentEmoji.ts @@ -0,0 +1,23 @@ +import { useEffect, useState } from 'react'; +import { ClientEvent, MatrixClient, MatrixEvent } from 'matrix-js-sdk'; +import { getRecentEmojis } from '../plugins/recent-emoji'; +import { AccountDataEvent } from '../../types/matrix/accountData'; +import { IEmoji } from '../plugins/emoji'; + +export const useRecentEmoji = (mx: MatrixClient, limit?: number): IEmoji[] => { + const [recentEmoji, setRecentEmoji] = useState(() => getRecentEmojis(mx, limit)); + + useEffect(() => { + const handleAccountData = (event: MatrixEvent) => { + if (event.getType() !== AccountDataEvent.ElementRecentEmoji) return; + setRecentEmoji(getRecentEmojis(mx, limit)); + }; + + mx.on(ClientEvent.AccountData, handleAccountData); + return () => { + mx.removeListener(ClientEvent.AccountData, handleAccountData); + }; + }, [mx, limit]); + + return recentEmoji; +}; diff --git a/src/app/hooks/useResizeObserver.ts b/src/app/hooks/useResizeObserver.ts new file mode 100644 index 000000000..69ec65d06 --- /dev/null +++ b/src/app/hooks/useResizeObserver.ts @@ -0,0 +1,24 @@ +import { useEffect, useMemo } from 'react'; + +export type OnResizeCallback = (entries: ResizeObserverEntry[]) => void; + +export const getResizeObserverEntry = ( + target: Element, + entries: ResizeObserverEntry[] +): ResizeObserverEntry | undefined => entries.find((entry) => entry.target === target); + +export const useResizeObserver = ( + element: Element | null, + onResizeCallback: OnResizeCallback +): ResizeObserver => { + const resizeObserver = useMemo(() => new ResizeObserver(onResizeCallback), [onResizeCallback]); + + useEffect(() => { + if (element) resizeObserver.observe(element); + return () => { + if (element) resizeObserver.unobserve(element); + }; + }, [resizeObserver, element]); + + return resizeObserver; +}; diff --git a/src/app/hooks/useRoomMembers.ts b/src/app/hooks/useRoomMembers.ts new file mode 100644 index 000000000..544d97a08 --- /dev/null +++ b/src/app/hooks/useRoomMembers.ts @@ -0,0 +1,34 @@ +import { MatrixClient, MatrixEvent, RoomMember, RoomMemberEvent } from 'matrix-js-sdk'; +import { useEffect, useState } from 'react'; +import { useAlive } from './useAlive'; + +export const useRoomMembers = (mx: MatrixClient, roomId: string): RoomMember[] => { + const [members, setMembers] = useState([]); + const alive = useAlive(); + + useEffect(() => { + const room = mx.getRoom(roomId); + + const updateMemberList = (event?: MatrixEvent) => { + if (!room || !alive || (event && event.getRoomId() !== roomId)) return; + setMembers(room.getMembers()); + }; + + if (room) { + updateMemberList(); + room.loadMembersIfNeeded().then(() => { + if (!alive) return; + updateMemberList(); + }); + } + + mx.on(RoomMemberEvent.Membership, updateMemberList); + mx.on(RoomMemberEvent.PowerLevel, updateMemberList); + return () => { + mx.removeListener(RoomMemberEvent.Membership, updateMemberList); + mx.removeListener(RoomMemberEvent.PowerLevel, updateMemberList); + }; + }, [mx, roomId, alive]); + + return members; +}; diff --git a/src/app/hooks/useStateEvent.ts b/src/app/hooks/useStateEvent.ts new file mode 100644 index 000000000..7bc66aa2e --- /dev/null +++ b/src/app/hooks/useStateEvent.ts @@ -0,0 +1,32 @@ +import { Room } from 'matrix-js-sdk'; +import { useCallback, useMemo } from 'react'; +import { useStateEventCallback } from './useStateEventCallback'; +import { useForceUpdate } from './useForceUpdate'; +import { getStateEvent } from '../utils/room'; +import { StateEvent } from '../../types/matrix/room'; + +export const useStateEvent = (room: Room, eventType: StateEvent, stateKey = '') => { + const [updateCount, forceUpdate] = useForceUpdate(); + + useStateEventCallback( + room.client, + useCallback( + (event) => { + if ( + event.getRoomId() === room.roomId && + event.getType() === eventType && + event.getStateKey() === stateKey + ) { + forceUpdate(); + } + }, + [room, eventType, stateKey, forceUpdate] + ) + ); + + return useMemo( + () => getStateEvent(room, eventType, stateKey), + // eslint-disable-next-line react-hooks/exhaustive-deps + [room, eventType, stateKey, updateCount] + ); +}; diff --git a/src/app/hooks/useStateEventCallback.ts b/src/app/hooks/useStateEventCallback.ts new file mode 100644 index 000000000..85be3aeb1 --- /dev/null +++ b/src/app/hooks/useStateEventCallback.ts @@ -0,0 +1,17 @@ +import { MatrixClient, MatrixEvent, RoomState, RoomStateEvent } from 'matrix-js-sdk'; +import { useEffect } from 'react'; + +export type StateEventCallback = ( + event: MatrixEvent, + state: RoomState, + lastStateEvent: MatrixEvent | null +) => void; + +export const useStateEventCallback = (mx: MatrixClient, onStateEvent: StateEventCallback) => { + useEffect(() => { + mx.on(RoomStateEvent.Events, onStateEvent); + return () => { + mx.removeListener(RoomStateEvent.Events, onStateEvent); + }; + }, [mx, onStateEvent]); +}; diff --git a/src/app/hooks/useStateEvents.ts b/src/app/hooks/useStateEvents.ts new file mode 100644 index 000000000..dd0856930 --- /dev/null +++ b/src/app/hooks/useStateEvents.ts @@ -0,0 +1,28 @@ +import { useCallback, useMemo } from 'react'; +import { Room } from 'matrix-js-sdk'; +import { StateEvent } from '../../types/matrix/room'; +import { useForceUpdate } from './useForceUpdate'; +import { useStateEventCallback } from './useStateEventCallback'; +import { getStateEvents } from '../utils/room'; + +export const useStateEvents = (room: Room, eventType: StateEvent) => { + const [updateCount, forceUpdate] = useForceUpdate(); + + useStateEventCallback( + room.client, + useCallback( + (event) => { + if (event.getRoomId() === room.roomId && event.getType() === eventType) { + forceUpdate(); + } + }, + [room, eventType, forceUpdate] + ) + ); + + return useMemo( + () => getStateEvents(room, eventType), + // eslint-disable-next-line react-hooks/exhaustive-deps + [room, eventType, updateCount] + ); +}; diff --git a/src/app/hooks/useThrottle.ts b/src/app/hooks/useThrottle.ts new file mode 100644 index 000000000..12b249f29 --- /dev/null +++ b/src/app/hooks/useThrottle.ts @@ -0,0 +1,41 @@ +import { useCallback, useRef } from 'react'; + +export interface ThrottleOptions { + wait?: number; + immediate?: boolean; +} + +export type ThrottleCallback = (...args: T) => void; + +export function useThrottle( + callback: ThrottleCallback, + options?: ThrottleOptions +): ThrottleCallback { + const timeoutIdRef = useRef(); + const argsRef = useRef(); + const { wait, immediate } = options ?? {}; + + const debounceCallback = useCallback( + (...cbArgs: T) => { + argsRef.current = cbArgs; + + if (timeoutIdRef.current) { + return; + } + if (immediate) { + callback(...cbArgs); + } + + timeoutIdRef.current = window.setTimeout(() => { + if (argsRef.current) { + callback(...argsRef.current); + } + argsRef.current = undefined; + timeoutIdRef.current = undefined; + }, wait); + }, + [callback, wait, immediate] + ); + + return debounceCallback; +} diff --git a/src/app/hooks/useTypingStatusUpdater.ts b/src/app/hooks/useTypingStatusUpdater.ts new file mode 100644 index 000000000..af76eae7e --- /dev/null +++ b/src/app/hooks/useTypingStatusUpdater.ts @@ -0,0 +1,42 @@ +import { MatrixClient } from 'matrix-js-sdk'; +import { useMemo, useRef } from 'react'; + +type TypingStatusUpdater = (typing: boolean) => void; + +const TYPING_TIMEOUT_MS = 5000; // 5 seconds + +export const useTypingStatusUpdater = (mx: MatrixClient, roomId: string): TypingStatusUpdater => { + const statusSentTsRef = useRef(0); + + const sendTypingStatus: TypingStatusUpdater = useMemo(() => { + statusSentTsRef.current = 0; + return (typing) => { + if (typing) { + if (Date.now() - statusSentTsRef.current < TYPING_TIMEOUT_MS) { + return; + } + + mx.sendTyping(roomId, true, TYPING_TIMEOUT_MS); + const sentTs = Date.now(); + statusSentTsRef.current = sentTs; + + // Don't believe server will timeout typing status; + // Clear typing status after timeout if already not; + setTimeout(() => { + if (statusSentTsRef.current === sentTs) { + mx.sendTyping(roomId, false, TYPING_TIMEOUT_MS); + statusSentTsRef.current = 0; + } + }, TYPING_TIMEOUT_MS); + return; + } + + if (Date.now() - statusSentTsRef.current < TYPING_TIMEOUT_MS) { + mx.sendTyping(roomId, false, TYPING_TIMEOUT_MS); + } + statusSentTsRef.current = 0; + }; + }, [mx, roomId]); + + return sendTypingStatus; +}; diff --git a/src/app/molecules/following-members/FollowingMembers.jsx b/src/app/molecules/following-members/FollowingMembers.jsx index 652965353..949dac76a 100644 --- a/src/app/molecules/following-members/FollowingMembers.jsx +++ b/src/app/molecules/following-members/FollowingMembers.jsx @@ -17,38 +17,40 @@ function FollowingMembers({ roomTimeline }) { const [followingMembers, setFollowingMembers] = useState([]); const { roomId } = roomTimeline; const mx = initMatrix.matrixClient; - const { roomsInput } = initMatrix; const myUserId = mx.getUserId(); - const handleOnMessageSent = () => setFollowingMembers([]); - useEffect(() => { const updateFollowingMembers = () => { setFollowingMembers(roomTimeline.getLiveReaders()); }; + const updateOnEvent = (event, room) => { + if (room.roomId !== roomId) return; + setFollowingMembers(roomTimeline.getLiveReaders()); + }; updateFollowingMembers(); roomTimeline.on(cons.events.roomTimeline.LIVE_RECEIPT, updateFollowingMembers); - roomsInput.on(cons.events.roomsInput.MESSAGE_SENT, handleOnMessageSent); + mx.on('Room.timeline', updateOnEvent); return () => { roomTimeline.removeListener(cons.events.roomTimeline.LIVE_RECEIPT, updateFollowingMembers); - roomsInput.removeListener(cons.events.roomsInput.MESSAGE_SENT, handleOnMessageSent); + mx.removeListener('Room.timeline', updateOnEvent); }; - }, [roomTimeline]); + }, [roomTimeline, roomId]); const filteredM = followingMembers.filter((userId) => userId !== myUserId); - return filteredM.length !== 0 && ( - + return ( + filteredM.length !== 0 && ( + + ) ); } diff --git a/src/app/organisms/drag-drop/DragDrop.jsx b/src/app/organisms/drag-drop/DragDrop.jsx deleted file mode 100644 index e92f8a703..000000000 --- a/src/app/organisms/drag-drop/DragDrop.jsx +++ /dev/null @@ -1,24 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import './DragDrop.scss'; - -import RawModal from '../../atoms/modal/RawModal'; -import Text from '../../atoms/text/Text'; - -function DragDrop({ isOpen }) { - return ( - - Drop file to upload - - ); -} - -DragDrop.propTypes = { - isOpen: PropTypes.bool.isRequired, -}; - -export default DragDrop; diff --git a/src/app/organisms/drag-drop/DragDrop.scss b/src/app/organisms/drag-drop/DragDrop.scss deleted file mode 100644 index 2e5b4f512..000000000 --- a/src/app/organisms/drag-drop/DragDrop.scss +++ /dev/null @@ -1,12 +0,0 @@ -.drag-drop__modal { - box-shadow: none; - text-align: center; - - .text { - color: white; - } -} - -.drag-drop__overlay { - background-color: var(--bg-overlay-low); -} diff --git a/src/app/organisms/navigation/SideBar.scss b/src/app/organisms/navigation/SideBar.scss index 6ff66288a..401947a41 100644 --- a/src/app/organisms/navigation/SideBar.scss +++ b/src/app/organisms/navigation/SideBar.scss @@ -7,10 +7,7 @@ width: var(--navigation-sidebar-width); height: 100%; background-color: var(--bg-surface-extra-low); - @include dir.side(border, - none, - 1px solid var(--bg-surface-border), - ); + @include dir.side(border, none, 1px solid var(--bg-surface-border)); &__scrollable, &__sticky { @@ -24,7 +21,7 @@ .scrollable-content { &::after { - content: ""; + content: ''; display: block; width: 100%; height: 8px; @@ -33,7 +30,8 @@ background-image: linear-gradient( to top, var(--bg-surface-extra-low), - var(--bg-surface-extra-low-transparent)); + var(--bg-surface-extra-low-transparent) + ); position: sticky; bottom: -1px; left: 0; @@ -44,7 +42,7 @@ .space-container, .sticky-container { @extend .cp-fx__column--c-c; - + padding: var(--sp-ultra-tight) 0; & > .sidebar-avatar, @@ -63,7 +61,7 @@ box-shadow: var(--bs-danger-border); animation-name: pushRight; animation-duration: 400ms; - animation-iteration-count: infinite; + animation-iteration-count: 30; animation-direction: alternate; } @@ -74,4 +72,4 @@ to { transform: translateX(0) scale(1); } -} \ No newline at end of file +} diff --git a/src/app/organisms/navigation/Sidebar1.tsx b/src/app/organisms/navigation/Sidebar1.tsx new file mode 100644 index 000000000..d9ee4662b --- /dev/null +++ b/src/app/organisms/navigation/Sidebar1.tsx @@ -0,0 +1,125 @@ +import React from 'react'; +import { Icon, Icons, Badge, AvatarFallback, Text } from 'folds'; +import { useAtom } from 'jotai'; + +import { + Sidebar, + SidebarContent, + SidebarStackSeparator, + SidebarStack, + SidebarAvatar, +} from '../../components/sidebar'; +import { selectedTabAtom, SidebarTab } from '../../state/selectedTab'; + +export function Sidebar1() { + const [selectedTab, setSelectedTab] = useAtom(selectedTabAtom); + + return ( + + + + } + onClick={() => setSelectedTab(SidebarTab.Home)} + /> + } + onClick={() => setSelectedTab(SidebarTab.People)} + /> + + + + ( + + )} + avatarChildren={ + + B + + } + /> + ( + + 64 + + )} + avatarChildren={ + + C + + } + /> + + + + } + /> + } + /> + + + } + sticky={ + <> + + + } + /> + + A + + } + /> + + + } + /> + + ); +} diff --git a/src/app/organisms/room/Room.jsx b/src/app/organisms/room/Room.jsx index 447686af8..9d861c962 100644 --- a/src/app/organisms/room/Room.jsx +++ b/src/app/organisms/room/Room.jsx @@ -15,6 +15,7 @@ import PeopleDrawer from './PeopleDrawer'; function Room() { const [roomInfo, setRoomInfo] = useState({ + room: null, roomTimeline: null, eventId: null, }); @@ -25,14 +26,17 @@ function Room() { useEffect(() => { const handleRoomSelected = (rId, pRoomId, eId) => { roomInfo.roomTimeline?.removeInternalListeners(); - if (mx.getRoom(rId)) { + const r = mx.getRoom(rId); + if (r) { setRoomInfo({ + room: r, roomTimeline: new RoomTimeline(rId), eventId: eId ?? null, }); } else { // TODO: add ability to join room if roomId is invalid setRoomInfo({ + room: r, roomTimeline: null, eventId: null, }); @@ -43,7 +47,7 @@ function Room() { return () => { navigation.removeListener(cons.events.navigation.ROOM_SELECTED, handleRoomSelected); }; - }, [roomInfo]); + }, [roomInfo, mx]); useEffect(() => { const handleDrawerToggling = (visiblity) => setIsDrawer(visiblity); @@ -53,7 +57,7 @@ function Room() { }; }, []); - const { roomTimeline, eventId } = roomInfo; + const { room, roomTimeline, eventId } = roomInfo; if (roomTimeline === null) { setTimeout(() => openNavigation()); return ; @@ -63,7 +67,7 @@ function Room() {
      - +
      {isDrawer && }
      diff --git a/src/app/organisms/room/RoomInput.tsx b/src/app/organisms/room/RoomInput.tsx new file mode 100644 index 000000000..17830ad98 --- /dev/null +++ b/src/app/organisms/room/RoomInput.tsx @@ -0,0 +1,539 @@ +import React, { + KeyboardEventHandler, + RefObject, + forwardRef, + useCallback, + useEffect, + useMemo, + useRef, + useState, +} from 'react'; +import { useAtom } from 'jotai'; +import isHotkey from 'is-hotkey'; +import { EventType, IContent, MsgType, Room } from 'matrix-js-sdk'; +import { ReactEditor } from 'slate-react'; +import { Transforms, Range, Editor, Element } from 'slate'; +import { + Box, + Dialog, + Icon, + IconButton, + Icons, + Overlay, + OverlayBackdrop, + OverlayCenter, + PopOut, + Scroll, + Text, + config, + toRem, +} from 'folds'; +import to from 'await-to-js'; + +import { useMatrixClient } from '../../hooks/useMatrixClient'; +import { + CustomEditor, + EditorChangeHandler, + useEditor, + Toolbar, + toMatrixCustomHTML, + toPlainText, + AUTOCOMPLETE_PREFIXES, + AutocompletePrefix, + AutocompleteQuery, + getAutocompleteQuery, + getPrevWorldRange, + resetEditor, + RoomMentionAutocomplete, + UserMentionAutocomplete, + EmoticonAutocomplete, + createEmoticonElement, + moveCursor, +} from '../../components/editor'; +import { EmojiBoard, EmojiBoardTab } from '../../components/emoji-board'; +import { UseStateProvider } from '../../components/UseStateProvider'; +import initMatrix from '../../../client/initMatrix'; +import { TUploadContent, encryptFile, getImageInfo } from '../../utils/matrix'; +import { useTypingStatusUpdater } from '../../hooks/useTypingStatusUpdater'; +import { useFilePicker } from '../../hooks/useFilePicker'; +import { useFilePasteHandler } from '../../hooks/useFilePasteHandler'; +import { useFileDropZone } from '../../hooks/useFileDrop'; +import { + TUploadItem, + roomIdToMsgDraftAtomFamily, + roomIdToReplyDraftAtomFamily, + roomIdToUploadItemsAtomFamily, + roomUploadAtomFamily, +} from '../../state/roomInputDrafts'; +import { UploadCardRenderer } from '../../components/upload-card'; +import { + UploadBoard, + UploadBoardContent, + UploadBoardHeader, + UploadBoardImperativeHandlers, +} from '../../components/upload-board'; +import { + Upload, + UploadStatus, + UploadSuccess, + createUploadFamilyObserverAtom, +} from '../../state/upload'; +import { getImageUrlBlob, loadImageElement } from '../../utils/dom'; +import { safeFile } from '../../utils/mimeTypes'; +import { fulfilledPromiseSettledResult } from '../../utils/common'; +import { useSetting } from '../../state/hooks/settings'; +import { settingsAtom } from '../../state/settings'; +import { + getAudioMsgContent, + getFileMsgContent, + getImageMsgContent, + getVideoMsgContent, +} from './msgContent'; +import navigation from '../../../client/state/navigation'; +import cons from '../../../client/state/cons'; +import { MessageReply } from '../../molecules/message/Message'; +import colorMXID from '../../../util/colorMXID'; +import { parseReplyBody, parseReplyFormattedBody } from '../../utils/room'; +import { sanitizeText } from '../../utils/sanitize'; + +interface RoomInputProps { + roomViewRef: RefObject; + roomId: string; +} +export const RoomInput = forwardRef( + ({ roomViewRef, roomId }, ref) => { + const mx = useMatrixClient(); + const editor = useEditor(); + const room = mx.getRoom(roomId); + + const [msgDraft, setMsgDraft] = useAtom(roomIdToMsgDraftAtomFamily(roomId)); + const [replyDraft, setReplyDraft] = useAtom(roomIdToReplyDraftAtomFamily(roomId)); + const [uploadBoard, setUploadBoard] = useState(true); + const [selectedFiles, setSelectedFiles] = useAtom(roomIdToUploadItemsAtomFamily(roomId)); + const uploadFamilyObserverAtom = createUploadFamilyObserverAtom( + roomUploadAtomFamily, + selectedFiles.map((f) => f.file) + ); + const uploadBoardHandlers = useRef(); + + const imagePackRooms: Room[] = useMemo(() => { + const allParentSpaces = [roomId, ...(initMatrix.roomList?.getAllParentSpaces(roomId) ?? [])]; + return allParentSpaces.reduce((list, rId) => { + const r = mx.getRoom(rId); + if (r) list.push(r); + return list; + }, []); + }, [mx, roomId]); + + const [toolbar, setToolbar] = useSetting(settingsAtom, 'editorToolbar'); + const [autocompleteQuery, setAutocompleteQuery] = + useState>(); + + const sendTypingStatus = useTypingStatusUpdater(mx, roomId); + + const handleFiles = useCallback( + async (files: File[]) => { + setUploadBoard(true); + const safeFiles = files.map(safeFile); + const fileItems: TUploadItem[] = []; + + if (mx.isRoomEncrypted(roomId)) { + const encryptFiles = fulfilledPromiseSettledResult( + await Promise.allSettled(safeFiles.map((f) => encryptFile(f))) + ); + encryptFiles.forEach((ef) => fileItems.push(ef)); + } else { + safeFiles.forEach((f) => + fileItems.push({ file: f, originalFile: f, encInfo: undefined }) + ); + } + setSelectedFiles({ + type: 'PUT', + item: fileItems, + }); + }, + [setSelectedFiles, roomId, mx] + ); + const pickFile = useFilePicker(handleFiles, true); + const handlePaste = useFilePasteHandler(handleFiles); + const dropZoneVisible = useFileDropZone(roomViewRef, handleFiles); + + useEffect(() => { + Transforms.insertFragment(editor, msgDraft); + }, [editor, msgDraft]); + + useEffect(() => { + ReactEditor.focus(editor); + return () => { + const parsedDraft = JSON.parse(JSON.stringify(editor.children)); + setMsgDraft(parsedDraft); + resetEditor(editor); + }; + }, [roomId, editor, setMsgDraft]); + + useEffect(() => { + const handleReplyTo = ( + userId: string, + eventId: string, + body: string, + formattedBody: string + ) => { + setReplyDraft({ + userId, + eventId, + body, + formattedBody, + }); + }; + navigation.on(cons.events.navigation.REPLY_TO_CLICKED, handleReplyTo); + return () => { + navigation.removeListener(cons.events.navigation.REPLY_TO_CLICKED, handleReplyTo); + }; + }, [setReplyDraft]); + + const handleRemoveUpload = useCallback( + (upload: TUploadContent | TUploadContent[]) => { + const uploads = Array.isArray(upload) ? upload : [upload]; + setSelectedFiles({ + type: 'DELETE', + item: selectedFiles.filter((f) => uploads.find((u) => u === f.file)), + }); + uploads.forEach((u) => roomUploadAtomFamily.remove(u)); + }, + [setSelectedFiles, selectedFiles] + ); + + const handleCancelUpload = (uploads: Upload[]) => { + uploads.forEach((upload) => { + if (upload.status === UploadStatus.Loading) { + mx.cancelUpload(upload.promise); + } + }); + handleRemoveUpload(uploads.map((upload) => upload.file)); + }; + + const handleSendUpload = async (uploads: UploadSuccess[]) => { + const sendPromises = uploads.map(async (upload) => { + const fileItem = selectedFiles.find((f) => f.file === upload.file); + if (fileItem && fileItem.file.type.startsWith('image')) { + const [imgError, imgContent] = await to(getImageMsgContent(fileItem, upload.mxc)); + if (imgError) console.warn(imgError); + if (imgContent) mx.sendMessage(roomId, imgContent); + return; + } + if (fileItem && fileItem.file.type.startsWith('video')) { + const [videoError, videoContent] = await to(getVideoMsgContent(mx, fileItem, upload.mxc)); + if (videoError) console.warn(videoError); + if (videoContent) mx.sendMessage(roomId, videoContent); + return; + } + if (fileItem && fileItem.file.type.startsWith('audio')) { + mx.sendMessage(roomId, getAudioMsgContent(fileItem, upload.mxc)); + return; + } + if (fileItem) { + mx.sendMessage(roomId, getFileMsgContent(fileItem, upload.mxc)); + } + }); + handleCancelUpload(uploads); + await Promise.allSettled(sendPromises); + }; + + const submit = useCallback(() => { + uploadBoardHandlers.current?.handleSend(); + + const plainText = toPlainText(editor.children).trim(); + const customHtml = toMatrixCustomHTML(editor.children); + + if (plainText === '') return; + + let body = plainText; + let formattedBody = customHtml; + if (replyDraft) { + body = parseReplyBody(replyDraft.userId, replyDraft.userId) + body; + formattedBody = + parseReplyFormattedBody( + roomId, + replyDraft.userId, + replyDraft.eventId, + replyDraft.formattedBody ?? sanitizeText(replyDraft.body) + ) + formattedBody; + } + + const content: IContent = { + msgtype: MsgType.Text, + body, + format: 'org.matrix.custom.html', + formatted_body: formattedBody, + }; + if (replyDraft) { + content['m.relates_to'] = { + 'm.in_reply_to': { + event_id: replyDraft.eventId, + }, + }; + } + mx.sendMessage(roomId, content); + resetEditor(editor); + setReplyDraft(); + sendTypingStatus(false); + }, [mx, roomId, editor, replyDraft, sendTypingStatus, setReplyDraft]); + + const handleKeyDown: KeyboardEventHandler = useCallback( + (evt) => { + const { selection } = editor; + if (isHotkey('enter', evt)) { + evt.preventDefault(); + submit(); + } + if (isHotkey('escape', evt)) { + evt.preventDefault(); + setReplyDraft(); + } + if (selection && Range.isCollapsed(selection)) { + if (isHotkey('arrowleft', evt)) { + evt.preventDefault(); + Transforms.move(editor, { unit: 'offset', reverse: true }); + } + if (isHotkey('arrowright', evt)) { + evt.preventDefault(); + Transforms.move(editor, { unit: 'offset' }); + } + } + }, + [submit, editor, setReplyDraft] + ); + + const handleChange: EditorChangeHandler = (value) => { + const prevWordRange = getPrevWorldRange(editor); + const query = prevWordRange + ? getAutocompleteQuery(editor, prevWordRange, AUTOCOMPLETE_PREFIXES) + : undefined; + + setAutocompleteQuery(query); + + const descendant = value[0]; + if (descendant && Element.isElement(descendant)) { + const isEmpty = value.length === 1 && Editor.isEmpty(editor, descendant); + sendTypingStatus(!isEmpty); + } + }; + + const handleEmoticonSelect = (key: string, shortcode: string) => { + editor.insertNode(createEmoticonElement(key, shortcode)); + moveCursor(editor); + }; + + const handleStickerSelect = async (mxc: string, shortcode: string) => { + const stickerUrl = mx.mxcUrlToHttp(mxc); + if (!stickerUrl) return; + + const info = await getImageInfo( + await loadImageElement(stickerUrl), + await getImageUrlBlob(stickerUrl) + ); + + mx.sendEvent(roomId, EventType.Sticker, { + body: shortcode, + url: mxc, + info, + }); + }; + + return ( +
      + {selectedFiles.length > 0 && ( + setUploadBoard(!uploadBoard)} + uploadFamilyObserverAtom={uploadFamilyObserverAtom} + onSend={handleSendUpload} + imperativeHandlerRef={uploadBoardHandlers} + onCancel={handleCancelUpload} + /> + } + > + {uploadBoard && ( + + + {Array.from(selectedFiles) + .reverse() + .map((fileItem, index) => ( + + ))} + + + )} + + )} + } + style={{ pointerEvents: 'none' }} + > + + + + + + {`Drop Files in "${room?.name || 'Room'}"`} + + Drag and drop files here or click for selection dialog + + + + + {autocompleteQuery?.prefix === AutocompletePrefix.RoomMention && ( + setAutocompleteQuery(undefined)} + /> + )} + {autocompleteQuery?.prefix === AutocompletePrefix.UserMention && ( + setAutocompleteQuery(undefined)} + /> + )} + {autocompleteQuery?.prefix === AutocompletePrefix.Emoticon && ( + setAutocompleteQuery(undefined)} + /> + )} + + + setReplyDraft()} + variant="SurfaceVariant" + size="300" + radii="300" + > + + + + +
      + ) + } + before={ + pickFile('*')} + variant="SurfaceVariant" + size="300" + radii="300" + > + + + } + after={ + <> + setToolbar(!toolbar)} + > + + + + {(emojiBoardTab: EmojiBoardTab | undefined, setEmojiBoardTab) => ( + { + setEmojiBoardTab(undefined); + ReactEditor.focus(editor); + }} + /> + } + > + {(anchorRef) => ( + <> + setEmojiBoardTab(EmojiBoardTab.Sticker)} + variant="SurfaceVariant" + size="300" + radii="300" + > + + + setEmojiBoardTab(EmojiBoardTab.Emoji)} + variant="SurfaceVariant" + size="300" + radii="300" + > + + + + )} + + )} + + + + + + } + bottom={toolbar && } + /> + + ); + } +); diff --git a/src/app/organisms/room/RoomInputPlaceholder.css.ts b/src/app/organisms/room/RoomInputPlaceholder.css.ts new file mode 100644 index 000000000..d0873dad1 --- /dev/null +++ b/src/app/organisms/room/RoomInputPlaceholder.css.ts @@ -0,0 +1,10 @@ +import { style } from '@vanilla-extract/css'; +import { color, config, toRem } from 'folds'; + +export const RoomInputPlaceholder = style({ + minHeight: toRem(48), + backgroundColor: color.SurfaceVariant.Container, + color: color.SurfaceVariant.OnContainer, + boxShadow: `inset 0 0 0 ${config.borderWidth.B300} ${color.SurfaceVariant.ContainerLine}`, + borderRadius: config.radii.R400, +}); diff --git a/src/app/organisms/room/RoomInputPlaceholder.tsx b/src/app/organisms/room/RoomInputPlaceholder.tsx new file mode 100644 index 000000000..77c7ccf36 --- /dev/null +++ b/src/app/organisms/room/RoomInputPlaceholder.tsx @@ -0,0 +1,11 @@ +import React, { ComponentProps } from 'react'; +import { Box, as } from 'folds'; +import classNames from 'classnames'; + +import * as css from './RoomInputPlaceholder.css'; + +export const RoomInputPlaceholder = as<'div', ComponentProps>( + ({ className, ...props }, ref) => ( + + ) +); diff --git a/src/app/organisms/room/RoomTombstone.css.ts b/src/app/organisms/room/RoomTombstone.css.ts new file mode 100644 index 000000000..c4c04612c --- /dev/null +++ b/src/app/organisms/room/RoomTombstone.css.ts @@ -0,0 +1,7 @@ +import { style } from '@vanilla-extract/css'; +import { config } from 'folds'; + +export const RoomTombstone = style({ + padding: config.space.S200, + paddingLeft: config.space.S400, +}); diff --git a/src/app/organisms/room/RoomTombstone.tsx b/src/app/organisms/room/RoomTombstone.tsx new file mode 100644 index 000000000..39f0e635c --- /dev/null +++ b/src/app/organisms/room/RoomTombstone.tsx @@ -0,0 +1,67 @@ +import React, { useCallback } from 'react'; +import { Box, Button, Spinner, Text, color } from 'folds'; + +import { selectRoom } from '../../../client/action/navigation'; + +import * as css from './RoomTombstone.css'; +import { useMatrixClient } from '../../hooks/useMatrixClient'; +import { genRoomVia } from '../../../util/matrixUtil'; +import { AsyncStatus, useAsyncCallback } from '../../hooks/useAsyncCallback'; +import { Membership } from '../../../types/matrix/room'; +import { RoomInputPlaceholder } from './RoomInputPlaceholder'; + +type RoomTombstoneProps = { roomId: string; body?: string; replacementRoomId: string }; +export function RoomTombstone({ roomId, body, replacementRoomId }: RoomTombstoneProps) { + const mx = useMatrixClient(); + + const [joinState, handleJoin] = useAsyncCallback( + useCallback(() => { + const currentRoom = mx.getRoom(roomId); + const via = currentRoom ? genRoomVia(currentRoom) : []; + return mx.joinRoom(replacementRoomId, { + viaServers: via, + }); + }, [mx, roomId, replacementRoomId]) + ); + const replacementRoom = mx.getRoom(replacementRoomId); + + const handleOpen = () => { + if (replacementRoom) selectRoom(replacementRoom.roomId); + if (joinState.status === AsyncStatus.Success) selectRoom(joinState.data.roomId); + }; + + return ( + + + {body || 'This room has been replaced and is no longer active.'} + {joinState.status === AsyncStatus.Error && ( + + {(joinState.error as any)?.message ?? 'Failed to join replacement room!'} + + )} + + {replacementRoom?.getMyMembership() === Membership.Join || + joinState.status === AsyncStatus.Success ? ( + + ) : ( + + )} + + ); +} diff --git a/src/app/organisms/room/RoomView.jsx b/src/app/organisms/room/RoomView.jsx index b94c35c48..591fcceae 100644 --- a/src/app/organisms/room/RoomView.jsx +++ b/src/app/organisms/room/RoomView.jsx @@ -1,6 +1,7 @@ import React, { useEffect, useRef } from 'react'; import PropTypes from 'prop-types'; import './RoomView.scss'; +import { Text, config } from 'folds'; import EventEmitter from 'events'; @@ -10,16 +11,29 @@ import navigation from '../../../client/state/navigation'; import RoomViewHeader from './RoomViewHeader'; import RoomViewContent from './RoomViewContent'; import RoomViewFloating from './RoomViewFloating'; -import RoomViewInput from './RoomViewInput'; import RoomViewCmdBar from './RoomViewCmdBar'; +import { RoomInput } from './RoomInput'; +import { useStateEvent } from '../../hooks/useStateEvent'; +import { StateEvent } from '../../../types/matrix/room'; +import { RoomTombstone } from './RoomTombstone'; +import { usePowerLevels } from '../../hooks/usePowerLevels'; +import { useMatrixClient } from '../../hooks/useMatrixClient'; +import { RoomInputPlaceholder } from './RoomInputPlaceholder'; const viewEvent = new EventEmitter(); -function RoomView({ roomTimeline, eventId }) { +function RoomView({ room, roomTimeline, eventId }) { + const roomInputRef = useRef(null); const roomViewRef = useRef(null); // eslint-disable-next-line react/prop-types const { roomId } = roomTimeline; + const mx = useMatrixClient(); + const tombstoneEvent = useStateEvent(room, StateEvent.RoomTombstone); + const { getPowerLevel, canSendEvent } = usePowerLevels(room); + const myUserId = mx.getUserId(); + const canMessage = myUserId ? canSendEvent(undefined, getPowerLevel(myUserId)) : false; + useEffect(() => { const settingsToggle = (isVisible) => { const roomView = roomViewRef.current; @@ -47,23 +61,36 @@ function RoomView({ roomTimeline, eventId }) { - +
      - - +
      + {tombstoneEvent ? ( + + ) : ( + <> + {canMessage && ( + + )} + {!canMessage && ( + + You do not have permission to post in this room + + )} + + )} +
      +
      @@ -74,6 +101,7 @@ RoomView.defaultProps = { eventId: null, }; RoomView.propTypes = { + room: PropTypes.shape({}).isRequired, roomTimeline: PropTypes.shape({}).isRequired, eventId: PropTypes.string, }; diff --git a/src/app/organisms/room/RoomView.scss b/src/app/organisms/room/RoomView.scss index 4f06bf262..c70c2b092 100644 --- a/src/app/organisms/room/RoomView.scss +++ b/src/app/organisms/room/RoomView.scss @@ -35,11 +35,12 @@ @extend .cp-fx__item-one; position: relative; } - + &__sticky { - min-height: 85px; position: relative; background: var(--bg-surface); - border-top: 1px solid var(--bg-surface-border); } -} \ No newline at end of file + &__editor { + padding: 0 var(--sp-normal); + } +} diff --git a/src/app/organisms/room/RoomViewContent.jsx b/src/app/organisms/room/RoomViewContent.jsx index 0a9256ceb..fe598bf62 100644 --- a/src/app/organisms/room/RoomViewContent.jsx +++ b/src/app/organisms/room/RoomViewContent.jsx @@ -28,6 +28,7 @@ import { useForceUpdate } from '../../hooks/useForceUpdate'; import { parseTimelineChange } from './common'; import TimelineScroll from './TimelineScroll'; import EventLimit from './EventLimit'; +import { getResizeObserverEntry, useResizeObserver } from '../../hooks/useResizeObserver'; const PAG_LIMIT = 30; const MAX_MSG_DIFF_MINUTES = 5; @@ -392,7 +393,7 @@ function useEventArrive(roomTimeline, readUptoEvtStore, timelineScrollRef, event let jumpToItemIndex = -1; -function RoomViewContent({ eventId, roomTimeline }) { +function RoomViewContent({ roomInputRef, eventId, roomTimeline }) { const [throttle] = useState(new Throttle()); const timelineSVRef = useRef(null); @@ -484,6 +485,21 @@ function RoomViewContent({ eventId, roomTimeline }) { } }, [newEvent]); + useResizeObserver( + roomInputRef.current, + useCallback((entries) => { + if (!roomInputRef.current) return; + const editorBaseEntry = getResizeObserverEntry(roomInputRef.current, entries); + if (!editorBaseEntry) return; + + const timelineScroll = timelineScrollRef.current; + if (!roomTimeline.initialized) return; + if (timelineScroll.bottom < 40 && !roomTimeline.canPaginateForward() && document.visibilityState === 'visible') { + timelineScroll.scrollToBottom(); + } + }, [roomInputRef]) + ); + const listenKeyboard = useCallback((event) => { if (event.ctrlKey || event.altKey || event.metaKey) return; if (event.key !== 'ArrowUp') return; @@ -620,6 +636,9 @@ RoomViewContent.defaultProps = { RoomViewContent.propTypes = { eventId: PropTypes.string, roomTimeline: PropTypes.shape({}).isRequired, + roomInputRef: PropTypes.shape({ + current: PropTypes.shape({}) + }).isRequired }; export default RoomViewContent; diff --git a/src/app/organisms/room/msgContent.ts b/src/app/organisms/room/msgContent.ts new file mode 100644 index 000000000..2b0c50edb --- /dev/null +++ b/src/app/organisms/room/msgContent.ts @@ -0,0 +1,148 @@ +import { IContent, MatrixClient, MsgType } from 'matrix-js-sdk'; +import to from 'await-to-js'; +import { IThumbnailContent } from '../../../types/matrix/common'; +import { + getImageFileUrl, + getThumbnail, + getThumbnailDimensions, + getVideoFileUrl, + loadImageElement, + loadVideoElement, +} from '../../utils/dom'; +import { encryptFile, getImageInfo, getThumbnailContent, getVideoInfo } from '../../utils/matrix'; +import { TUploadItem } from '../../state/roomInputDrafts'; +import { MATRIX_BLUR_HASH_PROPERTY_NAME, encodeBlurHash } from '../../utils/blurHash'; + +const generateThumbnailContent = async ( + mx: MatrixClient, + img: HTMLImageElement | HTMLVideoElement, + dimensions: [number, number], + encrypt: boolean +): Promise => { + const thumbnail = await getThumbnail(img, ...dimensions); + if (!thumbnail) throw new Error('Can not create thumbnail!'); + const encThumbData = encrypt ? await encryptFile(thumbnail) : undefined; + const thumbnailFile = encThumbData?.file ?? thumbnail; + if (!thumbnailFile) throw new Error('Can not create thumbnail!'); + + const data = await mx.uploadContent(thumbnailFile); + const thumbMxc = data?.content_uri; + if (!thumbMxc) throw new Error('Failed when uploading thumbnail!'); + const thumbnailContent = getThumbnailContent({ + thumbnail: thumbnailFile, + encInfo: encThumbData?.encInfo, + mxc: thumbMxc, + width: dimensions[0], + height: dimensions[1], + }); + return thumbnailContent; +}; + +export const getImageMsgContent = async (item: TUploadItem, mxc: string): Promise => { + const { file, originalFile, encInfo } = item; + const [imgError, imgEl] = await to(loadImageElement(getImageFileUrl(originalFile))); + if (imgError) console.warn(imgError); + + const content: IContent = { + msgtype: MsgType.Image, + body: file.name, + }; + if (imgEl) { + content.info = { + ...getImageInfo(imgEl, file), + [MATRIX_BLUR_HASH_PROPERTY_NAME]: encodeBlurHash(imgEl), + }; + } + if (encInfo) { + content.file = { + ...encInfo, + url: mxc, + }; + } else { + content.url = mxc; + } + return content; +}; + +export const getVideoMsgContent = async ( + mx: MatrixClient, + item: TUploadItem, + mxc: string +): Promise => { + const { file, originalFile, encInfo } = item; + + const [videoError, videoEl] = await to(loadVideoElement(getVideoFileUrl(originalFile))); + if (videoError) console.warn(videoError); + + const content: IContent = { + msgtype: MsgType.Video, + body: file.name, + }; + if (videoEl) { + const [thumbError, thumbContent] = await to( + generateThumbnailContent( + mx, + videoEl, + getThumbnailDimensions(videoEl.videoWidth, videoEl.videoHeight), + !!encInfo + ) + ); + if (thumbError) console.warn(thumbError); + content.info = { + ...getVideoInfo(videoEl, file), + ...thumbContent, + }; + } + if (encInfo) { + content.file = { + ...encInfo, + url: mxc, + }; + } else { + content.url = mxc; + } + return content; +}; + +export const getAudioMsgContent = (item: TUploadItem, mxc: string): IContent => { + const { file, encInfo } = item; + const content: IContent = { + msgtype: MsgType.Audio, + body: file.name, + info: { + mimetype: file.type, + size: file.size, + }, + }; + if (encInfo) { + content.file = { + ...encInfo, + url: mxc, + }; + } else { + content.url = mxc; + } + return content; +}; + +export const getFileMsgContent = (item: TUploadItem, mxc: string): IContent => { + const { file, encInfo } = item; + const content: IContent = { + msgtype: MsgType.File, + body: file.name, + filename: file.name, + info: { + mimetype: file.type, + size: file.size, + }, + }; + if (encInfo) { + content.file = { + ...encInfo, + url: mxc, + }; + } else { + content.url = mxc; + } + return content; +}; diff --git a/src/app/pages/App.jsx b/src/app/pages/App.jsx index af7cc29b0..2828d7be8 100644 --- a/src/app/pages/App.jsx +++ b/src/app/pages/App.jsx @@ -1,4 +1,5 @@ -import React from 'react'; +import React, { StrictMode } from 'react'; +import { Provider } from 'jotai'; import { isAuthenticated } from '../../client/state/auth'; @@ -6,7 +7,11 @@ import Auth from '../templates/auth/Auth'; import Client from '../templates/client/Client'; function App() { - return isAuthenticated() ? : ; + return ( + + {isAuthenticated() ? : } + + ); } export default App; diff --git a/src/app/plugins/custom-emoji.ts b/src/app/plugins/custom-emoji.ts new file mode 100644 index 000000000..daceef44b --- /dev/null +++ b/src/app/plugins/custom-emoji.ts @@ -0,0 +1,293 @@ +import { IImageInfo, MatrixClient, Room } from 'matrix-js-sdk'; +import { AccountDataEvent } from '../../types/matrix/accountData'; +import { getAccountData, getStateEvents } from '../utils/room'; +import { StateEvent } from '../../types/matrix/room'; + +// https://github.com/Sorunome/matrix-doc/blob/soru/emotes/proposals/2545-emotes.md + +export type PackEventIdToUnknown = Record; +export type EmoteRoomIdToPackEvents = Record; +export type EmoteRoomsContent = { + rooms?: EmoteRoomIdToPackEvents; +}; + +export enum PackUsage { + Emoticon = 'emoticon', + Sticker = 'sticker', +} + +export type PackImage = { + url: string; + body?: string; + usage?: PackUsage[]; + info?: IImageInfo; +}; + +export type PackImages = Record; + +export type PackMeta = { + display_name?: string; + avatar_url?: string; + attribution?: string; + usage?: PackUsage[]; +}; + +export type ExtendedPackImage = PackImage & { + shortcode: string; +}; + +export type PackContent = { + pack?: PackMeta; + images?: PackImages; +}; + +export class ImagePack { + public id: string; + + public content: PackContent; + + public displayName?: string; + + public avatarUrl?: string; + + public usage?: PackUsage[]; + + public attribution?: string; + + public images: Map; + + public emoticons: ExtendedPackImage[]; + + public stickers: ExtendedPackImage[]; + + static parsePack(eventId: string, packContent: PackContent) { + if (!eventId || typeof packContent?.images !== 'object') { + return undefined; + } + + return new ImagePack(eventId, packContent); + } + + constructor(eventId: string, content: PackContent) { + this.id = eventId; + this.content = JSON.parse(JSON.stringify(content)); + + this.images = new Map(); + this.emoticons = []; + this.stickers = []; + + this.applyPackMeta(content); + this.applyImages(content); + } + + applyPackMeta(content: PackContent) { + const pack = content.pack ?? {}; + + this.displayName = pack.display_name; + this.avatarUrl = pack.avatar_url; + this.usage = pack.usage ?? [PackUsage.Emoticon, PackUsage.Sticker]; + this.attribution = pack.attribution; + } + + applyImages(content: PackContent) { + this.images = new Map(); + this.emoticons = []; + this.stickers = []; + if (!content.images) return; + + Object.entries(content.images).forEach(([shortcode, data]) => { + const { url } = data; + const body = data.body ?? shortcode; + const usage = data.usage ?? this.usage; + const { info } = data; + + if (!url) return; + const image: ExtendedPackImage = { + shortcode, + url, + body, + usage, + info, + }; + + this.images.set(shortcode, image); + if (usage && usage.includes(PackUsage.Emoticon)) { + this.emoticons.push(image); + } + if (usage && usage.includes(PackUsage.Sticker)) { + this.stickers.push(image); + } + }); + } + + getImages() { + return this.images; + } + + getEmojis() { + return this.emoticons; + } + + getStickers() { + return this.stickers; + } + + getImagesFor(usage: PackUsage) { + if (usage === PackUsage.Emoticon) return this.getEmojis(); + if (usage === PackUsage.Sticker) return this.getStickers(); + return this.getEmojis(); + } + + getContent() { + return this.content; + } + + getPackAvatarUrl(usage: PackUsage): string | undefined { + return this.avatarUrl || this.getImagesFor(usage)[0].url; + } + + private updatePackProperty(property: K, value: PackMeta[K]) { + if (this.content.pack === undefined) { + this.content.pack = {}; + } + this.content.pack[property] = value; + this.applyPackMeta(this.content); + } + + setAvatarUrl(avatarUrl?: string) { + this.updatePackProperty('avatar_url', avatarUrl); + } + + setDisplayName(displayName?: string) { + this.updatePackProperty('display_name', displayName); + } + + setAttribution(attribution?: string) { + this.updatePackProperty('attribution', attribution); + } + + setUsage(usage?: PackUsage[]) { + this.updatePackProperty('usage', usage); + } + + addImage(key: string, imgContent: PackImage) { + this.content.images = { + [key]: imgContent, + ...this.content.images, + }; + this.applyImages(this.content); + } + + removeImage(key: string) { + if (!this.content.images) return; + if (this.content.images[key] === undefined) return; + delete this.content.images[key]; + this.applyImages(this.content); + } + + updateImageKey(key: string, newKey: string) { + const { images } = this.content; + if (!images) return; + if (images[key] === undefined) return; + const copyImages: PackImages = {}; + Object.keys(images).forEach((imgKey) => { + copyImages[imgKey === key ? newKey : imgKey] = images[imgKey]; + }); + this.content.images = copyImages; + this.applyImages(this.content); + } + + private updateImageProperty( + key: string, + property: K, + value: PackImage[K] + ) { + if (!this.content.images) return; + if (this.content.images[key] === undefined) return; + this.content.images[key][property] = value; + this.applyImages(this.content); + } + + setImageUrl(key: string, url: string) { + this.updateImageProperty(key, 'url', url); + } + + setImageBody(key: string, body?: string) { + this.updateImageProperty(key, 'body', body); + } + + setImageInfo(key: string, info?: IImageInfo) { + this.updateImageProperty(key, 'info', info); + } + + setImageUsage(key: string, usage?: PackUsage[]) { + this.updateImageProperty(key, 'usage', usage); + } +} + +export function getRoomImagePacks(room: Room): ImagePack[] { + const dataEvents = getStateEvents(room, StateEvent.PoniesRoomEmotes); + + return dataEvents.reduce((roomPacks, packEvent) => { + const packId = packEvent?.getId(); + const content = packEvent?.getContent() as PackContent | undefined; + if (!packId || !content) return roomPacks; + const pack = ImagePack.parsePack(packId, content); + if (pack) { + roomPacks.push(pack); + } + return roomPacks; + }, []); +} + +export function getGlobalImagePacks(mx: MatrixClient): ImagePack[] { + const emoteRoomsContent = getAccountData(mx, AccountDataEvent.PoniesEmoteRooms)?.getContent() as + | EmoteRoomsContent + | undefined; + if (typeof emoteRoomsContent !== 'object') return []; + + const { rooms } = emoteRoomsContent; + if (typeof rooms !== 'object') return []; + + const roomIds = Object.keys(rooms); + + const packs = roomIds.flatMap((roomId) => { + if (typeof rooms[roomId] !== 'object') return []; + const room = mx.getRoom(roomId); + if (!room) return []; + return getRoomImagePacks(room); + }); + + return packs; +} + +export function getUserImagePack(mx: MatrixClient): ImagePack | undefined { + const userPackContent = getAccountData(mx, AccountDataEvent.PoniesUserEmotes)?.getContent() as + | PackContent + | undefined; + const userId = mx.getUserId(); + if (!userPackContent || !userId) { + return undefined; + } + + const userImagePack = ImagePack.parsePack(userId, userPackContent); + return userImagePack; +} + +/** + * @param {MatrixClient} mx Provide if you want to include user personal/global pack + * @param {Room[]} rooms Provide rooms if you want to include rooms pack + * @returns {ImagePack[]} packs + */ +export function getRelevantPacks(mx?: MatrixClient, rooms?: Room[]): ImagePack[] { + const userPack = mx && getUserImagePack(mx); + const userPacks = userPack ? [userPack] : []; + const globalPacks = mx ? getGlobalImagePacks(mx) : []; + const globalPackIds = new Set(globalPacks.map((pack) => pack.id)); + const roomsPack = rooms?.flatMap(getRoomImagePacks) ?? []; + + return userPacks.concat( + globalPacks, + roomsPack.filter((pack) => !globalPackIds.has(pack.id)) + ); +} diff --git a/src/app/plugins/emoji.ts b/src/app/plugins/emoji.ts new file mode 100644 index 000000000..36bd044e5 --- /dev/null +++ b/src/app/plugins/emoji.ts @@ -0,0 +1,104 @@ +import { CompactEmoji } from 'emojibase'; +import emojisData from 'emojibase-data/en/compact.json'; +import joypixels from 'emojibase-data/en/shortcodes/joypixels.json'; +import emojibase from 'emojibase-data/en/shortcodes/emojibase.json'; + +export type IEmoji = CompactEmoji & { + shortcode: string; +}; + +export enum EmojiGroupId { + People = 'People', + Nature = 'Nature', + Food = 'Food', + Activity = 'Activity', + Travel = 'Travel', + Object = 'Object', + Symbol = 'Symbol', + Flag = 'Flag', +} + +export type IEmojiGroup = { + id: EmojiGroupId; + order: number; + emojis: IEmoji[]; +}; + +export const emojiGroups: IEmojiGroup[] = [ + { + id: EmojiGroupId.People, + order: 0, + emojis: [], + }, + { + id: EmojiGroupId.Nature, + order: 1, + emojis: [], + }, + { + id: EmojiGroupId.Food, + order: 2, + emojis: [], + }, + { + id: EmojiGroupId.Activity, + order: 3, + emojis: [], + }, + { + id: EmojiGroupId.Travel, + order: 4, + emojis: [], + }, + { + id: EmojiGroupId.Object, + order: 5, + emojis: [], + }, + { + id: EmojiGroupId.Symbol, + order: 6, + emojis: [], + }, + { + id: EmojiGroupId.Flag, + order: 7, + emojis: [], + }, +]; + +export const emojis: IEmoji[] = []; + +function addEmojiToGroup(groupIndex: number, emoji: IEmoji) { + emojiGroups[groupIndex].emojis.push(emoji); +} + +function getGroupIndex(emoji: IEmoji): number | undefined { + if (emoji.group === 0 || emoji.group === 1) return 0; + if (emoji.group === 3) return 1; + if (emoji.group === 4) return 2; + if (emoji.group === 6) return 3; + if (emoji.group === 5) return 4; + if (emoji.group === 7) return 5; + if (emoji.group === 8 || typeof emoji.group === 'undefined') return 6; + if (emoji.group === 9) return 7; + return undefined; +} + +emojisData.forEach((emoji) => { + const myShortCodes = joypixels[emoji.hexcode] || emojibase[emoji.hexcode]; + if (!myShortCodes) return; + if (Array.isArray(myShortCodes) && myShortCodes.length === 0) return; + + const em: IEmoji = { + ...emoji, + shortcode: Array.isArray(myShortCodes) ? myShortCodes[0] : myShortCodes, + shortcodes: Array.isArray(myShortCodes) ? myShortCodes : emoji.shortcodes, + }; + + const groupIndex = getGroupIndex(em); + if (groupIndex !== undefined) { + addEmojiToGroup(groupIndex, em); + emojis.push(em); + } +}); diff --git a/src/app/plugins/recent-emoji.ts b/src/app/plugins/recent-emoji.ts new file mode 100644 index 000000000..3634538fb --- /dev/null +++ b/src/app/plugins/recent-emoji.ts @@ -0,0 +1,44 @@ +import { MatrixClient } from 'matrix-js-sdk'; +import { getAccountData } from '../utils/room'; +import { IEmoji, emojis } from './emoji'; +import { AccountDataEvent } from '../../types/matrix/accountData'; + +type EmojiUnicode = string; +type EmojiUsageCount = number; + +export type IRecentEmojiContent = { + recent_emoji?: [EmojiUnicode, EmojiUsageCount][]; +}; + +export const getRecentEmojis = (mx: MatrixClient, limit?: number): IEmoji[] => { + const recentEmojiEvent = getAccountData(mx, AccountDataEvent.ElementRecentEmoji); + const recentEmoji = recentEmojiEvent?.getContent().recent_emoji; + if (!Array.isArray(recentEmoji)) return []; + + return recentEmoji + .sort((e1, e2) => e2[1] - e1[1]) + .slice(0, limit) + .reduce((list, [unicode]) => { + const emoji = emojis.find((e) => e.unicode === unicode); + if (emoji) list.push(emoji); + return list; + }, []); +}; + +export function addRecentEmoji(mx: MatrixClient, unicode: string) { + const recentEmojiEvent = getAccountData(mx, AccountDataEvent.ElementRecentEmoji); + const recentEmoji = recentEmojiEvent?.getContent().recent_emoji ?? []; + + const emojiIndex = recentEmoji.findIndex(([u]) => u === unicode); + let entry: [EmojiUnicode, EmojiUsageCount]; + if (emojiIndex < 0) { + entry = [unicode, 1]; + } else { + [entry] = recentEmoji.splice(emojiIndex, 1); + entry[1] += 1; + } + recentEmoji.unshift(entry); + mx.setAccountData(AccountDataEvent.ElementRecentEmoji, { + recent_emoji: recentEmoji.slice(0, 100), + }); +} diff --git a/src/app/state/hooks/inviteList.ts b/src/app/state/hooks/inviteList.ts new file mode 100644 index 000000000..f8b7e057c --- /dev/null +++ b/src/app/state/hooks/inviteList.ts @@ -0,0 +1,63 @@ +import { useAtomValue, WritableAtom } from 'jotai'; +import { selectAtom } from 'jotai/utils'; +import { MatrixClient } from 'matrix-js-sdk'; +import { useCallback } from 'react'; +import { isDirectInvite, isRoom, isSpace, isUnsupportedRoom } from '../../utils/room'; +import { compareRoomsEqual, RoomsAction } from '../utils'; +import { MDirectAction } from '../mDirectList'; + +export const useSpaceInvites = ( + mx: MatrixClient, + allInvitesAtom: WritableAtom +) => { + const selector = useCallback( + (rooms: string[]) => rooms.filter((roomId) => isSpace(mx.getRoom(roomId))), + [mx] + ); + return useAtomValue(selectAtom(allInvitesAtom, selector, compareRoomsEqual)); +}; + +export const useRoomInvites = ( + mx: MatrixClient, + allInvitesAtom: WritableAtom, + mDirectAtom: WritableAtom, MDirectAction> +) => { + const mDirects = useAtomValue(mDirectAtom); + const selector = useCallback( + (rooms: string[]) => + rooms.filter( + (roomId) => + isRoom(mx.getRoom(roomId)) && + !(mDirects.has(roomId) || isDirectInvite(mx.getRoom(roomId), mx.getUserId())) + ), + [mx, mDirects] + ); + return useAtomValue(selectAtom(allInvitesAtom, selector, compareRoomsEqual)); +}; + +export const useDirectInvites = ( + mx: MatrixClient, + allInvitesAtom: WritableAtom, + mDirectAtom: WritableAtom, MDirectAction> +) => { + const mDirects = useAtomValue(mDirectAtom); + const selector = useCallback( + (rooms: string[]) => + rooms.filter( + (roomId) => mDirects.has(roomId) || isDirectInvite(mx.getRoom(roomId), mx.getUserId()) + ), + [mx, mDirects] + ); + return useAtomValue(selectAtom(allInvitesAtom, selector, compareRoomsEqual)); +}; + +export const useUnsupportedInvites = ( + mx: MatrixClient, + allInvitesAtom: WritableAtom +) => { + const selector = useCallback( + (rooms: string[]) => rooms.filter((roomId) => isUnsupportedRoom(mx.getRoom(roomId))), + [mx] + ); + return useAtomValue(selectAtom(allInvitesAtom, selector, compareRoomsEqual)); +}; diff --git a/src/app/state/hooks/roomList.ts b/src/app/state/hooks/roomList.ts new file mode 100644 index 000000000..5d0890bdd --- /dev/null +++ b/src/app/state/hooks/roomList.ts @@ -0,0 +1,54 @@ +import { useAtomValue, WritableAtom } from 'jotai'; +import { selectAtom } from 'jotai/utils'; +import { MatrixClient } from 'matrix-js-sdk'; +import { useCallback } from 'react'; +import { isRoom, isSpace, isUnsupportedRoom } from '../../utils/room'; +import { compareRoomsEqual, RoomsAction } from '../utils'; +import { MDirectAction } from '../mDirectList'; + +export const useSpaces = (mx: MatrixClient, allRoomsAtom: WritableAtom) => { + const selector = useCallback( + (rooms: string[]) => rooms.filter((roomId) => isSpace(mx.getRoom(roomId))), + [mx] + ); + return useAtomValue(selectAtom(allRoomsAtom, selector, compareRoomsEqual)); +}; + +export const useRooms = ( + mx: MatrixClient, + allRoomsAtom: WritableAtom, + mDirectAtom: WritableAtom, MDirectAction> +) => { + const mDirects = useAtomValue(mDirectAtom); + const selector = useCallback( + (rooms: string[]) => + rooms.filter((roomId) => isRoom(mx.getRoom(roomId)) && !mDirects.has(roomId)), + [mx, mDirects] + ); + return useAtomValue(selectAtom(allRoomsAtom, selector, compareRoomsEqual)); +}; + +export const useDirects = ( + mx: MatrixClient, + allRoomsAtom: WritableAtom, + mDirectAtom: WritableAtom, MDirectAction> +) => { + const mDirects = useAtomValue(mDirectAtom); + const selector = useCallback( + (rooms: string[]) => + rooms.filter((roomId) => isRoom(mx.getRoom(roomId)) && mDirects.has(roomId)), + [mx, mDirects] + ); + return useAtomValue(selectAtom(allRoomsAtom, selector, compareRoomsEqual)); +}; + +export const useUnsupportedRooms = ( + mx: MatrixClient, + allRoomsAtom: WritableAtom +) => { + const selector = useCallback( + (rooms: string[]) => rooms.filter((roomId) => isUnsupportedRoom(mx.getRoom(roomId))), + [mx] + ); + return useAtomValue(selectAtom(allRoomsAtom, selector, compareRoomsEqual)); +}; diff --git a/src/app/state/hooks/settings.ts b/src/app/state/hooks/settings.ts new file mode 100644 index 000000000..3f4dab60d --- /dev/null +++ b/src/app/state/hooks/settings.ts @@ -0,0 +1,34 @@ +import { atom, useAtomValue, useSetAtom, WritableAtom } from 'jotai'; +import { SetAtom } from 'jotai/core/atom'; +import { selectAtom } from 'jotai/utils'; +import { useMemo } from 'react'; +import { Settings } from '../settings'; + +export const useSetSetting = ( + settingsAtom: WritableAtom, + key: K +) => { + const setterAtom = useMemo( + () => + atom(null, (get, set, value) => { + const s = { ...get(settingsAtom) }; + s[key] = value; + set(settingsAtom, s); + }), + [settingsAtom, key] + ); + + return useSetAtom(setterAtom); +}; + +export const useSetting = ( + settingsAtom: WritableAtom, + key: K +): [Settings[K], SetAtom] => { + const selector = useMemo(() => (s: Settings) => s[key], [key]); + const setting = useAtomValue(selectAtom(settingsAtom, selector)); + + const setter = useSetSetting(settingsAtom, key); + + return [setting, setter]; +}; diff --git a/src/app/state/hooks/useBindAtoms.ts b/src/app/state/hooks/useBindAtoms.ts new file mode 100644 index 000000000..6dc2a3de9 --- /dev/null +++ b/src/app/state/hooks/useBindAtoms.ts @@ -0,0 +1,16 @@ +import { MatrixClient } from 'matrix-js-sdk'; +import { allInvitesAtom, useBindAllInvitesAtom } from '../inviteList'; +import { allRoomsAtom, useBindAllRoomsAtom } from '../roomList'; +import { mDirectAtom, useBindMDirectAtom } from '../mDirectList'; +import { muteChangesAtom, mutedRoomsAtom, useBindMutedRoomsAtom } from '../mutedRoomList'; +import { roomToUnreadAtom, useBindRoomToUnreadAtom } from '../roomToUnread'; +import { roomToParentsAtom, useBindRoomToParentsAtom } from '../roomToParents'; + +export const useBindAtoms = (mx: MatrixClient) => { + useBindMDirectAtom(mx, mDirectAtom); + useBindAllInvitesAtom(mx, allInvitesAtom); + useBindAllRoomsAtom(mx, allRoomsAtom); + useBindRoomToParentsAtom(mx, roomToParentsAtom); + useBindMutedRoomsAtom(mx, mutedRoomsAtom); + useBindRoomToUnreadAtom(mx, roomToUnreadAtom, muteChangesAtom); +}; diff --git a/src/app/state/inviteList.ts b/src/app/state/inviteList.ts new file mode 100644 index 000000000..463fd352d --- /dev/null +++ b/src/app/state/inviteList.ts @@ -0,0 +1,32 @@ +import { atom, WritableAtom } from 'jotai'; +import { MatrixClient } from 'matrix-js-sdk'; +import { useMemo } from 'react'; +import { Membership } from '../../types/matrix/room'; +import { RoomsAction, useBindRoomsWithMembershipsAtom } from './utils'; + +const baseRoomsAtom = atom([]); +export const allInvitesAtom = atom( + (get) => get(baseRoomsAtom), + (get, set, action) => { + if (action.type === 'INITIALIZE') { + set(baseRoomsAtom, action.rooms); + return; + } + set(baseRoomsAtom, (ids) => { + const newIds = ids.filter((id) => id !== action.roomId); + if (action.type === 'PUT') newIds.push(action.roomId); + return newIds; + }); + } +); + +export const useBindAllInvitesAtom = ( + mx: MatrixClient, + allRooms: WritableAtom +) => { + useBindRoomsWithMembershipsAtom( + mx, + allRooms, + useMemo(() => [Membership.Invite], []) + ); +}; diff --git a/src/app/state/list.ts b/src/app/state/list.ts new file mode 100644 index 000000000..4f5a61914 --- /dev/null +++ b/src/app/state/list.ts @@ -0,0 +1,33 @@ +import { atom } from 'jotai'; + +export type ListAction = + | { + type: 'PUT'; + item: T | T[]; + } + | { + type: 'DELETE'; + item: T | T[]; + }; + +export const createListAtom = () => { + const baseListAtom = atom([]); + return atom>( + (get) => get(baseListAtom), + (get, set, action) => { + const items = get(baseListAtom); + const newItems = Array.isArray(action.item) ? action.item : [action.item]; + if (action.type === 'DELETE') { + set( + baseListAtom, + items.filter((item) => !newItems.includes(item)) + ); + return; + } + if (action.type === 'PUT') { + set(baseListAtom, [...items, ...newItems]); + } + } + ); +}; +export type TListAtom = ReturnType>; diff --git a/src/app/state/mDirectList.ts b/src/app/state/mDirectList.ts new file mode 100644 index 000000000..96e2f0d03 --- /dev/null +++ b/src/app/state/mDirectList.ts @@ -0,0 +1,47 @@ +import { atom, useSetAtom, WritableAtom } from 'jotai'; +import { ClientEvent, MatrixClient, MatrixEvent } from 'matrix-js-sdk'; +import { useEffect } from 'react'; +import { AccountDataEvent } from '../../types/matrix/accountData'; +import { getAccountData, getMDirects } from '../utils/room'; + +export type MDirectAction = { + type: 'INITIALIZE' | 'UPDATE'; + rooms: Set; +}; + +const baseMDirectAtom = atom(new Set()); +export const mDirectAtom = atom, MDirectAction>( + (get) => get(baseMDirectAtom), + (get, set, action) => { + set(baseMDirectAtom, action.rooms); + } +); + +export const useBindMDirectAtom = ( + mx: MatrixClient, + mDirect: WritableAtom, MDirectAction> +) => { + const setMDirect = useSetAtom(mDirect); + + useEffect(() => { + const mDirectEvent = getAccountData(mx, AccountDataEvent.Direct); + if (mDirectEvent) { + setMDirect({ + type: 'INITIALIZE', + rooms: getMDirects(mDirectEvent), + }); + } + + const handleAccountData = (event: MatrixEvent) => { + setMDirect({ + type: 'UPDATE', + rooms: getMDirects(event), + }); + }; + + mx.on(ClientEvent.AccountData, handleAccountData); + return () => { + mx.removeListener(ClientEvent.AccountData, handleAccountData); + }; + }, [mx, setMDirect]); +}; diff --git a/src/app/state/mutedRoomList.ts b/src/app/state/mutedRoomList.ts new file mode 100644 index 000000000..d456f8533 --- /dev/null +++ b/src/app/state/mutedRoomList.ts @@ -0,0 +1,101 @@ +import { atom, WritableAtom, useSetAtom } from 'jotai'; +import { ClientEvent, IPushRule, IPushRules, MatrixClient, MatrixEvent } from 'matrix-js-sdk'; +import { useEffect } from 'react'; +import { MuteChanges } from '../../types/matrix/room'; +import { findMutedRule, isMutedRule } from '../utils/room'; + +export type MutedRoomsUpdate = + | { + type: 'INITIALIZE'; + addRooms: string[]; + } + | { + type: 'UPDATE'; + addRooms: string[]; + removeRooms: string[]; + }; + +export const muteChangesAtom = atom({ + added: [], + removed: [], +}); + +const baseMutedRoomsAtom = atom(new Set()); +export const mutedRoomsAtom = atom, MutedRoomsUpdate>( + (get) => get(baseMutedRoomsAtom), + (get, set, action) => { + const mutedRooms = new Set([...get(mutedRoomsAtom)]); + if (action.type === 'INITIALIZE') { + set(baseMutedRoomsAtom, new Set([...action.addRooms])); + set(muteChangesAtom, { + added: [...action.addRooms], + removed: [], + }); + return; + } + if (action.type === 'UPDATE') { + action.removeRooms.forEach((roomId) => mutedRooms.delete(roomId)); + action.addRooms.forEach((roomId) => mutedRooms.add(roomId)); + set(baseMutedRoomsAtom, mutedRooms); + set(muteChangesAtom, { + added: [...action.addRooms], + removed: [...action.removeRooms], + }); + } + } +); + +export const useBindMutedRoomsAtom = ( + mx: MatrixClient, + mutedAtom: WritableAtom, MutedRoomsUpdate> +) => { + const setMuted = useSetAtom(mutedAtom); + + useEffect(() => { + const overrideRules = mx.getAccountData('m.push_rules')?.getContent() + ?.global?.override; + if (overrideRules) { + const mutedRooms = overrideRules.reduce((rooms, rule) => { + if (isMutedRule(rule)) rooms.push(rule.rule_id); + return rooms; + }, []); + setMuted({ + type: 'INITIALIZE', + addRooms: mutedRooms, + }); + } + }, [mx, setMuted]); + + useEffect(() => { + const handlePushRules = (mEvent: MatrixEvent, oldMEvent?: MatrixEvent) => { + if (mEvent.getType() === 'm.push_rules') { + const override = mEvent?.getContent()?.global?.override as IPushRule[] | undefined; + const oldOverride = oldMEvent?.getContent()?.global?.override as IPushRule[] | undefined; + if (!override || !oldOverride) return; + + const isMuteToggled = (rule: IPushRule, otherOverride: IPushRule[]) => { + const roomId = rule.rule_id; + + const isMuted = isMutedRule(rule); + if (!isMuted) return false; + const isOtherMuted = findMutedRule(otherOverride, roomId); + if (isOtherMuted) return false; + return true; + }; + + const mutedRules = override.filter((rule) => isMuteToggled(rule, oldOverride)); + const unMutedRules = oldOverride.filter((rule) => isMuteToggled(rule, override)); + + setMuted({ + type: 'UPDATE', + addRooms: mutedRules.map((rule) => rule.rule_id), + removeRooms: unMutedRules.map((rule) => rule.rule_id), + }); + } + }; + mx.on(ClientEvent.AccountData, handlePushRules); + return () => { + mx.removeListener(ClientEvent.AccountData, handlePushRules); + }; + }, [mx, setMuted]); +}; diff --git a/src/app/state/roomInputDrafts.ts b/src/app/state/roomInputDrafts.ts new file mode 100644 index 000000000..2708b8bdf --- /dev/null +++ b/src/app/state/roomInputDrafts.ts @@ -0,0 +1,48 @@ +import { atom } from 'jotai'; +import { atomFamily } from 'jotai/utils'; +import { Descendant } from 'slate'; +import { EncryptedAttachmentInfo } from 'browser-encrypt-attachment'; +import { TListAtom, createListAtom } from './list'; +import { createUploadAtomFamily } from './upload'; +import { TUploadContent } from '../utils/matrix'; + +export const roomUploadAtomFamily = createUploadAtomFamily(); + +export type TUploadItem = { + file: TUploadContent; + originalFile: TUploadContent; + encInfo: EncryptedAttachmentInfo | undefined; +}; + +export const roomIdToUploadItemsAtomFamily = atomFamily>( + createListAtom +); + +export type RoomIdToMsgAction = + | { + type: 'PUT'; + roomId: string; + msg: Descendant[]; + } + | { + type: 'DELETE'; + roomId: string; + }; + +const createMsgDraftAtom = () => atom([]); +export type TMsgDraftAtom = ReturnType; +export const roomIdToMsgDraftAtomFamily = atomFamily(() => + createMsgDraftAtom() +); + +export type IReplyDraft = { + userId: string; + eventId: string; + body: string; + formattedBody?: string; +}; +const createReplyDraftAtom = () => atom(undefined); +export type TReplyDraftAtom = ReturnType; +export const roomIdToReplyDraftAtomFamily = atomFamily(() => + createReplyDraftAtom() +); diff --git a/src/app/state/roomList.ts b/src/app/state/roomList.ts new file mode 100644 index 000000000..7a793d8c3 --- /dev/null +++ b/src/app/state/roomList.ts @@ -0,0 +1,31 @@ +import { atom, WritableAtom } from 'jotai'; +import { MatrixClient } from 'matrix-js-sdk'; +import { useMemo } from 'react'; +import { Membership } from '../../types/matrix/room'; +import { RoomsAction, useBindRoomsWithMembershipsAtom } from './utils'; + +const baseRoomsAtom = atom([]); +export const allRoomsAtom = atom( + (get) => get(baseRoomsAtom), + (get, set, action) => { + if (action.type === 'INITIALIZE') { + set(baseRoomsAtom, action.rooms); + return; + } + set(baseRoomsAtom, (ids) => { + const newIds = ids.filter((id) => id !== action.roomId); + if (action.type === 'PUT') newIds.push(action.roomId); + return newIds; + }); + } +); +export const useBindAllRoomsAtom = ( + mx: MatrixClient, + allRooms: WritableAtom +) => { + useBindRoomsWithMembershipsAtom( + mx, + allRooms, + useMemo(() => [Membership.Join], []) + ); +}; diff --git a/src/app/state/roomToParents.ts b/src/app/state/roomToParents.ts new file mode 100644 index 000000000..374ddd575 --- /dev/null +++ b/src/app/state/roomToParents.ts @@ -0,0 +1,120 @@ +import produce from 'immer'; +import { atom, useSetAtom, WritableAtom } from 'jotai'; +import { + ClientEvent, + MatrixClient, + MatrixEvent, + Room, + RoomEvent, + RoomStateEvent, +} from 'matrix-js-sdk'; +import { useEffect } from 'react'; +import { Membership, RoomToParents, StateEvent } from '../../types/matrix/room'; +import { + getRoomToParents, + getSpaceChildren, + isSpace, + isValidChild, + mapParentWithChildren, +} from '../utils/room'; + +export type RoomToParentsAction = + | { + type: 'INITIALIZE'; + roomToParents: RoomToParents; + } + | { + type: 'PUT'; + parent: string; + children: string[]; + } + | { + type: 'DELETE'; + roomId: string; + }; + +const baseRoomToParents = atom(new Map()); +export const roomToParentsAtom = atom( + (get) => get(baseRoomToParents), + (get, set, action) => { + if (action.type === 'INITIALIZE') { + set(baseRoomToParents, action.roomToParents); + return; + } + if (action.type === 'PUT') { + set( + baseRoomToParents, + produce(get(baseRoomToParents), (draftRoomToParents) => { + mapParentWithChildren(draftRoomToParents, action.parent, action.children); + }) + ); + return; + } + if (action.type === 'DELETE') { + set( + baseRoomToParents, + produce(get(baseRoomToParents), (draftRoomToParents) => { + const noParentRooms: string[] = []; + draftRoomToParents.delete(action.roomId); + draftRoomToParents.forEach((parents, child) => { + parents.delete(action.roomId); + if (parents.size === 0) noParentRooms.push(child); + }); + noParentRooms.forEach((room) => draftRoomToParents.delete(room)); + }) + ); + } + } +); + +export const useBindRoomToParentsAtom = ( + mx: MatrixClient, + roomToParents: WritableAtom +) => { + const setRoomToParents = useSetAtom(roomToParents); + + useEffect(() => { + setRoomToParents({ type: 'INITIALIZE', roomToParents: getRoomToParents(mx) }); + + const handleAddRoom = (room: Room) => { + if (isSpace(room) && room.getMyMembership() !== Membership.Invite) { + setRoomToParents({ type: 'PUT', parent: room.roomId, children: getSpaceChildren(room) }); + } + }; + + const handleMembershipChange = (room: Room, membership: string) => { + if (isSpace(room) && membership === Membership.Join) { + setRoomToParents({ type: 'PUT', parent: room.roomId, children: getSpaceChildren(room) }); + } + }; + + const handleStateChange = (mEvent: MatrixEvent) => { + if (mEvent.getType() === StateEvent.SpaceChild) { + const childId = mEvent.getStateKey(); + const roomId = mEvent.getRoomId(); + if (childId && roomId) { + if (isValidChild(mEvent)) { + setRoomToParents({ type: 'PUT', parent: roomId, children: [childId] }); + } else { + setRoomToParents({ type: 'DELETE', roomId: childId }); + } + } + } + }; + + const handleDeleteRoom = (roomId: string) => { + setRoomToParents({ type: 'DELETE', roomId }); + }; + + mx.on(ClientEvent.Room, handleAddRoom); + mx.on(RoomEvent.MyMembership, handleMembershipChange); + mx.on(RoomStateEvent.Events, handleStateChange); + mx.on(ClientEvent.DeleteRoom, handleDeleteRoom); + return () => { + mx.removeListener(ClientEvent.Room, handleAddRoom); + mx.removeListener(RoomEvent.MyMembership, handleMembershipChange); + mx.removeListener(RoomStateEvent.Events, handleStateChange); + mx.removeListener(ClientEvent.DeleteRoom, handleDeleteRoom); + }; + }, [mx, setRoomToParents]); +}; diff --git a/src/app/state/roomToUnread.ts b/src/app/state/roomToUnread.ts new file mode 100644 index 000000000..0c7b6bd69 --- /dev/null +++ b/src/app/state/roomToUnread.ts @@ -0,0 +1,219 @@ +import produce from 'immer'; +import { atom, useSetAtom, PrimitiveAtom, WritableAtom, useAtomValue } from 'jotai'; +import { IRoomTimelineData, MatrixClient, MatrixEvent, Room, RoomEvent } from 'matrix-js-sdk'; +import { ReceiptContent, ReceiptType } from 'matrix-js-sdk/lib/@types/read_receipts'; +import { useEffect } from 'react'; +import { + MuteChanges, + Membership, + NotificationType, + RoomToUnread, + UnreadInfo, +} from '../../types/matrix/room'; +import { + getAllParents, + getNotificationType, + getUnreadInfo, + getUnreadInfos, + isNotificationEvent, + roomHaveUnread, +} from '../utils/room'; +import { roomToParentsAtom } from './roomToParents'; + +export type RoomToUnreadAction = + | { + type: 'RESET'; + unreadInfos: UnreadInfo[]; + } + | { + type: 'PUT'; + unreadInfo: UnreadInfo; + } + | { + type: 'DELETE'; + roomId: string; + }; + +const putUnreadInfo = ( + roomToUnread: RoomToUnread, + allParents: Set, + unreadInfo: UnreadInfo +) => { + const oldUnread = roomToUnread.get(unreadInfo.roomId) ?? { highlight: 0, total: 0, from: null }; + roomToUnread.set(unreadInfo.roomId, { + highlight: unreadInfo.highlight, + total: unreadInfo.total, + from: null, + }); + + const newH = unreadInfo.highlight - oldUnread.highlight; + const newT = unreadInfo.total - oldUnread.total; + + allParents.forEach((parentId) => { + const oldParentUnread = roomToUnread.get(parentId) ?? { highlight: 0, total: 0, from: null }; + roomToUnread.set(parentId, { + highlight: (oldParentUnread.highlight += newH), + total: (oldParentUnread.total += newT), + from: new Set([...(oldParentUnread.from ?? []), unreadInfo.roomId]), + }); + }); +}; + +const deleteUnreadInfo = (roomToUnread: RoomToUnread, allParents: Set, roomId: string) => { + const oldUnread = roomToUnread.get(roomId); + if (!oldUnread) return; + roomToUnread.delete(roomId); + + allParents.forEach((parentId) => { + const oldParentUnread = roomToUnread.get(parentId); + if (!oldParentUnread) return; + const newFrom = new Set([...(oldParentUnread.from ?? roomId)]); + newFrom.delete(roomId); + if (newFrom.size === 0) { + roomToUnread.delete(parentId); + return; + } + roomToUnread.set(parentId, { + highlight: oldParentUnread.highlight - oldUnread.highlight, + total: oldParentUnread.total - oldUnread.total, + from: newFrom, + }); + }); +}; + +const baseRoomToUnread = atom(new Map()); +export const roomToUnreadAtom = atom( + (get) => get(baseRoomToUnread), + (get, set, action) => { + if (action.type === 'RESET') { + const draftRoomToUnread: RoomToUnread = new Map(); + action.unreadInfos.forEach((unreadInfo) => { + putUnreadInfo( + draftRoomToUnread, + getAllParents(get(roomToParentsAtom), unreadInfo.roomId), + unreadInfo + ); + }); + set(baseRoomToUnread, draftRoomToUnread); + return; + } + if (action.type === 'PUT') { + set( + baseRoomToUnread, + produce(get(baseRoomToUnread), (draftRoomToUnread) => + putUnreadInfo( + draftRoomToUnread, + getAllParents(get(roomToParentsAtom), action.unreadInfo.roomId), + action.unreadInfo + ) + ) + ); + return; + } + if (action.type === 'DELETE' && get(baseRoomToUnread).has(action.roomId)) { + set( + baseRoomToUnread, + produce(get(baseRoomToUnread), (draftRoomToUnread) => + deleteUnreadInfo( + draftRoomToUnread, + getAllParents(get(roomToParentsAtom), action.roomId), + action.roomId + ) + ) + ); + } + } +); + +export const useBindRoomToUnreadAtom = ( + mx: MatrixClient, + unreadAtom: WritableAtom, + muteChangesAtom: PrimitiveAtom +) => { + const setUnreadAtom = useSetAtom(unreadAtom); + const muteChanges = useAtomValue(muteChangesAtom); + + useEffect(() => { + setUnreadAtom({ + type: 'RESET', + unreadInfos: getUnreadInfos(mx), + }); + }, [mx, setUnreadAtom]); + + useEffect(() => { + const handleTimelineEvent = ( + mEvent: MatrixEvent, + room: Room | undefined, + toStartOfTimeline: boolean | undefined, + removed: boolean, + data: IRoomTimelineData + ) => { + if (!room || !data.liveEvent || room.isSpaceRoom() || !isNotificationEvent(mEvent)) return; + if (getNotificationType(mx, room.roomId) === NotificationType.Mute) { + setUnreadAtom({ + type: 'DELETE', + roomId: room.roomId, + }); + return; + } + + if (mEvent.getSender() === mx.getUserId()) return; + setUnreadAtom({ type: 'PUT', unreadInfo: getUnreadInfo(room) }); + }; + mx.on(RoomEvent.Timeline, handleTimelineEvent); + return () => { + mx.removeListener(RoomEvent.Timeline, handleTimelineEvent); + }; + }, [mx, setUnreadAtom]); + + useEffect(() => { + const handleReceipt = (mEvent: MatrixEvent, room: Room) => { + if (mEvent.getType() === 'm.receipt') { + const myUserId = mx.getUserId(); + if (!myUserId) return; + if (room.isSpaceRoom()) return; + const content = mEvent.getContent(); + + const isMyReceipt = Object.keys(content).find((eventId) => + (Object.keys(content[eventId]) as ReceiptType[]).find( + (receiptType) => content[eventId][receiptType][myUserId] + ) + ); + if (isMyReceipt) { + setUnreadAtom({ type: 'DELETE', roomId: room.roomId }); + } + } + }; + mx.on(RoomEvent.Receipt, handleReceipt); + return () => { + mx.removeListener(RoomEvent.Receipt, handleReceipt); + }; + }, [mx, setUnreadAtom]); + + useEffect(() => { + muteChanges.removed.forEach((roomId) => { + const room = mx.getRoom(roomId); + if (!room) return; + if (!roomHaveUnread(mx, room)) return; + setUnreadAtom({ type: 'PUT', unreadInfo: getUnreadInfo(room) }); + }); + muteChanges.added.forEach((roomId) => { + setUnreadAtom({ type: 'DELETE', roomId }); + }); + }, [mx, setUnreadAtom, muteChanges]); + + useEffect(() => { + const handleMembershipChange = (room: Room, membership: string) => { + if (membership !== Membership.Join) { + setUnreadAtom({ + type: 'DELETE', + roomId: room.roomId, + }); + } + }; + mx.on(RoomEvent.MyMembership, handleMembershipChange); + return () => { + mx.removeListener(RoomEvent.MyMembership, handleMembershipChange); + }; + }, [mx, setUnreadAtom]); +}; diff --git a/src/app/state/selectedRoom.ts b/src/app/state/selectedRoom.ts new file mode 100644 index 000000000..1ef04de35 --- /dev/null +++ b/src/app/state/selectedRoom.ts @@ -0,0 +1,3 @@ +import { atom } from 'jotai'; + +export const selectedRoomAtom = atom(undefined); diff --git a/src/app/state/selectedTab.ts b/src/app/state/selectedTab.ts new file mode 100644 index 000000000..e680ae606 --- /dev/null +++ b/src/app/state/selectedTab.ts @@ -0,0 +1,8 @@ +import { atom } from 'jotai'; + +export enum SidebarTab { + Home = 'Home', + People = 'People', +} + +export const selectedTabAtom = atom(SidebarTab.Home); diff --git a/src/app/state/settings.ts b/src/app/state/settings.ts new file mode 100644 index 000000000..7739c589e --- /dev/null +++ b/src/app/state/settings.ts @@ -0,0 +1,49 @@ +import { atom } from 'jotai'; + +const STORAGE_KEY = 'settings'; +export interface Settings { + themeIndex: number; + useSystemTheme: boolean; + isMarkdown: boolean; + editorToolbar: boolean; + isPeopleDrawer: boolean; + + hideMembershipEvents: boolean; + hideNickAvatarEvents: boolean; + + showNotifications: boolean; + isNotificationSounds: boolean; +} + +const defaultSettings: Settings = { + themeIndex: 0, + useSystemTheme: true, + isMarkdown: true, + editorToolbar: false, + isPeopleDrawer: true, + + hideMembershipEvents: false, + hideNickAvatarEvents: true, + + showNotifications: true, + isNotificationSounds: true, +}; + +export const getSettings = () => { + const settings = localStorage.getItem(STORAGE_KEY); + if (settings === null) return defaultSettings; + return JSON.parse(settings) as Settings; +}; + +export const setSettings = (settings: Settings) => { + localStorage.setItem(STORAGE_KEY, JSON.stringify(settings)); +}; + +const baseSettings = atom(getSettings()); +export const settingsAtom = atom( + (get) => get(baseSettings), + (get, set, update) => { + set(baseSettings, update); + setSettings(update); + } +); diff --git a/src/app/state/tabToRoom.ts b/src/app/state/tabToRoom.ts new file mode 100644 index 000000000..2f4ee92a4 --- /dev/null +++ b/src/app/state/tabToRoom.ts @@ -0,0 +1,34 @@ +import produce from 'immer'; +import { atom } from 'jotai'; +import { MatrixClient } from 'matrix-js-sdk'; + +type RoomInfo = { + roomId: string; + timestamp: number; +}; +type TabToRoom = Map; + +type TabToRoomAction = { + type: 'PUT'; + tabInfo: { tabId: string; roomInfo: RoomInfo }; +}; + +const baseTabToRoom = atom(new Map()); +export const tabToRoomAtom = atom( + (get) => get(baseTabToRoom), + (get, set, action) => { + if (action.type === 'PUT') { + set( + baseTabToRoom, + produce(get(baseTabToRoom), (draft) => { + draft.set(action.tabInfo.tabId, action.tabInfo.roomInfo); + }) + ); + } + } +); + +export const useBindTabToRoomAtom = (mx: MatrixClient) => { + console.log(mx); + // TODO: +}; diff --git a/src/app/state/upload.ts b/src/app/state/upload.ts new file mode 100644 index 000000000..d92b93d3d --- /dev/null +++ b/src/app/state/upload.ts @@ -0,0 +1,146 @@ +import { atom, useAtom } from 'jotai'; +import { atomFamily } from 'jotai/utils'; +import { MatrixClient, UploadResponse, UploadProgress, MatrixError } from 'matrix-js-sdk'; +import { useCallback } from 'react'; +import { useThrottle } from '../hooks/useThrottle'; +import { uploadContent, TUploadContent } from '../utils/matrix'; + +export enum UploadStatus { + Idle = 'idle', + Loading = 'loading', + Success = 'success', + Error = 'error', +} + +export type UploadIdle = { + file: TUploadContent; + status: UploadStatus.Idle; +}; + +export type UploadLoading = { + file: TUploadContent; + status: UploadStatus.Loading; + promise: Promise; + progress: UploadProgress; +}; + +export type UploadSuccess = { + file: TUploadContent; + status: UploadStatus.Success; + mxc: string; +}; + +export type UploadError = { + file: TUploadContent; + status: UploadStatus.Error; + error: MatrixError; +}; + +export type Upload = UploadIdle | UploadLoading | UploadSuccess | UploadError; + +export type UploadAtomAction = + | { + promise: Promise; + } + | { + progress: UploadProgress; + } + | { + mxc: string; + } + | { + error: MatrixError; + }; + +export const createUploadAtom = (file: TUploadContent) => { + const baseUploadAtom = atom({ + file, + status: UploadStatus.Idle, + }); + return atom( + (get) => get(baseUploadAtom), + (get, set, update) => { + const uploadState = get(baseUploadAtom); + if ('promise' in update) { + set(baseUploadAtom, { + status: UploadStatus.Loading, + file, + promise: update.promise, + progress: { loaded: 0, total: file.size }, + }); + return; + } + if ('progress' in update && uploadState.status === UploadStatus.Loading) { + set(baseUploadAtom, { + ...uploadState, + progress: update.progress, + }); + return; + } + if ('mxc' in update) { + set(baseUploadAtom, { + status: UploadStatus.Success, + file, + mxc: update.mxc, + }); + return; + } + if ('error' in update) { + set(baseUploadAtom, { + status: UploadStatus.Error, + file, + error: update.error, + }); + } + } + ); +}; +export type TUploadAtom = ReturnType; + +export const useBindUploadAtom = ( + mx: MatrixClient, + file: TUploadContent, + uploadAtom: TUploadAtom, + hideFilename?: boolean +) => { + const [upload, setUpload] = useAtom(uploadAtom); + + const handleProgress = useThrottle( + useCallback((progress: UploadProgress) => setUpload({ progress }), [setUpload]), + { immediate: true, wait: 200 } + ); + + const startUpload = useCallback( + () => + uploadContent(mx, file, { + hideFilename, + onPromise: (promise: Promise) => setUpload({ promise }), + onProgress: handleProgress, + onSuccess: (mxc) => setUpload({ mxc }), + onError: (error) => setUpload({ error }), + }), + [mx, file, hideFilename, setUpload, handleProgress] + ); + + const cancelUpload = useCallback(async () => { + if (upload.status === UploadStatus.Loading) { + await mx.cancelUpload(upload.promise); + } + }, [mx, upload]); + + return { + upload, + startUpload, + cancelUpload, + }; +}; + +export const createUploadAtomFamily = () => + atomFamily(createUploadAtom); +export type TUploadAtomFamily = ReturnType; + +export const createUploadFamilyObserverAtom = ( + uploadFamily: TUploadAtomFamily, + uploads: TUploadContent[] +) => atom((get) => uploads.map((upload) => get(uploadFamily(upload)))); +export type TUploadFamilyObserverAtom = ReturnType; diff --git a/src/app/state/utils.ts b/src/app/state/utils.ts new file mode 100644 index 000000000..355c94110 --- /dev/null +++ b/src/app/state/utils.ts @@ -0,0 +1,64 @@ +import { useSetAtom, WritableAtom } from 'jotai'; +import { ClientEvent, MatrixClient, Room, RoomEvent } from 'matrix-js-sdk'; +import { useEffect } from 'react'; +import { Membership } from '../../types/matrix/room'; + +export type RoomsAction = + | { + type: 'INITIALIZE'; + rooms: string[]; + } + | { + type: 'PUT' | 'DELETE'; + roomId: string; + }; + +export const useBindRoomsWithMembershipsAtom = ( + mx: MatrixClient, + roomsAtom: WritableAtom, + memberships: Membership[] +) => { + const setRoomsAtom = useSetAtom(roomsAtom); + + useEffect(() => { + const satisfyMembership = (room: Room): boolean => + !!memberships.find((membership) => membership === room.getMyMembership()); + setRoomsAtom({ + type: 'INITIALIZE', + rooms: mx + .getRooms() + .filter(satisfyMembership) + .map((room) => room.roomId), + }); + + const handleAddRoom = (room: Room) => { + if (satisfyMembership(room)) { + setRoomsAtom({ type: 'PUT', roomId: room.roomId }); + } + }; + + const handleMembershipChange = (room: Room) => { + if (!satisfyMembership(room)) { + setRoomsAtom({ type: 'DELETE', roomId: room.roomId }); + } + }; + + const handleDeleteRoom = (roomId: string) => { + setRoomsAtom({ type: 'DELETE', roomId }); + }; + + mx.on(ClientEvent.Room, handleAddRoom); + mx.on(RoomEvent.MyMembership, handleMembershipChange); + mx.on(ClientEvent.DeleteRoom, handleDeleteRoom); + return () => { + mx.removeListener(ClientEvent.Room, handleAddRoom); + mx.removeListener(RoomEvent.MyMembership, handleMembershipChange); + mx.removeListener(ClientEvent.DeleteRoom, handleDeleteRoom); + }; + }, [mx, memberships, setRoomsAtom]); +}; + +export const compareRoomsEqual = (a: string[], b: string[]) => { + if (a.length !== b.length) return false; + return a.every((roomId, roomIdIndex) => roomId === b[roomIdIndex]); +}; diff --git a/src/app/templates/client/Client.jsx b/src/app/templates/client/Client.jsx index d83845b8b..cc9d88fa0 100644 --- a/src/app/templates/client/Client.jsx +++ b/src/app/templates/client/Client.jsx @@ -18,14 +18,13 @@ import EmojiBoardOpener from '../../organisms/emoji-board/EmojiBoardOpener'; import initMatrix from '../../../client/initMatrix'; import navigation from '../../../client/state/navigation'; import cons from '../../../client/state/cons'; -import DragDrop from '../../organisms/drag-drop/DragDrop'; import VerticalMenuIC from '../../../../public/res/ic/outlined/vertical-menu.svg'; +import { MatrixClientProvider } from '../../hooks/useMatrixClient'; function Client() { const [isLoading, changeLoading] = useState(true); const [loadingMsg, setLoadingMsg] = useState('Heating up'); - const [dragCounter, setDragCounter] = useState(0); const classNameHidden = 'client__item-hidden'; const navWrapperRef = useRef(null); @@ -44,19 +43,17 @@ function Client() { navigation.on(cons.events.navigation.ROOM_SELECTED, onRoomSelected); navigation.on(cons.events.navigation.NAVIGATION_OPENED, onNavigationSelected); - return (() => { + return () => { navigation.removeListener(cons.events.navigation.ROOM_SELECTED, onRoomSelected); navigation.removeListener(cons.events.navigation.NAVIGATION_OPENED, onNavigationSelected); - }); + }; }, []); useEffect(() => { + changeLoading(true); let counter = 0; const iId = setInterval(() => { - const msgList = [ - 'Almost there...', - 'Looks like you have a lot of stuff to heat up!', - ]; + const msgList = ['Almost there...', 'Looks like you have a lot of stuff to heat up!']; if (counter === msgList.length - 1) { setLoadingMsg(msgList[msgList.length - 1]); clearInterval(iId); @@ -80,103 +77,48 @@ function Client() {
      initMatrix.clearCacheAndReload()}> Clear cache & reload initMatrix.logout()}>Logout + } + render={(toggle) => ( + )} - render={(toggle) => } />
      - {loadingMsg} + + {loadingMsg} +
      - Cinny + + Cinny +
      ); } - function dragContainsFiles(e) { - if (!e.dataTransfer.types) return false; - - for (let i = 0; i < e.dataTransfer.types.length; i += 1) { - if (e.dataTransfer.types[i] === 'Files') return true; - } - return false; - } - - function modalOpen() { - return navigation.isRawModalVisible && dragCounter <= 0; - } - - function handleDragOver(e) { - if (!dragContainsFiles(e)) return; - - e.preventDefault(); - - if (!navigation.selectedRoomId || modalOpen()) { - e.dataTransfer.dropEffect = 'none'; - } - } - - function handleDragEnter(e) { - e.preventDefault(); - - if (navigation.selectedRoomId && !modalOpen() && dragContainsFiles(e)) { - setDragCounter(dragCounter + 1); - } - } - - function handleDragLeave(e) { - e.preventDefault(); - - if (navigation.selectedRoomId && !modalOpen() && dragContainsFiles(e)) { - setDragCounter(dragCounter - 1); - } - } - - function handleDrop(e) { - e.preventDefault(); - - setDragCounter(0); - - if (modalOpen()) return; - - const roomId = navigation.selectedRoomId; - if (!roomId) return; - - const { files } = e.dataTransfer; - if (!files?.length) return; - const file = files[0]; - initMatrix.roomsInput.setAttachment(roomId, file); - initMatrix.roomsInput.emit(cons.events.roomsInput.ATTACHMENT_SET, file); - } - return ( -
      -
      - + +
      +
      + +
      +
      + +
      + + + +
      -
      - -
      - - - - - -
      + ); } diff --git a/src/app/utils/AsyncSearch.ts b/src/app/utils/AsyncSearch.ts new file mode 100644 index 000000000..4baacf045 --- /dev/null +++ b/src/app/utils/AsyncSearch.ts @@ -0,0 +1,102 @@ +export type NormalizeOption = { + caseSensitive?: boolean; + normalizeUnicode?: boolean; + ignoreWhitespace?: boolean; +}; + +export type MatchQueryOption = { + contain?: boolean; +}; + +export type AsyncSearchOption = { + limit?: number; +}; + +export type MatchHandler = ( + item: TSearchItem, + query: string +) => boolean; +export type ResultHandler = ( + results: TSearchItem[], + query: string +) => void; + +export type AsyncSearchHandler = (query: string) => void; +export type TerminateAsyncSearch = () => void; + +export const normalize = (str: string, options?: NormalizeOption) => { + let nStr = str.normalize(options?.normalizeUnicode ?? true ? 'NFKC' : 'NFC'); + if (!options?.caseSensitive) nStr = nStr.toLocaleLowerCase(); + if (options?.ignoreWhitespace ?? true) nStr = nStr.replace(/\s/g, ''); + return nStr; +}; + +export const matchQuery = (item: string, query: string, options?: MatchQueryOption): boolean => { + if (options?.contain) return item.indexOf(query) !== -1; + return item.startsWith(query); +}; + +export const AsyncSearch = ( + list: TSearchItem[], + match: MatchHandler, + onResult: ResultHandler, + options?: AsyncSearchOption +): [AsyncSearchHandler, TerminateAsyncSearch] => { + let resultList: TSearchItem[] = []; + + let searchIndex = 0; + let sessionStartTimestamp = 0; + let sessionScheduleId: number | undefined; + + const terminateSearch: TerminateAsyncSearch = () => { + resultList = []; + searchIndex = 0; + sessionStartTimestamp = 0; + if (sessionScheduleId) clearTimeout(sessionScheduleId); + sessionScheduleId = undefined; + }; + + const find = (query: string, sessionTimestamp: number) => { + const findingCount = resultList.length; + sessionScheduleId = undefined; + // return if find session got reset + if (sessionTimestamp !== sessionStartTimestamp) return; + + sessionStartTimestamp = window.performance.now(); + for (; searchIndex < list.length; searchIndex += 1) { + if (match(list[searchIndex], query)) { + resultList.push(list[searchIndex]); + if (typeof options?.limit === 'number' && resultList.length >= options.limit) { + break; + } + } + + const matchFinishTime = window.performance.now(); + if (matchFinishTime - sessionStartTimestamp > 8) { + const currentFindingCount = resultList.length; + const thisSessionTimestamp = sessionStartTimestamp; + if (findingCount !== currentFindingCount) onResult(resultList, query); + + searchIndex += 1; + sessionScheduleId = window.setTimeout(() => find(query, thisSessionTimestamp), 1); + return; + } + } + + if (findingCount !== resultList.length || findingCount === 0) { + onResult(resultList, query); + } + terminateSearch(); + }; + + const search: AsyncSearchHandler = (query: string) => { + terminateSearch(); + if (query === '') { + onResult(resultList, query); + return; + } + find(query, sessionStartTimestamp); + }; + + return [search, terminateSearch]; +}; diff --git a/src/app/utils/blurHash.ts b/src/app/utils/blurHash.ts new file mode 100644 index 000000000..0de5a9225 --- /dev/null +++ b/src/app/utils/blurHash.ts @@ -0,0 +1,19 @@ +import { encode } from 'blurhash'; + +export const MATRIX_BLUR_HASH_PROPERTY_NAME = 'xyz.amorgan.blurhash'; + +export const encodeBlurHash = ( + img: HTMLImageElement | HTMLVideoElement, + width?: number, + height?: number +): string | undefined => { + const canvas = document.createElement('canvas'); + canvas.width = width || img.width; + canvas.height = height || img.height; + const context = canvas.getContext('2d'); + + if (!context) return undefined; + context.drawImage(img, 0, 0, canvas.width, canvas.height); + const data = context.getImageData(0, 0, canvas.width, canvas.height); + return encode(data.data, data.width, data.height, 4, 4); +}; diff --git a/src/app/utils/common.ts b/src/app/utils/common.ts new file mode 100644 index 000000000..d3804ae8e --- /dev/null +++ b/src/app/utils/common.ts @@ -0,0 +1,32 @@ +import { IconName, IconSrc } from 'folds'; + +export const bytesToSize = (bytes: number): string => { + const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB']; + if (bytes === 0) return '0KB'; + + let sizeIndex = Math.floor(Math.log(bytes) / Math.log(1000)); + + if (sizeIndex === 0) sizeIndex = 1; + + return `${(bytes / 1000 ** sizeIndex).toFixed(1)} ${sizes[sizeIndex]}`; +}; + +export const getFileTypeIcon = (icons: Record, fileType: string): IconSrc => { + const type = fileType.toLowerCase(); + if (type.startsWith('audio')) { + return icons.Play; + } + if (type.startsWith('video')) { + return icons.Vlc; + } + if (type.startsWith('image')) { + return icons.Photo; + } + return icons.File; +}; + +export const fulfilledPromiseSettledResult = (prs: PromiseSettledResult[]): T[] => + prs.reduce((values, pr) => { + if (pr.status === 'fulfilled') values.push(pr.value); + return values; + }, []); diff --git a/src/app/utils/disposable.ts b/src/app/utils/disposable.ts new file mode 100644 index 000000000..7840fe494 --- /dev/null +++ b/src/app/utils/disposable.ts @@ -0,0 +1,8 @@ +export type DisposeCallback = (...args: Q) => R; +export type DisposableContext

      = ( + ...args: P +) => DisposeCallback; + +export const disposable =

      ( + context: DisposableContext +) => context; diff --git a/src/app/utils/dom.ts b/src/app/utils/dom.ts new file mode 100644 index 000000000..d717adf2e --- /dev/null +++ b/src/app/utils/dom.ts @@ -0,0 +1,133 @@ +export const targetFromEvent = (evt: Event, selector: string): Element | undefined => { + const targets = evt.composedPath() as Element[]; + return targets.find((target) => target.matches?.(selector)); +}; + +export const editableActiveElement = (): boolean => + !!document.activeElement && + /^(input)|(textarea)$/.test(document.activeElement.nodeName.toLowerCase()); + +export const inVisibleScrollArea = ( + scrollElement: HTMLElement, + childElement: HTMLElement +): boolean => { + const scrollTop = scrollElement.offsetTop + scrollElement.scrollTop; + const scrollBottom = scrollTop + scrollElement.offsetHeight; + + const childTop = childElement.offsetTop; + const childBottom = childTop + childElement.clientHeight; + + if (childTop >= scrollTop && childTop < scrollBottom) return true; + if (childTop < scrollTop && childBottom > scrollTop) return true; + return false; +}; + +export type FilesOrFile = T extends true ? File[] : File; + +export const selectFile = ( + accept: string, + multiple?: M +): Promise | undefined> => + new Promise((resolve) => { + const input = document.createElement('input'); + input.type = 'file'; + if (accept) input.accept = accept; + if (multiple) input.multiple = true; + + const changeHandler = () => { + const fileList = input.files; + if (!fileList) { + resolve(undefined); + } else { + const files: File[] = [...fileList].filter((file) => file); + resolve((multiple ? files : files[0]) as FilesOrFile); + } + input.removeEventListener('change', changeHandler); + }; + + input.addEventListener('change', changeHandler); + input.click(); + }); + +export const getDataTransferFiles = (dataTransfer: DataTransfer): File[] | undefined => { + const fileList = dataTransfer.files; + const files = [...fileList].filter((file) => file); + if (files.length === 0) return undefined; + return files; +}; + +export const getImageUrlBlob = async (url: string) => { + const res = await fetch(url); + const blob = await res.blob(); + return blob; +}; + +export const getImageFileUrl = (fileOrBlob: File | Blob) => URL.createObjectURL(fileOrBlob); + +export const getVideoFileUrl = (fileOrBlob: File | Blob) => URL.createObjectURL(fileOrBlob); + +export const loadImageElement = (url: string): Promise => + new Promise((resolve, reject) => { + const img = document.createElement('img'); + img.onload = () => resolve(img); + img.onerror = (err) => reject(err); + img.src = url; + }); + +export const loadVideoElement = (url: string): Promise => + new Promise((resolve, reject) => { + const video = document.createElement('video'); + video.preload = 'metadata'; + video.playsInline = true; + video.muted = true; + + video.onloadeddata = () => { + resolve(video); + video.pause(); + }; + video.onerror = (e) => { + reject(e); + }; + + video.src = url; + video.load(); + video.play(); + }); + +export const getThumbnailDimensions = (width: number, height: number): [number, number] => { + const MAX_WIDTH = 400; + const MAX_HEIGHT = 300; + let targetWidth = width; + let targetHeight = height; + if (targetHeight > MAX_HEIGHT) { + targetWidth = Math.floor(targetWidth * (MAX_HEIGHT / targetHeight)); + targetHeight = MAX_HEIGHT; + } + if (targetWidth > MAX_WIDTH) { + targetHeight = Math.floor(targetHeight * (MAX_WIDTH / targetWidth)); + targetWidth = MAX_WIDTH; + } + return [targetWidth, targetHeight]; +}; + +export const getThumbnail = ( + img: HTMLImageElement | SVGImageElement | HTMLVideoElement, + width: number, + height: number, + thumbnailMimeType?: string +): Promise => + new Promise((resolve) => { + const canvas = document.createElement('canvas'); + canvas.width = width; + canvas.height = height; + const context = canvas.getContext('2d'); + if (!context) { + resolve(undefined); + return; + } + context.drawImage(img, 0, 0, width, height); + + canvas.toBlob((thumbnail) => { + resolve(thumbnail ?? undefined); + }, thumbnailMimeType ?? 'image/jpeg'); + }); diff --git a/src/app/utils/key-symbol.ts b/src/app/utils/key-symbol.ts new file mode 100644 index 000000000..7e758fd94 --- /dev/null +++ b/src/app/utils/key-symbol.ts @@ -0,0 +1,6 @@ +export enum KeySymbol { + Command = '⌘', + Shift = '⇧', + Option = '⌥', + Control = '⌃', +} diff --git a/src/app/utils/keyboard.ts b/src/app/utils/keyboard.ts new file mode 100644 index 000000000..56eeb9fcb --- /dev/null +++ b/src/app/utils/keyboard.ts @@ -0,0 +1,25 @@ +import isHotkey from 'is-hotkey'; +import { KeyboardEventHandler } from 'react'; + +export interface KeyboardEventLike { + key: string; + which: number; + altKey: boolean; + ctrlKey: boolean; + metaKey: boolean; + shiftKey: boolean; + preventDefault(): void; +} + +export const onTabPress = (evt: KeyboardEventLike, callback: () => void) => { + if (isHotkey('tab', evt)) { + evt.preventDefault(); + callback(); + } +}; + +export const preventScrollWithArrowKey: KeyboardEventHandler = (evt) => { + if (isHotkey(['arrowup', 'arrowright', 'arrowdown', 'arrowleft'], evt)) { + evt.preventDefault(); + } +}; diff --git a/src/app/utils/matrix.ts b/src/app/utils/matrix.ts new file mode 100644 index 000000000..7f2fc0f24 --- /dev/null +++ b/src/app/utils/matrix.ts @@ -0,0 +1,118 @@ +import { EncryptedAttachmentInfo, encryptAttachment } from 'browser-encrypt-attachment'; +import { MatrixClient, MatrixError, UploadProgress, UploadResponse } from 'matrix-js-sdk'; +import { IImageInfo, IThumbnailContent, IVideoInfo } from '../../types/matrix/common'; + +export const matchMxId = (id: string): RegExpMatchArray | null => + id.match(/^([@!$+#])(\S+):(\S+)$/); + +export const validMxId = (id: string): boolean => !!matchMxId(id); + +export const getMxIdServer = (userId: string): string | undefined => matchMxId(userId)?.[3]; + +export const getMxIdLocalPart = (userId: string): string | undefined => matchMxId(userId)?.[2]; + +export const isUserId = (id: string): boolean => validMxId(id) && id.startsWith('@'); + +export const getImageInfo = (img: HTMLImageElement, fileOrBlob: File | Blob): IImageInfo => { + const info: IImageInfo = {}; + info.w = img.width; + info.h = img.height; + info.mimetype = fileOrBlob.type; + info.size = fileOrBlob.size; + return info; +}; + +export const getVideoInfo = (video: HTMLVideoElement, fileOrBlob: File | Blob): IVideoInfo => { + const info: IVideoInfo = {}; + info.duration = Number.isNaN(video.duration) ? undefined : video.duration; + info.w = video.videoWidth; + info.h = video.videoHeight; + info.mimetype = fileOrBlob.type; + info.size = fileOrBlob.size; + return info; +}; + +export const getThumbnailContent = (thumbnailInfo: { + thumbnail: File | Blob; + encInfo: EncryptedAttachmentInfo | undefined; + mxc: string; + width: number; + height: number; +}): IThumbnailContent => { + const { thumbnail, encInfo, mxc, width, height } = thumbnailInfo; + + const content: IThumbnailContent = { + thumbnail_info: { + mimetype: thumbnail.type, + size: thumbnail.size, + w: width, + h: height, + }, + }; + if (encInfo) { + content.thumbnail_file = { + ...encInfo, + url: mxc, + }; + } else { + content.thumbnail_url = mxc; + } + return content; +}; + +export const encryptFile = async ( + file: File | Blob +): Promise<{ + encInfo: EncryptedAttachmentInfo; + file: File; + originalFile: File | Blob; +}> => { + const dataBuffer = await file.arrayBuffer(); + const encryptedAttachment = await encryptAttachment(dataBuffer); + const encFile = new File([encryptedAttachment.data], file.name, { + type: file.type, + }); + return { + encInfo: encryptedAttachment.info, + file: encFile, + originalFile: file, + }; +}; + +export type TUploadContent = File | Blob; + +export type ContentUploadOptions = { + name?: string; + fileType?: string; + hideFilename?: boolean; + onPromise?: (promise: Promise) => void; + onProgress?: (progress: UploadProgress) => void; + onSuccess: (mxc: string) => void; + onError: (error: MatrixError) => void; +}; + +export const uploadContent = async ( + mx: MatrixClient, + file: TUploadContent, + options: ContentUploadOptions +) => { + const { name, fileType, hideFilename, onProgress, onPromise, onSuccess, onError } = options; + + const uploadPromise = mx.uploadContent(file, { + name, + type: fileType, + includeFilename: !hideFilename, + progressHandler: onProgress, + }); + onPromise?.(uploadPromise); + try { + const data = await uploadPromise; + const mxc = data.content_uri; + if (mxc) onSuccess(mxc); + else onError(new MatrixError(data)); + } catch (e: any) { + const error = typeof e?.message === 'string' ? e.message : undefined; + const errcode = typeof e?.name === 'string' ? e.message : undefined; + onError(new MatrixError({ error, errcode })); + } +}; diff --git a/src/app/utils/mimeTypes.ts b/src/app/utils/mimeTypes.ts new file mode 100644 index 000000000..c432bdc3c --- /dev/null +++ b/src/app/utils/mimeTypes.ts @@ -0,0 +1,47 @@ +// https://github.com/matrix-org/matrix-react-sdk/blob/cd15e08fc285da42134817cce50de8011809cd53/src/utils/blobs.ts +export const ALLOWED_BLOB_MIMETYPES = [ + 'image/jpeg', + 'image/gif', + 'image/png', + 'image/apng', + 'image/webp', + 'image/avif', + + 'video/mp4', + 'video/webm', + 'video/ogg', + 'video/quicktime', + + 'audio/mp4', + 'audio/webm', + 'audio/aac', + 'audio/mpeg', + 'audio/ogg', + 'audio/wave', + 'audio/wav', + 'audio/x-wav', + 'audio/x-pn-wav', + 'audio/flac', + 'audio/x-flac', +]; + +export const getBlobSafeMimeType = (mimeType: string) => { + if (typeof mimeType !== 'string') return 'application/octet-stream'; + const [type] = mimeType.split(';'); + if (!ALLOWED_BLOB_MIMETYPES.includes(type)) { + return 'application/octet-stream'; + } + // Required for Chromium browsers + if (type === 'video/quicktime') { + return 'video/mp4'; + } + return type; +}; + +export const safeFile = (f: File) => { + const safeType = getBlobSafeMimeType(f.type); + if (safeType !== f.type) { + return new File([f], f.name, { type: safeType }); + } + return f; +}; diff --git a/src/app/utils/room.ts b/src/app/utils/room.ts new file mode 100644 index 000000000..daf956009 --- /dev/null +++ b/src/app/utils/room.ts @@ -0,0 +1,265 @@ +import { IconName, IconSrc } from 'folds'; + +import { + IPushRule, + IPushRules, + JoinRule, + MatrixClient, + MatrixEvent, + NotificationCountType, + Room, +} from 'matrix-js-sdk'; +import { AccountDataEvent } from '../../types/matrix/accountData'; +import { + NotificationType, + RoomToParents, + RoomType, + StateEvent, + UnreadInfo, +} from '../../types/matrix/room'; + +export const getStateEvent = ( + room: Room, + eventType: StateEvent, + stateKey = '' +): MatrixEvent | undefined => room.currentState.getStateEvents(eventType, stateKey) ?? undefined; + +export const getStateEvents = (room: Room, eventType: StateEvent): MatrixEvent[] => + room.currentState.getStateEvents(eventType); + +export const getAccountData = ( + mx: MatrixClient, + eventType: AccountDataEvent +): MatrixEvent | undefined => mx.getAccountData(eventType); + +export const getMDirects = (mDirectEvent: MatrixEvent): Set => { + const roomIds = new Set(); + const userIdToDirects = mDirectEvent?.getContent(); + + if (userIdToDirects === undefined) return roomIds; + + Object.keys(userIdToDirects).forEach((userId) => { + const directs = userIdToDirects[userId]; + if (Array.isArray(directs)) { + directs.forEach((id) => { + if (typeof id === 'string') roomIds.add(id); + }); + } + }); + + return roomIds; +}; + +export const isDirectInvite = (room: Room | null, myUserId: string | null): boolean => { + if (!room || !myUserId) return false; + const me = room.getMember(myUserId); + const memberEvent = me?.events?.member; + const content = memberEvent?.getContent(); + return content?.is_direct === true; +}; + +export const isSpace = (room: Room | null): boolean => { + if (!room) return false; + const event = getStateEvent(room, StateEvent.RoomCreate); + if (!event) return false; + return event.getContent().type === RoomType.Space; +}; + +export const isRoom = (room: Room | null): boolean => { + if (!room) return false; + const event = getStateEvent(room, StateEvent.RoomCreate); + if (!event) return false; + return event.getContent().type === undefined; +}; + +export const isUnsupportedRoom = (room: Room | null): boolean => { + if (!room) return false; + const event = getStateEvent(room, StateEvent.RoomCreate); + if (!event) return true; // Consider room unsupported if m.room.create event doesn't exist + return event.getContent().type !== undefined && event.getContent().type !== RoomType.Space; +}; + +export function isValidChild(mEvent: MatrixEvent): boolean { + return mEvent.getType() === StateEvent.SpaceChild && Object.keys(mEvent.getContent()).length > 0; +} + +export const getAllParents = (roomToParents: RoomToParents, roomId: string): Set => { + const allParents = new Set(); + + const addAllParentIds = (rId: string) => { + if (allParents.has(rId)) return; + allParents.add(rId); + + const parents = roomToParents.get(rId); + parents?.forEach((id) => addAllParentIds(id)); + }; + addAllParentIds(roomId); + allParents.delete(roomId); + return allParents; +}; + +export const getSpaceChildren = (room: Room) => + getStateEvents(room, StateEvent.SpaceChild).reduce((filtered, mEvent) => { + const stateKey = mEvent.getStateKey(); + if (isValidChild(mEvent) && stateKey) { + filtered.push(stateKey); + } + return filtered; + }, []); + +export const mapParentWithChildren = ( + roomToParents: RoomToParents, + roomId: string, + children: string[] +) => { + const allParents = getAllParents(roomToParents, roomId); + children.forEach((childId) => { + if (allParents.has(childId)) { + // Space cycle detected. + return; + } + const parents = roomToParents.get(childId) ?? new Set(); + parents.add(roomId); + roomToParents.set(childId, parents); + }); +}; + +export const getRoomToParents = (mx: MatrixClient): RoomToParents => { + const map: RoomToParents = new Map(); + mx.getRooms() + .filter((room) => isSpace(room)) + .forEach((room) => mapParentWithChildren(map, room.roomId, getSpaceChildren(room))); + + return map; +}; + +export const isMutedRule = (rule: IPushRule) => + rule.actions[0] === 'dont_notify' && rule.conditions?.[0]?.kind === 'event_match'; + +export const findMutedRule = (overrideRules: IPushRule[], roomId: string) => + overrideRules.find((rule) => rule.rule_id === roomId && isMutedRule(rule)); + +export const getNotificationType = (mx: MatrixClient, roomId: string): NotificationType => { + let roomPushRule: IPushRule | undefined; + try { + roomPushRule = mx.getRoomPushRule('global', roomId); + } catch { + roomPushRule = undefined; + } + + if (!roomPushRule) { + const overrideRules = mx.getAccountData('m.push_rules')?.getContent() + ?.global?.override; + if (!overrideRules) return NotificationType.Default; + + return findMutedRule(overrideRules, roomId) ? NotificationType.Mute : NotificationType.Default; + } + + if (roomPushRule.actions[0] === 'notify') return NotificationType.AllMessages; + return NotificationType.MentionsAndKeywords; +}; + +export const isNotificationEvent = (mEvent: MatrixEvent) => { + const eType = mEvent.getType(); + if ( + ['m.room.create', 'm.room.message', 'm.room.encrypted', 'm.room.member', 'm.sticker'].find( + (type) => type === eType + ) + ) + return false; + if (eType === 'm.room.member') return false; + + if (mEvent.isRedacted()) return false; + if (mEvent.getRelation()?.rel_type === 'm.replace') return false; + + return true; +}; + +export const roomHaveUnread = (mx: MatrixClient, room: Room) => { + const userId = mx.getUserId(); + if (!userId) return false; + const readUpToId = room.getEventReadUpTo(userId); + const liveEvents = room.getLiveTimeline().getEvents(); + + if (liveEvents[liveEvents.length - 1]?.getSender() === userId) { + return false; + } + + for (let i = liveEvents.length - 1; i >= 0; i -= 1) { + const event = liveEvents[i]; + if (!event) return false; + if (event.getId() === readUpToId) return false; + if (isNotificationEvent(event)) return true; + } + return true; +}; + +export const getUnreadInfo = (room: Room): UnreadInfo => { + const total = room.getUnreadNotificationCount(NotificationCountType.Total); + const highlight = room.getUnreadNotificationCount(NotificationCountType.Highlight); + return { + roomId: room.roomId, + highlight, + total: highlight > total ? highlight : total, + }; +}; + +export const getUnreadInfos = (mx: MatrixClient): UnreadInfo[] => { + const unreadInfos = mx.getRooms().reduce((unread, room) => { + if (room.isSpaceRoom()) return unread; + if (room.getMyMembership() !== 'join') return unread; + if (getNotificationType(mx, room.roomId) === NotificationType.Mute) return unread; + + if (roomHaveUnread(mx, room)) { + unread.push(getUnreadInfo(room)); + } + + return unread; + }, []); + return unreadInfos; +}; + +export const joinRuleToIconSrc = ( + icons: Record, + joinRule: JoinRule, + space: boolean +): IconSrc | undefined => { + if (joinRule === JoinRule.Restricted) { + return space ? icons.Space : icons.Hash; + } + if (joinRule === JoinRule.Knock) { + return space ? icons.SpaceLock : icons.HashLock; + } + if (joinRule === JoinRule.Invite) { + return space ? icons.SpaceLock : icons.HashLock; + } + if (joinRule === JoinRule.Public) { + return space ? icons.SpaceGlobe : icons.HashGlobe; + } + return undefined; +}; + +export const getRoomAvatarUrl = (mx: MatrixClient, room: Room): string | undefined => { + const url = + room.getAvatarFallbackMember()?.getAvatarUrl(mx.baseUrl, 32, 32, 'crop', undefined, false) ?? + undefined; + if (url) return url; + return room.getAvatarUrl(mx.baseUrl, 32, 32, 'crop') ?? undefined; +}; + +export const parseReplyBody = (userId: string, body: string) => + `> <${userId}> ${body.replace(/\n/g, '\n> ')}\n\n`; + +export const parseReplyFormattedBody = ( + roomId: string, + userId: string, + eventId: string, + formattedBody: string +): string => { + const replyToLink = `In reply to`; + const userLink = `${userId}`; + + return `

      ${replyToLink}${userLink}
      ${formattedBody}
      `; +}; diff --git a/src/app/utils/sanitize.ts b/src/app/utils/sanitize.ts new file mode 100644 index 000000000..555089de2 --- /dev/null +++ b/src/app/utils/sanitize.ts @@ -0,0 +1,10 @@ +export const sanitizeText = (body: string) => { + const tagsToReplace: Record = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''', + }; + return body.replace(/[&<>'"]/g, (tag) => tagsToReplace[tag] || tag); +}; diff --git a/src/app/utils/user-agent.ts b/src/app/utils/user-agent.ts new file mode 100644 index 000000000..61a903f5a --- /dev/null +++ b/src/app/utils/user-agent.ts @@ -0,0 +1,5 @@ +import { UAParser } from 'ua-parser-js'; + +export const ua = () => UAParser(window.navigator.userAgent); + +export const isMacOS = () => ua().os.name === 'Mac OS'; diff --git a/src/client/initMatrix.js b/src/client/initMatrix.js index 420f3154e..9b8d1d82e 100644 --- a/src/client/initMatrix.js +++ b/src/client/initMatrix.js @@ -23,6 +23,11 @@ class InitMatrix extends EventEmitter { } async init() { + if (this.matrixClient) { + console.warn('Client is already initialized!') + return; + } + await this.startClient(); this.setupSync(); this.listenEvents(); diff --git a/src/client/mx.ts b/src/client/mx.ts new file mode 100644 index 000000000..30909458b --- /dev/null +++ b/src/client/mx.ts @@ -0,0 +1,7 @@ +import { MatrixClient } from 'matrix-js-sdk'; +import initMatrix from './initMatrix'; + +export const mx = (): MatrixClient => { + if (!initMatrix.matrixClient) console.error('Matrix client is used before initialization!'); + return initMatrix.matrixClient!; +}; diff --git a/src/client/state/RoomList.js b/src/client/state/RoomList.js index a1570480a..fc137ae26 100644 --- a/src/client/state/RoomList.js +++ b/src/client/state/RoomList.js @@ -220,12 +220,6 @@ class RoomList extends EventEmitter { this.inviteRooms.clear(); this.matrixClient.getRooms().forEach((room) => { const { roomId } = room; - const tombstone = room.currentState.events.get('m.room.tombstone'); - if (tombstone?.get('') !== undefined) { - const repRoomId = tombstone.get('').getContent().replacement_room; - const repRoomMembership = this.matrixClient.getRoom(repRoomId)?.getMyMembership(); - if (repRoomMembership === 'join') return; - } if (room.getMyMembership() === 'invite') { if (this._isDMInvite(room)) this.inviteDirects.add(roomId); diff --git a/src/client/state/settings.js b/src/client/state/settings.js index 32f55fcc6..af2e279ad 100644 --- a/src/client/state/settings.js +++ b/src/client/state/settings.js @@ -1,7 +1,9 @@ +import { lightTheme } from 'folds'; import EventEmitter from 'events'; import appDispatcher from '../dispatcher'; import cons from './cons'; +import { darkTheme, butterTheme, silverTheme } from '../../colors.css'; function getSettings() { const settings = localStorage.getItem('settings'); @@ -20,6 +22,7 @@ class Settings extends EventEmitter { constructor() { super(); + this.themeClasses = [lightTheme, silverTheme, darkTheme, butterTheme]; this.themes = ['', 'silver-theme', 'dark-theme', 'butter-theme']; this.themeIndex = this.getThemeIndex(); @@ -31,6 +34,10 @@ class Settings extends EventEmitter { this._showNotifications = this.getShowNotifications(); this.isNotificationSounds = this.getIsNotificationSounds(); + this.darkModeQueryList = window.matchMedia('(prefers-color-scheme: dark)'); + + this.darkModeQueryList.addEventListener('change', () => this.applyTheme()) + this.isTouchScreenDevice = ('ontouchstart' in window) || (navigator.maxTouchPoints > 0) || (navigator.msMaxTouchPoints > 0); } @@ -49,20 +56,19 @@ class Settings extends EventEmitter { } _clearTheme() { - document.body.classList.remove('system-theme'); - this.themes.forEach((themeName) => { - if (themeName === '') return; - document.body.classList.remove(themeName); + this.themes.forEach((themeName, index) => { + if (themeName !== '') document.body.classList.remove(themeName); + document.body.classList.remove(this.themeClasses[index]); }); } applyTheme() { this._clearTheme(); - if (this.useSystemTheme) { - document.body.classList.add('system-theme'); - } else if (this.themes[this.themeIndex]) { - document.body.classList.add(this.themes[this.themeIndex]); - } + const autoThemeIndex = this.darkModeQueryList.matches ? 2 : 0; + const themeIndex = this.useSystemTheme ? autoThemeIndex : this.themeIndex; + if (this.themes[themeIndex] === undefined) return + if (this.themes[themeIndex]) document.body.classList.add(this.themes[themeIndex]); + document.body.classList.add(this.themeClasses[themeIndex]); } setTheme(themeIndex) { diff --git a/src/colors.css.ts b/src/colors.css.ts new file mode 100644 index 000000000..9b854bef7 --- /dev/null +++ b/src/colors.css.ts @@ -0,0 +1,238 @@ +import { createTheme } from '@vanilla-extract/css'; +import { color } from 'folds'; + +export const silverTheme = createTheme(color, { + Background: { + Container: '#E6E6E6', + ContainerHover: '#DADADA', + ContainerActive: '#CECECE', + ContainerLine: '#C2C2C2', + OnContainer: '#000000', + }, + + Surface: { + Container: '#F2F2F2', + ContainerHover: '#E6E6E6', + ContainerActive: '#DADADA', + ContainerLine: '#CECECE', + OnContainer: '#000000', + }, + + SurfaceVariant: { + Container: '#E6E6E6', + ContainerHover: '#DADADA', + ContainerActive: '#CECECE', + ContainerLine: '#C2C2C2', + OnContainer: '#000000', + }, + + Primary: { + Main: '#1858D5', + MainHover: '#164FC0', + MainActive: '#144BB5', + MainLine: '#1346AA', + OnMain: '#FFFFFF', + Container: '#E8EEFB', + ContainerHover: '#DCE6F9', + ContainerActive: '#D1DEF7', + ContainerLine: '#C5D5F5', + OnContainer: '#113E95', + }, + + Secondary: { + Main: '#000000', + MainHover: '#0C0C0C', + MainActive: '#181818', + MainLine: '#303030', + OnMain: '#F2F2F2', + Container: '#CECECE', + ContainerHover: '#C2C2C2', + ContainerActive: '#B5B5B5', + ContainerLine: '#A9A9A9', + OnContainer: '#0C0C0C', + }, + + Success: { + Main: '#00844C', + MainHover: '#007744', + MainActive: '#007041', + MainLine: '#006A3D', + OnMain: '#FFFFFF', + Container: '#E5F3ED', + ContainerHover: '#D9EDE4', + ContainerActive: '#CCE6DB', + ContainerLine: '#BFE0D2', + OnContainer: '#005C35', + }, + + Warning: { + Main: '#A85400', + MainHover: '#974C00', + MainActive: '#8F4700', + MainLine: '#864300', + OnMain: '#FFFFFF', + Container: '#F6EEE5', + ContainerHover: '#F2E5D9', + ContainerActive: '#EEDDCC', + ContainerLine: '#E9D4BF', + OnContainer: '#763B00', + }, + + Critical: { + Main: '#C40E0E', + MainHover: '#AC0909', + MainActive: '#A60C0C', + MainLine: '#9C0B0B', + OnMain: '#FFFFFF', + Container: '#F9E7E7', + ContainerHover: '#F6DBDB', + ContainerActive: '#F3CFCF', + ContainerLine: '#F0C3C3', + OnContainer: '#890A0A', + }, + + Other: { + FocusRing: 'rgba(0 0 0 / 50%)', + Shadow: 'rgba(0 0 0 / 20%)', + Overlay: 'rgba(0 0 0 / 50%)', + }, +}); + +const darkThemeData = { + Background: { + Container: '#15171A', + ContainerHover: '#1F2326', + ContainerActive: '#2A2E33', + ContainerLine: '#343A40', + OnContainer: '#ffffff', + }, + + Surface: { + Container: '#1F2326', + ContainerHover: '#2A2E33', + ContainerActive: '#343A40', + ContainerLine: '#3F464D', + OnContainer: '#ffffff', + }, + + SurfaceVariant: { + Container: '#2A2E33', + ContainerHover: '#343A40', + ContainerActive: '#3F464D', + ContainerLine: '#495159', + OnContainer: '#ffffff', + }, + + Primary: { + Main: '#BDB6EC', + MainHover: '#B2AAE9', + MainActive: '#ADA3E8', + MainLine: '#A79DE6', + OnMain: '#2C2843', + Container: '#413C65', + ContainerHover: '#494370', + ContainerActive: '#50497B', + ContainerLine: '#575086', + OnContainer: '#E3E1F7', + }, + + Secondary: { + Main: '#D1E8FF', + MainHover: '#BCD1E5', + MainActive: '#B2C5D9', + MainLine: '#A7BACC', + OnMain: '#15171A', + Container: '#343A40', + ContainerHover: '#3F464D', + ContainerActive: '#495159', + ContainerLine: '#545D66', + OnContainer: '#C7DCF2', + }, + + Success: { + Main: '#85E0BA', + MainHover: '#70DBAF', + MainActive: '#66D9A9', + MainLine: '#5CD6A3', + OnMain: '#0F3D2A', + Container: '#175C3F', + ContainerHover: '#1A6646', + ContainerActive: '#1C704D', + ContainerLine: '#1F7A54', + OnContainer: '#CCF2E2', + }, + + Warning: { + Main: '#E3BA91', + MainHover: '#DFAF7E', + MainActive: '#DDA975', + MainLine: '#DAA36C', + OnMain: '#3F2A15', + Container: '#5E3F20', + ContainerHover: '#694624', + ContainerActive: '#734D27', + ContainerLine: '#7D542B', + OnContainer: '#F3E2D1', + }, + + Critical: { + Main: '#E69D9D', + MainHover: '#E28D8D', + MainActive: '#E08585', + MainLine: '#DE7D7D', + OnMain: '#401C1C', + Container: '#602929', + ContainerHover: '#6B2E2E', + ContainerActive: '#763333', + ContainerLine: '#803737', + OnContainer: '#F5D6D6', + }, + + Other: { + FocusRing: 'rgba(255, 255, 255, 0.5)', + Shadow: 'rgba(0, 0, 0, 1)', + Overlay: 'rgba(0, 0, 0, 0.6)', + }, +}; + +export const darkTheme = createTheme(color, darkThemeData); + +export const butterTheme = createTheme(color, { + ...darkThemeData, + Background: { + Container: '#1A1916', + ContainerHover: '#262621', + ContainerActive: '#33322C', + ContainerLine: '#403F38', + OnContainer: '#FFFBDE', + }, + + Surface: { + Container: '#262621', + ContainerHover: '#33322C', + ContainerActive: '#403F38', + ContainerLine: '#4D4B43', + OnContainer: '#FFFBDE', + }, + + SurfaceVariant: { + Container: '#33322C', + ContainerHover: '#403F38', + ContainerActive: '#4D4B43', + ContainerLine: '#59584E', + OnContainer: '#FFFBDE', + }, + + Secondary: { + Main: '#FFFBDE', + MainHover: '#E5E2C8', + MainActive: '#D9D5BD', + MainLine: '#CCC9B2', + OnMain: '#1A1916', + Container: '#403F38', + ContainerHover: '#4D4B43', + ContainerActive: '#59584E', + ContainerLine: '#666459', + OnContainer: '#F2EED3', + }, +}); diff --git a/src/ext.d.ts b/src/ext.d.ts new file mode 100644 index 000000000..55f59327c --- /dev/null +++ b/src/ext.d.ts @@ -0,0 +1,23 @@ +declare module 'browser-encrypt-attachment' { + export interface EncryptedAttachmentInfo { + v: string; + key: { + alg: string; + key_ops: string[]; + kty: string; + k: string; + ext: boolean; + }; + iv: string; + hashes: { + [alg: string]: string; + }; + } + + export interface EncryptedAttachment { + data: ArrayBuffer; + info: EncryptedAttachmentInfo; + } + + export function encryptAttachment(dataBuffer: ArrayBuffer): Promise; +} diff --git a/src/index.jsx b/src/index.jsx index a252f6f05..e7256e251 100644 --- a/src/index.jsx +++ b/src/index.jsx @@ -1,5 +1,13 @@ +/* eslint-disable import/first */ import React from 'react'; import ReactDom from 'react-dom'; +import { enableMapSet } from 'immer'; +import '@fontsource/inter/variable.css'; +import 'folds/dist/style.css'; +import { configClass, varsClass } from 'folds'; + +enableMapSet(); + import './font'; import './index.scss'; @@ -7,6 +15,8 @@ import settings from './client/state/settings'; import App from './app/pages/App'; +document.body.classList.add(configClass, varsClass); + settings.applyTheme(); ReactDom.render(, document.getElementById('root')); diff --git a/src/index.scss b/src/index.scss index 39d0612b0..93443fe91 100644 --- a/src/index.scss +++ b/src/index.scss @@ -1,14 +1,20 @@ @use './app/partials/screen'; -:root { +@font-face { + font-family: Twemoji; + src: url('../public/font/Twemoji.Mozilla.v.7.0.woff2'), + url('../public/font/Twemoji.Mozilla.v0.7.0.ttf'); + font-display: swap; +} +:root { /* background color | --bg-[background type]: value */ - --bg-surface: #FFFFFF; - --bg-surface-transparent: #FFFFFF00; - --bg-surface-low: #F6F6F6; - --bg-surface-low-transparent: #F6F6F600; - --bg-surface-extra-low: #F6F6F6; - --bg-surface-extra-low-transparent: #F6F6F600; + --bg-surface: #ffffff; + --bg-surface-transparent: #ffffff00; + --bg-surface-low: #f6f6f6; + --bg-surface-low-transparent: #f6f6f600; + --bg-surface-extra-low: #f6f6f6; + --bg-surface-extra-low-transparent: #f6f6f600; --bg-surface-hover: rgba(0, 0, 0, 3%); --bg-surface-active: rgba(0, 0, 0, 5%); --bg-surface-border: rgba(0, 0, 0, 6%); @@ -22,7 +28,7 @@ --bg-positive-hover: rgba(69, 184, 59, 8%); --bg-positive-active: rgba(69, 184, 59, 15%); --bg-positive-border: rgba(69, 184, 59, 40%); - + --bg-caution: rgb(255, 179, 0); --bg-caution-hover: rgba(255, 179, 0, 8%); --bg-caution-active: rgba(255, 179, 0, 15%); @@ -37,18 +43,18 @@ --bg-badge: #989898; --bg-ping: hsla(137deg, 100%, 68%, 40%); --bg-ping-hover: hsla(137deg, 100%, 68%, 50%); - --bg-divider: hsla(0, 0%, 0%, .1); + --bg-divider: hsla(0, 0%, 0%, 0.1); /* text color | --tc-[background type]-[priority]: value */ --tc-surface-high: #000000; --tc-surface-normal: rgba(0, 0, 0, 78%); --tc-surface-normal-low: rgba(0, 0, 0, 60%); --tc-surface-low: rgba(0, 0, 0, 48%); - + --tc-primary-high: #ffffff; --tc-primary-normal: rgba(255, 255, 255, 68%); --tc-primary-low: rgba(255, 255, 255, 40%); - + --tc-positive-high: var(--bg-positive); --tc-positive-normal: rgb(69, 184, 59, 80%); --tc-positive-low: rgb(69, 184, 59, 60%); @@ -56,7 +62,7 @@ --tc-caution-high: var(--bg-caution); --tc-caution-normal: rgb(255, 179, 0, 80%); --tc-caution-low: rgb(255, 179, 0, 60%); - + --tc-danger-high: var(--bg-danger); --tc-danger-normal: rgba(240, 71, 71, 88%); --tc-danger-low: rgba(240, 71, 71, 60%); @@ -66,7 +72,6 @@ --tc-tooltip: white; --tc-badge: white; - /* system icons | --ic-[background type]-[priority]: value */ --ic-surface-high: #272727; --ic-surface-normal: #626262; @@ -102,7 +107,6 @@ --av-small: 36px; --av-extra-small: 24px; - /* shadow and overlay */ --bg-overlay: rgba(0, 0, 0, 20%); --bg-overlay-low: rgba(0, 0, 0, 50%); @@ -124,11 +128,9 @@ --bs-danger-border: inset 0 0 0 1px var(--bg-danger-border); --bs-danger-outline: 0 0 0 2px var(--bg-danger-border); - /* border */ --bo-radius: 8px; - /* font styles: font-size, letter-spacing, line-hight */ --fs-h1: 36px; --ls-h1: -1.5px; @@ -160,7 +162,6 @@ --fw-medium: 500; --fw-bold: 700; - /* spacing | --sp-[space]: value */ --sp-none: 0px; --sp-ultra-tight: 4px; @@ -170,7 +171,6 @@ --sp-loose: 20px; --sp-extra-loose: 32px; - /* other */ --border-width: 1px; --header-height: 54px; @@ -180,7 +180,7 @@ --people-drawer-width: calc(268px - var(--border-width)); --popup-window-drawer-width: 280px; - + @include screen.smallerThan(tabletBreakpoint) { --navigation-drawer-width: calc(240px + var(--border-width)); --people-drawer-width: calc(256px - var(--border-width)); @@ -191,11 +191,11 @@ --fluid-push: cubic-bezier(0, 0.8, 0.67, 0.97); --fluid-slide-down: cubic-bezier(0.02, 0.82, 0.4, 0.96); --fluid-slide-up: cubic-bezier(0.13, 0.56, 0.25, 0.99); - - --font-primary: 'Roboto', sans-serif; - --font-secondary: 'Roboto', sans-serif; -} + --font-emoji: 'Twemoji'; + --font-primary: 'Roboto', var(--font-emoji), sans-serif; + --font-secondary: 'Roboto', var(--font-emoji), sans-serif; +} .silver-theme { /* background color | --bg-[background type]: value */ @@ -207,7 +207,8 @@ --bg-surface-extra-low-transparent: hsla(0, 0%, 91%, 0); } -@mixin dark-mode() { +.dark-theme, +.butter-theme { /* background color | --bg-[background type]: value */ --bg-surface: hsl(208, 8%, 20%); --bg-surface-transparent: hsla(208, 8%, 20%, 0); @@ -228,15 +229,14 @@ --bg-badge: hsl(0, 0%, 75%); --bg-ping: hsla(137deg, 100%, 38%, 40%); --bg-ping-hover: hsla(137deg, 100%, 38%, 50%); - --bg-divider: hsla(0, 0%, 100%, .1); - + --bg-divider: hsla(0, 0%, 100%, 0.1); /* text color | --tc-[background type]-[priority]: value */ --tc-surface-high: rgba(255, 255, 255, 98%); --tc-surface-normal: rgba(255, 255, 255, 94%); --tc-surface-normal-low: rgba(255, 255, 255, 60%); --tc-surface-low: rgba(255, 255, 255, 58%); - + --tc-primary-high: #ffffff; --tc-primary-normal: rgba(255, 255, 255, 0.68); --tc-primary-low: rgba(255, 255, 255, 0.4); @@ -262,7 +262,7 @@ --mx-uc-7: hsl(243, 100%, 74%); --mx-uc-8: hsl(94, 66%, 50%); } - + /* shadow and overlay */ --bg-overlay: rgba(0, 0, 0, 60%); --bg-overlay-low: rgba(0, 0, 0, 80%); @@ -274,7 +274,7 @@ --bs-primary-border: inset 0 0 0 1px var(--bg-primary-border); --bs-primary-outline: 0 0 0 2px var(--bg-primary-border); - + /* font styles: font-size, letter-spacing, line-hight */ --fs-h1: 35.6px; @@ -292,18 +292,7 @@ /* override normal font weight for dark mode */ --fw-normal: 350; - --font-secondary: 'InterVariable', 'Roboto', sans-serif; -} - -.dark-theme, -.butter-theme { - @include dark-mode(); -} - -@media (prefers-color-scheme: dark) { - .system-theme { - @include dark-mode(); - } + --font-secondary: 'InterVariable', 'Roboto', var(--font-emoji), sans-serif; } .butter-theme { @@ -317,14 +306,12 @@ --bg-badge: #c4c1ab; - /* text color | --tc-[background type]-[priority]: value */ --tc-surface-high: rgb(255, 251, 222, 94%); --tc-surface-normal: rgba(255, 251, 222, 94%); - --tc-surface-normal-low: rgba(255, 251, 222, 60%); + --tc-surface-normal-low: rgba(255, 251, 222, 60%); --tc-surface-low: rgba(255, 251, 222, 58%); - /* system icons | --ic-[background type]-[priority]: value */ --ic-surface-high: rgb(255, 251, 222); --ic-surface-normal: rgba(255, 251, 222, 84%); @@ -387,9 +374,11 @@ body { height: 100%; } -*, *::before, *::after { +*, +*::before, +*::after { box-sizing: border-box; - -webkit-tap-highlight-color: rgba(0,0,0,0); + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); -webkit-tap-highlight-color: transparent; } a { @@ -428,16 +417,16 @@ button { textarea, input, input[type], -input[type=text], -input[type=username], -input[type=password], -input[type=email], -input[type=checkbox] { +input[type='text'], +input[type='username'], +input[type='password'], +input[type='email'], +input[type='checkbox'] { -webkit-appearance: none; -moz-appearance: none; appearance: none; } -input[type=checkbox] { +input[type='checkbox'] { margin: 0; padding: 0; width: 20px; @@ -451,7 +440,7 @@ input[type=checkbox] { &:checked { background-color: var(--bg-primary); &::before { - content: ""; + content: ''; display: inline-block; width: 12px; height: 6px; @@ -468,11 +457,11 @@ textarea { } .noselect { -webkit-touch-callout: none; /* iOS Safari */ - -webkit-user-select: none; /* Safari */ - -khtml-user-select: none; /* Konqueror HTML */ - -moz-user-select: none; /* Old versions of Firefox */ - -ms-user-select: none; /* Internet Explorer/Edge */ - user-select: none; /* Non-prefixed version, currently + -webkit-user-select: none; /* Safari */ + -khtml-user-select: none; /* Konqueror HTML */ + -moz-user-select: none; /* Old versions of Firefox */ + -ms-user-select: none; /* Internet Explorer/Edge */ + user-select: none; /* Non-prefixed version, currently supported by Chrome, Edge, Opera and Firefox */ } @@ -484,4 +473,4 @@ audio:not([controls]) { display: flex; justify-content: center; align-items: center; -} \ No newline at end of file +} diff --git a/src/types/matrix/accountData.ts b/src/types/matrix/accountData.ts new file mode 100644 index 000000000..1078cb356 --- /dev/null +++ b/src/types/matrix/accountData.ts @@ -0,0 +1,12 @@ +export enum AccountDataEvent { + PushRules = 'm.push_rules', + Direct = 'm.direct', + IgnoredUserList = 'm.ignored_user_list', + + CinnySpaces = 'in.cinny.spaces', + + ElementRecentEmoji = 'io.element.recent_emoji', + + PoniesUserEmotes = 'im.ponies.user_emotes', + PoniesEmoteRooms = 'im.ponies.emote_rooms', +} diff --git a/src/types/matrix/common.ts b/src/types/matrix/common.ts new file mode 100644 index 000000000..94a46a90a --- /dev/null +++ b/src/types/matrix/common.ts @@ -0,0 +1,22 @@ +import { EncryptedAttachmentInfo } from 'browser-encrypt-attachment'; + +export type IImageInfo = { + w?: number; + h?: number; + mimetype?: string; + size?: number; +}; + +export type IVideoInfo = IImageInfo & { + duration?: number; +}; + +export type IEncryptedFile = EncryptedAttachmentInfo & { + url: string; +}; + +export type IThumbnailContent = { + thumbnail_info?: IImageInfo; + thumbnail_file?: IEncryptedFile; + thumbnail_url?: string; +}; diff --git a/src/types/matrix/room.ts b/src/types/matrix/room.ts new file mode 100644 index 000000000..93e876152 --- /dev/null +++ b/src/types/matrix/room.ts @@ -0,0 +1,61 @@ +export enum Membership { + Invite = 'invite', + Knock = 'knock', + Join = 'join', + Leave = 'leave', + Ban = 'ban', +} + +export enum StateEvent { + RoomCanonicalAlias = 'm.room.canonical_alias', + RoomCreate = 'm.room.create', + RoomJoinRules = 'm.room.join_rules', + RoomMember = 'm.room.member', + RoomThirdPartyInvite = 'm.room.third_party_invite', + RoomPowerLevels = 'm.room.power_levels', + RoomName = 'm.room.name', + RoomTopic = 'm.room.topic', + RoomAvatar = 'm.room.avatar', + RoomPinnedEvents = 'm.room.pinned_events', + RoomEncryption = 'm.room.encryption', + RoomHistoryVisibility = 'm.room.history_visibility', + RoomGuestAccess = 'm.room.guest_access', + RoomServerAcl = 'm.room.server_acl', + RoomTombstone = 'm.room.tombstone', + + SpaceChild = 'm.space.child', + SpaceParent = 'm.space.parent', + + PoniesRoomEmotes = 'im.ponies.room_emotes', +} + +export enum RoomType { + Space = 'm.space', +} + +export enum NotificationType { + Default = 'default', + AllMessages = 'all_messages', + MentionsAndKeywords = 'mentions_and_keywords', + Mute = 'mute', +} + +export type RoomToParents = Map>; +export type RoomToUnread = Map< + string, + { + total: number; + highlight: number; + from: Set | null; + } +>; +export type UnreadInfo = { + roomId: string; + total: number; + highlight: number; +}; + +export type MuteChanges = { + added: string[]; + removed: string[]; +}; diff --git a/src/util/sanitize.js b/src/util/sanitize.js index 79cc04183..3723a11b3 100644 --- a/src/util/sanitize.js +++ b/src/util/sanitize.js @@ -6,7 +6,7 @@ let mx = null; const permittedHtmlTags = [ 'font', 'del', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'blockquote', 'p', 'a', 'ul', 'ol', 'sup', 'sub', - 'li', 'b', 'i', 'u', 'strong', 'em', 'strike', 'code', + 'li', 'b', 'i', 'u', 'strong', 'em', 'strike', 's', 'code', 'hr', 'br', 'div', 'table', 'thead', 'tbody', 'tr', 'th', 'td', 'caption', 'pre', 'span', 'img', 'details', 'summary', ]; diff --git a/tsconfig.json b/tsconfig.json index e109a97cc..02eb1843b 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,8 +2,9 @@ "compilerOptions": { "sourceMap": true, "jsx": "react", - "target": "ES6", + "target": "ES2016", "allowJs": true, + "strict": true, "esModuleInterop": true, "moduleResolution": "Node", "outDir": "dist", diff --git a/vite.config.js b/vite.config.js index 979e9aa0b..6a443166d 100644 --- a/vite.config.js +++ b/vite.config.js @@ -2,6 +2,7 @@ import { defineConfig } from 'vite'; import react from '@vitejs/plugin-react'; import { wasm } from '@rollup/plugin-wasm'; import { viteStaticCopy } from 'vite-plugin-static-copy'; +import { vanillaExtractPlugin } from "@vanilla-extract/vite-plugin"; import { NodeGlobalsPolyfillPlugin } from '@esbuild-plugins/node-globals-polyfill'; import inject from '@rollup/plugin-inject'; import { svgLoader } from './viteSvgLoader'; @@ -37,6 +38,7 @@ export default defineConfig({ }, plugins: [ viteStaticCopy(copyFiles), + vanillaExtractPlugin(), svgLoader(), wasm(), react(), From 2bbf0d1b825ecb177d2e9964c11a403874ca9178 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Jun 2023 21:29:33 +1000 Subject: [PATCH 1018/1531] Bump vite from 4.0.1 to 4.3.9 (#1256) Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 4.0.1 to 4.3.9. - [Release notes](https://github.com/vitejs/vite/releases) - [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md) - [Commits](https://github.com/vitejs/vite/commits/v4.3.9/packages/vite) --- updated-dependencies: - dependency-name: vite dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 434 ++++++++++++++++++++++++++++++++++++++++++++-- package.json | 2 +- 2 files changed, 417 insertions(+), 19 deletions(-) diff --git a/package-lock.json b/package-lock.json index 626752477..3c5b27c87 100644 --- a/package-lock.json +++ b/package-lock.json @@ -76,7 +76,7 @@ "prettier": "2.8.1", "sass": "1.56.2", "typescript": "4.9.4", - "vite": "4.0.4", + "vite": "4.3.9", "vite-plugin-static-copy": "0.13.0" }, "engines": { @@ -4321,9 +4321,15 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/nanoid": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", - "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", + "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -4628,9 +4634,9 @@ } }, "node_modules/postcss": { - "version": "8.4.20", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.20.tgz", - "integrity": "sha512-6Q04AXR1212bXr5fh03u8aAwbLxAQNGQ/Q1LNa0VfOI06ZAlhPHtQvE4OIdpj4kLThXilalPnmDSOD65DcHt+g==", + "version": "8.4.24", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.24.tgz", + "integrity": "sha512-M0RzbcI0sO/XJNucsGjvWU9ERWxb/ytp1w6dKtxTKgixdtQDq4rmx/g8W1hnaheq9jgwL/oyEdH5Bc4WwJKMqg==", "funding": [ { "type": "opencollective", @@ -4639,10 +4645,14 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ], "dependencies": { - "nanoid": "^3.3.4", + "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" }, @@ -5007,9 +5017,9 @@ } }, "node_modules/rollup": { - "version": "3.7.5", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.7.5.tgz", - "integrity": "sha512-z0ZbqHBtS/et2EEUKMrAl2CoSdwN7ZPzL17UMiKN9RjjqHShTlv7F9J6ZJZJNREYjBh3TvBrdfjkFDIXFNeuiQ==", + "version": "3.25.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.25.1.tgz", + "integrity": "sha512-tywOR+rwIt5m2ZAWSe5AIJcTat8vGlnPFAv15ycCrw33t6iFsXZ6mzHVFh2psSjxQPmI+xgzMZZizUAukBI4aQ==", "dev": true, "bin": { "rollup": "dist/bin/rollup" @@ -5593,15 +5603,14 @@ } }, "node_modules/vite": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.0.4.tgz", - "integrity": "sha512-xevPU7M8FU0i/80DMR+YhgrzR5KS2ORy1B4xcX/cXLsvnUWvfHuqMmVU6N0YiJ4JWGRJJsLCgjEzKjG9/GKoSw==", + "version": "4.3.9", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.3.9.tgz", + "integrity": "sha512-qsTNZjO9NoJNW7KnOrgYwczm0WctJ8m/yqYAMAK9Lxt4SoySUfS5S8ia9K7JHpa3KEeMfyF8LoJ3c5NeBJy6pg==", "dev": true, "dependencies": { - "esbuild": "^0.16.3", - "postcss": "^8.4.20", - "resolve": "^1.22.1", - "rollup": "^3.7.0" + "esbuild": "^0.17.5", + "postcss": "^8.4.23", + "rollup": "^3.21.0" }, "bin": { "vite": "bin/vite.js" @@ -5694,6 +5703,395 @@ "node": ">= 10.0.0" } }, + "node_modules/vite/node_modules/@esbuild/android-arm": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.19.tgz", + "integrity": "sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/android-arm64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.19.tgz", + "integrity": "sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/android-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.19.tgz", + "integrity": "sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/darwin-arm64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.19.tgz", + "integrity": "sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/darwin-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.19.tgz", + "integrity": "sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/freebsd-arm64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.19.tgz", + "integrity": "sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/freebsd-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.19.tgz", + "integrity": "sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-arm": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.19.tgz", + "integrity": "sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-arm64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.19.tgz", + "integrity": "sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-ia32": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.19.tgz", + "integrity": "sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-loong64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.19.tgz", + "integrity": "sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-mips64el": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.19.tgz", + "integrity": "sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-ppc64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.19.tgz", + "integrity": "sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-riscv64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.19.tgz", + "integrity": "sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-s390x": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.19.tgz", + "integrity": "sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.19.tgz", + "integrity": "sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/netbsd-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.19.tgz", + "integrity": "sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/openbsd-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.19.tgz", + "integrity": "sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/sunos-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.19.tgz", + "integrity": "sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-arm64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.19.tgz", + "integrity": "sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-ia32": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.19.tgz", + "integrity": "sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.19.tgz", + "integrity": "sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/esbuild": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.19.tgz", + "integrity": "sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/android-arm": "0.17.19", + "@esbuild/android-arm64": "0.17.19", + "@esbuild/android-x64": "0.17.19", + "@esbuild/darwin-arm64": "0.17.19", + "@esbuild/darwin-x64": "0.17.19", + "@esbuild/freebsd-arm64": "0.17.19", + "@esbuild/freebsd-x64": "0.17.19", + "@esbuild/linux-arm": "0.17.19", + "@esbuild/linux-arm64": "0.17.19", + "@esbuild/linux-ia32": "0.17.19", + "@esbuild/linux-loong64": "0.17.19", + "@esbuild/linux-mips64el": "0.17.19", + "@esbuild/linux-ppc64": "0.17.19", + "@esbuild/linux-riscv64": "0.17.19", + "@esbuild/linux-s390x": "0.17.19", + "@esbuild/linux-x64": "0.17.19", + "@esbuild/netbsd-x64": "0.17.19", + "@esbuild/openbsd-x64": "0.17.19", + "@esbuild/sunos-x64": "0.17.19", + "@esbuild/win32-arm64": "0.17.19", + "@esbuild/win32-ia32": "0.17.19", + "@esbuild/win32-x64": "0.17.19" + } + }, "node_modules/warning": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", diff --git a/package.json b/package.json index 38be28dff..855b56887 100644 --- a/package.json +++ b/package.json @@ -86,7 +86,7 @@ "prettier": "2.8.1", "sass": "1.56.2", "typescript": "4.9.4", - "vite": "4.0.4", + "vite": "4.3.9", "vite-plugin-static-copy": "0.13.0" } } From 15feac81c9ae9b683c9bd01a6ddd37afe0e332dd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Jun 2023 21:32:10 +1000 Subject: [PATCH 1019/1531] Bump actions/upload-artifact from 3.1.1 to 3.1.2 (#1055) Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 3.1.1 to 3.1.2. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/v3.1.1...v3.1.2) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build-pull-request.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-pull-request.yml b/.github/workflows/build-pull-request.yml index 5be042932..9cd911fcb 100644 --- a/.github/workflows/build-pull-request.yml +++ b/.github/workflows/build-pull-request.yml @@ -25,7 +25,7 @@ jobs: NODE_OPTIONS: "--max_old_space_size=4096" run: npm run build - name: Upload artifact - uses: actions/upload-artifact@v3.1.1 + uses: actions/upload-artifact@v3.1.2 with: name: preview path: dist @@ -33,7 +33,7 @@ jobs: - name: Save pr number run: echo ${PR_NUMBER} > ./pr.txt - name: Upload pr number - uses: actions/upload-artifact@v3.1.1 + uses: actions/upload-artifact@v3.1.2 with: name: pr path: ./pr.txt From 14b4969a656bc7d6960a129cf4ea33b0a8f6b1e9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Jun 2023 21:34:23 +1000 Subject: [PATCH 1020/1531] Bump actions/setup-node from 3.5.1 to 3.6.0 (#1057) Bumps [actions/setup-node](https://github.com/actions/setup-node) from 3.5.1 to 3.6.0. - [Release notes](https://github.com/actions/setup-node/releases) - [Commits](https://github.com/actions/setup-node/compare/v3.5.1...v3.6.0) --- updated-dependencies: - dependency-name: actions/setup-node dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build-pull-request.yml | 2 +- .github/workflows/netlify-dev.yml | 2 +- .github/workflows/prod-deploy.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-pull-request.yml b/.github/workflows/build-pull-request.yml index 9cd911fcb..5a612a6c8 100644 --- a/.github/workflows/build-pull-request.yml +++ b/.github/workflows/build-pull-request.yml @@ -14,7 +14,7 @@ jobs: - name: Checkout repository uses: actions/checkout@v3.2.0 - name: Setup node - uses: actions/setup-node@v3.5.1 + uses: actions/setup-node@v3.6.0 with: node-version: 18.12.1 cache: "npm" diff --git a/.github/workflows/netlify-dev.yml b/.github/workflows/netlify-dev.yml index 12785f460..319fc4caa 100644 --- a/.github/workflows/netlify-dev.yml +++ b/.github/workflows/netlify-dev.yml @@ -13,7 +13,7 @@ jobs: - name: Checkout repository uses: actions/checkout@v3.2.0 - name: Setup node - uses: actions/setup-node@v3.5.1 + uses: actions/setup-node@v3.6.0 with: node-version: 18.12.1 cache: "npm" diff --git a/.github/workflows/prod-deploy.yml b/.github/workflows/prod-deploy.yml index 8d72a86e9..6f9edd445 100644 --- a/.github/workflows/prod-deploy.yml +++ b/.github/workflows/prod-deploy.yml @@ -12,7 +12,7 @@ jobs: - name: Checkout repository uses: actions/checkout@v3.2.0 - name: Setup node - uses: actions/setup-node@v3.5.1 + uses: actions/setup-node@v3.6.0 with: node-version: 18.12.1 cache: "npm" From 9f2fb716f7fe15de120ae4cde4a112553eb8c785 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Jun 2023 21:36:13 +1000 Subject: [PATCH 1021/1531] Bump thollander/actions-comment-pull-request from 2.0.0 to 2.3.1 (#1081) Bumps [thollander/actions-comment-pull-request](https://github.com/thollander/actions-comment-pull-request) from 2.0.0 to 2.3.1. - [Release notes](https://github.com/thollander/actions-comment-pull-request/releases) - [Commits](https://github.com/thollander/actions-comment-pull-request/compare/c22fb302208b7b170d252a61a505d2ea27245eff...632cf9ce90574d125be56b5f3405cda41a84e2fd) --- updated-dependencies: - dependency-name: thollander/actions-comment-pull-request dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/deploy-pull-request.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deploy-pull-request.yml b/.github/workflows/deploy-pull-request.yml index ab54f8dff..741d06513 100644 --- a/.github/workflows/deploy-pull-request.yml +++ b/.github/workflows/deploy-pull-request.yml @@ -45,7 +45,7 @@ jobs: NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID_PR_CINNY }} timeout-minutes: 1 - name: Comment preview on PR - uses: thollander/actions-comment-pull-request@c22fb302208b7b170d252a61a505d2ea27245eff + uses: thollander/actions-comment-pull-request@632cf9ce90574d125be56b5f3405cda41a84e2fd env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: From f1fcde2142bb22f984353d59c30336af1195ac37 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Jun 2023 21:38:53 +1000 Subject: [PATCH 1022/1531] Bump dawidd6/action-download-artifact from 2.24.2 to 2.27.0 (#1202) Bumps [dawidd6/action-download-artifact](https://github.com/dawidd6/action-download-artifact) from 2.24.2 to 2.27.0. - [Release notes](https://github.com/dawidd6/action-download-artifact/releases) - [Commits](https://github.com/dawidd6/action-download-artifact/compare/e6e25ac3a2b93187502a8be1ef9e9603afc34925...246dbf436b23d7c49e21a7ab8204ca9ecd1fe615) --- updated-dependencies: - dependency-name: dawidd6/action-download-artifact dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/deploy-pull-request.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/deploy-pull-request.yml b/.github/workflows/deploy-pull-request.yml index 741d06513..fdb0e810e 100644 --- a/.github/workflows/deploy-pull-request.yml +++ b/.github/workflows/deploy-pull-request.yml @@ -15,7 +15,7 @@ jobs: if: ${{ github.event.workflow_run.conclusion == 'success' }} steps: - name: Download pr number - uses: dawidd6/action-download-artifact@e6e25ac3a2b93187502a8be1ef9e9603afc34925 + uses: dawidd6/action-download-artifact@246dbf436b23d7c49e21a7ab8204ca9ecd1fe615 with: workflow: ${{ github.event.workflow.id }} run_id: ${{ github.event.workflow_run.id }} @@ -24,7 +24,7 @@ jobs: id: pr run: echo "id=$(> $GITHUB_OUTPUT - name: Download artifact - uses: dawidd6/action-download-artifact@e6e25ac3a2b93187502a8be1ef9e9603afc34925 + uses: dawidd6/action-download-artifact@246dbf436b23d7c49e21a7ab8204ca9ecd1fe615 with: workflow: ${{ github.event.workflow.id }} run_id: ${{ github.event.workflow_run.id }} From ed5431680ff37bdb3f8685df69a91e91ffdd9dd2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 13 Jun 2023 09:21:07 +1000 Subject: [PATCH 1023/1531] Bump actions/checkout from 3.2.0 to 3.5.3 (#1276) Bumps [actions/checkout](https://github.com/actions/checkout) from 3.2.0 to 3.5.3. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v3.2.0...v3.5.3) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build-pull-request.yml | 2 +- .github/workflows/docker-pr.yml | 2 +- .github/workflows/lockfile.yml | 2 +- .github/workflows/netlify-dev.yml | 2 +- .github/workflows/prod-deploy.yml | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build-pull-request.yml b/.github/workflows/build-pull-request.yml index 5a612a6c8..d77310558 100644 --- a/.github/workflows/build-pull-request.yml +++ b/.github/workflows/build-pull-request.yml @@ -12,7 +12,7 @@ jobs: PR_NUMBER: ${{github.event.number}} steps: - name: Checkout repository - uses: actions/checkout@v3.2.0 + uses: actions/checkout@v3.5.3 - name: Setup node uses: actions/setup-node@v3.6.0 with: diff --git a/.github/workflows/docker-pr.yml b/.github/workflows/docker-pr.yml index 47dbfe32a..d4b1d73a7 100644 --- a/.github/workflows/docker-pr.yml +++ b/.github/workflows/docker-pr.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v3.2.0 + uses: actions/checkout@v3.5.3 - name: Build Docker image uses: docker/build-push-action@v3.2.0 with: diff --git a/.github/workflows/lockfile.yml b/.github/workflows/lockfile.yml index b417df101..30d00760a 100644 --- a/.github/workflows/lockfile.yml +++ b/.github/workflows/lockfile.yml @@ -14,7 +14,7 @@ jobs: pull-requests: write steps: - name: Checkout - uses: actions/checkout@v3.2.0 + uses: actions/checkout@v3.5.3 - name: NPM Lockfile Changes uses: codepunkt/npm-lockfile-changes@b40543471c36394409466fdb277a73a0856d7891 with: diff --git a/.github/workflows/netlify-dev.yml b/.github/workflows/netlify-dev.yml index 319fc4caa..8935c510f 100644 --- a/.github/workflows/netlify-dev.yml +++ b/.github/workflows/netlify-dev.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v3.2.0 + uses: actions/checkout@v3.5.3 - name: Setup node uses: actions/setup-node@v3.6.0 with: diff --git a/.github/workflows/prod-deploy.yml b/.github/workflows/prod-deploy.yml index 6f9edd445..f2cd3fa1c 100644 --- a/.github/workflows/prod-deploy.yml +++ b/.github/workflows/prod-deploy.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v3.2.0 + uses: actions/checkout@v3.5.3 - name: Setup node uses: actions/setup-node@v3.6.0 with: @@ -66,7 +66,7 @@ jobs: packages: write steps: - name: Checkout repository - uses: actions/checkout@v3.2.0 + uses: actions/checkout@v3.5.3 - name: Set up QEMU uses: docker/setup-qemu-action@v2.1.0 - name: Set up Docker Buildx From db33707e5eeddaa7eb97d98df5e7ea9a80667609 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 13 Jun 2023 09:24:17 +1000 Subject: [PATCH 1024/1531] fix(deps): update dependency matrix-js-sdk to v24.1.0 [security] (#1251) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package-lock.json | 18 +++++++++--------- package.json | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3c5b27c87..99e3c9136 100644 --- a/package-lock.json +++ b/package-lock.json @@ -36,7 +36,7 @@ "katex": "0.16.4", "linkify-html": "4.0.2", "linkifyjs": "4.0.2", - "matrix-js-sdk": "24.0.0", + "matrix-js-sdk": "24.1.0", "prop-types": "15.8.1", "react": "17.0.2", "react-autosize-textarea": "7.1.0", @@ -4225,18 +4225,18 @@ "integrity": "sha512-1QEOsXO+bhyCroIe2/A5OwaxHvBm7EsSQ46DEDn8RBIfQwN5HWBpFvyWWR4QY0KHPPnnJdI99wgRiAl7Ad5qaA==" }, "node_modules/matrix-js-sdk": { - "version": "24.0.0", - "resolved": "https://registry.npmjs.org/matrix-js-sdk/-/matrix-js-sdk-24.0.0.tgz", - "integrity": "sha512-AOhO036ziDf6lwYoauj5DES/RJ6RDTq+vrK2yO/GW/8n+bAXhkjWc9AA/WcTK/9SkNHS46ZanmolkhS1n8WniQ==", + "version": "24.1.0", + "resolved": "https://registry.npmjs.org/matrix-js-sdk/-/matrix-js-sdk-24.1.0.tgz", + "integrity": "sha512-xEx2ZoNsS56dwgqLJ3rIv2SUpFxdQLrLKmJCpMatMUKCAg+NGuZfpQ3QXblIbGaqFNQZCH7fC7S48AeTMZp1Jw==", "dependencies": { "@babel/runtime": "^7.12.5", - "@matrix-org/matrix-sdk-crypto-js": "^0.1.0-alpha.3", + "@matrix-org/matrix-sdk-crypto-js": "^0.1.0-alpha.5", "another-json": "^0.2.0", "bs58": "^5.0.0", "content-type": "^1.0.4", "loglevel": "^1.7.1", "matrix-events-sdk": "0.0.1", - "matrix-widget-api": "^1.0.0", + "matrix-widget-api": "^1.3.1", "p-retry": "4", "sdp-transform": "^2.14.1", "unhomoglyph": "^1.0.6", @@ -4247,9 +4247,9 @@ } }, "node_modules/matrix-widget-api": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/matrix-widget-api/-/matrix-widget-api-1.1.1.tgz", - "integrity": "sha512-gNSgmgSwvOsOcWK9k2+tOhEMYBiIMwX95vMZu0JqY7apkM02xrOzUBuPRProzN8CnbIALH7e3GAhatF6QCNvtA==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/matrix-widget-api/-/matrix-widget-api-1.4.0.tgz", + "integrity": "sha512-dw0dRylGQzDUoiaY/g5xx1tBbS7aoov31PRtFMAvG58/4uerYllV9Gfou7w+I1aglwB6hihTREzKltVjARWV6A==", "dependencies": { "@types/events": "^3.0.0", "events": "^3.2.0" diff --git a/package.json b/package.json index 855b56887..5f0f42f28 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,7 @@ "katex": "0.16.4", "linkify-html": "4.0.2", "linkifyjs": "4.0.2", - "matrix-js-sdk": "24.0.0", + "matrix-js-sdk": "24.1.0", "prop-types": "15.8.1", "react": "17.0.2", "react-autosize-textarea": "7.1.0", From 511c8ea79d266854009575476797a32190b77f43 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 13 Jun 2023 09:25:20 +1000 Subject: [PATCH 1025/1531] Bump nginx from 1.23.3-alpine to 1.25.0-alpine (#1254) Bumps nginx from 1.23.3-alpine to 1.25.0-alpine. --- updated-dependencies: - dependency-name: nginx dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index af9abbd9a..3cae982a2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -11,7 +11,7 @@ RUN npm run build ## App -FROM nginx:1.23.3-alpine +FROM nginx:1.25.0-alpine COPY --from=builder /src/dist /app From a07d954f1c3ab6401205651c3cdff2df666edd66 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 13 Jun 2023 09:26:54 +1000 Subject: [PATCH 1026/1531] Bump docker/metadata-action from 4.1.1 to 4.5.0 (#1271) Bumps [docker/metadata-action](https://github.com/docker/metadata-action) from 4.1.1 to 4.5.0. - [Release notes](https://github.com/docker/metadata-action/releases) - [Commits](https://github.com/docker/metadata-action/compare/v4.1.1...v4.5.0) --- updated-dependencies: - dependency-name: docker/metadata-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/prod-deploy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/prod-deploy.yml b/.github/workflows/prod-deploy.yml index f2cd3fa1c..25ac23bb4 100644 --- a/.github/workflows/prod-deploy.yml +++ b/.github/workflows/prod-deploy.yml @@ -84,7 +84,7 @@ jobs: password: ${{ secrets.GITHUB_TOKEN }} - name: Extract metadata (tags, labels) for Docker id: meta - uses: docker/metadata-action@v4.1.1 + uses: docker/metadata-action@v4.5.0 with: images: | ${{ secrets.DOCKER_USERNAME }}/cinny From bd64f7bd868d79365ea1aa096c146ddab4e19e28 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 13 Jun 2023 09:28:07 +1000 Subject: [PATCH 1027/1531] Bump thollander/actions-comment-pull-request from 2.3.1 to 2.4.0 (#1272) Bumps [thollander/actions-comment-pull-request](https://github.com/thollander/actions-comment-pull-request) from 2.3.1 to 2.4.0. - [Release notes](https://github.com/thollander/actions-comment-pull-request/releases) - [Commits](https://github.com/thollander/actions-comment-pull-request/compare/632cf9ce90574d125be56b5f3405cda41a84e2fd...dadb7667129e23f12ca3925c90dc5cd7121ab57e) --- updated-dependencies: - dependency-name: thollander/actions-comment-pull-request dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/deploy-pull-request.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deploy-pull-request.yml b/.github/workflows/deploy-pull-request.yml index fdb0e810e..c4d824365 100644 --- a/.github/workflows/deploy-pull-request.yml +++ b/.github/workflows/deploy-pull-request.yml @@ -45,7 +45,7 @@ jobs: NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID_PR_CINNY }} timeout-minutes: 1 - name: Comment preview on PR - uses: thollander/actions-comment-pull-request@632cf9ce90574d125be56b5f3405cda41a84e2fd + uses: thollander/actions-comment-pull-request@dadb7667129e23f12ca3925c90dc5cd7121ab57e env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: From 1c27a292383af262b491d2e04f3da655d3730c0e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 13 Jun 2023 09:28:39 +1000 Subject: [PATCH 1028/1531] Bump docker/setup-buildx-action from 2.2.1 to 2.6.0 (#1274) Bumps [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) from 2.2.1 to 2.6.0. - [Release notes](https://github.com/docker/setup-buildx-action/releases) - [Commits](https://github.com/docker/setup-buildx-action/compare/v2.2.1...v2.6.0) --- updated-dependencies: - dependency-name: docker/setup-buildx-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/prod-deploy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/prod-deploy.yml b/.github/workflows/prod-deploy.yml index 25ac23bb4..84c963fec 100644 --- a/.github/workflows/prod-deploy.yml +++ b/.github/workflows/prod-deploy.yml @@ -70,7 +70,7 @@ jobs: - name: Set up QEMU uses: docker/setup-qemu-action@v2.1.0 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2.2.1 + uses: docker/setup-buildx-action@v2.6.0 - name: Login to Docker Hub uses: docker/login-action@v2.1.0 with: From 6d199244efa054760b6c0cd75f509708e0c80aee Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 13 Jun 2023 09:29:18 +1000 Subject: [PATCH 1029/1531] Bump docker/build-push-action from 3.2.0 to 4.1.0 (#1275) Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 3.2.0 to 4.1.0. - [Release notes](https://github.com/docker/build-push-action/releases) - [Commits](https://github.com/docker/build-push-action/compare/v3.2.0...v4.1.0) --- updated-dependencies: - dependency-name: docker/build-push-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/docker-pr.yml | 2 +- .github/workflows/prod-deploy.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docker-pr.yml b/.github/workflows/docker-pr.yml index d4b1d73a7..3edc3c187 100644 --- a/.github/workflows/docker-pr.yml +++ b/.github/workflows/docker-pr.yml @@ -13,7 +13,7 @@ jobs: - name: Checkout repository uses: actions/checkout@v3.5.3 - name: Build Docker image - uses: docker/build-push-action@v3.2.0 + uses: docker/build-push-action@v4.1.0 with: context: . push: false diff --git a/.github/workflows/prod-deploy.yml b/.github/workflows/prod-deploy.yml index 84c963fec..484ecba92 100644 --- a/.github/workflows/prod-deploy.yml +++ b/.github/workflows/prod-deploy.yml @@ -90,7 +90,7 @@ jobs: ${{ secrets.DOCKER_USERNAME }}/cinny ghcr.io/${{ github.repository }} - name: Build and push Docker image - uses: docker/build-push-action@v3.2.0 + uses: docker/build-push-action@v4.1.0 with: context: . platforms: linux/amd64,linux/arm64 From 2883b4c35b12d35272d4cebb1185cf1938d402c2 Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Wed, 14 Jun 2023 03:47:18 +1000 Subject: [PATCH 1030/1531] Fix editor bugs (#1281) * focus editor on reply click * fix emoji and sticker img object-fit * fix cursor not moving with autocomplete * stop sanitizing sending plain text body * improve autocomplete query parsing * add escape to turn off active editor toolbar item --- src/app/components/editor/Editor.tsx | 3 +- .../autocomplete/EmoticonAutocomplete.tsx | 2 +- .../editor/autocomplete/autocompleteQuery.ts | 13 +++--- src/app/components/editor/common.ts | 22 +++++++++- src/app/components/editor/keyboard.ts | 43 ++++++++++++++----- src/app/components/editor/output.ts | 2 +- .../components/emoji-board/EmojiBoard.css.tsx | 2 + src/app/components/emoji-board/EmojiBoard.tsx | 1 + src/app/organisms/room/RoomInput.tsx | 3 +- 9 files changed, 69 insertions(+), 22 deletions(-) diff --git a/src/app/components/editor/Editor.tsx b/src/app/components/editor/Editor.tsx index edf1ac6d8..2657b2135 100644 --- a/src/app/components/editor/Editor.tsx +++ b/src/app/components/editor/Editor.tsx @@ -93,7 +93,8 @@ export const CustomEditor = forwardRef( const handleKeydown: KeyboardEventHandler = useCallback( (evt) => { onKeyDown?.(evt); - toggleKeyboardShortcut(editor, evt); + const shortcutToggled = toggleKeyboardShortcut(editor, evt); + if (shortcutToggled) evt.preventDefault(); }, [editor, onKeyDown] ); diff --git a/src/app/components/editor/autocomplete/EmoticonAutocomplete.tsx b/src/app/components/editor/autocomplete/EmoticonAutocomplete.tsx index e5af3fa10..17712b870 100644 --- a/src/app/components/editor/autocomplete/EmoticonAutocomplete.tsx +++ b/src/app/components/editor/autocomplete/EmoticonAutocomplete.tsx @@ -104,7 +104,7 @@ export function EmoticonAutocomplete({ as="img" src={mx.mxcUrlToHttp(key) || key} alt={emoticon.shortcode} - style={{ width: toRem(24), height: toRem(24) }} + style={{ width: toRem(24), height: toRem(24), objectFit: 'contain' }} /> ) : ( ( validPrefixes: readonly TPrefix[] ): TPrefix | undefined => { const world = Editor.string(editor, queryRange); - const prefix = world[0] as TPrefix | undefined; - if (!prefix) return undefined; - return validPrefixes.includes(prefix) ? prefix : undefined; + return validPrefixes.find((p) => world.startsWith(p)); }; -export const getAutocompleteQueryText = (editor: Editor, queryRange: BaseRange): string => - Editor.string(editor, queryRange).slice(1); +export const getAutocompleteQueryText = ( + editor: Editor, + queryRange: BaseRange, + prefix: string +): string => Editor.string(editor, queryRange).slice(prefix.length); export const getAutocompleteQuery = ( editor: Editor, @@ -41,6 +42,6 @@ export const getAutocompleteQuery = ( return { range: queryRange, prefix, - text: getAutocompleteQueryText(editor, queryRange), + text: getAutocompleteQueryText(editor, queryRange, prefix), }; }; diff --git a/src/app/components/editor/common.ts b/src/app/components/editor/common.ts index c9cf086c2..619a1bfee 100644 --- a/src/app/components/editor/common.ts +++ b/src/app/components/editor/common.ts @@ -2,11 +2,25 @@ import { BasePoint, BaseRange, Editor, Element, Point, Range, Transforms } from import { BlockType, MarkType } from './Elements'; import { EmoticonElement, FormattedText, HeadingLevel, LinkElement, MentionElement } from './slate'; +const ALL_MARK_TYPE: MarkType[] = [ + MarkType.Bold, + MarkType.Code, + MarkType.Italic, + MarkType.Spoiler, + MarkType.StrikeThrough, + MarkType.Underline, +]; + export const isMarkActive = (editor: Editor, format: MarkType) => { const marks = Editor.marks(editor); return marks ? marks[format] === true : false; }; +export const isAnyMarkActive = (editor: Editor) => { + const marks = Editor.marks(editor); + return marks && !!ALL_MARK_TYPE.find((type) => marks[type] === true); +}; + export const toggleMark = (editor: Editor, format: MarkType) => { const isActive = isMarkActive(editor, format); @@ -17,6 +31,10 @@ export const toggleMark = (editor: Editor, format: MarkType) => { } }; +export const removeAllMark = (editor: Editor) => { + ALL_MARK_TYPE.forEach((mark) => Editor.removeMark(editor, mark)); +}; + export const isBlockActive = (editor: Editor, format: BlockType) => { const [match] = Editor.nodes(editor, { match: (node) => Element.isElement(node) && node.type === format, @@ -140,11 +158,11 @@ export const replaceWithElement = (editor: Editor, selectRange: BaseRange, eleme }; export const moveCursor = (editor: Editor, withSpace?: boolean) => { - // without timeout it works properly when we select autocomplete with Tab or Space + // without timeout move cursor doesn't works properly. setTimeout(() => { Transforms.move(editor); if (withSpace) editor.insertText(' '); - }, 1); + }, 100); }; interface PointUntilCharOptions { diff --git a/src/app/components/editor/keyboard.ts b/src/app/components/editor/keyboard.ts index 52217dd56..3fbe5363d 100644 --- a/src/app/components/editor/keyboard.ts +++ b/src/app/components/editor/keyboard.ts @@ -1,7 +1,7 @@ import { isHotkey } from 'is-hotkey'; import { KeyboardEvent } from 'react'; import { Editor } from 'slate'; -import { isBlockActive, toggleBlock, toggleMark } from './common'; +import { isAnyMarkActive, isBlockActive, removeAllMark, toggleBlock, toggleMark } from './common'; import { BlockType, MarkType } from './Elements'; export const INLINE_HOTKEYS: Record = { @@ -22,19 +22,42 @@ export const BLOCK_HOTKEYS: Record = { }; const BLOCK_KEYS = Object.keys(BLOCK_HOTKEYS); -export const toggleKeyboardShortcut = (editor: Editor, event: KeyboardEvent) => { - BLOCK_KEYS.forEach((hotkey) => { +/** + * @return boolean true if shortcut is toggled. + */ +export const toggleKeyboardShortcut = (editor: Editor, event: KeyboardEvent): boolean => { + if (isHotkey('escape', event)) { + if (isAnyMarkActive(editor)) { + removeAllMark(editor); + return true; + } + console.log(isBlockActive(editor, BlockType.Paragraph)); + if (!isBlockActive(editor, BlockType.Paragraph)) { + toggleBlock(editor, BlockType.Paragraph); + return true; + } + return false; + } + + const blockToggled = BLOCK_KEYS.find((hotkey) => { if (isHotkey(hotkey, event)) { event.preventDefault(); toggleBlock(editor, BLOCK_HOTKEYS[hotkey]); + return true; } + return false; }); + if (blockToggled) return true; - if (!isBlockActive(editor, BlockType.CodeBlock)) - INLINE_KEYS.forEach((hotkey) => { - if (isHotkey(hotkey, event)) { - event.preventDefault(); - toggleMark(editor, INLINE_HOTKEYS[hotkey]); - } - }); + const inlineToggled = isBlockActive(editor, BlockType.CodeBlock) + ? false + : INLINE_KEYS.find((hotkey) => { + if (isHotkey(hotkey, event)) { + event.preventDefault(); + toggleMark(editor, INLINE_HOTKEYS[hotkey]); + return true; + } + return false; + }); + return !!inlineToggled; }; diff --git a/src/app/components/editor/output.ts b/src/app/components/editor/output.ts index 091dab794..38c544993 100644 --- a/src/app/components/editor/output.ts +++ b/src/app/components/editor/output.ts @@ -88,7 +88,7 @@ const elementToPlainText = (node: CustomElement, children: string): string => { export const toPlainText = (node: Descendant | Descendant[]): string => { if (Array.isArray(node)) return node.map((n) => toPlainText(n)).join(''); - if (Text.isText(node)) return sanitizeText(node.text); + if (Text.isText(node)) return node.text; const children = node.children.map((n) => toPlainText(n)).join(''); return elementToPlainText(node, children); diff --git a/src/app/components/emoji-board/EmojiBoard.css.tsx b/src/app/components/emoji-board/EmojiBoard.css.tsx index 0fefc5b95..adeb25005 100644 --- a/src/app/components/emoji-board/EmojiBoard.css.tsx +++ b/src/app/components/emoji-board/EmojiBoard.css.tsx @@ -122,6 +122,7 @@ export const CustomEmojiImg = style([ { width: toRem(32), height: toRem(32), + objectFit: 'contain', }, ]); @@ -130,5 +131,6 @@ export const StickerImg = style([ { width: toRem(96), height: toRem(96), + objectFit: 'contain', }, ]); diff --git a/src/app/components/emoji-board/EmojiBoard.tsx b/src/app/components/emoji-board/EmojiBoard.tsx index c5f5038c5..3b1ccc554 100644 --- a/src/app/components/emoji-board/EmojiBoard.tsx +++ b/src/app/components/emoji-board/EmojiBoard.tsx @@ -373,6 +373,7 @@ function ImagePackSidebarStack({ style={{ width: toRem(24), height: toRem(24), + objectFit: 'contain', }} src={mx.mxcUrlToHttp(pack.getPackAvatarUrl(usage) ?? '') || pack.avatarUrl} alt={label || 'Unknown Pack'} diff --git a/src/app/organisms/room/RoomInput.tsx b/src/app/organisms/room/RoomInput.tsx index 17830ad98..e79f4883b 100644 --- a/src/app/organisms/room/RoomInput.tsx +++ b/src/app/organisms/room/RoomInput.tsx @@ -184,12 +184,13 @@ export const RoomInput = forwardRef( body, formattedBody, }); + ReactEditor.focus(editor); }; navigation.on(cons.events.navigation.REPLY_TO_CLICKED, handleReplyTo); return () => { navigation.removeListener(cons.events.navigation.REPLY_TO_CLICKED, handleReplyTo); }; - }, [setReplyDraft]); + }, [setReplyDraft, editor]); const handleRemoveUpload = useCallback( (upload: TUploadContent | TUploadContent[]) => { From bc5e7445d9cb1ff2ad71981b8d405c221aacbd34 Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Fri, 16 Jun 2023 11:09:09 +1000 Subject: [PATCH 1031/1531] Add ESC btn to toolbar to quickly exit formatting (#1283) * Add ESC btn to toolbar to quickly exit formatting * add horizontal scroll to toolbar item * make editor toolbar usable in touch device * fix editor hotkeys not working in window * remove unused import --- src/app/components/editor/Editor.css.ts | 14 +- src/app/components/editor/Editor.tsx | 8 +- src/app/components/editor/Toolbar.tsx | 225 +++++++++++++++--------- src/app/components/editor/common.ts | 4 +- src/app/components/editor/keyboard.ts | 6 +- src/app/organisms/room/RoomInput.tsx | 58 ++++-- src/app/utils/key-symbol.ts | 3 + 7 files changed, 210 insertions(+), 108 deletions(-) diff --git a/src/app/components/editor/Editor.css.ts b/src/app/components/editor/Editor.css.ts index 034ded79a..9ec8cfaf8 100644 --- a/src/app/components/editor/Editor.css.ts +++ b/src/app/components/editor/Editor.css.ts @@ -43,6 +43,7 @@ export const EditorPlaceholder = style([ { position: 'absolute', zIndex: 1, + width: '100%', opacity: config.opacity.Placeholder, pointerEvents: 'none', userSelect: 'none', @@ -55,9 +56,10 @@ export const EditorPlaceholder = style([ }, ]); -export const EditorToolbar = style([ - DefaultReset, - { - padding: config.space.S100, - }, -]); +export const EditorToolbarBase = style({ + padding: `0 ${config.borderWidth.B300}`, +}); + +export const EditorToolbar = style({ + padding: config.space.S100, +}); diff --git a/src/app/components/editor/Editor.tsx b/src/app/components/editor/Editor.tsx index 2657b2135..3f048a6f8 100644 --- a/src/app/components/editor/Editor.tsx +++ b/src/app/components/editor/Editor.tsx @@ -104,7 +104,13 @@ export const CustomEditor = forwardRef( // eslint-disable-next-line @typescript-eslint/no-unused-vars const { style, ...props } = attributes; return ( - + {children} ); diff --git a/src/app/components/editor/Toolbar.tsx b/src/app/components/editor/Toolbar.tsx index a84fca229..72e2c38cf 100644 --- a/src/app/components/editor/Toolbar.tsx +++ b/src/app/components/editor/Toolbar.tsx @@ -10,6 +10,7 @@ import { Line, Menu, PopOut, + Scroll, Text, Tooltip, TooltipProvider, @@ -17,7 +18,14 @@ import { } from 'folds'; import React, { ReactNode, useState } from 'react'; import { ReactEditor, useSlate } from 'slate-react'; -import { isBlockActive, isMarkActive, toggleBlock, toggleMark } from './common'; +import { + isAnyMarkActive, + isBlockActive, + isMarkActive, + removeAllMark, + toggleBlock, + toggleMark, +} from './common'; import * as css from './Editor.css'; import { BlockType, MarkType } from './Elements'; import { HeadingLevel } from './slate'; @@ -44,6 +52,11 @@ function BtnTooltip({ text, shortCode }: { text: string; shortCode?: string }) { type MarkButtonProps = { format: MarkType; icon: IconSrc; tooltip: ReactNode }; export function MarkButton({ format, icon, tooltip }: MarkButtonProps) { const editor = useSlate(); + const disableInline = isBlockActive(editor, BlockType.CodeBlock); + + if (disableInline) { + removeAllMark(editor); + } const handleClick = () => { toggleMark(editor, format); @@ -58,10 +71,11 @@ export function MarkButton({ format, icon, tooltip }: MarkButtonProps) { variant="SurfaceVariant" onClick={handleClick} aria-pressed={isMarkActive(editor, format)} - size="300" + size="400" radii="300" + disabled={disableInline} > - + )} @@ -89,10 +103,10 @@ export function BlockButton({ format, icon, tooltip }: BlockButtonProps) { variant="SurfaceVariant" onClick={handleClick} aria-pressed={isBlockActive(editor, format)} - size="300" + size="400" radii="300" > - + )} @@ -115,6 +129,7 @@ export function HeadingBlockButton() { return ( - handleMenuSelect(1)} size="300" radii="300"> - + handleMenuSelect(1)} size="400" radii="300"> + - handleMenuSelect(2)} size="300" radii="300"> - + handleMenuSelect(2)} size="400" radii="300"> + - handleMenuSelect(3)} size="300" radii="300"> - + handleMenuSelect(3)} size="400" radii="300"> + @@ -151,97 +166,143 @@ export function HeadingBlockButton() { variant="SurfaceVariant" onClick={() => (isActive ? toggleBlock(editor, BlockType.Heading) : setOpen(!open))} aria-pressed={isActive} - size="300" + size="400" radii="300" > - - + + )} ); } -export function Toolbar() { +type ExitFormattingProps = { tooltip: ReactNode }; +export function ExitFormatting({ tooltip }: ExitFormattingProps) { const editor = useSlate(); - const allowInline = !isBlockActive(editor, BlockType.CodeBlock); - const modKey = isMacOS() ? KeySymbol.Command : 'Ctrl'; + + const handleClick = () => { + if (isAnyMarkActive(editor)) { + removeAllMark(editor); + } else if (!isBlockActive(editor, BlockType.Paragraph)) { + toggleBlock(editor, BlockType.Paragraph); + } + ReactEditor.focus(editor); + }; return ( - - - - - } - /> - - } - /> - - } - /> - - } - /> - - {allowInline && ( - <> - - - } + + {(triggerRef) => ( + + {`Exit ${KeySymbol.Hyper}`} + + )} + + ); +} + +export function Toolbar() { + const editor = useSlate(); + const modKey = isMacOS() ? KeySymbol.Command : 'Ctrl'; + + const canEscape = isAnyMarkActive(editor) || !isBlockActive(editor, BlockType.Paragraph); + + return ( + + + + <> + + } + /> + } + /> + } + /> + + } + /> + } + /> + } + /> + + + + + + } /> - } + + } /> - } + + } /> - } /> - } - /> - } - /> + - - )} + {canEscape && ( + <> + + + } + /> + + + )} + + ); } diff --git a/src/app/components/editor/common.ts b/src/app/components/editor/common.ts index 619a1bfee..2f20790de 100644 --- a/src/app/components/editor/common.ts +++ b/src/app/components/editor/common.ts @@ -32,7 +32,9 @@ export const toggleMark = (editor: Editor, format: MarkType) => { }; export const removeAllMark = (editor: Editor) => { - ALL_MARK_TYPE.forEach((mark) => Editor.removeMark(editor, mark)); + ALL_MARK_TYPE.forEach((mark) => { + if (isMarkActive(editor, mark)) Editor.removeMark(editor, mark); + }); }; export const isBlockActive = (editor: Editor, format: BlockType) => { diff --git a/src/app/components/editor/keyboard.ts b/src/app/components/editor/keyboard.ts index 3fbe5363d..b6e1c3f4f 100644 --- a/src/app/components/editor/keyboard.ts +++ b/src/app/components/editor/keyboard.ts @@ -15,7 +15,7 @@ export const INLINE_HOTKEYS: Record = { const INLINE_KEYS = Object.keys(INLINE_HOTKEYS); export const BLOCK_HOTKEYS: Record = { - 'mod+shift+0': BlockType.OrderedList, + 'mod+shift+7': BlockType.OrderedList, 'mod+shift+8': BlockType.UnorderedList, "mod+shift+'": BlockType.BlockQuote, 'mod+shift+;': BlockType.CodeBlock, @@ -26,12 +26,12 @@ const BLOCK_KEYS = Object.keys(BLOCK_HOTKEYS); * @return boolean true if shortcut is toggled. */ export const toggleKeyboardShortcut = (editor: Editor, event: KeyboardEvent): boolean => { - if (isHotkey('escape', event)) { + if (isHotkey('mod+e', event)) { if (isAnyMarkActive(editor)) { removeAllMark(editor); return true; } - console.log(isBlockActive(editor, BlockType.Paragraph)); + if (!isBlockActive(editor, BlockType.Paragraph)) { toggleBlock(editor, BlockType.Paragraph); return true; diff --git a/src/app/organisms/room/RoomInput.tsx b/src/app/organisms/room/RoomInput.tsx index e79f4883b..3a22b57f8 100644 --- a/src/app/organisms/room/RoomInput.tsx +++ b/src/app/organisms/room/RoomInput.tsx @@ -19,6 +19,7 @@ import { Icon, IconButton, Icons, + Line, Overlay, OverlayBackdrop, OverlayCenter, @@ -95,6 +96,7 @@ import { MessageReply } from '../../molecules/message/Message'; import colorMXID from '../../../util/colorMXID'; import { parseReplyBody, parseReplyFormattedBody } from '../../utils/room'; import { sanitizeText } from '../../utils/sanitize'; +import { getResizeObserverEntry, useResizeObserver } from '../../hooks/useResizeObserver'; interface RoomInputProps { roomViewRef: RefObject; @@ -158,6 +160,16 @@ export const RoomInput = forwardRef( const handlePaste = useFilePasteHandler(handleFiles); const dropZoneVisible = useFileDropZone(roomViewRef, handleFiles); + const [mobile, setMobile] = useState(document.body.clientWidth < 500); + useResizeObserver( + document.body, + useCallback((entries) => { + const bodyEntry = getResizeObserverEntry(document.body, entries); + if (bodyEntry && bodyEntry.contentRect.width < 500) setMobile(true); + else setMobile(false); + }, []) + ); + useEffect(() => { Transforms.insertFragment(editor, msgDraft); }, [editor, msgDraft]); @@ -500,27 +512,36 @@ export const RoomInput = forwardRef( > {(anchorRef) => ( <> - setEmojiBoardTab(EmojiBoardTab.Sticker)} - variant="SurfaceVariant" - size="300" - radii="300" - > - - + {!mobile && ( + setEmojiBoardTab(EmojiBoardTab.Sticker)} + variant="SurfaceVariant" + size="300" + radii="300" + > + + + )} setEmojiBoardTab(EmojiBoardTab.Emoji)} variant="SurfaceVariant" size="300" radii="300" > - + )} @@ -532,7 +553,14 @@ export const RoomInput = forwardRef( } - bottom={toolbar && } + bottom={ + toolbar && ( +
      + + +
      + ) + } />
      ); diff --git a/src/app/utils/key-symbol.ts b/src/app/utils/key-symbol.ts index 7e758fd94..00dd1042a 100644 --- a/src/app/utils/key-symbol.ts +++ b/src/app/utils/key-symbol.ts @@ -3,4 +3,7 @@ export enum KeySymbol { Shift = '⇧', Option = '⌥', Control = '⌃', + Hyper = '✦', + Super = '❖', + Escape = '⎋', } From 41f67cabc047dc44c36c5b907004c4d03b782a9d Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Fri, 16 Jun 2023 11:11:03 +1000 Subject: [PATCH 1032/1531] Add editor history (#1284) * add slate editor history * reset mark on editor reset --- package-lock.json | 12 ++++++++++++ package.json | 1 + src/app/components/editor/Editor.tsx | 4 ++-- src/app/components/editor/common.ts | 9 +++++++++ src/app/components/editor/slate.d.ts | 7 +++---- src/app/organisms/room/RoomInput.tsx | 3 +++ 6 files changed, 30 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index 99e3c9136..bb98ea699 100644 --- a/package-lock.json +++ b/package-lock.json @@ -48,6 +48,7 @@ "react-modal": "3.16.1", "sanitize-html": "2.8.0", "slate": "0.90.0", + "slate-history": "0.93.0", "slate-react": "0.90.0", "tippy.js": "6.3.7", "twemoji": "14.0.2", @@ -5210,6 +5211,17 @@ "tiny-warning": "^1.0.3" } }, + "node_modules/slate-history": { + "version": "0.93.0", + "resolved": "https://registry.npmjs.org/slate-history/-/slate-history-0.93.0.tgz", + "integrity": "sha512-Gr1GMGPipRuxIz41jD2/rbvzPj8eyar56TVMyJBvBeIpQSSjNISssvGNDYfJlSWM8eaRqf6DAcxMKzsLCYeX6g==", + "dependencies": { + "is-plain-object": "^5.0.0" + }, + "peerDependencies": { + "slate": ">=0.65.3" + } + }, "node_modules/slate-react": { "version": "0.90.0", "resolved": "https://registry.npmjs.org/slate-react/-/slate-react-0.90.0.tgz", diff --git a/package.json b/package.json index 5f0f42f28..bf9adeaea 100644 --- a/package.json +++ b/package.json @@ -58,6 +58,7 @@ "react-modal": "3.16.1", "sanitize-html": "2.8.0", "slate": "0.90.0", + "slate-history": "0.93.0", "slate-react": "0.90.0", "tippy.js": "6.3.7", "twemoji": "14.0.2", diff --git a/src/app/components/editor/Editor.tsx b/src/app/components/editor/Editor.tsx index 3f048a6f8..f4241e0e3 100644 --- a/src/app/components/editor/Editor.tsx +++ b/src/app/components/editor/Editor.tsx @@ -7,7 +7,6 @@ import React, { useCallback, useState, } from 'react'; - import { Box, Scroll, Text } from 'folds'; import { Descendant, Editor, createEditor } from 'slate'; import { @@ -18,6 +17,7 @@ import { RenderElementProps, RenderPlaceholderProps, } from 'slate-react'; +import { withHistory } from 'slate-history'; import { BlockType, RenderElement, RenderLeaf } from './Elements'; import { CustomElement } from './slate'; import * as css from './Editor.css'; @@ -50,7 +50,7 @@ const withVoid = (editor: Editor): Editor => { }; export const useEditor = (): Editor => { - const [editor] = useState(withInline(withVoid(withReact(createEditor())))); + const [editor] = useState(withInline(withVoid(withReact(withHistory(createEditor()))))); return editor; }; diff --git a/src/app/components/editor/common.ts b/src/app/components/editor/common.ts index 2f20790de..198840973 100644 --- a/src/app/components/editor/common.ts +++ b/src/app/components/editor/common.ts @@ -124,6 +124,15 @@ export const resetEditor = (editor: Editor) => { }); toggleBlock(editor, BlockType.Paragraph); + removeAllMark(editor); +}; + +export const resetEditorHistory = (editor: Editor) => { + // eslint-disable-next-line no-param-reassign + editor.history = { + undos: [], + redos: [], + }; }; export const createMentionElement = ( diff --git a/src/app/components/editor/slate.d.ts b/src/app/components/editor/slate.d.ts index a321904bf..74b207085 100644 --- a/src/app/components/editor/slate.d.ts +++ b/src/app/components/editor/slate.d.ts @@ -1,10 +1,11 @@ import { BaseEditor } from 'slate'; import { ReactEditor } from 'slate-react'; +import { HistoryEditor } from 'slate-history'; import { BlockType } from './Elements'; export type HeadingLevel = 1 | 2 | 3; -export type Editor = BaseEditor & ReactEditor; +export type Editor = BaseEditor & HistoryEditor & ReactEditor; export type Text = { text: string; @@ -96,11 +97,9 @@ export type CustomElement = | OrderedListElement | UnorderedListElement; -export type CustomEditor = BaseEditor & ReactEditor; - declare module 'slate' { interface CustomTypes { - Editor: BaseEditor & ReactEditor; + Editor: Editor; Element: CustomElement; Text: FormattedText & Text; } diff --git a/src/app/organisms/room/RoomInput.tsx b/src/app/organisms/room/RoomInput.tsx index 3a22b57f8..39016add2 100644 --- a/src/app/organisms/room/RoomInput.tsx +++ b/src/app/organisms/room/RoomInput.tsx @@ -50,6 +50,7 @@ import { EmoticonAutocomplete, createEmoticonElement, moveCursor, + resetEditorHistory, } from '../../components/editor'; import { EmojiBoard, EmojiBoardTab } from '../../components/emoji-board'; import { UseStateProvider } from '../../components/UseStateProvider'; @@ -180,6 +181,7 @@ export const RoomInput = forwardRef( const parsedDraft = JSON.parse(JSON.stringify(editor.children)); setMsgDraft(parsedDraft); resetEditor(editor); + resetEditorHistory(editor); }; }, [roomId, editor, setMsgDraft]); @@ -288,6 +290,7 @@ export const RoomInput = forwardRef( } mx.sendMessage(roomId, content); resetEditor(editor); + resetEditorHistory(editor); setReplyDraft(); sendTypingStatus(false); }, [mx, roomId, editor, replyDraft, sendTypingStatus, setReplyDraft]); From f05dccd384e60d7e93be307c409a3b5f0bda066f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 20 Jun 2023 09:07:04 +1000 Subject: [PATCH 1033/1531] Bump nginx from 1.25.0-alpine to 1.25.1-alpine (#1288) Bumps nginx from 1.25.0-alpine to 1.25.1-alpine. --- updated-dependencies: - dependency-name: nginx dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 3cae982a2..da04492cd 100644 --- a/Dockerfile +++ b/Dockerfile @@ -11,7 +11,7 @@ RUN npm run build ## App -FROM nginx:1.25.0-alpine +FROM nginx:1.25.1-alpine COPY --from=builder /src/dist /app From e6a343c7ec512f861725dbb5b37100967cb8ccf8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 20 Jun 2023 09:07:34 +1000 Subject: [PATCH 1034/1531] Bump docker/login-action from 2.1.0 to 2.2.0 (#1289) Bumps [docker/login-action](https://github.com/docker/login-action) from 2.1.0 to 2.2.0. - [Release notes](https://github.com/docker/login-action/releases) - [Commits](https://github.com/docker/login-action/compare/v2.1.0...v2.2.0) --- updated-dependencies: - dependency-name: docker/login-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/prod-deploy.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/prod-deploy.yml b/.github/workflows/prod-deploy.yml index 484ecba92..ef2cd752f 100644 --- a/.github/workflows/prod-deploy.yml +++ b/.github/workflows/prod-deploy.yml @@ -72,12 +72,12 @@ jobs: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v2.6.0 - name: Login to Docker Hub - uses: docker/login-action@v2.1.0 + uses: docker/login-action@v2.2.0 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} - name: Login to the Container registry - uses: docker/login-action@v2.1.0 + uses: docker/login-action@v2.2.0 with: registry: ghcr.io username: ${{ github.actor }} From bec78e84e6db82dec19cb1a8e004af07e40f029e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 20 Jun 2023 09:08:08 +1000 Subject: [PATCH 1035/1531] Bump docker/setup-qemu-action from 2.1.0 to 2.2.0 (#1295) Bumps [docker/setup-qemu-action](https://github.com/docker/setup-qemu-action) from 2.1.0 to 2.2.0. - [Release notes](https://github.com/docker/setup-qemu-action/releases) - [Commits](https://github.com/docker/setup-qemu-action/compare/v2.1.0...v2.2.0) --- updated-dependencies: - dependency-name: docker/setup-qemu-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/prod-deploy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/prod-deploy.yml b/.github/workflows/prod-deploy.yml index ef2cd752f..413cb11d3 100644 --- a/.github/workflows/prod-deploy.yml +++ b/.github/workflows/prod-deploy.yml @@ -68,7 +68,7 @@ jobs: - name: Checkout repository uses: actions/checkout@v3.5.3 - name: Set up QEMU - uses: docker/setup-qemu-action@v2.1.0 + uses: docker/setup-qemu-action@v2.2.0 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v2.6.0 - name: Login to Docker Hub From e65dd330848051e6ee93e2bce536cd49c349cdad Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 20 Jun 2023 09:08:37 +1000 Subject: [PATCH 1036/1531] Bump docker/build-push-action from 4.1.0 to 4.1.1 (#1290) Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 4.1.0 to 4.1.1. - [Release notes](https://github.com/docker/build-push-action/releases) - [Commits](https://github.com/docker/build-push-action/compare/v4.1.0...v4.1.1) --- updated-dependencies: - dependency-name: docker/build-push-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/docker-pr.yml | 2 +- .github/workflows/prod-deploy.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docker-pr.yml b/.github/workflows/docker-pr.yml index 3edc3c187..302351575 100644 --- a/.github/workflows/docker-pr.yml +++ b/.github/workflows/docker-pr.yml @@ -13,7 +13,7 @@ jobs: - name: Checkout repository uses: actions/checkout@v3.5.3 - name: Build Docker image - uses: docker/build-push-action@v4.1.0 + uses: docker/build-push-action@v4.1.1 with: context: . push: false diff --git a/.github/workflows/prod-deploy.yml b/.github/workflows/prod-deploy.yml index 413cb11d3..277fc742f 100644 --- a/.github/workflows/prod-deploy.yml +++ b/.github/workflows/prod-deploy.yml @@ -90,7 +90,7 @@ jobs: ${{ secrets.DOCKER_USERNAME }}/cinny ghcr.io/${{ github.repository }} - name: Build and push Docker image - uses: docker/build-push-action@v4.1.0 + uses: docker/build-push-action@v4.1.1 with: context: . platforms: linux/amd64,linux/arm64 From 3b1e3ea62cb63d4e00b89fa0c9efa2fc1e058c59 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 20 Jun 2023 09:09:06 +1000 Subject: [PATCH 1037/1531] Bump docker/metadata-action from 4.5.0 to 4.6.0 (#1292) Bumps [docker/metadata-action](https://github.com/docker/metadata-action) from 4.5.0 to 4.6.0. - [Release notes](https://github.com/docker/metadata-action/releases) - [Commits](https://github.com/docker/metadata-action/compare/v4.5.0...v4.6.0) --- updated-dependencies: - dependency-name: docker/metadata-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/prod-deploy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/prod-deploy.yml b/.github/workflows/prod-deploy.yml index 277fc742f..058b5f23d 100644 --- a/.github/workflows/prod-deploy.yml +++ b/.github/workflows/prod-deploy.yml @@ -84,7 +84,7 @@ jobs: password: ${{ secrets.GITHUB_TOKEN }} - name: Extract metadata (tags, labels) for Docker id: meta - uses: docker/metadata-action@v4.5.0 + uses: docker/metadata-action@v4.6.0 with: images: | ${{ secrets.DOCKER_USERNAME }}/cinny From b78d568d9f5b80ab674df6890dfc974de7c1c88c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 20 Jun 2023 09:09:25 +1000 Subject: [PATCH 1038/1531] Bump cla-assistant/github-action from 2.2.1 to 2.3.0 (#1294) Bumps [cla-assistant/github-action](https://github.com/cla-assistant/github-action) from 2.2.1 to 2.3.0. - [Release notes](https://github.com/cla-assistant/github-action/releases) - [Commits](https://github.com/cla-assistant/github-action/compare/v2.2.1...v2.3.0) --- updated-dependencies: - dependency-name: cla-assistant/github-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/cla.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cla.yml b/.github/workflows/cla.yml index b433b8d94..1b9461b67 100644 --- a/.github/workflows/cla.yml +++ b/.github/workflows/cla.yml @@ -12,7 +12,7 @@ jobs: - name: 'CLA Assistant' if: (github.event.comment.body == 'recheck' || github.event.comment.body == 'I have read the CLA Document and I hereby sign the CLA') || github.event_name == 'pull_request_target' # Beta Release - uses: cla-assistant/github-action@v2.2.1 + uses: cla-assistant/github-action@v2.3.0 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # the below token should have repo scope and must be manually added by you in the repository's secret From 715f2bc90743af665cfd2ed7258c1aaf2ce90fae Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 20 Jun 2023 09:10:12 +1000 Subject: [PATCH 1039/1531] Bump docker/setup-buildx-action from 2.6.0 to 2.7.0 (#1293) Bumps [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) from 2.6.0 to 2.7.0. - [Release notes](https://github.com/docker/setup-buildx-action/releases) - [Commits](https://github.com/docker/setup-buildx-action/compare/v2.6.0...v2.7.0) --- updated-dependencies: - dependency-name: docker/setup-buildx-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/prod-deploy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/prod-deploy.yml b/.github/workflows/prod-deploy.yml index 058b5f23d..66f405239 100644 --- a/.github/workflows/prod-deploy.yml +++ b/.github/workflows/prod-deploy.yml @@ -70,7 +70,7 @@ jobs: - name: Set up QEMU uses: docker/setup-qemu-action@v2.2.0 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2.6.0 + uses: docker/setup-buildx-action@v2.7.0 - name: Login to Docker Hub uses: docker/login-action@v2.2.0 with: From 4c84673bdf3ef3ffe593efe1f2614caa28a963a3 Mon Sep 17 00:00:00 2001 From: ZeroAurora Date: Wed, 21 Jun 2023 08:00:43 +0800 Subject: [PATCH 1040/1531] Improve verification instructions (#1301) --- src/app/organisms/settings/DeviceManage.jsx | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/app/organisms/settings/DeviceManage.jsx b/src/app/organisms/settings/DeviceManage.jsx index 4825e2387..74738ea8b 100644 --- a/src/app/organisms/settings/DeviceManage.jsx +++ b/src/app/organisms/settings/DeviceManage.jsx @@ -217,6 +217,26 @@ function DeviceManage() {
      Unverified sessions + {!isMeVerified && ( +
      + +
      + )} + {isMeVerified && unverified.length > 0 && ( +
      + +
      + )} {!isCSEnabled && (
      Date: Wed, 21 Jun 2023 20:59:02 +1000 Subject: [PATCH 1041/1531] fix global pack showing all room packs (#1303) --- src/app/plugins/custom-emoji.ts | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/src/app/plugins/custom-emoji.ts b/src/app/plugins/custom-emoji.ts index daceef44b..ffb379446 100644 --- a/src/app/plugins/custom-emoji.ts +++ b/src/app/plugins/custom-emoji.ts @@ -1,4 +1,4 @@ -import { IImageInfo, MatrixClient, Room } from 'matrix-js-sdk'; +import { IImageInfo, MatrixClient, MatrixEvent, Room } from 'matrix-js-sdk'; import { AccountDataEvent } from '../../types/matrix/accountData'; import { getAccountData, getStateEvents } from '../utils/room'; import { StateEvent } from '../../types/matrix/room'; @@ -225,21 +225,24 @@ export class ImagePack { } } -export function getRoomImagePacks(room: Room): ImagePack[] { - const dataEvents = getStateEvents(room, StateEvent.PoniesRoomEmotes); - - return dataEvents.reduce((roomPacks, packEvent) => { +export function packEventsToImagePacks(packEvents: MatrixEvent[]): ImagePack[] { + return packEvents.reduce((imagePacks, packEvent) => { const packId = packEvent?.getId(); const content = packEvent?.getContent() as PackContent | undefined; - if (!packId || !content) return roomPacks; + if (!packId || !content) return imagePacks; const pack = ImagePack.parsePack(packId, content); if (pack) { - roomPacks.push(pack); + imagePacks.push(pack); } - return roomPacks; + return imagePacks; }, []); } +export function getRoomImagePacks(room: Room): ImagePack[] { + const dataEvents = getStateEvents(room, StateEvent.PoniesRoomEmotes); + return packEventsToImagePacks(dataEvents); +} + export function getGlobalImagePacks(mx: MatrixClient): ImagePack[] { const emoteRoomsContent = getAccountData(mx, AccountDataEvent.PoniesEmoteRooms)?.getContent() as | EmoteRoomsContent @@ -255,7 +258,14 @@ export function getGlobalImagePacks(mx: MatrixClient): ImagePack[] { if (typeof rooms[roomId] !== 'object') return []; const room = mx.getRoom(roomId); if (!room) return []; - return getRoomImagePacks(room); + const packEventIdToUnknown = rooms[roomId]; + const roomPacks = getStateEvents(room, StateEvent.PoniesRoomEmotes); + const globalPacks = roomPacks.filter((mE) => { + const packKey = mE.getStateKey(); + if (typeof packKey === 'string') return !!packEventIdToUnknown[packKey]; + return false; + }); + return packEventsToImagePacks(globalPacks); }); return packs; From da32d0d9e7b2ccee0352cc63999fbf23bd4de869 Mon Sep 17 00:00:00 2001 From: Krishan <33421343+kfiven@users.noreply.github.com> Date: Wed, 21 Jun 2023 22:26:27 +1000 Subject: [PATCH 1042/1531] Update project link (#1302) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0d4a38ac2..0910dfbb2 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@

      A Matrix client focusing primarily on simple, elegant and secure interface. The main goal is to have an instant messaging application that is easy on people and has a modern touch. -- [Roadmap](https://github.com/ajbura/cinny/projects/11) +- [Roadmap](https://github.com/orgs/cinnyapp/projects/1) - [Contributing](./CONTRIBUTING.md) From c07905c360c7c975d9eda39964764ff0cb63ad01 Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Thu, 22 Jun 2023 09:14:50 +1000 Subject: [PATCH 1043/1531] Improve Members Right Panel (#1286) * fix room members hook * fix resize observer hook * add intersection observer hook * install react-virtual lib * improve right panel - WIP * add filters for members * fix bug in async search * categories members and add search * show spinner on room member fetch * make invite member btn clickable * so no member text * add line between room view and member drawer * fix imports * add screen size hook * fix set setting hook * make member drawer responsive * extract power level tags hook * fix room members hook * fix use async search api * produce search result on filter change --- package-lock.json | 173 +++++- package.json | 2 + .../autocomplete/EmoticonAutocomplete.tsx | 7 +- .../autocomplete/RoomMentionAutocomplete.tsx | 7 +- .../autocomplete/UserMentionAutocomplete.tsx | 7 +- src/app/components/emoji-board/EmojiBoard.tsx | 11 +- src/app/hooks/useAsyncSearch.ts | 17 +- src/app/hooks/useIntersectionObserver.ts | 37 ++ src/app/hooks/usePowerLevelTags.ts | 38 ++ src/app/hooks/useResizeObserver.ts | 7 +- src/app/hooks/useRoomMembers.ts | 15 +- src/app/hooks/useScreenSize.ts | 36 ++ src/app/organisms/room/MembersDrawer.css.ts | 64 +++ src/app/organisms/room/MembersDrawer.tsx | 528 ++++++++++++++++++ src/app/organisms/room/Room.jsx | 26 +- src/app/organisms/room/RoomInput.tsx | 21 +- src/app/organisms/room/RoomViewContent.jsx | 4 +- src/app/organisms/room/RoomViewHeader.jsx | 56 +- src/app/state/hooks/settings.ts | 7 +- 19 files changed, 984 insertions(+), 79 deletions(-) create mode 100644 src/app/hooks/useIntersectionObserver.ts create mode 100644 src/app/hooks/usePowerLevelTags.ts create mode 100644 src/app/hooks/useScreenSize.ts create mode 100644 src/app/organisms/room/MembersDrawer.css.ts create mode 100644 src/app/organisms/room/MembersDrawer.tsx diff --git a/package-lock.json b/package-lock.json index bb98ea699..61eebbf90 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,7 @@ "@fontsource/roboto": "4.5.8", "@khanacademy/simple-markdown": "0.8.6", "@matrix-org/olm": "3.2.14", + "@tanstack/react-virtual": "3.0.0-beta.54", "@tippyjs/react": "4.2.6", "@vanilla-extract/css": "1.9.3", "@vanilla-extract/recipes": "0.3.0", @@ -37,6 +38,7 @@ "linkify-html": "4.0.2", "linkifyjs": "4.0.2", "matrix-js-sdk": "24.1.0", + "millify": "6.1.0", "prop-types": "15.8.1", "react": "17.0.2", "react-autosize-textarea": "7.1.0", @@ -1106,6 +1108,30 @@ "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", "dev": true }, + "node_modules/@tanstack/react-virtual": { + "version": "3.0.0-beta.54", + "resolved": "https://registry.npmjs.org/@tanstack/react-virtual/-/react-virtual-3.0.0-beta.54.tgz", + "integrity": "sha512-D1mDMf4UPbrtHRZZriCly5bXTBMhylslm4dhcHqTtDJ6brQcgGmk8YD9JdWBGWfGSWPKoh2x1H3e7eh+hgPXtQ==", + "dependencies": { + "@tanstack/virtual-core": "3.0.0-beta.54" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@tanstack/virtual-core": { + "version": "3.0.0-beta.54", + "resolved": "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.0.0-beta.54.tgz", + "integrity": "sha512-jtkwqdP2rY2iCCDVAFuaNBH3fiEi29aTn2RhtIoky8DTTiCdc48plpHHreLwmv1PICJ4AJUUESaq3xa8fZH8+g==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, "node_modules/@tippyjs/react": { "version": "4.2.6", "resolved": "https://registry.npmjs.org/@tippyjs/react/-/react-4.2.6.tgz", @@ -1669,7 +1695,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, "engines": { "node": ">=8" } @@ -2058,6 +2083,19 @@ "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz", "integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==" }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -3349,6 +3387,14 @@ "node": ">=6.9.0" } }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, "node_modules/get-intrinsic": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", @@ -3771,6 +3817,14 @@ "node": ">=0.10.0" } }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", @@ -4286,6 +4340,17 @@ "node": ">=8.6" } }, + "node_modules/millify": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/millify/-/millify-6.1.0.tgz", + "integrity": "sha512-H/E3J6t+DQs/F2YgfDhxUVZz/dF8JXPPKTLHL/yHCcLZLtCXJDUaqvhJXQwqOVBvbyNn4T0WjLpIHd7PAw7fBA==", + "dependencies": { + "yargs": "^17.0.1" + }, + "bin": { + "millify": "bin/millify" + } + }, "node_modules/mini-svg-data-uri": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/mini-svg-data-uri/-/mini-svg-data-uri-1.4.4.tgz", @@ -4965,6 +5030,14 @@ "url": "https://github.com/sponsors/mysticatea" } }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/require-like": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/require-like/-/require-like-0.1.2.tgz", @@ -5256,6 +5329,24 @@ "node": ">=0.10.0" } }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, "node_modules/string.prototype.matchall": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.8.tgz", @@ -5307,7 +5398,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, "dependencies": { "ansi-regex": "^5.0.1" }, @@ -6166,12 +6256,66 @@ "node": ">=0.10.0" } }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "dev": true }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "engines": { + "node": ">=10" + } + }, "node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", @@ -6186,6 +6330,31 @@ "node": ">= 6" } }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "engines": { + "node": ">=12" + } + }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/package.json b/package.json index bf9adeaea..beaae0956 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "@fontsource/roboto": "4.5.8", "@khanacademy/simple-markdown": "0.8.6", "@matrix-org/olm": "3.2.14", + "@tanstack/react-virtual": "3.0.0-beta.54", "@tippyjs/react": "4.2.6", "@vanilla-extract/css": "1.9.3", "@vanilla-extract/recipes": "0.3.0", @@ -47,6 +48,7 @@ "linkify-html": "4.0.2", "linkifyjs": "4.0.2", "matrix-js-sdk": "24.1.0", + "millify": "6.1.0", "prop-types": "15.8.1", "react": "17.0.2", "react-autosize-textarea": "7.1.0", diff --git a/src/app/components/editor/autocomplete/EmoticonAutocomplete.tsx b/src/app/components/editor/autocomplete/EmoticonAutocomplete.tsx index 17712b870..2e556000c 100644 --- a/src/app/components/editor/autocomplete/EmoticonAutocomplete.tsx +++ b/src/app/components/editor/autocomplete/EmoticonAutocomplete.tsx @@ -60,12 +60,13 @@ export function EmoticonAutocomplete({ ); }, [imagePacks]); - const [result, search] = useAsyncSearch(searchList, getEmoticonStr, SEARCH_OPTIONS); + const [result, search, resetSearch] = useAsyncSearch(searchList, getEmoticonStr, SEARCH_OPTIONS); const autoCompleteEmoticon = result ? result.items : recentEmoji; useEffect(() => { - search(query.text); - }, [query.text, search]); + if (query.text) search(query.text); + else resetSearch(); + }, [query.text, search, resetSearch]); const handleAutocomplete: EmoticonCompleteHandler = (key, shortcode) => { const emoticonEl = createEmoticonElement(key, shortcode); diff --git a/src/app/components/editor/autocomplete/RoomMentionAutocomplete.tsx b/src/app/components/editor/autocomplete/RoomMentionAutocomplete.tsx index 2edfb8bc4..6bea1952b 100644 --- a/src/app/components/editor/autocomplete/RoomMentionAutocomplete.tsx +++ b/src/app/components/editor/autocomplete/RoomMentionAutocomplete.tsx @@ -81,7 +81,7 @@ export function RoomMentionAutocomplete({ return [...spaces, ...rooms, ...directs].sort(roomIdByActivity); }, []); - const [result, search] = useAsyncSearch( + const [result, search, resetSearch] = useAsyncSearch( allRoomId, useCallback( (rId) => { @@ -99,8 +99,9 @@ export function RoomMentionAutocomplete({ const autoCompleteRoomIds = result ? result.items : allRoomId.slice(0, 20); useEffect(() => { - search(query.text); - }, [query.text, search]); + if (query.text) search(query.text); + else resetSearch(); + }, [query.text, search, resetSearch]); const handleAutocomplete: MentionAutoCompleteHandler = (roomAliasOrId, name) => { const mentionEl = createMentionElement( diff --git a/src/app/components/editor/autocomplete/UserMentionAutocomplete.tsx b/src/app/components/editor/autocomplete/UserMentionAutocomplete.tsx index 10088ada6..00ecb0158 100644 --- a/src/app/components/editor/autocomplete/UserMentionAutocomplete.tsx +++ b/src/app/components/editor/autocomplete/UserMentionAutocomplete.tsx @@ -94,12 +94,13 @@ export function UserMentionAutocomplete({ const roomAliasOrId = room?.getCanonicalAlias() || roomId; const members = useRoomMembers(mx, roomId); - const [result, search] = useAsyncSearch(members, getRoomMemberStr, SEARCH_OPTIONS); + const [result, search, resetSearch] = useAsyncSearch(members, getRoomMemberStr, SEARCH_OPTIONS); const autoCompleteMembers = result ? result.items : members.slice(0, 20); useEffect(() => { - search(query.text); - }, [query.text, search]); + if (query.text) search(query.text); + else resetSearch(); + }, [query.text, search, resetSearch]); const handleAutocomplete: MentionAutoCompleteHandler = (uId, name) => { const mentionEl = createMentionElement( diff --git a/src/app/components/emoji-board/EmojiBoard.tsx b/src/app/components/emoji-board/EmojiBoard.tsx index 3b1ccc554..4005234ad 100644 --- a/src/app/components/emoji-board/EmojiBoard.tsx +++ b/src/app/components/emoji-board/EmojiBoard.tsx @@ -647,15 +647,20 @@ export function EmojiBoard({ return list; }, [emojiTab, usage, imagePacks]); - const [result, search] = useAsyncSearch(searchList, getSearchListItemStr, SEARCH_OPTIONS); + const [result, search, resetSearch] = useAsyncSearch( + searchList, + getSearchListItemStr, + SEARCH_OPTIONS + ); const handleOnChange: ChangeEventHandler = useDebounce( useCallback( (evt) => { const term = evt.target.value; - search(term); + if (term) search(term); + else resetSearch(); }, - [search] + [search, resetSearch] ), { wait: 200 } ); diff --git a/src/app/hooks/useAsyncSearch.ts b/src/app/hooks/useAsyncSearch.ts index b083a19ab..d0e73e7f8 100644 --- a/src/app/hooks/useAsyncSearch.ts +++ b/src/app/hooks/useAsyncSearch.ts @@ -25,11 +25,13 @@ export type UseAsyncSearchResult = items: TSearchItem[]; }; +export type SearchResetHandler = () => void; + export const useAsyncSearch = ( list: TSearchItem[], getItemStr: SearchItemStrGetter, options?: UseAsyncSearchOptions -): [UseAsyncSearchResult | undefined, AsyncSearchHandler] => { +): [UseAsyncSearchResult | undefined, AsyncSearchHandler, SearchResetHandler] => { const [result, setResult] = useState>(); const [searchCallback, terminateSearch] = useMemo(() => { @@ -51,7 +53,7 @@ export const useAsyncSearch = ( const handleResult: ResultHandler = (results, query) => setResult({ query, - items: results, + items: [...results], }); return AsyncSearch(list, handleMatch, handleResult, options); @@ -60,15 +62,16 @@ export const useAsyncSearch = ( const searchHandler: AsyncSearchHandler = useCallback( (query) => { const normalizedQuery = normalize(query, options?.normalizeOptions); - if (!normalizedQuery) { - setResult(undefined); - return; - } searchCallback(normalizedQuery); }, [searchCallback, options?.normalizeOptions] ); + const resetHandler: SearchResetHandler = useCallback(() => { + terminateSearch(); + setResult(undefined); + }, [terminateSearch]); + useEffect( () => () => { // terminate any ongoing search request on unmount. @@ -77,5 +80,5 @@ export const useAsyncSearch = ( [terminateSearch] ); - return [result, searchHandler]; + return [result, searchHandler, resetHandler]; }; diff --git a/src/app/hooks/useIntersectionObserver.ts b/src/app/hooks/useIntersectionObserver.ts new file mode 100644 index 000000000..754007aed --- /dev/null +++ b/src/app/hooks/useIntersectionObserver.ts @@ -0,0 +1,37 @@ +import { useEffect, useState } from 'react'; + +export type OnIntersectionCallback = (entries: IntersectionObserverEntry[]) => void; + +export type IntersectionObserverOpts = { + root?: Element | Document | null; + rootMargin?: string; + threshold?: number | number[]; +}; + +export const getIntersectionObserverEntry = ( + target: Element | Document, + entries: IntersectionObserverEntry[] +): IntersectionObserverEntry | undefined => entries.find((entry) => entry.target === target); + +export const useIntersectionObserver = ( + onIntersectionCallback: OnIntersectionCallback, + opts?: IntersectionObserverOpts | (() => IntersectionObserverOpts), + observeElement?: Element | null | (() => Element | null) +): IntersectionObserver | undefined => { + const [intersectionObserver, setIntersectionObserver] = useState(); + + useEffect(() => { + const initOpts = typeof opts === 'function' ? opts() : opts; + setIntersectionObserver(new IntersectionObserver(onIntersectionCallback, initOpts)); + }, [onIntersectionCallback, opts]); + + useEffect(() => { + const element = typeof observeElement === 'function' ? observeElement() : observeElement; + if (element) intersectionObserver?.observe(element); + return () => { + if (element) intersectionObserver?.unobserve(element); + }; + }, [intersectionObserver, observeElement]); + + return intersectionObserver; +}; diff --git a/src/app/hooks/usePowerLevelTags.ts b/src/app/hooks/usePowerLevelTags.ts new file mode 100644 index 000000000..dd0a3df8a --- /dev/null +++ b/src/app/hooks/usePowerLevelTags.ts @@ -0,0 +1,38 @@ +import { useCallback, useMemo } from 'react'; + +export type PowerLevelTag = { + name: string; +}; +export const usePowerLevelTags = () => { + const powerLevelTags = useMemo( + () => ({ + 9000: { + name: 'Goku', + }, + 101: { + name: 'Founder', + }, + 100: { + name: 'Admin', + }, + 50: { + name: 'Moderator', + }, + 0: { + name: 'Default', + }, + }), + [] + ); + + return useCallback( + (powerLevel: number): PowerLevelTag => { + if (powerLevel >= 9000) return powerLevelTags[9000]; + if (powerLevel >= 101) return powerLevelTags[101]; + if (powerLevel === 100) return powerLevelTags[100]; + if (powerLevel >= 50) return powerLevelTags[50]; + return powerLevelTags[0]; + }, + [powerLevelTags] + ); +}; diff --git a/src/app/hooks/useResizeObserver.ts b/src/app/hooks/useResizeObserver.ts index 69ec65d06..1e0fc7263 100644 --- a/src/app/hooks/useResizeObserver.ts +++ b/src/app/hooks/useResizeObserver.ts @@ -8,17 +8,18 @@ export const getResizeObserverEntry = ( ): ResizeObserverEntry | undefined => entries.find((entry) => entry.target === target); export const useResizeObserver = ( - element: Element | null, - onResizeCallback: OnResizeCallback + onResizeCallback: OnResizeCallback, + observeElement?: Element | null | (() => Element | null) ): ResizeObserver => { const resizeObserver = useMemo(() => new ResizeObserver(onResizeCallback), [onResizeCallback]); useEffect(() => { + const element = typeof observeElement === 'function' ? observeElement() : observeElement; if (element) resizeObserver.observe(element); return () => { if (element) resizeObserver.unobserve(element); }; - }, [resizeObserver, element]); + }, [resizeObserver, observeElement]); return resizeObserver; }; diff --git a/src/app/hooks/useRoomMembers.ts b/src/app/hooks/useRoomMembers.ts index 544d97a08..df369011b 100644 --- a/src/app/hooks/useRoomMembers.ts +++ b/src/app/hooks/useRoomMembers.ts @@ -1,23 +1,25 @@ import { MatrixClient, MatrixEvent, RoomMember, RoomMemberEvent } from 'matrix-js-sdk'; import { useEffect, useState } from 'react'; -import { useAlive } from './useAlive'; export const useRoomMembers = (mx: MatrixClient, roomId: string): RoomMember[] => { const [members, setMembers] = useState([]); - const alive = useAlive(); useEffect(() => { const room = mx.getRoom(roomId); + let loadingMembers = true; + let disposed = false; const updateMemberList = (event?: MatrixEvent) => { - if (!room || !alive || (event && event.getRoomId() !== roomId)) return; + if (!room || disposed || (event && event.getRoomId() !== roomId)) return; + if (loadingMembers) return; setMembers(room.getMembers()); }; if (room) { - updateMemberList(); + setMembers(room.getMembers()); room.loadMembersIfNeeded().then(() => { - if (!alive) return; + loadingMembers = false; + if (disposed) return; updateMemberList(); }); } @@ -25,10 +27,11 @@ export const useRoomMembers = (mx: MatrixClient, roomId: string): RoomMember[] = mx.on(RoomMemberEvent.Membership, updateMemberList); mx.on(RoomMemberEvent.PowerLevel, updateMemberList); return () => { + disposed = true; mx.removeListener(RoomMemberEvent.Membership, updateMemberList); mx.removeListener(RoomMemberEvent.PowerLevel, updateMemberList); }; - }, [mx, roomId, alive]); + }, [mx, roomId]); return members; }; diff --git a/src/app/hooks/useScreenSize.ts b/src/app/hooks/useScreenSize.ts new file mode 100644 index 000000000..4afe90832 --- /dev/null +++ b/src/app/hooks/useScreenSize.ts @@ -0,0 +1,36 @@ +import { useCallback, useState } from 'react'; +import { getResizeObserverEntry, useResizeObserver } from './useResizeObserver'; + +export const TABLET_BREAKPOINT = 1124; +export const MOBILE_BREAKPOINT = 750; + +export enum ScreenSize { + Desktop = 'Desktop', + Tablet = 'Tablet', + Mobile = 'Mobile', +} + +export const getScreenSize = (width: number): ScreenSize => { + if (width > TABLET_BREAKPOINT) return ScreenSize.Desktop; + if (width > MOBILE_BREAKPOINT) return ScreenSize.Tablet; + return ScreenSize.Mobile; +}; + +export const useScreenSize = (): [ScreenSize, number] => { + const [size, setSize] = useState<[ScreenSize, number]>([ + getScreenSize(document.body.clientWidth), + document.body.clientWidth, + ]); + useResizeObserver( + useCallback((entries) => { + const bodyEntry = getResizeObserverEntry(document.body, entries); + if (bodyEntry) { + const bWidth = bodyEntry.contentRect.width; + setSize([getScreenSize(bWidth), bWidth]); + } + }, []), + document.body + ); + + return size; +}; diff --git a/src/app/organisms/room/MembersDrawer.css.ts b/src/app/organisms/room/MembersDrawer.css.ts new file mode 100644 index 000000000..2718e92d1 --- /dev/null +++ b/src/app/organisms/room/MembersDrawer.css.ts @@ -0,0 +1,64 @@ +import { keyframes, style } from '@vanilla-extract/css'; +import { color, config, toRem } from 'folds'; + +export const MembersDrawer = style({ + width: toRem(266), + backgroundColor: color.Background.Container, + color: color.Background.OnContainer, +}); + +export const MembersDrawerHeader = style({ + flexShrink: 0, + padding: `0 ${config.space.S200} 0 ${config.space.S300}`, + borderBottomWidth: config.borderWidth.B300, +}); + +export const MemberDrawerContentBase = style({ + position: 'relative', + overflow: 'hidden', +}); + +export const MemberDrawerContent = style({ + padding: `${config.space.S300} 0`, +}); + +const ScrollBtnAnime = keyframes({ + '0%': { + transform: `translate(-50%, -100%) scale(0)`, + }, + '100%': { + transform: `translate(-50%, 0) scale(1)`, + }, +}); + +export const DrawerScrollTop = style({ + position: 'absolute', + top: config.space.S200, + left: '50%', + transform: 'translateX(-50%)', + zIndex: 1, + animation: `${ScrollBtnAnime} 100ms`, +}); + +export const DrawerGroup = style({ + padding: `0 ${config.space.S100} 0 ${config.space.S300}`, +}); + +export const MembersGroup = style({ + paddingLeft: config.space.S200, +}); +export const MembersGroupLabel = style({ + padding: config.space.S200, + selectors: { + '&:not(:first-child)': { + paddingTop: config.space.S500, + }, + }, +}); + +export const DrawerVirtualItem = style({ + position: 'absolute', + top: 0, + left: 0, + width: '100%', +}); diff --git a/src/app/organisms/room/MembersDrawer.tsx b/src/app/organisms/room/MembersDrawer.tsx new file mode 100644 index 000000000..d50c3666b --- /dev/null +++ b/src/app/organisms/room/MembersDrawer.tsx @@ -0,0 +1,528 @@ +import React, { + ChangeEventHandler, + MouseEventHandler, + useCallback, + useMemo, + useRef, + useState, +} from 'react'; +import { + Avatar, + AvatarFallback, + AvatarImage, + Box, + Chip, + ContainerColor, + Header, + Icon, + IconButton, + Icons, + Input, + Menu, + MenuItem, + PopOut, + Scroll, + Spinner, + Text, + Tooltip, + TooltipProvider, + config, +} from 'folds'; +import { Room, RoomMember } from 'matrix-js-sdk'; +import { useVirtualizer } from '@tanstack/react-virtual'; +import FocusTrap from 'focus-trap-react'; +import millify from 'millify'; +import classNames from 'classnames'; + +import { openInviteUser, openProfileViewer } from '../../../client/action/navigation'; +import * as css from './MembersDrawer.css'; +import { useRoomMembers } from '../../hooks/useRoomMembers'; +import { useMatrixClient } from '../../hooks/useMatrixClient'; +import { + getIntersectionObserverEntry, + useIntersectionObserver, +} from '../../hooks/useIntersectionObserver'; +import { Membership } from '../../../types/matrix/room'; +import { UseStateProvider } from '../../components/UseStateProvider'; +import { UseAsyncSearchOptions, useAsyncSearch } from '../../hooks/useAsyncSearch'; +import { useDebounce } from '../../hooks/useDebounce'; +import colorMXID from '../../../util/colorMXID'; +import { usePowerLevelTags, PowerLevelTag } from '../../hooks/usePowerLevelTags'; + +export const MembershipFilters = { + filterJoined: (m: RoomMember) => m.membership === Membership.Join, + filterInvited: (m: RoomMember) => m.membership === Membership.Invite, + filterLeaved: (m: RoomMember) => + m.membership === Membership.Leave && + m.events.member?.getStateKey() === m.events.member?.getSender(), + filterKicked: (m: RoomMember) => + m.membership === Membership.Leave && + m.events.member?.getStateKey() !== m.events.member?.getSender(), + filterBanned: (m: RoomMember) => m.membership === Membership.Ban, +}; + +export type MembershipFilterFn = (m: RoomMember) => boolean; + +export type MembershipFilter = { + name: string; + filterFn: MembershipFilterFn; + color: ContainerColor; +}; + +const useMembershipFilterMenu = (): MembershipFilter[] => + useMemo( + () => [ + { + name: 'Joined', + filterFn: MembershipFilters.filterJoined, + color: 'Surface', + }, + { + name: 'Invited', + filterFn: MembershipFilters.filterInvited, + color: 'Success', + }, + { + name: 'Left', + filterFn: MembershipFilters.filterLeaved, + color: 'Secondary', + }, + { + name: 'Kicked', + filterFn: MembershipFilters.filterKicked, + color: 'Warning', + }, + { + name: 'Banned', + filterFn: MembershipFilters.filterBanned, + color: 'Critical', + }, + ], + [] + ); + +export const SortFilters = { + filterAscending: (a: RoomMember, b: RoomMember) => + a.name.toLowerCase() < b.name.toLowerCase() ? -1 : 1, + filterDescending: (a: RoomMember, b: RoomMember) => + a.name.toLowerCase() > b.name.toLowerCase() ? -1 : 1, + filterNewestFirst: (a: RoomMember, b: RoomMember) => + (b.events.member?.getTs() ?? 0) - (a.events.member?.getTs() ?? 0), + filterOldest: (a: RoomMember, b: RoomMember) => + (a.events.member?.getTs() ?? 0) - (b.events.member?.getTs() ?? 0), +}; + +export type SortFilterFn = (a: RoomMember, b: RoomMember) => number; + +export type SortFilter = { + name: string; + filterFn: SortFilterFn; +}; + +const useSortFilterMenu = (): SortFilter[] => + useMemo( + () => [ + { + name: 'A to Z', + filterFn: SortFilters.filterAscending, + }, + { + name: 'Z to A', + filterFn: SortFilters.filterDescending, + }, + { + name: 'Newest First', + filterFn: SortFilters.filterNewestFirst, + }, + { + name: 'Oldest First', + filterFn: SortFilters.filterOldest, + }, + ], + [] + ); + +export type MembersFilterOptions = { + membershipFilter: MembershipFilter; + sortFilter: SortFilter; +}; + +const SEARCH_OPTIONS: UseAsyncSearchOptions = { + limit: 100, + matchOptions: { + contain: true, + }, +}; +const getMemberItemStr = (m: RoomMember) => [m.name, m.userId]; + +type MembersDrawerProps = { + room: Room; +}; +export function MembersDrawer({ room }: MembersDrawerProps) { + const mx = useMatrixClient(); + const scrollRef = useRef(null); + const searchInputRef = useRef(null); + const scrollTopAnchorRef = useRef(null); + const members = useRoomMembers(mx, room.roomId); + const getPowerLevelTag = usePowerLevelTags(); + const fetchingMembers = members.length < room.getJoinedMemberCount(); + + const membershipFilterMenu = useMembershipFilterMenu(); + const sortFilterMenu = useSortFilterMenu(); + const [filter, setFilter] = useState({ + membershipFilter: membershipFilterMenu[0], + sortFilter: sortFilterMenu[0], + }); + const [onTop, setOnTop] = useState(true); + + const filteredMembers = useMemo( + () => + members + .filter(filter.membershipFilter.filterFn) + .sort(filter.sortFilter.filterFn) + .sort((a, b) => b.powerLevel - a.powerLevel), + [members, filter] + ); + + const [result, search, resetSearch] = useAsyncSearch( + filteredMembers, + getMemberItemStr, + SEARCH_OPTIONS + ); + if (!result && searchInputRef.current?.value) search(searchInputRef.current.value); + + const processMembers = result ? result.items : filteredMembers; + + const PLTagOrRoomMember = useMemo(() => { + let prevTag: PowerLevelTag | undefined; + const tagOrMember: Array = []; + processMembers.forEach((m) => { + const plTag = getPowerLevelTag(m.powerLevel); + if (plTag !== prevTag) { + prevTag = plTag; + tagOrMember.push(plTag); + } + tagOrMember.push(m); + }); + return tagOrMember; + }, [processMembers, getPowerLevelTag]); + + const virtualizer = useVirtualizer({ + count: PLTagOrRoomMember.length, + getScrollElement: () => scrollRef.current, + estimateSize: () => 40, + overscan: 10, + }); + + useIntersectionObserver( + useCallback((intersectionEntries) => { + if (!scrollTopAnchorRef.current) return; + const entry = getIntersectionObserverEntry(scrollTopAnchorRef.current, intersectionEntries); + if (entry) setOnTop(entry.isIntersecting); + }, []), + useCallback(() => ({ root: scrollRef.current }), []), + useCallback(() => scrollTopAnchorRef.current, []) + ); + + const handleSearchChange: ChangeEventHandler = useDebounce( + useCallback( + (evt) => { + if (evt.target.value) search(evt.target.value); + else resetSearch(); + }, + [search, resetSearch] + ), + { wait: 200 } + ); + + const handleMemberClick: MouseEventHandler = (evt) => { + const btn = evt.currentTarget as HTMLButtonElement; + const userId = btn.getAttribute('data-user-id'); + openProfileViewer(userId, room.roomId); + }; + + return ( + +
      + + + + {`${millify(room.getJoinedMemberCount(), { precision: 1 })} Members`} + + + + + Invite Member + + } + > + {(triggerRef) => ( + openInviteUser(room.roomId)} + > + + + )} + + + +
      + + + + + Filter + + + {(open, setOpen) => ( + setOpen(false), + clickOutsideDeactivates: true, + isKeyForward: (evt: KeyboardEvent) => evt.key === 'ArrowDown', + isKeyBackward: (evt: KeyboardEvent) => evt.key === 'ArrowUp', + }} + > + + {membershipFilterMenu.map((menuItem) => ( + { + setFilter((f) => ({ ...f, membershipFilter: menuItem })); + setOpen(false); + }} + > + {menuItem.name} + + ))} + + + } + > + {(anchorRef) => ( + setOpen(!open)} + variant={filter.membershipFilter.color} + radii="400" + outlined + after={} + > + {filter.membershipFilter.name} + + )} + + )} + + + {(open, setOpen) => ( + setOpen(false), + clickOutsideDeactivates: true, + isKeyForward: (evt: KeyboardEvent) => evt.key === 'ArrowDown', + isKeyBackward: (evt: KeyboardEvent) => evt.key === 'ArrowUp', + }} + > + + {sortFilterMenu.map((menuItem) => ( + { + setFilter((f) => ({ ...f, sortFilter: menuItem })); + setOpen(false); + }} + > + {menuItem.name} + + ))} + + + } + > + {(anchorRef) => ( + setOpen(!open)} + variant="Surface" + radii="400" + outlined + after={} + > + {`Order: ${filter.sortFilter.name}`} + + )} + + )} + + + + + + Search + } + after={ + result && ( + 0 ? 'Success' : 'Critical'} + size="400" + radii="Pill" + onClick={() => { + if (searchInputRef.current) searchInputRef.current.value = ''; + resetSearch(); + }} + after={} + > + {`${result.items.length || 'No'} ${ + result.items.length === 1 ? 'Result' : 'Results' + }`} + + ) + } + /> + + + {!onTop && ( + + virtualizer.scrollToOffset(0)} + variant="Surface" + radii="Pill" + outlined + size="300" + aria-label="Scroll to Top" + > + + + + )} + + {!fetchingMembers && !result && processMembers.length === 0 && ( + + {`No "${filter.membershipFilter.name}" Members`} + + )} + + +
      + {virtualizer.getVirtualItems().map((vItem) => { + const tagOrMember = PLTagOrRoomMember[vItem.index]; + if (!('userId' in tagOrMember)) { + return ( + + {tagOrMember.name} + + ); + } + + const member = tagOrMember; + const avatarUrl = member.getAvatarUrl( + mx.baseUrl, + 100, + 100, + 'crop', + undefined, + false + ); + + return ( + + {avatarUrl ? ( + + ) : ( + + {member.name[0]} + + )} + + } + > + + {member.name} + + + ); + })} +
      +
      + + {fetchingMembers && ( + + + + )} +
      +
      +
      +
      + ); +} diff --git a/src/app/organisms/room/Room.jsx b/src/app/organisms/room/Room.jsx index 9d861c962..0603b985a 100644 --- a/src/app/organisms/room/Room.jsx +++ b/src/app/organisms/room/Room.jsx @@ -1,9 +1,9 @@ import React, { useState, useEffect } from 'react'; import './Room.scss'; +import { Line } from 'folds'; import initMatrix from '../../../client/initMatrix'; import cons from '../../../client/state/cons'; -import settings from '../../../client/state/settings'; import RoomTimeline from '../../../client/state/RoomTimeline'; import navigation from '../../../client/state/navigation'; import { openNavigation } from '../../../client/action/navigation'; @@ -11,7 +11,10 @@ import { openNavigation } from '../../../client/action/navigation'; import Welcome from '../welcome/Welcome'; import RoomView from './RoomView'; import RoomSettings from './RoomSettings'; -import PeopleDrawer from './PeopleDrawer'; +import { MembersDrawer } from './MembersDrawer'; +import { ScreenSize, useScreenSize } from '../../hooks/useScreenSize'; +import { useSetting } from '../../state/hooks/settings'; +import { settingsAtom } from '../../state/settings'; function Room() { const [roomInfo, setRoomInfo] = useState({ @@ -19,7 +22,8 @@ function Room() { roomTimeline: null, eventId: null, }); - const [isDrawer, setIsDrawer] = useState(settings.isPeopleDrawer); + const [isDrawer] = useSetting(settingsAtom, 'isPeopleDrawer'); + const [screenSize] = useScreenSize(); const mx = initMatrix.matrixClient; @@ -49,14 +53,6 @@ function Room() { }; }, [roomInfo, mx]); - useEffect(() => { - const handleDrawerToggling = (visiblity) => setIsDrawer(visiblity); - settings.on(cons.events.settings.PEOPLE_DRAWER_TOGGLED, handleDrawerToggling); - return () => { - settings.removeListener(cons.events.settings.PEOPLE_DRAWER_TOGGLED, handleDrawerToggling); - }; - }, []); - const { room, roomTimeline, eventId } = roomInfo; if (roomTimeline === null) { setTimeout(() => openNavigation()); @@ -69,7 +65,13 @@ function Room() {
      - {isDrawer && } + + {screenSize === ScreenSize.Desktop && isDrawer && ( + <> + + + + )}
      ); } diff --git a/src/app/organisms/room/RoomInput.tsx b/src/app/organisms/room/RoomInput.tsx index 39016add2..e869e16d0 100644 --- a/src/app/organisms/room/RoomInput.tsx +++ b/src/app/organisms/room/RoomInput.tsx @@ -97,7 +97,7 @@ import { MessageReply } from '../../molecules/message/Message'; import colorMXID from '../../../util/colorMXID'; import { parseReplyBody, parseReplyFormattedBody } from '../../utils/room'; import { sanitizeText } from '../../utils/sanitize'; -import { getResizeObserverEntry, useResizeObserver } from '../../hooks/useResizeObserver'; +import { useScreenSize } from '../../hooks/useScreenSize'; interface RoomInputProps { roomViewRef: RefObject; @@ -161,15 +161,8 @@ export const RoomInput = forwardRef( const handlePaste = useFilePasteHandler(handleFiles); const dropZoneVisible = useFileDropZone(roomViewRef, handleFiles); - const [mobile, setMobile] = useState(document.body.clientWidth < 500); - useResizeObserver( - document.body, - useCallback((entries) => { - const bodyEntry = getResizeObserverEntry(document.body, entries); - if (bodyEntry && bodyEntry.contentRect.width < 500) setMobile(true); - else setMobile(false); - }, []) - ); + const [, screenWidth] = useScreenSize(); + const hideStickerBtn = screenWidth < 500; useEffect(() => { Transforms.insertFragment(editor, msgDraft); @@ -515,7 +508,7 @@ export const RoomInput = forwardRef( > {(anchorRef) => ( <> - {!mobile && ( + {!hideStickerBtn && ( setEmojiBoardTab(EmojiBoardTab.Sticker)} @@ -532,7 +525,7 @@ export const RoomInput = forwardRef( setEmojiBoardTab(EmojiBoardTab.Emoji)} variant="SurfaceVariant" @@ -542,7 +535,9 @@ export const RoomInput = forwardRef( diff --git a/src/app/organisms/room/RoomViewContent.jsx b/src/app/organisms/room/RoomViewContent.jsx index fe598bf62..5726fe119 100644 --- a/src/app/organisms/room/RoomViewContent.jsx +++ b/src/app/organisms/room/RoomViewContent.jsx @@ -486,7 +486,6 @@ function RoomViewContent({ roomInputRef, eventId, roomTimeline }) { }, [newEvent]); useResizeObserver( - roomInputRef.current, useCallback((entries) => { if (!roomInputRef.current) return; const editorBaseEntry = getResizeObserverEntry(roomInputRef.current, entries); @@ -497,7 +496,8 @@ function RoomViewContent({ roomInputRef, eventId, roomTimeline }) { if (timelineScroll.bottom < 40 && !roomTimeline.canPaginateForward() && document.visibilityState === 'visible') { timelineScroll.scrollToBottom(); } - }, [roomInputRef]) + }, [roomInputRef]), + useCallback(() => roomInputRef.current, [roomInputRef]), ); const listenKeyboard = useCallback((event) => { diff --git a/src/app/organisms/room/RoomViewHeader.jsx b/src/app/organisms/room/RoomViewHeader.jsx index 46a6ba0e3..6571241eb 100644 --- a/src/app/organisms/room/RoomViewHeader.jsx +++ b/src/app/organisms/room/RoomViewHeader.jsx @@ -8,8 +8,11 @@ import { blurOnBubbling } from '../../atoms/button/script'; import initMatrix from '../../../client/initMatrix'; import cons from '../../../client/state/cons'; import navigation from '../../../client/state/navigation'; -import { toggleRoomSettings, openReusableContextMenu, openNavigation } from '../../../client/action/navigation'; -import { togglePeopleDrawer } from '../../../client/action/settings'; +import { + toggleRoomSettings, + openReusableContextMenu, + openNavigation, +} from '../../../client/action/navigation'; import colorMXID from '../../../util/colorMXID'; import { getEventCords } from '../../../util/common'; @@ -28,23 +31,26 @@ import VerticalMenuIC from '../../../../public/res/ic/outlined/vertical-menu.svg import BackArrowIC from '../../../../public/res/ic/outlined/chevron-left.svg'; import { useForceUpdate } from '../../hooks/useForceUpdate'; +import { useSetSetting } from '../../state/hooks/settings'; +import { settingsAtom } from '../../state/settings'; function RoomViewHeader({ roomId }) { const [, forceUpdate] = useForceUpdate(); const mx = initMatrix.matrixClient; const isDM = initMatrix.roomList.directs.has(roomId); const room = mx.getRoom(roomId); + const setPeopleDrawer = useSetSetting(settingsAtom, 'isPeopleDrawer'); let avatarSrc = room.getAvatarUrl(mx.baseUrl, 36, 36, 'crop'); - avatarSrc = isDM ? room.getAvatarFallbackMember()?.getAvatarUrl(mx.baseUrl, 36, 36, 'crop') : avatarSrc; + avatarSrc = isDM + ? room.getAvatarFallbackMember()?.getAvatarUrl(mx.baseUrl, 36, 36, 'crop') + : avatarSrc; const roomName = room.name; const roomHeaderBtnRef = useRef(null); useEffect(() => { const settingsToggle = (isVisibile) => { const rawIcon = roomHeaderBtnRef.current.lastElementChild; - rawIcon.style.transform = isVisibile - ? 'rotateX(180deg)' - : 'rotateX(0deg)'; + rawIcon.style.transform = isVisibile ? 'rotateX(180deg)' : 'rotateX(0deg)'; }; navigation.on(cons.events.navigation.ROOM_SETTINGS_TOGGLED, settingsToggle); return () => { @@ -66,11 +72,9 @@ function RoomViewHeader({ roomId }) { }, [roomId]); const openRoomOptions = (e) => { - openReusableContextMenu( - 'bottom', - getEventCords(e, '.ic-btn'), - (closeMenu) => , - ); + openReusableContextMenu('bottom', getEventCords(e, '.ic-btn'), (closeMenu) => ( + + )); }; return ( @@ -90,18 +94,34 @@ function RoomViewHeader({ roomId }) { > - {twemojify(roomName)} + + {twemojify(roomName)} + - {mx.isRoomEncrypted(roomId) === false && toggleRoomSettings(tabText.SEARCH)} tooltip="Search" src={SearchIC} />} - - toggleRoomSettings(tabText.MEMBERS)} tooltip="Members" src={UserIC} /> + {mx.isRoomEncrypted(roomId) === false && ( + toggleRoomSettings(tabText.SEARCH)} + tooltip="Search" + src={SearchIC} + /> + )} { + setPeopleDrawer((t) => !t); + }} + tooltip="People" + src={UserIC} /> + toggleRoomSettings(tabText.MEMBERS)} + tooltip="Members" + src={UserIC} + /> + ); } diff --git a/src/app/state/hooks/settings.ts b/src/app/state/hooks/settings.ts index 3f4dab60d..43b565534 100644 --- a/src/app/state/hooks/settings.ts +++ b/src/app/state/hooks/settings.ts @@ -10,9 +10,9 @@ export const useSetSetting = ( ) => { const setterAtom = useMemo( () => - atom(null, (get, set, value) => { + atom Settings[K])>(null, (get, set, value) => { const s = { ...get(settingsAtom) }; - s[key] = value; + s[key] = typeof value === 'function' ? value(s[key]) : value; set(settingsAtom, s); }), [settingsAtom, key] @@ -24,11 +24,10 @@ export const useSetSetting = ( export const useSetting = ( settingsAtom: WritableAtom, key: K -): [Settings[K], SetAtom] => { +): [Settings[K], SetAtom Settings[K]), void>] => { const selector = useMemo(() => (s: Settings) => s[key], [key]); const setting = useAtomValue(selectAtom(settingsAtom, selector)); const setter = useSetSetting(settingsAtom, key); - return [setting, setter]; }; From b19e24838364aff27aa90fcdc6a704968363085a Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Fri, 23 Jun 2023 09:46:04 +1000 Subject: [PATCH 1044/1531] Fix member panel filter layout (#1307) * fix member panel filter layout * make member role text lowercase --- src/app/organisms/room/MembersDrawer.css.ts | 2 +- src/app/organisms/room/MembersDrawer.tsx | 98 ++++++++++----------- 2 files changed, 50 insertions(+), 50 deletions(-) diff --git a/src/app/organisms/room/MembersDrawer.css.ts b/src/app/organisms/room/MembersDrawer.css.ts index 2718e92d1..6d347bf1a 100644 --- a/src/app/organisms/room/MembersDrawer.css.ts +++ b/src/app/organisms/room/MembersDrawer.css.ts @@ -41,7 +41,7 @@ export const DrawerScrollTop = style({ }); export const DrawerGroup = style({ - padding: `0 ${config.space.S100} 0 ${config.space.S300}`, + paddingLeft: config.space.S200, }); export const MembersGroup = style({ diff --git a/src/app/organisms/room/MembersDrawer.tsx b/src/app/organisms/room/MembersDrawer.tsx index d50c3666b..680a4e9d4 100644 --- a/src/app/organisms/room/MembersDrawer.tsx +++ b/src/app/organisms/room/MembersDrawer.tsx @@ -75,7 +75,7 @@ const useMembershipFilterMenu = (): MembershipFilter[] => { name: 'Joined', filterFn: MembershipFilters.filterJoined, - color: 'Surface', + color: 'Background', }, { name: 'Invited', @@ -131,11 +131,11 @@ const useSortFilterMenu = (): SortFilter[] => filterFn: SortFilters.filterDescending, }, { - name: 'Newest First', + name: 'New First', filterFn: SortFilters.filterNewestFirst, }, { - name: 'Oldest First', + name: 'Old First', filterFn: SortFilters.filterOldest, }, ], @@ -275,10 +275,9 @@ export function MembersDrawer({ room }: MembersDrawerProps) { - - - Filter - + + + {(open, setOpen) => ( { setFilter((f) => ({ ...f, membershipFilter: menuItem })); @@ -322,9 +322,9 @@ export function MembersDrawer({ room }: MembersDrawerProps) { ref={anchorRef} onClick={() => setOpen(!open)} variant={filter.membershipFilter.color} - radii="400" - outlined - after={} + size="400" + radii="300" + before={} > {filter.membershipFilter.name} @@ -337,7 +337,7 @@ export function MembersDrawer({ room }: MembersDrawerProps) { setOpen(!open)} - variant="Surface" - radii="400" - outlined - after={} + variant="Background" + size="400" + radii="300" + after={} > - {`Order: ${filter.sortFilter.name}`} + {filter.sortFilter.name} )} )} - - - Search - } - after={ - result && ( - 0 ? 'Success' : 'Critical'} - size="400" - radii="Pill" - onClick={() => { - if (searchInputRef.current) searchInputRef.current.value = ''; - resetSearch(); - }} - after={} - > - {`${result.items.length || 'No'} ${ - result.items.length === 1 ? 'Result' : 'Results' - }`} - - ) - } - /> + + } + after={ + result && ( + 0 ? 'Success' : 'Critical'} + size="400" + radii="Pill" + aria-pressed + onClick={() => { + if (searchInputRef.current) { + searchInputRef.current.value = ''; + searchInputRef.current.focus(); + } + resetSearch(); + }} + after={} + > + {`${result.items.length || 'No'} ${ + result.items.length === 1 ? 'Result' : 'Results' + }`} + + ) + } + /> + {!onTop && ( @@ -458,7 +458,7 @@ export function MembersDrawer({ room }: MembersDrawerProps) { ref={virtualizer.measureElement} key={`${room.roomId}-${vItem.index}`} className={classNames(css.MembersGroupLabel, css.DrawerVirtualItem)} - size="O400" + size="L400" > {tagOrMember.name} From b6283b3469707321430ba2d9820c9aaa07bf8049 Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Sun, 25 Jun 2023 08:40:48 +0530 Subject: [PATCH 1045/1531] Update member drawer icons (#1312) * update folds * update member drawer icons --- package-lock.json | 8 ++++---- package.json | 2 +- src/app/organisms/room/MembersDrawer.css.ts | 2 +- src/app/organisms/room/MembersDrawer.tsx | 18 +++++++++++------- 4 files changed, 17 insertions(+), 13 deletions(-) diff --git a/package-lock.json b/package-lock.json index 61eebbf90..d5867ae16 100644 --- a/package-lock.json +++ b/package-lock.json @@ -28,7 +28,7 @@ "file-saver": "2.0.5", "flux": "4.0.3", "focus-trap-react": "10.0.2", - "folds": "1.2.1", + "folds": "1.3.0", "formik": "2.2.9", "html-react-parser": "3.0.4", "immer": "9.0.16", @@ -3271,9 +3271,9 @@ } }, "node_modules/folds": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/folds/-/folds-1.2.1.tgz", - "integrity": "sha512-BCV5oFCndiGFp1HyeSnbDKmTSbu1yfAtAIF6znPvLthuI/QG4516bBUr6+MyNUQWx/IAkj1bdQL/cdD+jEZWCw==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/folds/-/folds-1.3.0.tgz", + "integrity": "sha512-Jcv6xN9woJWaTaATDGCD9xFqUhjuSw+afvChYoUt4UsAyY351hfpkGNYzglN+gA5fvJw6N9oa6Ogjj2p84kFfA==", "peerDependencies": { "@vanilla-extract/css": "^1.9.2", "@vanilla-extract/recipes": "^0.3.0", diff --git a/package.json b/package.json index beaae0956..5eb3fa988 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,7 @@ "file-saver": "2.0.5", "flux": "4.0.3", "focus-trap-react": "10.0.2", - "folds": "1.2.1", + "folds": "1.3.0", "formik": "2.2.9", "html-react-parser": "3.0.4", "immer": "9.0.16", diff --git a/src/app/organisms/room/MembersDrawer.css.ts b/src/app/organisms/room/MembersDrawer.css.ts index 6d347bf1a..a1f4153e8 100644 --- a/src/app/organisms/room/MembersDrawer.css.ts +++ b/src/app/organisms/room/MembersDrawer.css.ts @@ -19,7 +19,7 @@ export const MemberDrawerContentBase = style({ }); export const MemberDrawerContent = style({ - padding: `${config.space.S300} 0`, + padding: `${config.space.S200} 0`, }); const ScrollBtnAnime = keyframes({ diff --git a/src/app/organisms/room/MembersDrawer.tsx b/src/app/organisms/room/MembersDrawer.tsx index 680a4e9d4..5712c66f6 100644 --- a/src/app/organisms/room/MembersDrawer.tsx +++ b/src/app/organisms/room/MembersDrawer.tsx @@ -131,11 +131,11 @@ const useSortFilterMenu = (): SortFilter[] => filterFn: SortFilters.filterDescending, }, { - name: 'New First', + name: 'Newest', filterFn: SortFilters.filterNewestFirst, }, { - name: 'Old First', + name: 'Oldest', filterFn: SortFilters.filterOldest, }, ], @@ -254,6 +254,7 @@ export function MembersDrawer({ room }: MembersDrawerProps) { Invite Member @@ -275,8 +276,8 @@ export function MembersDrawer({ room }: MembersDrawerProps) { - - + + {(open, setOpen) => ( @@ -284,6 +285,7 @@ export function MembersDrawer({ room }: MembersDrawerProps) { open={open} position="Bottom" align="Start" + offset={4} content={ } + before={} > {filter.membershipFilter.name} @@ -338,6 +340,7 @@ export function MembersDrawer({ room }: MembersDrawerProps) { open={open} position="Bottom" align="End" + offset={4} content={ } + after={} > {filter.sortFilter.name} @@ -383,7 +386,6 @@ export function MembersDrawer({ room }: MembersDrawerProps) { )} - } after={ result && ( From f14d70ea3508a8467c0a27b9d61c8ab6661054ab Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Wed, 28 Jun 2023 17:27:28 +0530 Subject: [PATCH 1046/1531] fix msg event permission check (#1315) --- src/app/components/emoji-board/EmojiBoard.css.tsx | 2 +- src/app/hooks/usePowerLevels.ts | 2 +- src/app/organisms/room/RoomView.jsx | 5 ++++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/app/components/emoji-board/EmojiBoard.css.tsx b/src/app/components/emoji-board/EmojiBoard.css.tsx index adeb25005..ba4ca4e01 100644 --- a/src/app/components/emoji-board/EmojiBoard.css.tsx +++ b/src/app/components/emoji-board/EmojiBoard.css.tsx @@ -7,7 +7,7 @@ export const Base = style({ height: toRem(450), backgroundColor: color.Surface.Container, color: color.Surface.OnContainer, - border: `${config.borderWidth.B300} solid ${color.SurfaceVariant.ContainerLine}`, + border: `${config.borderWidth.B300} solid ${color.Surface.ContainerLine}`, borderRadius: config.radii.R400, boxShadow: config.shadow.E200, overflow: 'hidden', diff --git a/src/app/hooks/usePowerLevels.ts b/src/app/hooks/usePowerLevels.ts index 8f999d484..3ce75a2f2 100644 --- a/src/app/hooks/usePowerLevels.ts +++ b/src/app/hooks/usePowerLevels.ts @@ -47,7 +47,7 @@ export function usePowerLevels(room: Room) { const canSendEvent = useCallback( (eventType: string | undefined, powerLevel: number) => { const { events, events_default: eventsDefault } = powerLevels; - if (events && eventType && typeof events[eventType] === 'string') { + if (events && eventType && typeof events[eventType] === 'number') { return powerLevel >= events[eventType]; } return powerLevel >= (eventsDefault ?? DefaultPowerLevels.eventsDefault); diff --git a/src/app/organisms/room/RoomView.jsx b/src/app/organisms/room/RoomView.jsx index 591fcceae..9b3ae76fa 100644 --- a/src/app/organisms/room/RoomView.jsx +++ b/src/app/organisms/room/RoomView.jsx @@ -2,6 +2,7 @@ import React, { useEffect, useRef } from 'react'; import PropTypes from 'prop-types'; import './RoomView.scss'; import { Text, config } from 'folds'; +import { EventType } from 'matrix-js-sdk'; import EventEmitter from 'events'; @@ -32,7 +33,9 @@ function RoomView({ room, roomTimeline, eventId }) { const tombstoneEvent = useStateEvent(room, StateEvent.RoomTombstone); const { getPowerLevel, canSendEvent } = usePowerLevels(room); const myUserId = mx.getUserId(); - const canMessage = myUserId ? canSendEvent(undefined, getPowerLevel(myUserId)) : false; + const canMessage = myUserId + ? canSendEvent(EventType.RoomMessage, getPowerLevel(myUserId)) + : false; useEffect(() => { const settingsToggle = (isVisible) => { From 1a37fd0ca463d00d70273ca2b2f32bc7b4d936de Mon Sep 17 00:00:00 2001 From: greentore <117551249+greentore@users.noreply.github.com> Date: Sun, 23 Jul 2023 10:11:36 +0200 Subject: [PATCH 1047/1531] Use sticker body for searching (#1347) --- src/app/components/emoji-board/EmojiBoard.tsx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/app/components/emoji-board/EmojiBoard.tsx b/src/app/components/emoji-board/EmojiBoard.tsx index 4005234ad..76c6f05dd 100644 --- a/src/app/components/emoji-board/EmojiBoard.tsx +++ b/src/app/components/emoji-board/EmojiBoard.tsx @@ -598,7 +598,13 @@ export const NativeEmojiGroups = memo( ) ); -const getSearchListItemStr = (item: ExtendedPackImage | IEmoji) => `:${item.shortcode}:`; +const getSearchListItemStr = (item: ExtendedPackImage | IEmoji) => { + const shortcode = `:${item.shortcode}:`; + if ('body' in item) { + return [shortcode, item.body ?? '']; + } + return shortcode; +}; const SEARCH_OPTIONS: UseAsyncSearchOptions = { limit: 26, matchOptions: { From 053b80126239cc51679d7ece5b912af5fb68ddb8 Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Sun, 23 Jul 2023 18:12:09 +1000 Subject: [PATCH 1048/1531] Fix editor custom html output (#1348) * replace paragraph with line breaks * stop sending plain msg as custom html * removes console log * fix false negative for sanitized customHtml * fix customHtmlEqualsPlainText doc --- src/app/components/editor/output.ts | 18 ++++++++++++++++-- src/app/organisms/room/RoomInput.tsx | 10 +++++++--- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/src/app/components/editor/output.ts b/src/app/components/editor/output.ts index 38c544993..5d0443fa8 100644 --- a/src/app/components/editor/output.ts +++ b/src/app/components/editor/output.ts @@ -17,7 +17,7 @@ const textToCustomHtml = (node: FormattedText): string => { const elementToCustomHtml = (node: CustomElement, children: string): string => { switch (node.type) { case BlockType.Paragraph: - return `

      ${children}

      `; + return `${children}
      `; case BlockType.Heading: return `${children}`; case BlockType.CodeLine: @@ -25,7 +25,7 @@ const elementToCustomHtml = (node: CustomElement, children: string): string => { case BlockType.CodeBlock: return `
      ${children}
      `; case BlockType.QuoteLine: - return `

      ${children}

      `; + return `${children}
      `; case BlockType.BlockQuote: return `
      ${children}
      `; case BlockType.ListItem: @@ -93,3 +93,17 @@ export const toPlainText = (node: Descendant | Descendant[]): string => { const children = node.children.map((n) => toPlainText(n)).join(''); return elementToPlainText(node, children); }; + +/** + * Check if customHtml is equals to plainText + * by replacing `
      ` with `/n` in customHtml + * and sanitizing plainText before comparison + * because text are sanitized in customHtml + * @param customHtml string + * @param plain string + * @returns boolean + */ +export const customHtmlEqualsPlainText = (customHtml: string, plain: string): boolean => + customHtml.replace(//g, '\n') === sanitizeText(plain); + +export const trimCustomHtml = (customHtml: string) => customHtml.replace(/$/g, ''); diff --git a/src/app/organisms/room/RoomInput.tsx b/src/app/organisms/room/RoomInput.tsx index e869e16d0..a50c80047 100644 --- a/src/app/organisms/room/RoomInput.tsx +++ b/src/app/organisms/room/RoomInput.tsx @@ -51,6 +51,8 @@ import { createEmoticonElement, moveCursor, resetEditorHistory, + customHtmlEqualsPlainText, + trimCustomHtml, } from '../../components/editor'; import { EmojiBoard, EmojiBoardTab } from '../../components/emoji-board'; import { UseStateProvider } from '../../components/UseStateProvider'; @@ -251,7 +253,7 @@ export const RoomInput = forwardRef( uploadBoardHandlers.current?.handleSend(); const plainText = toPlainText(editor.children).trim(); - const customHtml = toMatrixCustomHTML(editor.children); + const customHtml = trimCustomHtml(toMatrixCustomHTML(editor.children)); if (plainText === '') return; @@ -271,9 +273,11 @@ export const RoomInput = forwardRef( const content: IContent = { msgtype: MsgType.Text, body, - format: 'org.matrix.custom.html', - formatted_body: formattedBody, }; + if (replyDraft || !customHtmlEqualsPlainText(formattedBody, body)) { + content.format = 'org.matrix.custom.html'; + content.formatted_body = formattedBody; + } if (replyDraft) { content['m.relates_to'] = { 'm.in_reply_to': { From 3c60976efa3ae0d4ab3e93a114cb00401b60e92b Mon Sep 17 00:00:00 2001 From: greentore <117551249+greentore@users.noreply.github.com> Date: Mon, 24 Jul 2023 06:40:43 +0200 Subject: [PATCH 1049/1531] Passive private receipt support (#1108) Co-authored-by: Ajay Bura <32841439+ajbura@users.noreply.github.com> --- src/client/state/Notifications.js | 22 ++++++++++++---------- src/client/state/cons.js | 4 ++++ 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/client/state/Notifications.js b/src/client/state/Notifications.js index db4610a34..13dd3e172 100644 --- a/src/client/state/Notifications.js +++ b/src/client/state/Notifications.js @@ -383,17 +383,19 @@ class Notifications extends EventEmitter { }); this.matrixClient.on('Room.receipt', (mEvent, room) => { - if (mEvent.getType() === 'm.receipt') { - if (room.isSpaceRoom()) return; - const content = mEvent.getContent(); - const readedEventId = Object.keys(content)[0]; - const readerUserId = Object.keys(content[readedEventId]['m.read'])[0]; - if (readerUserId !== this.matrixClient.getUserId()) return; + if (mEvent.getType() !== 'm.receipt' || room.isSpaceRoom()) return; + const content = mEvent.getContent(); + const userId = this.matrixClient.getUserId(); - this.deleteNoti(room.roomId); - - this._deletePopupRoomNotis(room.roomId); - } + Object.keys(content).forEach((eventId) => { + Object.entries(content[eventId]).forEach(([receiptType, receipt]) => { + if (!cons.supportReceiptTypes.includes(receiptType)) return; + if (Object.keys(receipt || {}).includes(userId)) { + this.deleteNoti(room.roomId); + this._deletePopupRoomNotis(room.roomId); + } + }); + }); }); this.matrixClient.on('Room.myMembership', (room, membership) => { diff --git a/src/client/state/cons.js b/src/client/state/cons.js index 8d9fda543..873c4e333 100644 --- a/src/client/state/cons.js +++ b/src/client/state/cons.js @@ -19,6 +19,10 @@ const cons = { 'm.room.member', 'm.sticker', ], + supportReceiptTypes: [ + 'm.read', + 'm.read.private', + ], notifs: { DEFAULT: 'default', ALL_MESSAGES: 'all_messages', From 1adee07127f184dd024d235467732471f4a4f296 Mon Sep 17 00:00:00 2001 From: ts <124226059+uniformization@users.noreply.github.com> Date: Wed, 26 Jul 2023 20:55:10 -0700 Subject: [PATCH 1050/1531] Fix Profile Viewer text (#1357) If you only had a single session open, the Profile Viewer would've said "View 1 sessions" instead of "View 1 session." --- src/app/organisms/profile-viewer/ProfileViewer.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/organisms/profile-viewer/ProfileViewer.jsx b/src/app/organisms/profile-viewer/ProfileViewer.jsx index fec9189a5..b6ce426e0 100644 --- a/src/app/organisms/profile-viewer/ProfileViewer.jsx +++ b/src/app/organisms/profile-viewer/ProfileViewer.jsx @@ -137,7 +137,7 @@ function SessionInfo({ userId }) { onClick={() => setIsVisible(!isVisible)} iconSrc={isVisible ? ChevronBottomIC : ChevronRightIC} > - {`View ${devices?.length > 0 ? `${devices.length} ` : ''}sessions`} + {`View ${devices?.length > 0 ? `${devices.length} ${devices.length == 1 ? 'session' : 'sessions'}` : 'sessions'}`} {renderSessionChips()}
      From 34b2901566bb49bdeab4cd6d3fb9dc7ee845279f Mon Sep 17 00:00:00 2001 From: greentore <117551249+greentore@users.noreply.github.com> Date: Thu, 3 Aug 2023 06:23:28 +0200 Subject: [PATCH 1051/1531] Prevent `manifest.json` from being inlined (#1359) * Disable asset inlining * Prevent `manifest.json` from being inlined * Update backtick to single quote in vite.config.js --------- Co-authored-by: Ajay Bura <32841439+ajbura@users.noreply.github.com> --- index.html | 2 +- vite.config.js | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/index.html b/index.html index 36c5740ae..6bc955c14 100644 --- a/index.html +++ b/index.html @@ -27,7 +27,7 @@ - + diff --git a/vite.config.js b/vite.config.js index 6a443166d..f09aa71e8 100644 --- a/vite.config.js +++ b/vite.config.js @@ -21,10 +21,14 @@ const copyFiles = { src: 'config.json', dest: '', }, + { + src: 'public/manifest.json', + dest: '', + }, { src: 'public/res/android', dest: 'public/', - } + }, ], } From 47f6c44c17dcf2c03e3ce0cbd8fd352069560556 Mon Sep 17 00:00:00 2001 From: Emi Date: Fri, 1 Sep 2023 00:49:34 -0400 Subject: [PATCH 1052/1531] Fix permission detection for updating emojis (#1125) --- src/app/molecules/room-emojis/RoomEmojis.jsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/app/molecules/room-emojis/RoomEmojis.jsx b/src/app/molecules/room-emojis/RoomEmojis.jsx index 81cee0a86..94ae61074 100644 --- a/src/app/molecules/room-emojis/RoomEmojis.jsx +++ b/src/app/molecules/room-emojis/RoomEmojis.jsx @@ -80,8 +80,7 @@ function RoomEmojis({ roomId }) { const { usablePacks, createPack, deletePack } = useRoomPacks(room); - const myPowerlevel = room.getMember(mx.getUserId())?.powerLevel || 0; - const canChange = room.currentState.hasSufficientPowerLevelFor('state_default', myPowerlevel); + const canChange = room.currentState.maySendStateEvent('im.ponies.room_emote', mx.getUserId()); const handlePackCreate = (e) => { e.preventDefault(); From fcd7723f73f1e89f4ea9fabd6e0c03c4c8a4ffd4 Mon Sep 17 00:00:00 2001 From: Alliegaytor <61523203+Alliegaytor@users.noreply.github.com> Date: Sun, 24 Sep 2023 14:31:02 +1000 Subject: [PATCH 1053/1531] Fix notifications not displaying when document is not focused (#1425) Allows notifications from the active room while app is not focused (e.g. tabbed out) --- src/client/state/Notifications.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/state/Notifications.js b/src/client/state/Notifications.js index 13dd3e172..09fa240e7 100644 --- a/src/client/state/Notifications.js +++ b/src/client/state/Notifications.js @@ -234,7 +234,7 @@ class Notifications extends EventEmitter { const actions = this.matrixClient.getPushActionsForEvent(mEvent); if (!actions?.notify) return; - if (navigation.selectedRoomId === room.roomId && document.visibilityState === 'visible') return; + if (navigation.selectedRoomId === room.roomId && document.hasFocus()) return; if (mEvent.isEncrypted()) { await mEvent.attemptDecryption(this.matrixClient.crypto); From 3a95d0da01c5c69d16fda6421188e1576ddae90b Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Fri, 6 Oct 2023 13:44:06 +1100 Subject: [PATCH 1054/1531] Refactor timeline (#1346) * fix intersection & resize observer * add binary search util * add scroll info util * add virtual paginator hook - WIP * render timeline using paginator hook * add continuous pagination to fill timeline * add doc comments in virtual paginator hook * add scroll to element func in virtual paginator * extract timeline pagination login into hook * add sliding name for timeline messages - testing * scroll with live event * change message rending style * make message timestamp smaller * remove unused imports * add random number between util * add compact message component * add sanitize html types * fix sending alias in room mention * get room member display name util * add get room with canonical alias util * add sanitize html util * render custom html with new styles * fix linkifying link text * add reaction component * display message reactions in timeline * Change mention color * show edited message * add event sent by function factory * add functions to get emoji shortcode * add component for reaction msg * add tooltip for who has reacted * add message layouts & placeholder * fix reaction size * fix dark theme colors * add code highlight with prismjs * add options to configure spacing in msgs * render message reply * fix trim reply from body regex * fix crash when loading reply * fix reply hover style * decrypt event on timeline paginate * update custom html code style * remove console logs * fix virtual paginator scroll to func * fix virtual paginator scroll to types * add stop scroll for in view item options * fix virtual paginator out of range scroll to index * scroll to and highlight reply on click * fix reply hover style * make message avatar clickable * fix scrollTo issue in virtual paginator * load reply from fetch * import virtual paginator restore scroll * load timeline for specific event * Fix back pagination recalibration * fix reply min height * revert code block colors to secondary * stop sanitizing text in code block * add decrypt file util * add image media component * update folds * fix code block font style * add msg event type * add scale dimension util * strict msg layout type * add image renderer component * add message content fallback components * add message matrix event renderer components * render matrix event using hooks * add attachment component * add attachment content types * handle error when rendering image in timeline * add video component * render video * include blurhash in thumbnails * generate thumbnails for image message * fix reactToDom spoiler opts * add hooks for HTMLMediaElement * render audio file in timeline * add msg image content component * fix image content props * add video content component * render new image/video component in timeline * remove console.log * convert seconds to milliseconds in video info * add load thumbnail prop to video content component * add file saver types * add file header component * add file content component * render file in timeline * add media control component * render audio message in room timeline * remove moved components * safely load message reply * add media loading hook * update media control layout * add loading indication in audio component * fill audio play icon when playing audio * fix media expanding * add image viewer - WIP * add pan and zoom control to image viewer * add text based file viewer * add pdf viewer * add error handling in pdf viewer * add download btn to pdf viewer * fix file button spinner fill * fix file opens on re-render * add range slider in audio content player * render location in timeline * update folds * display membership event in timeline * make reactions toggle * render sticker messages in timeline * render room name, topic, avatar change and event * fix typos * update render state event type style * add room intro in start of timeline * add power levels context * fix wrong param passing in RoomView * fix sending typing notification in wrong room Slate onChange callback was not updating with react re-renders. * send typing status on key up * add typing indicator component * add typing member atom * display typing status in member drawer * add room view typing member component * display typing members in room view * remove old roomTimeline uses * add event readers hook * add latest event hook * display following members in room view * fetch event instead of event context for reply * fix typo in virtual paginator hook * add scroll to latest btn in timeline * change scroll to latest chip variant * destructure paginator object to improve perf * restore forward dir scroll in virtual paginator * run scroll to bottom in layout effect * display unread message indicator in timeline * make component for room timeline float * add timeline divider component * add day divider and format message time * apply message spacing to dividers * format date in room intro * send read receipt on message arrive * add event readers component * add reply, read receipt, source delete opt * bug fixes * update timeline on delete & show reason * fix empty reaction container style * show msg selection effect on msg option open * add report message options * add options to send quick reactions * add emoji board in message options * add reaction viewer * fix styles * show view reaction in msg options menu * fix spacing between two msg by same person * add option menu in other rendered event * handle m.room.encrypted messages * fix italic reply text overflow cut * handle encrypted sticker messages * remove console log * prevent message context menu with alt key pressed * make mentions clickable in messages * add options to show and hidden events in timeline * add option to disable media autoload * remove old emojiboard opener * add options to use system emoji * refresh timeline on reset * fix stuck typing member in member drawer --- .eslintrc.js | 3 + package-lock.json | 648 ++++++- package.json | 13 +- .../components/Pdf-viewer/PdfViewer.css.ts | 37 + src/app/components/Pdf-viewer/PdfViewer.tsx | 257 +++ src/app/components/Pdf-viewer/index.ts | 1 + src/app/components/editor/Editor.tsx | 5 +- src/app/components/editor/Elements.tsx | 12 +- .../autocomplete/RoomMentionAutocomplete.tsx | 7 +- src/app/components/emoji-board/EmojiBoard.tsx | 4 +- .../event-readers/EventReaders.css.ts | 21 + .../components/event-readers/EventReaders.tsx | 110 ++ src/app/components/event-readers/index.ts | 1 + .../image-viewer/ImageViewer.css.ts | 40 + .../components/image-viewer/ImageViewer.tsx | 95 + src/app/components/image-viewer/index.ts | 1 + src/app/components/media/Image.tsx | 9 + src/app/components/media/MediaControls.tsx | 27 + src/app/components/media/Video.tsx | 10 + src/app/components/media/index.ts | 3 + src/app/components/media/media.css.ts | 20 + .../message/MessageContentFallback.tsx | 66 + src/app/components/message/Reaction.css.ts | 75 + src/app/components/message/Reaction.tsx | 113 ++ src/app/components/message/Reply.css.ts | 25 + src/app/components/message/Reply.tsx | 100 + src/app/components/message/Time.tsx | 27 + .../message/attachment/Attachment.css.ts | 42 + .../message/attachment/Attachment.tsx | 44 + .../components/message/attachment/index.ts | 1 + src/app/components/message/index.ts | 7 + src/app/components/message/layout/Base.tsx | 25 + src/app/components/message/layout/Bubble.tsx | 18 + src/app/components/message/layout/Compact.tsx | 18 + src/app/components/message/layout/Modern.tsx | 18 + src/app/components/message/layout/index.ts | 4 + .../components/message/layout/layout.css.ts | 155 ++ .../placeholder/CompactPlaceholder.tsx | 22 + .../placeholder/DefaultPlaceholder.tsx | 25 + .../placeholder/LinePlaceholder.css.ts | 12 + .../message/placeholder/LinePlaceholder.tsx | 8 + .../components/message/placeholder/index.ts | 3 + src/app/components/room-intro/RoomIntro.tsx | 114 ++ src/app/components/room-intro/index.ts | 1 + .../components/text-viewer/TextViewer.css.ts | 37 + src/app/components/text-viewer/TextViewer.tsx | 69 + src/app/components/text-viewer/index.ts | 1 + .../typing-indicator/TypingIndicator.css.ts | 49 + .../typing-indicator/TypingIndicator.tsx | 21 + src/app/components/typing-indicator/index.ts | 1 + src/app/hooks/media/index.ts | 6 + src/app/hooks/media/useMediaLoading.ts | 51 + src/app/hooks/media/useMediaPlay.ts | 46 + .../hooks/media/useMediaPlayTimeCallback.ts | 24 + src/app/hooks/media/useMediaPlaybackRate.ts | 40 + src/app/hooks/media/useMediaSeek.ts | 51 + src/app/hooks/media/useMediaVolume.ts | 60 + src/app/hooks/useIntersectionObserver.ts | 2 + src/app/hooks/useMatrixEventRenderer.ts | 80 + src/app/hooks/useMemberEventParser.tsx | 218 +++ src/app/hooks/usePan.ts | 62 + src/app/hooks/usePowerLevels.ts | 43 +- src/app/hooks/useRelations.ts | 25 + src/app/hooks/useResizeObserver.ts | 2 + src/app/hooks/useRoomEventReaders.ts | 35 + src/app/hooks/useRoomLatestEvent.ts | 29 + src/app/hooks/useRoomMsgContentRenderer.ts | 68 + src/app/hooks/useVirtualPaginator.ts | 405 ++++ src/app/hooks/useZoom.ts | 26 + src/app/organisms/room/MembersDrawer.tsx | 33 +- src/app/organisms/room/Room.jsx | 79 - src/app/organisms/room/Room.tsx | 46 + src/app/organisms/room/RoomInput.tsx | 31 +- src/app/organisms/room/RoomTimeline.css.ts | 30 + src/app/organisms/room/RoomTimeline.tsx | 1689 +++++++++++++++++ src/app/organisms/room/RoomView.jsx | 39 +- .../organisms/room/RoomViewFollowing.css.ts | 31 + src/app/organisms/room/RoomViewFollowing.tsx | 141 ++ src/app/organisms/room/RoomViewTyping.css.ts | 24 + src/app/organisms/room/RoomViewTyping.tsx | 102 + .../organisms/room/message/AudioContent.tsx | 192 ++ .../room/message/EncryptedContent.tsx | 22 + .../organisms/room/message/EventContent.tsx | 37 + .../organisms/room/message/FileContent.tsx | 250 +++ src/app/organisms/room/message/FileHeader.tsx | 22 + .../organisms/room/message/ImageContent.tsx | 170 ++ src/app/organisms/room/message/Message.tsx | 993 ++++++++++ src/app/organisms/room/message/Reactions.tsx | 133 ++ .../organisms/room/message/StickerContent.tsx | 41 + .../organisms/room/message/VideoContent.tsx | 176 ++ .../organisms/room/message/fileRenderer.tsx | 45 + src/app/organisms/room/message/index.ts | 10 + src/app/organisms/room/message/styles.css.ts | 72 + src/app/organisms/room/message/util.ts | 23 + src/app/organisms/room/msgContent.ts | 30 +- .../reaction-viewer/ReactionViewer.css.ts | 31 + .../room/reaction-viewer/ReactionViewer.tsx | 155 ++ .../organisms/room/reaction-viewer/index.ts | 1 + src/app/organisms/settings/Settings.jsx | 84 +- src/app/plugins/emoji.ts | 14 +- src/app/plugins/pdfjs-dist.ts | 47 + src/app/plugins/react-custom-html-parser.tsx | 274 +++ src/app/plugins/react-prism/ReactPrism.css | 97 + src/app/plugins/react-prism/ReactPrism.tsx | 35 + src/app/state/settings.ts | 17 +- src/app/state/typingMembers.ts | 70 + .../CustomHtml.css.ts} | 86 +- src/app/templates/client/Client.jsx | 21 +- src/app/templates/client/ClientContent.jsx | 49 + src/app/utils/blurHash.ts | 8 +- src/app/utils/common.ts | 47 + src/app/utils/dom.ts | 59 +- src/app/utils/matrix.ts | 50 +- src/app/utils/mimeTypes.ts | 65 +- src/app/utils/room.ts | 34 + src/app/utils/sanitize.ts | 142 ++ src/app/utils/time.ts | 35 + src/client/state/settings.js | 3 + src/ext.d.ts | 5 + src/index.scss | 16 +- src/types/matrix/common.ts | 60 +- src/types/matrix/room.ts | 27 + tsconfig.json | 1 + vite.config.js | 4 + 124 files changed, 9438 insertions(+), 258 deletions(-) create mode 100644 src/app/components/Pdf-viewer/PdfViewer.css.ts create mode 100644 src/app/components/Pdf-viewer/PdfViewer.tsx create mode 100644 src/app/components/Pdf-viewer/index.ts create mode 100644 src/app/components/event-readers/EventReaders.css.ts create mode 100644 src/app/components/event-readers/EventReaders.tsx create mode 100644 src/app/components/event-readers/index.ts create mode 100644 src/app/components/image-viewer/ImageViewer.css.ts create mode 100644 src/app/components/image-viewer/ImageViewer.tsx create mode 100644 src/app/components/image-viewer/index.ts create mode 100644 src/app/components/media/Image.tsx create mode 100644 src/app/components/media/MediaControls.tsx create mode 100644 src/app/components/media/Video.tsx create mode 100644 src/app/components/media/index.ts create mode 100644 src/app/components/media/media.css.ts create mode 100644 src/app/components/message/MessageContentFallback.tsx create mode 100644 src/app/components/message/Reaction.css.ts create mode 100644 src/app/components/message/Reaction.tsx create mode 100644 src/app/components/message/Reply.css.ts create mode 100644 src/app/components/message/Reply.tsx create mode 100644 src/app/components/message/Time.tsx create mode 100644 src/app/components/message/attachment/Attachment.css.ts create mode 100644 src/app/components/message/attachment/Attachment.tsx create mode 100644 src/app/components/message/attachment/index.ts create mode 100644 src/app/components/message/index.ts create mode 100644 src/app/components/message/layout/Base.tsx create mode 100644 src/app/components/message/layout/Bubble.tsx create mode 100644 src/app/components/message/layout/Compact.tsx create mode 100644 src/app/components/message/layout/Modern.tsx create mode 100644 src/app/components/message/layout/index.ts create mode 100644 src/app/components/message/layout/layout.css.ts create mode 100644 src/app/components/message/placeholder/CompactPlaceholder.tsx create mode 100644 src/app/components/message/placeholder/DefaultPlaceholder.tsx create mode 100644 src/app/components/message/placeholder/LinePlaceholder.css.ts create mode 100644 src/app/components/message/placeholder/LinePlaceholder.tsx create mode 100644 src/app/components/message/placeholder/index.ts create mode 100644 src/app/components/room-intro/RoomIntro.tsx create mode 100644 src/app/components/room-intro/index.ts create mode 100644 src/app/components/text-viewer/TextViewer.css.ts create mode 100644 src/app/components/text-viewer/TextViewer.tsx create mode 100644 src/app/components/text-viewer/index.ts create mode 100644 src/app/components/typing-indicator/TypingIndicator.css.ts create mode 100644 src/app/components/typing-indicator/TypingIndicator.tsx create mode 100644 src/app/components/typing-indicator/index.ts create mode 100644 src/app/hooks/media/index.ts create mode 100644 src/app/hooks/media/useMediaLoading.ts create mode 100644 src/app/hooks/media/useMediaPlay.ts create mode 100644 src/app/hooks/media/useMediaPlayTimeCallback.ts create mode 100644 src/app/hooks/media/useMediaPlaybackRate.ts create mode 100644 src/app/hooks/media/useMediaSeek.ts create mode 100644 src/app/hooks/media/useMediaVolume.ts create mode 100644 src/app/hooks/useMatrixEventRenderer.ts create mode 100644 src/app/hooks/useMemberEventParser.tsx create mode 100644 src/app/hooks/usePan.ts create mode 100644 src/app/hooks/useRelations.ts create mode 100644 src/app/hooks/useRoomEventReaders.ts create mode 100644 src/app/hooks/useRoomLatestEvent.ts create mode 100644 src/app/hooks/useRoomMsgContentRenderer.ts create mode 100644 src/app/hooks/useVirtualPaginator.ts create mode 100644 src/app/hooks/useZoom.ts delete mode 100644 src/app/organisms/room/Room.jsx create mode 100644 src/app/organisms/room/Room.tsx create mode 100644 src/app/organisms/room/RoomTimeline.css.ts create mode 100644 src/app/organisms/room/RoomTimeline.tsx create mode 100644 src/app/organisms/room/RoomViewFollowing.css.ts create mode 100644 src/app/organisms/room/RoomViewFollowing.tsx create mode 100644 src/app/organisms/room/RoomViewTyping.css.ts create mode 100644 src/app/organisms/room/RoomViewTyping.tsx create mode 100644 src/app/organisms/room/message/AudioContent.tsx create mode 100644 src/app/organisms/room/message/EncryptedContent.tsx create mode 100644 src/app/organisms/room/message/EventContent.tsx create mode 100644 src/app/organisms/room/message/FileContent.tsx create mode 100644 src/app/organisms/room/message/FileHeader.tsx create mode 100644 src/app/organisms/room/message/ImageContent.tsx create mode 100644 src/app/organisms/room/message/Message.tsx create mode 100644 src/app/organisms/room/message/Reactions.tsx create mode 100644 src/app/organisms/room/message/StickerContent.tsx create mode 100644 src/app/organisms/room/message/VideoContent.tsx create mode 100644 src/app/organisms/room/message/fileRenderer.tsx create mode 100644 src/app/organisms/room/message/index.ts create mode 100644 src/app/organisms/room/message/styles.css.ts create mode 100644 src/app/organisms/room/message/util.ts create mode 100644 src/app/organisms/room/reaction-viewer/ReactionViewer.css.ts create mode 100644 src/app/organisms/room/reaction-viewer/ReactionViewer.tsx create mode 100644 src/app/organisms/room/reaction-viewer/index.ts create mode 100644 src/app/plugins/pdfjs-dist.ts create mode 100644 src/app/plugins/react-custom-html-parser.tsx create mode 100644 src/app/plugins/react-prism/ReactPrism.css create mode 100644 src/app/plugins/react-prism/ReactPrism.tsx create mode 100644 src/app/state/typingMembers.ts rename src/app/{components/editor/Elements.css.ts => styles/CustomHtml.css.ts} (59%) create mode 100644 src/app/templates/client/ClientContent.jsx create mode 100644 src/app/utils/time.ts diff --git a/.eslintrc.js b/.eslintrc.js index 704374182..36101fbe5 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -20,6 +20,9 @@ module.exports = { ecmaVersion: 'latest', sourceType: 'module', }, + "globals": { + JSX: "readonly" + }, plugins: [ 'react', '@typescript-eslint' diff --git a/package-lock.json b/package-lock.json index d5867ae16..6f00efe82 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,22 +23,26 @@ "browser-encrypt-attachment": "0.3.0", "classnames": "2.3.2", "dateformat": "5.0.3", + "dayjs": "1.11.10", "emojibase": "6.1.0", "emojibase-data": "7.0.1", "file-saver": "2.0.5", "flux": "4.0.3", "focus-trap-react": "10.0.2", - "folds": "1.3.0", + "folds": "1.5.0", "formik": "2.2.9", - "html-react-parser": "3.0.4", + "html-react-parser": "4.2.0", "immer": "9.0.16", "is-hotkey": "0.2.0", "jotai": "1.12.0", "katex": "0.16.4", "linkify-html": "4.0.2", + "linkify-react": "4.1.1", "linkifyjs": "4.0.2", "matrix-js-sdk": "24.1.0", "millify": "6.1.0", + "pdfjs-dist": "3.10.111", + "prismjs": "1.29.0", "prop-types": "15.8.1", "react": "17.0.2", "react-autosize-textarea": "7.1.0", @@ -46,8 +50,10 @@ "react-dnd": "15.1.2", "react-dnd-html5-backend": "15.1.3", "react-dom": "17.0.2", + "react-error-boundary": "4.0.10", "react-google-recaptcha": "2.1.0", "react-modal": "3.16.1", + "react-range": "1.8.14", "sanitize-html": "2.8.0", "slate": "0.90.0", "slate-history": "0.93.0", @@ -60,9 +66,12 @@ "@esbuild-plugins/node-globals-polyfill": "0.2.3", "@rollup/plugin-inject": "5.0.3", "@rollup/plugin-wasm": "6.1.1", + "@types/file-saver": "2.0.5", "@types/node": "18.11.18", + "@types/prismjs": "1.26.0", "@types/react": "18.0.26", "@types/react-dom": "18.0.9", + "@types/sanitize-html": "2.9.0", "@types/ua-parser-js": "0.7.36", "@typescript-eslint/eslint-plugin": "5.46.1", "@typescript-eslint/parser": "5.46.1", @@ -963,6 +972,41 @@ "react-dom": "16.14.0" } }, + "node_modules/@mapbox/node-pre-gyp": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz", + "integrity": "sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==", + "optional": true, + "dependencies": { + "detect-libc": "^2.0.0", + "https-proxy-agent": "^5.0.0", + "make-dir": "^3.1.0", + "node-fetch": "^2.6.7", + "nopt": "^5.0.0", + "npmlog": "^5.0.1", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.11" + }, + "bin": { + "node-pre-gyp": "bin/node-pre-gyp" + } + }, + "node_modules/@mapbox/node-pre-gyp/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "optional": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/@matrix-org/matrix-sdk-crypto-js": { "version": "0.1.0-alpha.5", "resolved": "https://registry.npmjs.org/@matrix-org/matrix-sdk-crypto-js/-/matrix-sdk-crypto-js-0.1.0-alpha.5.tgz", @@ -1155,6 +1199,12 @@ "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==" }, + "node_modules/@types/file-saver": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@types/file-saver/-/file-saver-2.0.5.tgz", + "integrity": "sha512-zv9kNf3keYegP5oThGLaPk8E081DFDuwfqjtiTzm6PoxChdJ1raSuADf2YGCVIyrSynLrgc8JWv296s7Q7pQSQ==", + "dev": true + }, "node_modules/@types/is-hotkey": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/@types/is-hotkey/-/is-hotkey-0.1.7.tgz", @@ -1183,6 +1233,12 @@ "integrity": "sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA==", "dev": true }, + "node_modules/@types/prismjs": { + "version": "1.26.0", + "resolved": "https://registry.npmjs.org/@types/prismjs/-/prismjs-1.26.0.tgz", + "integrity": "sha512-ZTaqn/qSqUuAq1YwvOFQfVW1AR/oQJlLSZVustdjwI+GZ8kr0MSHBj0tsXPW1EqHubx50gtBEjbPGsdZwQwCjQ==", + "dev": true + }, "node_modules/@types/prop-types": { "version": "15.7.5", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", @@ -1212,6 +1268,15 @@ "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==" }, + "node_modules/@types/sanitize-html": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/@types/sanitize-html/-/sanitize-html-2.9.0.tgz", + "integrity": "sha512-4fP/kEcKNj2u39IzrxWYuf/FnCCwwQCpif6wwY6ROUS1EPRIfWJjGkY3HIowY1EX/VbX5e86yq8AAE7UPMgATg==", + "dev": true, + "dependencies": { + "htmlparser2": "^8.0.0" + } + }, "node_modules/@types/scheduler": { "version": "0.16.2", "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", @@ -1644,6 +1709,12 @@ "vite": "^4.0.0" } }, + "node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "optional": true + }, "node_modules/acorn": { "version": "8.8.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", @@ -1665,6 +1736,18 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "optional": true, + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, "node_modules/ahocorasick": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/ahocorasick/-/ahocorasick-1.0.2.tgz", @@ -1723,6 +1806,25 @@ "node": ">= 8" } }, + "node_modules/aproba": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", + "optional": true + }, + "node_modules/are-we-there-yet": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", + "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", + "optional": true, + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -1862,7 +1964,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true + "devOptional": true }, "node_modules/base-x": { "version": "4.0.0", @@ -1907,7 +2009,7 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, + "devOptional": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -2026,6 +2128,21 @@ } ] }, + "node_modules/canvas": { + "version": "2.11.2", + "resolved": "https://registry.npmjs.org/canvas/-/canvas-2.11.2.tgz", + "integrity": "sha512-ItanGBMrmRV7Py2Z+Xhs7cT+FNt5K0vPL4p9EZ/UX/Mu7hFbkxSjKF2KVtPwX7UYWp7dRKnrTvReflgrItJbdw==", + "hasInstallScript": true, + "optional": true, + "dependencies": { + "@mapbox/node-pre-gyp": "^1.0.0", + "nan": "^2.17.0", + "simple-get": "^3.0.3" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -2078,6 +2195,15 @@ "node": ">= 6" } }, + "node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "optional": true, + "engines": { + "node": ">=10" + } + }, "node_modules/classnames": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz", @@ -2109,6 +2235,15 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" }, + "node_modules/color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "optional": true, + "bin": { + "color-support": "bin.js" + } + }, "node_modules/compute-scroll-into-view": { "version": "1.0.20", "resolved": "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-1.0.20.tgz", @@ -2123,7 +2258,7 @@ "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true + "devOptional": true }, "node_modules/confusing-browser-globals": { "version": "1.0.11", @@ -2131,6 +2266,12 @@ "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==", "dev": true }, + "node_modules/console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", + "optional": true + }, "node_modules/content-type": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", @@ -2218,6 +2359,11 @@ "node": ">=12.20" } }, + "node_modules/dayjs": { + "version": "1.11.10", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.10.tgz", + "integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==" + }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -2234,6 +2380,18 @@ } } }, + "node_modules/decompress-response": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz", + "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==", + "optional": true, + "dependencies": { + "mimic-response": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -2269,6 +2427,21 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", + "optional": true + }, + "node_modules/detect-libc": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz", + "integrity": "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==", + "optional": true, + "engines": { + "node": ">=8" + } + }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -2354,13 +2527,13 @@ } }, "node_modules/domutils": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz", - "integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", + "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", "dependencies": { "dom-serializer": "^2.0.0", "domelementtype": "^2.3.0", - "domhandler": "^5.0.1" + "domhandler": "^5.0.3" }, "funding": { "url": "https://github.com/fb55/domutils?sponsor=1" @@ -2399,9 +2572,9 @@ } }, "node_modules/entities": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz", - "integrity": "sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", "engines": { "node": ">=0.12" }, @@ -3215,21 +3388,6 @@ "node": "^10.12.0 || >=12.0.0" } }, - "node_modules/flat-cache/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/flatted": { "version": "3.2.7", "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", @@ -3271,9 +3429,9 @@ } }, "node_modules/folds": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/folds/-/folds-1.3.0.tgz", - "integrity": "sha512-Jcv6xN9woJWaTaATDGCD9xFqUhjuSw+afvChYoUt4UsAyY351hfpkGNYzglN+gA5fvJw6N9oa6Ogjj2p84kFfA==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/folds/-/folds-1.5.0.tgz", + "integrity": "sha512-1QNHzD57OxFZT5SOe0nWcrKQvWmfMRv1f5sTF8xhGtwx9rajjv36T9SwCcj9Fh58PbERqOdBiwvpdhu+BQTVjg==", "peerDependencies": { "@vanilla-extract/css": "^1.9.2", "@vanilla-extract/recipes": "^0.3.0", @@ -3326,11 +3484,35 @@ "graceful-fs": "^4.1.6" } }, + "node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "optional": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/fs-minipass/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "optional": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true + "devOptional": true }, "node_modules/fsevents": { "version": "2.3.2", @@ -3379,6 +3561,26 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/gauge": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz", + "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", + "optional": true, + "dependencies": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.2", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.1", + "object-assign": "^4.1.1", + "signal-exit": "^3.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.2" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -3429,7 +3631,7 @@ "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, + "devOptional": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -3576,6 +3778,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", + "optional": true + }, "node_modules/hoist-non-react-statics": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", @@ -3585,23 +3793,41 @@ } }, "node_modules/html-dom-parser": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/html-dom-parser/-/html-dom-parser-3.1.2.tgz", - "integrity": "sha512-mLTtl3pVn3HnqZSZzW3xVs/mJAKrG1yIw3wlp+9bdoZHHLaBRvELdpfShiPVLyjPypq1Fugv2KMDoGHW4lVXnw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/html-dom-parser/-/html-dom-parser-4.0.0.tgz", + "integrity": "sha512-TUa3wIwi80f5NF8CVWzkopBVqVAtlawUzJoLwVLHns0XSJGynss4jiY0mTWpiDOsuyw+afP+ujjMgRh9CoZcXw==", "dependencies": { "domhandler": "5.0.3", - "htmlparser2": "8.0.1" + "htmlparser2": "9.0.0" + } + }, + "node_modules/html-dom-parser/node_modules/htmlparser2": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.0.0.tgz", + "integrity": "sha512-uxbSI98wmFT/G4P2zXx4OVx04qWUmyFPrD2/CNepa2Zo3GPNaCaaxElDgwUrwYWkK1nr9fft0Ya8dws8coDLLQ==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.1.0", + "entities": "^4.5.0" } }, "node_modules/html-react-parser": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/html-react-parser/-/html-react-parser-3.0.4.tgz", - "integrity": "sha512-va68PSmC7uA6PbOEc9yuw5Mu3OHPXmFKUpkLGvUPdTuNrZ0CJZk1s/8X/FaHjswK/6uZghu2U02tJjussT8+uw==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/html-react-parser/-/html-react-parser-4.2.0.tgz", + "integrity": "sha512-gzU55AS+FI6qD7XaKe5BLuLFM2Xw0/LodfMWZlxV9uOHe7LCD5Lukx/EgYuBI3c0kLu0XlgFXnSzO0qUUn3Vrg==", "dependencies": { "domhandler": "5.0.3", - "html-dom-parser": "3.1.2", + "html-dom-parser": "4.0.0", "react-property": "2.0.0", - "style-to-js": "1.1.1" + "style-to-js": "1.1.3" }, "peerDependencies": { "react": "0.14 || 15 || 16 || 17 || 18" @@ -3625,6 +3851,19 @@ "entities": "^4.3.0" } }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "optional": true, + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", @@ -3698,7 +3937,7 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, + "devOptional": true, "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -3708,7 +3947,7 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true + "devOptional": true }, "node_modules/inline-style-parser": { "version": "0.1.1", @@ -4192,6 +4431,15 @@ "linkifyjs": "^4.0.0" } }, + "node_modules/linkify-react": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/linkify-react/-/linkify-react-4.1.1.tgz", + "integrity": "sha512-2K9Y1cUdvq40dFWqCJ//X+WP19nlzIVITFGI93RjLnA0M7KbnxQ/ffC3AZIZaEIrLangF9Hjt3i0GQ9/anEG5A==", + "peerDependencies": { + "linkifyjs": "^4.0.0", + "react": ">= 15.0.0" + } + }, "node_modules/linkifyjs": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/linkifyjs/-/linkifyjs-4.0.2.tgz", @@ -4254,7 +4502,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, + "devOptional": true, "dependencies": { "yallist": "^4.0.0" }, @@ -4274,6 +4522,21 @@ "node": ">=12" } }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "optional": true, + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/matrix-events-sdk": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/matrix-events-sdk/-/matrix-events-sdk-0.0.1.tgz", @@ -4351,6 +4614,18 @@ "millify": "bin/millify" } }, + "node_modules/mimic-response": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", + "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==", + "optional": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/mini-svg-data-uri": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/mini-svg-data-uri/-/mini-svg-data-uri-1.4.4.tgz", @@ -4364,7 +4639,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, + "devOptional": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -4381,11 +4656,63 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "optional": true, + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minizlib/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "optional": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "optional": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, + "node_modules/nan": { + "version": "2.17.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.17.0.tgz", + "integrity": "sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==", + "optional": true + }, "node_modules/nanoid": { "version": "3.3.6", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", @@ -4439,6 +4766,21 @@ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.8.tgz", "integrity": "sha512-dFSmB8fFHEH/s81Xi+Y/15DQY6VHW81nXRj86EMSL3lmuTmK1e+aT4wrFCkTbm+gSwkw4KpX+rT/pMM2c1mF+A==" }, + "node_modules/nopt": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", + "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "optional": true, + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -4448,6 +4790,18 @@ "node": ">=0.10.0" } }, + "node_modules/npmlog": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", + "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", + "optional": true, + "dependencies": { + "are-we-there-yet": "^2.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^3.0.0", + "set-blocking": "^2.0.0" + } + }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -4557,7 +4911,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, + "devOptional": true, "dependencies": { "wrappy": "1" } @@ -4653,7 +5007,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, + "devOptional": true, "engines": { "node": ">=0.10.0" } @@ -4682,6 +5036,27 @@ "node": ">=8" } }, + "node_modules/path2d-polyfill": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path2d-polyfill/-/path2d-polyfill-2.0.1.tgz", + "integrity": "sha512-ad/3bsalbbWhmBo0D6FZ4RNMwsLsPpL6gnvhuSaU5Vm7b06Kr5ubSltQQ0T7YKsiJQO+g22zJ4dJKNTXIyOXtA==", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/pdfjs-dist": { + "version": "3.10.111", + "resolved": "https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-3.10.111.tgz", + "integrity": "sha512-+SXXGN/3YTNQSK5Ae7EyqQuR+4IAsNunJq/Us5ByOkRJ45qBXXOwkiWi3RIDU+CyF+ak5eSWXl2FQW2PKBrsRA==", + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "canvas": "^2.11.2", + "path2d-polyfill": "^2.0.1" + } + }, "node_modules/picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", @@ -4778,6 +5153,14 @@ "url": "https://github.com/prettier/prettier?sponsor=1" } }, + "node_modules/prismjs": { + "version": "1.29.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz", + "integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==", + "engines": { + "node": ">=6" + } + }, "node_modules/promise": { "version": "7.3.1", "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", @@ -4922,6 +5305,17 @@ "react": "17.0.2" } }, + "node_modules/react-error-boundary": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-4.0.10.tgz", + "integrity": "sha512-pvVKdi77j2OoPHo+p3rorgE43OjDWiqFkaqkJz8sJKK6uf/u8xtzuaVfj5qJ2JnDLIgF1De3zY5AJDijp+LVPA==", + "dependencies": { + "@babel/runtime": "^7.12.5" + }, + "peerDependencies": { + "react": ">=16.13.1" + } + }, "node_modules/react-fast-compare": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-2.0.4.tgz", @@ -4972,6 +5366,15 @@ "resolved": "https://registry.npmjs.org/react-property/-/react-property-2.0.0.tgz", "integrity": "sha512-kzmNjIgU32mO4mmH5+iUyrqlpFQhF8K2k7eZ4fdLSOPFrD1XgEuSBv9LDEgxRXTMBqMd8ppT0x6TIzqE5pdGdw==" }, + "node_modules/react-range": { + "version": "1.8.14", + "resolved": "https://registry.npmjs.org/react-range/-/react-range-1.8.14.tgz", + "integrity": "sha512-v2nyD5106rHf9dwHzq+WRlhCes83h1wJRHIMFjbZsYYsO6LF4mG/mR3cH7Cf+dkeHq65DItuqIbLn/3jjYjsHg==", + "peerDependencies": { + "react": "^16.8.0-0 || ^17.0.0-0 || ^18.0.0-0", + "react-dom": "^16.8.0-0 || ^17.0.0-0 || ^18.0.0-0" + } + }, "node_modules/react-refresh": { "version": "0.14.0", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.0.tgz", @@ -4981,6 +5384,20 @@ "node": ">=0.10.0" } }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "optional": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -5090,6 +5507,21 @@ "node": ">=0.10.0" } }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "devOptional": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/rollup": { "version": "3.25.1", "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.25.1.tgz", @@ -5129,6 +5561,26 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "optional": true + }, "node_modules/safe-regex-test": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", @@ -5225,6 +5677,12 @@ "semver": "bin/semver.js" } }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "optional": true + }, "node_modules/setimmediate": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", @@ -5265,6 +5723,43 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "optional": true + }, + "node_modules/simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "optional": true + }, + "node_modules/simple-get": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.1.tgz", + "integrity": "sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA==", + "optional": true, + "dependencies": { + "decompress-response": "^4.2.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -5329,6 +5824,15 @@ "node": ">=0.10.0" } }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "optional": true, + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, "node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -5427,17 +5931,17 @@ } }, "node_modules/style-to-js": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/style-to-js/-/style-to-js-1.1.1.tgz", - "integrity": "sha512-RJ18Z9t2B02sYhZtfWKQq5uplVctgvjTfLWT7+Eb1zjUjIrWzX5SdlkwLGQozrqarTmEzJJ/YmdNJCUNI47elg==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/style-to-js/-/style-to-js-1.1.3.tgz", + "integrity": "sha512-zKI5gN/zb7LS/Vm0eUwjmjrXWw8IMtyA8aPBJZdYiQTXj4+wQ3IucOLIOnF7zCHxvW8UhIGh/uZh/t9zEHXNTQ==", "dependencies": { - "style-to-object": "0.3.0" + "style-to-object": "0.4.1" } }, "node_modules/style-to-object": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.3.0.tgz", - "integrity": "sha512-CzFnRRXhzWIdItT3OmF8SQfWyahHhjq3HwcMNCNLn+N7klOOqPjMeG/4JSu77D7ypZdGvSzvkrbyeTMizz2VrA==", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.4.1.tgz", + "integrity": "sha512-HFpbb5gr2ypci7Qw+IOhnP2zOU7e77b+rzM+wTzXzfi1PrtBCX0E7Pk4wL4iTLnhzZ+JgEGAhX81ebTg/aYjQw==", "dependencies": { "inline-style-parser": "0.1.1" } @@ -5470,6 +5974,23 @@ "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.0.1.tgz", "integrity": "sha512-SYJSIgeyXW7EuX1ytdneO5e8jip42oHWg9xl/o3oTYhmXusZVgiA+VlPvjIN+kHii9v90AmzTZEBcsEvuAY+TA==" }, + "node_modules/tar": { + "version": "6.1.15", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.15.tgz", + "integrity": "sha512-/zKt9UyngnxIT/EAGYuxaMYgOIJiP81ab9ZfkILq4oNLPFX50qyYmu7jRj9qeXoxmJHjGlbH0+cm2uy1WCs10A==", + "optional": true, + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -5696,6 +6217,12 @@ "punycode": "^2.1.0" } }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "optional": true + }, "node_modules/uuid": { "version": "9.0.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", @@ -6247,6 +6774,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/wide-align": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "optional": true, + "dependencies": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, "node_modules/word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", @@ -6306,7 +6842,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true + "devOptional": true }, "node_modules/y18n": { "version": "5.0.8", @@ -6320,7 +6856,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "devOptional": true }, "node_modules/yaml": { "version": "1.10.2", diff --git a/package.json b/package.json index 5eb3fa988..83850a80e 100644 --- a/package.json +++ b/package.json @@ -33,22 +33,26 @@ "browser-encrypt-attachment": "0.3.0", "classnames": "2.3.2", "dateformat": "5.0.3", + "dayjs": "1.11.10", "emojibase": "6.1.0", "emojibase-data": "7.0.1", "file-saver": "2.0.5", "flux": "4.0.3", "focus-trap-react": "10.0.2", - "folds": "1.3.0", + "folds": "1.5.0", "formik": "2.2.9", - "html-react-parser": "3.0.4", + "html-react-parser": "4.2.0", "immer": "9.0.16", "is-hotkey": "0.2.0", "jotai": "1.12.0", "katex": "0.16.4", "linkify-html": "4.0.2", + "linkify-react": "4.1.1", "linkifyjs": "4.0.2", "matrix-js-sdk": "24.1.0", "millify": "6.1.0", + "pdfjs-dist": "3.10.111", + "prismjs": "1.29.0", "prop-types": "15.8.1", "react": "17.0.2", "react-autosize-textarea": "7.1.0", @@ -56,8 +60,10 @@ "react-dnd": "15.1.2", "react-dnd-html5-backend": "15.1.3", "react-dom": "17.0.2", + "react-error-boundary": "4.0.10", "react-google-recaptcha": "2.1.0", "react-modal": "3.16.1", + "react-range": "1.8.14", "sanitize-html": "2.8.0", "slate": "0.90.0", "slate-history": "0.93.0", @@ -70,9 +76,12 @@ "@esbuild-plugins/node-globals-polyfill": "0.2.3", "@rollup/plugin-inject": "5.0.3", "@rollup/plugin-wasm": "6.1.1", + "@types/file-saver": "2.0.5", "@types/node": "18.11.18", + "@types/prismjs": "1.26.0", "@types/react": "18.0.26", "@types/react-dom": "18.0.9", + "@types/sanitize-html": "2.9.0", "@types/ua-parser-js": "0.7.36", "@typescript-eslint/eslint-plugin": "5.46.1", "@typescript-eslint/parser": "5.46.1", diff --git a/src/app/components/Pdf-viewer/PdfViewer.css.ts b/src/app/components/Pdf-viewer/PdfViewer.css.ts new file mode 100644 index 000000000..465510983 --- /dev/null +++ b/src/app/components/Pdf-viewer/PdfViewer.css.ts @@ -0,0 +1,37 @@ +import { style } from '@vanilla-extract/css'; +import { DefaultReset, color, config } from 'folds'; + +export const PdfViewer = style([ + DefaultReset, + { + height: '100%', + }, +]); + +export const PdfViewerHeader = style([ + DefaultReset, + { + paddingLeft: config.space.S200, + paddingRight: config.space.S200, + borderBottomWidth: config.borderWidth.B300, + flexShrink: 0, + gap: config.space.S200, + }, +]); +export const PdfViewerFooter = style([ + PdfViewerHeader, + { + borderTopWidth: config.borderWidth.B300, + borderBottomWidth: 0, + }, +]); + +export const PdfViewerContent = style([ + DefaultReset, + { + margin: 'auto', + display: 'inline-block', + backgroundColor: color.Surface.Container, + color: color.Surface.OnContainer, + }, +]); diff --git a/src/app/components/Pdf-viewer/PdfViewer.tsx b/src/app/components/Pdf-viewer/PdfViewer.tsx new file mode 100644 index 000000000..c440cce9b --- /dev/null +++ b/src/app/components/Pdf-viewer/PdfViewer.tsx @@ -0,0 +1,257 @@ +/* eslint-disable no-param-reassign */ +/* eslint-disable jsx-a11y/no-noninteractive-element-interactions */ +import React, { FormEventHandler, useEffect, useRef, useState } from 'react'; +import classNames from 'classnames'; +import { + Box, + Button, + Chip, + Header, + Icon, + IconButton, + Icons, + Input, + Menu, + PopOut, + Scroll, + Spinner, + Text, + as, + config, +} from 'folds'; +import FocusTrap from 'focus-trap-react'; +import FileSaver from 'file-saver'; +import * as css from './PdfViewer.css'; +import { AsyncStatus } from '../../hooks/useAsyncCallback'; +import { useZoom } from '../../hooks/useZoom'; +import { createPage, usePdfDocumentLoader, usePdfJSLoader } from '../../plugins/pdfjs-dist'; + +export type PdfViewerProps = { + name: string; + src: string; + requestClose: () => void; +}; + +export const PdfViewer = as<'div', PdfViewerProps>( + ({ className, name, src, requestClose, ...props }, ref) => { + const containerRef = useRef(null); + const scrollRef = useRef(null); + const { zoom, zoomIn, zoomOut, setZoom } = useZoom(0.2); + + const [pdfJSState, loadPdfJS] = usePdfJSLoader(); + const [docState, loadPdfDocument] = usePdfDocumentLoader( + pdfJSState.status === AsyncStatus.Success ? pdfJSState.data : undefined, + src + ); + const isLoading = + pdfJSState.status === AsyncStatus.Loading || docState.status === AsyncStatus.Loading; + const isError = + pdfJSState.status === AsyncStatus.Error || docState.status === AsyncStatus.Error; + const [pageNo, setPageNo] = useState(1); + const [openJump, setOpenJump] = useState(false); + + useEffect(() => { + loadPdfJS(); + }, [loadPdfJS]); + useEffect(() => { + if (pdfJSState.status === AsyncStatus.Success) { + loadPdfDocument(); + } + }, [pdfJSState, loadPdfDocument]); + + useEffect(() => { + if (docState.status === AsyncStatus.Success) { + const doc = docState.data; + if (pageNo < 0 || pageNo > doc.numPages) return; + createPage(doc, pageNo, { scale: zoom }).then((canvas) => { + const container = containerRef.current; + if (!container) return; + container.textContent = ''; + container.append(canvas); + scrollRef.current?.scrollTo({ + top: 0, + }); + }); + } + }, [docState, pageNo, zoom]); + + const handleDownload = () => { + FileSaver.saveAs(src, name); + }; + + const handleJumpSubmit: FormEventHandler = (evt) => { + evt.preventDefault(); + if (docState.status !== AsyncStatus.Success) return; + const jumpInput = evt.currentTarget.jumpInput as HTMLInputElement; + if (!jumpInput) return; + const jumpTo = parseInt(jumpInput.value, 10); + setPageNo(Math.max(1, Math.min(docState.data.numPages, jumpTo))); + setOpenJump(false); + }; + + const handlePrevPage = () => { + setPageNo((n) => Math.max(n - 1, 1)); + }; + + const handleNextPage = () => { + if (docState.status !== AsyncStatus.Success) return; + setPageNo((n) => Math.min(n + 1, docState.data.numPages)); + }; + + return ( + +
      + + + + + + {name} + + + + + + + setZoom(zoom === 1 ? 2 : 1)}> + {Math.round(zoom * 100)}% + + 1 ? 'Success' : 'SurfaceVariant'} + outlined={zoom > 1} + size="300" + radii="Pill" + onClick={zoomIn} + aria-label="Zoom In" + > + + + } + > + Download + + +
      + + {isLoading && } + {isError && ( + <> + Failed to load PDF + + + )} + {docState.status === AsyncStatus.Success && ( + + +

      0RIE}q+~cmG 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

      + + + )} + + {docState.status === AsyncStatus.Success && ( +
      + } + onClick={handlePrevPage} + aria-disabled={pageNo <= 1} + > + Previous + + + setOpenJump(false), + clickOutsideDeactivates: true, + }} + > + + + + + + + + } + > + {(anchorRef) => ( + setOpenJump(!openJump)} + ref={anchorRef} + variant="SurfaceVariant" + radii="300" + aria-pressed={openJump} + > + {`${pageNo}/${docState.data.numPages}`} + + )} + + + } + onClick={handleNextPage} + aria-disabled={pageNo >= docState.data.numPages} + > + Next + +
      + )} + + ); + } +); diff --git a/src/app/components/Pdf-viewer/index.ts b/src/app/components/Pdf-viewer/index.ts new file mode 100644 index 000000000..5fc0566f6 --- /dev/null +++ b/src/app/components/Pdf-viewer/index.ts @@ -0,0 +1 @@ +export * from './PdfViewer'; diff --git a/src/app/components/editor/Editor.tsx b/src/app/components/editor/Editor.tsx index f4241e0e3..e5377f2fc 100644 --- a/src/app/components/editor/Editor.tsx +++ b/src/app/components/editor/Editor.tsx @@ -54,7 +54,7 @@ export const useEditor = (): Editor => { return editor; }; -export type EditorChangeHandler = ((value: Descendant[]) => void) | undefined; +export type EditorChangeHandler = (value: Descendant[]) => void; type CustomEditorProps = { top?: ReactNode; bottom?: ReactNode; @@ -64,6 +64,7 @@ type CustomEditorProps = { editor: Editor; placeholder?: string; onKeyDown?: KeyboardEventHandler; + onKeyUp?: KeyboardEventHandler; onChange?: EditorChangeHandler; onPaste?: ClipboardEventHandler; }; @@ -78,6 +79,7 @@ export const CustomEditor = forwardRef( editor, placeholder, onKeyDown, + onKeyUp, onChange, onPaste, }, @@ -141,6 +143,7 @@ export const CustomEditor = forwardRef( renderElement={renderElement} renderLeaf={renderLeaf} onKeyDown={handleKeydown} + onKeyUp={onKeyUp} onPaste={onPaste} /> diff --git a/src/app/components/editor/Elements.tsx b/src/app/components/editor/Elements.tsx index 59893e539..2df809936 100644 --- a/src/app/components/editor/Elements.tsx +++ b/src/app/components/editor/Elements.tsx @@ -2,7 +2,7 @@ import { Scroll, Text } from 'folds'; import React from 'react'; import { RenderElementProps, RenderLeafProps, useFocused, useSelected } from 'slate-react'; -import * as css from './Elements.css'; +import * as css from '../../styles/CustomHtml.css'; import { EmoticonElement, LinkElement, MentionElement } from './slate'; import { useMatrixClient } from '../../hooks/useMatrixClient'; @@ -145,7 +145,13 @@ export function RenderElement({ attributes, element, children }: RenderElementPr case BlockType.CodeBlock: return ( - +
      {children}
      @@ -242,7 +248,7 @@ export function RenderLeaf({ attributes, leaf, children }: RenderLeafProps) { ); if (leaf.spoiler) child = ( - + {child} diff --git a/src/app/components/editor/autocomplete/RoomMentionAutocomplete.tsx b/src/app/components/editor/autocomplete/RoomMentionAutocomplete.tsx index 6bea1952b..baa217ca9 100644 --- a/src/app/components/editor/autocomplete/RoomMentionAutocomplete.tsx +++ b/src/app/components/editor/autocomplete/RoomMentionAutocomplete.tsx @@ -122,8 +122,9 @@ export function RoomMentionAutocomplete({ return; } const rId = autoCompleteRoomIds[0]; - const name = mx.getRoom(rId)?.name ?? rId; - handleAutocomplete(rId, name); + const r = mx.getRoom(rId); + const name = r?.name ?? rId; + handleAutocomplete(r?.getCanonicalAlias() ?? rId, name); }); }); @@ -147,7 +148,7 @@ export function RoomMentionAutocomplete({ onKeyDown={(evt: ReactKeyboardEvent) => onTabPress(evt, () => handleAutocomplete(rId, room.name)) } - onClick={() => handleAutocomplete(rId, room.name)} + onClick={() => handleAutocomplete(room.getCanonicalAlias() ?? rId, room.name)} after={ {room.getCanonicalAlias() ?? ''} diff --git a/src/app/components/emoji-board/EmojiBoard.tsx b/src/app/components/emoji-board/EmojiBoard.tsx index 76c6f05dd..a7309834c 100644 --- a/src/app/components/emoji-board/EmojiBoard.tsx +++ b/src/app/components/emoji-board/EmojiBoard.tsx @@ -42,7 +42,7 @@ import { useMatrixClient } from '../../hooks/useMatrixClient'; import { useRecentEmoji } from '../../hooks/useRecentEmoji'; import { ExtendedPackImage, ImagePack, PackUsage } from '../../plugins/custom-emoji'; import { isUserId } from '../../utils/matrix'; -import { editableActiveElement, inVisibleScrollArea, targetFromEvent } from '../../utils/dom'; +import { editableActiveElement, isIntersectingScrollView, targetFromEvent } from '../../utils/dom'; import { useAsyncSearch, UseAsyncSearchOptions } from '../../hooks/useAsyncSearch'; import { useDebounce } from '../../hooks/useDebounce'; import { useThrottle } from '../../hooks/useThrottle'; @@ -675,7 +675,7 @@ export function EmojiBoard({ const targetEl = contentScrollRef.current; if (!targetEl) return; const groupEls = [...targetEl.querySelectorAll('div[data-group-id]')] as HTMLElement[]; - const groupEl = groupEls.find((el) => inVisibleScrollArea(targetEl, el)); + const groupEl = groupEls.find((el) => isIntersectingScrollView(targetEl, el)); const groupId = groupEl?.getAttribute('data-group-id') ?? undefined; setActiveGroupId(groupId); }, [setActiveGroupId]); diff --git a/src/app/components/event-readers/EventReaders.css.ts b/src/app/components/event-readers/EventReaders.css.ts new file mode 100644 index 000000000..36f47b56e --- /dev/null +++ b/src/app/components/event-readers/EventReaders.css.ts @@ -0,0 +1,21 @@ +import { style } from '@vanilla-extract/css'; +import { DefaultReset, config } from 'folds'; + +export const EventReaders = style([ + DefaultReset, + { + height: '100%', + }, +]); + +export const Header = style({ + paddingLeft: config.space.S400, + paddingRight: config.space.S300, + + flexShrink: 0, +}); + +export const Content = style({ + paddingLeft: config.space.S200, + paddingBottom: config.space.S400, +}); diff --git a/src/app/components/event-readers/EventReaders.tsx b/src/app/components/event-readers/EventReaders.tsx new file mode 100644 index 000000000..c05efc50a --- /dev/null +++ b/src/app/components/event-readers/EventReaders.tsx @@ -0,0 +1,110 @@ +import React from 'react'; +import classNames from 'classnames'; +import { + Avatar, + AvatarFallback, + AvatarImage, + Box, + Header, + Icon, + IconButton, + Icons, + MenuItem, + Scroll, + Text, + as, + config, +} from 'folds'; +import { Room, RoomMember } from 'matrix-js-sdk'; +import { useRoomEventReaders } from '../../hooks/useRoomEventReaders'; +import { getMemberDisplayName } from '../../utils/room'; +import { getMxIdLocalPart } from '../../utils/matrix'; +import * as css from './EventReaders.css'; +import { useMatrixClient } from '../../hooks/useMatrixClient'; +import colorMXID from '../../../util/colorMXID'; +import { openProfileViewer } from '../../../client/action/navigation'; + +export type EventReadersProps = { + room: Room; + eventId: string; + requestClose: () => void; +}; +export const EventReaders = as<'div', EventReadersProps>( + ({ className, room, eventId, requestClose, ...props }, ref) => { + const mx = useMatrixClient(); + const latestEventReaders = useRoomEventReaders(room, eventId); + const followingMembers = latestEventReaders + .map((readerId) => room.getMember(readerId)) + .filter((member) => member) as RoomMember[]; + + const getName = (member: RoomMember) => + getMemberDisplayName(room, member.userId) ?? getMxIdLocalPart(member.userId) ?? member.userId; + + return ( + +
      + + Seen by + + + + +
      + + + + {followingMembers.map((member) => { + const name = getName(member); + const avatarUrl = member.getAvatarUrl( + mx.baseUrl, + 100, + 100, + 'crop', + undefined, + false + ); + + return ( + { + requestClose(); + openProfileViewer(member.userId, room.roomId); + }} + before={ + + {avatarUrl ? ( + + ) : ( + + {name[0]} + + )} + + } + > + + {name} + + + ); + })} + + + +
      + ); + } +); diff --git a/src/app/components/event-readers/index.ts b/src/app/components/event-readers/index.ts new file mode 100644 index 000000000..8a37548b5 --- /dev/null +++ b/src/app/components/event-readers/index.ts @@ -0,0 +1 @@ +export * from './EventReaders'; diff --git a/src/app/components/image-viewer/ImageViewer.css.ts b/src/app/components/image-viewer/ImageViewer.css.ts new file mode 100644 index 000000000..fc2f50884 --- /dev/null +++ b/src/app/components/image-viewer/ImageViewer.css.ts @@ -0,0 +1,40 @@ +import { style } from '@vanilla-extract/css'; +import { DefaultReset, color, config } from 'folds'; + +export const ImageViewer = style([ + DefaultReset, + { + height: '100%', + }, +]); + +export const ImageViewerHeader = style([ + DefaultReset, + { + paddingLeft: config.space.S200, + paddingRight: config.space.S200, + borderBottomWidth: config.borderWidth.B300, + flexShrink: 0, + gap: config.space.S200, + }, +]); + +export const ImageViewerContent = style([ + DefaultReset, + { + backgroundColor: color.Background.Container, + color: color.Background.OnContainer, + overflow: 'hidden', + }, +]); + +export const ImageViewerImg = style([ + DefaultReset, + { + objectFit: 'contain', + width: '100%', + height: '100%', + backgroundColor: color.Surface.Container, + transition: 'transform 100ms linear', + }, +]); diff --git a/src/app/components/image-viewer/ImageViewer.tsx b/src/app/components/image-viewer/ImageViewer.tsx new file mode 100644 index 000000000..4fd06b7a7 --- /dev/null +++ b/src/app/components/image-viewer/ImageViewer.tsx @@ -0,0 +1,95 @@ +/* eslint-disable jsx-a11y/no-noninteractive-element-interactions */ +import React from 'react'; +import FileSaver from 'file-saver'; +import classNames from 'classnames'; +import { Box, Chip, Header, Icon, IconButton, Icons, Text, as } from 'folds'; +import * as css from './ImageViewer.css'; +import { useZoom } from '../../hooks/useZoom'; +import { usePan } from '../../hooks/usePan'; + +export type ImageViewerProps = { + alt: string; + src: string; + requestClose: () => void; +}; + +export const ImageViewer = as<'div', ImageViewerProps>( + ({ className, alt, src, requestClose, ...props }, ref) => { + const { zoom, zoomIn, zoomOut, setZoom } = useZoom(0.2); + const { pan, cursor, onMouseDown } = usePan(zoom !== 1); + + const handleDownload = () => { + FileSaver.saveAs(src, alt); + }; + + return ( + +
      + + + + + + {alt} + + + + + + + setZoom(zoom === 1 ? 2 : 1)}> + {Math.round(zoom * 100)}% + + 1 ? 'Success' : 'SurfaceVariant'} + outlined={zoom > 1} + size="300" + radii="Pill" + onClick={zoomIn} + aria-label="Zoom In" + > + + + } + > + Download + + +
      + + {alt} + +
      + ); + } +); diff --git a/src/app/components/image-viewer/index.ts b/src/app/components/image-viewer/index.ts new file mode 100644 index 000000000..69943f2ff --- /dev/null +++ b/src/app/components/image-viewer/index.ts @@ -0,0 +1 @@ +export * from './ImageViewer'; diff --git a/src/app/components/media/Image.tsx b/src/app/components/media/Image.tsx new file mode 100644 index 000000000..dda21a53f --- /dev/null +++ b/src/app/components/media/Image.tsx @@ -0,0 +1,9 @@ +import React, { ImgHTMLAttributes, forwardRef } from 'react'; +import classNames from 'classnames'; +import * as css from './media.css'; + +export const Image = forwardRef>( + ({ className, alt, ...props }, ref) => ( + {alt} + ) +); diff --git a/src/app/components/media/MediaControls.tsx b/src/app/components/media/MediaControls.tsx new file mode 100644 index 000000000..95a344aba --- /dev/null +++ b/src/app/components/media/MediaControls.tsx @@ -0,0 +1,27 @@ +import React, { ReactNode } from 'react'; +import { Box, as } from 'folds'; + +export type MediaControlProps = { + before?: ReactNode; + after?: ReactNode; + leftControl?: ReactNode; + rightControl?: ReactNode; +}; +export const MediaControl = as<'div', MediaControlProps>( + ({ before, after, leftControl, rightControl, children, ...props }, ref) => ( + + {before && {before}} + + + {leftControl} + + + + {rightControl} + + + {after && {after}} + {children} + + ) +); diff --git a/src/app/components/media/Video.tsx b/src/app/components/media/Video.tsx new file mode 100644 index 000000000..ab13c5bdc --- /dev/null +++ b/src/app/components/media/Video.tsx @@ -0,0 +1,10 @@ +import React, { VideoHTMLAttributes, forwardRef } from 'react'; +import classNames from 'classnames'; +import * as css from './media.css'; + +export const Video = forwardRef>( + ({ className, ...props }, ref) => ( + // eslint-disable-next-line jsx-a11y/media-has-caption +
      + ) +); + +export const AvatarBase = as<'span'>(({ className, ...props }, ref) => ( + +)); + +export const Username = as<'span'>(({ as: AsUsername = 'span', className, ...props }, ref) => ( + +)); diff --git a/src/app/components/message/layout/Bubble.tsx b/src/app/components/message/layout/Bubble.tsx new file mode 100644 index 000000000..6f8e70da0 --- /dev/null +++ b/src/app/components/message/layout/Bubble.tsx @@ -0,0 +1,18 @@ +import React, { ReactNode } from 'react'; +import { Box, as } from 'folds'; +import * as css from './layout.css'; + +type BubbleLayoutProps = { + before?: ReactNode; +}; + +export const BubbleLayout = as<'div', BubbleLayoutProps>(({ before, children, ...props }, ref) => ( + + + {before} + + + {children} + + +)); diff --git a/src/app/components/message/layout/Compact.tsx b/src/app/components/message/layout/Compact.tsx new file mode 100644 index 000000000..a033919f7 --- /dev/null +++ b/src/app/components/message/layout/Compact.tsx @@ -0,0 +1,18 @@ +import React, { ReactNode } from 'react'; +import { Box, as } from 'folds'; +import * as css from './layout.css'; + +type CompactLayoutProps = { + before?: ReactNode; +}; + +export const CompactLayout = as<'div', CompactLayoutProps>( + ({ before, children, ...props }, ref) => ( + + + {before} + + {children} + + ) +); diff --git a/src/app/components/message/layout/Modern.tsx b/src/app/components/message/layout/Modern.tsx new file mode 100644 index 000000000..70b25c57b --- /dev/null +++ b/src/app/components/message/layout/Modern.tsx @@ -0,0 +1,18 @@ +import React, { ReactNode } from 'react'; +import { Box, as } from 'folds'; +import * as css from './layout.css'; + +type ModernLayoutProps = { + before?: ReactNode; +}; + +export const ModernLayout = as<'div', ModernLayoutProps>(({ before, children, ...props }, ref) => ( + + + {before} + + + {children} + + +)); diff --git a/src/app/components/message/layout/index.ts b/src/app/components/message/layout/index.ts new file mode 100644 index 000000000..979f5800e --- /dev/null +++ b/src/app/components/message/layout/index.ts @@ -0,0 +1,4 @@ +export * from './Modern'; +export * from './Compact'; +export * from './Bubble'; +export * from './Base'; diff --git a/src/app/components/message/layout/layout.css.ts b/src/app/components/message/layout/layout.css.ts new file mode 100644 index 000000000..ff31baa59 --- /dev/null +++ b/src/app/components/message/layout/layout.css.ts @@ -0,0 +1,155 @@ +import { createVar, keyframes, style, styleVariants } from '@vanilla-extract/css'; +import { recipe, RecipeVariants } from '@vanilla-extract/recipes'; +import { DefaultReset, color, config, toRem } from 'folds'; + +export const StickySection = style({ + position: 'sticky', + top: config.space.S100, +}); + +const SpacingVar = createVar(); +const SpacingVariant = styleVariants({ + '0': { + vars: { + [SpacingVar]: config.space.S0, + }, + }, + '100': { + vars: { + [SpacingVar]: config.space.S100, + }, + }, + '200': { + vars: { + [SpacingVar]: config.space.S200, + }, + }, + '300': { + vars: { + [SpacingVar]: config.space.S300, + }, + }, + '400': { + vars: { + [SpacingVar]: config.space.S400, + }, + }, + '500': { + vars: { + [SpacingVar]: config.space.S500, + }, + }, +}); + +const highlightAnime = keyframes({ + '0%': { + backgroundColor: color.Primary.Container, + }, + '25%': { + backgroundColor: color.Primary.ContainerActive, + }, + '50%': { + backgroundColor: color.Primary.Container, + }, + '75%': { + backgroundColor: color.Primary.ContainerActive, + }, + '100%': { + backgroundColor: color.Primary.Container, + }, +}); +const HighlightVariant = styleVariants({ + true: { + animation: `${highlightAnime} 2000ms ease-in-out`, + }, +}); + +const SelectedVariant = styleVariants({ + true: { + backgroundColor: color.Surface.ContainerActive, + }, +}); + +const AutoCollapse = style({ + selectors: { + [`&+&`]: { + marginTop: 0, + }, + }, +}); + +export const MessageBase = recipe({ + base: [ + DefaultReset, + { + marginTop: SpacingVar, + padding: `${config.space.S100} ${config.space.S200} ${config.space.S100} ${config.space.S400}`, + borderRadius: `0 ${config.radii.R400} ${config.radii.R400} 0`, + }, + ], + variants: { + space: SpacingVariant, + collapse: { + true: { + marginTop: 0, + }, + }, + autoCollapse: { + true: AutoCollapse, + }, + highlight: HighlightVariant, + selected: SelectedVariant, + }, + defaultVariants: { + space: '400', + }, +}); + +export type MessageBaseVariants = RecipeVariants; + +export const CompactHeader = style([ + DefaultReset, + StickySection, + { + maxWidth: toRem(170), + width: '100%', + }, +]); + +export const AvatarBase = style({ + paddingTop: toRem(4), + cursor: 'pointer', + transition: 'transform 200ms cubic-bezier(0, 0.8, 0.67, 0.97)', + + selectors: { + '&:hover': { + transform: `translateY(${toRem(-4)})`, + }, + }, +}); + +export const ModernBefore = style({ + minWidth: toRem(36), +}); + +export const BubbleBefore = style([ModernBefore]); + +export const BubbleContent = style({ + maxWidth: toRem(800), + padding: config.space.S200, + backgroundColor: color.SurfaceVariant.Container, + color: color.SurfaceVariant.OnContainer, + borderRadius: config.radii.R400, +}); + +export const Username = style({ + cursor: 'pointer', + overflow: 'hidden', + whiteSpace: 'nowrap', + textOverflow: 'ellipsis', + selectors: { + '&:hover, &:focus-visible': { + textDecoration: 'underline', + }, + }, +}); diff --git a/src/app/components/message/placeholder/CompactPlaceholder.tsx b/src/app/components/message/placeholder/CompactPlaceholder.tsx new file mode 100644 index 000000000..a6be083ef --- /dev/null +++ b/src/app/components/message/placeholder/CompactPlaceholder.tsx @@ -0,0 +1,22 @@ +import React from 'react'; +import { as, toRem } from 'folds'; +import { randomNumberBetween } from '../../../utils/common'; +import { LinePlaceholder } from './LinePlaceholder'; +import { CompactLayout, MessageBase } from '../layout'; + +export const CompactPlaceholder = as<'div'>(({ ...props }, ref) => ( + + + + + + } + > + + + +)); diff --git a/src/app/components/message/placeholder/DefaultPlaceholder.tsx b/src/app/components/message/placeholder/DefaultPlaceholder.tsx new file mode 100644 index 000000000..5f0b57fae --- /dev/null +++ b/src/app/components/message/placeholder/DefaultPlaceholder.tsx @@ -0,0 +1,25 @@ +import React, { CSSProperties } from 'react'; +import { Avatar, Box, as, color, toRem } from 'folds'; +import { randomNumberBetween } from '../../../utils/common'; +import { LinePlaceholder } from './LinePlaceholder'; +import { MessageBase, ModernLayout } from '../layout'; + +const contentMargin: CSSProperties = { marginTop: toRem(3) }; +const avatarBg: CSSProperties = { backgroundColor: color.SurfaceVariant.Container }; + +export const DefaultPlaceholder = as<'div'>(({ ...props }, ref) => ( + + }> + + + + + + + + + + + + +)); diff --git a/src/app/components/message/placeholder/LinePlaceholder.css.ts b/src/app/components/message/placeholder/LinePlaceholder.css.ts new file mode 100644 index 000000000..0baedf6e1 --- /dev/null +++ b/src/app/components/message/placeholder/LinePlaceholder.css.ts @@ -0,0 +1,12 @@ +import { style } from '@vanilla-extract/css'; +import { DefaultReset, color, config, toRem } from 'folds'; + +export const LinePlaceholder = style([ + DefaultReset, + { + width: '100%', + height: toRem(16), + borderRadius: config.radii.R300, + backgroundColor: color.SurfaceVariant.Container, + }, +]); diff --git a/src/app/components/message/placeholder/LinePlaceholder.tsx b/src/app/components/message/placeholder/LinePlaceholder.tsx new file mode 100644 index 000000000..a5e7bd75a --- /dev/null +++ b/src/app/components/message/placeholder/LinePlaceholder.tsx @@ -0,0 +1,8 @@ +import React from 'react'; +import { Box, as } from 'folds'; +import classNames from 'classnames'; +import * as css from './LinePlaceholder.css'; + +export const LinePlaceholder = as<'div'>(({ className, ...props }, ref) => ( + +)); diff --git a/src/app/components/message/placeholder/index.ts b/src/app/components/message/placeholder/index.ts new file mode 100644 index 000000000..8a3a222f7 --- /dev/null +++ b/src/app/components/message/placeholder/index.ts @@ -0,0 +1,3 @@ +export * from './LinePlaceholder'; +export * from './CompactPlaceholder'; +export * from './DefaultPlaceholder'; diff --git a/src/app/components/room-intro/RoomIntro.tsx b/src/app/components/room-intro/RoomIntro.tsx new file mode 100644 index 000000000..863c7cf01 --- /dev/null +++ b/src/app/components/room-intro/RoomIntro.tsx @@ -0,0 +1,114 @@ +import React, { useCallback } from 'react'; +import { Avatar, AvatarFallback, AvatarImage, Box, Button, Spinner, Text, as, color } from 'folds'; +import { Room } from 'matrix-js-sdk'; +import { openInviteUser, selectRoom } from '../../../client/action/navigation'; +import { useStateEvent } from '../../hooks/useStateEvent'; +import { IRoomCreateContent, Membership, StateEvent } from '../../../types/matrix/room'; +import { getMemberDisplayName, getStateEvent } from '../../utils/room'; +import { useMatrixClient } from '../../hooks/useMatrixClient'; +import { getMxIdLocalPart } from '../../utils/matrix'; +import { AsyncStatus, useAsyncCallback } from '../../hooks/useAsyncCallback'; +import { timeDayMonthYear, timeHourMinute } from '../../utils/time'; + +export type RoomIntroProps = { + room: Room; +}; + +export const RoomIntro = as<'div', RoomIntroProps>(({ room, ...props }, ref) => { + const mx = useMatrixClient(); + const createEvent = getStateEvent(room, StateEvent.RoomCreate); + const avatarEvent = useStateEvent(room, StateEvent.RoomAvatar); + const nameEvent = useStateEvent(room, StateEvent.RoomName); + const topicEvent = useStateEvent(room, StateEvent.RoomTopic); + const createContent = createEvent?.getContent(); + + const ts = createEvent?.getTs(); + const creatorId = createEvent?.getSender(); + const creatorName = + creatorId && (getMemberDisplayName(room, creatorId) ?? getMxIdLocalPart(creatorId)); + const prevRoomId = createContent?.predecessor?.room_id; + const avatarMxc = (avatarEvent?.getContent().url as string) || undefined; + const avatarHttpUrl = avatarMxc ? mx.mxcUrlToHttp(avatarMxc) : undefined; + const name = (nameEvent?.getContent().name || room.name) as string; + const topic = (topicEvent?.getContent().topic as string) || undefined; + + const [prevRoomState, joinPrevRoom] = useAsyncCallback( + useCallback(async (roomId: string) => mx.joinRoom(roomId), [mx]) + ); + + return ( + + + + {avatarHttpUrl ? ( + + ) : ( + + {name[0]} + + )} + + + + + + {name} + + + {typeof topic === 'string' ? topic : 'This is the beginning of conversation.'} + + {creatorName && ts && ( + + {'Created by '} + @{creatorName} + {` on ${timeDayMonthYear(ts)} ${timeHourMinute(ts)}`} + + )} + + + + {typeof prevRoomId === 'string' && + (mx.getRoom(prevRoomId)?.getMyMembership() === Membership.Join ? ( + + ) : ( + + ))} + + + + ); +}); diff --git a/src/app/components/room-intro/index.ts b/src/app/components/room-intro/index.ts new file mode 100644 index 000000000..7250c7898 --- /dev/null +++ b/src/app/components/room-intro/index.ts @@ -0,0 +1 @@ +export * from './RoomIntro'; diff --git a/src/app/components/text-viewer/TextViewer.css.ts b/src/app/components/text-viewer/TextViewer.css.ts new file mode 100644 index 000000000..1ec5647e0 --- /dev/null +++ b/src/app/components/text-viewer/TextViewer.css.ts @@ -0,0 +1,37 @@ +import { style } from '@vanilla-extract/css'; +import { DefaultReset, color, config } from 'folds'; + +export const TextViewer = style([ + DefaultReset, + { + height: '100%', + }, +]); + +export const TextViewerHeader = style([ + DefaultReset, + { + paddingLeft: config.space.S200, + paddingRight: config.space.S200, + borderBottomWidth: config.borderWidth.B300, + flexShrink: 0, + gap: config.space.S200, + }, +]); + +export const TextViewerContent = style([ + DefaultReset, + { + backgroundColor: color.Background.Container, + color: color.Background.OnContainer, + overflow: 'hidden', + }, +]); + +export const TextViewerPre = style([ + DefaultReset, + { + padding: config.space.S600, + whiteSpace: 'pre-wrap', + }, +]); diff --git a/src/app/components/text-viewer/TextViewer.tsx b/src/app/components/text-viewer/TextViewer.tsx new file mode 100644 index 000000000..37642dbf2 --- /dev/null +++ b/src/app/components/text-viewer/TextViewer.tsx @@ -0,0 +1,69 @@ +/* eslint-disable jsx-a11y/no-noninteractive-element-interactions */ +import React, { Suspense, lazy } from 'react'; +import classNames from 'classnames'; +import { Box, Chip, Header, Icon, IconButton, Icons, Scroll, Text, as } from 'folds'; +import { ErrorBoundary } from 'react-error-boundary'; +import * as css from './TextViewer.css'; +import { mimeTypeToExt } from '../../utils/mimeTypes'; +import { copyToClipboard } from '../../utils/dom'; + +const ReactPrism = lazy(() => import('../../plugins/react-prism/ReactPrism')); + +export type TextViewerProps = { + name: string; + text: string; + mimeType: string; + requestClose: () => void; +}; + +export const TextViewer = as<'div', TextViewerProps>( + ({ className, name, text, mimeType, requestClose, ...props }, ref) => { + const handleCopy = () => { + copyToClipboard(text); + }; + + return ( + +
      + + + + + + {name} + + + + + Copy All + + +
      + + + + {text}
      }> + {text}
      }> + {(codeRef) => {text}} + + + + + + + ); + } +); diff --git a/src/app/components/text-viewer/index.ts b/src/app/components/text-viewer/index.ts new file mode 100644 index 000000000..4cf8e281e --- /dev/null +++ b/src/app/components/text-viewer/index.ts @@ -0,0 +1 @@ +export * from './TextViewer'; diff --git a/src/app/components/typing-indicator/TypingIndicator.css.ts b/src/app/components/typing-indicator/TypingIndicator.css.ts new file mode 100644 index 000000000..63a855628 --- /dev/null +++ b/src/app/components/typing-indicator/TypingIndicator.css.ts @@ -0,0 +1,49 @@ +import { keyframes } from '@vanilla-extract/css'; +import { recipe } from '@vanilla-extract/recipes'; +import { DefaultReset, toRem } from 'folds'; + +const TypingDotAnime = keyframes({ + to: { + opacity: '0.4', + transform: 'translateY(-15%)', + }, +}); + +export const TypingDot = recipe({ + base: [ + DefaultReset, + { + display: 'inline-block', + backgroundColor: 'currentColor', + borderRadius: '50%', + transform: 'translateY(15%)', + animation: `${TypingDotAnime} 0.6s infinite alternate`, + }, + ], + variants: { + size: { + '300': { + width: toRem(4), + height: toRem(4), + }, + '400': { + width: toRem(8), + height: toRem(8), + }, + }, + index: { + '0': { + animationDelay: '0s', + }, + '1': { + animationDelay: '0.2s', + }, + '2': { + animationDelay: '0.4s', + }, + }, + }, + defaultVariants: { + size: '400', + }, +}); diff --git a/src/app/components/typing-indicator/TypingIndicator.tsx b/src/app/components/typing-indicator/TypingIndicator.tsx new file mode 100644 index 000000000..336903594 --- /dev/null +++ b/src/app/components/typing-indicator/TypingIndicator.tsx @@ -0,0 +1,21 @@ +import React from 'react'; +import { Box, as, toRem } from 'folds'; +import * as css from './TypingIndicator.css'; + +export type TypingIndicatorProps = { + size?: '300' | '400'; +}; + +export const TypingIndicator = as<'div', TypingIndicatorProps>(({ size, style, ...props }, ref) => ( + + + + + +)); diff --git a/src/app/components/typing-indicator/index.ts b/src/app/components/typing-indicator/index.ts new file mode 100644 index 000000000..07efe0caa --- /dev/null +++ b/src/app/components/typing-indicator/index.ts @@ -0,0 +1 @@ +export * from './TypingIndicator'; diff --git a/src/app/hooks/media/index.ts b/src/app/hooks/media/index.ts new file mode 100644 index 000000000..7c202f9cf --- /dev/null +++ b/src/app/hooks/media/index.ts @@ -0,0 +1,6 @@ +export * from './useMediaPlay'; +export * from './useMediaPlayTimeCallback'; +export * from './useMediaPlaybackRate'; +export * from './useMediaSeek'; +export * from './useMediaVolume'; +export * from './useMediaLoading'; diff --git a/src/app/hooks/media/useMediaLoading.ts b/src/app/hooks/media/useMediaLoading.ts new file mode 100644 index 000000000..9d7320103 --- /dev/null +++ b/src/app/hooks/media/useMediaLoading.ts @@ -0,0 +1,51 @@ +import { useEffect, useState } from 'react'; + +export type MediaLoadingData = { + loading: boolean; + error: boolean; +}; + +export const useMediaLoading = ( + getTargetElement: () => HTMLMediaElement | null +): MediaLoadingData => { + const [loadingData, setLoadingData] = useState({ + loading: false, + error: false, + }); + + useEffect(() => { + const targetEl = getTargetElement(); + const handleStart = () => { + setLoadingData({ + loading: true, + error: false, + }); + }; + const handleStop = () => { + setLoadingData({ + loading: false, + error: false, + }); + }; + const handleError = () => { + setLoadingData({ + loading: false, + error: true, + }); + }; + targetEl?.addEventListener('loadstart', handleStart); + targetEl?.addEventListener('loadeddata', handleStop); + targetEl?.addEventListener('stalled', handleStop); + targetEl?.addEventListener('suspend', handleStop); + targetEl?.addEventListener('error', handleError); + return () => { + targetEl?.removeEventListener('loadstart', handleStart); + targetEl?.removeEventListener('loadeddata', handleStop); + targetEl?.removeEventListener('stalled', handleStop); + targetEl?.removeEventListener('suspend', handleStop); + targetEl?.removeEventListener('error', handleError); + }; + }, [getTargetElement]); + + return loadingData; +}; diff --git a/src/app/hooks/media/useMediaPlay.ts b/src/app/hooks/media/useMediaPlay.ts new file mode 100644 index 000000000..e175eee21 --- /dev/null +++ b/src/app/hooks/media/useMediaPlay.ts @@ -0,0 +1,46 @@ +import { useCallback, useEffect, useState } from 'react'; + +export type MediaPlayData = { + playing: boolean; +}; + +export type MediaPlayControl = { + setPlaying: (play: boolean) => void; +}; + +export const useMediaPlay = ( + getTargetElement: () => HTMLMediaElement | null +): MediaPlayData & MediaPlayControl => { + const [playing, setPlay] = useState(false); + + const setPlaying = useCallback( + (play: boolean) => { + const targetEl = getTargetElement(); + if (!targetEl) return; + if (play) targetEl.play(); + else targetEl.pause(); + }, + [getTargetElement] + ); + + useEffect(() => { + const targetEl = getTargetElement(); + const handleChange = () => { + if (!targetEl) return; + setPlay(targetEl.paused === false); + }; + targetEl?.addEventListener('playing', handleChange); + targetEl?.addEventListener('play', handleChange); + targetEl?.addEventListener('pause', handleChange); + return () => { + targetEl?.removeEventListener('playing', handleChange); + targetEl?.removeEventListener('play', handleChange); + targetEl?.removeEventListener('pause', handleChange); + }; + }, [getTargetElement]); + + return { + playing, + setPlaying, + }; +}; diff --git a/src/app/hooks/media/useMediaPlayTimeCallback.ts b/src/app/hooks/media/useMediaPlayTimeCallback.ts new file mode 100644 index 000000000..c70ddc6e8 --- /dev/null +++ b/src/app/hooks/media/useMediaPlayTimeCallback.ts @@ -0,0 +1,24 @@ +import { useEffect } from 'react'; + +export type PlayTimeCallback = (duration: number, currentTime: number) => void; + +export const useMediaPlayTimeCallback = ( + getTargetElement: () => HTMLMediaElement | null, + onPlayTimeCallback: PlayTimeCallback +): void => { + useEffect(() => { + const targetEl = getTargetElement(); + const handleChange = () => { + if (!targetEl) return; + onPlayTimeCallback(targetEl.duration, targetEl.currentTime); + }; + targetEl?.addEventListener('timeupdate', handleChange); + targetEl?.addEventListener('loadedmetadata', handleChange); + targetEl?.addEventListener('ended', handleChange); + return () => { + targetEl?.removeEventListener('timeupdate', handleChange); + targetEl?.removeEventListener('loadedmetadata', handleChange); + targetEl?.removeEventListener('ended', handleChange); + }; + }, [getTargetElement, onPlayTimeCallback]); +}; diff --git a/src/app/hooks/media/useMediaPlaybackRate.ts b/src/app/hooks/media/useMediaPlaybackRate.ts new file mode 100644 index 000000000..173688450 --- /dev/null +++ b/src/app/hooks/media/useMediaPlaybackRate.ts @@ -0,0 +1,40 @@ +import { useCallback, useEffect, useState } from 'react'; + +export type MediaPlaybackRateData = { + playbackRate: number; +}; +export type MediaPlaybackRateControl = { + setPlaybackRate: (rate: number) => void; +}; + +export const useMediaPlaybackRate = ( + getTargetElement: () => HTMLMediaElement | null +): MediaPlaybackRateData & MediaPlaybackRateControl => { + const [rate, setRate] = useState(1.0); + + const setPlaybackRate = useCallback( + (playbackRate: number) => { + const targetEl = getTargetElement(); + if (!targetEl) return; + targetEl.playbackRate = playbackRate; + }, + [getTargetElement] + ); + + useEffect(() => { + const targetEl = getTargetElement(); + const handleChange = () => { + if (!targetEl) return; + setRate(targetEl.playbackRate); + }; + targetEl?.addEventListener('ratechange', handleChange); + return () => { + targetEl?.removeEventListener('ratechange', handleChange); + }; + }, [getTargetElement]); + + return { + playbackRate: rate, + setPlaybackRate, + }; +}; diff --git a/src/app/hooks/media/useMediaSeek.ts b/src/app/hooks/media/useMediaSeek.ts new file mode 100644 index 000000000..89c8d077c --- /dev/null +++ b/src/app/hooks/media/useMediaSeek.ts @@ -0,0 +1,51 @@ +import { useCallback, useEffect, useState } from 'react'; + +export type MediaSeekData = { + seeking: boolean; + seekable?: TimeRanges; +}; +export type MediaSeekControl = { + seek: (time: number) => void; +}; + +export const useMediaSeek = ( + getTargetElement: () => HTMLMediaElement | null +): MediaSeekData & MediaSeekControl => { + const [seekData, setSeekData] = useState({ + seeking: false, + seekable: undefined, + }); + + const seek = useCallback( + (time: number) => { + const targetEl = getTargetElement(); + if (!targetEl) return; + targetEl.currentTime = time; + }, + [getTargetElement] + ); + + useEffect(() => { + const targetEl = getTargetElement(); + const handleChange = () => { + if (!targetEl) return; + setSeekData({ + seeking: targetEl.seeking, + seekable: targetEl.seekable, + }); + }; + targetEl?.addEventListener('loadedmetadata', handleChange); + targetEl?.addEventListener('seeked', handleChange); + targetEl?.addEventListener('seeking', handleChange); + return () => { + targetEl?.removeEventListener('loadedmetadata', handleChange); + targetEl?.removeEventListener('seeked', handleChange); + targetEl?.removeEventListener('seeking', handleChange); + }; + }, [getTargetElement]); + + return { + ...seekData, + seek, + }; +}; diff --git a/src/app/hooks/media/useMediaVolume.ts b/src/app/hooks/media/useMediaVolume.ts new file mode 100644 index 000000000..605cee461 --- /dev/null +++ b/src/app/hooks/media/useMediaVolume.ts @@ -0,0 +1,60 @@ +import { useCallback, useEffect, useState } from 'react'; + +export type MediaVolumeData = { + volume: number; + mute: boolean; +}; + +export type MediaVolumeControl = { + setMute: (mute: boolean) => void; + setVolume: (volume: number) => void; +}; + +export const useMediaVolume = ( + getTargetElement: () => HTMLMediaElement | null +): MediaVolumeData & MediaVolumeControl => { + const [volumeData, setVolumeData] = useState({ + volume: 1, + mute: false, + }); + + const setMute = useCallback( + (mute: boolean) => { + const targetEl = getTargetElement(); + if (!targetEl) return; + targetEl.muted = mute; + }, + [getTargetElement] + ); + + const setVolume = useCallback( + (volume: number) => { + const targetEl = getTargetElement(); + if (!targetEl) return; + targetEl.volume = volume; + }, + [getTargetElement] + ); + + useEffect(() => { + const targetEl = getTargetElement(); + const handleChange = () => { + if (!targetEl) return; + + setVolumeData({ + mute: targetEl.muted, + volume: Math.max(0, Math.min(targetEl.volume, 1)), + }); + }; + targetEl?.addEventListener('volumechange', handleChange); + return () => { + targetEl?.removeEventListener('volumechange', handleChange); + }; + }, [getTargetElement]); + + return { + ...volumeData, + setMute, + setVolume, + }; +}; diff --git a/src/app/hooks/useIntersectionObserver.ts b/src/app/hooks/useIntersectionObserver.ts index 754007aed..9b0b50e84 100644 --- a/src/app/hooks/useIntersectionObserver.ts +++ b/src/app/hooks/useIntersectionObserver.ts @@ -25,6 +25,8 @@ export const useIntersectionObserver = ( setIntersectionObserver(new IntersectionObserver(onIntersectionCallback, initOpts)); }, [onIntersectionCallback, opts]); + useEffect(() => () => intersectionObserver?.disconnect(), [intersectionObserver]); + useEffect(() => { const element = typeof observeElement === 'function' ? observeElement() : observeElement; if (element) intersectionObserver?.observe(element); diff --git a/src/app/hooks/useMatrixEventRenderer.ts b/src/app/hooks/useMatrixEventRenderer.ts new file mode 100644 index 000000000..9ace6b66a --- /dev/null +++ b/src/app/hooks/useMatrixEventRenderer.ts @@ -0,0 +1,80 @@ +import { ReactNode } from 'react'; +import { MatrixEvent } from 'matrix-js-sdk'; +import { MessageEvent, StateEvent } from '../../types/matrix/room'; + +export type EventRenderer = ( + eventId: string, + mEvent: MatrixEvent, + ...args: T +) => ReactNode; + +export type EventRendererOpts = { + renderRoomMessage?: EventRenderer; + renderRoomEncrypted?: EventRenderer; + renderSticker?: EventRenderer; + renderRoomMember?: EventRenderer; + renderRoomName?: EventRenderer; + renderRoomTopic?: EventRenderer; + renderRoomAvatar?: EventRenderer; + renderStateEvent?: EventRenderer; + renderEvent?: EventRenderer; +}; + +export type RenderMatrixEvent = ( + eventId: string, + mEvent: MatrixEvent, + ...args: T +) => ReactNode; + +export const useMatrixEventRenderer = + ({ + renderRoomMessage, + renderRoomEncrypted, + renderSticker, + renderRoomMember, + renderRoomName, + renderRoomTopic, + renderRoomAvatar, + renderStateEvent, + renderEvent, + }: EventRendererOpts): RenderMatrixEvent => + (eventId, mEvent, ...args) => { + const eventType = mEvent.getWireType(); + + if (eventType === MessageEvent.RoomMessage && renderRoomMessage) { + return renderRoomMessage(eventId, mEvent, ...args); + } + + if (eventType === MessageEvent.RoomMessageEncrypted && renderRoomEncrypted) { + return renderRoomEncrypted(eventId, mEvent, ...args); + } + + if (eventType === MessageEvent.Sticker && renderSticker) { + return renderSticker(eventId, mEvent, ...args); + } + + if (eventType === StateEvent.RoomMember && renderRoomMember) { + return renderRoomMember(eventId, mEvent, ...args); + } + + if (eventType === StateEvent.RoomName && renderRoomName) { + return renderRoomName(eventId, mEvent, ...args); + } + + if (eventType === StateEvent.RoomTopic && renderRoomTopic) { + return renderRoomTopic(eventId, mEvent, ...args); + } + + if (eventType === StateEvent.RoomAvatar && renderRoomAvatar) { + return renderRoomAvatar(eventId, mEvent, ...args); + } + + if (typeof mEvent.getStateKey() === 'string' && renderStateEvent) { + return renderStateEvent(eventId, mEvent, ...args); + } + + if (typeof mEvent.getStateKey() !== 'string' && renderEvent) { + return renderEvent(eventId, mEvent, ...args); + } + return null; + }; diff --git a/src/app/hooks/useMemberEventParser.tsx b/src/app/hooks/useMemberEventParser.tsx new file mode 100644 index 000000000..ecb6f66b2 --- /dev/null +++ b/src/app/hooks/useMemberEventParser.tsx @@ -0,0 +1,218 @@ +import React, { ReactNode } from 'react'; +import { IconSrc, Icons } from 'folds'; +import { MatrixEvent } from 'matrix-js-sdk'; +import { IMemberContent, Membership } from '../../types/matrix/room'; +import { getMxIdLocalPart } from '../utils/matrix'; + +export type ParsedResult = { + icon: IconSrc; + body: ReactNode; +}; + +export type MemberEventParser = (mEvent: MatrixEvent) => ParsedResult; + +export const useMemberEventParser = (): MemberEventParser => { + const parseMemberEvent: MemberEventParser = (mEvent) => { + const content = mEvent.getContent(); + const prevContent = mEvent.getPrevContent() as IMemberContent; + const senderId = mEvent.getSender(); + const userId = mEvent.getStateKey(); + + if (!senderId || !userId) + return { + icon: Icons.User, + body: 'Broken membership event', + }; + + const senderName = getMxIdLocalPart(senderId); + const userName = content.displayname || getMxIdLocalPart(userId); + + if (content.membership !== prevContent.membership) { + if (content.membership === Membership.Invite) { + if (prevContent.membership === Membership.Knock) { + return { + icon: Icons.ArrowGoRightPlus, + body: ( + <> + {senderName} + {' accepted '} + {userName} + {`'s join request `} + {content.reason} + + ), + }; + } + + return { + icon: Icons.ArrowGoRightPlus, + body: ( + <> + {senderName} + {' invited '} + {userName} {content.reason} + + ), + }; + } + + if (content.membership === Membership.Knock) { + return { + icon: Icons.ArrowGoRightPlus, + body: ( + <> + {userName} + {' request to join room '} + {content.reason} + + ), + }; + } + + if (content.membership === Membership.Join) { + return { + icon: Icons.ArrowGoRight, + body: ( + <> + {userName} + {' joined the room'} + + ), + }; + } + + if (content.membership === Membership.Leave) { + if (prevContent.membership === Membership.Invite) { + return { + icon: Icons.ArrowGoRightCross, + body: + senderId === userId ? ( + <> + {userName} + {' reject the invitation '} + {content.reason} + + ) : ( + <> + {senderName} + {' reject '} + {userName} + {`'s join request `} + {content.reason} + + ), + }; + } + + if (prevContent.membership === Membership.Knock) { + return { + icon: Icons.ArrowGoRightCross, + body: + senderId === userId ? ( + <> + {userName} + {' revoked joined request '} + {content.reason} + + ) : ( + <> + {senderName} + {' revoked '} + {userName} + {`'s invite `} + {content.reason} + + ), + }; + } + + if (prevContent.membership === Membership.Ban) { + return { + icon: Icons.ArrowGoLeft, + body: ( + <> + {senderName} + {' unbanned '} + {userName} {content.reason} + + ), + }; + } + + return { + icon: Icons.ArrowGoLeft, + body: + senderId === userId ? ( + <> + {userName} + {' left the room '} + {content.reason} + + ) : ( + <> + {senderName} + {' kicked '} + {userName} {content.reason} + + ), + }; + } + + if (content.membership === Membership.Ban) { + return { + icon: Icons.ArrowGoLeft, + body: ( + <> + {senderName} + {' banned '} + {userName} {content.reason} + + ), + }; + } + } + + if (content.displayname !== prevContent.displayname) { + const prevUserName = prevContent.displayname || userId; + + return { + icon: Icons.Mention, + body: content.displayname ? ( + <> + {prevUserName} + {' changed display name to '} + {userName} + + ) : ( + <> + {prevUserName} + {' removed their display name '} + + ), + }; + } + if (content.avatar_url !== prevContent.avatar_url) { + return { + icon: Icons.User, + body: content.displayname ? ( + <> + {userName} + {' changed their avatar'} + + ) : ( + <> + {userName} + {' removed their avatar '} + + ), + }; + } + + return { + icon: Icons.User, + body: 'Broken membership event', + }; + }; + + return parseMemberEvent; +}; diff --git a/src/app/hooks/usePan.ts b/src/app/hooks/usePan.ts new file mode 100644 index 000000000..60d7954f3 --- /dev/null +++ b/src/app/hooks/usePan.ts @@ -0,0 +1,62 @@ +import { MouseEventHandler, useEffect, useState } from 'react'; + +export type Pan = { + translateX: number; + translateY: number; +}; + +const INITIAL_PAN = { + translateX: 0, + translateY: 0, +}; + +export const usePan = (active: boolean) => { + const [pan, setPan] = useState(INITIAL_PAN); + const [cursor, setCursor] = useState<'grab' | 'grabbing' | 'initial'>( + active ? 'grab' : 'initial' + ); + + useEffect(() => { + setCursor(active ? 'grab' : 'initial'); + }, [active]); + + const handleMouseMove = (evt: MouseEvent) => { + evt.preventDefault(); + evt.stopPropagation(); + + setPan((p) => { + const { translateX, translateY } = p; + const mX = translateX + evt.movementX; + const mY = translateY + evt.movementY; + + return { translateX: mX, translateY: mY }; + }); + }; + + const handleMouseUp = (evt: MouseEvent) => { + evt.preventDefault(); + setCursor('grab'); + + document.removeEventListener('mousemove', handleMouseMove); + document.removeEventListener('mouseup', handleMouseUp); + }; + + const handleMouseDown: MouseEventHandler = (evt) => { + if (!active) return; + evt.preventDefault(); + setCursor('grabbing'); + + document.addEventListener('mousemove', handleMouseMove); + document.addEventListener('mouseup', handleMouseUp); + }; + + useEffect(() => { + if (!active) setPan(INITIAL_PAN); + }, [active]); + + return { + pan, + cursor, + onMouseDown: handleMouseDown, + }; +}; diff --git a/src/app/hooks/usePowerLevels.ts b/src/app/hooks/usePowerLevels.ts index 3ce75a2f2..98e3701ed 100644 --- a/src/app/hooks/usePowerLevels.ts +++ b/src/app/hooks/usePowerLevels.ts @@ -1,8 +1,10 @@ import { Room } from 'matrix-js-sdk'; -import { useCallback } from 'react'; +import { createContext, useCallback, useContext } from 'react'; import { useStateEvent } from './useStateEvent'; import { StateEvent } from '../../types/matrix/room'; +export type PowerLevelActions = 'invite' | 'redact' | 'kick' | 'ban' | 'historical'; + enum DefaultPowerLevels { usersDefault = 0, stateDefault = 50, @@ -29,12 +31,23 @@ interface IPowerLevels { notifications?: Record; } -export function usePowerLevels(room: Room) { +export type GetPowerLevel = (userId: string) => number; +export type CanSend = (eventType: string | undefined, powerLevel: number) => boolean; +export type CanDoAction = (action: PowerLevelActions, powerLevel: number) => boolean; + +export type PowerLevelsAPI = { + getPowerLevel: GetPowerLevel; + canSendEvent: CanSend; + canSendStateEvent: CanSend; + canDoAction: CanDoAction; +}; + +export function usePowerLevels(room: Room): PowerLevelsAPI { const powerLevelsEvent = useStateEvent(room, StateEvent.RoomPowerLevels); const powerLevels: IPowerLevels = powerLevelsEvent?.getContent() ?? DefaultPowerLevels; - const getPowerLevel = useCallback( - (userId: string) => { + const getPowerLevel: GetPowerLevel = useCallback( + (userId) => { const { users_default: usersDefault, users } = powerLevels; if (users && typeof users[userId] === 'number') { return users[userId]; @@ -44,8 +57,8 @@ export function usePowerLevels(room: Room) { [powerLevels] ); - const canSendEvent = useCallback( - (eventType: string | undefined, powerLevel: number) => { + const canSendEvent: CanSend = useCallback( + (eventType, powerLevel) => { const { events, events_default: eventsDefault } = powerLevels; if (events && eventType && typeof events[eventType] === 'number') { return powerLevel >= events[eventType]; @@ -55,8 +68,8 @@ export function usePowerLevels(room: Room) { [powerLevels] ); - const canSendStateEvent = useCallback( - (eventType: string | undefined, powerLevel: number) => { + const canSendStateEvent: CanSend = useCallback( + (eventType, powerLevel) => { const { events, state_default: stateDefault } = powerLevels; if (events && eventType && typeof events[eventType] === 'number') { return powerLevel >= events[eventType]; @@ -66,8 +79,8 @@ export function usePowerLevels(room: Room) { [powerLevels] ); - const canDoAction = useCallback( - (action: 'invite' | 'redact' | 'kick' | 'ban' | 'historical', powerLevel: number) => { + const canDoAction: CanDoAction = useCallback( + (action, powerLevel) => { const requiredPL = powerLevels[action]; if (typeof requiredPL === 'number') { return powerLevel >= requiredPL; @@ -84,3 +97,13 @@ export function usePowerLevels(room: Room) { canDoAction, }; } + +export const PowerLevelsContext = createContext(null); + +export const PowerLevelsContextProvider = PowerLevelsContext.Provider; + +export const usePowerLevelsAPI = (): PowerLevelsAPI => { + const api = useContext(PowerLevelsContext); + if (!api) throw new Error('PowerLevelContext is not initialized!'); + return api; +}; diff --git a/src/app/hooks/useRelations.ts b/src/app/hooks/useRelations.ts new file mode 100644 index 000000000..51978de51 --- /dev/null +++ b/src/app/hooks/useRelations.ts @@ -0,0 +1,25 @@ +import { useEffect, useState } from 'react'; +import { RelationsEvent, type Relations } from 'matrix-js-sdk/lib/models/relations'; + +export const useRelations = ( + relations: Relations, + getRelations: (relations: Relations) => T +) => { + const [data, setData] = useState(() => getRelations(relations)); + + useEffect(() => { + const handleUpdate = () => { + setData(getRelations(relations)); + }; + relations.on(RelationsEvent.Add, handleUpdate); + relations.on(RelationsEvent.Redaction, handleUpdate); + relations.on(RelationsEvent.Remove, handleUpdate); + return () => { + relations.removeListener(RelationsEvent.Add, handleUpdate); + relations.removeListener(RelationsEvent.Redaction, handleUpdate); + relations.removeListener(RelationsEvent.Remove, handleUpdate); + }; + }, [relations, getRelations]); + + return data; +}; diff --git a/src/app/hooks/useResizeObserver.ts b/src/app/hooks/useResizeObserver.ts index 1e0fc7263..707d34871 100644 --- a/src/app/hooks/useResizeObserver.ts +++ b/src/app/hooks/useResizeObserver.ts @@ -13,6 +13,8 @@ export const useResizeObserver = ( ): ResizeObserver => { const resizeObserver = useMemo(() => new ResizeObserver(onResizeCallback), [onResizeCallback]); + useEffect(() => () => resizeObserver?.disconnect(), [resizeObserver]); + useEffect(() => { const element = typeof observeElement === 'function' ? observeElement() : observeElement; if (element) resizeObserver.observe(element); diff --git a/src/app/hooks/useRoomEventReaders.ts b/src/app/hooks/useRoomEventReaders.ts new file mode 100644 index 000000000..f6bac27e5 --- /dev/null +++ b/src/app/hooks/useRoomEventReaders.ts @@ -0,0 +1,35 @@ +import { Room, RoomEvent, RoomEventHandlerMap } from 'matrix-js-sdk'; +import { useEffect, useState } from 'react'; + +const getEventReaders = (room: Room, evtId?: string) => { + if (!evtId) return []; + const liveEvents = room.getLiveTimeline().getEvents(); + const userIds: string[] = []; + + for (let i = liveEvents.length - 1; i >= 0; i -= 1) { + userIds.splice(userIds.length, 0, ...room.getUsersReadUpTo(liveEvents[i])); + if (liveEvents[i].getId() === evtId) break; + } + + return [...new Set(userIds)]; +}; + +export const useRoomEventReaders = (room: Room, eventId?: string): string[] => { + const [readers, setReaders] = useState(() => getEventReaders(room, eventId)); + + useEffect(() => { + setReaders(getEventReaders(room, eventId)); + + const handleReceipt: RoomEventHandlerMap[RoomEvent.Receipt] = (event, r) => { + if (r.roomId !== room.roomId) return; + setReaders(getEventReaders(room, eventId)); + }; + + room.on(RoomEvent.Receipt, handleReceipt); + return () => { + room.removeListener(RoomEvent.Receipt, handleReceipt); + }; + }, [room, eventId]); + + return readers; +}; diff --git a/src/app/hooks/useRoomLatestEvent.ts b/src/app/hooks/useRoomLatestEvent.ts new file mode 100644 index 000000000..337438ce9 --- /dev/null +++ b/src/app/hooks/useRoomLatestEvent.ts @@ -0,0 +1,29 @@ +import { MatrixEvent, Room, RoomEvent, RoomEventHandlerMap } from 'matrix-js-sdk'; +import { useEffect, useState } from 'react'; + +export const useRoomLatestEvent = (room: Room) => { + const [latestEvent, setLatestEvent] = useState(); + + useEffect(() => { + const getLatestEvent = (): MatrixEvent | undefined => { + const liveEvents = room.getLiveTimeline().getEvents(); + for (let i = liveEvents.length - 1; i >= 0; i -= 1) { + const evt = liveEvents[i]; + if (evt) return evt; + } + return undefined; + }; + + const handleTimelineEvent: RoomEventHandlerMap[RoomEvent.Timeline] = () => { + setLatestEvent(getLatestEvent()); + }; + setLatestEvent(getLatestEvent()); + + room.on(RoomEvent.Timeline, handleTimelineEvent); + return () => { + room.removeListener(RoomEvent.Timeline, handleTimelineEvent); + }; + }, [room]); + + return latestEvent; +}; diff --git a/src/app/hooks/useRoomMsgContentRenderer.ts b/src/app/hooks/useRoomMsgContentRenderer.ts new file mode 100644 index 000000000..b014249a2 --- /dev/null +++ b/src/app/hooks/useRoomMsgContentRenderer.ts @@ -0,0 +1,68 @@ +import { ReactNode } from 'react'; +import { MatrixEvent, MsgType } from 'matrix-js-sdk'; + +export type MsgContentRenderer = ( + eventId: string, + mEvent: MatrixEvent, + ...args: T +) => ReactNode; + +export type RoomMsgContentRendererOpts = { + renderText?: MsgContentRenderer; + renderEmote?: MsgContentRenderer; + renderNotice?: MsgContentRenderer; + renderImage?: MsgContentRenderer; + renderVideo?: MsgContentRenderer; + renderAudio?: MsgContentRenderer; + renderFile?: MsgContentRenderer; + renderLocation?: MsgContentRenderer; + renderBadEncrypted?: MsgContentRenderer; + renderUnsupported?: MsgContentRenderer; + renderBrokenFallback?: MsgContentRenderer; +}; + +export type RenderRoomMsgContent = ( + eventId: string, + mEvent: MatrixEvent, + ...args: T +) => ReactNode; + +export const useRoomMsgContentRenderer = + ({ + renderText, + renderEmote, + renderNotice, + renderImage, + renderVideo, + renderAudio, + renderFile, + renderLocation, + renderBadEncrypted, + renderUnsupported, + renderBrokenFallback, + }: RoomMsgContentRendererOpts): RenderRoomMsgContent => + (eventId, mEvent, ...args) => { + const msgType = mEvent.getContent().msgtype; + + let node: ReactNode = null; + + if (msgType === MsgType.Text && renderText) node = renderText(eventId, mEvent, ...args); + else if (msgType === MsgType.Emote && renderEmote) node = renderEmote(eventId, mEvent, ...args); + else if (msgType === MsgType.Notice && renderNotice) + node = renderNotice(eventId, mEvent, ...args); + else if (msgType === MsgType.Image && renderImage) node = renderImage(eventId, mEvent, ...args); + else if (msgType === MsgType.Video && renderVideo) node = renderVideo(eventId, mEvent, ...args); + else if (msgType === MsgType.Audio && renderAudio) node = renderAudio(eventId, mEvent, ...args); + else if (msgType === MsgType.File && renderFile) node = renderFile(eventId, mEvent, ...args); + else if (msgType === MsgType.Location && renderLocation) + node = renderLocation(eventId, mEvent, ...args); + else if (msgType === 'm.bad.encrypted' && renderBadEncrypted) + node = renderBadEncrypted(eventId, mEvent, ...args); + else if (renderUnsupported) { + node = renderUnsupported(eventId, mEvent, ...args); + } + + if (!node && renderBrokenFallback) node = renderBrokenFallback(eventId, mEvent, ...args); + + return node; + }; diff --git a/src/app/hooks/useVirtualPaginator.ts b/src/app/hooks/useVirtualPaginator.ts new file mode 100644 index 000000000..550e11c03 --- /dev/null +++ b/src/app/hooks/useVirtualPaginator.ts @@ -0,0 +1,405 @@ +import { useCallback, useEffect, useLayoutEffect, useMemo, useRef } from 'react'; +import { OnIntersectionCallback, useIntersectionObserver } from './useIntersectionObserver'; +import { + canFitInScrollView, + getScrollInfo, + isInScrollView, + isIntersectingScrollView, +} from '../utils/dom'; + +const PAGINATOR_ANCHOR_ATTR = 'data-paginator-anchor'; + +export enum Direction { + Backward = 'B', + Forward = 'F', +} + +export type ItemRange = { + start: number; + end: number; +}; + +export type ScrollToOptions = { + offset?: number; + align?: 'start' | 'center' | 'end'; + behavior?: 'auto' | 'instant' | 'smooth'; + stopInView?: boolean; +}; + +export type ScrollToElement = (element: HTMLElement, opts?: ScrollToOptions) => void; +export type ScrollToItem = (index: number, opts?: ScrollToOptions) => void; + +type HandleObserveAnchor = (element: HTMLElement | null) => void; + +type VirtualPaginatorOptions = { + count: number; + limit: number; + range: ItemRange; + onRangeChange: (range: ItemRange) => void; + getScrollElement: () => TScrollElement | null; + getItemElement: (index: number) => HTMLElement | undefined; + onEnd?: (back: boolean) => void; +}; + +type VirtualPaginator = { + getItems: () => number[]; + scrollToElement: ScrollToElement; + scrollToItem: ScrollToItem; + observeBackAnchor: HandleObserveAnchor; + observeFrontAnchor: HandleObserveAnchor; +}; + +const generateItems = (range: ItemRange) => { + const items: number[] = []; + for (let i = range.start; i < range.end; i += 1) { + items.push(i); + } + + return items; +}; + +const getDropIndex = ( + scrollEl: HTMLElement, + range: ItemRange, + dropDirection: Direction, + getItemElement: (index: number) => HTMLElement | undefined, + pageThreshold = 1 +): number | undefined => { + const fromBackward = dropDirection === Direction.Backward; + const items = fromBackward ? generateItems(range) : generateItems(range).reverse(); + + const { viewHeight, top, height } = getScrollInfo(scrollEl); + const { offsetTop: sOffsetTop } = scrollEl; + const bottom = top + viewHeight; + const dropEdgePx = fromBackward + ? Math.max(top - viewHeight * pageThreshold, 0) + : Math.min(bottom + viewHeight * pageThreshold, height); + if (dropEdgePx === 0 || dropEdgePx === height) return undefined; + + let dropIndex: number | undefined; + + items.find((item) => { + const el = getItemElement(item); + if (!el) { + dropIndex = item; + return false; + } + const { clientHeight } = el; + const offsetTop = el.offsetTop - sOffsetTop; + const offsetBottom = offsetTop + clientHeight; + const isInView = fromBackward ? offsetBottom > dropEdgePx : offsetTop < dropEdgePx; + if (isInView) return true; + dropIndex = item; + return false; + }); + + return dropIndex; +}; + +type RestoreAnchorData = [number | undefined, HTMLElement | undefined]; +const getRestoreAnchor = ( + range: ItemRange, + getItemElement: (index: number) => HTMLElement | undefined, + direction: Direction +): RestoreAnchorData => { + let scrollAnchorEl: HTMLElement | undefined; + const scrollAnchorItem = ( + direction === Direction.Backward ? generateItems(range) : generateItems(range).reverse() + ).find((i) => { + const el = getItemElement(i); + if (el) { + scrollAnchorEl = el; + return true; + } + return false; + }); + return [scrollAnchorItem, scrollAnchorEl]; +}; + +const getRestoreScrollData = (scrollTop: number, restoreAnchorData: RestoreAnchorData) => { + const [anchorItem, anchorElement] = restoreAnchorData; + if (!anchorItem || !anchorElement) { + return undefined; + } + return { + scrollTop, + anchorItem, + anchorOffsetTop: anchorElement.offsetTop, + }; +}; + +const useObserveAnchorHandle = ( + intersectionObserver: ReturnType, + anchorType: Direction +): HandleObserveAnchor => + useMemo(() => { + let anchor: HTMLElement | null = null; + return (element) => { + if (element === anchor) return; + if (anchor) intersectionObserver?.unobserve(anchor); + if (!element) return; + anchor = element; + element.setAttribute(PAGINATOR_ANCHOR_ATTR, anchorType); + intersectionObserver?.observe(element); + }; + }, [intersectionObserver, anchorType]); + +export const useVirtualPaginator = ( + options: VirtualPaginatorOptions +): VirtualPaginator => { + const { count, limit, range, onRangeChange, getScrollElement, getItemElement, onEnd } = options; + + const initialRenderRef = useRef(true); + + const restoreScrollRef = useRef<{ + scrollTop: number; + anchorOffsetTop: number; + anchorItem: number; + }>(); + + const scrollToItemRef = useRef<{ + index: number; + opts?: ScrollToOptions; + }>(); + + const propRef = useRef({ + range, + limit, + count, + }); + if (propRef.current.count !== count) { + // Clear restoreScrollRef on count change + // As restoreScrollRef.current.anchorItem might changes + restoreScrollRef.current = undefined; + } + propRef.current = { + range, + count, + limit, + }; + + const getItems = useMemo(() => { + const items = generateItems(range); + return () => items; + }, [range]); + + const scrollToElement = useCallback( + (element, opts) => { + const scrollElement = getScrollElement(); + if (!scrollElement) return; + + if (opts?.stopInView && isInScrollView(scrollElement, element)) { + return; + } + let scrollTo = element.offsetTop; + if (opts?.align === 'center' && canFitInScrollView(scrollElement, element)) { + const scrollInfo = getScrollInfo(scrollElement); + scrollTo = + element.offsetTop - + Math.round(scrollInfo.viewHeight / 2) + + Math.round(element.clientHeight / 2); + } else if (opts?.align === 'end' && canFitInScrollView(scrollElement, element)) { + const scrollInfo = getScrollInfo(scrollElement); + scrollTo = element.offsetTop - Math.round(scrollInfo.viewHeight) + element.clientHeight; + } + + scrollElement.scrollTo({ + top: scrollTo - (opts?.offset ?? 0), + behavior: opts?.behavior, + }); + }, + [getScrollElement] + ); + + const scrollToItem = useCallback( + (index, opts) => { + const { range: currentRange, limit: currentLimit, count: currentCount } = propRef.current; + + if (index < 0 || index >= currentCount) return; + // index is not in range change range + // and trigger scrollToItem in layoutEffect hook + if (index < currentRange.start || index >= currentRange.end) { + onRangeChange({ + start: Math.max(index - currentLimit, 0), + end: Math.min(index + currentLimit, currentCount), + }); + scrollToItemRef.current = { + index, + opts, + }; + return; + } + + // find target or it's previous rendered element to scroll to + const targetItems = generateItems({ start: currentRange.start, end: index + 1 }); + const targetItem = targetItems.reverse().find((i) => getItemElement(i) !== undefined); + const itemElement = targetItem && getItemElement(targetItem); + + if (!itemElement) { + const scrollElement = getScrollElement(); + scrollElement?.scrollTo({ + top: opts?.offset ?? 0, + behavior: opts?.behavior, + }); + return; + } + scrollToElement(itemElement, opts); + }, + [getScrollElement, scrollToElement, getItemElement, onRangeChange] + ); + + const paginate = useCallback( + (direction: Direction) => { + const scrollEl = getScrollElement(); + const { range: currentRange, limit: currentLimit, count: currentCount } = propRef.current; + let { start, end } = currentRange; + + if (direction === Direction.Backward) { + restoreScrollRef.current = undefined; + if (start === 0) { + onEnd?.(true); + return; + } + if (scrollEl) { + restoreScrollRef.current = getRestoreScrollData( + scrollEl.scrollTop, + getRestoreAnchor({ start, end }, getItemElement, Direction.Backward) + ); + } + if (scrollEl) { + end = getDropIndex(scrollEl, currentRange, Direction.Forward, getItemElement, 2) ?? end; + } + start = Math.max(start - currentLimit, 0); + } + + if (direction === Direction.Forward) { + restoreScrollRef.current = undefined; + if (end === currentCount) { + onEnd?.(false); + return; + } + if (scrollEl) { + restoreScrollRef.current = getRestoreScrollData( + scrollEl.scrollTop, + getRestoreAnchor({ start, end }, getItemElement, Direction.Forward) + ); + } + end = Math.min(end + currentLimit, currentCount); + if (scrollEl) { + start = + getDropIndex(scrollEl, currentRange, Direction.Backward, getItemElement, 2) ?? start; + } + } + + onRangeChange({ + start, + end, + }); + }, + [getScrollElement, getItemElement, onEnd, onRangeChange] + ); + + const handlePaginatorElIntersection: OnIntersectionCallback = useCallback( + (entries) => { + const anchorB = entries.find( + (entry) => entry.target.getAttribute(PAGINATOR_ANCHOR_ATTR) === Direction.Backward + ); + if (anchorB?.isIntersecting) { + paginate(Direction.Backward); + } + const anchorF = entries.find( + (entry) => entry.target.getAttribute(PAGINATOR_ANCHOR_ATTR) === Direction.Forward + ); + if (anchorF?.isIntersecting) { + paginate(Direction.Forward); + } + }, + [paginate] + ); + + const intersectionObserver = useIntersectionObserver( + handlePaginatorElIntersection, + useMemo( + () => ({ + root: getScrollElement(), + }), + [getScrollElement] + ) + ); + + const observeBackAnchor = useObserveAnchorHandle(intersectionObserver, Direction.Backward); + const observeFrontAnchor = useObserveAnchorHandle(intersectionObserver, Direction.Forward); + + // Restore scroll when local pagination. + // restoreScrollRef.current only gets set + // when paginate() changes range itself + useLayoutEffect(() => { + const scrollEl = getScrollElement(); + if (!restoreScrollRef.current || !scrollEl) return; + const { + anchorOffsetTop: oldOffsetTop, + anchorItem, + scrollTop: oldScrollTop, + } = restoreScrollRef.current; + const anchorEl = getItemElement(anchorItem); + + if (!anchorEl) return; + const { offsetTop } = anchorEl; + const offsetAddition = offsetTop - oldOffsetTop; + const restoreTop = oldScrollTop + offsetAddition; + + scrollEl.scrollTo({ + top: restoreTop, + behavior: 'instant', + }); + restoreScrollRef.current = undefined; + }, [range, getScrollElement, getItemElement]); + + // When scrollToItem index was not in range. + // Scroll to item after range changes. + useLayoutEffect(() => { + if (scrollToItemRef.current === undefined) return; + const { index, opts } = scrollToItemRef.current; + scrollToItem(index, { + ...opts, + behavior: 'instant', + }); + scrollToItemRef.current = undefined; + }, [range, scrollToItem]); + + // Continue pagination to fill view height with scroll items + // check if pagination anchor are in visible view height + // and trigger pagination + useEffect(() => { + if (initialRenderRef.current) { + // Do not trigger pagination on initial render + // anchor intersection observable will trigger pagination on mount + initialRenderRef.current = false; + return; + } + const scrollElement = getScrollElement(); + if (!scrollElement) return; + const backAnchor = scrollElement.querySelector( + `[${PAGINATOR_ANCHOR_ATTR}="${Direction.Backward}"]` + ) as HTMLElement | null; + const frontAnchor = scrollElement.querySelector( + `[${PAGINATOR_ANCHOR_ATTR}="${Direction.Forward}"]` + ) as HTMLElement | null; + + if (backAnchor && isIntersectingScrollView(scrollElement, backAnchor)) { + paginate(Direction.Backward); + return; + } + if (frontAnchor && isIntersectingScrollView(scrollElement, frontAnchor)) { + paginate(Direction.Forward); + } + }, [range, getScrollElement, paginate]); + + return { + getItems, + scrollToItem, + scrollToElement, + observeBackAnchor, + observeFrontAnchor, + }; +}; diff --git a/src/app/hooks/useZoom.ts b/src/app/hooks/useZoom.ts new file mode 100644 index 000000000..018106372 --- /dev/null +++ b/src/app/hooks/useZoom.ts @@ -0,0 +1,26 @@ +import { useState } from 'react'; + +export const useZoom = (step: number, min = 0.1, max = 5) => { + const [zoom, setZoom] = useState(1); + + const zoomIn = () => { + setZoom((z) => { + const newZ = z + step; + return newZ > max ? z : newZ; + }); + }; + + const zoomOut = () => { + setZoom((z) => { + const newZ = z - step; + return newZ < min ? z : newZ; + }); + }; + + return { + zoom, + setZoom, + zoomIn, + zoomOut, + }; +}; diff --git a/src/app/organisms/room/MembersDrawer.tsx b/src/app/organisms/room/MembersDrawer.tsx index 5712c66f6..d0bb55d5d 100644 --- a/src/app/organisms/room/MembersDrawer.tsx +++ b/src/app/organisms/room/MembersDrawer.tsx @@ -10,6 +10,7 @@ import { Avatar, AvatarFallback, AvatarImage, + Badge, Box, Chip, ContainerColor, @@ -33,6 +34,7 @@ import { useVirtualizer } from '@tanstack/react-virtual'; import FocusTrap from 'focus-trap-react'; import millify from 'millify'; import classNames from 'classnames'; +import { useAtomValue } from 'jotai'; import { openInviteUser, openProfileViewer } from '../../../client/action/navigation'; import * as css from './MembersDrawer.css'; @@ -48,6 +50,10 @@ import { UseAsyncSearchOptions, useAsyncSearch } from '../../hooks/useAsyncSearc import { useDebounce } from '../../hooks/useDebounce'; import colorMXID from '../../../util/colorMXID'; import { usePowerLevelTags, PowerLevelTag } from '../../hooks/usePowerLevelTags'; +import { roomIdToTypingMembersAtom, selectRoomTypingMembersAtom } from '../../state/typingMembers'; +import { TypingIndicator } from '../../components/typing-indicator'; +import { getMemberDisplayName } from '../../utils/room'; +import { getMxIdLocalPart } from '../../utils/matrix'; export const MembershipFilters = { filterJoined: (m: RoomMember) => m.membership === Membership.Join, @@ -175,6 +181,10 @@ export function MembersDrawer({ room }: MembersDrawerProps) { }); const [onTop, setOnTop] = useState(true); + const typingMembers = useAtomValue( + useMemo(() => selectRoomTypingMembersAtom(room.roomId, roomIdToTypingMembersAtom), [room]) + ); + const filteredMembers = useMemo( () => members @@ -235,6 +245,9 @@ export function MembersDrawer({ room }: MembersDrawerProps) { { wait: 200 } ); + const getName = (member: RoomMember) => + getMemberDisplayName(room, member.userId) ?? getMxIdLocalPart(member.userId) ?? member.userId; + const handleMemberClick: MouseEventHandler = (evt) => { const btn = evt.currentTarget as HTMLButtonElement; const userId = btn.getAttribute('data-user-id'); @@ -470,6 +483,7 @@ export function MembersDrawer({ room }: MembersDrawerProps) { } const member = tagOrMember; + const name = getName(member); const avatarUrl = member.getAvatarUrl( mx.baseUrl, 100, @@ -482,7 +496,7 @@ export function MembersDrawer({ room }: MembersDrawerProps) { return ( - {member.name[0]} + {name[0]} )} } + after={ + typingMembers.find((tm) => tm.userId === member.userId) && ( + + + + ) + } > - - {member.name} - + + + {name} + + ); })} diff --git a/src/app/organisms/room/Room.jsx b/src/app/organisms/room/Room.jsx deleted file mode 100644 index 0603b985a..000000000 --- a/src/app/organisms/room/Room.jsx +++ /dev/null @@ -1,79 +0,0 @@ -import React, { useState, useEffect } from 'react'; -import './Room.scss'; -import { Line } from 'folds'; - -import initMatrix from '../../../client/initMatrix'; -import cons from '../../../client/state/cons'; -import RoomTimeline from '../../../client/state/RoomTimeline'; -import navigation from '../../../client/state/navigation'; -import { openNavigation } from '../../../client/action/navigation'; - -import Welcome from '../welcome/Welcome'; -import RoomView from './RoomView'; -import RoomSettings from './RoomSettings'; -import { MembersDrawer } from './MembersDrawer'; -import { ScreenSize, useScreenSize } from '../../hooks/useScreenSize'; -import { useSetting } from '../../state/hooks/settings'; -import { settingsAtom } from '../../state/settings'; - -function Room() { - const [roomInfo, setRoomInfo] = useState({ - room: null, - roomTimeline: null, - eventId: null, - }); - const [isDrawer] = useSetting(settingsAtom, 'isPeopleDrawer'); - const [screenSize] = useScreenSize(); - - const mx = initMatrix.matrixClient; - - useEffect(() => { - const handleRoomSelected = (rId, pRoomId, eId) => { - roomInfo.roomTimeline?.removeInternalListeners(); - const r = mx.getRoom(rId); - if (r) { - setRoomInfo({ - room: r, - roomTimeline: new RoomTimeline(rId), - eventId: eId ?? null, - }); - } else { - // TODO: add ability to join room if roomId is invalid - setRoomInfo({ - room: r, - roomTimeline: null, - eventId: null, - }); - } - }; - - navigation.on(cons.events.navigation.ROOM_SELECTED, handleRoomSelected); - return () => { - navigation.removeListener(cons.events.navigation.ROOM_SELECTED, handleRoomSelected); - }; - }, [roomInfo, mx]); - - const { room, roomTimeline, eventId } = roomInfo; - if (roomTimeline === null) { - setTimeout(() => openNavigation()); - return ; - } - - return ( -
      -
      - - -
      - - {screenSize === ScreenSize.Desktop && isDrawer && ( - <> - - - - )} -
      - ); -} - -export default Room; diff --git a/src/app/organisms/room/Room.tsx b/src/app/organisms/room/Room.tsx new file mode 100644 index 000000000..094daadc5 --- /dev/null +++ b/src/app/organisms/room/Room.tsx @@ -0,0 +1,46 @@ +import React from 'react'; +import './Room.scss'; +import { Room } from 'matrix-js-sdk'; +import { Line } from 'folds'; + +import RoomView from './RoomView'; +import RoomSettings from './RoomSettings'; +import { MembersDrawer } from './MembersDrawer'; +import { ScreenSize, useScreenSize } from '../../hooks/useScreenSize'; +import { useSetting } from '../../state/hooks/settings'; +import { settingsAtom } from '../../state/settings'; +import { PowerLevelsContextProvider, usePowerLevels } from '../../hooks/usePowerLevels'; +import { + roomIdToTypingMembersAtom, + useBindRoomIdToTypingMembersAtom, +} from '../../state/typingMembers'; + +export type RoomBaseViewProps = { + room: Room; + eventId?: string; +}; +export function RoomBaseView({ room, eventId }: RoomBaseViewProps) { + useBindRoomIdToTypingMembersAtom(room.client, roomIdToTypingMembersAtom); + + const [isDrawer] = useSetting(settingsAtom, 'isPeopleDrawer'); + const [screenSize] = useScreenSize(); + const powerLevelAPI = usePowerLevels(room); + + return ( + +
      +
      + + +
      + + {screenSize === ScreenSize.Desktop && isDrawer && ( + <> + + + + )} +
      +
      + ); +} diff --git a/src/app/organisms/room/RoomInput.tsx b/src/app/organisms/room/RoomInput.tsx index a50c80047..efef03a27 100644 --- a/src/app/organisms/room/RoomInput.tsx +++ b/src/app/organisms/room/RoomInput.tsx @@ -34,8 +34,6 @@ import to from 'await-to-js'; import { useMatrixClient } from '../../hooks/useMatrixClient'; import { CustomEditor, - EditorChangeHandler, - useEditor, Toolbar, toMatrixCustomHTML, toPlainText, @@ -102,13 +100,13 @@ import { sanitizeText } from '../../utils/sanitize'; import { useScreenSize } from '../../hooks/useScreenSize'; interface RoomInputProps { + editor: Editor; roomViewRef: RefObject; roomId: string; } export const RoomInput = forwardRef( - ({ roomViewRef, roomId }, ref) => { + ({ editor, roomViewRef, roomId }, ref) => { const mx = useMatrixClient(); - const editor = useEditor(); const room = mx.getRoom(roomId); const [msgDraft, setMsgDraft] = useAtom(roomIdToMsgDraftAtomFamily(roomId)); @@ -226,7 +224,7 @@ export const RoomInput = forwardRef( const sendPromises = uploads.map(async (upload) => { const fileItem = selectedFiles.find((f) => f.file === upload.file); if (fileItem && fileItem.file.type.startsWith('image')) { - const [imgError, imgContent] = await to(getImageMsgContent(fileItem, upload.mxc)); + const [imgError, imgContent] = await to(getImageMsgContent(mx, fileItem, upload.mxc)); if (imgError) console.warn(imgError); if (imgContent) mx.sendMessage(roomId, imgContent); return; @@ -294,7 +292,6 @@ export const RoomInput = forwardRef( const handleKeyDown: KeyboardEventHandler = useCallback( (evt) => { - const { selection } = editor; if (isHotkey('enter', evt)) { evt.preventDefault(); submit(); @@ -303,7 +300,8 @@ export const RoomInput = forwardRef( evt.preventDefault(); setReplyDraft(); } - if (selection && Range.isCollapsed(selection)) { + + if (editor.selection && Range.isCollapsed(editor.selection)) { if (isHotkey('arrowleft', evt)) { evt.preventDefault(); Transforms.move(editor, { unit: 'offset', reverse: true }); @@ -317,20 +315,19 @@ export const RoomInput = forwardRef( [submit, editor, setReplyDraft] ); - const handleChange: EditorChangeHandler = (value) => { + const handleKeyUp: KeyboardEventHandler = useCallback(() => { + const firstChildren = editor.children[0]; + if (firstChildren && Element.isElement(firstChildren)) { + const isEmpty = editor.children.length === 1 && Editor.isEmpty(editor, firstChildren); + sendTypingStatus(!isEmpty); + } + const prevWordRange = getPrevWorldRange(editor); const query = prevWordRange ? getAutocompleteQuery(editor, prevWordRange, AUTOCOMPLETE_PREFIXES) : undefined; - setAutocompleteQuery(query); - - const descendant = value[0]; - if (descendant && Element.isElement(descendant)) { - const isEmpty = value.length === 1 && Editor.isEmpty(editor, descendant); - sendTypingStatus(!isEmpty); - } - }; + }, [editor, sendTypingStatus]); const handleEmoticonSelect = (key: string, shortcode: string) => { editor.insertNode(createEmoticonElement(key, shortcode)); @@ -439,7 +436,7 @@ export const RoomInput = forwardRef( editor={editor} placeholder="Send a message..." onKeyDown={handleKeyDown} - onChange={handleChange} + onKeyUp={handleKeyUp} onPaste={handlePaste} top={ replyDraft && ( diff --git a/src/app/organisms/room/RoomTimeline.css.ts b/src/app/organisms/room/RoomTimeline.css.ts new file mode 100644 index 000000000..9cd428edc --- /dev/null +++ b/src/app/organisms/room/RoomTimeline.css.ts @@ -0,0 +1,30 @@ +import { RecipeVariants, recipe } from '@vanilla-extract/recipes'; +import { DefaultReset, config } from 'folds'; + +export const TimelineFloat = recipe({ + base: [ + DefaultReset, + { + position: 'absolute', + left: '50%', + transform: 'translateX(-50%)', + zIndex: 1, + minWidth: 'max-content', + }, + ], + variants: { + position: { + Top: { + top: config.space.S400, + }, + Bottom: { + bottom: config.space.S400, + }, + }, + }, + defaultVariants: { + position: 'Top', + }, +}); + +export type TimelineFloatVariants = RecipeVariants; diff --git a/src/app/organisms/room/RoomTimeline.tsx b/src/app/organisms/room/RoomTimeline.tsx new file mode 100644 index 000000000..03f72a372 --- /dev/null +++ b/src/app/organisms/room/RoomTimeline.tsx @@ -0,0 +1,1689 @@ +import React, { + Dispatch, + MouseEventHandler, + RefObject, + SetStateAction, + useCallback, + useEffect, + useLayoutEffect, + useMemo, + useRef, + useState, +} from 'react'; +import { + Direction, + EventTimeline, + EventTimelineSet, + EventTimelineSetHandlerMap, + EventType, + IEncryptedFile, + MatrixClient, + MatrixEvent, + RelationType, + Room, + RoomEvent, + RoomEventHandlerMap, +} from 'matrix-js-sdk'; +import parse, { HTMLReactParserOptions } from 'html-react-parser'; +import classNames from 'classnames'; +import { ReactEditor } from 'slate-react'; +import { Editor } from 'slate'; +import to from 'await-to-js'; +import { useSetAtom } from 'jotai'; +import { + Badge, + Box, + Chip, + ContainerColor, + Icon, + Icons, + Line, + Scroll, + Text, + as, + color, + config, + toRem, +} from 'folds'; +import Linkify from 'linkify-react'; +import { + decryptFile, + eventWithShortcode, + factoryEventSentBy, + getMxIdLocalPart, + isRoomId, + isUserId, + matrixEventByRecency, +} from '../../utils/matrix'; +import { sanitizeCustomHtml } from '../../utils/sanitize'; +import { useMatrixClient } from '../../hooks/useMatrixClient'; +import { useVirtualPaginator, ItemRange } from '../../hooks/useVirtualPaginator'; +import { useAlive } from '../../hooks/useAlive'; +import { scrollToBottom } from '../../utils/dom'; +import { + DefaultPlaceholder, + CompactPlaceholder, + Reply, + MessageBase, + MessageDeletedContent, + MessageBrokenContent, + MessageUnsupportedContent, + MessageEditedContent, + MessageEmptyContent, + AttachmentBox, + Attachment, + AttachmentContent, + AttachmentHeader, + Time, + MessageBadEncryptedContent, + MessageNotDecryptedContent, +} from '../../components/message'; +import { LINKIFY_OPTS, getReactCustomHtmlParser } from '../../plugins/react-custom-html-parser'; +import { + decryptAllTimelineEvent, + getMemberDisplayName, + getReactionContent, +} from '../../utils/room'; +import { useSetting } from '../../state/hooks/settings'; +import { settingsAtom } from '../../state/settings'; +import { openJoinAlias, openProfileViewer, selectRoom } from '../../../client/action/navigation'; +import { useForceUpdate } from '../../hooks/useForceUpdate'; +import { parseGeoUri, scaleYDimension } from '../../utils/common'; +import { useMatrixEventRenderer } from '../../hooks/useMatrixEventRenderer'; +import { useRoomMsgContentRenderer } from '../../hooks/useRoomMsgContentRenderer'; +import { IAudioContent, IImageContent, IVideoContent } from '../../../types/matrix/common'; +import { getBlobSafeMimeType } from '../../utils/mimeTypes'; +import { + ImageContent, + VideoContent, + FileHeader, + fileRenderer, + AudioContent, + Reactions, + EventContent, + Message, + Event, + EncryptedContent, + StickerContent, +} from './message'; +import { useMemberEventParser } from '../../hooks/useMemberEventParser'; +import * as customHtmlCss from '../../styles/CustomHtml.css'; +import { RoomIntro } from '../../components/room-intro'; +import { + OnIntersectionCallback, + getIntersectionObserverEntry, + useIntersectionObserver, +} from '../../hooks/useIntersectionObserver'; +import { markAsRead } from '../../../client/action/notifications'; +import { useDebounce } from '../../hooks/useDebounce'; +import { getResizeObserverEntry, useResizeObserver } from '../../hooks/useResizeObserver'; +import * as css from './RoomTimeline.css'; +import { inSameDay, minuteDifference, timeDayMonthYear, today, yesterday } from '../../utils/time'; +import { createMentionElement, moveCursor } from '../../components/editor'; +import { roomIdToReplyDraftAtomFamily } from '../../state/roomInputDrafts'; +import { usePowerLevelsAPI } from '../../hooks/usePowerLevels'; +import { MessageEvent } from '../../../types/matrix/room'; +import initMatrix from '../../../client/initMatrix'; + +const TimelineFloat = as<'div', css.TimelineFloatVariants>( + ({ position, className, ...props }, ref) => ( + + ) +); + +const TimelineDivider = as<'div', { variant?: ContainerColor | 'Inherit' }>( + ({ variant, children, ...props }, ref) => ( + + + {children} + + + ) +); + +export const getLiveTimeline = (room: Room): EventTimeline => + room.getUnfilteredTimelineSet().getLiveTimeline(); + +export const getEventTimeline = (room: Room, eventId: string): EventTimeline | undefined => { + const timelineSet = room.getUnfilteredTimelineSet(); + return timelineSet.getTimelineForEvent(eventId) ?? undefined; +}; + +export const getFirstLinkedTimeline = ( + timeline: EventTimeline, + direction: Direction +): EventTimeline => { + const linkedTm = timeline.getNeighbouringTimeline(direction); + if (!linkedTm) return timeline; + return getFirstLinkedTimeline(linkedTm, direction); +}; + +export const getLinkedTimelines = (timeline: EventTimeline): EventTimeline[] => { + const firstTimeline = getFirstLinkedTimeline(timeline, Direction.Backward); + const timelines = []; + + for ( + let nextTimeline: EventTimeline | null = firstTimeline; + nextTimeline; + nextTimeline = nextTimeline.getNeighbouringTimeline(Direction.Forward) + ) { + timelines.push(nextTimeline); + } + return timelines; +}; + +export const timelineToEventsCount = (t: EventTimeline) => t.getEvents().length; +export const getTimelinesEventsCount = (timelines: EventTimeline[]): number => { + const timelineEventCountReducer = (count: number, tm: EventTimeline) => + count + timelineToEventsCount(tm); + return timelines.reduce(timelineEventCountReducer, 0); +}; + +export const getTimelineAndBaseIndex = ( + timelines: EventTimeline[], + index: number +): [EventTimeline | undefined, number] => { + let uptoTimelineLen = 0; + const timeline = timelines.find((t) => { + uptoTimelineLen += t.getEvents().length; + if (index < uptoTimelineLen) return true; + return false; + }); + if (!timeline) return [undefined, 0]; + return [timeline, uptoTimelineLen - timeline.getEvents().length]; +}; + +export const getTimelineRelativeIndex = (absoluteIndex: number, timelineBaseIndex: number) => + absoluteIndex - timelineBaseIndex; + +export const getTimelineEvent = (timeline: EventTimeline, index: number): MatrixEvent | undefined => + timeline.getEvents()[index]; + +export const getEventIdAbsoluteIndex = ( + timelines: EventTimeline[], + eventTimeline: EventTimeline, + eventId: string +): number | undefined => { + const timelineIndex = timelines.findIndex((t) => t === eventTimeline); + if (timelineIndex === -1) return undefined; + const eventIndex = eventTimeline.getEvents().findIndex((evt) => evt.getId() === eventId); + if (eventIndex === -1) return undefined; + const baseIndex = timelines + .slice(0, timelineIndex) + .reduce((accValue, timeline) => timeline.getEvents().length + accValue, 0); + return baseIndex + eventIndex; +}; + +export const getEventReactions = (timelineSet: EventTimelineSet, eventId: string) => + timelineSet.relations.getChildEventsForEvent( + eventId, + RelationType.Annotation, + EventType.Reaction + ); + +export const getEventEdits = (timelineSet: EventTimelineSet, eventId: string, eventType: string) => + timelineSet.relations.getChildEventsForEvent(eventId, RelationType.Replace, eventType); + +export const getLatestEdit = ( + targetEvent: MatrixEvent, + editEvents: MatrixEvent[] +): MatrixEvent | undefined => { + const eventByTargetSender = (rEvent: MatrixEvent) => + rEvent.getSender() === targetEvent.getSender(); + return editEvents.sort(matrixEventByRecency).find(eventByTargetSender); +}; + +export const getEditedEvent = ( + mEventId: string, + mEvent: MatrixEvent, + timelineSet: EventTimelineSet +): MatrixEvent | undefined => { + const edits = getEventEdits(timelineSet, mEventId, mEvent.getType()); + return edits && getLatestEdit(mEvent, edits.getRelations()); +}; + +export const factoryGetFileSrcUrl = + (httpUrl: string, mimeType: string, encFile?: IEncryptedFile) => async (): Promise => { + if (encFile) { + if (typeof httpUrl !== 'string') throw new Error('Malformed event'); + const encRes = await fetch(httpUrl, { method: 'GET' }); + const encData = await encRes.arrayBuffer(); + const decryptedBlob = await decryptFile(encData, mimeType, encFile); + return URL.createObjectURL(decryptedBlob); + } + return httpUrl; + }; + +type RoomTimelineProps = { + room: Room; + eventId?: string; + roomInputRef: RefObject; + editor: Editor; +}; + +const PAGINATION_LIMIT = 80; + +type Timeline = { + linkedTimelines: EventTimeline[]; + range: ItemRange; +}; + +const useEventTimelineLoader = ( + mx: MatrixClient, + room: Room, + onLoad: (eventId: string, linkedTimelines: EventTimeline[], evtAbsIndex: number) => void, + onError: (err: Error | null) => void +) => { + const loadEventTimeline = useCallback( + async (eventId: string) => { + const [err, replyEvtTimeline] = await to( + mx.getEventTimeline(room.getUnfilteredTimelineSet(), eventId) + ); + if (!replyEvtTimeline) { + onError(err ?? null); + return; + } + const linkedTimelines = getLinkedTimelines(replyEvtTimeline); + const absIndex = getEventIdAbsoluteIndex(linkedTimelines, replyEvtTimeline, eventId); + + if (absIndex === undefined) { + onError(err ?? null); + return; + } + + onLoad(eventId, linkedTimelines, absIndex); + }, + [mx, room, onLoad, onError] + ); + + return loadEventTimeline; +}; + +const useTimelinePagination = ( + mx: MatrixClient, + timeline: Timeline, + setTimeline: Dispatch>, + limit: number +) => { + const timelineRef = useRef(timeline); + timelineRef.current = timeline; + const alive = useAlive(); + + const handleTimelinePagination = useMemo(() => { + let fetching = false; + + const recalibratePagination = ( + linkedTimelines: EventTimeline[], + timelinesEventsCount: number[], + backwards: boolean + ) => { + const topTimeline = linkedTimelines[0]; + const timelineMatch = (mt: EventTimeline) => (t: EventTimeline) => t === mt; + + const newLTimelines = getLinkedTimelines(topTimeline); + const topTmIndex = newLTimelines.findIndex(timelineMatch(topTimeline)); + const topAddedTm = topTmIndex === -1 ? [] : newLTimelines.slice(0, topTmIndex); + + const topTmAddedEvt = + timelineToEventsCount(newLTimelines[topTmIndex]) - timelinesEventsCount[0]; + const offsetRange = getTimelinesEventsCount(topAddedTm) + (backwards ? topTmAddedEvt : 0); + + setTimeline((currentTimeline) => ({ + linkedTimelines: newLTimelines, + range: + offsetRange > 0 + ? { + start: currentTimeline.range.start + offsetRange, + end: currentTimeline.range.end + offsetRange, + } + : { ...currentTimeline.range }, + })); + }; + + return async (backwards: boolean) => { + if (fetching) return; + const { linkedTimelines: lTimelines } = timelineRef.current; + const timelinesEventsCount = lTimelines.map(timelineToEventsCount); + + const timelineToPaginate = backwards ? lTimelines[0] : lTimelines[lTimelines.length - 1]; + if (!timelineToPaginate) return; + + const paginationToken = timelineToPaginate.getPaginationToken( + backwards ? Direction.Backward : Direction.Forward + ); + if ( + !paginationToken && + getTimelinesEventsCount(lTimelines) !== + getTimelinesEventsCount(getLinkedTimelines(timelineToPaginate)) + ) { + recalibratePagination(lTimelines, timelinesEventsCount, backwards); + return; + } + + fetching = true; + const [err] = await to( + mx.paginateEventTimeline(timelineToPaginate, { + backwards, + limit, + }) + ); + if (err) { + // TODO: handle pagination error. + return; + } + const fetchedTimeline = + timelineToPaginate.getNeighbouringTimeline( + backwards ? Direction.Backward : Direction.Forward + ) ?? timelineToPaginate; + // Decrypt all event ahead of render cycle + if (mx.isRoomEncrypted(fetchedTimeline.getRoomId() ?? '')) { + await to(decryptAllTimelineEvent(mx, fetchedTimeline)); + } + + fetching = false; + if (alive()) { + recalibratePagination(lTimelines, timelinesEventsCount, backwards); + } + }; + }, [mx, alive, setTimeline, limit]); + return handleTimelinePagination; +}; + +const useLiveEventArrive = (room: Room, onArrive: (mEvent: MatrixEvent) => void) => { + useEffect(() => { + const handleTimelineEvent: EventTimelineSetHandlerMap[RoomEvent.Timeline] = ( + mEvent, + eventRoom, + toStartOfTimeline, + removed, + data + ) => { + if (eventRoom?.roomId !== room.roomId || !data.liveEvent) return; + onArrive(mEvent); + }; + const handleRedaction: RoomEventHandlerMap[RoomEvent.Redaction] = (mEvent, eventRoom) => { + if (eventRoom?.roomId !== room.roomId) return; + onArrive(mEvent); + }; + + room.on(RoomEvent.Timeline, handleTimelineEvent); + room.on(RoomEvent.Redaction, handleRedaction); + return () => { + room.removeListener(RoomEvent.Timeline, handleTimelineEvent); + room.removeListener(RoomEvent.Redaction, handleRedaction); + }; + }, [room, onArrive]); +}; + +const useLiveTimelineRefresh = (room: Room, onRefresh: () => void) => { + useEffect(() => { + const handleTimelineRefresh: RoomEventHandlerMap[RoomEvent.TimelineRefresh] = (r) => { + if (r.roomId !== room.roomId) return; + onRefresh(); + }; + + room.on(RoomEvent.TimelineRefresh, handleTimelineRefresh); + return () => { + room.removeListener(RoomEvent.TimelineRefresh, handleTimelineRefresh); + }; + }, [room, onRefresh]); +}; + +const getInitialTimeline = (room: Room) => { + const linkedTimelines = getLinkedTimelines(getLiveTimeline(room)); + const evLength = getTimelinesEventsCount(linkedTimelines); + return { + linkedTimelines, + range: { + start: Math.max(evLength - PAGINATION_LIMIT, 0), + end: evLength, + }, + }; +}; + +const getEmptyTimeline = () => ({ + range: { start: 0, end: 0 }, + linkedTimelines: [], +}); + +const getRoomUnreadInfo = (room: Room, scrollTo = false) => { + const readUptoEventId = room.getEventReadUpTo(room.client.getUserId() ?? ''); + if (!readUptoEventId) return undefined; + const evtTimeline = getEventTimeline(room, readUptoEventId); + const latestTimeline = evtTimeline && getFirstLinkedTimeline(evtTimeline, Direction.Forward); + return { + readUptoEventId, + inLiveTimeline: latestTimeline === room.getLiveTimeline(), + scrollTo, + }; +}; + +export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimelineProps) { + const mx = useMatrixClient(); + const [messageLayout] = useSetting(settingsAtom, 'messageLayout'); + const [messageSpacing] = useSetting(settingsAtom, 'messageSpacing'); + const [hideMembershipEvents] = useSetting(settingsAtom, 'hideMembershipEvents'); + const [hideNickAvatarEvents] = useSetting(settingsAtom, 'hideNickAvatarEvents'); + const [mediaAutoLoad] = useSetting(settingsAtom, 'mediaAutoLoad'); + const [showHiddenEvents] = useSetting(settingsAtom, 'showHiddenEvents'); + const setReplyDraft = useSetAtom(roomIdToReplyDraftAtomFamily(room.roomId)); + const { canDoAction, canSendEvent, getPowerLevel } = usePowerLevelsAPI(); + const myPowerLevel = getPowerLevel(mx.getUserId() ?? ''); + const canRedact = canDoAction('redact', myPowerLevel); + const canSendReaction = canSendEvent(MessageEvent.Reaction, myPowerLevel); + + const imagePackRooms: Room[] = useMemo(() => { + const allParentSpaces = [ + room.roomId, + ...(initMatrix.roomList?.getAllParentSpaces(room.roomId) ?? []), + ]; + return allParentSpaces.reduce((list, rId) => { + const r = mx.getRoom(rId); + if (r) list.push(r); + return list; + }, []); + }, [mx, room]); + + const [unreadInfo, setUnreadInfo] = useState(() => getRoomUnreadInfo(room, true)); + const readUptoEventIdRef = useRef(); + if (unreadInfo) { + readUptoEventIdRef.current = unreadInfo.readUptoEventId; + } + + const atBottomAnchorRef = useRef(null); + const [atBottom, setAtBottom] = useState(); + const atBottomRef = useRef(atBottom); + atBottomRef.current = atBottom; + + const scrollRef = useRef(null); + const scrollToBottomRef = useRef({ + count: 0, + smooth: true, + }); + + const focusItem = useRef<{ + index: number; + scrollTo: boolean; + highlight: boolean; + }>(); + const alive = useAlive(); + const [, forceUpdate] = useForceUpdate(); + + const htmlReactParserOptions = useMemo( + () => + getReactCustomHtmlParser(mx, room, { + handleSpoilerClick: (evt) => { + const target = evt.currentTarget; + if (target.getAttribute('aria-pressed') === 'true') { + evt.stopPropagation(); + target.setAttribute('aria-pressed', 'false'); + target.style.cursor = 'initial'; + } + }, + handleMentionClick: (evt) => { + const target = evt.currentTarget; + const mentionId = target.getAttribute('data-mention-id'); + if (typeof mentionId !== 'string') return; + if (isUserId(mentionId)) { + openProfileViewer(mentionId, room.roomId); + return; + } + if (isRoomId(mentionId) && mx.getRoom(mentionId)) { + selectRoom(mentionId); + return; + } + openJoinAlias(mentionId); + }, + }), + [mx, room] + ); + const parseMemberEvent = useMemberEventParser(); + + const [timeline, setTimeline] = useState(() => + eventId ? getEmptyTimeline() : getInitialTimeline(room) + ); + const eventsLength = getTimelinesEventsCount(timeline.linkedTimelines); + const liveTimelineLinked = + timeline.linkedTimelines[timeline.linkedTimelines.length - 1] === getLiveTimeline(room); + const canPaginateBack = + typeof timeline.linkedTimelines[0]?.getPaginationToken(Direction.Backward) === 'string'; + const rangeAtStart = timeline.range.start === 0; + const rangeAtEnd = timeline.range.end === eventsLength; + + const handleTimelinePagination = useTimelinePagination( + mx, + timeline, + setTimeline, + PAGINATION_LIMIT + ); + + const getScrollElement = useCallback(() => scrollRef.current, []); + + const { getItems, scrollToItem, observeBackAnchor, observeFrontAnchor } = useVirtualPaginator({ + count: eventsLength, + limit: PAGINATION_LIMIT, + range: timeline.range, + onRangeChange: useCallback((r) => setTimeline((cs) => ({ ...cs, range: r })), []), + getScrollElement, + getItemElement: useCallback( + (index: number) => + (scrollRef.current?.querySelector(`[data-message-item="${index}"]`) as HTMLElement) ?? + undefined, + [] + ), + onEnd: handleTimelinePagination, + }); + + const loadEventTimeline = useEventTimelineLoader( + mx, + room, + useCallback( + (evtId, lTimelines, evtAbsIndex) => { + if (!alive()) return; + const evLength = getTimelinesEventsCount(lTimelines); + + focusItem.current = { + index: evtAbsIndex, + scrollTo: true, + highlight: evtId !== unreadInfo?.readUptoEventId, + }; + setTimeline({ + linkedTimelines: lTimelines, + range: { + start: Math.max(evtAbsIndex - PAGINATION_LIMIT, 0), + end: Math.min(evtAbsIndex + PAGINATION_LIMIT, evLength), + }, + }); + }, + [unreadInfo, alive] + ), + useCallback(() => { + if (!alive()) return; + setTimeline(getInitialTimeline(room)); + scrollToBottomRef.current.count += 1; + scrollToBottomRef.current.smooth = false; + }, [alive, room]) + ); + + useLiveEventArrive( + room, + useCallback( + (mEvt: MatrixEvent) => { + if (atBottomRef.current && document.hasFocus()) { + if (!unreadInfo && mEvt.getSender() !== mx.getUserId()) { + markAsRead(mEvt.getRoomId()); + } + + scrollToBottomRef.current.count += 1; + scrollToBottomRef.current.smooth = true; + setTimeline((ct) => ({ + ...ct, + range: { + start: ct.range.start + 1, + end: ct.range.end + 1, + }, + })); + return; + } + setTimeline((ct) => ({ ...ct })); + if (!unreadInfo) { + setUnreadInfo(getRoomUnreadInfo(room)); + } + }, + [mx, room, unreadInfo] + ) + ); + + useLiveTimelineRefresh( + room, + useCallback(() => { + if (liveTimelineLinked) { + setTimeline(getInitialTimeline(room)); + } + }, [room, liveTimelineLinked]) + ); + + // Stay at bottom when room editor resize + useResizeObserver( + useCallback( + (entries) => { + if (!roomInputRef.current) return; + const editorBaseEntry = getResizeObserverEntry(roomInputRef.current, entries); + const scrollElement = getScrollElement(); + if (!editorBaseEntry || !scrollElement) return; + + if (atBottomRef.current) { + scrollToBottom(scrollElement); + } + }, + [getScrollElement, roomInputRef] + ), + useCallback(() => roomInputRef.current, [roomInputRef]) + ); + + const handleAtBottomIntersection: OnIntersectionCallback = useCallback((entries) => { + const target = atBottomAnchorRef.current; + if (!target) return; + const targetEntry = getIntersectionObserverEntry(target, entries); + + setAtBottom(targetEntry?.isIntersecting === true); + }, []); + useIntersectionObserver( + useDebounce(handleAtBottomIntersection, { + wait: 200, + }), + useMemo( + () => ({ + root: getScrollElement(), + rootMargin: '100px', + }), + [getScrollElement] + ), + useCallback(() => atBottomAnchorRef.current, []) + ); + + useEffect(() => { + if (eventId) { + setTimeline(getEmptyTimeline()); + loadEventTimeline(eventId); + } + }, [eventId, loadEventTimeline]); + + // Scroll to bottom on initial timeline load + useLayoutEffect(() => { + const scrollEl = scrollRef.current; + if (scrollEl) scrollToBottom(scrollEl); + }, []); + + // Scroll to last read message if it is linked to live timeline + useLayoutEffect(() => { + const { readUptoEventId, inLiveTimeline, scrollTo } = unreadInfo ?? {}; + if (readUptoEventId && inLiveTimeline && scrollTo) { + const linkedTimelines = getLinkedTimelines(getLiveTimeline(room)); + const evtTimeline = getEventTimeline(room, readUptoEventId); + const absoluteIndex = + evtTimeline && getEventIdAbsoluteIndex(linkedTimelines, evtTimeline, readUptoEventId); + if (absoluteIndex) + scrollToItem(absoluteIndex, { + behavior: 'instant', + align: 'start', + stopInView: true, + }); + } + }, [room, unreadInfo, scrollToItem]); + + // scroll to focused message + const focusItm = focusItem.current; + useLayoutEffect(() => { + if (focusItm && focusItm.scrollTo) { + scrollToItem(focusItm.index, { + behavior: 'instant', + align: 'center', + stopInView: true, + }); + } + + focusItem.current = undefined; + }, [focusItm, scrollToItem]); + + // scroll to bottom of timeline + const scrollToBottomCount = scrollToBottomRef.current.count; + useLayoutEffect(() => { + if (scrollToBottomCount > 0) { + const scrollEl = scrollRef.current; + if (scrollEl) + scrollToBottom(scrollEl, scrollToBottomRef.current.smooth ? 'smooth' : 'instant'); + } + }, [scrollToBottomCount]); + + // send readReceipts when reach bottom + useEffect(() => { + if (liveTimelineLinked && rangeAtEnd && atBottom && document.hasFocus()) { + if (!unreadInfo) { + markAsRead(room.roomId); + return; + } + const evtTimeline = getEventTimeline(room, unreadInfo.readUptoEventId); + const latestTimeline = evtTimeline && getFirstLinkedTimeline(evtTimeline, Direction.Forward); + if (latestTimeline === room.getLiveTimeline()) { + markAsRead(); + setUnreadInfo(undefined); + } + } + }, [room, unreadInfo, liveTimelineLinked, rangeAtEnd, atBottom]); + + const handleJumpToLatest = () => { + setTimeline(getInitialTimeline(room)); + scrollToBottomRef.current.count += 1; + scrollToBottomRef.current.smooth = false; + }; + + const handleJumpToUnread = () => { + if (unreadInfo?.readUptoEventId) { + setTimeline(getEmptyTimeline()); + loadEventTimeline(unreadInfo.readUptoEventId); + } + }; + + const handleMarkAsRead = () => { + markAsRead(room.roomId); + setUnreadInfo(undefined); + }; + + const handleOpenReply: MouseEventHandler = useCallback( + async (evt) => { + const replyId = evt.currentTarget.getAttribute('data-reply-id'); + if (typeof replyId !== 'string') return; + const replyTimeline = getEventTimeline(room, replyId); + const absoluteIndex = + replyTimeline && getEventIdAbsoluteIndex(timeline.linkedTimelines, replyTimeline, replyId); + + if (typeof absoluteIndex === 'number') { + scrollToItem(absoluteIndex, { + behavior: 'smooth', + align: 'center', + stopInView: true, + }); + focusItem.current = { + index: absoluteIndex, + scrollTo: false, + highlight: true, + }; + forceUpdate(); + } else { + setTimeline(getEmptyTimeline()); + loadEventTimeline(replyId); + } + }, + [room, timeline, scrollToItem, loadEventTimeline, forceUpdate] + ); + + const handleUserClick: MouseEventHandler = useCallback( + (evt) => { + evt.preventDefault(); + evt.stopPropagation(); + const userId = evt.currentTarget.getAttribute('data-user-id'); + if (!userId) { + console.warn('Button should have "data-user-id" attribute!'); + return; + } + openProfileViewer(userId, room.roomId); + }, + [room] + ); + const handleUsernameClick: MouseEventHandler = useCallback( + (evt) => { + evt.preventDefault(); + const userId = evt.currentTarget.getAttribute('data-user-id'); + if (!userId) { + console.warn('Button should have "data-user-id" attribute!'); + return; + } + const name = getMemberDisplayName(room, userId) ?? getMxIdLocalPart(userId) ?? userId; + editor.insertNode( + createMentionElement( + userId, + name.startsWith('@') ? name : `@${name}`, + userId === mx.getUserId() + ) + ); + ReactEditor.focus(editor); + moveCursor(editor); + }, + [mx, room, editor] + ); + + const handleReplyClick: MouseEventHandler = useCallback( + (evt) => { + const replyId = evt.currentTarget.getAttribute('data-event-id'); + if (!replyId) { + console.warn('Button should have "data-event-id" attribute!'); + return; + } + const replyEvt = room.findEventById(replyId); + if (!replyEvt) return; + const editedReply = getEditedEvent(replyId, replyEvt, room.getUnfilteredTimelineSet()); + const { body, formatted_body: formattedBody }: Record = + editedReply?.getContent()['m.new.content'] ?? replyEvt.getContent(); + const senderId = replyEvt.getSender(); + if (senderId && typeof body === 'string') { + setReplyDraft({ + userId: senderId, + eventId: replyId, + body, + formattedBody, + }); + setTimeout(() => ReactEditor.focus(editor), 100); + } + }, + [room, setReplyDraft, editor] + ); + + const handleReactionToggle = useCallback( + (targetEventId: string, key: string, shortcode?: string) => { + const relations = getEventReactions(room.getUnfilteredTimelineSet(), targetEventId); + const allReactions = relations?.getSortedAnnotationsByKey() ?? []; + const [, reactionsSet] = allReactions.find(([k]) => k === key) ?? []; + const reactions = reactionsSet ? Array.from(reactionsSet) : []; + const myReaction = reactions.find(factoryEventSentBy(mx.getUserId()!)); + + if (myReaction && !!myReaction?.isRelation()) { + mx.redactEvent(room.roomId, myReaction.getId()!); + return; + } + const rShortcode = + shortcode || + (reactions.find(eventWithShortcode)?.getContent().shortcode as string | undefined); + mx.sendEvent( + room.roomId, + MessageEvent.Reaction, + getReactionContent(targetEventId, key, rShortcode) + ); + }, + [mx, room] + ); + + const renderBody = (body: string, customBody?: string) => { + if (body === '') ; + if (customBody) { + if (customBody === '') ; + return parse(sanitizeCustomHtml(customBody), htmlReactParserOptions); + } + return {body}; + }; + + const renderRoomMsgContent = useRoomMsgContentRenderer<[EventTimelineSet]>({ + renderText: (mEventId, mEvent, timelineSet) => { + const editedEvent = getEditedEvent(mEventId, mEvent, timelineSet); + const { body, formatted_body: customBody }: Record = + editedEvent?.getContent()['m.new.content'] ?? mEvent.getContent(); + + if (typeof body !== 'string') return null; + return ( + + {renderBody(body, typeof customBody === 'string' ? customBody : undefined)} + {!!editedEvent && } + + ); + }, + renderEmote: (mEventId, mEvent, timelineSet) => { + const editedEvent = getEditedEvent(mEventId, mEvent, timelineSet); + const { body, formatted_body: customBody } = + editedEvent?.getContent()['m.new.content'] ?? mEvent.getContent(); + const senderId = mEvent.getSender() ?? ''; + + const senderDisplayName = + getMemberDisplayName(room, senderId) ?? getMxIdLocalPart(senderId) ?? senderId; + return ( + + {`${senderDisplayName} `} + {renderBody(body, typeof customBody === 'string' ? customBody : undefined)} + {!!editedEvent && } + + ); + }, + renderNotice: (mEventId, mEvent, timelineSet) => { + const editedEvent = getEditedEvent(mEventId, mEvent, timelineSet); + const { body, formatted_body: customBody }: Record = + editedEvent?.getContent()['m.new.content'] ?? mEvent.getContent(); + + if (typeof body !== 'string') return null; + return ( + + {renderBody(body, typeof customBody === 'string' ? customBody : undefined)} + {!!editedEvent && } + + ); + }, + renderImage: (mEventId, mEvent) => { + const content = mEvent.getContent(); + const imgInfo = content?.info; + const mxcUrl = content.file?.url ?? content.url; + if (!imgInfo || typeof imgInfo.mimetype !== 'string' || typeof mxcUrl !== 'string') { + if (mxcUrl) { + return fileRenderer(mEventId, mEvent); + } + return null; + } + const height = scaleYDimension(imgInfo.w || 400, 400, imgInfo.h || 400); + + return ( + + + + + + ); + }, + renderVideo: (mEventId, mEvent) => { + const content = mEvent.getContent(); + + const videoInfo = content?.info; + const mxcUrl = content.file?.url ?? content.url; + const safeMimeType = getBlobSafeMimeType(videoInfo?.mimetype ?? ''); + + if (!videoInfo || !safeMimeType.startsWith('video') || typeof mxcUrl !== 'string') { + if (mxcUrl) { + return fileRenderer(mEventId, mEvent); + } + return null; + } + + const height = scaleYDimension(videoInfo.w || 400, 400, videoInfo.h || 400); + + return ( + + + + + + ); + }, + renderAudio: (mEventId, mEvent) => { + const content = mEvent.getContent(); + + const audioInfo = content?.info; + const mxcUrl = content.file?.url ?? content.url; + const safeMimeType = getBlobSafeMimeType(audioInfo?.mimetype ?? ''); + + if (!audioInfo || !safeMimeType.startsWith('audio') || typeof mxcUrl !== 'string') { + if (mxcUrl) { + return fileRenderer(mEventId, mEvent); + } + return null; + } + + return ( + + + + + + + + + + + ); + }, + renderLocation: (mEventId, mEvent) => { + const content = mEvent.getContent(); + const geoUri = content.geo_uri; + if (typeof geoUri !== 'string') return null; + const location = parseGeoUri(geoUri); + return ( + + {geoUri} + } + > + Open Location + + + ); + }, + renderFile: fileRenderer, + renderBadEncrypted: () => ( + + + + ), + renderUnsupported: (mEventId, mEvent) => { + if (mEvent.isRedacted()) { + const redactedEvt = mEvent.getRedactionEvent(); + const reason = + redactedEvt && 'content' in redactedEvt ? redactedEvt.content.reason : undefined; + + return ( + + + + ); + } + return ( + + + + ); + }, + renderBrokenFallback: (mEventId, mEvent) => { + if (mEvent.isRedacted()) { + const redactedEvt = mEvent.getRedactionEvent(); + const reason = + redactedEvt && 'content' in redactedEvt ? redactedEvt.content.reason : undefined; + return ( + + + + ); + } + return ( + + + + ); + }, + }); + + const renderMatrixEvent = useMatrixEventRenderer<[number, EventTimelineSet, boolean]>({ + renderRoomMessage: (mEventId, mEvent, item, timelineSet, collapse) => { + const reactionRelations = getEventReactions(timelineSet, mEventId); + const reactions = reactionRelations && reactionRelations.getSortedAnnotationsByKey(); + const hasReactions = reactions && reactions.length > 0; + const { replyEventId } = mEvent; + const highlighted = focusItem.current?.index === item && focusItem.current.highlight; + + return ( + + ) + } + reactions={ + reactionRelations && ( + + ) + } + > + {renderRoomMsgContent(mEventId, mEvent, timelineSet)} + + ); + }, + renderRoomEncrypted: (mEventId, mEvent, item, timelineSet, collapse) => { + const reactionRelations = getEventReactions(timelineSet, mEventId); + const reactions = reactionRelations && reactionRelations.getSortedAnnotationsByKey(); + const hasReactions = reactions && reactions.length > 0; + const { replyEventId } = mEvent; + const highlighted = focusItem.current?.index === item && focusItem.current.highlight; + + return ( + + ) + } + reactions={ + reactionRelations && ( + + ) + } + > + + {() => { + if (mEvent.getType() === MessageEvent.Sticker) + return ; + if (mEvent.getType() === MessageEvent.RoomMessage) + return renderRoomMsgContent(mEventId, mEvent, timelineSet); + if (mEvent.getType() === MessageEvent.RoomMessageEncrypted) + return ( + + + + ); + return ( + + + + ); + }} + + + ); + }, + renderSticker: (mEventId, mEvent, item, timelineSet, collapse) => { + const reactionRelations = getEventReactions(timelineSet, mEventId); + const reactions = reactionRelations && reactionRelations.getSortedAnnotationsByKey(); + const hasReactions = reactions && reactions.length > 0; + const highlighted = focusItem.current?.index === item && focusItem.current.highlight; + + return ( + + ) + } + > + + + ); + }, + renderRoomMember: (mEventId, mEvent, item) => { + const membershipChanged = + mEvent.getContent().membership !== mEvent.getPrevContent().membership; + if (membershipChanged && hideMembershipEvents) return null; + if (!membershipChanged && hideNickAvatarEvents) return null; + + const highlighted = focusItem.current?.index === item && focusItem.current.highlight; + const parsed = parseMemberEvent(mEvent); + + const timeJSX = + } + /> + + ); + }, + renderRoomName: (mEventId, mEvent, item) => { + const highlighted = focusItem.current?.index === item && focusItem.current.highlight; + const senderId = mEvent.getSender() ?? ''; + const senderName = getMemberDisplayName(room, senderId) || getMxIdLocalPart(senderId); + + const timeJSX =
      @@ -105,7 +111,6 @@ RoomView.defaultProps = { }; RoomView.propTypes = { room: PropTypes.shape({}).isRequired, - roomTimeline: PropTypes.shape({}).isRequired, eventId: PropTypes.string, }; diff --git a/src/app/organisms/room/RoomViewFollowing.css.ts b/src/app/organisms/room/RoomViewFollowing.css.ts new file mode 100644 index 000000000..0a0358e0c --- /dev/null +++ b/src/app/organisms/room/RoomViewFollowing.css.ts @@ -0,0 +1,31 @@ +import { recipe } from '@vanilla-extract/recipes'; +import { DefaultReset, color, config, toRem } from 'folds'; + +export const RoomViewFollowing = recipe({ + base: [ + DefaultReset, + { + minHeight: toRem(28), + padding: `0 ${config.space.S400}`, + width: '100%', + backgroundColor: color.Surface.Container, + color: color.Surface.OnContainer, + outline: 'none', + }, + ], + variants: { + clickable: { + true: { + cursor: 'pointer', + selectors: { + '&:hover, &:focus-visible': { + color: color.Primary.Main, + }, + '&:active': { + color: color.Primary.Main, + }, + }, + }, + }, + }, +}); diff --git a/src/app/organisms/room/RoomViewFollowing.tsx b/src/app/organisms/room/RoomViewFollowing.tsx new file mode 100644 index 000000000..cd62c429d --- /dev/null +++ b/src/app/organisms/room/RoomViewFollowing.tsx @@ -0,0 +1,141 @@ +import React, { useState } from 'react'; +import { + Box, + Icon, + Icons, + Modal, + Overlay, + OverlayBackdrop, + OverlayCenter, + Text, + as, + config, +} from 'folds'; +import { Room, RoomMember } from 'matrix-js-sdk'; +import classNames from 'classnames'; +import FocusTrap from 'focus-trap-react'; + +import { getMemberDisplayName } from '../../utils/room'; +import { getMxIdLocalPart } from '../../utils/matrix'; +import * as css from './RoomViewFollowing.css'; +import { useMatrixClient } from '../../hooks/useMatrixClient'; +import { useRoomLatestEvent } from '../../hooks/useRoomLatestEvent'; +import { useRoomEventReaders } from '../../hooks/useRoomEventReaders'; +import { EventReaders } from '../../components/event-readers'; + +export type RoomViewFollowingProps = { + room: Room; +}; +export const RoomViewFollowing = as<'div', RoomViewFollowingProps>( + ({ className, room, ...props }, ref) => { + const mx = useMatrixClient(); + const [open, setOpen] = useState(false); + const latestEvent = useRoomLatestEvent(room); + const latestEventReaders = useRoomEventReaders(room, latestEvent?.getId()); + const followingMembers = latestEventReaders + .map((readerId) => room.getMember(readerId)) + .filter((member) => member && member.userId !== mx.getUserId()) as RoomMember[]; + + const names = followingMembers.map( + (member) => getMemberDisplayName(room, member.userId) ?? getMxIdLocalPart(member.userId) + ); + + const eventId = latestEvent?.getId(); + + return ( + <> + {eventId && ( + }> + + setOpen(false), + clickOutsideDeactivates: true, + }} + > + + setOpen(false)} /> + + + + + )} + 0 ? 'button' : 'div'} + onClick={names.length > 0 ? () => setOpen(true) : undefined} + className={classNames(css.RoomViewFollowing({ clickable: names.length > 0 }), className)} + alignItems="Center" + justifyContent="End" + gap="200" + {...props} + ref={ref} + > + {names.length > 0 && ( + <> + + + {names.length === 1 && ( + <> + {names[0]} + + {' is following the conversation.'} + + + )} + {names.length === 2 && ( + <> + {names[0]} + + {' and '} + + {names[1]} + + {' are following the conversation.'} + + + )} + {names.length === 3 && ( + <> + {names[0]} + + {', '} + + {names[1]} + + {' and '} + + {names[2]} + + {' are following the conversation.'} + + + )} + {names.length > 3 && ( + <> + {names[0]} + + {', '} + + {names[1]} + + {', '} + + {names[2]} + + {' and '} + + {names.length - 3} others + + {' are following the conversation.'} + + + )} + + + )} + + + ); + } +); diff --git a/src/app/organisms/room/RoomViewTyping.css.ts b/src/app/organisms/room/RoomViewTyping.css.ts new file mode 100644 index 000000000..ef07316f2 --- /dev/null +++ b/src/app/organisms/room/RoomViewTyping.css.ts @@ -0,0 +1,24 @@ +import { keyframes, style } from '@vanilla-extract/css'; +import { DefaultReset, color, config } from 'folds'; + +const SlideUpAnime = keyframes({ + from: { + transform: 'translateY(100%)', + }, + to: { + transform: 'translateY(0)', + }, +}); + +export const RoomViewTyping = style([ + DefaultReset, + { + padding: `${config.space.S100} ${config.space.S500}`, + width: '100%', + backgroundColor: color.Surface.Container, + color: color.Surface.OnContainer, + position: 'absolute', + bottom: 0, + animation: `${SlideUpAnime} 100ms ease-in-out`, + }, +]); diff --git a/src/app/organisms/room/RoomViewTyping.tsx b/src/app/organisms/room/RoomViewTyping.tsx new file mode 100644 index 000000000..c7c15ea5b --- /dev/null +++ b/src/app/organisms/room/RoomViewTyping.tsx @@ -0,0 +1,102 @@ +import React, { useMemo } from 'react'; +import { Box, Text, as } from 'folds'; +import { Room } from 'matrix-js-sdk'; +import classNames from 'classnames'; +import { useAtomValue } from 'jotai'; +import { roomIdToTypingMembersAtom, selectRoomTypingMembersAtom } from '../../state/typingMembers'; +import { TypingIndicator } from '../../components/typing-indicator'; +import { getMemberDisplayName } from '../../utils/room'; +import { getMxIdLocalPart } from '../../utils/matrix'; +import * as css from './RoomViewTyping.css'; +import { useMatrixClient } from '../../hooks/useMatrixClient'; + +export type RoomViewTypingProps = { + room: Room; +}; +export const RoomViewTyping = as<'div', RoomViewTypingProps>( + ({ className, room, ...props }, ref) => { + const mx = useMatrixClient(); + const typingMembers = useAtomValue( + useMemo(() => selectRoomTypingMembersAtom(room.roomId, roomIdToTypingMembersAtom), [room]) + ); + + const typingNames = typingMembers + .filter((member) => member.userId !== mx.getUserId()) + .map((member) => getMemberDisplayName(room, member.userId) ?? getMxIdLocalPart(member.userId)) + .reverse(); + + if (typingNames.length === 0) { + return null; + } + + return ( + + + + {typingNames.length === 1 && ( + <> + {typingNames[0]} + + {' is typing...'} + + + )} + {typingNames.length === 2 && ( + <> + {typingNames[0]} + + {' and '} + + {typingNames[1]} + + {' are typing...'} + + + )} + {typingNames.length === 3 && ( + <> + {typingNames[0]} + + {', '} + + {typingNames[1]} + + {' and '} + + {typingNames[2]} + + {' are typing...'} + + + )} + {typingNames.length > 3 && ( + <> + {typingNames[0]} + + {', '} + + {typingNames[1]} + + {', '} + + {typingNames[2]} + + {' and '} + + {typingNames.length - 3} others + + {' are typing...'} + + + )} + + + ); + } +); diff --git a/src/app/organisms/room/message/AudioContent.tsx b/src/app/organisms/room/message/AudioContent.tsx new file mode 100644 index 000000000..b5873f352 --- /dev/null +++ b/src/app/organisms/room/message/AudioContent.tsx @@ -0,0 +1,192 @@ +/* eslint-disable jsx-a11y/media-has-caption */ +import { Badge, Chip, Icon, IconButton, Icons, ProgressBar, Spinner, Text, as, toRem } from 'folds'; +import React, { useCallback, useRef, useState } from 'react'; +import { EncryptedAttachmentInfo } from 'browser-encrypt-attachment'; +import { Range } from 'react-range'; +import { useMatrixClient } from '../../../hooks/useMatrixClient'; +import { AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback'; +import { getFileSrcUrl } from './util'; +import { IAudioInfo } from '../../../../types/matrix/common'; +import { MediaControl } from '../../../components/media'; +import { + PlayTimeCallback, + useMediaLoading, + useMediaPlay, + useMediaPlayTimeCallback, + useMediaSeek, + useMediaVolume, +} from '../../../hooks/media'; +import { useThrottle } from '../../../hooks/useThrottle'; +import { secondsToMinutesAndSeconds } from '../../../utils/common'; + +const PLAY_TIME_THROTTLE_OPS = { + wait: 500, + immediate: true, +}; + +export type AudioContentProps = { + mimeType: string; + url: string; + info: IAudioInfo; + encInfo?: EncryptedAttachmentInfo; +}; +export const AudioContent = as<'div', AudioContentProps>( + ({ mimeType, url, info, encInfo, ...props }, ref) => { + const mx = useMatrixClient(); + + const [srcState, loadSrc] = useAsyncCallback( + useCallback( + () => getFileSrcUrl(mx.mxcUrlToHttp(url) ?? '', mimeType, encInfo), + [mx, url, mimeType, encInfo] + ) + ); + + const audioRef = useRef(null); + + const [currentTime, setCurrentTime] = useState(0); + const [duration, setDuration] = useState(info.duration ?? 0); + + const getAudioRef = useCallback(() => audioRef.current, []); + const { loading } = useMediaLoading(getAudioRef); + const { playing, setPlaying } = useMediaPlay(getAudioRef); + const { seek } = useMediaSeek(getAudioRef); + const { volume, mute, setMute, setVolume } = useMediaVolume(getAudioRef); + const handlePlayTimeCallback: PlayTimeCallback = useCallback((d, ct) => { + setDuration(d); + setCurrentTime(ct); + }, []); + useMediaPlayTimeCallback( + getAudioRef, + useThrottle(handlePlayTimeCallback, PLAY_TIME_THROTTLE_OPS) + ); + + const handlePlay = () => { + if (srcState.status === AsyncStatus.Success) { + setPlaying(!playing); + } else if (srcState.status !== AsyncStatus.Loading) { + loadSrc(); + } + }; + + return ( + seek(values[0])} + renderTrack={(params) => ( +
      + {params.children} + +
      + )} + renderThumb={(params) => ( + + )} + /> + } + leftControl={ + <> + + ) : ( + + ) + } + > + {playing ? 'Pause' : 'Play'} + + + {`${secondsToMinutesAndSeconds( + currentTime + )} / ${secondsToMinutesAndSeconds(duration)}`} + + } + rightControl={ + <> + setMute(!mute)} + aria-pressed={mute} + > + + + setVolume(values[0])} + renderTrack={(params) => ( +
      + {params.children} + +
      + )} + renderThumb={(params) => ( + + )} + /> + + } + {...props} + ref={ref} + > + +
      + ); + } +); diff --git a/src/app/organisms/room/message/EncryptedContent.tsx b/src/app/organisms/room/message/EncryptedContent.tsx new file mode 100644 index 000000000..97aa9ccf9 --- /dev/null +++ b/src/app/organisms/room/message/EncryptedContent.tsx @@ -0,0 +1,22 @@ +import { MatrixEvent, MatrixEventEvent, MatrixEventHandlerMap } from 'matrix-js-sdk'; +import React, { ReactNode, useEffect, useState } from 'react'; + +type EncryptedContentProps = { + mEvent: MatrixEvent; + children: () => ReactNode; +}; + +export function EncryptedContent({ mEvent, children }: EncryptedContentProps) { + const [, setDecrypted] = useState(mEvent.isBeingDecrypted()); + + useEffect(() => { + const handleDecrypted: MatrixEventHandlerMap[MatrixEventEvent.Decrypted] = () => + setDecrypted(true); + mEvent.on(MatrixEventEvent.Decrypted, handleDecrypted); + return () => { + mEvent.removeListener(MatrixEventEvent.Decrypted, handleDecrypted); + }; + }, [mEvent]); + + return <>{children()}; +} diff --git a/src/app/organisms/room/message/EventContent.tsx b/src/app/organisms/room/message/EventContent.tsx new file mode 100644 index 000000000..e60333d08 --- /dev/null +++ b/src/app/organisms/room/message/EventContent.tsx @@ -0,0 +1,37 @@ +import { Box, Icon, IconSrc } from 'folds'; +import React, { ReactNode } from 'react'; +import { CompactLayout, ModernLayout } from '../../../components/message'; + +export type EventContentProps = { + messageLayout: number; + time: ReactNode; + iconSrc: IconSrc; + content: ReactNode; +}; +export function EventContent({ messageLayout, time, iconSrc, content }: EventContentProps) { + const beforeJSX = ( + + {messageLayout === 1 && time} + + + + + ); + + const msgContentJSX = ( + + {content} + {messageLayout !== 1 && time} + + ); + + return messageLayout === 1 ? ( + {msgContentJSX} + ) : ( + {msgContentJSX} + ); +} diff --git a/src/app/organisms/room/message/FileContent.tsx b/src/app/organisms/room/message/FileContent.tsx new file mode 100644 index 000000000..8484d8499 --- /dev/null +++ b/src/app/organisms/room/message/FileContent.tsx @@ -0,0 +1,250 @@ +import React, { useCallback, useState } from 'react'; +import { + Box, + Button, + Icon, + Icons, + Modal, + Overlay, + OverlayBackdrop, + OverlayCenter, + Spinner, + Text, + Tooltip, + TooltipProvider, + as, +} from 'folds'; +import FileSaver from 'file-saver'; +import { EncryptedAttachmentInfo } from 'browser-encrypt-attachment'; +import FocusTrap from 'focus-trap-react'; +import { IFileInfo } from '../../../../types/matrix/common'; +import { AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback'; +import { useMatrixClient } from '../../../hooks/useMatrixClient'; +import { getFileSrcUrl, getSrcFile } from './util'; +import { bytesToSize } from '../../../utils/common'; +import { TextViewer } from '../../../components/text-viewer'; +import { READABLE_TEXT_MIME_TYPES } from '../../../utils/mimeTypes'; +import { PdfViewer } from '../../../components/Pdf-viewer'; + +export type FileContentProps = { + body: string; + mimeType: string; + url: string; + info: IFileInfo; + encInfo?: EncryptedAttachmentInfo; +}; + +const renderErrorButton = (retry: () => void, text: string) => ( + + Failed to load file! + + } + position="Top" + align="Center" + > + {(triggerRef) => ( + + )} + +); + +function ReadTextFile({ body, mimeType, url, encInfo }: Omit) { + const mx = useMatrixClient(); + const [textViewer, setTextViewer] = useState(false); + + const loadSrc = useCallback( + () => getFileSrcUrl(mx.mxcUrlToHttp(url) ?? '', mimeType, encInfo), + [mx, url, mimeType, encInfo] + ); + + const [textState, loadText] = useAsyncCallback( + useCallback(async () => { + const src = await loadSrc(); + const blob = await getSrcFile(src); + const text = blob.text(); + setTextViewer(true); + return text; + }, [loadSrc]) + ); + + return ( + <> + {textState.status === AsyncStatus.Success && ( + }> + + setTextViewer(false), + clickOutsideDeactivates: true, + }} + > + + setTextViewer(false)} + /> + + + + + )} + {textState.status === AsyncStatus.Error ? ( + renderErrorButton(loadText, 'Open File') + ) : ( + + )} + + ); +} + +function ReadPdfFile({ body, mimeType, url, encInfo }: Omit) { + const mx = useMatrixClient(); + const [pdfViewer, setPdfViewer] = useState(false); + + const [pdfState, loadPdf] = useAsyncCallback( + useCallback(async () => { + const httpUrl = await getFileSrcUrl(mx.mxcUrlToHttp(url) ?? '', mimeType, encInfo); + setPdfViewer(true); + return httpUrl; + }, [mx, url, mimeType, encInfo]) + ); + + return ( + <> + {pdfState.status === AsyncStatus.Success && ( + }> + + setPdfViewer(false), + clickOutsideDeactivates: true, + }} + > + + setPdfViewer(false)} + /> + + + + + )} + {pdfState.status === AsyncStatus.Error ? ( + renderErrorButton(loadPdf, 'Open PDF') + ) : ( + + )} + + ); +} + +function DownloadFile({ body, mimeType, url, info, encInfo }: FileContentProps) { + const mx = useMatrixClient(); + + const [downloadState, download] = useAsyncCallback( + useCallback(async () => { + const httpUrl = await getFileSrcUrl(mx.mxcUrlToHttp(url) ?? '', mimeType, encInfo); + FileSaver.saveAs(httpUrl, body); + return httpUrl; + }, [mx, url, mimeType, encInfo, body]) + ); + + return downloadState.status === AsyncStatus.Error ? ( + renderErrorButton(download, `Retry Download (${bytesToSize(info.size ?? 0)})`) + ) : ( + + ); +} + +export const FileContent = as<'div', FileContentProps>( + ({ body, mimeType, url, info, encInfo, ...props }, ref) => ( + + {READABLE_TEXT_MIME_TYPES.includes(mimeType) && ( + + )} + {mimeType === 'application/pdf' && ( + + )} + + + ) +); diff --git a/src/app/organisms/room/message/FileHeader.tsx b/src/app/organisms/room/message/FileHeader.tsx new file mode 100644 index 000000000..8d523b362 --- /dev/null +++ b/src/app/organisms/room/message/FileHeader.tsx @@ -0,0 +1,22 @@ +import { Badge, Box, Text, as, toRem } from 'folds'; +import React from 'react'; +import { mimeTypeToExt } from '../../../utils/mimeTypes'; + +const badgeStyles = { maxWidth: toRem(100) }; + +export type FileHeaderProps = { + body: string; + mimeType: string; +}; +export const FileHeader = as<'div', FileHeaderProps>(({ body, mimeType, ...props }, ref) => ( + + + + {mimeTypeToExt(mimeType)} + + + + {body} + + +)); diff --git a/src/app/organisms/room/message/ImageContent.tsx b/src/app/organisms/room/message/ImageContent.tsx new file mode 100644 index 000000000..2005b3acc --- /dev/null +++ b/src/app/organisms/room/message/ImageContent.tsx @@ -0,0 +1,170 @@ +import React, { useCallback, useEffect, useState } from 'react'; +import { + Badge, + Box, + Button, + Icon, + Icons, + Modal, + Overlay, + OverlayBackdrop, + OverlayCenter, + Spinner, + Text, + Tooltip, + TooltipProvider, + as, +} from 'folds'; +import classNames from 'classnames'; +import { BlurhashCanvas } from 'react-blurhash'; +import FocusTrap from 'focus-trap-react'; +import { EncryptedAttachmentInfo } from 'browser-encrypt-attachment'; +import { IImageInfo, MATRIX_BLUR_HASH_PROPERTY_NAME } from '../../../../types/matrix/common'; +import { AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback'; +import { useMatrixClient } from '../../../hooks/useMatrixClient'; +import { getFileSrcUrl } from './util'; +import { Image } from '../../../components/media'; +import * as css from './styles.css'; +import { bytesToSize } from '../../../utils/common'; +import { ImageViewer } from '../../../components/image-viewer'; + +export type ImageContentProps = { + body: string; + mimeType: string; + url: string; + info: IImageInfo; + encInfo?: EncryptedAttachmentInfo; + autoPlay?: boolean; +}; +export const ImageContent = as<'div', ImageContentProps>( + ({ className, body, mimeType, url, info, encInfo, autoPlay, ...props }, ref) => { + const mx = useMatrixClient(); + const blurHash = info[MATRIX_BLUR_HASH_PROPERTY_NAME]; + + const [load, setLoad] = useState(false); + const [error, setError] = useState(false); + const [viewer, setViewer] = useState(false); + + const [srcState, loadSrc] = useAsyncCallback( + useCallback( + () => getFileSrcUrl(mx.mxcUrlToHttp(url) ?? '', mimeType, encInfo), + [mx, url, mimeType, encInfo] + ) + ); + + const handleLoad = () => { + setLoad(true); + }; + const handleError = () => { + setLoad(false); + setError(true); + }; + + const handleRetry = () => { + setError(false); + loadSrc(); + }; + + useEffect(() => { + if (autoPlay) loadSrc(); + }, [autoPlay, loadSrc]); + + return ( + + {srcState.status === AsyncStatus.Success && ( + }> + + setViewer(false), + clickOutsideDeactivates: true, + }} + > + + setViewer(false)} + /> + + + + + )} + {typeof blurHash === 'string' && !load && ( + + )} + {!autoPlay && srcState.status === AsyncStatus.Idle && ( + + + + )} + {srcState.status === AsyncStatus.Success && ( + + {body} setViewer(true)} + tabIndex={0} + /> + + )} + {(srcState.status === AsyncStatus.Loading || srcState.status === AsyncStatus.Success) && + !load && ( + + + + )} + {(error || srcState.status === AsyncStatus.Error) && ( + + + Failed to load image! + + } + position="Top" + align="Center" + > + {(triggerRef) => ( + + )} + + + )} + {!load && typeof info.size === 'number' && ( + + + {bytesToSize(info.size)} + + + )} + + ); + } +); diff --git a/src/app/organisms/room/message/Message.tsx b/src/app/organisms/room/message/Message.tsx new file mode 100644 index 000000000..8f25861e8 --- /dev/null +++ b/src/app/organisms/room/message/Message.tsx @@ -0,0 +1,993 @@ +import { + Avatar, + AvatarFallback, + AvatarImage, + Box, + Button, + Dialog, + Header, + Icon, + IconButton, + Icons, + Input, + Line, + Menu, + MenuItem, + Modal, + Overlay, + OverlayBackdrop, + OverlayCenter, + PopOut, + Spinner, + Text, + as, + color, + config, +} from 'folds'; +import React, { + FormEventHandler, + MouseEventHandler, + ReactNode, + useCallback, + useState, +} from 'react'; +import FocusTrap from 'focus-trap-react'; +import { MatrixEvent, Room } from 'matrix-js-sdk'; +import { Relations } from 'matrix-js-sdk/lib/models/relations'; +import classNames from 'classnames'; +import { + AvatarBase, + BubbleLayout, + CompactLayout, + MessageBase, + ModernLayout, + Time, + Username, +} from '../../../components/message'; +import colorMXID from '../../../../util/colorMXID'; +import { getMemberAvatarMxc, getMemberDisplayName } from '../../../utils/room'; +import { getMxIdLocalPart } from '../../../utils/matrix'; +import { MessageLayout, MessageSpacing } from '../../../state/settings'; +import { useMatrixClient } from '../../../hooks/useMatrixClient'; +import { useRecentEmoji } from '../../../hooks/useRecentEmoji'; +import * as css from './styles.css'; +import { EventReaders } from '../../../components/event-readers'; +import { TextViewer } from '../../../components/text-viewer'; +import { AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback'; +import { EmojiBoard } from '../../../components/emoji-board'; +import { ReactionViewer } from '../reaction-viewer'; + +export type ReactionHandler = (keyOrMxc: string, shortcode: string) => void; + +type MessageQuickReactionsProps = { + onReaction: ReactionHandler; +}; +export const MessageQuickReactions = as<'div', MessageQuickReactionsProps>( + ({ onReaction, ...props }, ref) => { + const mx = useMatrixClient(); + const recentEmojis = useRecentEmoji(mx, 4); + + if (recentEmojis.length === 0) return ; + return ( + <> + + {recentEmojis.map((emoji) => ( + onReaction(emoji.unicode, emoji.shortcode)} + > + {emoji.unicode} + + ))} + + + + ); + } +); + +export const MessageAllReactionItem = as< + 'button', + { + room: Room; + relations: Relations; + onClose?: () => void; + } +>(({ room, relations, onClose, ...props }, ref) => { + const [open, setOpen] = useState(false); + + const handleClose = () => { + setOpen(false); + onClose?.(); + }; + + return ( + <> + { + evt.stopPropagation(); + }} + open={open} + backdrop={} + > + + handleClose(), + clickOutsideDeactivates: true, + }} + > + + setOpen(false)} + /> + + + + + } + radii="300" + onClick={() => setOpen(true)} + {...props} + ref={ref} + aria-pressed={open} + > + + View Reactions + + + + ); +}); + +export const MessageReadReceiptItem = as< + 'button', + { + room: Room; + eventId: string; + onClose?: () => void; + } +>(({ room, eventId, onClose, ...props }, ref) => { + const [open, setOpen] = useState(false); + + const handleClose = () => { + setOpen(false); + onClose?.(); + }; + + return ( + <> + }> + + + + + + + + + } + radii="300" + onClick={() => setOpen(true)} + {...props} + ref={ref} + aria-pressed={open} + > + + Read Receipts + + + + ); +}); + +export const MessageSourceCodeItem = as< + 'button', + { + mEvent: MatrixEvent; + onClose?: () => void; + } +>(({ mEvent, onClose, ...props }, ref) => { + const [open, setOpen] = useState(false); + const text = JSON.stringify( + mEvent.isEncrypted() + ? { + [`<== DECRYPTED_EVENT ==>`]: mEvent.getEffectiveEvent(), + [`<== ORIGINAL_EVENT ==>`]: mEvent.event, + } + : mEvent.event, + null, + 2 + ); + + const handleClose = () => { + setOpen(false); + onClose?.(); + }; + + return ( + <> + }> + + + + + + + + + } + radii="300" + onClick={() => setOpen(true)} + {...props} + ref={ref} + aria-pressed={open} + > + + View Source + + + + ); +}); + +export const MessageDeleteItem = as< + 'button', + { + room: Room; + mEvent: MatrixEvent; + onClose?: () => void; + } +>(({ room, mEvent, onClose, ...props }, ref) => { + const mx = useMatrixClient(); + const [open, setOpen] = useState(false); + + const [deleteState, deleteMessage] = useAsyncCallback( + useCallback( + (eventId: string, reason?: string) => + mx.redactEvent(room.roomId, eventId, undefined, reason ? { reason } : undefined), + [mx, room] + ) + ); + + const handleSubmit: FormEventHandler = (evt) => { + evt.preventDefault(); + const eventId = mEvent.getId(); + if ( + !eventId || + deleteState.status === AsyncStatus.Loading || + deleteState.status === AsyncStatus.Success + ) + return; + const target = evt.target as HTMLFormElement | undefined; + const reasonInput = target?.reasonInput as HTMLInputElement | undefined; + const reason = reasonInput && reasonInput.value.trim(); + deleteMessage(eventId, reason); + }; + + const handleClose = () => { + setOpen(false); + onClose?.(); + }; + + return ( + <> + }> + + + +
      + + Delete Message + + + + +
      + + + This action is irreversible! Are you sure that you want to delete this message? + + + + Reason{' '} + + (optional) + + + + {deleteState.status === AsyncStatus.Error && ( + + Failed to delete message! Please try again. + + )} + + + +
      +
      +
      +
      + + + ); +}); + +export const MessageReportItem = as< + 'button', + { + room: Room; + mEvent: MatrixEvent; + onClose?: () => void; + } +>(({ room, mEvent, onClose, ...props }, ref) => { + const mx = useMatrixClient(); + const [open, setOpen] = useState(false); + + const [reportState, reportMessage] = useAsyncCallback( + useCallback( + (eventId: string, score: number, reason: string) => + mx.reportEvent(room.roomId, eventId, score, reason), + [mx, room] + ) + ); + + const handleSubmit: FormEventHandler = (evt) => { + evt.preventDefault(); + const eventId = mEvent.getId(); + if ( + !eventId || + reportState.status === AsyncStatus.Loading || + reportState.status === AsyncStatus.Success + ) + return; + const target = evt.target as HTMLFormElement | undefined; + const reasonInput = target?.reasonInput as HTMLInputElement | undefined; + const reason = reasonInput && reasonInput.value.trim(); + if (reasonInput) reasonInput.value = ''; + reportMessage(eventId, reason ? -100 : -50, reason || 'No reason provided'); + }; + + const handleClose = () => { + setOpen(false); + onClose?.(); + }; + + return ( + <> + }> + + + +
      + + Report Message + + + + +
      + + + Report this message to server, which may then notify the appropriate people to + take action. + + + Reason + + {reportState.status === AsyncStatus.Error && ( + + Failed to report message! Please try again. + + )} + {reportState.status === AsyncStatus.Success && ( + + Message has been reported to server. + + )} + + + +
      +
      +
      +
      + + + ); +}); + +export type MessageProps = { + room: Room; + mEvent: MatrixEvent; + collapse: boolean; + highlight: boolean; + canDelete?: boolean; + canSendReaction?: boolean; + imagePackRooms?: Room[]; + relations?: Relations; + messageLayout: MessageLayout; + messageSpacing: MessageSpacing; + onUserClick: MouseEventHandler; + onUsernameClick: MouseEventHandler; + onReplyClick: MouseEventHandler; + onReactionToggle: (targetEventId: string, key: string, shortcode?: string) => void; + reply?: ReactNode; + reactions?: ReactNode; +}; +export const Message = as<'div', MessageProps>( + ( + { + className, + room, + mEvent, + collapse, + highlight, + canDelete, + canSendReaction, + imagePackRooms, + relations, + messageLayout, + messageSpacing, + onUserClick, + onUsernameClick, + onReplyClick, + onReactionToggle, + reply, + reactions, + children, + ...props + }, + ref + ) => { + const mx = useMatrixClient(); + const senderId = mEvent.getSender() ?? ''; + const [hover, setHover] = useState(false); + const [menu, setMenu] = useState(false); + const [emojiBoard, setEmojiBoard] = useState(false); + + const senderDisplayName = + getMemberDisplayName(room, senderId) ?? getMxIdLocalPart(senderId) ?? senderId; + const senderAvatarMxc = getMemberAvatarMxc(room, senderId); + + const headerJSX = !collapse && ( + + + + {senderDisplayName} + + + + {messageLayout !== 1 && hover && ( + <> + + {senderId} + + + | + + + )} + + + ); + + const avatarJSX = !collapse && messageLayout !== 1 && ( + + + {senderAvatarMxc ? ( + + ) : ( + + {senderDisplayName[0]} + + )} + + + ); + + const msgContentJSX = ( + + {reply} + {children} + {reactions} + + ); + + const showOptions = () => setHover(true); + const hideOptions = () => setHover(false); + + const handleContextMenu: MouseEventHandler = (evt) => { + if (evt.altKey) return; + const tag = (evt.target as any).tagName; + if (typeof tag === 'string' && tag.toLowerCase() === 'a') return; + evt.preventDefault(); + setMenu(true); + }; + + const closeMenu = () => { + setMenu(false); + }; + + return ( + + {(hover || menu || emojiBoard) && ( +
      + + + {canSendReaction && ( + { + onReactionToggle(mEvent.getId()!, key); + setEmojiBoard(false); + }} + onCustomEmojiSelect={(mxc, shortcode) => { + onReactionToggle(mEvent.getId()!, mxc, shortcode); + setEmojiBoard(false); + }} + requestClose={() => { + setEmojiBoard(false); + }} + /> + } + > + {(anchorRef) => ( + setEmojiBoard(true)} + variant="SurfaceVariant" + size="300" + radii="300" + aria-pressed={emojiBoard} + > + + + )} + + )} + + + + setMenu(false), + clickOutsideDeactivates: true, + isKeyForward: (evt: KeyboardEvent) => evt.key === 'ArrowDown', + isKeyBackward: (evt: KeyboardEvent) => evt.key === 'ArrowUp', + }} + > + + {canSendReaction && ( + { + onReactionToggle(mEvent.getId()!, key, shortcode); + closeMenu(); + }} + /> + )} + + {canSendReaction && ( + } + radii="300" + onClick={() => { + closeMenu(); + // open it with timeout because closeMenu + // FocusTrap will return focus from emojiBoard + setTimeout(() => setEmojiBoard(true), 100); + }} + > + + Add Reaction + + + )} + {relations && ( + + )} + } + radii="300" + data-event-id={mEvent.getId()} + onClick={(evt: any) => { + onReplyClick(evt); + closeMenu(); + }} + > + + Reply + + + + + + {((!mEvent.isRedacted() && canDelete) || + mEvent.getSender() !== mx.getUserId()) && ( + <> + + + {!mEvent.isRedacted() && canDelete && ( + + )} + {mEvent.getSender() !== mx.getUserId() && ( + + )} + + + )} + + + } + > + {(targetRef) => ( + setMenu((v) => !v)} + aria-pressed={menu} + > + + + )} + + + +
      + )} + {messageLayout === 1 && ( + + {msgContentJSX} + + )} + {messageLayout === 2 && ( + + {headerJSX} + {msgContentJSX} + + )} + {messageLayout !== 1 && messageLayout !== 2 && ( + + {headerJSX} + {msgContentJSX} + + )} +
      + ); + } +); + +export type EventProps = { + room: Room; + mEvent: MatrixEvent; + highlight: boolean; + canDelete?: boolean; + messageSpacing: MessageSpacing; +}; +export const Event = as<'div', EventProps>( + ({ className, room, mEvent, highlight, canDelete, messageSpacing, children, ...props }, ref) => { + const mx = useMatrixClient(); + const [hover, setHover] = useState(false); + const [menu, setMenu] = useState(false); + const stateEvent = typeof mEvent.getStateKey() === 'string'; + + const showOptions = () => setHover(true); + const hideOptions = () => setHover(false); + + const handleContextMenu: MouseEventHandler = (evt) => { + if (evt.altKey) return; + const tag = (evt.target as any).tagName; + if (typeof tag === 'string' && tag.toLowerCase() === 'a') return; + evt.preventDefault(); + setMenu(true); + }; + + const closeMenu = () => { + setMenu(false); + }; + + return ( + + {(hover || menu) && ( +
      + + + setMenu(false), + clickOutsideDeactivates: true, + isKeyForward: (evt: KeyboardEvent) => evt.key === 'ArrowDown', + isKeyBackward: (evt: KeyboardEvent) => evt.key === 'ArrowUp', + }} + > + + + + + + {((!mEvent.isRedacted() && canDelete && !stateEvent) || + (mEvent.getSender() !== mx.getUserId() && !stateEvent)) && ( + <> + + + {!mEvent.isRedacted() && canDelete && ( + + )} + {mEvent.getSender() !== mx.getUserId() && ( + + )} + + + )} + + + } + > + {(targetRef) => ( + setMenu((v) => !v)} + aria-pressed={menu} + > + + + )} + + + +
      + )} +
      {children}
      +
      + ); + } +); diff --git a/src/app/organisms/room/message/Reactions.tsx b/src/app/organisms/room/message/Reactions.tsx new file mode 100644 index 000000000..354820cdc --- /dev/null +++ b/src/app/organisms/room/message/Reactions.tsx @@ -0,0 +1,133 @@ +import React, { MouseEventHandler, useCallback, useState } from 'react'; +import { + Box, + Modal, + Overlay, + OverlayBackdrop, + OverlayCenter, + Text, + Tooltip, + TooltipProvider, + as, + toRem, +} from 'folds'; +import classNames from 'classnames'; +import { EventTimelineSet, EventType, RelationType, Room } from 'matrix-js-sdk'; +import { type Relations } from 'matrix-js-sdk/lib/models/relations'; +import FocusTrap from 'focus-trap-react'; +import { useMatrixClient } from '../../../hooks/useMatrixClient'; +import { factoryEventSentBy } from '../../../utils/matrix'; +import { Reaction, ReactionTooltipMsg } from '../../../components/message'; +import { useRelations } from '../../../hooks/useRelations'; +import * as css from './styles.css'; +import { ReactionViewer } from '../reaction-viewer'; + +export const getEventReactions = (timelineSet: EventTimelineSet, eventId: string) => + timelineSet.relations.getChildEventsForEvent( + eventId, + RelationType.Annotation, + EventType.Reaction + ); + +export type ReactionsProps = { + room: Room; + mEventId: string; + canSendReaction?: boolean; + relations: Relations; + onReactionToggle: (targetEventId: string, key: string, shortcode?: string) => void; +}; +export const Reactions = as<'div', ReactionsProps>( + ({ className, room, relations, mEventId, canSendReaction, onReactionToggle, ...props }, ref) => { + const mx = useMatrixClient(); + const [viewer, setViewer] = useState(false); + const myUserId = mx.getUserId(); + const reactions = useRelations( + relations, + useCallback((rel) => [...(rel.getSortedAnnotationsByKey() ?? [])], []) + ); + + const handleViewReaction: MouseEventHandler = (evt) => { + evt.stopPropagation(); + evt.preventDefault(); + const key = evt.currentTarget.getAttribute('data-reaction-key'); + console.log(key); + if (!key) setViewer(true); + else setViewer(key); + }; + + return ( + + {reactions.map(([key, events]) => { + const rEvents = Array.from(events); + if (rEvents.length === 0) return null; + const myREvent = myUserId ? rEvents.find(factoryEventSentBy(myUserId)) : undefined; + const isPressed = !!myREvent?.getRelation(); + + return ( + + + + + + } + > + {(targetRef) => ( + onReactionToggle(mEventId, key) : undefined} + onContextMenu={handleViewReaction} + aria-disabled={!canSendReaction} + /> + )} + + ); + })} + {reactions.length > 0 && ( + { + evt.stopPropagation(); + }} + open={!!viewer} + backdrop={} + > + + setViewer(false), + clickOutsideDeactivates: true, + }} + > + + setViewer(false)} + /> + + + + + )} + + ); + } +); diff --git a/src/app/organisms/room/message/StickerContent.tsx b/src/app/organisms/room/message/StickerContent.tsx new file mode 100644 index 000000000..b6dcc6143 --- /dev/null +++ b/src/app/organisms/room/message/StickerContent.tsx @@ -0,0 +1,41 @@ +import React from 'react'; +import { as, toRem } from 'folds'; +import { MatrixEvent } from 'matrix-js-sdk'; +import { AttachmentBox, MessageBrokenContent } from '../../../components/message'; +import { ImageContent } from './ImageContent'; +import { scaleYDimension } from '../../../utils/common'; +import { IImageContent } from '../../../../types/matrix/common'; + +type StickerContentProps = { + mEvent: MatrixEvent; + autoPlay: boolean; +}; +export const StickerContent = as<'div', StickerContentProps>(({ mEvent, autoPlay, ...props }, ref) => { + const content = mEvent.getContent(); + const imgInfo = content?.info; + const mxcUrl = content.file?.url ?? content.url; + if (!imgInfo || typeof imgInfo.mimetype !== 'string' || typeof mxcUrl !== 'string') { + return ; + } + const height = scaleYDimension(imgInfo.w || 152, 152, imgInfo.h || 152); + + return ( + + + + ); +}); diff --git a/src/app/organisms/room/message/VideoContent.tsx b/src/app/organisms/room/message/VideoContent.tsx new file mode 100644 index 000000000..107d5f9ac --- /dev/null +++ b/src/app/organisms/room/message/VideoContent.tsx @@ -0,0 +1,176 @@ +import React, { useCallback, useEffect, useState } from 'react'; +import { + Badge, + Box, + Button, + Icon, + Icons, + Spinner, + Text, + Tooltip, + TooltipProvider, + as, +} from 'folds'; +import classNames from 'classnames'; +import { BlurhashCanvas } from 'react-blurhash'; +import { EncryptedAttachmentInfo } from 'browser-encrypt-attachment'; +import { + IThumbnailContent, + IVideoInfo, + MATRIX_BLUR_HASH_PROPERTY_NAME, +} from '../../../../types/matrix/common'; +import * as css from './styles.css'; +import { useMatrixClient } from '../../../hooks/useMatrixClient'; +import { AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback'; +import { getFileSrcUrl } from './util'; +import { Image, Video } from '../../../components/media'; +import { bytesToSize } from '../../../../util/common'; +import { millisecondsToMinutesAndSeconds } from '../../../utils/common'; + +export type VideoContentProps = { + body: string; + mimeType: string; + url: string; + info: IVideoInfo & IThumbnailContent; + encInfo?: EncryptedAttachmentInfo; + autoPlay?: boolean; + loadThumbnail?: boolean; +}; +export const VideoContent = as<'div', VideoContentProps>( + ({ className, body, mimeType, url, info, encInfo, autoPlay, loadThumbnail, ...props }, ref) => { + const mx = useMatrixClient(); + const blurHash = info.thumbnail_info?.[MATRIX_BLUR_HASH_PROPERTY_NAME]; + + const [load, setLoad] = useState(false); + const [error, setError] = useState(false); + + const [srcState, loadSrc] = useAsyncCallback( + useCallback( + () => getFileSrcUrl(mx.mxcUrlToHttp(url) ?? '', mimeType, encInfo), + [mx, url, mimeType, encInfo] + ) + ); + const [thumbSrcState, loadThumbSrc] = useAsyncCallback( + useCallback(() => { + const thumbInfo = info.thumbnail_info; + const thumbMxcUrl = info.thumbnail_file?.url ?? info.thumbnail_url; + if (typeof thumbMxcUrl !== 'string' || typeof thumbInfo?.mimetype !== 'string') { + throw new Error('Failed to load thumbnail'); + } + return getFileSrcUrl( + mx.mxcUrlToHttp(thumbMxcUrl) ?? '', + thumbInfo.mimetype, + info.thumbnail_file + ); + }, [mx, info]) + ); + + const handleLoad = () => { + setLoad(true); + }; + const handleError = () => { + setLoad(false); + setError(true); + }; + + const handleRetry = () => { + setError(false); + loadSrc(); + }; + + useEffect(() => { + if (autoPlay) loadSrc(); + }, [autoPlay, loadSrc]); + useEffect(() => { + if (loadThumbnail) loadThumbSrc(); + }, [loadThumbnail, loadThumbSrc]); + + return ( + + {typeof blurHash === 'string' && !load && ( + + )} + {thumbSrcState.status === AsyncStatus.Success && !load && ( + + {body} + + )} + {!autoPlay && srcState.status === AsyncStatus.Idle && ( + + + + )} + {srcState.status === AsyncStatus.Success && ( + + + )} + {(srcState.status === AsyncStatus.Loading || srcState.status === AsyncStatus.Success) && + !load && ( + + + + )} + {(error || srcState.status === AsyncStatus.Error) && ( + + + Failed to load video! + + } + position="Top" + align="Center" + > + {(triggerRef) => ( + + )} + + + )} + {!load && typeof info.size === 'number' && ( + + + {millisecondsToMinutesAndSeconds(info.duration ?? 0)} + + + {bytesToSize(info.size)} + + + )} + + ); + } +); diff --git a/src/app/organisms/room/message/fileRenderer.tsx b/src/app/organisms/room/message/fileRenderer.tsx new file mode 100644 index 000000000..5ff70b330 --- /dev/null +++ b/src/app/organisms/room/message/fileRenderer.tsx @@ -0,0 +1,45 @@ +import React from 'react'; +import { MatrixEvent } from 'matrix-js-sdk'; +import { IFileContent } from '../../../../types/matrix/common'; +import { + Attachment, + AttachmentBox, + AttachmentContent, + AttachmentHeader, +} from '../../../components/message'; +import { FileHeader } from './FileHeader'; +import { FileContent } from './FileContent'; +import { FALLBACK_MIMETYPE } from '../../../utils/mimeTypes'; + +export const fileRenderer = (mEventId: string, mEvent: MatrixEvent) => { + const content = mEvent.getContent(); + + const fileInfo = content?.info; + const mxcUrl = content.file?.url ?? content.url; + + if (typeof mxcUrl !== 'string') { + return null; + } + + return ( + + + + + + + + + + + ); +}; diff --git a/src/app/organisms/room/message/index.ts b/src/app/organisms/room/message/index.ts new file mode 100644 index 000000000..d89086164 --- /dev/null +++ b/src/app/organisms/room/message/index.ts @@ -0,0 +1,10 @@ +export * from './ImageContent'; +export * from './VideoContent'; +export * from './FileHeader'; +export * from './fileRenderer'; +export * from './AudioContent'; +export * from './Reactions'; +export * from './EventContent'; +export * from './Message'; +export * from './EncryptedContent'; +export * from './StickerContent'; diff --git a/src/app/organisms/room/message/styles.css.ts b/src/app/organisms/room/message/styles.css.ts new file mode 100644 index 000000000..1fe7fe04e --- /dev/null +++ b/src/app/organisms/room/message/styles.css.ts @@ -0,0 +1,72 @@ +import { style } from '@vanilla-extract/css'; +import { DefaultReset, config, toRem } from 'folds'; + +export const RelativeBase = style([ + DefaultReset, + { + position: 'relative', + width: '100%', + height: '100%', + }, +]); + +export const AbsoluteContainer = style([ + DefaultReset, + { + position: 'absolute', + top: 0, + left: 0, + width: '100%', + height: '100%', + }, +]); + +export const AbsoluteFooter = style([ + DefaultReset, + { + position: 'absolute', + bottom: config.space.S100, + left: config.space.S100, + right: config.space.S100, + }, +]); + +export const MessageBase = style({ + position: 'relative', +}); + +export const MessageOptionsBase = style([ + DefaultReset, + { + position: 'absolute', + top: toRem(-30), + right: 0, + zIndex: 1, + }, +]); +export const MessageOptionsBar = style([ + DefaultReset, + { + padding: config.space.S100, + }, +]); + +export const MessageQuickReaction = style({ + minWidth: toRem(32), +}); + +export const MessageMenuGroup = style({ + padding: config.space.S100, +}); + +export const MessageMenuItemText = style({ + flexGrow: 1, +}); + +export const ReactionsContainer = style({ + selectors: { + '&:empty': { + display: 'none', + }, + }, +}); diff --git a/src/app/organisms/room/message/util.ts b/src/app/organisms/room/message/util.ts new file mode 100644 index 000000000..2cc434184 --- /dev/null +++ b/src/app/organisms/room/message/util.ts @@ -0,0 +1,23 @@ +import { EncryptedAttachmentInfo } from 'browser-encrypt-attachment'; +import { decryptFile } from '../../../utils/matrix'; + +export const getFileSrcUrl = async ( + httpUrl: string, + mimeType: string, + encInfo?: EncryptedAttachmentInfo +): Promise => { + if (encInfo) { + if (typeof httpUrl !== 'string') throw new Error('Malformed event'); + const encRes = await fetch(httpUrl, { method: 'GET' }); + const encData = await encRes.arrayBuffer(); + const decryptedBlob = await decryptFile(encData, mimeType, encInfo); + return URL.createObjectURL(decryptedBlob); + } + return httpUrl; +}; + +export const getSrcFile = async (src: string): Promise => { + const res = await fetch(src, { method: 'GET' }); + const blob = await res.blob(); + return blob; +}; diff --git a/src/app/organisms/room/msgContent.ts b/src/app/organisms/room/msgContent.ts index 2b0c50edb..5b03af91b 100644 --- a/src/app/organisms/room/msgContent.ts +++ b/src/app/organisms/room/msgContent.ts @@ -1,6 +1,6 @@ import { IContent, MatrixClient, MsgType } from 'matrix-js-sdk'; import to from 'await-to-js'; -import { IThumbnailContent } from '../../../types/matrix/common'; +import { IThumbnailContent, MATRIX_BLUR_HASH_PROPERTY_NAME } from '../../../types/matrix/common'; import { getImageFileUrl, getThumbnail, @@ -11,7 +11,7 @@ import { } from '../../utils/dom'; import { encryptFile, getImageInfo, getThumbnailContent, getVideoInfo } from '../../utils/matrix'; import { TUploadItem } from '../../state/roomInputDrafts'; -import { MATRIX_BLUR_HASH_PROPERTY_NAME, encodeBlurHash } from '../../utils/blurHash'; +import { encodeBlurHash } from '../../utils/blurHash'; const generateThumbnailContent = async ( mx: MatrixClient, @@ -38,7 +38,11 @@ const generateThumbnailContent = async ( return thumbnailContent; }; -export const getImageMsgContent = async (item: TUploadItem, mxc: string): Promise => { +export const getImageMsgContent = async ( + mx: MatrixClient, + item: TUploadItem, + mxc: string +): Promise => { const { file, originalFile, encInfo } = item; const [imgError, imgEl] = await to(loadImageElement(getImageFileUrl(originalFile))); if (imgError) console.warn(imgError); @@ -48,9 +52,24 @@ export const getImageMsgContent = async (item: TUploadItem, mxc: string): Promis body: file.name, }; if (imgEl) { + const blurHash = encodeBlurHash(imgEl); + const [thumbError, thumbContent] = await to( + generateThumbnailContent( + mx, + imgEl, + getThumbnailDimensions(imgEl.width, imgEl.height), + !!encInfo + ) + ); + + if (thumbContent && thumbContent.thumbnail_info) { + thumbContent.thumbnail_info[MATRIX_BLUR_HASH_PROPERTY_NAME] = blurHash; + } + if (thumbError) console.warn(thumbError); content.info = { ...getImageInfo(imgEl, file), - [MATRIX_BLUR_HASH_PROPERTY_NAME]: encodeBlurHash(imgEl), + [MATRIX_BLUR_HASH_PROPERTY_NAME]: blurHash, + ...thumbContent, }; } if (encInfo) { @@ -87,6 +106,9 @@ export const getVideoMsgContent = async ( !!encInfo ) ); + if (thumbContent && thumbContent.thumbnail_info) { + thumbContent.thumbnail_info[MATRIX_BLUR_HASH_PROPERTY_NAME] = encodeBlurHash(videoEl); + } if (thumbError) console.warn(thumbError); content.info = { ...getVideoInfo(videoEl, file), diff --git a/src/app/organisms/room/reaction-viewer/ReactionViewer.css.ts b/src/app/organisms/room/reaction-viewer/ReactionViewer.css.ts new file mode 100644 index 000000000..a8a85b035 --- /dev/null +++ b/src/app/organisms/room/reaction-viewer/ReactionViewer.css.ts @@ -0,0 +1,31 @@ +import { style } from '@vanilla-extract/css'; +import { DefaultReset, color, config } from 'folds'; + +export const ReactionViewer = style([ + DefaultReset, + { + height: '100%', + }, +]); + +export const Sidebar = style({ + backgroundColor: color.Background.Container, + color: color.Background.OnContainer, +}); +export const SidebarContent = style({ + padding: config.space.S200, + paddingRight: 0, +}); + +export const Header = style({ + paddingLeft: config.space.S400, + paddingRight: config.space.S300, + + flexShrink: 0, + gap: config.space.S200, +}); + +export const Content = style({ + paddingLeft: config.space.S200, + paddingBottom: config.space.S400, +}); diff --git a/src/app/organisms/room/reaction-viewer/ReactionViewer.tsx b/src/app/organisms/room/reaction-viewer/ReactionViewer.tsx new file mode 100644 index 000000000..702f04a24 --- /dev/null +++ b/src/app/organisms/room/reaction-viewer/ReactionViewer.tsx @@ -0,0 +1,155 @@ +import React, { useCallback, useState } from 'react'; +import classNames from 'classnames'; +import { + Avatar, + AvatarFallback, + AvatarImage, + Box, + Header, + Icon, + IconButton, + Icons, + Line, + MenuItem, + Scroll, + Text, + as, + config, +} from 'folds'; +import { MatrixEvent, Room, RoomMember } from 'matrix-js-sdk'; +import { Relations } from 'matrix-js-sdk/lib/models/relations'; +import { getMemberDisplayName } from '../../../utils/room'; +import { eventWithShortcode, getMxIdLocalPart } from '../../../utils/matrix'; +import * as css from './ReactionViewer.css'; +import { useMatrixClient } from '../../../hooks/useMatrixClient'; +import colorMXID from '../../../../util/colorMXID'; +import { openProfileViewer } from '../../../../client/action/navigation'; +import { useRelations } from '../../../hooks/useRelations'; +import { Reaction } from '../../../components/message'; +import { getHexcodeForEmoji, getShortcodeFor } from '../../../plugins/emoji'; + +export type ReactionViewerProps = { + room: Room; + initialKey?: string; + relations: Relations; + requestClose: () => void; +}; +export const ReactionViewer = as<'div', ReactionViewerProps>( + ({ className, room, initialKey, relations, requestClose, ...props }, ref) => { + const mx = useMatrixClient(); + const reactions = useRelations( + relations, + useCallback((rel) => [...(rel.getSortedAnnotationsByKey() ?? [])], []) + ); + const [selectedKey, setSelectedKey] = useState(initialKey ?? reactions[0][0]); + + const getName = (member: RoomMember) => + getMemberDisplayName(room, member.userId) ?? getMxIdLocalPart(member.userId) ?? member.userId; + + const getReactionsForKey = (key: string): MatrixEvent[] => { + const reactSet = reactions.find(([k]) => k === key)?.[1]; + if (!reactSet) return []; + return Array.from(reactSet); + }; + + const selectedReactions = getReactionsForKey(selectedKey); + const selectedShortcode = + selectedReactions.find(eventWithShortcode)?.getContent().shortcode ?? + getShortcodeFor(getHexcodeForEmoji(selectedKey)) ?? + selectedKey; + + return ( + + + + + {reactions.map(([key, evts]) => ( + setSelectedKey(key)} + /> + ))} + + + + + +
      + + {`Reacted with :${selectedShortcode}:`} + + + + +
      + + + + + {selectedReactions.map((mEvent) => { + const senderId = mEvent.getSender(); + if (!senderId) return null; + const member = room.getMember(senderId); + if (!member) return null; + const name = getName(member); + + const avatarUrl = member.getAvatarUrl( + mx.baseUrl, + 100, + 100, + 'crop', + undefined, + false + ); + + return ( + { + requestClose(); + openProfileViewer(member.userId, room.roomId); + }} + before={ + + {avatarUrl ? ( + + ) : ( + + {name[0]} + + )} + + } + > + + + {name} + + + + ); + })} + + + +
      +
      + ); + } +); diff --git a/src/app/organisms/room/reaction-viewer/index.ts b/src/app/organisms/room/reaction-viewer/index.ts new file mode 100644 index 000000000..172e6f301 --- /dev/null +++ b/src/app/organisms/room/reaction-viewer/index.ts @@ -0,0 +1 @@ +export * from './ReactionViewer'; diff --git a/src/app/organisms/settings/Settings.jsx b/src/app/organisms/settings/Settings.jsx index a0869b615..fef158675 100644 --- a/src/app/organisms/settings/Settings.jsx +++ b/src/app/organisms/settings/Settings.jsx @@ -6,7 +6,7 @@ import cons from '../../../client/state/cons'; import settings from '../../../client/state/settings'; import navigation from '../../../client/state/navigation'; import { - toggleSystemTheme, toggleMarkdown, toggleMembershipEvents, toggleNickAvatarEvents, + toggleSystemTheme, toggleMarkdown, toggleNotifications, toggleNotificationSounds, } from '../../../client/action/settings'; import { usePermission } from '../../hooks/usePermission'; @@ -43,10 +43,21 @@ import CrossIC from '../../../../public/res/ic/outlined/cross.svg'; import CinnySVG from '../../../../public/res/svg/cinny.svg'; import { confirmDialog } from '../../molecules/confirm-dialog/ConfirmDialog'; +import { useSetting } from '../../state/hooks/settings'; +import { settingsAtom } from '../../state/settings'; function AppearanceSection() { const [, updateState] = useState({}); + const [messageLayout, setMessageLayout] = useSetting(settingsAtom, 'messageLayout'); + const [messageSpacing, setMessageSpacing] = useSetting(settingsAtom, 'messageSpacing'); + const [useSystemEmoji, setUseSystemEmoji] = useSetting(settingsAtom, 'useSystemEmoji'); + const [hideMembershipEvents, setHideMembershipEvents] = useSetting(settingsAtom, 'hideMembershipEvents'); + const [hideNickAvatarEvents, setHideNickAvatarEvents] = useSetting(settingsAtom, 'hideNickAvatarEvents'); + const [mediaAutoLoad, setMediaAutoLoad] = useSetting(settingsAtom, 'mediaAutoLoad'); + const [showHiddenEvents, setShowHiddenEvents] = useSetting(settingsAtom, 'showHiddenEvents'); + const spacings = ['0', '100', '200', '300', '400', '500'] + return (
      @@ -80,9 +91,52 @@ function AppearanceSection() { /> )} /> + setUseSystemEmoji(!useSystemEmoji)} + /> + )} + content={Use system emoji instead of Twitter emojis.} + />
      Room messages + setMessageLayout(index)} + /> + } + /> + s === messageSpacing)} + segments={[ + { text: 'No' }, + { text: 'XXS' }, + { text: 'XS' }, + { text: 'S' }, + { text: 'M' }, + { text: 'L' }, + ]} + onSelect={(index) => { + setMessageSpacing(spacings[index]) + }} + /> + } + /> { toggleMembershipEvents(); updateState({}); }} + isActive={hideMembershipEvents} + onToggle={() => setHideMembershipEvents(!hideMembershipEvents)} /> )} content={Hide membership change messages from room timeline. (Join, Leave, Invite, Kick and Ban)} @@ -107,12 +161,32 @@ function AppearanceSection() { title="Hide nick/avatar events" options={( { toggleNickAvatarEvents(); updateState({}); }} + isActive={hideNickAvatarEvents} + onToggle={() => setHideNickAvatarEvents(!hideNickAvatarEvents)} /> )} content={Hide nick and avatar change messages from room timeline.} /> + setMediaAutoLoad(!mediaAutoLoad)} + /> + )} + content={Prevent images and videos from auto loading to save bandwidth.} + /> + setShowHiddenEvents(!showHiddenEvents)} + /> + )} + content={Show hidden state and message events.} + />
      ); diff --git a/src/app/plugins/emoji.ts b/src/app/plugins/emoji.ts index 36bd044e5..2462b7ffe 100644 --- a/src/app/plugins/emoji.ts +++ b/src/app/plugins/emoji.ts @@ -1,4 +1,4 @@ -import { CompactEmoji } from 'emojibase'; +import { CompactEmoji, fromUnicodeToHexcode } from 'emojibase'; import emojisData from 'emojibase-data/en/compact.json'; import joypixels from 'emojibase-data/en/shortcodes/joypixels.json'; import emojibase from 'emojibase-data/en/shortcodes/emojibase.json'; @@ -24,6 +24,16 @@ export type IEmojiGroup = { emojis: IEmoji[]; }; +export const getShortcodesFor = (hexcode: string): string[] | string | undefined => + joypixels[hexcode] || emojibase[hexcode]; + +export const getShortcodeFor = (hexcode: string): string | undefined => { + const shortcode = joypixels[hexcode] || emojibase[hexcode]; + return Array.isArray(shortcode) ? shortcode[0] : shortcode; +}; + +export const getHexcodeForEmoji = fromUnicodeToHexcode; + export const emojiGroups: IEmojiGroup[] = [ { id: EmojiGroupId.People, @@ -86,7 +96,7 @@ function getGroupIndex(emoji: IEmoji): number | undefined { } emojisData.forEach((emoji) => { - const myShortCodes = joypixels[emoji.hexcode] || emojibase[emoji.hexcode]; + const myShortCodes = getShortcodesFor(emoji.hexcode); if (!myShortCodes) return; if (Array.isArray(myShortCodes) && myShortCodes.length === 0) return; diff --git a/src/app/plugins/pdfjs-dist.ts b/src/app/plugins/pdfjs-dist.ts new file mode 100644 index 000000000..ccdef5e54 --- /dev/null +++ b/src/app/plugins/pdfjs-dist.ts @@ -0,0 +1,47 @@ +import { useCallback } from 'react'; +import type * as PdfJsDist from 'pdfjs-dist'; +import type { GetViewportParameters } from 'pdfjs-dist/types/src/display/api'; +import { useAsyncCallback } from '../hooks/useAsyncCallback'; + +export const usePdfJSLoader = () => + useAsyncCallback( + useCallback(async () => { + const pdf = await import('pdfjs-dist'); + pdf.GlobalWorkerOptions.workerSrc = '/pdf.worker.min.js'; + return pdf; + }, []) + ); + +export const usePdfDocumentLoader = (pdfJS: typeof PdfJsDist | undefined, src: string) => + useAsyncCallback( + useCallback(async () => { + if (!pdfJS) { + throw new Error('PdfJS is not loaded'); + } + const doc = await pdfJS.getDocument(src).promise; + return doc; + }, [pdfJS, src]) + ); + +export const createPage = async ( + doc: PdfJsDist.PDFDocumentProxy, + pNo: number, + opts: GetViewportParameters +): Promise => { + const page = await doc.getPage(pNo); + const pageViewport = page.getViewport(opts); + const canvas = document.createElement('canvas'); + const context = canvas.getContext('2d'); + + if (!context) throw new Error('failed to render page.'); + + canvas.width = pageViewport.width; + canvas.height = pageViewport.height; + + page.render({ + canvasContext: context, + viewport: pageViewport, + }); + + return canvas; +}; diff --git a/src/app/plugins/react-custom-html-parser.tsx b/src/app/plugins/react-custom-html-parser.tsx new file mode 100644 index 000000000..aba5997dc --- /dev/null +++ b/src/app/plugins/react-custom-html-parser.tsx @@ -0,0 +1,274 @@ +/* eslint-disable jsx-a11y/alt-text */ +import React, { ReactEventHandler, Suspense, lazy } from 'react'; +import { + Element, + Text as DOMText, + HTMLReactParserOptions, + attributesToProps, + domToReact, +} from 'html-react-parser'; +import { MatrixClient, Room } from 'matrix-js-sdk'; +import classNames from 'classnames'; +import { Scroll, Text } from 'folds'; +import { Opts as LinkifyOpts } from 'linkifyjs'; +import Linkify from 'linkify-react'; +import { ErrorBoundary } from 'react-error-boundary'; +import * as css from '../styles/CustomHtml.css'; +import { getMxIdLocalPart, getRoomWithCanonicalAlias } from '../utils/matrix'; +import { getMemberDisplayName } from '../utils/room'; + +const ReactPrism = lazy(() => import('./react-prism/ReactPrism')); + +export const LINKIFY_OPTS: LinkifyOpts = { + attributes: { + target: '_blank', + rel: 'noreferrer noopener', + }, + validate: { + url: (value) => /^(https|http|ftp|mailto|magnet)?:/.test(value), + }, +}; + +export const getReactCustomHtmlParser = ( + mx: MatrixClient, + room: Room, + params: { + handleSpoilerClick?: ReactEventHandler; + handleMentionClick?: ReactEventHandler; + } +): HTMLReactParserOptions => { + const opts: HTMLReactParserOptions = { + replace: (domNode) => { + if (domNode instanceof Element && 'name' in domNode) { + const { name, attribs, children, parent } = domNode; + const props = attributesToProps(attribs); + + if (name === 'h1') { + return ( + + {domToReact(children, opts)} + + ); + } + + if (name === 'h2') { + return ( + + {domToReact(children, opts)} + + ); + } + + if (name === 'h3') { + return ( + + {domToReact(children, opts)} + + ); + } + + if (name === 'h4') { + return ( + + {domToReact(children, opts)} + + ); + } + + if (name === 'h5') { + return ( + + {domToReact(children, opts)} + + ); + } + + if (name === 'h6') { + return ( + + {domToReact(children, opts)} + + ); + } + + if (name === 'p') { + return ( + + {domToReact(children, opts)} + + ); + } + + if (name === 'pre') { + return ( + + +
      {domToReact(children, opts)}
      +
      +
      + ); + } + + if (name === 'blockquote') { + return ( + + {domToReact(children, opts)} + + ); + } + + if (name === 'ul') { + return ( +
        + {domToReact(children, opts)} +
      + ); + } + if (name === 'ol') { + return ( +
        + {domToReact(children, opts)} +
      + ); + } + + if (name === 'code') { + if (parent && 'name' in parent && parent.name === 'pre') { + const codeReact = domToReact(children, opts); + if (typeof codeReact === 'string') { + let lang = props.className; + if (lang === 'language-rs') lang = 'language-rust'; + return ( + {codeReact}}> + {codeReact}}> + + {(ref) => ( + + {codeReact} + + )} + + + + ); + } + } else { + return ( + + {domToReact(children, opts)} + + ); + } + } + + if (name === 'a') { + const mention = decodeURIComponent(props.href).match( + /^https?:\/\/matrix.to\/#\/((@|#|!).+:[^?/]+)/ + ); + if (mention) { + // convert mention link to pill + const mentionId = mention[1]; + const mentionPrefix = mention[2]; + if (mentionPrefix === '#' || mentionPrefix === '!') { + const mentionRoom = + mentionPrefix === '#' + ? getRoomWithCanonicalAlias(mx, mentionId) + : mx.getRoom(mentionId); + const mentionName = mentionRoom?.name; + + const mentionDisplayName = + mentionName && (mentionName.startsWith('#') ? mentionName : `#${mentionName}`); + return ( + + {mentionDisplayName ?? mentionId} + + ); + } + if (mentionPrefix === '@') + return ( + + {`@${getMemberDisplayName(room, mentionId) ?? getMxIdLocalPart(mentionId)}`} + + ); + } + } + + if (name === 'span' && 'data-mx-spoiler' in props) { + return ( + + {domToReact(children, opts)} + + ); + } + + if (name === 'img') { + const htmlSrc = mx.mxcUrlToHttp(props.src); + if (htmlSrc && props.src.startsWith('mxc://') === false) { + return ( + + {props.alt && htmlSrc} + + ); + } + if (htmlSrc && 'data-mx-emoticon' in props) { + return ( + + + + + + ); + } + if (htmlSrc) return ; + } + } + + if ( + domNode instanceof DOMText && + !(domNode.parent && 'name' in domNode.parent && domNode.parent.name === 'code') && + !(domNode.parent && 'name' in domNode.parent && domNode.parent.name === 'a') + ) { + return {domNode.data}; + } + return undefined; + }, + }; + return opts; +}; diff --git a/src/app/plugins/react-prism/ReactPrism.css b/src/app/plugins/react-prism/ReactPrism.css new file mode 100644 index 000000000..e6a121771 --- /dev/null +++ b/src/app/plugins/react-prism/ReactPrism.css @@ -0,0 +1,97 @@ +.prism-light { + --prism-comment: #0f4777; + --prism-punctuation: #6d5050; + --prism-property: #9b1144; + --prism-boolean: #4816a3; + --prism-selector: #659604; + --prism-operator: #2a2a2a; + --prism-atrule: #7e6d00; + --prism-keyword: #00829f; + --prism-regex: #9b6426; +} + +.prism-dark { + --prism-comment: #8292a2; + --prism-punctuation: #f8f8f2; + --prism-property: #f92672; + --prism-boolean: #ae81ff; + --prism-selector: #a6e22e; + --prism-operator: #f8f8f2; + --prism-atrule: #e6db74; + --prism-keyword: #66d9ef; + --prism-regex: #fd971f; +} + +code .token.comment, +code .token.prolog, +code .token.doctype, +code .token.cdata { + color: var(--prism-comment); +} + +code .token.punctuation { + color: var(--prism-punctuation); +} + +code .token.namespace { + opacity: 0.7; +} + +code .token.property, +code .token.tag, +code .token.constant, +code .token.symbol, +code .token.deleted { + color: var(--prism-property); +} + +code .token.boolean, +code .token.number { + color: var(--prism-boolean); +} + +code .token.selector, +code .token.attr-name, +code .token.string, +code .token.char, +code .token.builtin, +code .token.inserted { + color: var(--prism-selector); +} + +code .token.operator, +code .token.entity, +code .token.url, +.language-css code .token.string, +.style code .token.string, +code .token.variable { + color: var(--prism-operator); +} + +code .token.atrule, +code .token.attr-value, +code .token.function, +code .token.class-name { + color: var(--prism-atrule); +} + +code .token.keyword { + color: var(--prism-keyword); +} + +code .token.regex, +code .token.important { + color: var(--prism-regex); +} + +code .token.important, +code .token.bold { + font-weight: bold; +} +code .token.italic { + font-style: italic; +} + +code .token.entity { + cursor: help; +} diff --git a/src/app/plugins/react-prism/ReactPrism.tsx b/src/app/plugins/react-prism/ReactPrism.tsx new file mode 100644 index 000000000..1aa795483 --- /dev/null +++ b/src/app/plugins/react-prism/ReactPrism.tsx @@ -0,0 +1,35 @@ +import React, { MutableRefObject, ReactNode, useEffect, useRef } from 'react'; + +import Prism from 'prismjs'; + +import 'prismjs/components/prism-json'; +import 'prismjs/components/prism-javascript'; +import 'prismjs/components/prism-typescript'; +import 'prismjs/components/prism-css'; +import 'prismjs/components/prism-sass'; +import 'prismjs/components/prism-swift'; +import 'prismjs/components/prism-rust'; +import 'prismjs/components/prism-go'; +import 'prismjs/components/prism-c'; +import 'prismjs/components/prism-cpp'; +import 'prismjs/components/prism-java'; +import 'prismjs/components/prism-python'; + +import './ReactPrism.css'; +// we apply theme in client/state/settings.js +// using classNames .prism-dark .prism-light from ReactPrism.css + +export default function ReactPrism({ + children, +}: { + children: (ref: MutableRefObject) => ReactNode; +}) { + const codeRef = useRef(null); + + useEffect(() => { + const el = codeRef.current; + if (el) Prism.highlightElement(el); + }, []); + + return <>{children(codeRef as MutableRefObject)}; +} diff --git a/src/app/state/settings.ts b/src/app/state/settings.ts index 7739c589e..667c7c275 100644 --- a/src/app/state/settings.ts +++ b/src/app/state/settings.ts @@ -1,15 +1,22 @@ import { atom } from 'jotai'; const STORAGE_KEY = 'settings'; +export type MessageSpacing = '0' | '100' | '200' | '300' | '400' | '500'; +export type MessageLayout = 0 | 1 | 2; export interface Settings { themeIndex: number; useSystemTheme: boolean; isMarkdown: boolean; editorToolbar: boolean; isPeopleDrawer: boolean; + useSystemEmoji: boolean; + messageLayout: MessageLayout; + messageSpacing: MessageSpacing; hideMembershipEvents: boolean; hideNickAvatarEvents: boolean; + mediaAutoLoad: boolean; + showHiddenEvents: boolean; showNotifications: boolean; isNotificationSounds: boolean; @@ -21,9 +28,14 @@ const defaultSettings: Settings = { isMarkdown: true, editorToolbar: false, isPeopleDrawer: true, + useSystemEmoji: false, + messageLayout: 0, + messageSpacing: '400', hideMembershipEvents: false, hideNickAvatarEvents: true, + mediaAutoLoad: true, + showHiddenEvents: false, showNotifications: true, isNotificationSounds: true, @@ -32,7 +44,10 @@ const defaultSettings: Settings = { export const getSettings = () => { const settings = localStorage.getItem(STORAGE_KEY); if (settings === null) return defaultSettings; - return JSON.parse(settings) as Settings; + return { + ...defaultSettings, + ...(JSON.parse(settings) as Settings), + }; }; export const setSettings = (settings: Settings) => { diff --git a/src/app/state/typingMembers.ts b/src/app/state/typingMembers.ts new file mode 100644 index 000000000..b87817d19 --- /dev/null +++ b/src/app/state/typingMembers.ts @@ -0,0 +1,70 @@ +import { atom, useSetAtom } from 'jotai'; +import { selectAtom } from 'jotai/utils'; +import { + MatrixClient, + RoomMember, + RoomMemberEvent, + RoomMemberEventHandlerMap, +} from 'matrix-js-sdk'; +import { useEffect } from 'react'; + +export type IRoomIdToTypingMembers = Map; + +export type IRoomIdToTypingMembersAction = + | { + type: 'PUT'; + roomId: string; + member: RoomMember; + } + | { + type: 'DELETE'; + roomId: string; + member: RoomMember; + }; + +const baseRoomIdToTypingMembersAtom = atom(new Map()); +export const roomIdToTypingMembersAtom = atom( + (get) => get(baseRoomIdToTypingMembersAtom), + (get, set, action) => { + const roomIdToTypingMembers = get(baseRoomIdToTypingMembersAtom); + let typingMembers = roomIdToTypingMembers.get(action.roomId) ?? []; + + typingMembers = typingMembers.filter((member) => member.userId !== action.member.userId); + + if (action.type === 'PUT') { + typingMembers = [...typingMembers, action.member]; + } + roomIdToTypingMembers.set(action.roomId, typingMembers); + set(baseRoomIdToTypingMembersAtom, new Map([...roomIdToTypingMembers])); + } +); + +export const useBindRoomIdToTypingMembersAtom = ( + mx: MatrixClient, + typingMembersAtom: typeof roomIdToTypingMembersAtom +) => { + const setTypingMembers = useSetAtom(typingMembersAtom); + + useEffect(() => { + const handleTypingEvent: RoomMemberEventHandlerMap[RoomMemberEvent.Typing] = ( + event, + member + ) => { + setTypingMembers({ + type: member.typing ? 'PUT' : 'DELETE', + roomId: member.roomId, + member, + }); + }; + + mx.on(RoomMemberEvent.Typing, handleTypingEvent); + return () => { + mx.removeListener(RoomMemberEvent.Typing, handleTypingEvent); + }; + }, [mx, setTypingMembers]); +}; + +export const selectRoomTypingMembersAtom = ( + roomId: string, + typingMembersAtom: typeof roomIdToTypingMembersAtom +) => selectAtom(typingMembersAtom, (atoms) => atoms.get(roomId) ?? []); diff --git a/src/app/components/editor/Elements.css.ts b/src/app/styles/CustomHtml.css.ts similarity index 59% rename from src/app/components/editor/Elements.css.ts rename to src/app/styles/CustomHtml.css.ts index 99d037dd2..0ace90c78 100644 --- a/src/app/components/editor/Elements.css.ts +++ b/src/app/styles/CustomHtml.css.ts @@ -2,22 +2,37 @@ import { style } from '@vanilla-extract/css'; import { recipe } from '@vanilla-extract/recipes'; import { color, config, DefaultReset, toRem } from 'folds'; -const MarginBottom = style({ +export const MarginSpaced = style({ marginBottom: config.space.S200, + marginTop: config.space.S200, selectors: { + '&:first-child': { + marginTop: 0, + }, '&:last-child': { marginBottom: 0, }, }, }); -export const Paragraph = style([MarginBottom]); +export const Paragraph = style([DefaultReset]); -export const Heading = style([MarginBottom]); +export const Heading = style([ + DefaultReset, + MarginSpaced, + { + marginTop: config.space.S400, + selectors: { + '&:first-child': { + marginTop: 0, + }, + }, + }, +]); export const BlockQuote = style([ DefaultReset, - MarginBottom, + MarginSpaced, { paddingLeft: config.space.S200, borderLeft: `${config.borderWidth.B700} solid ${color.SurfaceVariant.ContainerLine}`, @@ -27,9 +42,9 @@ export const BlockQuote = style([ const BaseCode = style({ fontFamily: 'monospace', - color: color.Warning.OnContainer, - background: color.Warning.Container, - border: `${config.borderWidth.B300} solid ${color.Warning.ContainerLine}`, + color: color.Secondary.OnContainer, + background: color.Secondary.Container, + border: `${config.borderWidth.B300} solid ${color.Secondary.ContainerLine}`, borderRadius: config.radii.R300, }); @@ -40,29 +55,60 @@ export const Code = style([ padding: `0 ${config.space.S100}`, }, ]); -export const Spoiler = style([ + +export const Spoiler = recipe({ + base: [ + DefaultReset, + { + padding: `0 ${config.space.S100}`, + backgroundColor: color.SurfaceVariant.ContainerActive, + borderRadius: config.radii.R300, + selectors: { + '&[aria-pressed=true]': { + color: 'transparent', + }, + }, + }, + ], + variants: { + active: { + true: { + color: 'transparent', + }, + }, + }, +}); + +export const CodeBlock = style([ DefaultReset, + BaseCode, + MarginSpaced, { - padding: `0 ${config.space.S100}`, - backgroundColor: color.SurfaceVariant.ContainerActive, - borderRadius: config.radii.R300, + fontStyle: 'normal', }, ]); - -export const CodeBlock = style([DefaultReset, BaseCode, MarginBottom]); export const CodeBlockInternal = style({ padding: `${config.space.S200} ${config.space.S200} 0`, }); export const List = style([ DefaultReset, - MarginBottom, + MarginSpaced, { padding: `0 ${config.space.S100}`, paddingLeft: config.space.S600, }, ]); +export const Img = style([ + DefaultReset, + MarginSpaced, + { + maxWidth: toRem(296), + borderRadius: config.radii.R300, + }, +]); + export const InlineChromiumBugfix = style({ fontSize: 0, lineHeight: 0, @@ -72,9 +118,9 @@ export const Mention = recipe({ base: [ DefaultReset, { - backgroundColor: color.Secondary.Container, - color: color.Secondary.OnContainer, - boxShadow: `0 0 0 ${config.borderWidth.B300} ${color.Secondary.ContainerLine}`, + backgroundColor: color.SurfaceVariant.Container, + color: color.SurfaceVariant.OnContainer, + boxShadow: `0 0 0 ${config.borderWidth.B300} ${color.SurfaceVariant.ContainerLine}`, padding: `0 ${toRem(2)}`, borderRadius: config.radii.R300, fontWeight: config.fontWeight.W500, @@ -83,9 +129,9 @@ export const Mention = recipe({ variants: { highlight: { true: { - backgroundColor: color.Primary.Container, - color: color.Primary.OnContainer, - boxShadow: `0 0 0 ${config.borderWidth.B300} ${color.Primary.ContainerLine}`, + backgroundColor: color.Success.Container, + color: color.Success.OnContainer, + boxShadow: `0 0 0 ${config.borderWidth.B300} ${color.Success.ContainerLine}`, }, }, focus: { diff --git a/src/app/templates/client/Client.jsx b/src/app/templates/client/Client.jsx index cc9d88fa0..77db4115a 100644 --- a/src/app/templates/client/Client.jsx +++ b/src/app/templates/client/Client.jsx @@ -10,10 +10,8 @@ import Navigation from '../../organisms/navigation/Navigation'; import ContextMenu, { MenuItem } from '../../atoms/context-menu/ContextMenu'; import IconButton from '../../atoms/button/IconButton'; import ReusableContextMenu from '../../atoms/context-menu/ReusableContextMenu'; -import Room from '../../organisms/room/Room'; import Windows from '../../organisms/pw/Windows'; import Dialogs from '../../organisms/pw/Dialogs'; -import EmojiBoardOpener from '../../organisms/emoji-board/EmojiBoardOpener'; import initMatrix from '../../../client/initMatrix'; import navigation from '../../../client/state/navigation'; @@ -21,6 +19,21 @@ import cons from '../../../client/state/cons'; import VerticalMenuIC from '../../../../public/res/ic/outlined/vertical-menu.svg'; import { MatrixClientProvider } from '../../hooks/useMatrixClient'; +import { ClientContent } from './ClientContent'; +import { useSetting } from '../../state/hooks/settings'; +import { settingsAtom } from '../../state/settings'; + +function SystemEmojiFeature() { + const [systemEmoji] = useSetting(settingsAtom, 'useSystemEmoji'); + + if (systemEmoji) { + document.documentElement.style.setProperty('--font-emoji', 'Twemoji_DISABLED'); + } else { + document.documentElement.style.setProperty('--font-emoji', 'Twemoji'); + } + + return null; +} function Client() { const [isLoading, changeLoading] = useState(true); @@ -111,12 +124,12 @@ function Client() {
      - +
      - + ); diff --git a/src/app/templates/client/ClientContent.jsx b/src/app/templates/client/ClientContent.jsx new file mode 100644 index 000000000..ada7008e5 --- /dev/null +++ b/src/app/templates/client/ClientContent.jsx @@ -0,0 +1,49 @@ +import React, { useState, useEffect } from 'react'; + +import initMatrix from '../../../client/initMatrix'; +import cons from '../../../client/state/cons'; +import navigation from '../../../client/state/navigation'; +import { openNavigation } from '../../../client/action/navigation'; + +import Welcome from '../../organisms/welcome/Welcome'; +import { RoomBaseView } from '../../organisms/room/Room'; + +export function ClientContent() { + const [roomInfo, setRoomInfo] = useState({ + room: null, + eventId: null, + }); + + const mx = initMatrix.matrixClient; + + useEffect(() => { + const handleRoomSelected = (rId, pRoomId, eId) => { + roomInfo.roomTimeline?.removeInternalListeners(); + const r = mx.getRoom(rId); + if (r) { + setRoomInfo({ + room: r, + eventId: eId ?? null, + }); + } else { + setRoomInfo({ + room: null, + eventId: null, + }); + } + }; + + navigation.on(cons.events.navigation.ROOM_SELECTED, handleRoomSelected); + return () => { + navigation.removeListener(cons.events.navigation.ROOM_SELECTED, handleRoomSelected); + }; + }, [roomInfo, mx]); + + const { room, eventId } = roomInfo; + if (!room) { + setTimeout(() => openNavigation()); + return ; + } + + return ; +} diff --git a/src/app/utils/blurHash.ts b/src/app/utils/blurHash.ts index 0de5a9225..3fe1ade0e 100644 --- a/src/app/utils/blurHash.ts +++ b/src/app/utils/blurHash.ts @@ -1,15 +1,15 @@ import { encode } from 'blurhash'; -export const MATRIX_BLUR_HASH_PROPERTY_NAME = 'xyz.amorgan.blurhash'; - export const encodeBlurHash = ( img: HTMLImageElement | HTMLVideoElement, width?: number, height?: number ): string | undefined => { + const imgWidth = img instanceof HTMLVideoElement ? img.videoWidth : img.width; + const imgHeight = img instanceof HTMLVideoElement ? img.videoHeight : img.height; const canvas = document.createElement('canvas'); - canvas.width = width || img.width; - canvas.height = height || img.height; + canvas.width = width || imgWidth; + canvas.height = height || imgHeight; const context = canvas.getContext('2d'); if (!context) return undefined; diff --git a/src/app/utils/common.ts b/src/app/utils/common.ts index d3804ae8e..e007f222f 100644 --- a/src/app/utils/common.ts +++ b/src/app/utils/common.ts @@ -11,6 +11,19 @@ export const bytesToSize = (bytes: number): string => { return `${(bytes / 1000 ** sizeIndex).toFixed(1)} ${sizes[sizeIndex]}`; }; +export const millisecondsToMinutesAndSeconds = (milliseconds: number): string => { + const seconds = Math.floor(milliseconds / 1000); + const mm = Math.floor(seconds / 60); + const ss = Math.round(seconds % 60); + return `${mm}:${ss < 10 ? '0' : ''}${ss}`; +}; + +export const secondsToMinutesAndSeconds = (seconds: number): string => { + const mm = Math.floor(seconds / 60); + const ss = Math.round(seconds % 60); + return `${mm}:${ss < 10 ? '0' : ''}${ss}`; +}; + export const getFileTypeIcon = (icons: Record, fileType: string): IconSrc => { const type = fileType.toLowerCase(); if (type.startsWith('audio')) { @@ -30,3 +43,37 @@ export const fulfilledPromiseSettledResult = (prs: PromiseSettledResult[]) if (pr.status === 'fulfilled') values.push(pr.value); return values; }, []); + +export const binarySearch = (items: T[], match: (item: T) => -1 | 0 | 1): T | undefined => { + const search = (start: number, end: number): T | undefined => { + if (start > end) return undefined; + + const mid = Math.floor((start + end) / 2); + + const result = match(items[mid]); + if (result === 0) return items[mid]; + + if (result === 1) return search(start, mid - 1); + return search(mid + 1, end); + }; + + return search(0, items.length - 1); +}; + +export const randomNumberBetween = (min: number, max: number) => + Math.floor(Math.random() * (max - min + 1)) + min; + +export const scaleYDimension = (x: number, scaledX: number, y: number): number => { + const scaleFactor = scaledX / x; + return scaleFactor * y; +}; + +export const parseGeoUri = (location: string) => { + const [, data] = location.split(':'); + const [cords] = data.split(';'); + const [latitude, longitude] = cords.split(','); + return { + latitude, + longitude, + }; +}; diff --git a/src/app/utils/dom.ts b/src/app/utils/dom.ts index d717adf2e..a8dc4be2c 100644 --- a/src/app/utils/dom.ts +++ b/src/app/utils/dom.ts @@ -7,7 +7,7 @@ export const editableActiveElement = (): boolean => !!document.activeElement && /^(input)|(textarea)$/.test(document.activeElement.nodeName.toLowerCase()); -export const inVisibleScrollArea = ( +export const isIntersectingScrollView = ( scrollElement: HTMLElement, childElement: HTMLElement ): boolean => { @@ -18,10 +18,25 @@ export const inVisibleScrollArea = ( const childBottom = childTop + childElement.clientHeight; if (childTop >= scrollTop && childTop < scrollBottom) return true; - if (childTop < scrollTop && childBottom > scrollTop) return true; + if (childBottom > scrollTop && childBottom <= scrollBottom) return true; + if (childTop < scrollTop && childBottom > scrollBottom) return true; return false; }; +export const isInScrollView = (scrollElement: HTMLElement, childElement: HTMLElement): boolean => { + const scrollTop = scrollElement.offsetTop + scrollElement.scrollTop; + const scrollBottom = scrollTop + scrollElement.offsetHeight; + return ( + childElement.offsetTop >= scrollTop && + childElement.offsetTop + childElement.offsetHeight <= scrollBottom + ); +}; + +export const canFitInScrollView = ( + scrollElement: HTMLElement, + childElement: HTMLElement +): boolean => childElement.offsetHeight < scrollElement.offsetHeight; + export type FilesOrFile = T extends true ? File[] : File; export const selectFile = ( @@ -131,3 +146,43 @@ export const getThumbnail = ( resolve(thumbnail ?? undefined); }, thumbnailMimeType ?? 'image/jpeg'); }); + +export type ScrollInfo = { + offsetTop: number; + top: number; + height: number; + viewHeight: number; + scrollable: boolean; +}; +export const getScrollInfo = (target: HTMLElement): ScrollInfo => ({ + offsetTop: Math.round(target.offsetTop), + top: Math.round(target.scrollTop), + height: Math.round(target.scrollHeight), + viewHeight: Math.round(target.offsetHeight), + scrollable: target.scrollHeight > target.offsetHeight, +}); + +export const scrollToBottom = (scrollEl: HTMLElement, behavior?: 'auto' | 'instant' | 'smooth') => { + scrollEl.scrollTo({ + top: Math.round(scrollEl.scrollHeight - scrollEl.offsetHeight), + behavior, + }); +}; + +export const copyToClipboard = (text: string) => { + if (navigator.clipboard) { + navigator.clipboard.writeText(text); + } else { + const host = document.body; + const copyInput = document.createElement('input'); + copyInput.style.position = 'fixed'; + copyInput.style.opacity = '0'; + copyInput.value = text; + host.append(copyInput); + + copyInput.select(); + copyInput.setSelectionRange(0, 99999); + document.execCommand('Copy'); + copyInput.remove(); + } +}; diff --git a/src/app/utils/matrix.ts b/src/app/utils/matrix.ts index 7f2fc0f24..91bd80f39 100644 --- a/src/app/utils/matrix.ts +++ b/src/app/utils/matrix.ts @@ -1,5 +1,16 @@ -import { EncryptedAttachmentInfo, encryptAttachment } from 'browser-encrypt-attachment'; -import { MatrixClient, MatrixError, UploadProgress, UploadResponse } from 'matrix-js-sdk'; +import { + EncryptedAttachmentInfo, + decryptAttachment, + encryptAttachment, +} from 'browser-encrypt-attachment'; +import { + MatrixClient, + MatrixError, + MatrixEvent, + Room, + UploadProgress, + UploadResponse, +} from 'matrix-js-sdk'; import { IImageInfo, IThumbnailContent, IVideoInfo } from '../../types/matrix/common'; export const matchMxId = (id: string): RegExpMatchArray | null => @@ -13,6 +24,13 @@ export const getMxIdLocalPart = (userId: string): string | undefined => matchMxI export const isUserId = (id: string): boolean => validMxId(id) && id.startsWith('@'); +export const isRoomId = (id: string): boolean => validMxId(id) && id.startsWith('!'); + +export const isRoomAlias = (id: string): boolean => validMxId(id) && id.startsWith('#'); + +export const getRoomWithCanonicalAlias = (mx: MatrixClient, alias: string): Room | undefined => + mx.getRooms()?.find((room) => room.getCanonicalAlias() === alias); + export const getImageInfo = (img: HTMLImageElement, fileOrBlob: File | Blob): IImageInfo => { const info: IImageInfo = {}; info.w = img.width; @@ -24,7 +42,7 @@ export const getImageInfo = (img: HTMLImageElement, fileOrBlob: File | Blob): II export const getVideoInfo = (video: HTMLVideoElement, fileOrBlob: File | Blob): IVideoInfo => { const info: IVideoInfo = {}; - info.duration = Number.isNaN(video.duration) ? undefined : video.duration; + info.duration = Number.isNaN(video.duration) ? undefined : Math.floor(video.duration * 1000); info.w = video.videoWidth; info.h = video.videoHeight; info.mimetype = fileOrBlob.type; @@ -79,6 +97,16 @@ export const encryptFile = async ( }; }; +export const decryptFile = async ( + dataBuffer: ArrayBuffer, + type: string, + encInfo: EncryptedAttachmentInfo +): Promise => { + const dataArray = await decryptAttachment(dataBuffer, encInfo); + const blob = new Blob([dataArray], { type }); + return blob; +}; + export type TUploadContent = File | Blob; export type ContentUploadOptions = { @@ -116,3 +144,19 @@ export const uploadContent = async ( onError(new MatrixError({ error, errcode })); } }; + +export const matrixEventByRecency = (m1: MatrixEvent, m2: MatrixEvent) => m2.getTs() - m1.getTs(); + +export const factoryEventSentBy = (senderId: string) => (ev: MatrixEvent) => + ev.getSender() === senderId; + +export const eventWithShortcode = (ev: MatrixEvent) => + typeof ev.getContent().shortcode === 'string'; + +export const trimReplyFromBody = (body: string): string => { + if (body.match(/^> <.+>/) === null) return body; + + const trimmedBody = body.slice(body.indexOf('\n\n') + 2); + + return trimmedBody || body; +}; diff --git a/src/app/utils/mimeTypes.ts b/src/app/utils/mimeTypes.ts index c432bdc3c..c883ddb9b 100644 --- a/src/app/utils/mimeTypes.ts +++ b/src/app/utils/mimeTypes.ts @@ -1,17 +1,15 @@ -// https://github.com/matrix-org/matrix-react-sdk/blob/cd15e08fc285da42134817cce50de8011809cd53/src/utils/blobs.ts -export const ALLOWED_BLOB_MIMETYPES = [ +export const IMAGE_MIME_TYPES = [ 'image/jpeg', 'image/gif', 'image/png', 'image/apng', 'image/webp', 'image/avif', +]; - 'video/mp4', - 'video/webm', - 'video/ogg', - 'video/quicktime', +export const VIDEO_MIME_TYPES = ['video/mp4', 'video/webm', 'video/ogg', 'video/quicktime']; +export const AUDIO_MIME_TYPES = [ 'audio/mp4', 'audio/webm', 'audio/aac', @@ -25,11 +23,55 @@ export const ALLOWED_BLOB_MIMETYPES = [ 'audio/x-flac', ]; +export const APPLICATION_MIME_TYPES = [ + 'application/pdf', + 'application/json', + 'application/x-sh', + 'application/ecmascript', + 'application/javascript', + 'application/xhtml+xml', + 'application/xml', +]; + +export const TEXT_MIME_TYPE = [ + 'text/plain', + 'text/html', + 'text/css', + 'text/javascript', + 'text/x-c', + 'text/csv', + 'text/tab-separated-values', + 'text/yaml', + 'text/x-java-source,java', + 'text/markdown', +]; + +export const READABLE_TEXT_MIME_TYPES = [ + 'application/json', + 'application/x-sh', + 'application/ecmascript', + 'application/javascript', + 'application/xhtml+xml', + 'application/xml', + + ...TEXT_MIME_TYPE, +]; + +export const ALLOWED_BLOB_MIME_TYPES = [ + ...IMAGE_MIME_TYPES, + ...VIDEO_MIME_TYPES, + ...AUDIO_MIME_TYPES, + ...APPLICATION_MIME_TYPES, + ...TEXT_MIME_TYPE, +]; + +export const FALLBACK_MIMETYPE = 'application/octet-stream'; + export const getBlobSafeMimeType = (mimeType: string) => { - if (typeof mimeType !== 'string') return 'application/octet-stream'; + if (typeof mimeType !== 'string') return FALLBACK_MIMETYPE; const [type] = mimeType.split(';'); - if (!ALLOWED_BLOB_MIMETYPES.includes(type)) { - return 'application/octet-stream'; + if (!ALLOWED_BLOB_MIME_TYPES.includes(type)) { + return FALLBACK_MIMETYPE; } // Required for Chromium browsers if (type === 'video/quicktime') { @@ -45,3 +87,8 @@ export const safeFile = (f: File) => { } return f; }; + +export const mimeTypeToExt = (mimeType: string): string => { + const extStart = mimeType.lastIndexOf('/') + 1; + return mimeType.slice(extStart); +}; diff --git a/src/app/utils/room.ts b/src/app/utils/room.ts index daf956009..f86378337 100644 --- a/src/app/utils/room.ts +++ b/src/app/utils/room.ts @@ -1,6 +1,7 @@ import { IconName, IconSrc } from 'folds'; import { + EventTimeline, IPushRule, IPushRules, JoinRule, @@ -9,6 +10,7 @@ import { NotificationCountType, Room, } from 'matrix-js-sdk'; +import { CryptoBackend } from 'matrix-js-sdk/lib/common-crypto/CryptoBackend'; import { AccountDataEvent } from '../../types/matrix/accountData'; import { NotificationType, @@ -263,3 +265,35 @@ export const parseReplyFormattedBody = ( return `
      ${replyToLink}${userLink}
      ${formattedBody}
      `; }; + +export const getMemberDisplayName = (room: Room, userId: string): string | undefined => { + const member = room.getMember(userId); + const name = member?.rawDisplayName; + if (name === userId) return undefined; + return name; +}; + +export const getMemberAvatarMxc = (room: Room, userId: string): string | undefined => { + const member = room.getMember(userId); + return member?.getMxcAvatarUrl(); +}; + +export const decryptAllTimelineEvent = async (mx: MatrixClient, timeline: EventTimeline) => { + const crypto = mx.getCrypto(); + if (!crypto) return; + const decryptionPromises = timeline + .getEvents() + .filter((event) => event.isEncrypted()) + .reverse() + .map((event) => event.attemptDecryption(crypto as CryptoBackend, { isRetry: true })); + await Promise.allSettled(decryptionPromises); +}; + +export const getReactionContent = (eventId: string, key: string, shortcode?: string) => ({ + 'm.relates_to': { + event_id: eventId, + key, + rel_type: 'm.annotation', + }, + shortcode, +}); diff --git a/src/app/utils/sanitize.ts b/src/app/utils/sanitize.ts index 555089de2..6a03ca7d5 100644 --- a/src/app/utils/sanitize.ts +++ b/src/app/utils/sanitize.ts @@ -1,3 +1,145 @@ +import sanitizeHtml, { Transformer } from 'sanitize-html'; + +const MAX_TAG_NESTING = 100; + +const permittedHtmlTags = [ + 'font', + 'del', + 'h1', + 'h2', + 'h3', + 'h4', + 'h5', + 'h6', + 'blockquote', + 'p', + 'a', + 'ul', + 'ol', + 'sup', + 'sub', + 'li', + 'b', + 'i', + 'u', + 'strong', + 'em', + 'strike', + 's', + 'code', + 'hr', + 'br', + 'div', + 'table', + 'thead', + 'tbody', + 'tr', + 'th', + 'td', + 'caption', + 'pre', + 'span', + 'img', + 'details', + 'summary', +]; + +const urlSchemes = ['https', 'http', 'ftp', 'mailto', 'magnet']; + +const permittedTagToAttributes = { + font: ['style', 'data-mx-bg-color', 'data-mx-color', 'color'], + span: [ + 'style', + 'data-mx-bg-color', + 'data-mx-color', + 'data-mx-spoiler', + 'data-mx-maths', + 'data-mx-pill', + 'data-mx-ping', + ], + div: ['data-mx-maths'], + a: ['name', 'target', 'href', 'rel'], + img: ['width', 'height', 'alt', 'title', 'src', 'data-mx-emoticon'], + ol: ['start'], + code: ['class'], +}; + +const transformFontTag: Transformer = (tagName, attribs) => ({ + tagName, + attribs: { + ...attribs, + style: `background-color: ${attribs['data-mx-bg-color']}; color: ${attribs['data-mx-color']}`, + }, +}); + +const transformSpanTag: Transformer = (tagName, attribs) => ({ + tagName, + attribs: { + ...attribs, + style: `background-color: ${attribs['data-mx-bg-color']}; color: ${attribs['data-mx-color']}`, + }, +}); + +const transformATag: Transformer = (tagName, attribs) => ({ + tagName, + attribs: { + ...attribs, + rel: 'noopener', + target: '_blank', + }, +}); + +const transformImgTag: Transformer = (tagName, attribs) => { + const { src } = attribs; + if (src.startsWith('mxc://') === false) { + return { + tagName: 'a', + attribs: { + href: src, + rel: 'noopener', + target: '_blank', + }, + text: attribs.alt || src, + }; + } + return { + tagName, + attribs: { + ...attribs, + }, + }; +}; + +export const sanitizeCustomHtml = (customHtml: string): string => + sanitizeHtml(customHtml, { + allowedTags: permittedHtmlTags, + allowedAttributes: permittedTagToAttributes, + disallowedTagsMode: 'discard', + allowedSchemes: urlSchemes, + allowedSchemesByTag: { + a: urlSchemes, + }, + allowedSchemesAppliedToAttributes: ['href'], + allowProtocolRelative: false, + allowedClasses: { + code: ['language-*'], + }, + allowedStyles: { + '*': { + color: [/^#(?:[0-9a-fA-F]{3}){1,2}$/], + 'background-color': [/^#(?:[0-9a-fA-F]{3}){1,2}$/], + }, + }, + transformTags: { + font: transformFontTag, + span: transformSpanTag, + a: transformATag, + img: transformImgTag, + }, + nonTextTags: ['style', 'script', 'textarea', 'option', 'noscript', 'mx-reply'], + nestingLimit: MAX_TAG_NESTING, + }); + export const sanitizeText = (body: string) => { const tagsToReplace: Record = { '&': '&', diff --git a/src/app/utils/time.ts b/src/app/utils/time.ts new file mode 100644 index 000000000..3ee6720c0 --- /dev/null +++ b/src/app/utils/time.ts @@ -0,0 +1,35 @@ +import dayjs from 'dayjs'; +import isToday from 'dayjs/plugin/isToday'; +import isYesterday from 'dayjs/plugin/isYesterday'; + +dayjs.extend(isToday); +dayjs.extend(isYesterday); + +export const today = (ts: number): boolean => dayjs(ts).isToday(); + +export const yesterday = (ts: number): boolean => dayjs(ts).isYesterday(); + +export const timeHourMinute = (ts: number): string => dayjs(ts).format('hh:mm A'); + +export const timeDayMonYear = (ts: number): string => dayjs(ts).format('D MMM YYYY'); + +export const timeDayMonthYear = (ts: number): string => dayjs(ts).format('D MMMM YYYY'); + +export const inSameDay = (ts1: number, ts2: number): boolean => { + const dt1 = new Date(ts1); + const dt2 = new Date(ts2); + return ( + dt2.getFullYear() === dt1.getFullYear() && + dt2.getMonth() === dt1.getMonth() && + dt2.getDate() === dt1.getDate() + ); +}; + +export const minuteDifference = (ts1: number, ts2: number): number => { + const dt1 = new Date(ts1); + const dt2 = new Date(ts2); + + let diff = (dt2.getTime() - dt1.getTime()) / 1000; + diff /= 60; + return Math.abs(Math.round(diff)); +}; diff --git a/src/client/state/settings.js b/src/client/state/settings.js index af2e279ad..cc1193cef 100644 --- a/src/client/state/settings.js +++ b/src/client/state/settings.js @@ -59,6 +59,8 @@ class Settings extends EventEmitter { this.themes.forEach((themeName, index) => { if (themeName !== '') document.body.classList.remove(themeName); document.body.classList.remove(this.themeClasses[index]); + document.body.classList.remove('prism-light') + document.body.classList.remove('prism-dark') }); } @@ -69,6 +71,7 @@ class Settings extends EventEmitter { if (this.themes[themeIndex] === undefined) return if (this.themes[themeIndex]) document.body.classList.add(this.themes[themeIndex]); document.body.classList.add(this.themeClasses[themeIndex]); + document.body.classList.add(themeIndex < 2 ? 'prism-light' : 'prism-dark'); } setTheme(themeIndex) { diff --git a/src/ext.d.ts b/src/ext.d.ts index 55f59327c..5593b6e7b 100644 --- a/src/ext.d.ts +++ b/src/ext.d.ts @@ -20,4 +20,9 @@ declare module 'browser-encrypt-attachment' { } export function encryptAttachment(dataBuffer: ArrayBuffer): Promise; + + export function decryptAttachment( + dataBuffer: ArrayBuffer, + info: EncryptedAttachmentInfo + ): Promise; } diff --git a/src/index.scss b/src/index.scss index 93443fe91..04125a1ca 100644 --- a/src/index.scss +++ b/src/index.scss @@ -210,14 +210,14 @@ .dark-theme, .butter-theme { /* background color | --bg-[background type]: value */ - --bg-surface: hsl(208, 8%, 20%); - --bg-surface-transparent: hsla(208, 8%, 20%, 0); - --bg-surface-low: hsl(208, 8%, 16%); - --bg-surface-low-transparent: hsla(208, 8%, 16%, 0); - --bg-surface-extra-low: hsl(208, 8%, 14%); - --bg-surface-extra-low-transparent: hsla(208, 8%, 14%, 0); - --bg-surface-hover: rgba(255, 255, 255, 3%); - --bg-surface-active: rgba(255, 255, 255, 5%); + --bg-surface: #1f2326; + --bg-surface-transparent: #1f232600; + --bg-surface-low: #15171a; + --bg-surface-low-transparent: #15171a00; + --bg-surface-extra-low: #15171a; + --bg-surface-extra-low-transparent: #15171a00; + --bg-surface-hover: #1f2326; + --bg-surface-active: #2a2e33; --bg-surface-border: rgba(0, 0, 0, 20%); --bg-primary: rgb(42, 98, 166); diff --git a/src/types/matrix/common.ts b/src/types/matrix/common.ts index 94a46a90a..cc20d453c 100644 --- a/src/types/matrix/common.ts +++ b/src/types/matrix/common.ts @@ -1,16 +1,35 @@ import { EncryptedAttachmentInfo } from 'browser-encrypt-attachment'; +import { MsgType } from 'matrix-js-sdk'; + +export const MATRIX_BLUR_HASH_PROPERTY_NAME = 'xyz.amorgan.blurhash'; export type IImageInfo = { w?: number; h?: number; mimetype?: string; size?: number; + [MATRIX_BLUR_HASH_PROPERTY_NAME]?: string; }; -export type IVideoInfo = IImageInfo & { +export type IVideoInfo = { + w?: number; + h?: number; + mimetype?: string; + size?: number; duration?: number; }; +export type IAudioInfo = { + mimetype?: string; + size?: number; + duration?: number; +}; + +export type IFileInfo = { + mimetype?: string; + size?: number; +}; + export type IEncryptedFile = EncryptedAttachmentInfo & { url: string; }; @@ -20,3 +39,42 @@ export type IThumbnailContent = { thumbnail_file?: IEncryptedFile; thumbnail_url?: string; }; + +export type IImageContent = { + msgtype: MsgType.Image; + body?: string; + url?: string; + info?: IImageInfo & IThumbnailContent; + file?: IEncryptedFile; +}; + +export type IVideoContent = { + msgtype: MsgType.Video; + body?: string; + url?: string; + info?: IVideoInfo & IThumbnailContent; + file?: IEncryptedFile; +}; + +export type IAudioContent = { + msgtype: MsgType.Audio; + body?: string; + url?: string; + info?: IAudioInfo; + file?: IEncryptedFile; +}; + +export type IFileContent = { + msgtype: MsgType.File; + body?: string; + url?: string; + info?: IFileInfo & IThumbnailContent; + file?: IEncryptedFile; +}; + +export type ILocationContent = { + msgtype: MsgType.Location; + body?: string; + geo_uri?: string; + info?: IThumbnailContent; +}; diff --git a/src/types/matrix/room.ts b/src/types/matrix/room.ts index 93e876152..33419ce5d 100644 --- a/src/types/matrix/room.ts +++ b/src/types/matrix/room.ts @@ -6,6 +6,14 @@ export enum Membership { Ban = 'ban', } +export type IMemberContent = { + avatar_url?: string; + displayname?: string; + membership?: Membership; + reason?: string; + is_direct?: boolean; +}; + export enum StateEvent { RoomCanonicalAlias = 'm.room.canonical_alias', RoomCreate = 'm.room.create', @@ -29,6 +37,14 @@ export enum StateEvent { PoniesRoomEmotes = 'im.ponies.room_emotes', } +export enum MessageEvent { + RoomMessage = 'm.room.message', + RoomMessageEncrypted = 'm.room.encrypted', + Sticker = 'm.sticker', + RoomRedaction = 'm.room.redaction', + Reaction = 'm.reaction', +} + export enum RoomType { Space = 'm.space', } @@ -40,6 +56,17 @@ export enum NotificationType { Mute = 'mute', } +export type IRoomCreateContent = { + creator?: string; + ['m.federate']?: boolean; + room_version: string; + type?: string; + predecessor?: { + event_id: string; + room_id: string; + }; +}; + export type RoomToParents = Map>; export type RoomToUnread = Map< string, diff --git a/tsconfig.json b/tsconfig.json index 02eb1843b..d2f1e8a10 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,6 +3,7 @@ "sourceMap": true, "jsx": "react", "target": "ES2016", + "module": "ES2020", "allowJs": true, "strict": true, "esModuleInterop": true, diff --git a/vite.config.js b/vite.config.js index f09aa71e8..835733984 100644 --- a/vite.config.js +++ b/vite.config.js @@ -13,6 +13,10 @@ const copyFiles = { src: 'node_modules/@matrix-org/olm/olm.wasm', dest: '', }, + { + src: 'node_modules/pdfjs-dist/build/pdf.worker.min.js', + dest: '', + }, { src: '_redirects', dest: '', From f9b895b32c0b42b56966db4e2529a5e219d0eb99 Mon Sep 17 00:00:00 2001 From: Cadence Ember Date: Fri, 6 Oct 2023 15:48:48 +1300 Subject: [PATCH 1055/1531] Prompt to send command as message (#1435) --- src/app/organisms/room/RoomViewInput.jsx | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/app/organisms/room/RoomViewInput.jsx b/src/app/organisms/room/RoomViewInput.jsx index c43eb6016..3fb780a4d 100644 --- a/src/app/organisms/room/RoomViewInput.jsx +++ b/src/app/organisms/room/RoomViewInput.jsx @@ -206,28 +206,36 @@ function RoomViewInput({ if (replyTo !== null) setReplyTo(null); }; - const processCommand = (cmdBody) => { + /** Return true if a command was executed. */ + const processCommand = async (cmdBody) => { const spaceIndex = cmdBody.indexOf(' '); const cmdName = cmdBody.slice(1, spaceIndex > -1 ? spaceIndex : undefined); const cmdData = spaceIndex > -1 ? cmdBody.slice(spaceIndex + 1) : ''; if (!commands[cmdName]) { - confirmDialog('Invalid Command', `"${cmdName}" is not a valid command.`, 'Alright'); - return; + const sendAsMessage = await confirmDialog('Invalid Command', `"${cmdName}" is not a valid command. Did you mean to send this as a message?`, 'Send as message'); + if (sendAsMessage) { + sendBody(cmdBody); + return true; + } + return false; } if (['me', 'shrug', 'plain'].includes(cmdName)) { commands[cmdName].exe(roomId, cmdData, sendBody); - return; + return true; } commands[cmdName].exe(roomId, cmdData); + return true; }; const sendMessage = async () => { requestAnimationFrame(() => deactivateCmdAndEmit()); const msgBody = textAreaRef.current.value.trim(); if (msgBody.startsWith('/')) { - processCommand(msgBody.trim()); - textAreaRef.current.value = ''; - textAreaRef.current.style.height = 'unset'; + const executed = await processCommand(msgBody.trim()); + if (executed) { + textAreaRef.current.value = ''; + textAreaRef.current.style.height = 'unset'; + } return; } if (msgBody === '' && attachment === null) return; From 1bdb7f4e3ab71445fb740454f064bc20797dd658 Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Sat, 7 Oct 2023 18:19:01 +1100 Subject: [PATCH 1056/1531] Timeline-refactor-fixes (#1438) * fix type * fix missing member from reaction * stop context menu event propagation in msg modal * prevent encode blur hash from freezing app * replace roboto font with inter and fix weight * add recent emoji when selecting emoji * fix room latest evt hook * add option to drop typing status --- package-lock.json | 6 -- package.json | 1 - src/app/components/emoji-board/EmojiBoard.tsx | 6 +- src/app/hooks/useRoomLatestEvent.ts | 29 ---------- src/app/hooks/useRoomLatestRenderedEvent.ts | 57 +++++++++++++++++++ src/app/organisms/room/RoomTimeline.tsx | 2 +- src/app/organisms/room/RoomViewFollowing.tsx | 4 +- src/app/organisms/room/RoomViewTyping.css.ts | 3 + src/app/organisms/room/RoomViewTyping.tsx | 22 ++++++- .../organisms/room/message/FileContent.tsx | 4 +- .../organisms/room/message/ImageContent.tsx | 2 +- src/app/organisms/room/msgContent.ts | 9 ++- .../room/reaction-viewer/ReactionViewer.tsx | 11 ++-- src/client/state/settings.js | 4 ++ src/config.css.ts | 26 +++++++++ src/font.js | 5 -- src/index.jsx | 1 - src/index.scss | 10 ++-- 18 files changed, 138 insertions(+), 64 deletions(-) delete mode 100644 src/app/hooks/useRoomLatestEvent.ts create mode 100644 src/app/hooks/useRoomLatestRenderedEvent.ts create mode 100644 src/config.css.ts delete mode 100644 src/font.js diff --git a/package-lock.json b/package-lock.json index 6f00efe82..6213a1df7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,6 @@ "license": "AGPL-3.0-only", "dependencies": { "@fontsource/inter": "4.5.14", - "@fontsource/roboto": "4.5.8", "@khanacademy/simple-markdown": "0.8.6", "@matrix-org/olm": "3.2.14", "@tanstack/react-virtual": "3.0.0-beta.54", @@ -875,11 +874,6 @@ "resolved": "https://registry.npmjs.org/@fontsource/inter/-/inter-4.5.14.tgz", "integrity": "sha512-JDC9AocdPLuGsASkvWw9hS5gtHE7K9dOwL98XLrk5yjYqxy4uVnScG58NUvFMJDVJRl/7c8Wnap6PEs+7Zvj1Q==" }, - "node_modules/@fontsource/roboto": { - "version": "4.5.8", - "resolved": "https://registry.npmjs.org/@fontsource/roboto/-/roboto-4.5.8.tgz", - "integrity": "sha512-CnD7zLItIzt86q4Sj3kZUiLcBk1dSk81qcqgMGaZe7SQ1P8hFNxhMl5AZthK1zrDM5m74VVhaOpuMGIL4gagaA==" - }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.7", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.7.tgz", diff --git a/package.json b/package.json index 83850a80e..8ee5cc548 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,6 @@ "license": "AGPL-3.0-only", "dependencies": { "@fontsource/inter": "4.5.14", - "@fontsource/roboto": "4.5.8", "@khanacademy/simple-markdown": "0.8.6", "@matrix-org/olm": "3.2.14", "@tanstack/react-virtual": "3.0.0-beta.54", diff --git a/src/app/components/emoji-board/EmojiBoard.tsx b/src/app/components/emoji-board/EmojiBoard.tsx index a7309834c..81730e3db 100644 --- a/src/app/components/emoji-board/EmojiBoard.tsx +++ b/src/app/components/emoji-board/EmojiBoard.tsx @@ -46,6 +46,7 @@ import { editableActiveElement, isIntersectingScrollView, targetFromEvent } from import { useAsyncSearch, UseAsyncSearchOptions } from '../../hooks/useAsyncSearch'; import { useDebounce } from '../../hooks/useDebounce'; import { useThrottle } from '../../hooks/useThrottle'; +import { addRecentEmoji } from '../../plugins/recent-emoji'; const RECENT_GROUP_ID = 'recent_group'; const SEARCH_GROUP_ID = 'search_group'; @@ -697,7 +698,10 @@ export function EmojiBoard({ if (!emojiInfo) return; if (emojiInfo.type === EmojiType.Emoji) { onEmojiSelect?.(emojiInfo.data, emojiInfo.shortcode); - if (!evt.altKey && !evt.shiftKey) requestClose(); + if (!evt.altKey && !evt.shiftKey) { + addRecentEmoji(mx, emojiInfo.data); + requestClose(); + } } if (emojiInfo.type === EmojiType.CustomEmoji) { onCustomEmojiSelect?.(emojiInfo.data, emojiInfo.shortcode); diff --git a/src/app/hooks/useRoomLatestEvent.ts b/src/app/hooks/useRoomLatestEvent.ts deleted file mode 100644 index 337438ce9..000000000 --- a/src/app/hooks/useRoomLatestEvent.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { MatrixEvent, Room, RoomEvent, RoomEventHandlerMap } from 'matrix-js-sdk'; -import { useEffect, useState } from 'react'; - -export const useRoomLatestEvent = (room: Room) => { - const [latestEvent, setLatestEvent] = useState(); - - useEffect(() => { - const getLatestEvent = (): MatrixEvent | undefined => { - const liveEvents = room.getLiveTimeline().getEvents(); - for (let i = liveEvents.length - 1; i >= 0; i -= 1) { - const evt = liveEvents[i]; - if (evt) return evt; - } - return undefined; - }; - - const handleTimelineEvent: RoomEventHandlerMap[RoomEvent.Timeline] = () => { - setLatestEvent(getLatestEvent()); - }; - setLatestEvent(getLatestEvent()); - - room.on(RoomEvent.Timeline, handleTimelineEvent); - return () => { - room.removeListener(RoomEvent.Timeline, handleTimelineEvent); - }; - }, [room]); - - return latestEvent; -}; diff --git a/src/app/hooks/useRoomLatestRenderedEvent.ts b/src/app/hooks/useRoomLatestRenderedEvent.ts new file mode 100644 index 000000000..295d10307 --- /dev/null +++ b/src/app/hooks/useRoomLatestRenderedEvent.ts @@ -0,0 +1,57 @@ +/* eslint-disable no-continue */ +import { MatrixEvent, Room, RoomEvent, RoomEventHandlerMap } from 'matrix-js-sdk'; +import { useEffect, useState } from 'react'; +import { settingsAtom } from '../state/settings'; +import { useSetting } from '../state/hooks/settings'; +import { MessageEvent, StateEvent } from '../../types/matrix/room'; + +export const useRoomLatestRenderedEvent = (room: Room) => { + const [hideMembershipEvents] = useSetting(settingsAtom, 'hideMembershipEvents'); + const [hideNickAvatarEvents] = useSetting(settingsAtom, 'hideNickAvatarEvents'); + const [showHiddenEvents] = useSetting(settingsAtom, 'showHiddenEvents'); + const [latestEvent, setLatestEvent] = useState(); + + useEffect(() => { + const getLatestEvent = (): MatrixEvent | undefined => { + const liveEvents = room.getLiveTimeline().getEvents(); + for (let i = liveEvents.length - 1; i >= 0; i -= 1) { + const evt = liveEvents[i]; + + if (!evt) continue; + if (evt.isRelation()) continue; + if (evt.getType() === StateEvent.RoomMember) { + const membershipChanged = evt.getContent().membership !== evt.getPrevContent().membership; + if (membershipChanged && hideMembershipEvents) continue; + if (!membershipChanged && hideNickAvatarEvents) continue; + return evt; + } + + if ( + evt.getType() === MessageEvent.RoomMessage || + evt.getType() === MessageEvent.RoomMessageEncrypted || + evt.getType() === MessageEvent.Sticker || + evt.getType() === StateEvent.RoomName || + evt.getType() === StateEvent.RoomTopic || + evt.getType() === StateEvent.RoomAvatar + ) { + return evt; + } + + if (showHiddenEvents) return evt; + } + return undefined; + }; + + const handleTimelineEvent: RoomEventHandlerMap[RoomEvent.Timeline] = () => { + setLatestEvent(getLatestEvent()); + }; + setLatestEvent(getLatestEvent()); + + room.on(RoomEvent.Timeline, handleTimelineEvent); + return () => { + room.removeListener(RoomEvent.Timeline, handleTimelineEvent); + }; + }, [room, hideMembershipEvents, hideNickAvatarEvents, showHiddenEvents]); + + return latestEvent; +}; diff --git a/src/app/organisms/room/RoomTimeline.tsx b/src/app/organisms/room/RoomTimeline.tsx index 03f72a372..b3902d8b4 100644 --- a/src/app/organisms/room/RoomTimeline.tsx +++ b/src/app/organisms/room/RoomTimeline.tsx @@ -167,7 +167,7 @@ export const getFirstLinkedTimeline = ( export const getLinkedTimelines = (timeline: EventTimeline): EventTimeline[] => { const firstTimeline = getFirstLinkedTimeline(timeline, Direction.Backward); - const timelines = []; + const timelines: EventTimeline[] = []; for ( let nextTimeline: EventTimeline | null = firstTimeline; diff --git a/src/app/organisms/room/RoomViewFollowing.tsx b/src/app/organisms/room/RoomViewFollowing.tsx index cd62c429d..a49f70d91 100644 --- a/src/app/organisms/room/RoomViewFollowing.tsx +++ b/src/app/organisms/room/RoomViewFollowing.tsx @@ -19,7 +19,7 @@ import { getMemberDisplayName } from '../../utils/room'; import { getMxIdLocalPart } from '../../utils/matrix'; import * as css from './RoomViewFollowing.css'; import { useMatrixClient } from '../../hooks/useMatrixClient'; -import { useRoomLatestEvent } from '../../hooks/useRoomLatestEvent'; +import { useRoomLatestRenderedEvent } from '../../hooks/useRoomLatestRenderedEvent'; import { useRoomEventReaders } from '../../hooks/useRoomEventReaders'; import { EventReaders } from '../../components/event-readers'; @@ -30,7 +30,7 @@ export const RoomViewFollowing = as<'div', RoomViewFollowingProps>( ({ className, room, ...props }, ref) => { const mx = useMatrixClient(); const [open, setOpen] = useState(false); - const latestEvent = useRoomLatestEvent(room); + const latestEvent = useRoomLatestRenderedEvent(room); const latestEventReaders = useRoomEventReaders(room, latestEvent?.getId()); const followingMembers = latestEventReaders .map((readerId) => room.getMember(readerId)) diff --git a/src/app/organisms/room/RoomViewTyping.css.ts b/src/app/organisms/room/RoomViewTyping.css.ts index ef07316f2..9def1aeec 100644 --- a/src/app/organisms/room/RoomViewTyping.css.ts +++ b/src/app/organisms/room/RoomViewTyping.css.ts @@ -22,3 +22,6 @@ export const RoomViewTyping = style([ animation: `${SlideUpAnime} 100ms ease-in-out`, }, ]); +export const TypingText = style({ + flexGrow: 1, +}); diff --git a/src/app/organisms/room/RoomViewTyping.tsx b/src/app/organisms/room/RoomViewTyping.tsx index c7c15ea5b..c393f3aee 100644 --- a/src/app/organisms/room/RoomViewTyping.tsx +++ b/src/app/organisms/room/RoomViewTyping.tsx @@ -1,8 +1,8 @@ import React, { useMemo } from 'react'; -import { Box, Text, as } from 'folds'; +import { Box, Icon, IconButton, Icons, Text, as } from 'folds'; import { Room } from 'matrix-js-sdk'; import classNames from 'classnames'; -import { useAtomValue } from 'jotai'; +import { useAtomValue, useSetAtom } from 'jotai'; import { roomIdToTypingMembersAtom, selectRoomTypingMembersAtom } from '../../state/typingMembers'; import { TypingIndicator } from '../../components/typing-indicator'; import { getMemberDisplayName } from '../../utils/room'; @@ -15,6 +15,7 @@ export type RoomViewTypingProps = { }; export const RoomViewTyping = as<'div', RoomViewTypingProps>( ({ className, room, ...props }, ref) => { + const setTypingMembers = useSetAtom(roomIdToTypingMembersAtom); const mx = useMatrixClient(); const typingMembers = useAtomValue( useMemo(() => selectRoomTypingMembersAtom(room.roomId, roomIdToTypingMembersAtom), [room]) @@ -29,6 +30,18 @@ export const RoomViewTyping = as<'div', RoomViewTypingProps>( return null; } + const handleDropAll = () => { + // some homeserver does not timeout typing status + // we have given option so user can drop their typing status + typingMembers.forEach((member) => + setTypingMembers({ + type: 'DELETE', + roomId: room.roomId, + member, + }) + ); + }; + return ( ( ref={ref} > - + {typingNames.length === 1 && ( <> {typingNames[0]} @@ -96,6 +109,9 @@ export const RoomViewTyping = as<'div', RoomViewTypingProps>( )} + + + ); } diff --git a/src/app/organisms/room/message/FileContent.tsx b/src/app/organisms/room/message/FileContent.tsx index 8484d8499..c6bd45d41 100644 --- a/src/app/organisms/room/message/FileContent.tsx +++ b/src/app/organisms/room/message/FileContent.tsx @@ -94,7 +94,7 @@ function ReadTextFile({ body, mimeType, url, encInfo }: Omit - + evt.stopPropagation()}> - + evt.stopPropagation()}> ( clickOutsideDeactivates: true, }} > - + evt.stopPropagation()}> ( const senderId = mEvent.getSender(); if (!senderId) return null; const member = room.getMember(senderId); - if (!member) return null; - const name = getName(member); + const name = (member ? getName(member) : getMxIdLocalPart(senderId)) ?? senderId; - const avatarUrl = member.getAvatarUrl( + const avatarUrl = member?.getAvatarUrl( mx.baseUrl, 100, 100, @@ -113,12 +112,12 @@ export const ReactionViewer = as<'div', ReactionViewerProps>( return ( { requestClose(); - openProfileViewer(member.userId, room.roomId); + openProfileViewer(senderId, room.roomId); }} before={ @@ -127,7 +126,7 @@ export const ReactionViewer = as<'div', ReactionViewerProps>( ) : ( diff --git a/src/client/state/settings.js b/src/client/state/settings.js index cc1193cef..d39b2ca10 100644 --- a/src/client/state/settings.js +++ b/src/client/state/settings.js @@ -4,6 +4,7 @@ import appDispatcher from '../dispatcher'; import cons from './cons'; import { darkTheme, butterTheme, silverTheme } from '../../colors.css'; +import { onLightFontWeight, onDarkFontWeight } from '../../config.css'; function getSettings() { const settings = localStorage.getItem('settings'); @@ -23,6 +24,7 @@ class Settings extends EventEmitter { super(); this.themeClasses = [lightTheme, silverTheme, darkTheme, butterTheme]; + this.fontWeightClasses = [onLightFontWeight, onLightFontWeight, onDarkFontWeight, onDarkFontWeight] this.themes = ['', 'silver-theme', 'dark-theme', 'butter-theme']; this.themeIndex = this.getThemeIndex(); @@ -59,6 +61,7 @@ class Settings extends EventEmitter { this.themes.forEach((themeName, index) => { if (themeName !== '') document.body.classList.remove(themeName); document.body.classList.remove(this.themeClasses[index]); + document.body.classList.remove(this.fontWeightClasses[index]); document.body.classList.remove('prism-light') document.body.classList.remove('prism-dark') }); @@ -71,6 +74,7 @@ class Settings extends EventEmitter { if (this.themes[themeIndex] === undefined) return if (this.themes[themeIndex]) document.body.classList.add(this.themes[themeIndex]); document.body.classList.add(this.themeClasses[themeIndex]); + document.body.classList.add(this.fontWeightClasses[themeIndex]); document.body.classList.add(themeIndex < 2 ? 'prism-light' : 'prism-dark'); } diff --git a/src/config.css.ts b/src/config.css.ts new file mode 100644 index 000000000..df04b9096 --- /dev/null +++ b/src/config.css.ts @@ -0,0 +1,26 @@ +import { createTheme } from '@vanilla-extract/css'; +import { config } from 'folds'; + +export const onLightFontWeight = createTheme(config.fontWeight, { + W100: '100', + W200: '200', + W300: '300', + W400: '420', + W500: '500', + W600: '600', + W700: '700', + W800: '800', + W900: '900', +}); + +export const onDarkFontWeight = createTheme(config.fontWeight, { + W100: '100', + W200: '200', + W300: '300', + W400: '350', + W500: '450', + W600: '550', + W700: '650', + W800: '750', + W900: '850', +}); diff --git a/src/font.js b/src/font.js deleted file mode 100644 index 94b1f4782..000000000 --- a/src/font.js +++ /dev/null @@ -1,5 +0,0 @@ -import '@fontsource/roboto/300.css'; -import '@fontsource/roboto/400.css'; -import '@fontsource/roboto/500.css'; -import '@fontsource/roboto/700.css'; -import '@fontsource/inter/variable.css'; diff --git a/src/index.jsx b/src/index.jsx index e7256e251..a8a765703 100644 --- a/src/index.jsx +++ b/src/index.jsx @@ -8,7 +8,6 @@ import { configClass, varsClass } from 'folds'; enableMapSet(); -import './font'; import './index.scss'; import settings from './client/state/settings'; diff --git a/src/index.scss b/src/index.scss index 04125a1ca..90ce60a8b 100644 --- a/src/index.scss +++ b/src/index.scss @@ -158,7 +158,7 @@ /* font-weight */ --fw-light: 300; - --fw-normal: 400; + --fw-normal: 420; --fw-medium: 500; --fw-bold: 700; @@ -193,8 +193,8 @@ --fluid-slide-up: cubic-bezier(0.13, 0.56, 0.25, 0.99); --font-emoji: 'Twemoji'; - --font-primary: 'Roboto', var(--font-emoji), sans-serif; - --font-secondary: 'Roboto', var(--font-emoji), sans-serif; + --font-primary: 'InterVariable', var(--font-emoji), sans-serif; + --font-secondary: 'InterVariable', var(--font-emoji), sans-serif; } .silver-theme { @@ -291,8 +291,10 @@ /* override normal font weight for dark mode */ --fw-normal: 350; + --fw-medium: 450; + --fw-bold: 550; - --font-secondary: 'InterVariable', 'Roboto', var(--font-emoji), sans-serif; + --font-secondary: 'InterVariable', var(--font-emoji), sans-serif; } .butter-theme { From 13573f4b3f562d785a498af162a181267150133e Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Sat, 7 Oct 2023 20:21:35 +1100 Subject: [PATCH 1057/1531] Fix space mention (#1439) * open space on space mention click * fix styles * fix message options sticks * revert last changes --- src/app/organisms/room/RoomTimeline.tsx | 10 ++++++++-- src/app/organisms/room/RoomViewTyping.css.ts | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/app/organisms/room/RoomTimeline.tsx b/src/app/organisms/room/RoomTimeline.tsx index b3902d8b4..c41bfbb81 100644 --- a/src/app/organisms/room/RoomTimeline.tsx +++ b/src/app/organisms/room/RoomTimeline.tsx @@ -86,7 +86,12 @@ import { } from '../../utils/room'; import { useSetting } from '../../state/hooks/settings'; import { settingsAtom } from '../../state/settings'; -import { openJoinAlias, openProfileViewer, selectRoom } from '../../../client/action/navigation'; +import { + openJoinAlias, + openProfileViewer, + selectRoom, + selectSpace, +} from '../../../client/action/navigation'; import { useForceUpdate } from '../../hooks/useForceUpdate'; import { parseGeoUri, scaleYDimension } from '../../utils/common'; import { useMatrixEventRenderer } from '../../hooks/useMatrixEventRenderer'; @@ -536,7 +541,8 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli return; } if (isRoomId(mentionId) && mx.getRoom(mentionId)) { - selectRoom(mentionId); + if (mx.getRoom(mentionId)?.isSpaceRoom()) selectSpace(mentionId); + else selectRoom(mentionId); return; } openJoinAlias(mentionId); diff --git a/src/app/organisms/room/RoomViewTyping.css.ts b/src/app/organisms/room/RoomViewTyping.css.ts index 9def1aeec..5c90a178b 100644 --- a/src/app/organisms/room/RoomViewTyping.css.ts +++ b/src/app/organisms/room/RoomViewTyping.css.ts @@ -13,7 +13,7 @@ const SlideUpAnime = keyframes({ export const RoomViewTyping = style([ DefaultReset, { - padding: `${config.space.S100} ${config.space.S500}`, + padding: `0 ${config.space.S500}`, width: '100%', backgroundColor: color.Surface.Container, color: color.Surface.OnContainer, From bffd27ae5b6a99ea13823cbe7181e38dc9d44b45 Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Sun, 8 Oct 2023 00:09:43 +1100 Subject: [PATCH 1058/1531] Fix-jump-latest-senstivity (#1440) * fix jump to latest sensitivity * select mention space as tab --- src/app/hooks/useVirtualPaginator.ts | 2 +- src/app/organisms/room/RoomTimeline.tsx | 33 ++++++++++++++----------- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/src/app/hooks/useVirtualPaginator.ts b/src/app/hooks/useVirtualPaginator.ts index 550e11c03..9ffc7f914 100644 --- a/src/app/hooks/useVirtualPaginator.ts +++ b/src/app/hooks/useVirtualPaginator.ts @@ -319,7 +319,7 @@ export const useVirtualPaginator = ( const intersectionObserver = useIntersectionObserver( handlePaginatorElIntersection, - useMemo( + useCallback( () => ({ root: getScrollElement(), }), diff --git a/src/app/organisms/room/RoomTimeline.tsx b/src/app/organisms/room/RoomTimeline.tsx index c41bfbb81..96555f3d7 100644 --- a/src/app/organisms/room/RoomTimeline.tsx +++ b/src/app/organisms/room/RoomTimeline.tsx @@ -90,7 +90,7 @@ import { openJoinAlias, openProfileViewer, selectRoom, - selectSpace, + selectTab, } from '../../../client/action/navigation'; import { useForceUpdate } from '../../hooks/useForceUpdate'; import { parseGeoUri, scaleYDimension } from '../../utils/common'; @@ -115,7 +115,6 @@ import { useMemberEventParser } from '../../hooks/useMemberEventParser'; import * as customHtmlCss from '../../styles/CustomHtml.css'; import { RoomIntro } from '../../components/room-intro'; import { - OnIntersectionCallback, getIntersectionObserverEntry, useIntersectionObserver, } from '../../hooks/useIntersectionObserver'; @@ -541,7 +540,7 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli return; } if (isRoomId(mentionId) && mx.getRoom(mentionId)) { - if (mx.getRoom(mentionId)?.isSpaceRoom()) selectSpace(mentionId); + if (mx.getRoom(mentionId)?.isSpaceRoom()) selectTab(mentionId); else selectRoom(mentionId); return; } @@ -674,18 +673,24 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli useCallback(() => roomInputRef.current, [roomInputRef]) ); - const handleAtBottomIntersection: OnIntersectionCallback = useCallback((entries) => { - const target = atBottomAnchorRef.current; - if (!target) return; - const targetEntry = getIntersectionObserverEntry(target, entries); - - setAtBottom(targetEntry?.isIntersecting === true); - }, []); + const debounceSetAtBottom = useDebounce( + useCallback((entry: IntersectionObserverEntry) => { + if (!entry.isIntersecting) setAtBottom(false); + }, []), + { wait: 1000 } + ); useIntersectionObserver( - useDebounce(handleAtBottomIntersection, { - wait: 200, - }), - useMemo( + useCallback( + (entries) => { + const target = atBottomAnchorRef.current; + if (!target) return; + const targetEntry = getIntersectionObserverEntry(target, entries); + if (targetEntry) debounceSetAtBottom(targetEntry); + if (targetEntry?.isIntersecting) setAtBottom(true); + }, + [debounceSetAtBottom] + ), + useCallback( () => ({ root: getScrollElement(), rootMargin: '100px', From 60b5b5d312e9e82bdd5480424686f78cfd02d293 Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Sun, 8 Oct 2023 16:35:16 +1100 Subject: [PATCH 1059/1531] consider membership change with reason change (#1441) --- src/app/hooks/useMemberEventParser.tsx | 3 ++- src/app/hooks/useRoomLatestRenderedEvent.ts | 3 ++- src/app/organisms/room/RoomTimeline.tsx | 4 ++-- src/app/utils/room.ts | 4 ++++ 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/app/hooks/useMemberEventParser.tsx b/src/app/hooks/useMemberEventParser.tsx index ecb6f66b2..367e76d95 100644 --- a/src/app/hooks/useMemberEventParser.tsx +++ b/src/app/hooks/useMemberEventParser.tsx @@ -3,6 +3,7 @@ import { IconSrc, Icons } from 'folds'; import { MatrixEvent } from 'matrix-js-sdk'; import { IMemberContent, Membership } from '../../types/matrix/room'; import { getMxIdLocalPart } from '../utils/matrix'; +import { isMembershipChanged } from '../utils/room'; export type ParsedResult = { icon: IconSrc; @@ -27,7 +28,7 @@ export const useMemberEventParser = (): MemberEventParser => { const senderName = getMxIdLocalPart(senderId); const userName = content.displayname || getMxIdLocalPart(userId); - if (content.membership !== prevContent.membership) { + if (isMembershipChanged(mEvent)) { if (content.membership === Membership.Invite) { if (prevContent.membership === Membership.Knock) { return { diff --git a/src/app/hooks/useRoomLatestRenderedEvent.ts b/src/app/hooks/useRoomLatestRenderedEvent.ts index 295d10307..428e7b52a 100644 --- a/src/app/hooks/useRoomLatestRenderedEvent.ts +++ b/src/app/hooks/useRoomLatestRenderedEvent.ts @@ -4,6 +4,7 @@ import { useEffect, useState } from 'react'; import { settingsAtom } from '../state/settings'; import { useSetting } from '../state/hooks/settings'; import { MessageEvent, StateEvent } from '../../types/matrix/room'; +import { isMembershipChanged } from '../utils/room'; export const useRoomLatestRenderedEvent = (room: Room) => { const [hideMembershipEvents] = useSetting(settingsAtom, 'hideMembershipEvents'); @@ -20,7 +21,7 @@ export const useRoomLatestRenderedEvent = (room: Room) => { if (!evt) continue; if (evt.isRelation()) continue; if (evt.getType() === StateEvent.RoomMember) { - const membershipChanged = evt.getContent().membership !== evt.getPrevContent().membership; + const membershipChanged = isMembershipChanged(evt); if (membershipChanged && hideMembershipEvents) continue; if (!membershipChanged && hideNickAvatarEvents) continue; return evt; diff --git a/src/app/organisms/room/RoomTimeline.tsx b/src/app/organisms/room/RoomTimeline.tsx index 96555f3d7..03744c33d 100644 --- a/src/app/organisms/room/RoomTimeline.tsx +++ b/src/app/organisms/room/RoomTimeline.tsx @@ -83,6 +83,7 @@ import { decryptAllTimelineEvent, getMemberDisplayName, getReactionContent, + isMembershipChanged, } from '../../utils/room'; import { useSetting } from '../../state/hooks/settings'; import { settingsAtom } from '../../state/settings'; @@ -1311,8 +1312,7 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli ); }, renderRoomMember: (mEventId, mEvent, item) => { - const membershipChanged = - mEvent.getContent().membership !== mEvent.getPrevContent().membership; + const membershipChanged = isMembershipChanged(mEvent); if (membershipChanged && hideMembershipEvents) return null; if (!membershipChanged && hideNickAvatarEvents) return null; diff --git a/src/app/utils/room.ts b/src/app/utils/room.ts index f86378337..af9505d40 100644 --- a/src/app/utils/room.ts +++ b/src/app/utils/room.ts @@ -278,6 +278,10 @@ export const getMemberAvatarMxc = (room: Room, userId: string): string | undefin return member?.getMxcAvatarUrl(); }; +export const isMembershipChanged = (mEvent: MatrixEvent): boolean => + mEvent.getContent().membership !== mEvent.getPrevContent().membership || + mEvent.getContent().reason !== mEvent.getPrevContent().reason; + export const decryptAllTimelineEvent = async (mx: MatrixClient, timeline: EventTimeline) => { const crypto = mx.getCrypto(); if (!crypto) return; From 5940cf24a0ed86149202496bba4a23ad923134f2 Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Mon, 9 Oct 2023 22:26:54 +1100 Subject: [PATCH 1060/1531] Inline markdown in editor (#1442) * add inline markdown in editor * send markdown re-generative data in tags * enable vscode format on save * fix match italic and diff order * prevent formatting in code block * make code md rule highest * improve inline markdown parsing * add comment * improve code logic --- src/app/components/editor/output.ts | 43 ++++-- src/app/organisms/room/RoomInput.tsx | 10 +- src/app/organisms/settings/Settings.jsx | 11 +- src/app/utils/markdown.ts | 191 ++++++++++++++++++++++++ 4 files changed, 237 insertions(+), 18 deletions(-) create mode 100644 src/app/utils/markdown.ts diff --git a/src/app/components/editor/output.ts b/src/app/components/editor/output.ts index 5d0443fa8..92c86dd86 100644 --- a/src/app/components/editor/output.ts +++ b/src/app/components/editor/output.ts @@ -2,15 +2,28 @@ import { Descendant, Text } from 'slate'; import { sanitizeText } from '../../utils/sanitize'; import { BlockType } from './Elements'; import { CustomElement, FormattedText } from './slate'; +import { parseInlineMD } from '../../utils/markdown'; -const textToCustomHtml = (node: FormattedText): string => { +export type OutputOptions = { + allowTextFormatting?: boolean; + allowMarkdown?: boolean; +}; + +const textToCustomHtml = (node: FormattedText, opts: OutputOptions): string => { let string = sanitizeText(node.text); - if (node.bold) string = `${string}`; - if (node.italic) string = `${string}`; - if (node.underline) string = `${string}`; - if (node.strikeThrough) string = `${string}`; - if (node.code) string = `${string}`; - if (node.spoiler) string = `${string}`; + if (opts.allowTextFormatting) { + if (node.bold) string = `${string}`; + if (node.italic) string = `${string}`; + if (node.underline) string = `${string}`; + if (node.strikeThrough) string = `${string}`; + if (node.code) string = `${string}`; + if (node.spoiler) string = `${string}`; + } + + if (opts.allowMarkdown && string === sanitizeText(node.text)) { + string = parseInlineMD(string); + } + return string; }; @@ -47,11 +60,19 @@ const elementToCustomHtml = (node: CustomElement, children: string): string => { } }; -export const toMatrixCustomHTML = (node: Descendant | Descendant[]): string => { - if (Array.isArray(node)) return node.map((n) => toMatrixCustomHTML(n)).join(''); - if (Text.isText(node)) return textToCustomHtml(node); +export const toMatrixCustomHTML = ( + node: Descendant | Descendant[], + opts: OutputOptions +): string => { + const parseNode = (n: Descendant) => { + const isCodeLine = 'type' in n && n.type === BlockType.CodeLine; + if (isCodeLine) return toMatrixCustomHTML(n, {}); + return toMatrixCustomHTML(n, opts); + }; + if (Array.isArray(node)) return node.map(parseNode).join(''); + if (Text.isText(node)) return textToCustomHtml(node, opts); - const children = node.children.map((n) => toMatrixCustomHTML(n)).join(''); + const children = node.children.map(parseNode).join(''); return elementToCustomHtml(node, children); }; diff --git a/src/app/organisms/room/RoomInput.tsx b/src/app/organisms/room/RoomInput.tsx index efef03a27..7564d5f44 100644 --- a/src/app/organisms/room/RoomInput.tsx +++ b/src/app/organisms/room/RoomInput.tsx @@ -108,6 +108,7 @@ export const RoomInput = forwardRef( ({ editor, roomViewRef, roomId }, ref) => { const mx = useMatrixClient(); const room = mx.getRoom(roomId); + const [isMarkdown] = useSetting(settingsAtom, 'isMarkdown'); const [msgDraft, setMsgDraft] = useAtom(roomIdToMsgDraftAtomFamily(roomId)); const [replyDraft, setReplyDraft] = useAtom(roomIdToReplyDraftAtomFamily(roomId)); @@ -251,7 +252,12 @@ export const RoomInput = forwardRef( uploadBoardHandlers.current?.handleSend(); const plainText = toPlainText(editor.children).trim(); - const customHtml = trimCustomHtml(toMatrixCustomHTML(editor.children)); + const customHtml = trimCustomHtml( + toMatrixCustomHTML(editor.children, { + allowTextFormatting: true, + allowMarkdown: isMarkdown, + }) + ); if (plainText === '') return; @@ -288,7 +294,7 @@ export const RoomInput = forwardRef( resetEditorHistory(editor); setReplyDraft(); sendTypingStatus(false); - }, [mx, roomId, editor, replyDraft, sendTypingStatus, setReplyDraft]); + }, [mx, roomId, editor, replyDraft, sendTypingStatus, setReplyDraft, isMarkdown]); const handleKeyDown: KeyboardEventHandler = useCallback( (evt) => { diff --git a/src/app/organisms/settings/Settings.jsx b/src/app/organisms/settings/Settings.jsx index fef158675..bd9ce0441 100644 --- a/src/app/organisms/settings/Settings.jsx +++ b/src/app/organisms/settings/Settings.jsx @@ -6,7 +6,7 @@ import cons from '../../../client/state/cons'; import settings from '../../../client/state/settings'; import navigation from '../../../client/state/navigation'; import { - toggleSystemTheme, toggleMarkdown, + toggleSystemTheme, toggleNotifications, toggleNotificationSounds, } from '../../../client/action/settings'; import { usePermission } from '../../hooks/usePermission'; @@ -52,6 +52,7 @@ function AppearanceSection() { const [messageLayout, setMessageLayout] = useSetting(settingsAtom, 'messageLayout'); const [messageSpacing, setMessageSpacing] = useSetting(settingsAtom, 'messageSpacing'); const [useSystemEmoji, setUseSystemEmoji] = useSetting(settingsAtom, 'useSystemEmoji'); + const [isMarkdown, setIsMarkdown] = useSetting(settingsAtom, 'isMarkdown'); const [hideMembershipEvents, setHideMembershipEvents] = useSetting(settingsAtom, 'hideMembershipEvents'); const [hideNickAvatarEvents, setHideNickAvatarEvents] = useSetting(settingsAtom, 'hideNickAvatarEvents'); const [mediaAutoLoad, setMediaAutoLoad] = useSetting(settingsAtom, 'mediaAutoLoad'); @@ -138,14 +139,14 @@ function AppearanceSection() { } /> { toggleMarkdown(); updateState({}); }} + isActive={isMarkdown} + onToggle={() => setIsMarkdown(!isMarkdown) } /> )} - content={Format messages with markdown syntax before sending.} + content={Format messages with inline markdown syntax before sending.} /> string; +export type MatchResult = RegExpMatchArray | RegExpExecArray; +export type RuleMatch = (text: string) => MatchResult | null; +export type MatchConverter = (parse: PlainMDParser, match: MatchResult) => string; + +export type MDRule = { + match: RuleMatch; + html: MatchConverter; +}; + +export type MatchReplacer = ( + parse: PlainMDParser, + text: string, + match: MatchResult, + content: string +) => string; + +export type RuleRunner = (parse: PlainMDParser, text: string, rule: MDRule) => string | undefined; +export type RulesRunner = ( + parse: PlainMDParser, + text: string, + rules: MDRule[] +) => string | undefined; + +const MIN_ANY = '(.+?)'; + +const BOLD_MD_1 = '**'; +const BOLD_PREFIX_1 = '\\*{2}'; +const BOLD_NEG_LA_1 = '(?!\\*)'; +const BOLD_REG_1 = new RegExp(`${BOLD_PREFIX_1}${MIN_ANY}${BOLD_PREFIX_1}${BOLD_NEG_LA_1}`); +const BoldRule: MDRule = { + match: (text) => text.match(BOLD_REG_1), + html: (parse, match) => { + const [, g1] = match; + const child = parse(g1); + return `${child}`; + }, +}; + +const ITALIC_MD_1 = '*'; +const ITALIC_PREFIX_1 = '\\*'; +const ITALIC_NEG_LA_1 = '(?!\\*)'; +const ITALIC_REG_1 = new RegExp(`${ITALIC_PREFIX_1}${MIN_ANY}${ITALIC_PREFIX_1}${ITALIC_NEG_LA_1}`); +const ItalicRule1: MDRule = { + match: (text) => text.match(ITALIC_REG_1), + html: (parse, match) => { + const [, g1] = match; + return `${parse(g1)}`; + }, +}; + +const ITALIC_MD_2 = '_'; +const ITALIC_PREFIX_2 = '_'; +const ITALIC_NEG_LA_2 = '(?!_)'; +const ITALIC_REG_2 = new RegExp(`${ITALIC_PREFIX_2}${MIN_ANY}${ITALIC_PREFIX_2}${ITALIC_NEG_LA_2}`); +const ItalicRule2: MDRule = { + match: (text) => text.match(ITALIC_REG_2), + html: (parse, match) => { + const [, g1] = match; + return `${parse(g1)}`; + }, +}; + +const UNDERLINE_MD_1 = '__'; +const UNDERLINE_PREFIX_1 = '_{2}'; +const UNDERLINE_NEG_LA_1 = '(?!_)'; +const UNDERLINE_REG_1 = new RegExp( + `${UNDERLINE_PREFIX_1}${MIN_ANY}${UNDERLINE_PREFIX_1}${UNDERLINE_NEG_LA_1}` +); +const UnderlineRule: MDRule = { + match: (text) => text.match(UNDERLINE_REG_1), + html: (parse, match) => { + const [, g1] = match; + return `${parse(g1)}`; + }, +}; + +const STRIKE_MD_1 = '~~'; +const STRIKE_PREFIX_1 = '~{2}'; +const STRIKE_NEG_LA_1 = '(?!~)'; +const STRIKE_REG_1 = new RegExp(`${STRIKE_PREFIX_1}${MIN_ANY}${STRIKE_PREFIX_1}${STRIKE_NEG_LA_1}`); +const StrikeRule: MDRule = { + match: (text) => text.match(STRIKE_REG_1), + html: (parse, match) => { + const [, g1] = match; + return `${parse(g1)}`; + }, +}; + +const CODE_MD_1 = '`'; +const CODE_PREFIX_1 = '`'; +const CODE_NEG_LA_1 = '(?!`)'; +const CODE_REG_1 = new RegExp(`${CODE_PREFIX_1}${MIN_ANY}${CODE_PREFIX_1}${CODE_NEG_LA_1}`); +const CodeRule: MDRule = { + match: (text) => text.match(CODE_REG_1), + html: (parse, match) => { + const [, g1] = match; + return `${g1}`; + }, +}; + +const SPOILER_MD_1 = '||'; +const SPOILER_PREFIX_1 = '\\|{2}'; +const SPOILER_NEG_LA_1 = '(?!\\|)'; +const SPOILER_REG_1 = new RegExp( + `${SPOILER_PREFIX_1}${MIN_ANY}${SPOILER_PREFIX_1}${SPOILER_NEG_LA_1}` +); +const SpoilerRule: MDRule = { + match: (text) => text.match(SPOILER_REG_1), + html: (parse, match) => { + const [, g1] = match; + return `${parse(g1)}`; + }, +}; + +const LINK_ALT = `\\[${MIN_ANY}\\]`; +const LINK_URL = `\\((https?:\\/\\/.+?)\\)`; +const LINK_REG_1 = new RegExp(`${LINK_ALT}${LINK_URL}`); +const LinkRule: MDRule = { + match: (text) => text.match(LINK_REG_1), + html: (parse, match) => { + const [, g1, g2] = match; + return `${parse(g1)}`; + }, +}; + +const beforeMatch = (text: string, match: RegExpMatchArray | RegExpExecArray): string => + text.slice(0, match.index); +const afterMatch = (text: string, match: RegExpMatchArray | RegExpExecArray): string => + text.slice((match.index ?? 0) + match[0].length); + +const replaceMatch: MatchReplacer = (parse, text, match, content) => + `${parse(beforeMatch(text, match))}${content}${parse(afterMatch(text, match))}`; + +const runRule: RuleRunner = (parse, text, rule) => { + const matchResult = rule.match(text); + if (matchResult) { + const content = rule.html(parse, matchResult); + return replaceMatch(parse, text, matchResult, content); + } + return undefined; +}; + +/** + * Runs multiple rules at the same time to better handle nested rules. + * Rules will be run in the order they appear. + */ +const runRules: RulesRunner = (parse, text, rules) => { + const matchResults = rules.map((rule) => rule.match(text)); + + let targetRule: MDRule | undefined; + let targetResult: MatchResult | undefined; + + for (let i = 0; i < matchResults.length; i += 1) { + const currentResult = matchResults[i]; + if (currentResult && typeof currentResult.index === 'number') { + if ( + !targetResult || + (typeof targetResult?.index === 'number' && currentResult.index < targetResult.index) + ) { + targetResult = currentResult; + targetRule = rules[i]; + } + } + } + + if (targetRule && targetResult) { + const content = targetRule.html(parse, targetResult); + return replaceMatch(parse, text, targetResult, content); + } + return undefined; +}; + +const LeveledRules = [ + BoldRule, + ItalicRule1, + UnderlineRule, + ItalicRule2, + StrikeRule, + SpoilerRule, + LinkRule, +]; + +export const parseInlineMD = (text: string): string => { + let result: string | undefined; + if (!result) result = runRule(parseInlineMD, text, CodeRule); + + if (!result) result = runRules(parseInlineMD, text, LeveledRules); + + return result ?? text; +}; From d0f2a865bc57e7d41cce99acb2ad47b226983e8b Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Tue, 10 Oct 2023 17:07:03 +1100 Subject: [PATCH 1061/1531] make file, image viewer wide (#1444) --- src/app/organisms/room/message/FileContent.tsx | 13 +++++++++++-- src/app/organisms/room/message/ImageContent.tsx | 6 +++++- src/app/organisms/room/message/styles.css.ts | 5 +++++ 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/app/organisms/room/message/FileContent.tsx b/src/app/organisms/room/message/FileContent.tsx index c6bd45d41..303c45347 100644 --- a/src/app/organisms/room/message/FileContent.tsx +++ b/src/app/organisms/room/message/FileContent.tsx @@ -25,6 +25,7 @@ import { bytesToSize } from '../../../utils/common'; import { TextViewer } from '../../../components/text-viewer'; import { READABLE_TEXT_MIME_TYPES } from '../../../utils/mimeTypes'; import { PdfViewer } from '../../../components/Pdf-viewer'; +import * as css from './styles.css'; export type FileContentProps = { body: string; @@ -94,7 +95,11 @@ function ReadTextFile({ body, mimeType, url, encInfo }: Omit - evt.stopPropagation()}> + evt.stopPropagation()} + > - evt.stopPropagation()}> + evt.stopPropagation()} + > ( clickOutsideDeactivates: true, }} > - evt.stopPropagation()}> + evt.stopPropagation()} + > Date: Tue, 10 Oct 2023 17:07:15 +1100 Subject: [PATCH 1062/1531] show missing member in read receipt (#1445) --- .../components/event-readers/EventReaders.tsx | 30 +++++++------------ src/app/organisms/room/RoomViewFollowing.tsx | 14 ++++----- 2 files changed, 17 insertions(+), 27 deletions(-) diff --git a/src/app/components/event-readers/EventReaders.tsx b/src/app/components/event-readers/EventReaders.tsx index c05efc50a..a5a2646f4 100644 --- a/src/app/components/event-readers/EventReaders.tsx +++ b/src/app/components/event-readers/EventReaders.tsx @@ -15,7 +15,7 @@ import { as, config, } from 'folds'; -import { Room, RoomMember } from 'matrix-js-sdk'; +import { Room } from 'matrix-js-sdk'; import { useRoomEventReaders } from '../../hooks/useRoomEventReaders'; import { getMemberDisplayName } from '../../utils/room'; import { getMxIdLocalPart } from '../../utils/matrix'; @@ -33,12 +33,9 @@ export const EventReaders = as<'div', EventReadersProps>( ({ className, room, eventId, requestClose, ...props }, ref) => { const mx = useMatrixClient(); const latestEventReaders = useRoomEventReaders(room, eventId); - const followingMembers = latestEventReaders - .map((readerId) => room.getMember(readerId)) - .filter((member) => member) as RoomMember[]; - const getName = (member: RoomMember) => - getMemberDisplayName(room, member.userId) ?? getMxIdLocalPart(member.userId) ?? member.userId; + const getName = (userId: string) => + getMemberDisplayName(room, userId) ?? getMxIdLocalPart(userId) ?? userId; return ( ( - {followingMembers.map((member) => { - const name = getName(member); - const avatarUrl = member.getAvatarUrl( - mx.baseUrl, - 100, - 100, - 'crop', - undefined, - false - ); + {latestEventReaders.map((readerId) => { + const name = getName(readerId); + const avatarUrl = room + .getMember(readerId) + ?.getAvatarUrl(mx.baseUrl, 100, 100, 'crop', undefined, false); return ( { requestClose(); - openProfileViewer(member.userId, room.roomId); + openProfileViewer(readerId, room.roomId); }} before={ @@ -85,7 +77,7 @@ export const EventReaders = as<'div', EventReadersProps>( ) : ( diff --git a/src/app/organisms/room/RoomViewFollowing.tsx b/src/app/organisms/room/RoomViewFollowing.tsx index a49f70d91..2f7a583e3 100644 --- a/src/app/organisms/room/RoomViewFollowing.tsx +++ b/src/app/organisms/room/RoomViewFollowing.tsx @@ -11,7 +11,7 @@ import { as, config, } from 'folds'; -import { Room, RoomMember } from 'matrix-js-sdk'; +import { Room } from 'matrix-js-sdk'; import classNames from 'classnames'; import FocusTrap from 'focus-trap-react'; @@ -32,13 +32,11 @@ export const RoomViewFollowing = as<'div', RoomViewFollowingProps>( const [open, setOpen] = useState(false); const latestEvent = useRoomLatestRenderedEvent(room); const latestEventReaders = useRoomEventReaders(room, latestEvent?.getId()); - const followingMembers = latestEventReaders - .map((readerId) => room.getMember(readerId)) - .filter((member) => member && member.userId !== mx.getUserId()) as RoomMember[]; - - const names = followingMembers.map( - (member) => getMemberDisplayName(room, member.userId) ?? getMxIdLocalPart(member.userId) - ); + const names = latestEventReaders + .filter((readerId) => readerId !== mx.getUserId()) + .map( + (readerId) => getMemberDisplayName(room, readerId) ?? getMxIdLocalPart(readerId) ?? readerId + ); const eventId = latestEvent?.getId(); From 152576e85d46dd9d47296dc2e61491fe24bc735e Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Tue, 10 Oct 2023 17:07:28 +1100 Subject: [PATCH 1063/1531] Render file as readable with ext (#1446) --- src/app/components/text-viewer/TextViewer.tsx | 10 ++--- .../organisms/room/message/FileContent.tsx | 16 ++++++-- src/app/organisms/room/message/Message.tsx | 2 +- src/app/utils/mimeTypes.ts | 41 +++++++++++++++++++ 4 files changed, 58 insertions(+), 11 deletions(-) diff --git a/src/app/components/text-viewer/TextViewer.tsx b/src/app/components/text-viewer/TextViewer.tsx index 37642dbf2..7829fb35b 100644 --- a/src/app/components/text-viewer/TextViewer.tsx +++ b/src/app/components/text-viewer/TextViewer.tsx @@ -4,7 +4,6 @@ import classNames from 'classnames'; import { Box, Chip, Header, Icon, IconButton, Icons, Scroll, Text, as } from 'folds'; import { ErrorBoundary } from 'react-error-boundary'; import * as css from './TextViewer.css'; -import { mimeTypeToExt } from '../../utils/mimeTypes'; import { copyToClipboard } from '../../utils/dom'; const ReactPrism = lazy(() => import('../../plugins/react-prism/ReactPrism')); @@ -12,12 +11,12 @@ const ReactPrism = lazy(() => import('../../plugins/react-prism/ReactPrism')); export type TextViewerProps = { name: string; text: string; - mimeType: string; + langName: string; requestClose: () => void; }; export const TextViewer = as<'div', TextViewerProps>( - ({ className, name, text, mimeType, requestClose, ...props }, ref) => { + ({ className, name, text, langName, requestClose, ...props }, ref) => { const handleCopy = () => { copyToClipboard(text); }; @@ -51,10 +50,7 @@ export const TextViewer = as<'div', TextViewerProps>( alignItems="Center" > - + {text}}> {text}}> {(codeRef) => {text}} diff --git a/src/app/organisms/room/message/FileContent.tsx b/src/app/organisms/room/message/FileContent.tsx index 303c45347..9c6596670 100644 --- a/src/app/organisms/room/message/FileContent.tsx +++ b/src/app/organisms/room/message/FileContent.tsx @@ -23,7 +23,12 @@ import { useMatrixClient } from '../../../hooks/useMatrixClient'; import { getFileSrcUrl, getSrcFile } from './util'; import { bytesToSize } from '../../../utils/common'; import { TextViewer } from '../../../components/text-viewer'; -import { READABLE_TEXT_MIME_TYPES } from '../../../utils/mimeTypes'; +import { + READABLE_EXT_TO_MIME_TYPE, + READABLE_TEXT_MIME_TYPES, + getFileNameExt, + mimeTypeToExt, +} from '../../../utils/mimeTypes'; import { PdfViewer } from '../../../components/Pdf-viewer'; import * as css from './styles.css'; @@ -103,7 +108,11 @@ function ReadTextFile({ body, mimeType, url, encInfo }: Omit setTextViewer(false)} /> @@ -247,7 +256,8 @@ function DownloadFile({ body, mimeType, url, info, encInfo }: FileContentProps) export const FileContent = as<'div', FileContentProps>( ({ body, mimeType, url, info, encInfo, ...props }, ref) => ( - {READABLE_TEXT_MIME_TYPES.includes(mimeType) && ( + {(READABLE_TEXT_MIME_TYPES.includes(mimeType) || + READABLE_EXT_TO_MIME_TYPE[getFileNameExt(body)]) && ( )} {mimeType === 'application/pdf' && ( diff --git a/src/app/organisms/room/message/Message.tsx b/src/app/organisms/room/message/Message.tsx index 8f25861e8..13e43260d 100644 --- a/src/app/organisms/room/message/Message.tsx +++ b/src/app/organisms/room/message/Message.tsx @@ -246,7 +246,7 @@ export const MessageSourceCodeItem = as< diff --git a/src/app/utils/mimeTypes.ts b/src/app/utils/mimeTypes.ts index c883ddb9b..2a923677f 100644 --- a/src/app/utils/mimeTypes.ts +++ b/src/app/utils/mimeTypes.ts @@ -57,6 +57,43 @@ export const READABLE_TEXT_MIME_TYPES = [ ...TEXT_MIME_TYPE, ]; +export const READABLE_EXT_TO_MIME_TYPE: Record = { + go: 'text/go', + rs: 'text/rust', + py: 'text/python', + swift: 'text/swift', + c: 'text/c', + cpp: 'text/cpp', + java: 'text/java', + kt: 'text/kotlin', + lua: 'text/lua', + php: 'text/php', + ts: 'text/typescript', + js: 'text/javascript', + jsx: 'text/jsx', + tsx: 'text/tsx', + html: 'text/html', + xhtml: 'text/xhtml', + xht: 'text/xhtml', + css: 'text/css', + scss: 'text/scss', + sass: 'text/sass', + json: 'text/json', + md: 'text/markdown', + yaml: 'text/yaml', + yni: 'text/yni', + xml: 'text/xml', + txt: 'text/plain', + text: 'text/plain', + conf: 'text/conf', + cfg: 'text/conf', + cnf: 'text/conf', + log: 'text/log', + me: 'text/me', + cvs: 'text/cvs', + tvs: 'text/tvs', +}; + export const ALLOWED_BLOB_MIME_TYPES = [ ...IMAGE_MIME_TYPES, ...VIDEO_MIME_TYPES, @@ -92,3 +129,7 @@ export const mimeTypeToExt = (mimeType: string): string => { const extStart = mimeType.lastIndexOf('/') + 1; return mimeType.slice(extStart); }; +export const getFileNameExt = (fileName: string): string => { + const extStart = fileName.lastIndexOf('.') + 1; + return fileName.slice(extStart); +}; From f5bcc9b851dc7799c56449d4bd90bbe7c68733a7 Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Sat, 14 Oct 2023 16:08:43 +1100 Subject: [PATCH 1064/1531] Edit option (#1447) * add func to parse html to editor input * add plain to html input function * re-construct markdown * fix missing return * fix falsy condition * fix reading href instead of src of emoji * add message editor - WIP * fix plain to editor input func * add save edit message functionality * show edited event source code * focus message input on after editing message * use del tag for strike-through instead of s * prevent autocomplete from re-opening after esc * scroll out of view msg editor in view * handle up arrow edit * handle scroll to message editor without effect * revert prev commit: effect run after editor render * ignore relation event from editable * allow data-md tag for del and em in sanitize html * prevent edit without changes * ignore previous reply when replying to msg * fix up arrow edit not working sometime --- package-lock.json | 2 + package.json | 2 + src/app/components/editor/Editor.tsx | 5 +- src/app/components/editor/common.ts | 9 + src/app/components/editor/index.ts | 1 + src/app/components/editor/input.ts | 327 ++++++++++++++++++ src/app/components/editor/output.ts | 8 +- src/app/components/editor/slate.d.ts | 19 +- src/app/organisms/room/RoomInput.tsx | 53 ++- src/app/organisms/room/RoomTimeline.tsx | 134 ++++--- src/app/organisms/room/message/Message.tsx | 104 +++++- .../organisms/room/message/MessageEditor.tsx | 295 ++++++++++++++++ src/app/organisms/room/message/Reactions.tsx | 9 +- src/app/utils/dom.ts | 6 +- src/app/utils/markdown.ts | 2 +- src/app/utils/matrix.ts | 9 + src/app/utils/room.ts | 69 ++++ src/app/utils/sanitize.ts | 11 +- 18 files changed, 957 insertions(+), 108 deletions(-) create mode 100644 src/app/components/editor/input.ts create mode 100644 src/app/organisms/room/message/MessageEditor.tsx diff --git a/package-lock.json b/package-lock.json index 6213a1df7..70c90a9af 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,6 +23,7 @@ "classnames": "2.3.2", "dateformat": "5.0.3", "dayjs": "1.11.10", + "domhandler": "5.0.3", "emojibase": "6.1.0", "emojibase-data": "7.0.1", "file-saver": "2.0.5", @@ -30,6 +31,7 @@ "focus-trap-react": "10.0.2", "folds": "1.5.0", "formik": "2.2.9", + "html-dom-parser": "4.0.0", "html-react-parser": "4.2.0", "immer": "9.0.16", "is-hotkey": "0.2.0", diff --git a/package.json b/package.json index 8ee5cc548..7467126e4 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ "classnames": "2.3.2", "dateformat": "5.0.3", "dayjs": "1.11.10", + "domhandler": "5.0.3", "emojibase": "6.1.0", "emojibase-data": "7.0.1", "file-saver": "2.0.5", @@ -40,6 +41,7 @@ "focus-trap-react": "10.0.2", "folds": "1.5.0", "formik": "2.2.9", + "html-dom-parser": "4.0.0", "html-react-parser": "4.2.0", "immer": "9.0.16", "is-hotkey": "0.2.0", diff --git a/src/app/components/editor/Editor.tsx b/src/app/components/editor/Editor.tsx index e5377f2fc..62b413459 100644 --- a/src/app/components/editor/Editor.tsx +++ b/src/app/components/editor/Editor.tsx @@ -50,12 +50,13 @@ const withVoid = (editor: Editor): Editor => { }; export const useEditor = (): Editor => { - const [editor] = useState(withInline(withVoid(withReact(withHistory(createEditor()))))); + const [editor] = useState(() => withInline(withVoid(withReact(withHistory(createEditor()))))); return editor; }; export type EditorChangeHandler = (value: Descendant[]) => void; type CustomEditorProps = { + editableName?: string; top?: ReactNode; bottom?: ReactNode; before?: ReactNode; @@ -71,6 +72,7 @@ type CustomEditorProps = { export const CustomEditor = forwardRef( ( { + editableName, top, bottom, before, @@ -137,6 +139,7 @@ export const CustomEditor = forwardRef( hideTrack > { }); return worldStartPoint && Editor.range(editor, worldStartPoint, cursorPoint); }; + +export const isEmptyEditor = (editor: Editor): boolean => { + const firstChildren = editor.children[0]; + if (firstChildren && Element.isElement(firstChildren)) { + const isEmpty = editor.children.length === 1 && Editor.isEmpty(editor, firstChildren); + return isEmpty; + } + return false; +}; diff --git a/src/app/components/editor/index.ts b/src/app/components/editor/index.ts index 76ccf5624..7c63ce61d 100644 --- a/src/app/components/editor/index.ts +++ b/src/app/components/editor/index.ts @@ -5,3 +5,4 @@ export * from './Elements'; export * from './keyboard'; export * from './output'; export * from './Toolbar'; +export * from './input'; diff --git a/src/app/components/editor/input.ts b/src/app/components/editor/input.ts new file mode 100644 index 000000000..39db0e1b6 --- /dev/null +++ b/src/app/components/editor/input.ts @@ -0,0 +1,327 @@ +/* eslint-disable no-param-reassign */ +import { Descendant, Text } from 'slate'; +import parse from 'html-dom-parser'; +import { ChildNode, Element, isText, isTag } from 'domhandler'; + +import { sanitizeCustomHtml } from '../../utils/sanitize'; +import { BlockType, MarkType } from './Elements'; +import { + BlockQuoteElement, + CodeBlockElement, + CodeLineElement, + EmoticonElement, + HeadingElement, + HeadingLevel, + InlineElement, + ListItemElement, + MentionElement, + OrderedListElement, + ParagraphElement, + QuoteLineElement, + UnorderedListElement, +} from './slate'; +import { parseMatrixToUrl } from '../../utils/matrix'; +import { createEmoticonElement, createMentionElement } from './common'; + +const markNodeToType: Record = { + b: MarkType.Bold, + strong: MarkType.Bold, + i: MarkType.Italic, + em: MarkType.Italic, + u: MarkType.Underline, + s: MarkType.StrikeThrough, + del: MarkType.StrikeThrough, + code: MarkType.Code, + span: MarkType.Spoiler, +}; + +const elementToTextMark = (node: Element): MarkType | undefined => { + const markType = markNodeToType[node.name]; + if (!markType) return undefined; + + if (markType === MarkType.Spoiler && node.attribs['data-mx-spoiler'] === undefined) { + return undefined; + } + if ( + markType === MarkType.Code && + node.parent && + 'name' in node.parent && + node.parent.name === 'pre' + ) { + return undefined; + } + return markType; +}; + +const parseNodeText = (node: ChildNode): string => { + if (isText(node)) { + return node.data; + } + if (isTag(node)) { + return node.children.map((child) => parseNodeText(child)).join(''); + } + return ''; +}; + +const elementToInlineNode = (node: Element): MentionElement | EmoticonElement | undefined => { + if (node.name === 'img' && node.attribs['data-mx-emoticon'] !== undefined) { + const { src, alt } = node.attribs; + if (!src) return undefined; + return createEmoticonElement(src, alt || 'Unknown Emoji'); + } + if (node.name === 'a') { + const { href } = node.attribs; + if (typeof href !== 'string') return undefined; + const [mxId] = parseMatrixToUrl(href); + if (mxId) { + return createMentionElement(mxId, mxId, false); + } + } + return undefined; +}; + +const parseInlineNodes = (node: ChildNode): InlineElement[] => { + if (isText(node)) { + return [{ text: node.data }]; + } + if (isTag(node)) { + const markType = elementToTextMark(node); + if (markType) { + const children = node.children.flatMap(parseInlineNodes); + if (node.attribs['data-md'] !== undefined) { + children.unshift({ text: node.attribs['data-md'] }); + children.push({ text: node.attribs['data-md'] }); + } else { + children.forEach((child) => { + if (Text.isText(child)) { + child[markType] = true; + } + }); + } + return children; + } + + const inlineNode = elementToInlineNode(node); + if (inlineNode) return [inlineNode]; + + if (node.name === 'a') { + const children = node.childNodes.flatMap(parseInlineNodes); + children.unshift({ text: '[' }); + children.push({ text: `](${node.attribs.href})` }); + return children; + } + + return node.childNodes.flatMap(parseInlineNodes); + } + + return []; +}; + +const parseBlockquoteNode = (node: Element): BlockQuoteElement => { + const children: QuoteLineElement[] = []; + let lineHolder: InlineElement[] = []; + + const appendLine = () => { + if (lineHolder.length === 0) return; + + children.push({ + type: BlockType.QuoteLine, + children: lineHolder, + }); + lineHolder = []; + }; + + node.children.forEach((child) => { + if (isText(child)) { + lineHolder.push({ text: child.data }); + return; + } + if (isTag(child)) { + if (child.name === 'br') { + appendLine(); + return; + } + + if (child.name === 'p') { + appendLine(); + children.push({ + type: BlockType.QuoteLine, + children: child.children.flatMap((c) => parseInlineNodes(c)), + }); + return; + } + + parseInlineNodes(child).forEach((inlineNode) => lineHolder.push(inlineNode)); + } + }); + appendLine(); + + return { + type: BlockType.BlockQuote, + children, + }; +}; +const parseCodeBlockNode = (node: Element): CodeBlockElement => { + const children: CodeLineElement[] = []; + + const code = parseNodeText(node).trim(); + code.split('\n').forEach((lineTxt) => + children.push({ + type: BlockType.CodeLine, + children: [ + { + text: lineTxt, + }, + ], + }) + ); + + return { + type: BlockType.CodeBlock, + children, + }; +}; +const parseListNode = (node: Element): OrderedListElement | UnorderedListElement => { + const children: ListItemElement[] = []; + let lineHolder: InlineElement[] = []; + + const appendLine = () => { + if (lineHolder.length === 0) return; + + children.push({ + type: BlockType.ListItem, + children: lineHolder, + }); + lineHolder = []; + }; + + node.children.forEach((child) => { + if (isText(child)) { + lineHolder.push({ text: child.data }); + return; + } + if (isTag(child)) { + if (child.name === 'br') { + appendLine(); + return; + } + + if (child.name === 'li') { + appendLine(); + children.push({ + type: BlockType.ListItem, + children: child.children.flatMap((c) => parseInlineNodes(c)), + }); + return; + } + + parseInlineNodes(child).forEach((inlineNode) => lineHolder.push(inlineNode)); + } + }); + appendLine(); + + return { + type: node.name === 'ol' ? BlockType.OrderedList : BlockType.UnorderedList, + children, + }; +}; +const parseHeadingNode = (node: Element): HeadingElement => { + const children = node.children.flatMap((child) => parseInlineNodes(child)); + + const headingMatch = node.name.match(/^h([123456])$/); + const [, g1AsLevel] = headingMatch ?? ['h3', '3']; + const level = parseInt(g1AsLevel, 10); + return { + type: BlockType.Heading, + level: (level <= 3 ? level : 3) as HeadingLevel, + children, + }; +}; + +export const domToEditorInput = (domNodes: ChildNode[]): Descendant[] => { + const children: Descendant[] = []; + + let lineHolder: InlineElement[] = []; + + const appendLine = () => { + if (lineHolder.length === 0) return; + + children.push({ + type: BlockType.Paragraph, + children: lineHolder, + }); + lineHolder = []; + }; + + domNodes.forEach((node) => { + if (isText(node)) { + lineHolder.push({ text: node.data }); + return; + } + if (isTag(node)) { + if (node.name === 'br') { + appendLine(); + return; + } + + if (node.name === 'p') { + appendLine(); + children.push({ + type: BlockType.Paragraph, + children: node.children.flatMap((child) => parseInlineNodes(child)), + }); + return; + } + + if (node.name === 'blockquote') { + appendLine(); + children.push(parseBlockquoteNode(node)); + return; + } + if (node.name === 'pre') { + appendLine(); + children.push(parseCodeBlockNode(node)); + return; + } + if (node.name === 'ol' || node.name === 'ul') { + appendLine(); + children.push(parseListNode(node)); + return; + } + + if (node.name.match(/^h[123456]$/)) { + appendLine(); + children.push(parseHeadingNode(node)); + return; + } + + parseInlineNodes(node).forEach((inlineNode) => lineHolder.push(inlineNode)); + } + }); + appendLine(); + + return children; +}; + +export const htmlToEditorInput = (unsafeHtml: string): Descendant[] => { + const sanitizedHtml = sanitizeCustomHtml(unsafeHtml); + + const domNodes = parse(sanitizedHtml); + const editorNodes = domToEditorInput(domNodes); + return editorNodes; +}; + +export const plainToEditorInput = (text: string): Descendant[] => { + const editorNodes: Descendant[] = text.split('\n').map((lineText) => { + const paragraphNode: ParagraphElement = { + type: BlockType.Paragraph, + children: [ + { + text: lineText, + }, + ], + }; + return paragraphNode; + }); + return editorNodes; +}; diff --git a/src/app/components/editor/output.ts b/src/app/components/editor/output.ts index 92c86dd86..89a5f7c58 100644 --- a/src/app/components/editor/output.ts +++ b/src/app/components/editor/output.ts @@ -1,7 +1,8 @@ import { Descendant, Text } from 'slate'; + import { sanitizeText } from '../../utils/sanitize'; import { BlockType } from './Elements'; -import { CustomElement, FormattedText } from './slate'; +import { CustomElement } from './slate'; import { parseInlineMD } from '../../utils/markdown'; export type OutputOptions = { @@ -9,13 +10,13 @@ export type OutputOptions = { allowMarkdown?: boolean; }; -const textToCustomHtml = (node: FormattedText, opts: OutputOptions): string => { +const textToCustomHtml = (node: Text, opts: OutputOptions): string => { let string = sanitizeText(node.text); if (opts.allowTextFormatting) { if (node.bold) string = `${string}`; if (node.italic) string = `${string}`; if (node.underline) string = `${string}`; - if (node.strikeThrough) string = `${string}`; + if (node.strikeThrough) string = `${string}`; if (node.code) string = `${string}`; if (node.spoiler) string = `${string}`; } @@ -47,6 +48,7 @@ const elementToCustomHtml = (node: CustomElement, children: string): string => { return `
        ${children}
      `; case BlockType.UnorderedList: return `
        ${children}
      `; + case BlockType.Mention: return `${node.name}`; case BlockType.Emoticon: diff --git a/src/app/components/editor/slate.d.ts b/src/app/components/editor/slate.d.ts index 74b207085..ee046a082 100644 --- a/src/app/components/editor/slate.d.ts +++ b/src/app/components/editor/slate.d.ts @@ -23,13 +23,9 @@ export type FormattedText = Text & { export type LinkElement = { type: BlockType.Link; href: string; - children: FormattedText[]; -}; -export type SpoilerElement = { - type: 'spoiler'; - alert?: string; - children: FormattedText[]; + children: Text[]; }; + export type MentionElement = { type: BlockType.Mention; id: string; @@ -44,14 +40,16 @@ export type EmoticonElement = { children: Text[]; }; +export type InlineElement = Text | LinkElement | MentionElement | EmoticonElement; + export type ParagraphElement = { type: BlockType.Paragraph; - children: FormattedText[]; + children: InlineElement[]; }; export type HeadingElement = { type: BlockType.Heading; level: HeadingLevel; - children: FormattedText[]; + children: InlineElement[]; }; export type CodeLineElement = { type: BlockType.CodeLine; @@ -63,7 +61,7 @@ export type CodeBlockElement = { }; export type QuoteLineElement = { type: BlockType.QuoteLine; - children: FormattedText[]; + children: InlineElement[]; }; export type BlockQuoteElement = { type: BlockType.BlockQuote; @@ -71,7 +69,7 @@ export type BlockQuoteElement = { }; export type ListItemElement = { type: BlockType.ListItem; - children: FormattedText[]; + children: InlineElement[]; }; export type OrderedListElement = { type: BlockType.OrderedList; @@ -84,7 +82,6 @@ export type UnorderedListElement = { export type CustomElement = | LinkElement - // | SpoilerElement | MentionElement | EmoticonElement | ParagraphElement diff --git a/src/app/organisms/room/RoomInput.tsx b/src/app/organisms/room/RoomInput.tsx index 7564d5f44..acb45b327 100644 --- a/src/app/organisms/room/RoomInput.tsx +++ b/src/app/organisms/room/RoomInput.tsx @@ -12,7 +12,7 @@ import { useAtom } from 'jotai'; import isHotkey from 'is-hotkey'; import { EventType, IContent, MsgType, Room } from 'matrix-js-sdk'; import { ReactEditor } from 'slate-react'; -import { Transforms, Range, Editor, Element } from 'slate'; +import { Transforms, Range, Editor } from 'slate'; import { Box, Dialog, @@ -51,6 +51,7 @@ import { resetEditorHistory, customHtmlEqualsPlainText, trimCustomHtml, + isEmptyEditor, } from '../../components/editor'; import { EmojiBoard, EmojiBoardTab } from '../../components/emoji-board'; import { UseStateProvider } from '../../components/UseStateProvider'; @@ -95,7 +96,12 @@ import navigation from '../../../client/state/navigation'; import cons from '../../../client/state/cons'; import { MessageReply } from '../../molecules/message/Message'; import colorMXID from '../../../util/colorMXID'; -import { parseReplyBody, parseReplyFormattedBody } from '../../utils/room'; +import { + parseReplyBody, + parseReplyFormattedBody, + trimReplyFromBody, + trimReplyFromFormattedBody, +} from '../../utils/room'; import { sanitizeText } from '../../utils/sanitize'; import { useScreenSize } from '../../hooks/useScreenSize'; @@ -264,13 +270,15 @@ export const RoomInput = forwardRef( let body = plainText; let formattedBody = customHtml; if (replyDraft) { - body = parseReplyBody(replyDraft.userId, replyDraft.userId) + body; + body = parseReplyBody(replyDraft.userId, trimReplyFromBody(replyDraft.body)) + body; formattedBody = parseReplyFormattedBody( roomId, replyDraft.userId, replyDraft.eventId, - replyDraft.formattedBody ?? sanitizeText(replyDraft.body) + replyDraft.formattedBody + ? trimReplyFromFormattedBody(replyDraft.formattedBody) + : sanitizeText(replyDraft.body) ) + formattedBody; } @@ -321,19 +329,25 @@ export const RoomInput = forwardRef( [submit, editor, setReplyDraft] ); - const handleKeyUp: KeyboardEventHandler = useCallback(() => { - const firstChildren = editor.children[0]; - if (firstChildren && Element.isElement(firstChildren)) { - const isEmpty = editor.children.length === 1 && Editor.isEmpty(editor, firstChildren); - sendTypingStatus(!isEmpty); - } + const handleKeyUp: KeyboardEventHandler = useCallback( + (evt) => { + if (isHotkey('escape', evt)) { + evt.preventDefault(); + return; + } - const prevWordRange = getPrevWorldRange(editor); - const query = prevWordRange - ? getAutocompleteQuery(editor, prevWordRange, AUTOCOMPLETE_PREFIXES) - : undefined; - setAutocompleteQuery(query); - }, [editor, sendTypingStatus]); + sendTypingStatus(!isEmptyEditor(editor)); + + const prevWordRange = getPrevWorldRange(editor); + const query = prevWordRange + ? getAutocompleteQuery(editor, prevWordRange, AUTOCOMPLETE_PREFIXES) + : undefined; + setAutocompleteQuery(query); + }, + [editor, sendTypingStatus] + ); + + const handleCloseAutocomplete = useCallback(() => setAutocompleteQuery(undefined), []); const handleEmoticonSelect = (key: string, shortcode: string) => { editor.insertNode(createEmoticonElement(key, shortcode)); @@ -419,7 +433,7 @@ export const RoomInput = forwardRef( roomId={roomId} editor={editor} query={autocompleteQuery} - requestClose={() => setAutocompleteQuery(undefined)} + requestClose={handleCloseAutocomplete} /> )} {autocompleteQuery?.prefix === AutocompletePrefix.UserMention && ( @@ -427,7 +441,7 @@ export const RoomInput = forwardRef( roomId={roomId} editor={editor} query={autocompleteQuery} - requestClose={() => setAutocompleteQuery(undefined)} + requestClose={handleCloseAutocomplete} /> )} {autocompleteQuery?.prefix === AutocompletePrefix.Emoticon && ( @@ -435,10 +449,11 @@ export const RoomInput = forwardRef( imagePackRooms={imagePackRooms} editor={editor} query={autocompleteQuery} - requestClose={() => setAutocompleteQuery(undefined)} + requestClose={handleCloseAutocomplete} /> )} ( ({ position, className, ...props }, ref) => ( @@ -226,34 +229,6 @@ export const getEventIdAbsoluteIndex = ( return baseIndex + eventIndex; }; -export const getEventReactions = (timelineSet: EventTimelineSet, eventId: string) => - timelineSet.relations.getChildEventsForEvent( - eventId, - RelationType.Annotation, - EventType.Reaction - ); - -export const getEventEdits = (timelineSet: EventTimelineSet, eventId: string, eventType: string) => - timelineSet.relations.getChildEventsForEvent(eventId, RelationType.Replace, eventType); - -export const getLatestEdit = ( - targetEvent: MatrixEvent, - editEvents: MatrixEvent[] -): MatrixEvent | undefined => { - const eventByTargetSender = (rEvent: MatrixEvent) => - rEvent.getSender() === targetEvent.getSender(); - return editEvents.sort(matrixEventByRecency).find(eventByTargetSender); -}; - -export const getEditedEvent = ( - mEventId: string, - mEvent: MatrixEvent, - timelineSet: EventTimelineSet -): MatrixEvent | undefined => { - const edits = getEventEdits(timelineSet, mEventId, mEvent.getType()); - return edits && getLatestEdit(mEvent, edits.getRelations()); -}; - export const factoryGetFileSrcUrl = (httpUrl: string, mimeType: string, encFile?: IEncryptedFile) => async (): Promise => { if (encFile) { @@ -483,6 +458,7 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli const myPowerLevel = getPowerLevel(mx.getUserId() ?? ''); const canRedact = canDoAction('redact', myPowerLevel); const canSendReaction = canSendEvent(MessageEvent.Reaction, myPowerLevel); + const [editId, setEditId] = useState(); const imagePackRooms: Room[] = useMemo(() => { const allParentSpaces = [ @@ -572,20 +548,21 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli const getScrollElement = useCallback(() => scrollRef.current, []); - const { getItems, scrollToItem, observeBackAnchor, observeFrontAnchor } = useVirtualPaginator({ - count: eventsLength, - limit: PAGINATION_LIMIT, - range: timeline.range, - onRangeChange: useCallback((r) => setTimeline((cs) => ({ ...cs, range: r })), []), - getScrollElement, - getItemElement: useCallback( - (index: number) => - (scrollRef.current?.querySelector(`[data-message-item="${index}"]`) as HTMLElement) ?? - undefined, - [] - ), - onEnd: handleTimelinePagination, - }); + const { getItems, scrollToItem, scrollToElement, observeBackAnchor, observeFrontAnchor } = + useVirtualPaginator({ + count: eventsLength, + limit: PAGINATION_LIMIT, + range: timeline.range, + onRangeChange: useCallback((r) => setTimeline((cs) => ({ ...cs, range: r })), []), + getScrollElement, + getItemElement: useCallback( + (index: number) => + (scrollRef.current?.querySelector(`[data-message-item="${index}"]`) as HTMLElement) ?? + undefined, + [] + ), + onEnd: handleTimelinePagination, + }); const loadEventTimeline = useEventTimelineLoader( mx, @@ -701,6 +678,29 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli useCallback(() => atBottomAnchorRef.current, []) ); + // Handle up arrow edit + useKeyDown( + window, + useCallback( + (evt) => { + if ( + isHotkey('arrowup', evt) && + editableActiveElement() && + document.activeElement?.getAttribute('data-editable-name') === 'RoomInput' && + isEmptyEditor(editor) + ) { + const editableEvt = getLatestEditableEvt(room.getLiveTimeline(), (mEvt) => + canEditEvent(mx, mEvt) + ); + const editableEvtId = editableEvt?.getId(); + if (!editableEvtId) return; + setEditId(editableEvtId); + } + }, + [mx, room, editor] + ) + ); + useEffect(() => { if (eventId) { setTimeline(getEmptyTimeline()); @@ -771,6 +771,22 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli } }, [room, unreadInfo, liveTimelineLinked, rangeAtEnd, atBottom]); + // scroll out of view msg editor in view. + useEffect(() => { + if (editId) { + const editMsgElement = + (scrollRef.current?.querySelector(`[data-message-id="${editId}"]`) as HTMLElement) ?? + undefined; + if (editMsgElement) { + scrollToElement(editMsgElement, { + align: 'center', + behavior: 'smooth', + stopInView: true, + }); + } + } + }, [scrollToElement, editId]); + const handleJumpToLatest = () => { setTimeline(getInitialTimeline(room)); scrollToBottomRef.current.count += 1; @@ -901,6 +917,17 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli }, [mx, room] ); + const handleEdit = useCallback( + (editEvtId?: string) => { + if (editEvtId) { + setEditId(editEvtId); + return; + } + setEditId(undefined); + ReactEditor.focus(editor); + }, + [editor] + ); const renderBody = (body: string, customBody?: string) => { if (body === '') ; @@ -1153,12 +1180,14 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli void; @@ -211,21 +217,40 @@ export const MessageReadReceiptItem = as< export const MessageSourceCodeItem = as< 'button', { + room: Room; mEvent: MatrixEvent; onClose?: () => void; } ->(({ mEvent, onClose, ...props }, ref) => { +>(({ room, mEvent, onClose, ...props }, ref) => { const [open, setOpen] = useState(false); - const text = JSON.stringify( - mEvent.isEncrypted() + + const getContent = (evt: MatrixEvent) => + evt.isEncrypted() ? { - [`<== DECRYPTED_EVENT ==>`]: mEvent.getEffectiveEvent(), - [`<== ORIGINAL_EVENT ==>`]: mEvent.event, + [`<== DECRYPTED_EVENT ==>`]: evt.getEffectiveEvent(), + [`<== ORIGINAL_EVENT ==>`]: evt.event, } - : mEvent.event, - null, - 2 - ); + : evt.event; + + const getText = (): string => { + const evtId = mEvent.getId()!; + const evtTimeline = room.getTimelineForEvent(evtId); + const edits = + evtTimeline && + getEventEdits(evtTimeline.getTimelineSet(), evtId, mEvent.getType())?.getRelations(); + + if (!edits) return JSON.stringify(getContent(mEvent), null, 2); + + const content: Record = { + '<== MAIN_EVENT ==>': getContent(mEvent), + }; + + edits.forEach((editEvt, index) => { + content[`<== REPLACEMENT_EVENT_${index + 1} ==>`] = getContent(editEvt); + }); + + return JSON.stringify(content, null, 2); + }; const handleClose = () => { setOpen(false); @@ -247,7 +272,7 @@ export const MessageSourceCodeItem = as<
      @@ -537,6 +562,7 @@ export type MessageProps = { mEvent: MatrixEvent; collapse: boolean; highlight: boolean; + edit?: boolean; canDelete?: boolean; canSendReaction?: boolean; imagePackRooms?: Room[]; @@ -546,6 +572,7 @@ export type MessageProps = { onUserClick: MouseEventHandler; onUsernameClick: MouseEventHandler; onReplyClick: MouseEventHandler; + onEditId?: (eventId?: string) => void; onReactionToggle: (targetEventId: string, key: string, shortcode?: string) => void; reply?: ReactNode; reactions?: ReactNode; @@ -558,6 +585,7 @@ export const Message = as<'div', MessageProps>( mEvent, collapse, highlight, + edit, canDelete, canSendReaction, imagePackRooms, @@ -568,6 +596,7 @@ export const Message = as<'div', MessageProps>( onUsernameClick, onReplyClick, onReactionToggle, + onEditId, reply, reactions, children, @@ -644,7 +673,21 @@ export const Message = as<'div', MessageProps>( const msgContentJSX = ( {reply} - {children} + {edit && onEditId ? ( + onEditId()} + /> + ) : ( + children + )} {reactions} ); @@ -677,7 +720,7 @@ export const Message = as<'div', MessageProps>( onMouseLeave={hideOptions} ref={ref} > - {(hover || menu || emojiBoard) && ( + {!edit && (hover || menu || emojiBoard) && (
      @@ -728,6 +771,16 @@ export const Message = as<'div', MessageProps>( > + {canEditEvent(mx, mEvent) && onEditId && ( + onEditId(mEvent.getId())} + variant="SurfaceVariant" + size="300" + radii="300" + > + + + )} ( Reply + {canEditEvent(mx, mEvent) && onEditId && ( + } + radii="300" + data-event-id={mEvent.getId()} + onClick={() => { + onEditId(mEvent.getId()); + closeMenu(); + }} + > + + Edit Message + + + )} - + {((!mEvent.isRedacted() && canDelete) || mEvent.getSender() !== mx.getUserId()) && ( @@ -941,7 +1015,7 @@ export const Event = as<'div', EventProps>( eventId={mEvent.getId() ?? ''} onClose={closeMenu} /> - + {((!mEvent.isRedacted() && canDelete && !stateEvent) || (mEvent.getSender() !== mx.getUserId() && !stateEvent)) && ( diff --git a/src/app/organisms/room/message/MessageEditor.tsx b/src/app/organisms/room/message/MessageEditor.tsx new file mode 100644 index 000000000..903574790 --- /dev/null +++ b/src/app/organisms/room/message/MessageEditor.tsx @@ -0,0 +1,295 @@ +import React, { KeyboardEventHandler, useCallback, useEffect, useState } from 'react'; +import { Box, Chip, Icon, IconButton, Icons, Line, PopOut, Spinner, Text, as, config } from 'folds'; +import { Editor, Transforms } from 'slate'; +import { ReactEditor } from 'slate-react'; +import { IContent, MatrixEvent, RelationType, Room } from 'matrix-js-sdk'; +import isHotkey from 'is-hotkey'; +import { + AUTOCOMPLETE_PREFIXES, + AutocompletePrefix, + AutocompleteQuery, + CustomEditor, + EmoticonAutocomplete, + RoomMentionAutocomplete, + Toolbar, + UserMentionAutocomplete, + createEmoticonElement, + customHtmlEqualsPlainText, + getAutocompleteQuery, + getPrevWorldRange, + htmlToEditorInput, + moveCursor, + plainToEditorInput, + toMatrixCustomHTML, + toPlainText, + trimCustomHtml, + useEditor, +} from '../../../components/editor'; +import { useSetting } from '../../../state/hooks/settings'; +import { settingsAtom } from '../../../state/settings'; +import { UseStateProvider } from '../../../components/UseStateProvider'; +import { EmojiBoard } from '../../../components/emoji-board'; +import { AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback'; +import { useMatrixClient } from '../../../hooks/useMatrixClient'; +import { getEditedEvent, trimReplyFromFormattedBody } from '../../../utils/room'; + +type MessageEditorProps = { + roomId: string; + room: Room; + mEvent: MatrixEvent; + imagePackRooms?: Room[]; + onCancel: () => void; +}; +export const MessageEditor = as<'div', MessageEditorProps>( + ({ room, roomId, mEvent, imagePackRooms, onCancel, ...props }, ref) => { + const mx = useMatrixClient(); + const editor = useEditor(); + const [globalToolbar] = useSetting(settingsAtom, 'editorToolbar'); + const [isMarkdown] = useSetting(settingsAtom, 'isMarkdown'); + const [toolbar, setToolbar] = useState(globalToolbar); + + const [autocompleteQuery, setAutocompleteQuery] = + useState>(); + + const getPrevBodyAndFormattedBody = useCallback(() => { + const evtId = mEvent.getId()!; + const evtTimeline = room.getTimelineForEvent(evtId); + const editedEvent = + evtTimeline && getEditedEvent(evtId, mEvent, evtTimeline.getTimelineSet()); + + const { body, formatted_body: customHtml }: Record = + editedEvent?.getContent()['m.new.content'] ?? mEvent.getContent(); + + return [body, customHtml]; + }, [room, mEvent]); + + const [saveState, save] = useAsyncCallback( + useCallback(async () => { + const plainText = toPlainText(editor.children).trim(); + const customHtml = trimCustomHtml( + toMatrixCustomHTML(editor.children, { + allowTextFormatting: true, + allowMarkdown: isMarkdown, + }) + ); + + const [prevBody, prevCustomHtml] = getPrevBodyAndFormattedBody(); + + if (plainText === '') return undefined; + if ( + typeof prevCustomHtml === 'string' && + trimReplyFromFormattedBody(prevCustomHtml) === customHtml + ) { + return undefined; + } + if (!prevCustomHtml && typeof prevBody === 'string' && prevBody === plainText) { + return undefined; + } + + const newContent: IContent = { + msgtype: mEvent.getContent().msgtype, + body: plainText, + }; + + if (!customHtmlEqualsPlainText(customHtml, plainText)) { + newContent.format = 'org.matrix.custom.html'; + newContent.formatted_body = customHtml; + } + + const content: IContent = { + ...newContent, + body: `* ${plainText}`, + 'm.new_content': newContent, + 'm.relates_to': { + event_id: mEvent.getId(), + rel_type: RelationType.Replace, + }, + }; + + return mx.sendMessage(roomId, content); + }, [mx, editor, roomId, mEvent, isMarkdown, getPrevBodyAndFormattedBody]) + ); + + const handleSave = useCallback(() => { + if (saveState.status !== AsyncStatus.Loading) { + save(); + } + }, [saveState, save]); + + const handleKeyDown: KeyboardEventHandler = useCallback( + (evt) => { + if (isHotkey('enter', evt)) { + evt.preventDefault(); + handleSave(); + } + if (isHotkey('escape', evt)) { + evt.preventDefault(); + onCancel(); + } + }, + [onCancel, handleSave] + ); + + const handleKeyUp: KeyboardEventHandler = useCallback( + (evt) => { + if (isHotkey('escape', evt)) { + evt.preventDefault(); + return; + } + + const prevWordRange = getPrevWorldRange(editor); + const query = prevWordRange + ? getAutocompleteQuery(editor, prevWordRange, AUTOCOMPLETE_PREFIXES) + : undefined; + setAutocompleteQuery(query); + }, + [editor] + ); + + const handleCloseAutocomplete = useCallback(() => setAutocompleteQuery(undefined), []); + + const handleEmoticonSelect = (key: string, shortcode: string) => { + editor.insertNode(createEmoticonElement(key, shortcode)); + moveCursor(editor); + }; + + useEffect(() => { + const [body, customHtml] = getPrevBodyAndFormattedBody(); + + const initialValue = + typeof customHtml === 'string' + ? htmlToEditorInput(customHtml) + : plainToEditorInput(typeof body === 'string' ? body : ''); + + Transforms.select(editor, { + anchor: Editor.start(editor, []), + focus: Editor.end(editor, []), + }); + + editor.insertFragment(initialValue); + ReactEditor.focus(editor); + }, [editor, getPrevBodyAndFormattedBody]); + + useEffect(() => { + if (saveState.status === AsyncStatus.Success) { + onCancel(); + } + }, [saveState, onCancel]); + + return ( +
      + {autocompleteQuery?.prefix === AutocompletePrefix.RoomMention && ( + + )} + {autocompleteQuery?.prefix === AutocompletePrefix.UserMention && ( + + )} + {autocompleteQuery?.prefix === AutocompletePrefix.Emoticon && ( + + )} + + + + + ) : undefined + } + > + Save + + + Cancel + + + + setToolbar(!toolbar)} + > + + + + {(emojiBoard: boolean, setEmojiBoard) => ( + { + setEmojiBoard(false); + ReactEditor.focus(editor); + }} + /> + } + > + {(anchorRef) => ( + setEmojiBoard(true)} + variant="SurfaceVariant" + size="300" + radii="300" + > + + + )} + + )} + + + + {toolbar && ( +
      + + +
      + )} + + } + /> +
      + ); + } +); diff --git a/src/app/organisms/room/message/Reactions.tsx b/src/app/organisms/room/message/Reactions.tsx index 354820cdc..bc32c1a34 100644 --- a/src/app/organisms/room/message/Reactions.tsx +++ b/src/app/organisms/room/message/Reactions.tsx @@ -12,7 +12,7 @@ import { toRem, } from 'folds'; import classNames from 'classnames'; -import { EventTimelineSet, EventType, RelationType, Room } from 'matrix-js-sdk'; +import { Room } from 'matrix-js-sdk'; import { type Relations } from 'matrix-js-sdk/lib/models/relations'; import FocusTrap from 'focus-trap-react'; import { useMatrixClient } from '../../../hooks/useMatrixClient'; @@ -22,13 +22,6 @@ import { useRelations } from '../../../hooks/useRelations'; import * as css from './styles.css'; import { ReactionViewer } from '../reaction-viewer'; -export const getEventReactions = (timelineSet: EventTimelineSet, eventId: string) => - timelineSet.relations.getChildEventsForEvent( - eventId, - RelationType.Annotation, - EventType.Reaction - ); - export type ReactionsProps = { room: Room; mEventId: string; diff --git a/src/app/utils/dom.ts b/src/app/utils/dom.ts index a8dc4be2c..f39fe623a 100644 --- a/src/app/utils/dom.ts +++ b/src/app/utils/dom.ts @@ -5,7 +5,11 @@ export const targetFromEvent = (evt: Event, selector: string): Element | undefin export const editableActiveElement = (): boolean => !!document.activeElement && - /^(input)|(textarea)$/.test(document.activeElement.nodeName.toLowerCase()); + (document.activeElement.nodeName.toLowerCase() === 'input' || + document.activeElement.nodeName.toLowerCase() === 'textbox' || + document.activeElement.getAttribute('contenteditable') === 'true' || + document.activeElement.getAttribute('role') === 'input' || + document.activeElement.getAttribute('role') === 'textbox'); export const isIntersectingScrollView = ( scrollElement: HTMLElement, diff --git a/src/app/utils/markdown.ts b/src/app/utils/markdown.ts index e4294d7d6..6db7a3495 100644 --- a/src/app/utils/markdown.ts +++ b/src/app/utils/markdown.ts @@ -83,7 +83,7 @@ const StrikeRule: MDRule = { match: (text) => text.match(STRIKE_REG_1), html: (parse, match) => { const [, g1] = match; - return `${parse(g1)}`; + return `${parse(g1)}`; }, }; diff --git a/src/app/utils/matrix.ts b/src/app/utils/matrix.ts index 91bd80f39..ba27879e5 100644 --- a/src/app/utils/matrix.ts +++ b/src/app/utils/matrix.ts @@ -28,6 +28,15 @@ export const isRoomId = (id: string): boolean => validMxId(id) && id.startsWith( export const isRoomAlias = (id: string): boolean => validMxId(id) && id.startsWith('#'); +export const parseMatrixToUrl = (url: string): [string | undefined, string | undefined] => { + const href = decodeURIComponent(url); + + const match = href.match(/^https?:\/\/matrix.to\/#\/([@!$+#]\S+:[^\\?|^\s|^\\/]+)(\?(via=\S+))?/); + if (!match) return [undefined, undefined]; + const [, g1AsMxId, , g3AsVia] = match; + return [g1AsMxId, g3AsVia]; +}; + export const getRoomWithCanonicalAlias = (mx: MatrixClient, alias: string): Room | undefined => mx.getRooms()?.find((room) => room.getCanonicalAlias() === alias); diff --git a/src/app/utils/room.ts b/src/app/utils/room.ts index af9505d40..1dabdc074 100644 --- a/src/app/utils/room.ts +++ b/src/app/utils/room.ts @@ -2,17 +2,22 @@ import { IconName, IconSrc } from 'folds'; import { EventTimeline, + EventTimelineSet, + EventType, IPushRule, IPushRules, JoinRule, MatrixClient, MatrixEvent, + MsgType, NotificationCountType, + RelationType, Room, } from 'matrix-js-sdk'; import { CryptoBackend } from 'matrix-js-sdk/lib/common-crypto/CryptoBackend'; import { AccountDataEvent } from '../../types/matrix/accountData'; import { + MessageEvent, NotificationType, RoomToParents, RoomType, @@ -249,6 +254,21 @@ export const getRoomAvatarUrl = (mx: MatrixClient, room: Room): string | undefin return room.getAvatarUrl(mx.baseUrl, 32, 32, 'crop') ?? undefined; }; +export const trimReplyFromBody = (body: string): string => { + const match = body.match(/^>\s<.+?>\s.+\n\n/); + if (!match) return body; + return body.slice(match[0].length); +}; + +export const trimReplyFromFormattedBody = (formattedBody: string): string => { + const suffix = ''; + const i = formattedBody.lastIndexOf(suffix); + if (i < 0) { + return formattedBody; + } + return formattedBody.slice(i + suffix.length); +}; + export const parseReplyBody = (userId: string, body: string) => `> <${userId}> ${body.replace(/\n/g, '\n> ')}\n\n`; @@ -301,3 +321,52 @@ export const getReactionContent = (eventId: string, key: string, shortcode?: str }, shortcode, }); + +export const getEventReactions = (timelineSet: EventTimelineSet, eventId: string) => + timelineSet.relations.getChildEventsForEvent( + eventId, + RelationType.Annotation, + EventType.Reaction + ); + +export const getEventEdits = (timelineSet: EventTimelineSet, eventId: string, eventType: string) => + timelineSet.relations.getChildEventsForEvent(eventId, RelationType.Replace, eventType); + +export const getLatestEdit = ( + targetEvent: MatrixEvent, + editEvents: MatrixEvent[] +): MatrixEvent | undefined => { + const eventByTargetSender = (rEvent: MatrixEvent) => + rEvent.getSender() === targetEvent.getSender(); + return editEvents.sort((m1, m2) => m2.getTs() - m1.getTs()).find(eventByTargetSender); +}; + +export const getEditedEvent = ( + mEventId: string, + mEvent: MatrixEvent, + timelineSet: EventTimelineSet +): MatrixEvent | undefined => { + const edits = getEventEdits(timelineSet, mEventId, mEvent.getType()); + return edits && getLatestEdit(mEvent, edits.getRelations()); +}; + +export const canEditEvent = (mx: MatrixClient, mEvent: MatrixEvent) => + mEvent.getSender() === mx.getUserId() && + !mEvent.isRelation() && + mEvent.getType() === MessageEvent.RoomMessage && + (mEvent.getContent().msgtype === MsgType.Text || + mEvent.getContent().msgtype === MsgType.Emote || + mEvent.getContent().msgtype === MsgType.Notice); + +export const getLatestEditableEvt = ( + timeline: EventTimeline, + canEdit: (mEvent: MatrixEvent) => boolean +): MatrixEvent | undefined => { + const events = timeline.getEvents(); + + for (let i = events.length - 1; i >= 0; i -= 1) { + const evt = events[i]; + if (canEdit(evt)) return evt; + } + return undefined; +}; diff --git a/src/app/utils/sanitize.ts b/src/app/utils/sanitize.ts index 6a03ca7d5..8e7c1283b 100644 --- a/src/app/utils/sanitize.ts +++ b/src/app/utils/sanitize.ts @@ -56,12 +56,19 @@ const permittedTagToAttributes = { 'data-mx-maths', 'data-mx-pill', 'data-mx-ping', + 'data-md', ], div: ['data-mx-maths'], - a: ['name', 'target', 'href', 'rel'], + a: ['name', 'target', 'href', 'rel', 'data-md'], img: ['width', 'height', 'alt', 'title', 'src', 'data-mx-emoticon'], ol: ['start'], - code: ['class'], + code: ['class', 'data-md'], + strong: ['data-md'], + i: ['data-md'], + em: ['data-md'], + u: ['data-md'], + s: ['data-md'], + del: ['data-md'], }; const transformFontTag: Transformer = (tagName, attribs) => ({ From 4d0b6b93bc1cece068fe1a081bee3ab8324800bd Mon Sep 17 00:00:00 2001 From: Krishan <33421343+kfiven@users.noreply.github.com> Date: Wed, 18 Oct 2023 13:15:08 +1100 Subject: [PATCH 1065/1531] Fix verification notice not to display when CS is not setup (#1451) --- src/app/organisms/settings/DeviceManage.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/organisms/settings/DeviceManage.jsx b/src/app/organisms/settings/DeviceManage.jsx index 74738ea8b..7689f0f98 100644 --- a/src/app/organisms/settings/DeviceManage.jsx +++ b/src/app/organisms/settings/DeviceManage.jsx @@ -217,7 +217,7 @@ function DeviceManage() {
      Unverified sessions - {!isMeVerified && ( + {!isMeVerified && isCSEnabled && (
      Date: Wed, 18 Oct 2023 13:15:30 +1100 Subject: [PATCH 1066/1531] Editor Commands (#1450) * add commands hook * add commands in editor * add command auto complete menu * add commands in room input * remove old reply code from room input * fix video component css * do not auto focus input on android or ios * fix crash on enable block after selection * fix circular deps in editor * fix autocomplete return focus move editor cursor * remove unwanted keydown from room input * fix emoji alignment in editor * test ipad user agent * refactor isAndroidOrIOS to mobileOrTablet * update slate & slate-react * downgrade slate-react to 0.98.4 0.99.0 has breaking changes with ReactEditor.focus * add sql to readable ext mimetype * fix empty editor formatting gets saved as draft * add option to use enter for newline * remove empty msg draft from atom family * prevent msg ctx menu from open on text selection --- package-lock.json | 16 +- package.json | 4 +- src/app/components/editor/Editor.css.ts | 5 +- src/app/components/editor/Editor.tsx | 13 +- src/app/components/editor/Elements.tsx | 65 +++--- src/app/components/editor/Toolbar.tsx | 4 +- .../editor/autocomplete/AutocompleteMenu.tsx | 1 + .../autocomplete/EmoticonAutocomplete.tsx | 2 +- .../autocomplete/RoomMentionAutocomplete.tsx | 2 +- .../autocomplete/UserMentionAutocomplete.tsx | 2 +- .../editor/autocomplete/autocompleteQuery.ts | 2 + src/app/components/editor/index.ts | 3 +- src/app/components/editor/input.ts | 4 +- src/app/components/editor/keyboard.ts | 4 +- src/app/components/editor/output.ts | 16 +- src/app/components/editor/slate.d.ts | 10 +- src/app/components/editor/types.ts | 24 ++ .../components/editor/{common.ts => utils.ts} | 45 +++- src/app/components/emoji-board/EmojiBoard.tsx | 3 +- src/app/components/media/Video.tsx | 2 +- src/app/components/media/media.css.ts | 2 +- src/app/components/message/Reply.tsx | 4 +- src/app/hooks/useCommands.ts | 219 ++++++++++++++++++ .../organisms/room/CommandAutocomplete.tsx | 109 +++++++++ src/app/organisms/room/RoomInput.tsx | 109 +++++---- src/app/organisms/room/RoomView.jsx | 1 + src/app/organisms/room/message/Message.tsx | 4 +- .../organisms/room/message/MessageEditor.tsx | 15 +- src/app/organisms/settings/Settings.jsx | 11 + src/app/state/settings.ts | 2 + src/app/styles/CustomHtml.css.ts | 27 ++- src/app/utils/matrix.ts | 12 +- src/app/utils/mimeTypes.ts | 1 + src/app/utils/user-agent.ts | 8 + 34 files changed, 620 insertions(+), 131 deletions(-) create mode 100644 src/app/components/editor/types.ts rename src/app/components/editor/{common.ts => utils.ts} (82%) create mode 100644 src/app/hooks/useCommands.ts create mode 100644 src/app/organisms/room/CommandAutocomplete.tsx diff --git a/package-lock.json b/package-lock.json index 70c90a9af..1ef2fd4fe 100644 --- a/package-lock.json +++ b/package-lock.json @@ -56,9 +56,9 @@ "react-modal": "3.16.1", "react-range": "1.8.14", "sanitize-html": "2.8.0", - "slate": "0.90.0", + "slate": "0.94.1", "slate-history": "0.93.0", - "slate-react": "0.90.0", + "slate-react": "0.98.4", "tippy.js": "6.3.7", "twemoji": "14.0.2", "ua-parser-js": "1.0.35" @@ -5766,9 +5766,9 @@ } }, "node_modules/slate": { - "version": "0.90.0", - "resolved": "https://registry.npmjs.org/slate/-/slate-0.90.0.tgz", - "integrity": "sha512-dv8idv0JjYyHiAJcVKf5yWKPDMTDi+PSZyfjsnquEI8VB5nmTVGjeJab06lc3o69O7aN05ROwO9/OY8mU1IUPA==", + "version": "0.94.1", + "resolved": "https://registry.npmjs.org/slate/-/slate-0.94.1.tgz", + "integrity": "sha512-GH/yizXr1ceBoZ9P9uebIaHe3dC/g6Plpf9nlUwnvoyf6V1UOYrRwkabtOCd3ZfIGxomY4P7lfgLr7FPH8/BKA==", "dependencies": { "immer": "^9.0.6", "is-plain-object": "^5.0.0", @@ -5787,9 +5787,9 @@ } }, "node_modules/slate-react": { - "version": "0.90.0", - "resolved": "https://registry.npmjs.org/slate-react/-/slate-react-0.90.0.tgz", - "integrity": "sha512-z6pGd6jjU5VazLxlDi6zL3a6yaPBPJ+A2VyIlE/h/rvDywaLYGvk0xcrA9NrK71Dr47HK5ZN2zFEZNleh6wlPA==", + "version": "0.98.4", + "resolved": "https://registry.npmjs.org/slate-react/-/slate-react-0.98.4.tgz", + "integrity": "sha512-8Of3v9hFuX8rIRc86LuuBhU9t8ps+9ARKL4yyhCrKQYZ93Ep/LFA3GvPGvtf3zYuVadZ8tkhRH8tbHOGNAndLw==", "dependencies": { "@juggle/resize-observer": "^3.4.0", "@types/is-hotkey": "^0.1.1", diff --git a/package.json b/package.json index 7467126e4..f7bce7cf4 100644 --- a/package.json +++ b/package.json @@ -66,9 +66,9 @@ "react-modal": "3.16.1", "react-range": "1.8.14", "sanitize-html": "2.8.0", - "slate": "0.90.0", + "slate": "0.94.1", "slate-history": "0.93.0", - "slate-react": "0.90.0", + "slate-react": "0.98.4", "tippy.js": "6.3.7", "twemoji": "14.0.2", "ua-parser-js": "1.0.35" diff --git a/src/app/components/editor/Editor.css.ts b/src/app/components/editor/Editor.css.ts index 9ec8cfaf8..edce743f2 100644 --- a/src/app/components/editor/Editor.css.ts +++ b/src/app/components/editor/Editor.css.ts @@ -26,7 +26,7 @@ export const EditorTextarea = style([ { flexGrow: 1, height: '100%', - padding: `${toRem(13)} 0`, + padding: `${toRem(13)} ${toRem(1)}`, selectors: { [`${EditorTextareaScroll}:first-child &`]: { paddingLeft: toRem(13), @@ -34,6 +34,9 @@ export const EditorTextarea = style([ [`${EditorTextareaScroll}:last-child &`]: { paddingRight: toRem(13), }, + '&:focus': { + outline: 'none', + }, }, }, ]); diff --git a/src/app/components/editor/Editor.tsx b/src/app/components/editor/Editor.tsx index 62b413459..044d08379 100644 --- a/src/app/components/editor/Editor.tsx +++ b/src/app/components/editor/Editor.tsx @@ -18,7 +18,8 @@ import { RenderPlaceholderProps, } from 'slate-react'; import { withHistory } from 'slate-history'; -import { BlockType, RenderElement, RenderLeaf } from './Elements'; +import { BlockType } from './types'; +import { RenderElement, RenderLeaf } from './Elements'; import { CustomElement } from './slate'; import * as css from './Editor.css'; import { toggleKeyboardShortcut } from './keyboard'; @@ -34,8 +35,9 @@ const withInline = (editor: Editor): Editor => { const { isInline } = editor; editor.isInline = (element) => - [BlockType.Mention, BlockType.Emoticon, BlockType.Link].includes(element.type) || - isInline(element); + [BlockType.Mention, BlockType.Emoticon, BlockType.Link, BlockType.Command].includes( + element.type + ) || isInline(element); return editor; }; @@ -44,7 +46,8 @@ const withVoid = (editor: Editor): Editor => { const { isVoid } = editor; editor.isVoid = (element) => - [BlockType.Mention, BlockType.Emoticon].includes(element.type) || isVoid(element); + [BlockType.Mention, BlockType.Emoticon, BlockType.Command].includes(element.type) || + isVoid(element); return editor; }; @@ -122,7 +125,7 @@ export const CustomEditor = forwardRef( return (
      - + {top} {before && ( diff --git a/src/app/components/editor/Elements.tsx b/src/app/components/editor/Elements.tsx index 2df809936..c4767ab92 100644 --- a/src/app/components/editor/Elements.tsx +++ b/src/app/components/editor/Elements.tsx @@ -1,34 +1,18 @@ import { Scroll, Text } from 'folds'; import React from 'react'; -import { RenderElementProps, RenderLeafProps, useFocused, useSelected } from 'slate-react'; +import { + RenderElementProps, + RenderLeafProps, + useFocused, + useSelected, + useSlate, +} from 'slate-react'; import * as css from '../../styles/CustomHtml.css'; -import { EmoticonElement, LinkElement, MentionElement } from './slate'; +import { CommandElement, EmoticonElement, LinkElement, MentionElement } from './slate'; import { useMatrixClient } from '../../hooks/useMatrixClient'; - -export enum MarkType { - Bold = 'bold', - Italic = 'italic', - Underline = 'underline', - StrikeThrough = 'strikeThrough', - Code = 'code', - Spoiler = 'spoiler', -} - -export enum BlockType { - Paragraph = 'paragraph', - Heading = 'heading', - CodeLine = 'code-line', - CodeBlock = 'code-block', - QuoteLine = 'quote-line', - BlockQuote = 'block-quote', - ListItem = 'list-item', - OrderedList = 'ordered-list', - UnorderedList = 'unordered-list', - Mention = 'mention', - Emoticon = 'emoticon', - Link = 'link', -} +import { getBeginCommand } from './utils'; +import { BlockType } from './types'; // Put this at the start and end of an inline component to work around this Chromium bug: // https://bugs.chromium.org/p/chromium/issues/detail?id=1249405 @@ -62,6 +46,29 @@ function RenderMentionElement({ ); } +function RenderCommandElement({ + attributes, + element, + children, +}: { element: CommandElement } & RenderElementProps) { + const selected = useSelected(); + const focused = useFocused(); + const editor = useSlate(); + + return ( + + {`/${element.command}`} + {children} + + ); +} function RenderEmoticonElement({ attributes, @@ -200,6 +207,12 @@ export function RenderElement({ attributes, element, children }: RenderElementPr {children} ); + case BlockType.Command: + return ( + + {children} + + ); default: return ( diff --git a/src/app/components/editor/Toolbar.tsx b/src/app/components/editor/Toolbar.tsx index 72e2c38cf..342dd1060 100644 --- a/src/app/components/editor/Toolbar.tsx +++ b/src/app/components/editor/Toolbar.tsx @@ -25,9 +25,9 @@ import { removeAllMark, toggleBlock, toggleMark, -} from './common'; +} from './utils'; import * as css from './Editor.css'; -import { BlockType, MarkType } from './Elements'; +import { BlockType, MarkType } from './types'; import { HeadingLevel } from './slate'; import { isMacOS } from '../../utils/user-agent'; import { KeySymbol } from '../../utils/key-symbol'; diff --git a/src/app/components/editor/autocomplete/AutocompleteMenu.tsx b/src/app/components/editor/autocomplete/AutocompleteMenu.tsx index d89cda094..e7c8df388 100644 --- a/src/app/components/editor/autocomplete/AutocompleteMenu.tsx +++ b/src/app/components/editor/autocomplete/AutocompleteMenu.tsx @@ -19,6 +19,7 @@ export function AutocompleteMenu({ headerContent, requestClose, children }: Auto focusTrapOptions={{ initialFocus: false, onDeactivate: () => requestClose(), + returnFocusOnDeactivate: false, clickOutsideDeactivates: true, allowOutsideClick: true, isKeyForward: (evt: KeyboardEvent) => isHotkey('arrowdown', evt), diff --git a/src/app/components/editor/autocomplete/EmoticonAutocomplete.tsx b/src/app/components/editor/autocomplete/EmoticonAutocomplete.tsx index 2e556000c..bc98667ea 100644 --- a/src/app/components/editor/autocomplete/EmoticonAutocomplete.tsx +++ b/src/app/components/editor/autocomplete/EmoticonAutocomplete.tsx @@ -12,7 +12,7 @@ import { useAsyncSearch, } from '../../../hooks/useAsyncSearch'; import { onTabPress } from '../../../utils/keyboard'; -import { createEmoticonElement, moveCursor, replaceWithElement } from '../common'; +import { createEmoticonElement, moveCursor, replaceWithElement } from '../utils'; import { useRecentEmoji } from '../../../hooks/useRecentEmoji'; import { useRelevantImagePacks } from '../../../hooks/useImagePacks'; import { IEmoji, emojis } from '../../../plugins/emoji'; diff --git a/src/app/components/editor/autocomplete/RoomMentionAutocomplete.tsx b/src/app/components/editor/autocomplete/RoomMentionAutocomplete.tsx index baa217ca9..31acd2c54 100644 --- a/src/app/components/editor/autocomplete/RoomMentionAutocomplete.tsx +++ b/src/app/components/editor/autocomplete/RoomMentionAutocomplete.tsx @@ -3,7 +3,7 @@ import { Editor } from 'slate'; import { Avatar, AvatarFallback, AvatarImage, Icon, Icons, MenuItem, Text, color } from 'folds'; import { MatrixClient } from 'matrix-js-sdk'; -import { createMentionElement, moveCursor, replaceWithElement } from '../common'; +import { createMentionElement, moveCursor, replaceWithElement } from '../utils'; import { getRoomAvatarUrl, joinRuleToIconSrc } from '../../../utils/room'; import { roomIdByActivity } from '../../../../util/sort'; import initMatrix from '../../../../client/initMatrix'; diff --git a/src/app/components/editor/autocomplete/UserMentionAutocomplete.tsx b/src/app/components/editor/autocomplete/UserMentionAutocomplete.tsx index 00ecb0158..a99274a5d 100644 --- a/src/app/components/editor/autocomplete/UserMentionAutocomplete.tsx +++ b/src/app/components/editor/autocomplete/UserMentionAutocomplete.tsx @@ -13,7 +13,7 @@ import { useAsyncSearch, } from '../../../hooks/useAsyncSearch'; import { onTabPress } from '../../../utils/keyboard'; -import { createMentionElement, moveCursor, replaceWithElement } from '../common'; +import { createMentionElement, moveCursor, replaceWithElement } from '../utils'; import { useKeyDown } from '../../../hooks/useKeyDown'; import { getMxIdLocalPart, getMxIdServer, validMxId } from '../../../utils/matrix'; diff --git a/src/app/components/editor/autocomplete/autocompleteQuery.ts b/src/app/components/editor/autocomplete/autocompleteQuery.ts index 96dabc579..1baa44a13 100644 --- a/src/app/components/editor/autocomplete/autocompleteQuery.ts +++ b/src/app/components/editor/autocomplete/autocompleteQuery.ts @@ -4,11 +4,13 @@ export enum AutocompletePrefix { RoomMention = '#', UserMention = '@', Emoticon = ':', + Command = '/', } export const AUTOCOMPLETE_PREFIXES: readonly AutocompletePrefix[] = [ AutocompletePrefix.RoomMention, AutocompletePrefix.UserMention, AutocompletePrefix.Emoticon, + AutocompletePrefix.Command, ]; export type AutocompleteQuery = { diff --git a/src/app/components/editor/index.ts b/src/app/components/editor/index.ts index 7c63ce61d..aae0137d1 100644 --- a/src/app/components/editor/index.ts +++ b/src/app/components/editor/index.ts @@ -1,8 +1,9 @@ export * from './autocomplete'; -export * from './common'; +export * from './utils'; export * from './Editor'; export * from './Elements'; export * from './keyboard'; export * from './output'; export * from './Toolbar'; export * from './input'; +export * from './types'; diff --git a/src/app/components/editor/input.ts b/src/app/components/editor/input.ts index 39db0e1b6..37aa72442 100644 --- a/src/app/components/editor/input.ts +++ b/src/app/components/editor/input.ts @@ -4,7 +4,7 @@ import parse from 'html-dom-parser'; import { ChildNode, Element, isText, isTag } from 'domhandler'; import { sanitizeCustomHtml } from '../../utils/sanitize'; -import { BlockType, MarkType } from './Elements'; +import { BlockType, MarkType } from './types'; import { BlockQuoteElement, CodeBlockElement, @@ -21,7 +21,7 @@ import { UnorderedListElement, } from './slate'; import { parseMatrixToUrl } from '../../utils/matrix'; -import { createEmoticonElement, createMentionElement } from './common'; +import { createEmoticonElement, createMentionElement } from './utils'; const markNodeToType: Record = { b: MarkType.Bold, diff --git a/src/app/components/editor/keyboard.ts b/src/app/components/editor/keyboard.ts index b6e1c3f4f..b6d4d692b 100644 --- a/src/app/components/editor/keyboard.ts +++ b/src/app/components/editor/keyboard.ts @@ -1,8 +1,8 @@ import { isHotkey } from 'is-hotkey'; import { KeyboardEvent } from 'react'; import { Editor } from 'slate'; -import { isAnyMarkActive, isBlockActive, removeAllMark, toggleBlock, toggleMark } from './common'; -import { BlockType, MarkType } from './Elements'; +import { isAnyMarkActive, isBlockActive, removeAllMark, toggleBlock, toggleMark } from './utils'; +import { BlockType, MarkType } from './types'; export const INLINE_HOTKEYS: Record = { 'mod+b': MarkType.Bold, diff --git a/src/app/components/editor/output.ts b/src/app/components/editor/output.ts index 89a5f7c58..307ef8a2b 100644 --- a/src/app/components/editor/output.ts +++ b/src/app/components/editor/output.ts @@ -1,7 +1,7 @@ import { Descendant, Text } from 'slate'; import { sanitizeText } from '../../utils/sanitize'; -import { BlockType } from './Elements'; +import { BlockType } from './types'; import { CustomElement } from './slate'; import { parseInlineMD } from '../../utils/markdown'; @@ -57,6 +57,8 @@ const elementToCustomHtml = (node: CustomElement, children: string): string => { : node.key; case BlockType.Link: return `${node.children}`; + case BlockType.Command: + return `/${node.command}`; default: return children; } @@ -104,6 +106,8 @@ const elementToPlainText = (node: CustomElement, children: string): string => { return node.key.startsWith('mxc://') ? `:${node.shortcode}:` : node.key; case BlockType.Link: return `[${node.children}](${node.href})`; + case BlockType.Command: + return `/${node.command}`; default: return children; } @@ -129,4 +133,12 @@ export const toPlainText = (node: Descendant | Descendant[]): string => { export const customHtmlEqualsPlainText = (customHtml: string, plain: string): boolean => customHtml.replace(//g, '\n') === sanitizeText(plain); -export const trimCustomHtml = (customHtml: string) => customHtml.replace(/$/g, ''); +export const trimCustomHtml = (customHtml: string) => customHtml.replace(/$/g, '').trim(); + +export const trimCommand = (cmdName: string, str: string) => { + const cmdRegX = new RegExp(`^(\\s+)?(\\/${cmdName})([^\\S\n]+)?`); + + const match = str.match(cmdRegX); + if (!match) return str; + return str.slice(match[0].length); +}; diff --git a/src/app/components/editor/slate.d.ts b/src/app/components/editor/slate.d.ts index ee046a082..1b08ae884 100644 --- a/src/app/components/editor/slate.d.ts +++ b/src/app/components/editor/slate.d.ts @@ -1,7 +1,7 @@ import { BaseEditor } from 'slate'; import { ReactEditor } from 'slate-react'; import { HistoryEditor } from 'slate-history'; -import { BlockType } from './Elements'; +import { BlockType } from './types'; export type HeadingLevel = 1 | 2 | 3; @@ -39,8 +39,13 @@ export type EmoticonElement = { shortcode: string; children: Text[]; }; +export type CommandElement = { + type: BlockType.Command; + command: string; + children: Text[]; +}; -export type InlineElement = Text | LinkElement | MentionElement | EmoticonElement; +export type InlineElement = Text | LinkElement | MentionElement | EmoticonElement | CommandElement; export type ParagraphElement = { type: BlockType.Paragraph; @@ -84,6 +89,7 @@ export type CustomElement = | LinkElement | MentionElement | EmoticonElement + | CommandElement | ParagraphElement | HeadingElement | CodeLineElement diff --git a/src/app/components/editor/types.ts b/src/app/components/editor/types.ts new file mode 100644 index 000000000..9a108ec7d --- /dev/null +++ b/src/app/components/editor/types.ts @@ -0,0 +1,24 @@ +export enum MarkType { + Bold = 'bold', + Italic = 'italic', + Underline = 'underline', + StrikeThrough = 'strikeThrough', + Code = 'code', + Spoiler = 'spoiler', +} + +export enum BlockType { + Paragraph = 'paragraph', + Heading = 'heading', + CodeLine = 'code-line', + CodeBlock = 'code-block', + QuoteLine = 'quote-line', + BlockQuote = 'block-quote', + ListItem = 'list-item', + OrderedList = 'ordered-list', + UnorderedList = 'unordered-list', + Mention = 'mention', + Emoticon = 'emoticon', + Link = 'link', + Command = 'command', +} diff --git a/src/app/components/editor/common.ts b/src/app/components/editor/utils.ts similarity index 82% rename from src/app/components/editor/common.ts rename to src/app/components/editor/utils.ts index 68717b38e..9bdfde185 100644 --- a/src/app/components/editor/common.ts +++ b/src/app/components/editor/utils.ts @@ -1,6 +1,13 @@ -import { BasePoint, BaseRange, Editor, Element, Point, Range, Transforms } from 'slate'; -import { BlockType, MarkType } from './Elements'; -import { EmoticonElement, FormattedText, HeadingLevel, LinkElement, MentionElement } from './slate'; +import { BasePoint, BaseRange, Editor, Element, Point, Range, Text, Transforms } from 'slate'; +import { BlockType, MarkType } from './types'; +import { + CommandElement, + EmoticonElement, + FormattedText, + HeadingLevel, + LinkElement, + MentionElement, +} from './slate'; const ALL_MARK_TYPE: MarkType[] = [ MarkType.Bold, @@ -54,6 +61,9 @@ const NESTED_BLOCK = [ ]; export const toggleBlock = (editor: Editor, format: BlockType, option?: BlockOption) => { + Transforms.collapse(editor, { + edge: 'end', + }); const isActive = isBlockActive(editor, format); Transforms.unwrapNodes(editor, { @@ -163,17 +173,23 @@ export const createLinkElement = ( children: typeof children === 'string' ? [{ text: children }] : children, }); +export const createCommandElement = (command: string): CommandElement => ({ + type: BlockType.Command, + command, + children: [{ text: '' }], +}); + export const replaceWithElement = (editor: Editor, selectRange: BaseRange, element: Element) => { Transforms.select(editor, selectRange); Transforms.insertNodes(editor, element); + Transforms.collapse(editor, { + edge: 'end', + }); }; export const moveCursor = (editor: Editor, withSpace?: boolean) => { - // without timeout move cursor doesn't works properly. - setTimeout(() => { - Transforms.move(editor); - if (withSpace) editor.insertText(' '); - }, 100); + Transforms.move(editor); + if (withSpace) editor.insertText(' '); }; interface PointUntilCharOptions { @@ -230,3 +246,16 @@ export const isEmptyEditor = (editor: Editor): boolean => { } return false; }; + +export const getBeginCommand = (editor: Editor): string | undefined => { + const lineBlock = editor.children[0]; + if (!Element.isElement(lineBlock)) return undefined; + if (lineBlock.type !== BlockType.Paragraph) return undefined; + + const [firstInline, secondInline] = lineBlock.children; + const isEmptyText = Text.isText(firstInline) && firstInline.text.trim() === ''; + if (!isEmptyText) return undefined; + if (Element.isElement(secondInline) && secondInline.type === BlockType.Command) + return secondInline.command; + return undefined; +}; diff --git a/src/app/components/emoji-board/EmojiBoard.tsx b/src/app/components/emoji-board/EmojiBoard.tsx index 81730e3db..067ebe39c 100644 --- a/src/app/components/emoji-board/EmojiBoard.tsx +++ b/src/app/components/emoji-board/EmojiBoard.tsx @@ -47,6 +47,7 @@ import { useAsyncSearch, UseAsyncSearchOptions } from '../../hooks/useAsyncSearc import { useDebounce } from '../../hooks/useDebounce'; import { useThrottle } from '../../hooks/useThrottle'; import { addRecentEmoji } from '../../plugins/recent-emoji'; +import { mobileOrTablet } from '../../utils/user-agent'; const RECENT_GROUP_ID = 'recent_group'; const SEARCH_GROUP_ID = 'search_group'; @@ -782,7 +783,7 @@ export function EmojiBoard({ maxLength={50} after={} onChange={handleOnChange} - autoFocus + autoFocus={!mobileOrTablet()} /> diff --git a/src/app/components/media/Video.tsx b/src/app/components/media/Video.tsx index ab13c5bdc..03108c329 100644 --- a/src/app/components/media/Video.tsx +++ b/src/app/components/media/Video.tsx @@ -5,6 +5,6 @@ import * as css from './media.css'; export const Video = forwardRef>( ({ className, ...props }, ref) => ( // eslint-disable-next-line jsx-a11y/media-has-caption -
      diff --git a/src/app/organisms/room/RoomInput.tsx b/src/app/organisms/room/RoomInput.tsx index 81c29b030..ae12afb05 100644 --- a/src/app/organisms/room/RoomInput.tsx +++ b/src/app/organisms/room/RoomInput.tsx @@ -443,7 +443,7 @@ export const RoomInput = forwardRef( )} {autocompleteQuery?.prefix === AutocompletePrefix.UserMention && ( ( )} {autocompleteQuery?.prefix === AutocompletePrefix.UserMention && ( string +): string[] => [ + member.rawDisplayName === member.userId ? mxIdToName(member.userId) : member.rawDisplayName, + query.startsWith('@') || query.indexOf(':') > -1 ? member.userId : mxIdToName(member.userId), +]; + export const getMemberAvatarMxc = (room: Room, userId: string): string | undefined => { const member = room.getMember(userId); return member?.getMxcAvatarUrl(); From ed3d14b131ee39f4c530681df3de42ae93e34c0c Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Thu, 19 Oct 2023 17:43:37 +1100 Subject: [PATCH 1071/1531] fix recursive state updates (#1458) --- src/app/organisms/room/RoomInput.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/organisms/room/RoomInput.tsx b/src/app/organisms/room/RoomInput.tsx index ae12afb05..a1fa6c268 100644 --- a/src/app/organisms/room/RoomInput.tsx +++ b/src/app/organisms/room/RoomInput.tsx @@ -187,7 +187,7 @@ export const RoomInput = forwardRef( const parsedDraft = JSON.parse(JSON.stringify(editor.children)); setMsgDraft(parsedDraft); } else { - roomIdToMsgDraftAtomFamily.remove(roomId); + setMsgDraft([]); } resetEditor(editor); resetEditorHistory(editor); From a2692e1469c57430545421b616f5f1d648415464 Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Thu, 19 Oct 2023 17:43:54 +1100 Subject: [PATCH 1072/1531] Fix room mention (#1459) * create room mention with alias if possible * display room mention text as they were sent --- .../autocomplete/RoomMentionAutocomplete.tsx | 14 ++++++++------ src/app/components/editor/input.ts | 2 +- src/app/plugins/react-custom-html-parser.tsx | 5 +---- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/src/app/components/editor/autocomplete/RoomMentionAutocomplete.tsx b/src/app/components/editor/autocomplete/RoomMentionAutocomplete.tsx index 31acd2c54..b9fee8788 100644 --- a/src/app/components/editor/autocomplete/RoomMentionAutocomplete.tsx +++ b/src/app/components/editor/autocomplete/RoomMentionAutocomplete.tsx @@ -32,14 +32,14 @@ function UnknownRoomMentionItem({ const mx = useMatrixClient(); const roomAlias: string = roomAliasFromQueryText(mx, query.text); + const handleSelect = () => handleAutocomplete(roomAlias, roomAlias); + return ( ) => - onTabPress(evt, () => handleAutocomplete(roomAlias, roomAlias)) - } - onClick={() => handleAutocomplete(roomAlias, roomAlias)} + onKeyDown={(evt: ReactKeyboardEvent) => onTabPress(evt, handleSelect)} + onClick={handleSelect} before={ @@ -140,15 +140,17 @@ export function RoomMentionAutocomplete({ const avatarUrl = getRoomAvatarUrl(mx, room); const iconSrc = !dm && joinRuleToIconSrc(Icons, room.getJoinRule(), room.isSpaceRoom()); + const handleSelect = () => handleAutocomplete(room.getCanonicalAlias() ?? rId, room.name); + return ( ) => - onTabPress(evt, () => handleAutocomplete(rId, room.name)) + onTabPress(evt, handleSelect) } - onClick={() => handleAutocomplete(room.getCanonicalAlias() ?? rId, room.name)} + onClick={handleSelect} after={ {room.getCanonicalAlias() ?? ''} diff --git a/src/app/components/editor/input.ts b/src/app/components/editor/input.ts index 37aa72442..91386a877 100644 --- a/src/app/components/editor/input.ts +++ b/src/app/components/editor/input.ts @@ -74,7 +74,7 @@ const elementToInlineNode = (node: Element): MentionElement | EmoticonElement | if (typeof href !== 'string') return undefined; const [mxId] = parseMatrixToUrl(href); if (mxId) { - return createMentionElement(mxId, mxId, false); + return createMentionElement(mxId, parseNodeText(node) || mxId, false); } } return undefined; diff --git a/src/app/plugins/react-custom-html-parser.tsx b/src/app/plugins/react-custom-html-parser.tsx index aba5997dc..09f09d8f6 100644 --- a/src/app/plugins/react-custom-html-parser.tsx +++ b/src/app/plugins/react-custom-html-parser.tsx @@ -180,10 +180,7 @@ export const getReactCustomHtmlParser = ( mentionPrefix === '#' ? getRoomWithCanonicalAlias(mx, mentionId) : mx.getRoom(mentionId); - const mentionName = mentionRoom?.name; - const mentionDisplayName = - mentionName && (mentionName.startsWith('#') ? mentionName : `#${mentionName}`); return ( - {mentionDisplayName ?? mentionId} + {domToReact(children, opts)} ); } From 1d86c6da01bbab2ef6a7c268f17c9bcd6cfdd424 Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Thu, 19 Oct 2023 17:44:18 +1100 Subject: [PATCH 1073/1531] remove twemoji & katex usage (#1460) --- src/util/twemojify.jsx | 37 ++++--------------------------------- 1 file changed, 4 insertions(+), 33 deletions(-) diff --git a/src/util/twemojify.jsx b/src/util/twemojify.jsx index abe82a664..ad203a916 100644 --- a/src/util/twemojify.jsx +++ b/src/util/twemojify.jsx @@ -1,60 +1,31 @@ /* eslint-disable import/prefer-default-export */ -import React, { lazy, Suspense } from 'react'; - import linkifyHtml from 'linkify-html'; import parse from 'html-react-parser'; -import twemoji from 'twemoji'; import { sanitizeText } from './sanitize'; export const TWEMOJI_BASE_URL = 'https://cdn.jsdelivr.net/gh/twitter/twemoji@14.0.2/assets/'; -const Math = lazy(() => import('../app/atoms/math/Math')); - -const mathOptions = { - replace: (node) => { - const maths = node.attribs?.['data-mx-maths']; - if (maths) { - return ( - {maths}}> - - - ); - } - return null; - }, -}; - /** * @param {string} text - text to twemojify - * @param {object|undefined} opts - options for tweomoji.parse + * @param {object|undefined} opts - DEPRECATED - options for tweomoji.parse * @param {boolean} [linkify=false] - convert links to html tags (default: false) * @param {boolean} [sanitize=true] - sanitize html text (default: true) - * @param {boolean} [maths=false] - render maths (default: false) + * @param {boolean} [maths=false] - DEPRECATED - render maths (default: false) * @returns React component */ -export function twemojify(text, opts, linkify = false, sanitize = true, maths = false) { +export function twemojify(text, opts, linkify = false, sanitize = true) { if (typeof text !== 'string') return text; let content = text; - const options = opts ?? { base: TWEMOJI_BASE_URL }; - if (!options.base) { - options.base = TWEMOJI_BASE_URL; - } if (sanitize) { content = sanitizeText(content); } - content = twemoji.parse(content, options); if (linkify) { content = linkifyHtml(content, { target: '_blank', rel: 'noreferrer noopener', }); } - return parse(content, maths ? mathOptions : null); + return parse(content); } From 5eafa37cddab363cd348c08dc7242d5eeedb5f88 Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Thu, 19 Oct 2023 21:41:31 +1100 Subject: [PATCH 1074/1531] Change loading session message (#1461) --- src/app/organisms/settings/DeviceManage.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/organisms/settings/DeviceManage.jsx b/src/app/organisms/settings/DeviceManage.jsx index 7689f0f98..4a4f141cd 100644 --- a/src/app/organisms/settings/DeviceManage.jsx +++ b/src/app/organisms/settings/DeviceManage.jsx @@ -91,7 +91,7 @@ function DeviceManage() {
      - Loading devices... + Loading sessions...
      ); From 144cf7136887e2a31522511d42c3065ba17ade58 Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Thu, 19 Oct 2023 22:20:38 +1100 Subject: [PATCH 1075/1531] Add text reaction (#1462) --- src/app/components/emoji-board/EmojiBoard.tsx | 27 ++++++++++++++++++- src/app/organisms/room/message/Message.tsx | 1 + 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/app/components/emoji-board/EmojiBoard.tsx b/src/app/components/emoji-board/EmojiBoard.tsx index 067ebe39c..94ba14c1c 100644 --- a/src/app/components/emoji-board/EmojiBoard.tsx +++ b/src/app/components/emoji-board/EmojiBoard.tsx @@ -13,6 +13,7 @@ import React, { import { Badge, Box, + Chip, Icon, IconButton, Icons, @@ -623,6 +624,7 @@ export function EmojiBoard({ onEmojiSelect, onCustomEmojiSelect, onStickerSelect, + allowTextCustomEmoji, }: { tab?: EmojiBoardTab; onTabChange?: (tab: EmojiBoardTab) => void; @@ -632,6 +634,7 @@ export function EmojiBoard({ onEmojiSelect?: (unicode: string, shortcode: string) => void; onCustomEmojiSelect?: (mxc: string, shortcode: string) => void; onStickerSelect?: (mxc: string, shortcode: string) => void; + allowTextCustomEmoji?: boolean; }) { const emojiTab = tab === EmojiBoardTab.Emoji; const stickerTab = tab === EmojiBoardTab.Sticker; @@ -777,11 +780,33 @@ export function EmojiBoard({ {onTabChange && } } + after={ + allowTextCustomEmoji && result?.query ? ( + } + onClick={() => { + const searchInput = document.querySelector( + '[data-emoji-board-search="true"]' + ); + const textReaction = searchInput?.value.trim(); + if (!textReaction) return; + onCustomEmojiSelect?.(textReaction, textReaction); + requestClose(); + }} + > + React + + ) : ( + + ) + } onChange={handleOnChange} autoFocus={!mobileOrTablet()} /> diff --git a/src/app/organisms/room/message/Message.tsx b/src/app/organisms/room/message/Message.tsx index f5d25503e..e26f3662b 100644 --- a/src/app/organisms/room/message/Message.tsx +++ b/src/app/organisms/room/message/Message.tsx @@ -734,6 +734,7 @@ export const Message = as<'div', MessageProps>( { onReactionToggle(mEvent.getId()!, key); setEmojiBoard(false); From 03af183fb3e1d4fc52a5e96a4005eca32a1c0617 Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Fri, 20 Oct 2023 19:39:47 +1100 Subject: [PATCH 1076/1531] fix wrong following member count on message sent (#1464) --- src/app/hooks/useRoomEventReaders.ts | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/app/hooks/useRoomEventReaders.ts b/src/app/hooks/useRoomEventReaders.ts index f6bac27e5..6222bf92d 100644 --- a/src/app/hooks/useRoomEventReaders.ts +++ b/src/app/hooks/useRoomEventReaders.ts @@ -3,6 +3,11 @@ import { useEffect, useState } from 'react'; const getEventReaders = (room: Room, evtId?: string) => { if (!evtId) return []; + + // if eventId is locally generated + // we don't have read receipt for it yet + if (!evtId.startsWith('$')) return []; + const liveEvents = room.getLiveTimeline().getEvents(); const userIds: string[] = []; @@ -25,9 +30,25 @@ export const useRoomEventReaders = (room: Room, eventId?: string): string[] => { setReaders(getEventReaders(room, eventId)); }; + const handleLocalEcho: RoomEventHandlerMap[RoomEvent.LocalEchoUpdated] = ( + event, + r, + oldEventId + ) => { + // update members on local event id replaced + // with server generated id + if (r.roomId !== room.roomId || !oldEventId) return; + if (oldEventId.startsWith('$')) return; + if (oldEventId !== eventId) return; + + setReaders(getEventReaders(room, event.getId())); + }; + room.on(RoomEvent.Receipt, handleReceipt); + room.on(RoomEvent.LocalEchoUpdated, handleLocalEcho); return () => { room.removeListener(RoomEvent.Receipt, handleReceipt); + room.removeListener(RoomEvent.LocalEchoUpdated, handleLocalEcho); }; }, [room, eventId]); From 5dc613cd7957e06f2c29692a3b0d6d7e79311860 Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Sat, 21 Oct 2023 18:14:21 +1100 Subject: [PATCH 1077/1531] Fix auto read (#1466) * add height to bottom anchor * add width to bottom anchor * add make bottom anchor inline-block * try mark as read on focus receive --- src/app/hooks/useDocumentFocusChange.ts | 25 +++++++++++++++++++++ src/app/organisms/room/RoomTimeline.tsx | 30 ++++++++++++++++++------- 2 files changed, 47 insertions(+), 8 deletions(-) create mode 100644 src/app/hooks/useDocumentFocusChange.ts diff --git a/src/app/hooks/useDocumentFocusChange.ts b/src/app/hooks/useDocumentFocusChange.ts new file mode 100644 index 000000000..ae171b64a --- /dev/null +++ b/src/app/hooks/useDocumentFocusChange.ts @@ -0,0 +1,25 @@ +import { useEffect } from 'react'; + +export const useDocumentFocusChange = (onChange: (focus: boolean) => void) => { + useEffect(() => { + let localFocus = document.hasFocus(); + + const handleFocus = () => { + if (document.hasFocus()) { + if (localFocus) return; + localFocus = true; + onChange(localFocus); + } else if (localFocus) { + localFocus = false; + onChange(localFocus); + } + }; + + document.addEventListener('focusin', handleFocus); + document.addEventListener('focusout', handleFocus); + return () => { + document.removeEventListener('focusin', handleFocus); + document.removeEventListener('focusout', handleFocus); + }; + }, [onChange]); +}; diff --git a/src/app/organisms/room/RoomTimeline.tsx b/src/app/organisms/room/RoomTimeline.tsx index bc810812b..2a22245a1 100644 --- a/src/app/organisms/room/RoomTimeline.tsx +++ b/src/app/organisms/room/RoomTimeline.tsx @@ -133,6 +133,7 @@ import { MessageEvent } from '../../../types/matrix/room'; import initMatrix from '../../../client/initMatrix'; import { useKeyDown } from '../../hooks/useKeyDown'; import cons from '../../../client/state/cons'; +import { useDocumentFocusChange } from '../../hooks/useDocumentFocusChange'; const TimelineFloat = as<'div', css.TimelineFloatVariants>( ({ position, className, ...props }, ref) => ( @@ -606,13 +607,15 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli // keep paginating timeline and conditionally mark as read // otherwise we update timeline without paginating // so timeline can be updated with evt like: edits, reactions etc - if (atBottomRef.current && document.hasFocus()) { - if (!unreadInfo) { - markAsRead(mEvt.getRoomId()); + if (atBottomRef.current) { + if (document.hasFocus() && (!unreadInfo || mEvt.getSender() === mx.getUserId())) { + requestAnimationFrame(() => markAsRead(mEvt.getRoomId())); } - scrollToBottomRef.current.count += 1; - scrollToBottomRef.current.smooth = true; + if (document.hasFocus()) { + scrollToBottomRef.current.count += 1; + scrollToBottomRef.current.smooth = true; + } setTimeline((ct) => ({ ...ct, range: { @@ -627,7 +630,7 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli setUnreadInfo(getRoomUnreadInfo(room)); } }, - [room, unreadInfo] + [mx, room, unreadInfo] ) ); @@ -665,13 +668,13 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli const tryAutoMarkAsRead = useCallback(() => { if (!unreadInfo) { - markAsRead(room.roomId); + requestAnimationFrame(() => markAsRead(room.roomId)); return; } const evtTimeline = getEventTimeline(room, unreadInfo.readUptoEventId); const latestTimeline = evtTimeline && getFirstLinkedTimeline(evtTimeline, Direction.Forward); if (latestTimeline === room.getLiveTimeline()) { - markAsRead(room.roomId); + requestAnimationFrame(() => markAsRead(room.roomId)); } }, [room, unreadInfo]); @@ -705,6 +708,17 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli useCallback(() => atBottomAnchorRef.current, []) ); + useDocumentFocusChange( + useCallback( + (inFocus) => { + if (inFocus && atBottomRef.current) { + tryAutoMarkAsRead(); + } + }, + [tryAutoMarkAsRead] + ) + ); + // Handle up arrow edit useKeyDown( window, From d5ff55e23ed0ade6979e2d87bb48be9349e1ef98 Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Sat, 21 Oct 2023 18:14:33 +1100 Subject: [PATCH 1078/1531] Fix hotkeys (#1468) * use hotkey using key instead of which (default) * remove shift from block formatting hotkeys * smartly exit formatting with backspace * set markdown to off by default * exit formatting with escape --- src/app/components/editor/Toolbar.tsx | 23 +++------ .../editor/autocomplete/AutocompleteMenu.tsx | 6 +-- src/app/components/editor/keyboard.ts | 47 +++++++++++++++---- src/app/components/emoji-board/EmojiBoard.tsx | 6 +-- src/app/organisms/room/RoomInput.tsx | 8 ++-- src/app/organisms/room/RoomTimeline.tsx | 4 +- .../organisms/room/message/MessageEditor.tsx | 8 ++-- src/app/state/settings.ts | 2 +- src/app/utils/keyboard.ts | 6 +-- 9 files changed, 65 insertions(+), 45 deletions(-) diff --git a/src/app/components/editor/Toolbar.tsx b/src/app/components/editor/Toolbar.tsx index 342dd1060..766a1d839 100644 --- a/src/app/components/editor/Toolbar.tsx +++ b/src/app/components/editor/Toolbar.tsx @@ -261,33 +261,22 @@ export function Toolbar() { - } + tooltip={} /> - } + tooltip={} /> - } + tooltip={} /> - } + tooltip={} /> @@ -296,7 +285,9 @@ export function Toolbar() { } + tooltip={ + + } /> diff --git a/src/app/components/editor/autocomplete/AutocompleteMenu.tsx b/src/app/components/editor/autocomplete/AutocompleteMenu.tsx index e7c8df388..fc4327daf 100644 --- a/src/app/components/editor/autocomplete/AutocompleteMenu.tsx +++ b/src/app/components/editor/autocomplete/AutocompleteMenu.tsx @@ -1,6 +1,6 @@ import React, { ReactNode } from 'react'; import FocusTrap from 'focus-trap-react'; -import isHotkey from 'is-hotkey'; +import { isKeyHotkey } from 'is-hotkey'; import { Header, Menu, Scroll, config } from 'folds'; import * as css from './AutocompleteMenu.css'; @@ -22,8 +22,8 @@ export function AutocompleteMenu({ headerContent, requestClose, children }: Auto returnFocusOnDeactivate: false, clickOutsideDeactivates: true, allowOutsideClick: true, - isKeyForward: (evt: KeyboardEvent) => isHotkey('arrowdown', evt), - isKeyBackward: (evt: KeyboardEvent) => isHotkey('arrowup', evt), + isKeyForward: (evt: KeyboardEvent) => isKeyHotkey('arrowdown', evt), + isKeyBackward: (evt: KeyboardEvent) => isKeyHotkey('arrowup', evt), }} > diff --git a/src/app/components/editor/keyboard.ts b/src/app/components/editor/keyboard.ts index b6d4d692b..7031749e7 100644 --- a/src/app/components/editor/keyboard.ts +++ b/src/app/components/editor/keyboard.ts @@ -1,6 +1,6 @@ -import { isHotkey } from 'is-hotkey'; +import { isKeyHotkey } from 'is-hotkey'; import { KeyboardEvent } from 'react'; -import { Editor } from 'slate'; +import { Editor, Range } from 'slate'; import { isAnyMarkActive, isBlockActive, removeAllMark, toggleBlock, toggleMark } from './utils'; import { BlockType, MarkType } from './types'; @@ -15,10 +15,10 @@ export const INLINE_HOTKEYS: Record = { const INLINE_KEYS = Object.keys(INLINE_HOTKEYS); export const BLOCK_HOTKEYS: Record = { - 'mod+shift+7': BlockType.OrderedList, - 'mod+shift+8': BlockType.UnorderedList, - "mod+shift+'": BlockType.BlockQuote, - 'mod+shift+;': BlockType.CodeBlock, + 'mod+7': BlockType.OrderedList, + 'mod+8': BlockType.UnorderedList, + "mod+'": BlockType.BlockQuote, + 'mod+;': BlockType.CodeBlock, }; const BLOCK_KEYS = Object.keys(BLOCK_HOTKEYS); @@ -26,7 +26,36 @@ const BLOCK_KEYS = Object.keys(BLOCK_HOTKEYS); * @return boolean true if shortcut is toggled. */ export const toggleKeyboardShortcut = (editor: Editor, event: KeyboardEvent): boolean => { - if (isHotkey('mod+e', event)) { + if (isKeyHotkey('backspace', event) && editor.selection && Range.isCollapsed(editor.selection)) { + const startPoint = Range.start(editor.selection); + if (startPoint.offset !== 0) return false; + + const [parentNode, parentPath] = Editor.parent(editor, startPoint); + + if (Editor.isEditor(parentNode)) return false; + + if (parentNode.type === BlockType.Heading) { + toggleBlock(editor, BlockType.Paragraph); + return true; + } + if ( + parentNode.type === BlockType.CodeLine || + parentNode.type === BlockType.QuoteLine || + parentNode.type === BlockType.ListItem + ) { + // exit formatting only when line block + // is first of last of it's parent + const parentLocation = { at: parentPath }; + const [previousNode] = Editor.previous(editor, parentLocation) ?? []; + const [nextNode] = Editor.next(editor, parentLocation) ?? []; + if (!previousNode || !nextNode) { + toggleBlock(editor, BlockType.Paragraph); + return true; + } + } + } + + if (isKeyHotkey('mod+e', event) || isKeyHotkey('escape', event)) { if (isAnyMarkActive(editor)) { removeAllMark(editor); return true; @@ -40,7 +69,7 @@ export const toggleKeyboardShortcut = (editor: Editor, event: KeyboardEvent { - if (isHotkey(hotkey, event)) { + if (isKeyHotkey(hotkey, event)) { event.preventDefault(); toggleBlock(editor, BLOCK_HOTKEYS[hotkey]); return true; @@ -52,7 +81,7 @@ export const toggleKeyboardShortcut = (editor: Editor, event: KeyboardEvent { - if (isHotkey(hotkey, event)) { + if (isKeyHotkey(hotkey, event)) { event.preventDefault(); toggleMark(editor, INLINE_HOTKEYS[hotkey]); return true; diff --git a/src/app/components/emoji-board/EmojiBoard.tsx b/src/app/components/emoji-board/EmojiBoard.tsx index 94ba14c1c..52df92582 100644 --- a/src/app/components/emoji-board/EmojiBoard.tsx +++ b/src/app/components/emoji-board/EmojiBoard.tsx @@ -28,7 +28,7 @@ import { toRem, } from 'folds'; import FocusTrap from 'focus-trap-react'; -import isHotkey from 'is-hotkey'; +import { isKeyHotkey } from 'is-hotkey'; import classNames from 'classnames'; import { MatrixClient, Room } from 'matrix-js-sdk'; import { atom, useAtomValue, useSetAtom } from 'jotai'; @@ -769,9 +769,9 @@ export function EmojiBoard({ clickOutsideDeactivates: true, allowOutsideClick: true, isKeyForward: (evt: KeyboardEvent) => - !editableActiveElement() && isHotkey(['arrowdown', 'arrowright'], evt), + !editableActiveElement() && isKeyHotkey(['arrowdown', 'arrowright'], evt), isKeyBackward: (evt: KeyboardEvent) => - !editableActiveElement() && isHotkey(['arrowup', 'arrowleft'], evt), + !editableActiveElement() && isKeyHotkey(['arrowup', 'arrowleft'], evt), }} > ( const handleKeyDown: KeyboardEventHandler = useCallback( (evt) => { - if (enterForNewline ? isHotkey('shift+enter', evt) : isHotkey('enter', evt)) { + if (enterForNewline ? isKeyHotkey('shift+enter', evt) : isKeyHotkey('enter', evt)) { evt.preventDefault(); submit(); } - if (isHotkey('escape', evt)) { + if (isKeyHotkey('escape', evt)) { evt.preventDefault(); setReplyDraft(); } @@ -333,7 +333,7 @@ export const RoomInput = forwardRef( const handleKeyUp: KeyboardEventHandler = useCallback( (evt) => { - if (isHotkey('escape', evt)) { + if (isKeyHotkey('escape', evt)) { evt.preventDefault(); return; } diff --git a/src/app/organisms/room/RoomTimeline.tsx b/src/app/organisms/room/RoomTimeline.tsx index 2a22245a1..0852ecf7a 100644 --- a/src/app/organisms/room/RoomTimeline.tsx +++ b/src/app/organisms/room/RoomTimeline.tsx @@ -43,7 +43,7 @@ import { config, toRem, } from 'folds'; -import isHotkey from 'is-hotkey'; +import { isKeyHotkey } from 'is-hotkey'; import Linkify from 'linkify-react'; import { decryptFile, @@ -725,7 +725,7 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli useCallback( (evt) => { if ( - isHotkey('arrowup', evt) && + isKeyHotkey('arrowup', evt) && editableActiveElement() && document.activeElement?.getAttribute('data-editable-name') === 'RoomInput' && isEmptyEditor(editor) diff --git a/src/app/organisms/room/message/MessageEditor.tsx b/src/app/organisms/room/message/MessageEditor.tsx index f38cfbef7..385042ec1 100644 --- a/src/app/organisms/room/message/MessageEditor.tsx +++ b/src/app/organisms/room/message/MessageEditor.tsx @@ -3,7 +3,7 @@ import { Box, Chip, Icon, IconButton, Icons, Line, PopOut, Spinner, Text, as, co import { Editor, Transforms } from 'slate'; import { ReactEditor } from 'slate-react'; import { IContent, MatrixEvent, RelationType, Room } from 'matrix-js-sdk'; -import isHotkey from 'is-hotkey'; +import { isKeyHotkey } from 'is-hotkey'; import { AUTOCOMPLETE_PREFIXES, AutocompletePrefix, @@ -120,11 +120,11 @@ export const MessageEditor = as<'div', MessageEditorProps>( const handleKeyDown: KeyboardEventHandler = useCallback( (evt) => { - if (enterForNewline ? isHotkey('shift+enter', evt) : isHotkey('enter', evt)) { + if (enterForNewline ? isKeyHotkey('shift+enter', evt) : isKeyHotkey('enter', evt)) { evt.preventDefault(); handleSave(); } - if (isHotkey('escape', evt)) { + if (isKeyHotkey('escape', evt)) { evt.preventDefault(); onCancel(); } @@ -134,7 +134,7 @@ export const MessageEditor = as<'div', MessageEditorProps>( const handleKeyUp: KeyboardEventHandler = useCallback( (evt) => { - if (isHotkey('escape', evt)) { + if (isKeyHotkey('escape', evt)) { evt.preventDefault(); return; } diff --git a/src/app/state/settings.ts b/src/app/state/settings.ts index 7770a7586..26e3431dc 100644 --- a/src/app/state/settings.ts +++ b/src/app/state/settings.ts @@ -28,7 +28,7 @@ export interface Settings { const defaultSettings: Settings = { themeIndex: 0, useSystemTheme: true, - isMarkdown: true, + isMarkdown: false, editorToolbar: false, useSystemEmoji: false, diff --git a/src/app/utils/keyboard.ts b/src/app/utils/keyboard.ts index 56eeb9fcb..78aa25218 100644 --- a/src/app/utils/keyboard.ts +++ b/src/app/utils/keyboard.ts @@ -1,4 +1,4 @@ -import isHotkey from 'is-hotkey'; +import { isKeyHotkey } from 'is-hotkey'; import { KeyboardEventHandler } from 'react'; export interface KeyboardEventLike { @@ -12,14 +12,14 @@ export interface KeyboardEventLike { } export const onTabPress = (evt: KeyboardEventLike, callback: () => void) => { - if (isHotkey('tab', evt)) { + if (isKeyHotkey('tab', evt)) { evt.preventDefault(); callback(); } }; export const preventScrollWithArrowKey: KeyboardEventHandler = (evt) => { - if (isHotkey(['arrowup', 'arrowright', 'arrowdown', 'arrowleft'], evt)) { + if (isKeyHotkey(['arrowup', 'arrowright', 'arrowdown', 'arrowleft'], evt)) { evt.preventDefault(); } }; From 9200e22a7e0a8a1b15067bd8f4cc09295879452d Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Sat, 21 Oct 2023 21:16:36 +1100 Subject: [PATCH 1079/1531] fix backward delete with previous empty line (#1469) --- src/app/components/editor/keyboard.ts | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/app/components/editor/keyboard.ts b/src/app/components/editor/keyboard.ts index 7031749e7..2ea2dbe1e 100644 --- a/src/app/components/editor/keyboard.ts +++ b/src/app/components/editor/keyboard.ts @@ -1,6 +1,6 @@ import { isKeyHotkey } from 'is-hotkey'; import { KeyboardEvent } from 'react'; -import { Editor, Range } from 'slate'; +import { Editor, Element as SlateElement, Range, Transforms } from 'slate'; import { isAnyMarkActive, isBlockActive, removeAllMark, toggleBlock, toggleMark } from './utils'; import { BlockType, MarkType } from './types'; @@ -31,6 +31,9 @@ export const toggleKeyboardShortcut = (editor: Editor, event: KeyboardEvent Date: Sat, 21 Oct 2023 21:36:13 +1100 Subject: [PATCH 1080/1531] Update default server list in config.json (#1467) * Remove halogen.city * Update config.json * Update config.json --- config.json | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/config.json b/config.json index c919882f1..ac7b1f323 100644 --- a/config.json +++ b/config.json @@ -1,11 +1,13 @@ { "defaultHomeserver": 3, "homeserverList": [ + "0wnz.at", "converser.eu", "envs.net", - "halogen.city", "matrix.org", - "mozilla.org" + "monero.social", + "mozilla.org", + "xmr.se" ], "allowCustomHomeservers": true } From b80f801d235f1253acfae8db87b00a687b246a06 Mon Sep 17 00:00:00 2001 From: Krishan <33421343+kfiven@users.noreply.github.com> Date: Sat, 21 Oct 2023 21:37:30 +1100 Subject: [PATCH 1081/1531] Release v3.0.0 (#1463) * Release v3.0.0 * Update package-lock.json * Update cons.js --- package-lock.json | 4 ++-- package.json | 2 +- src/client/state/cons.js | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7354f3d5c..8c2e80d01 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "cinny", - "version": "2.2.6", + "version": "3.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "cinny", - "version": "2.2.6", + "version": "3.0.0", "license": "AGPL-3.0-only", "dependencies": { "@fontsource/inter": "4.5.14", diff --git a/package.json b/package.json index 8f37636c7..0f1bfa75e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cinny", - "version": "2.2.6", + "version": "3.0.0", "description": "Yet another matrix client", "main": "index.js", "engines": { diff --git a/src/client/state/cons.js b/src/client/state/cons.js index 873c4e333..5d29d1df7 100644 --- a/src/client/state/cons.js +++ b/src/client/state/cons.js @@ -1,5 +1,5 @@ const cons = { - version: '2.2.6', + version: '3.0.0', secretKey: { ACCESS_TOKEN: 'cinny_access_token', DEVICE_ID: 'cinny_device_id', From 1ff312d236bc8ad9cad02bd421d0e8e3a00a47e2 Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Mon, 23 Oct 2023 21:42:27 +1100 Subject: [PATCH 1082/1531] Fix edit related bugs (#1477) * fix missing empty line on edit * fix edit save after adding formatting to plaintext * fix reading edit content with wrong key --- src/app/components/editor/input.ts | 3 ++ src/app/organisms/room/RoomTimeline.tsx | 10 +++--- .../organisms/room/message/MessageEditor.tsx | 31 ++++++++++++------- 3 files changed, 29 insertions(+), 15 deletions(-) diff --git a/src/app/components/editor/input.ts b/src/app/components/editor/input.ts index 91386a877..5860df04f 100644 --- a/src/app/components/editor/input.ts +++ b/src/app/components/editor/input.ts @@ -138,6 +138,7 @@ const parseBlockquoteNode = (node: Element): BlockQuoteElement => { } if (isTag(child)) { if (child.name === 'br') { + lineHolder.push({ text: '' }); appendLine(); return; } @@ -202,6 +203,7 @@ const parseListNode = (node: Element): OrderedListElement | UnorderedListElement } if (isTag(child)) { if (child.name === 'br') { + lineHolder.push({ text: '' }); appendLine(); return; } @@ -260,6 +262,7 @@ export const domToEditorInput = (domNodes: ChildNode[]): Descendant[] => { } if (isTag(node)) { if (node.name === 'br') { + lineHolder.push({ text: '' }); appendLine(); return; } diff --git a/src/app/organisms/room/RoomTimeline.tsx b/src/app/organisms/room/RoomTimeline.tsx index 0852ecf7a..2cfbd6584 100644 --- a/src/app/organisms/room/RoomTimeline.tsx +++ b/src/app/organisms/room/RoomTimeline.tsx @@ -615,6 +615,8 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli if (document.hasFocus()) { scrollToBottomRef.current.count += 1; scrollToBottomRef.current.smooth = true; + } else if (!unreadInfo) { + setUnreadInfo(getRoomUnreadInfo(room)); } setTimeline((ct) => ({ ...ct, @@ -919,7 +921,7 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli if (!replyEvt) return; const editedReply = getEditedEvent(replyId, replyEvt, room.getUnfilteredTimelineSet()); const { body, formatted_body: formattedBody }: Record = - editedReply?.getContent()['m.new.content'] ?? replyEvt.getContent(); + editedReply?.getContent()['m.new_content'] ?? replyEvt.getContent(); const senderId = replyEvt.getSender(); if (senderId && typeof body === 'string') { setReplyDraft({ @@ -982,7 +984,7 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli renderText: (mEventId, mEvent, timelineSet) => { const editedEvent = getEditedEvent(mEventId, mEvent, timelineSet); const { body, formatted_body: customBody }: Record = - editedEvent?.getContent()['m.new.content'] ?? mEvent.getContent(); + editedEvent?.getContent()['m.new_content'] ?? mEvent.getContent(); if (typeof body !== 'string') return null; return ( @@ -1002,7 +1004,7 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli renderEmote: (mEventId, mEvent, timelineSet) => { const editedEvent = getEditedEvent(mEventId, mEvent, timelineSet); const { body, formatted_body: customBody } = - editedEvent?.getContent()['m.new.content'] ?? mEvent.getContent(); + editedEvent?.getContent()['m.new_content'] ?? mEvent.getContent(); const senderId = mEvent.getSender() ?? ''; const senderDisplayName = @@ -1027,7 +1029,7 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli renderNotice: (mEventId, mEvent, timelineSet) => { const editedEvent = getEditedEvent(mEventId, mEvent, timelineSet); const { body, formatted_body: customBody }: Record = - editedEvent?.getContent()['m.new.content'] ?? mEvent.getContent(); + editedEvent?.getContent()['m.new_content'] ?? mEvent.getContent(); if (typeof body !== 'string') return null; return ( diff --git a/src/app/organisms/room/message/MessageEditor.tsx b/src/app/organisms/room/message/MessageEditor.tsx index 385042ec1..776e1d4d8 100644 --- a/src/app/organisms/room/message/MessageEditor.tsx +++ b/src/app/organisms/room/message/MessageEditor.tsx @@ -53,16 +53,22 @@ export const MessageEditor = as<'div', MessageEditorProps>( const [autocompleteQuery, setAutocompleteQuery] = useState>(); - const getPrevBodyAndFormattedBody = useCallback(() => { + const getPrevBodyAndFormattedBody = useCallback((): [ + string | undefined, + string | undefined + ] => { const evtId = mEvent.getId()!; const evtTimeline = room.getTimelineForEvent(evtId); const editedEvent = evtTimeline && getEditedEvent(evtId, mEvent, evtTimeline.getTimelineSet()); const { body, formatted_body: customHtml }: Record = - editedEvent?.getContent()['m.new.content'] ?? mEvent.getContent(); + editedEvent?.getContent()['m.new_content'] ?? mEvent.getContent(); - return [body, customHtml]; + return [ + typeof body === 'string' ? body : undefined, + typeof customHtml === 'string' ? customHtml : undefined, + ]; }, [room, mEvent]); const [saveState, save] = useAsyncCallback( @@ -78,14 +84,17 @@ export const MessageEditor = as<'div', MessageEditorProps>( const [prevBody, prevCustomHtml] = getPrevBodyAndFormattedBody(); if (plainText === '') return undefined; - if ( - typeof prevCustomHtml === 'string' && - trimReplyFromFormattedBody(prevCustomHtml) === customHtml - ) { - return undefined; - } - if (!prevCustomHtml && typeof prevBody === 'string' && prevBody === plainText) { - return undefined; + if (prevBody) { + if (prevCustomHtml && trimReplyFromFormattedBody(prevCustomHtml) === customHtml) { + return undefined; + } + if ( + !prevCustomHtml && + prevBody === plainText && + customHtmlEqualsPlainText(customHtml, plainText) + ) { + return undefined; + } } const newContent: IContent = { From c0abb0d50da8ae03fa184514c4dfdf4479635f99 Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Mon, 23 Oct 2023 21:43:07 +1100 Subject: [PATCH 1083/1531] fix thread fallback (#1478) --- src/app/hooks/useRoomLatestRenderedEvent.ts | 4 ++-- src/app/organisms/room/RoomTimeline.tsx | 3 ++- src/app/utils/room.ts | 4 ++++ 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/app/hooks/useRoomLatestRenderedEvent.ts b/src/app/hooks/useRoomLatestRenderedEvent.ts index 428e7b52a..fd0ed9e5e 100644 --- a/src/app/hooks/useRoomLatestRenderedEvent.ts +++ b/src/app/hooks/useRoomLatestRenderedEvent.ts @@ -4,7 +4,7 @@ import { useEffect, useState } from 'react'; import { settingsAtom } from '../state/settings'; import { useSetting } from '../state/hooks/settings'; import { MessageEvent, StateEvent } from '../../types/matrix/room'; -import { isMembershipChanged } from '../utils/room'; +import { isMembershipChanged, reactionOrEditEvent } from '../utils/room'; export const useRoomLatestRenderedEvent = (room: Room) => { const [hideMembershipEvents] = useSetting(settingsAtom, 'hideMembershipEvents'); @@ -19,7 +19,7 @@ export const useRoomLatestRenderedEvent = (room: Room) => { const evt = liveEvents[i]; if (!evt) continue; - if (evt.isRelation()) continue; + if (reactionOrEditEvent(evt)) continue; if (evt.getType() === StateEvent.RoomMember) { const membershipChanged = isMembershipChanged(evt); if (membershipChanged && hideMembershipEvents) continue; diff --git a/src/app/organisms/room/RoomTimeline.tsx b/src/app/organisms/room/RoomTimeline.tsx index 2cfbd6584..09f332603 100644 --- a/src/app/organisms/room/RoomTimeline.tsx +++ b/src/app/organisms/room/RoomTimeline.tsx @@ -86,6 +86,7 @@ import { getMemberDisplayName, getReactionContent, isMembershipChanged, + reactionOrEditEvent, } from '../../utils/room'; import { useSetting } from '../../state/hooks/settings'; import { settingsAtom } from '../../state/settings'; @@ -1632,7 +1633,7 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli prevEvent.getType() === mEvent.getType() && minuteDifference(prevEvent.getTs(), mEvent.getTs()) < 2; - const eventJSX = mEvent.isRelation() + const eventJSX = reactionOrEditEvent(mEvent) ? null : renderMatrixEvent(mEventId, mEvent, item, timelineSet, collapsed); prevEvent = mEvent; diff --git a/src/app/utils/room.ts b/src/app/utils/room.ts index 1c015a1ff..adb6dc088 100644 --- a/src/app/utils/room.ts +++ b/src/app/utils/room.ts @@ -380,3 +380,7 @@ export const getLatestEditableEvt = ( } return undefined; }; + +export const reactionOrEditEvent = (mEvent: MatrixEvent) => + mEvent.getRelation()?.rel_type === RelationType.Annotation || + mEvent.getRelation()?.rel_type === RelationType.Replace; From 122ff2d21670b715d2b1d16f7832bf43364ed3fa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Oct 2023 21:49:38 +1100 Subject: [PATCH 1084/1531] Bump thollander/actions-comment-pull-request from 2.4.0 to 2.4.3 (#1480) Bumps [thollander/actions-comment-pull-request](https://github.com/thollander/actions-comment-pull-request) from 2.4.0 to 2.4.3. - [Release notes](https://github.com/thollander/actions-comment-pull-request/releases) - [Commits](https://github.com/thollander/actions-comment-pull-request/compare/dadb7667129e23f12ca3925c90dc5cd7121ab57e...1d3973dc4b8e1399c0620d3f2b1aa5e795465308) --- updated-dependencies: - dependency-name: thollander/actions-comment-pull-request dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/deploy-pull-request.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deploy-pull-request.yml b/.github/workflows/deploy-pull-request.yml index c4d824365..3ea1d6b04 100644 --- a/.github/workflows/deploy-pull-request.yml +++ b/.github/workflows/deploy-pull-request.yml @@ -45,7 +45,7 @@ jobs: NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID_PR_CINNY }} timeout-minutes: 1 - name: Comment preview on PR - uses: thollander/actions-comment-pull-request@dadb7667129e23f12ca3925c90dc5cd7121ab57e + uses: thollander/actions-comment-pull-request@1d3973dc4b8e1399c0620d3f2b1aa5e795465308 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: From 7b64258af6be85036fa051d7bd09cfcc6533aa15 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Oct 2023 22:03:00 +1100 Subject: [PATCH 1085/1531] Bump actions/setup-node from 3.6.0 to 3.8.1 (#1401) Bumps [actions/setup-node](https://github.com/actions/setup-node) from 3.6.0 to 3.8.1. - [Release notes](https://github.com/actions/setup-node/releases) - [Commits](https://github.com/actions/setup-node/compare/v3.6.0...v3.8.1) --- updated-dependencies: - dependency-name: actions/setup-node dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build-pull-request.yml | 2 +- .github/workflows/netlify-dev.yml | 2 +- .github/workflows/prod-deploy.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-pull-request.yml b/.github/workflows/build-pull-request.yml index d77310558..f2f93feb4 100644 --- a/.github/workflows/build-pull-request.yml +++ b/.github/workflows/build-pull-request.yml @@ -14,7 +14,7 @@ jobs: - name: Checkout repository uses: actions/checkout@v3.5.3 - name: Setup node - uses: actions/setup-node@v3.6.0 + uses: actions/setup-node@v3.8.1 with: node-version: 18.12.1 cache: "npm" diff --git a/.github/workflows/netlify-dev.yml b/.github/workflows/netlify-dev.yml index 8935c510f..15698e173 100644 --- a/.github/workflows/netlify-dev.yml +++ b/.github/workflows/netlify-dev.yml @@ -13,7 +13,7 @@ jobs: - name: Checkout repository uses: actions/checkout@v3.5.3 - name: Setup node - uses: actions/setup-node@v3.6.0 + uses: actions/setup-node@v3.8.1 with: node-version: 18.12.1 cache: "npm" diff --git a/.github/workflows/prod-deploy.yml b/.github/workflows/prod-deploy.yml index 66f405239..d42eef8e0 100644 --- a/.github/workflows/prod-deploy.yml +++ b/.github/workflows/prod-deploy.yml @@ -12,7 +12,7 @@ jobs: - name: Checkout repository uses: actions/checkout@v3.5.3 - name: Setup node - uses: actions/setup-node@v3.6.0 + uses: actions/setup-node@v3.8.1 with: node-version: 18.12.1 cache: "npm" From 8731f58948dcd015c5880d42a5fe6eb832519a0c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Oct 2023 22:05:38 +1100 Subject: [PATCH 1086/1531] Bump nwtgck/actions-netlify from 2.0.0 to 2.1.0 (#1402) Bumps [nwtgck/actions-netlify](https://github.com/nwtgck/actions-netlify) from 2.0.0 to 2.1.0. - [Release notes](https://github.com/nwtgck/actions-netlify/releases) - [Changelog](https://github.com/nwtgck/actions-netlify/blob/develop/CHANGELOG.md) - [Commits](https://github.com/nwtgck/actions-netlify/compare/5da65c9f74c7961c5501a3ba329b8d0912f39c03...7a92f00dde8c92a5a9e8385ec2919775f7647352) --- updated-dependencies: - dependency-name: nwtgck/actions-netlify dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/deploy-pull-request.yml | 2 +- .github/workflows/netlify-dev.yml | 2 +- .github/workflows/prod-deploy.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/deploy-pull-request.yml b/.github/workflows/deploy-pull-request.yml index 3ea1d6b04..12eabbe45 100644 --- a/.github/workflows/deploy-pull-request.yml +++ b/.github/workflows/deploy-pull-request.yml @@ -32,7 +32,7 @@ jobs: path: dist - name: Deploy to Netlify id: netlify - uses: nwtgck/actions-netlify@5da65c9f74c7961c5501a3ba329b8d0912f39c03 + uses: nwtgck/actions-netlify@7a92f00dde8c92a5a9e8385ec2919775f7647352 with: publish-dir: dist deploy-message: "Deploy PR ${{ steps.pr.outputs.id }}" diff --git a/.github/workflows/netlify-dev.yml b/.github/workflows/netlify-dev.yml index 15698e173..411b6e3e3 100644 --- a/.github/workflows/netlify-dev.yml +++ b/.github/workflows/netlify-dev.yml @@ -24,7 +24,7 @@ jobs: NODE_OPTIONS: "--max_old_space_size=4096" run: npm run build - name: Deploy to Netlify - uses: nwtgck/actions-netlify@5da65c9f74c7961c5501a3ba329b8d0912f39c03 + uses: nwtgck/actions-netlify@7a92f00dde8c92a5a9e8385ec2919775f7647352 with: publish-dir: dist deploy-message: "Dev deploy ${{ github.sha }}" diff --git a/.github/workflows/prod-deploy.yml b/.github/workflows/prod-deploy.yml index d42eef8e0..63fc342c9 100644 --- a/.github/workflows/prod-deploy.yml +++ b/.github/workflows/prod-deploy.yml @@ -23,7 +23,7 @@ jobs: NODE_OPTIONS: "--max_old_space_size=4096" run: npm run build - name: Deploy to Netlify - uses: nwtgck/actions-netlify@5da65c9f74c7961c5501a3ba329b8d0912f39c03 + uses: nwtgck/actions-netlify@7a92f00dde8c92a5a9e8385ec2919775f7647352 with: publish-dir: dist deploy-message: "Prod deploy ${{ github.ref_name }}" From c7e5c1fce813af88eba15d62c9294d53d2b858b8 Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Tue, 24 Oct 2023 22:21:39 +1100 Subject: [PATCH 1087/1531] Fix reply username overflow (#1501) * fix reply overflow * fix shrinkable typing indicator * fix message avatar hover & cursor --- src/app/components/message/Reply.tsx | 6 +++++- src/app/components/message/layout/layout.css.ts | 2 +- src/app/components/typing-indicator/TypingIndicator.tsx | 1 + src/app/organisms/room/message/Message.tsx | 8 +++++++- src/app/organisms/room/message/styles.css.ts | 4 ++++ 5 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/app/components/message/Reply.tsx b/src/app/components/message/Reply.tsx index a8800fa88..6eaab31ed 100644 --- a/src/app/components/message/Reply.tsx +++ b/src/app/components/message/Reply.tsx @@ -67,7 +67,11 @@ export const Reply = as<'div', ReplyProps>( {...props} ref={ref} > - + {sender && ( diff --git a/src/app/components/message/layout/layout.css.ts b/src/app/components/message/layout/layout.css.ts index ff31baa59..7b1a267df 100644 --- a/src/app/components/message/layout/layout.css.ts +++ b/src/app/components/message/layout/layout.css.ts @@ -118,8 +118,8 @@ export const CompactHeader = style([ export const AvatarBase = style({ paddingTop: toRem(4), - cursor: 'pointer', transition: 'transform 200ms cubic-bezier(0, 0.8, 0.67, 0.97)', + alignSelf: 'start', selectors: { '&:hover': { diff --git a/src/app/components/typing-indicator/TypingIndicator.tsx b/src/app/components/typing-indicator/TypingIndicator.tsx index 336903594..e52558738 100644 --- a/src/app/components/typing-indicator/TypingIndicator.tsx +++ b/src/app/components/typing-indicator/TypingIndicator.tsx @@ -10,6 +10,7 @@ export const TypingIndicator = as<'div', TypingIndicatorProps>(({ size, style, . ( const avatarJSX = !collapse && messageLayout !== 1 && ( - + {senderAvatarMxc ? ( Date: Wed, 25 Oct 2023 16:50:38 +1100 Subject: [PATCH 1088/1531] Room input improvements (#1502) * prevent context menu when editing message * send sticker body (#1479) * update emojiboard search text reaction input label * stop generating upload image thumbnail (#1475) * maintain upload order * Fix message options spinner variant * add markdown toggle in editor toolbar * fix heading toggle icon update with cursor move * add hotkeys for heading * change editor markdown btn style * use Ctrl + Enter to send message (#1470) * fix reaction tooltip word-break * add shift in editor hokeys with number * stop parsing markdown in link --- src/app/components/editor/Editor.css.ts | 4 + src/app/components/editor/Toolbar.tsx | 92 ++++++++++++++++--- src/app/components/editor/keyboard.ts | 19 +++- src/app/components/editor/utils.ts | 10 ++ src/app/components/emoji-board/EmojiBoard.tsx | 12 ++- src/app/organisms/room/RoomInput.tsx | 37 +++----- src/app/organisms/room/message/Message.tsx | 6 +- .../organisms/room/message/MessageEditor.tsx | 2 +- src/app/organisms/room/message/Reactions.tsx | 2 +- src/app/organisms/room/message/styles.css.ts | 4 + src/app/organisms/room/msgContent.ts | 13 --- src/app/organisms/settings/Settings.jsx | 4 +- src/app/utils/markdown.ts | 28 ++++-- 13 files changed, 162 insertions(+), 71 deletions(-) diff --git a/src/app/components/editor/Editor.css.ts b/src/app/components/editor/Editor.css.ts index edce743f2..09a444ec1 100644 --- a/src/app/components/editor/Editor.css.ts +++ b/src/app/components/editor/Editor.css.ts @@ -66,3 +66,7 @@ export const EditorToolbarBase = style({ export const EditorToolbar = style({ padding: config.space.S100, }); + +export const MarkdownBtnBox = style({ + paddingRight: config.space.S100, +}); diff --git a/src/app/components/editor/Toolbar.tsx b/src/app/components/editor/Toolbar.tsx index 766a1d839..6feae0095 100644 --- a/src/app/components/editor/Toolbar.tsx +++ b/src/app/components/editor/Toolbar.tsx @@ -19,6 +19,7 @@ import { import React, { ReactNode, useState } from 'react'; import { ReactEditor, useSlate } from 'slate-react'; import { + headingLevel, isAnyMarkActive, isBlockActive, isMarkActive, @@ -31,6 +32,8 @@ import { BlockType, MarkType } from './types'; import { HeadingLevel } from './slate'; import { isMacOS } from '../../utils/user-agent'; import { KeySymbol } from '../../utils/key-symbol'; +import { useSetting } from '../../state/hooks/settings'; +import { settingsAtom } from '../../state/settings'; function BtnTooltip({ text, shortCode }: { text: string; shortCode?: string }) { return ( @@ -115,13 +118,13 @@ export function BlockButton({ format, icon, tooltip }: BlockButtonProps) { export function HeadingBlockButton() { const editor = useSlate(); - const [level, setLevel] = useState(1); + const level = headingLevel(editor); const [open, setOpen] = useState(false); const isActive = isBlockActive(editor, BlockType.Heading); + const modKey = isMacOS() ? KeySymbol.Command : 'Ctrl'; const handleMenuSelect = (selectedLevel: HeadingLevel) => { setOpen(false); - setLevel(selectedLevel); toggleBlock(editor, BlockType.Heading, { level: selectedLevel }); ReactEditor.focus(editor); }; @@ -130,7 +133,6 @@ export function HeadingBlockButton() { - handleMenuSelect(1)} size="400" radii="300"> - - - handleMenuSelect(2)} size="400" radii="300"> - - - handleMenuSelect(3)} size="400" radii="300"> - - + } + delay={500} + > + {(triggerRef) => ( + handleMenuSelect(1)} + size="400" + radii="300" + > + + + )} + + } + delay={500} + > + {(triggerRef) => ( + handleMenuSelect(2)} + size="400" + radii="300" + > + + + )} + + } + delay={500} + > + {(triggerRef) => ( + handleMenuSelect(3)} + size="400" + radii="300" + > + + + )} + @@ -169,7 +207,7 @@ export function HeadingBlockButton() { size="400" radii="300" > - + )} @@ -210,8 +248,10 @@ export function ExitFormatting({ tooltip }: ExitFormattingProps) { export function Toolbar() { const editor = useSlate(); const modKey = isMacOS() ? KeySymbol.Command : 'Ctrl'; + const disableInline = isBlockActive(editor, BlockType.CodeBlock); const canEscape = isAnyMarkActive(editor) || !isBlockActive(editor, BlockType.Paragraph); + const [isMarkdown, setIsMarkdown] = useSetting(settingsAtom, 'isMarkdown'); return ( @@ -271,12 +311,12 @@ export function Toolbar() { } + tooltip={} /> } + tooltip={} /> @@ -292,6 +332,28 @@ export function Toolbar() { )} + + } + delay={500} + > + {(triggerRef) => ( + setIsMarkdown(!isMarkdown)} + aria-pressed={isMarkdown} + size="300" + radii="300" + disabled={disableInline || !!isAnyMarkActive(editor)} + > + + + )} + + + diff --git a/src/app/components/editor/keyboard.ts b/src/app/components/editor/keyboard.ts index 2ea2dbe1e..370f3e827 100644 --- a/src/app/components/editor/keyboard.ts +++ b/src/app/components/editor/keyboard.ts @@ -15,12 +15,15 @@ export const INLINE_HOTKEYS: Record = { const INLINE_KEYS = Object.keys(INLINE_HOTKEYS); export const BLOCK_HOTKEYS: Record = { - 'mod+7': BlockType.OrderedList, - 'mod+8': BlockType.UnorderedList, + 'mod+shift+7': BlockType.OrderedList, + 'mod+shift+8': BlockType.UnorderedList, "mod+'": BlockType.BlockQuote, 'mod+;': BlockType.CodeBlock, }; const BLOCK_KEYS = Object.keys(BLOCK_HOTKEYS); +const isHeading1 = isKeyHotkey('mod+shift+1'); +const isHeading2 = isKeyHotkey('mod+shift+2'); +const isHeading3 = isKeyHotkey('mod+shift+3'); /** * @return boolean true if shortcut is toggled. @@ -86,6 +89,18 @@ export const toggleKeyboardShortcut = (editor: Editor, event: KeyboardEvent { return !!match; }; +export const headingLevel = (editor: Editor): HeadingLevel | undefined => { + const [nodeEntry] = Editor.nodes(editor, { + match: (node) => Element.isElement(node) && node.type === BlockType.Heading, + }); + const [node] = nodeEntry ?? []; + if (!node) return undefined; + if ('level' in node) return node.level; + return undefined; +}; + type BlockOption = { level: HeadingLevel }; const NESTED_BLOCK = [ BlockType.OrderedList, diff --git a/src/app/components/emoji-board/EmojiBoard.tsx b/src/app/components/emoji-board/EmojiBoard.tsx index 52df92582..5452722fe 100644 --- a/src/app/components/emoji-board/EmojiBoard.tsx +++ b/src/app/components/emoji-board/EmojiBoard.tsx @@ -68,6 +68,7 @@ export type EmojiItemInfo = { type: EmojiType; data: string; shortcode: string; + label: string; }; const getDOMGroupId = (id: string): string => `EmojiBoardGroup-${id}`; @@ -75,13 +76,15 @@ const getDOMGroupId = (id: string): string => `EmojiBoardGroup-${id}`; const getEmojiItemInfo = (element: Element): EmojiItemInfo | undefined => { const type = element.getAttribute('data-emoji-type') as EmojiType | undefined; const data = element.getAttribute('data-emoji-data'); + const label = element.getAttribute('title'); const shortcode = element.getAttribute('data-emoji-shortcode'); - if (type && data && shortcode) + if (type && data && shortcode && label) return { type, data, shortcode, + label, }; return undefined; }; @@ -633,7 +636,7 @@ export function EmojiBoard({ returnFocusOnDeactivate?: boolean; onEmojiSelect?: (unicode: string, shortcode: string) => void; onCustomEmojiSelect?: (mxc: string, shortcode: string) => void; - onStickerSelect?: (mxc: string, shortcode: string) => void; + onStickerSelect?: (mxc: string, shortcode: string, label: string) => void; allowTextCustomEmoji?: boolean; }) { const emojiTab = tab === EmojiBoardTab.Emoji; @@ -712,7 +715,7 @@ export function EmojiBoard({ if (!evt.altKey && !evt.shiftKey) requestClose(); } if (emojiInfo.type === EmojiType.Sticker) { - onStickerSelect?.(emojiInfo.data, emojiInfo.shortcode); + onStickerSelect?.(emojiInfo.data, emojiInfo.shortcode, emojiInfo.label); if (!evt.altKey && !evt.shiftKey) requestClose(); } }; @@ -783,7 +786,7 @@ export function EmojiBoard({ data-emoji-board-search variant="SurfaceVariant" size="400" - placeholder="Search" + placeholder={allowTextCustomEmoji ? 'Search or Text Reaction ' : 'Search'} maxLength={50} after={ allowTextCustomEmoji && result?.query ? ( @@ -791,6 +794,7 @@ export function EmojiBoard({ variant="Primary" radii="Pill" after={} + outlined onClick={() => { const searchInput = document.querySelector( '[data-emoji-board-search="true"]' diff --git a/src/app/organisms/room/RoomInput.tsx b/src/app/organisms/room/RoomInput.tsx index f7b219be1..8dc4e6447 100644 --- a/src/app/organisms/room/RoomInput.tsx +++ b/src/app/organisms/room/RoomInput.tsx @@ -29,7 +29,6 @@ import { config, toRem, } from 'folds'; -import to from 'await-to-js'; import { useMatrixClient } from '../../hooks/useMatrixClient'; import { @@ -216,30 +215,24 @@ export const RoomInput = forwardRef( }; const handleSendUpload = async (uploads: UploadSuccess[]) => { - const sendPromises = uploads.map(async (upload) => { + const contentsPromises = uploads.map(async (upload) => { const fileItem = selectedFiles.find((f) => f.file === upload.file); - if (fileItem && fileItem.file.type.startsWith('image')) { - const [imgError, imgContent] = await to(getImageMsgContent(mx, fileItem, upload.mxc)); - if (imgError) console.warn(imgError); - if (imgContent) mx.sendMessage(roomId, imgContent); - return; + if (!fileItem) throw new Error('Broken upload'); + + if (fileItem.file.type.startsWith('image')) { + return getImageMsgContent(mx, fileItem, upload.mxc); } - if (fileItem && fileItem.file.type.startsWith('video')) { - const [videoError, videoContent] = await to(getVideoMsgContent(mx, fileItem, upload.mxc)); - if (videoError) console.warn(videoError); - if (videoContent) mx.sendMessage(roomId, videoContent); - return; + if (fileItem.file.type.startsWith('video')) { + return getVideoMsgContent(mx, fileItem, upload.mxc); } - if (fileItem && fileItem.file.type.startsWith('audio')) { - mx.sendMessage(roomId, getAudioMsgContent(fileItem, upload.mxc)); - return; - } - if (fileItem) { - mx.sendMessage(roomId, getFileMsgContent(fileItem, upload.mxc)); + if (fileItem.file.type.startsWith('audio')) { + return getAudioMsgContent(fileItem, upload.mxc); } + return getFileMsgContent(fileItem, upload.mxc); }); handleCancelUpload(uploads); - await Promise.allSettled(sendPromises); + const contents = fulfilledPromiseSettledResult(await Promise.allSettled(contentsPromises)); + contents.forEach((content) => mx.sendMessage(roomId, content)); }; const submit = useCallback(() => { @@ -319,7 +312,7 @@ export const RoomInput = forwardRef( const handleKeyDown: KeyboardEventHandler = useCallback( (evt) => { - if (enterForNewline ? isKeyHotkey('shift+enter', evt) : isKeyHotkey('enter', evt)) { + if (isKeyHotkey('mod+enter', evt) || (!enterForNewline && isKeyHotkey('enter', evt))) { evt.preventDefault(); submit(); } @@ -359,7 +352,7 @@ export const RoomInput = forwardRef( moveCursor(editor); }; - const handleStickerSelect = async (mxc: string, shortcode: string) => { + const handleStickerSelect = async (mxc: string, shortcode: string, label: string) => { const stickerUrl = mx.mxcUrlToHttp(mxc); if (!stickerUrl) return; @@ -369,7 +362,7 @@ export const RoomInput = forwardRef( ); mx.sendEvent(roomId, EventType.Sticker, { - body: shortcode, + body: label, url: mxc, info, }); diff --git a/src/app/organisms/room/message/Message.tsx b/src/app/organisms/room/message/Message.tsx index 14996a9a3..25d894f31 100644 --- a/src/app/organisms/room/message/Message.tsx +++ b/src/app/organisms/room/message/Message.tsx @@ -392,7 +392,7 @@ export const MessageDeleteItem = as< variant="Critical" before={ deleteState.status === AsyncStatus.Loading ? ( - + ) : undefined } aria-disabled={deleteState.status === AsyncStatus.Loading} @@ -522,7 +522,7 @@ export const MessageReportItem = as< variant="Critical" before={ reportState.status === AsyncStatus.Loading ? ( - + ) : undefined } aria-disabled={ @@ -702,7 +702,7 @@ export const Message = as<'div', MessageProps>( ); const handleContextMenu: MouseEventHandler = (evt) => { - if (evt.altKey || !window.getSelection()?.isCollapsed) return; + if (evt.altKey || !window.getSelection()?.isCollapsed || edit) return; const tag = (evt.target as any).tagName; if (typeof tag === 'string' && tag.toLowerCase() === 'a') return; evt.preventDefault(); diff --git a/src/app/organisms/room/message/MessageEditor.tsx b/src/app/organisms/room/message/MessageEditor.tsx index 776e1d4d8..0756c38ed 100644 --- a/src/app/organisms/room/message/MessageEditor.tsx +++ b/src/app/organisms/room/message/MessageEditor.tsx @@ -129,7 +129,7 @@ export const MessageEditor = as<'div', MessageEditorProps>( const handleKeyDown: KeyboardEventHandler = useCallback( (evt) => { - if (enterForNewline ? isKeyHotkey('shift+enter', evt) : isKeyHotkey('enter', evt)) { + if (isKeyHotkey('mod+enter', evt) || (!enterForNewline && isKeyHotkey('enter', evt))) { evt.preventDefault(); handleSave(); } diff --git a/src/app/organisms/room/message/Reactions.tsx b/src/app/organisms/room/message/Reactions.tsx index bc32c1a34..17b914e5f 100644 --- a/src/app/organisms/room/message/Reactions.tsx +++ b/src/app/organisms/room/message/Reactions.tsx @@ -68,7 +68,7 @@ export const Reactions = as<'div', ReactionsProps>( position="Top" tooltip={ - + diff --git a/src/app/organisms/room/message/styles.css.ts b/src/app/organisms/room/message/styles.css.ts index 9cb0f2efa..a5f2f6b5e 100644 --- a/src/app/organisms/room/message/styles.css.ts +++ b/src/app/organisms/room/message/styles.css.ts @@ -79,3 +79,7 @@ export const ReactionsContainer = style({ }, }, }); + +export const ReactionsTooltipText = style({ + wordBreak: 'break-all', +}); diff --git a/src/app/organisms/room/msgContent.ts b/src/app/organisms/room/msgContent.ts index e4cf1cbc0..0760ec9e9 100644 --- a/src/app/organisms/room/msgContent.ts +++ b/src/app/organisms/room/msgContent.ts @@ -54,23 +54,10 @@ export const getImageMsgContent = async ( }; if (imgEl) { const blurHash = encodeBlurHash(imgEl, 512, scaleYDimension(imgEl.width, 512, imgEl.height)); - const [thumbError, thumbContent] = await to( - generateThumbnailContent( - mx, - imgEl, - getThumbnailDimensions(imgEl.width, imgEl.height), - !!encInfo - ) - ); - if (thumbContent && thumbContent.thumbnail_info) { - thumbContent.thumbnail_info[MATRIX_BLUR_HASH_PROPERTY_NAME] = blurHash; - } - if (thumbError) console.warn(thumbError); content.info = { ...getImageInfo(imgEl, file), [MATRIX_BLUR_HASH_PROPERTY_NAME]: blurHash, - ...thumbContent, }; } if (encInfo) { diff --git a/src/app/organisms/settings/Settings.jsx b/src/app/organisms/settings/Settings.jsx index 962a80b66..ae094efff 100644 --- a/src/app/organisms/settings/Settings.jsx +++ b/src/app/organisms/settings/Settings.jsx @@ -45,6 +45,8 @@ import CinnySVG from '../../../../public/res/svg/cinny.svg'; import { confirmDialog } from '../../molecules/confirm-dialog/ConfirmDialog'; import { useSetting } from '../../state/hooks/settings'; import { settingsAtom } from '../../state/settings'; +import { isMacOS } from '../../utils/user-agent'; +import { KeySymbol } from '../../utils/key-symbol'; function AppearanceSection() { const [, updateState] = useState({}); @@ -147,7 +149,7 @@ function AppearanceSection() { onToggle={() => setEnterForNewline(!enterForNewline) } /> )} - content={Use SHIFT + ENTER to send message and ENTER for newline.} + content={{`Use ${isMacOS() ? KeySymbol.Command : 'Ctrl'} + ENTER to send message and ENTER for newline.`}} /> string | undefined; const MIN_ANY = '(.+?)'; +const URL_NEG_LB = '(? text.match(BOLD_REG_1), html: (parse, match) => { const [, g1] = match; - const child = parse(g1); - return `${child}`; + return `${parse(g1)}`; }, }; const ITALIC_MD_1 = '*'; const ITALIC_PREFIX_1 = '\\*'; const ITALIC_NEG_LA_1 = '(?!\\*)'; -const ITALIC_REG_1 = new RegExp(`${ITALIC_PREFIX_1}${MIN_ANY}${ITALIC_PREFIX_1}${ITALIC_NEG_LA_1}`); +const ITALIC_REG_1 = new RegExp( + `${URL_NEG_LB}${ITALIC_PREFIX_1}${MIN_ANY}${ITALIC_PREFIX_1}${ITALIC_NEG_LA_1}` +); const ItalicRule1: MDRule = { match: (text) => text.match(ITALIC_REG_1), html: (parse, match) => { @@ -52,7 +56,9 @@ const ItalicRule1: MDRule = { const ITALIC_MD_2 = '_'; const ITALIC_PREFIX_2 = '_'; const ITALIC_NEG_LA_2 = '(?!_)'; -const ITALIC_REG_2 = new RegExp(`${ITALIC_PREFIX_2}${MIN_ANY}${ITALIC_PREFIX_2}${ITALIC_NEG_LA_2}`); +const ITALIC_REG_2 = new RegExp( + `${URL_NEG_LB}${ITALIC_PREFIX_2}${MIN_ANY}${ITALIC_PREFIX_2}${ITALIC_NEG_LA_2}` +); const ItalicRule2: MDRule = { match: (text) => text.match(ITALIC_REG_2), html: (parse, match) => { @@ -65,7 +71,7 @@ const UNDERLINE_MD_1 = '__'; const UNDERLINE_PREFIX_1 = '_{2}'; const UNDERLINE_NEG_LA_1 = '(?!_)'; const UNDERLINE_REG_1 = new RegExp( - `${UNDERLINE_PREFIX_1}${MIN_ANY}${UNDERLINE_PREFIX_1}${UNDERLINE_NEG_LA_1}` + `${URL_NEG_LB}${UNDERLINE_PREFIX_1}${MIN_ANY}${UNDERLINE_PREFIX_1}${UNDERLINE_NEG_LA_1}` ); const UnderlineRule: MDRule = { match: (text) => text.match(UNDERLINE_REG_1), @@ -78,7 +84,9 @@ const UnderlineRule: MDRule = { const STRIKE_MD_1 = '~~'; const STRIKE_PREFIX_1 = '~{2}'; const STRIKE_NEG_LA_1 = '(?!~)'; -const STRIKE_REG_1 = new RegExp(`${STRIKE_PREFIX_1}${MIN_ANY}${STRIKE_PREFIX_1}${STRIKE_NEG_LA_1}`); +const STRIKE_REG_1 = new RegExp( + `${URL_NEG_LB}${STRIKE_PREFIX_1}${MIN_ANY}${STRIKE_PREFIX_1}${STRIKE_NEG_LA_1}` +); const StrikeRule: MDRule = { match: (text) => text.match(STRIKE_REG_1), html: (parse, match) => { @@ -90,7 +98,9 @@ const StrikeRule: MDRule = { const CODE_MD_1 = '`'; const CODE_PREFIX_1 = '`'; const CODE_NEG_LA_1 = '(?!`)'; -const CODE_REG_1 = new RegExp(`${CODE_PREFIX_1}${MIN_ANY}${CODE_PREFIX_1}${CODE_NEG_LA_1}`); +const CODE_REG_1 = new RegExp( + `${URL_NEG_LB}${CODE_PREFIX_1}${MIN_ANY}${CODE_PREFIX_1}${CODE_NEG_LA_1}` +); const CodeRule: MDRule = { match: (text) => text.match(CODE_REG_1), html: (parse, match) => { @@ -103,7 +113,7 @@ const SPOILER_MD_1 = '||'; const SPOILER_PREFIX_1 = '\\|{2}'; const SPOILER_NEG_LA_1 = '(?!\\|)'; const SPOILER_REG_1 = new RegExp( - `${SPOILER_PREFIX_1}${MIN_ANY}${SPOILER_PREFIX_1}${SPOILER_NEG_LA_1}` + `${URL_NEG_LB}${SPOILER_PREFIX_1}${MIN_ANY}${SPOILER_PREFIX_1}${SPOILER_NEG_LA_1}` ); const SpoilerRule: MDRule = { match: (text) => text.match(SPOILER_REG_1), From f53bb28b66cfb56ce7549608283dd6004745e6ce Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Thu, 26 Oct 2023 09:09:27 +1100 Subject: [PATCH 1089/1531] Fix emoji and other related bugs (#1504) * make system-emoji default & twitter emoji optional * add mozilla twemoji-colr credit * fix wrong audio duration * set locales to empty in member count millify * render system emoji as same size of custom emoji --- src/app/organisms/room/MembersDrawer.tsx | 2 +- src/app/organisms/room/RoomTimeline.tsx | 8 ++- .../organisms/room/message/AudioContent.tsx | 3 +- src/app/organisms/settings/Settings.jsx | 14 ++-- src/app/plugins/react-custom-html-parser.tsx | 70 +++++++++++++------ src/app/state/settings.ts | 4 +- src/app/styles/CustomHtml.css.ts | 4 +- src/app/templates/client/Client.jsx | 8 +-- src/app/utils/regex.ts | 4 ++ src/index.scss | 2 +- 10 files changed, 78 insertions(+), 41 deletions(-) create mode 100644 src/app/utils/regex.ts diff --git a/src/app/organisms/room/MembersDrawer.tsx b/src/app/organisms/room/MembersDrawer.tsx index 365dc62d6..b4ba6b799 100644 --- a/src/app/organisms/room/MembersDrawer.tsx +++ b/src/app/organisms/room/MembersDrawer.tsx @@ -271,7 +271,7 @@ export function MembersDrawer({ room }: MembersDrawerProps) { - {`${millify(room.getJoinedMemberCount(), { precision: 1 })} Members`} + {`${millify(room.getJoinedMemberCount(), { precision: 1, locales: [] })} Members`} diff --git a/src/app/organisms/room/RoomTimeline.tsx b/src/app/organisms/room/RoomTimeline.tsx index 09f332603..742971d1e 100644 --- a/src/app/organisms/room/RoomTimeline.tsx +++ b/src/app/organisms/room/RoomTimeline.tsx @@ -44,7 +44,6 @@ import { toRem, } from 'folds'; import { isKeyHotkey } from 'is-hotkey'; -import Linkify from 'linkify-react'; import { decryptFile, eventWithShortcode, @@ -76,7 +75,10 @@ import { MessageBadEncryptedContent, MessageNotDecryptedContent, } from '../../components/message'; -import { LINKIFY_OPTS, getReactCustomHtmlParser } from '../../plugins/react-custom-html-parser'; +import { + emojifyAndLinkify, + getReactCustomHtmlParser, +} from '../../plugins/react-custom-html-parser'; import { canEditEvent, decryptAllTimelineEvent, @@ -978,7 +980,7 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli if (customBody === '') ; return parse(sanitizeCustomHtml(customBody), htmlReactParserOptions); } - return {body}; + return emojifyAndLinkify(body, true); }; const renderRoomMsgContent = useRoomMsgContentRenderer<[EventTimelineSet]>({ diff --git a/src/app/organisms/room/message/AudioContent.tsx b/src/app/organisms/room/message/AudioContent.tsx index b5873f352..eae5447ba 100644 --- a/src/app/organisms/room/message/AudioContent.tsx +++ b/src/app/organisms/room/message/AudioContent.tsx @@ -44,7 +44,8 @@ export const AudioContent = as<'div', AudioContentProps>( const audioRef = useRef(null); const [currentTime, setCurrentTime] = useState(0); - const [duration, setDuration] = useState(info.duration ?? 0); + // duration in seconds. (NOTE: info.duration is in milliseconds) + const [duration, setDuration] = useState((info.duration ?? 0) / 1000); const getAudioRef = useCallback(() => audioRef.current, []); const { loading } = useMediaLoading(getAudioRef); diff --git a/src/app/organisms/settings/Settings.jsx b/src/app/organisms/settings/Settings.jsx index ae094efff..2b706edad 100644 --- a/src/app/organisms/settings/Settings.jsx +++ b/src/app/organisms/settings/Settings.jsx @@ -54,7 +54,7 @@ function AppearanceSection() { const [enterForNewline, setEnterForNewline] = useSetting(settingsAtom, 'enterForNewline'); const [messageLayout, setMessageLayout] = useSetting(settingsAtom, 'messageLayout'); const [messageSpacing, setMessageSpacing] = useSetting(settingsAtom, 'messageSpacing'); - const [useSystemEmoji, setUseSystemEmoji] = useSetting(settingsAtom, 'useSystemEmoji'); + const [twitterEmoji, setTwitterEmoji] = useSetting(settingsAtom, 'twitterEmoji'); const [isMarkdown, setIsMarkdown] = useSetting(settingsAtom, 'isMarkdown'); const [hideMembershipEvents, setHideMembershipEvents] = useSetting(settingsAtom, 'hideMembershipEvents'); const [hideNickAvatarEvents, setHideNickAvatarEvents] = useSetting(settingsAtom, 'hideNickAvatarEvents'); @@ -96,14 +96,14 @@ function AppearanceSection() { )} /> setUseSystemEmoji(!useSystemEmoji)} + isActive={twitterEmoji} + onToggle={() => setTwitterEmoji(!twitterEmoji)} /> )} - content={Use system emoji instead of Twitter emojis.} + content={Use Twitter emoji instead of system emoji.} />
      @@ -339,6 +339,10 @@ function AboutSection() { {/* eslint-disable-next-line react/jsx-one-expression-per-line */ } The matrix-js-sdk is © The Matrix.org Foundation C.I.C used under the terms of Apache 2.0. +
    • + {/* eslint-disable-next-line react/jsx-one-expression-per-line */ } + The twemoji-colr font is © Mozilla Foundation used under the terms of Apache 2.0. +
    • {/* eslint-disable-next-line react/jsx-one-expression-per-line */ } The Twemoji emoji art is © Twitter, Inc and other contributors used under the terms of CC-BY 4.0. diff --git a/src/app/plugins/react-custom-html-parser.tsx b/src/app/plugins/react-custom-html-parser.tsx index 09f09d8f6..478a8a3be 100644 --- a/src/app/plugins/react-custom-html-parser.tsx +++ b/src/app/plugins/react-custom-html-parser.tsx @@ -1,6 +1,6 @@ /* eslint-disable jsx-a11y/alt-text */ import React, { ReactEventHandler, Suspense, lazy } from 'react'; -import { +import parse, { Element, Text as DOMText, HTMLReactParserOptions, @@ -16,9 +16,14 @@ import { ErrorBoundary } from 'react-error-boundary'; import * as css from '../styles/CustomHtml.css'; import { getMxIdLocalPart, getRoomWithCanonicalAlias } from '../utils/matrix'; import { getMemberDisplayName } from '../utils/room'; +import { EMOJI_PATTERN, URL_NEG_LB } from '../utils/regex'; +import { sanitizeText } from '../utils/sanitize'; +import { getHexcodeForEmoji, getShortcodeFor } from './emoji'; const ReactPrism = lazy(() => import('./react-prism/ReactPrism')); +const EMOJI_REG = new RegExp(`${URL_NEG_LB}(${EMOJI_PATTERN})`, 'g'); + export const LINKIFY_OPTS: LinkifyOpts = { attributes: { target: '_blank', @@ -27,6 +32,28 @@ export const LINKIFY_OPTS: LinkifyOpts = { validate: { url: (value) => /^(https|http|ftp|mailto|magnet)?:/.test(value), }, + ignoreTags: ['span'], +}; + +const emojifyParserOptions: HTMLReactParserOptions = { + replace: (domNode) => { + if (domNode instanceof DOMText) { + return {domNode.data}; + } + return undefined; + }, +}; + +export const emojifyAndLinkify = (unsafeText: string, linkify?: boolean) => { + const emojifyHtml = sanitizeText(unsafeText).replace( + EMOJI_REG, + (emoji) => + `${emoji}` + ); + + return <>{parse(emojifyHtml, linkify ? emojifyParserOptions : undefined)}; }; export const getReactCustomHtmlParser = ( @@ -45,7 +72,7 @@ export const getReactCustomHtmlParser = ( if (name === 'h1') { return ( - + {domToReact(children, opts)} ); @@ -53,7 +80,7 @@ export const getReactCustomHtmlParser = ( if (name === 'h2') { return ( - + {domToReact(children, opts)} ); @@ -61,7 +88,7 @@ export const getReactCustomHtmlParser = ( if (name === 'h3') { return ( - + {domToReact(children, opts)} ); @@ -69,7 +96,7 @@ export const getReactCustomHtmlParser = ( if (name === 'h4') { return ( - + {domToReact(children, opts)} ); @@ -77,7 +104,7 @@ export const getReactCustomHtmlParser = ( if (name === 'h5') { return ( - + {domToReact(children, opts)} ); @@ -85,7 +112,7 @@ export const getReactCustomHtmlParser = ( if (name === 'h6') { return ( - + {domToReact(children, opts)} ); @@ -93,7 +120,7 @@ export const getReactCustomHtmlParser = ( if (name === 'p') { return ( - + {domToReact(children, opts)} ); @@ -101,7 +128,7 @@ export const getReactCustomHtmlParser = ( if (name === 'pre') { return ( - + + {domToReact(children, opts)} ); @@ -125,14 +152,14 @@ export const getReactCustomHtmlParser = ( if (name === 'ul') { return ( -
        +
          {domToReact(children, opts)}
        ); } if (name === 'ol') { return ( -
          +
            {domToReact(children, opts)}
          ); @@ -240,29 +267,28 @@ export const getReactCustomHtmlParser = ( if (htmlSrc && props.src.startsWith('mxc://') === false) { return ( - {props.alt && htmlSrc} + {props.alt || props.title || htmlSrc} ); } if (htmlSrc && 'data-mx-emoticon' in props) { return ( - - + + ); } - if (htmlSrc) return ; + if (htmlSrc) return ; } } - if ( - domNode instanceof DOMText && - !(domNode.parent && 'name' in domNode.parent && domNode.parent.name === 'code') && - !(domNode.parent && 'name' in domNode.parent && domNode.parent.name === 'a') - ) { - return {domNode.data}; + if (domNode instanceof DOMText) { + const linkify = + !(domNode.parent && 'name' in domNode.parent && domNode.parent.name === 'code') && + !(domNode.parent && 'name' in domNode.parent && domNode.parent.name === 'a'); + return emojifyAndLinkify(domNode.data, linkify); } return undefined; }, diff --git a/src/app/state/settings.ts b/src/app/state/settings.ts index 26e3431dc..3a7832cd9 100644 --- a/src/app/state/settings.ts +++ b/src/app/state/settings.ts @@ -9,7 +9,7 @@ export interface Settings { useSystemTheme: boolean; isMarkdown: boolean; editorToolbar: boolean; - useSystemEmoji: boolean; + twitterEmoji: boolean; isPeopleDrawer: boolean; memberSortFilterIndex: number; @@ -30,7 +30,7 @@ const defaultSettings: Settings = { useSystemTheme: true, isMarkdown: false, editorToolbar: false, - useSystemEmoji: false, + twitterEmoji: false, isPeopleDrawer: true, memberSortFilterIndex: 0, diff --git a/src/app/styles/CustomHtml.css.ts b/src/app/styles/CustomHtml.css.ts index 2a06c0fb8..076bbb61b 100644 --- a/src/app/styles/CustomHtml.css.ts +++ b/src/app/styles/CustomHtml.css.ts @@ -187,11 +187,11 @@ export const Emoticon = recipe({ height: '1em', minWidth: '1em', - fontSize: '1.47em', + fontSize: '1.33em', lineHeight: '1em', verticalAlign: 'middle', position: 'relative', - top: '-0.32em', + top: '-0.35em', borderRadius: config.radii.R300, }, ], diff --git a/src/app/templates/client/Client.jsx b/src/app/templates/client/Client.jsx index 77db4115a..e9be6b16e 100644 --- a/src/app/templates/client/Client.jsx +++ b/src/app/templates/client/Client.jsx @@ -24,12 +24,12 @@ import { useSetting } from '../../state/hooks/settings'; import { settingsAtom } from '../../state/settings'; function SystemEmojiFeature() { - const [systemEmoji] = useSetting(settingsAtom, 'useSystemEmoji'); + const [twitterEmoji] = useSetting(settingsAtom, 'twitterEmoji'); - if (systemEmoji) { - document.documentElement.style.setProperty('--font-emoji', 'Twemoji_DISABLED'); - } else { + if (twitterEmoji) { document.documentElement.style.setProperty('--font-emoji', 'Twemoji'); + } else { + document.documentElement.style.setProperty('--font-emoji', 'Twemoji_DISABLED'); } return null; diff --git a/src/app/utils/regex.ts b/src/app/utils/regex.ts new file mode 100644 index 000000000..73da664e9 --- /dev/null +++ b/src/app/utils/regex.ts @@ -0,0 +1,4 @@ +export const URL_NEG_LB = '(? Date: Thu, 26 Oct 2023 16:21:55 +1100 Subject: [PATCH 1090/1531] Fix-timeline-loading (#1506) * fix timeline jump to search item after markAsRead * improve pagination logic * add jumbo emoji support in msg rendering --- src/app/organisms/room/RoomTimeline.tsx | 17 +++++++++++++++-- src/app/utils/regex.ts | 3 +++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/app/organisms/room/RoomTimeline.tsx b/src/app/organisms/room/RoomTimeline.tsx index 742971d1e..2d3824548 100644 --- a/src/app/organisms/room/RoomTimeline.tsx +++ b/src/app/organisms/room/RoomTimeline.tsx @@ -137,6 +137,13 @@ import initMatrix from '../../../client/initMatrix'; import { useKeyDown } from '../../hooks/useKeyDown'; import cons from '../../../client/state/cons'; import { useDocumentFocusChange } from '../../hooks/useDocumentFocusChange'; +import { EMOJI_PATTERN, VARIATION_SELECTOR_PATTERN } from '../../utils/regex'; + +// Thumbs up emoji found to have Variation Selector 16 at the end +// so included variation selector pattern in regex +const JUMBO_EMOJI_REG = new RegExp( + `^(((${EMOJI_PATTERN})|(:.+?:))(${VARIATION_SELECTOR_PATTERN}|\\s)*){1,10}$` +); const TimelineFloat = as<'div', css.TimelineFloatVariants>( ({ position, className, ...props }, ref) => ( @@ -334,6 +341,7 @@ const useTimelinePagination = ( return async (backwards: boolean) => { if (fetching) return; + const targetTimeline = timelineRef.current; const { linkedTimelines: lTimelines } = timelineRef.current; const timelinesEventsCount = lTimelines.map(timelineToEventsCount); @@ -373,6 +381,7 @@ const useTimelinePagination = ( } fetching = false; + if (targetTimeline !== timelineRef.current) return; if (alive()) { recalibratePagination(lTimelines, timelinesEventsCount, backwards); } @@ -582,7 +591,7 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli focusItem.current = { index: evtAbsIndex, scrollTo: true, - highlight: evtId !== unreadInfo?.readUptoEventId, + highlight: evtId !== readUptoEventIdRef.current, }; setTimeline({ linkedTimelines: lTimelines, @@ -592,7 +601,7 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli }, }); }, - [unreadInfo, alive] + [alive] ), useCallback(() => { if (!alive()) return; @@ -990,12 +999,16 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli editedEvent?.getContent()['m.new_content'] ?? mEvent.getContent(); if (typeof body !== 'string') return null; + const jumboEmoji = JUMBO_EMOJI_REG.test(body); + return ( diff --git a/src/app/utils/regex.ts b/src/app/utils/regex.ts index 73da664e9..3b0e98152 100644 --- a/src/app/utils/regex.ts +++ b/src/app/utils/regex.ts @@ -1,4 +1,7 @@ export const URL_NEG_LB = '(? Date: Fri, 27 Oct 2023 21:27:22 +1100 Subject: [PATCH 1091/1531] Improve Editor related bugs and add multiline md (#1507) * remove shift from editor hotkeys * fix inline markdown not working * add block md parser - WIP * emojify and linkify text without react-parser * no need to sanitize text when emojify * parse block markdown in editor output - WIP * add inline parser option in block md parser * improve codeblock regex * ignore html tag when parsing inline md in block md * add list markdown rule in block parser * re-generate block markdown on edit * change copy from inline markdown to markdown * fix trim reply from body regex * fix jumbo emoji in reply message * fix broken list regex in block markdown * enable markdown by defualt --- src/app/components/editor/Toolbar.tsx | 19 +- src/app/components/editor/input.ts | 151 +++++++--- src/app/components/editor/keyboard.ts | 12 +- src/app/components/editor/output.ts | 41 ++- src/app/components/message/Reply.tsx | 9 +- src/app/organisms/room/RoomInput.tsx | 3 +- src/app/organisms/room/RoomTimeline.tsx | 3 +- .../organisms/room/message/MessageEditor.tsx | 3 +- src/app/organisms/room/message/styles.css.ts | 2 +- src/app/organisms/settings/Settings.jsx | 4 +- src/app/plugins/react-custom-html-parser.tsx | 46 +-- src/app/state/settings.ts | 2 +- src/app/utils/markdown.ts | 277 ++++++++++++++---- src/app/utils/room.ts | 2 +- src/app/utils/sanitize.ts | 11 +- 15 files changed, 425 insertions(+), 160 deletions(-) diff --git a/src/app/components/editor/Toolbar.tsx b/src/app/components/editor/Toolbar.tsx index 6feae0095..5d5e98943 100644 --- a/src/app/components/editor/Toolbar.tsx +++ b/src/app/components/editor/Toolbar.tsx @@ -148,7 +148,7 @@ export function HeadingBlockButton() { } + tooltip={} delay={500} > {(triggerRef) => ( @@ -163,7 +163,7 @@ export function HeadingBlockButton() { )} } + tooltip={} delay={500} > {(triggerRef) => ( @@ -178,7 +178,7 @@ export function HeadingBlockButton() { )} } + tooltip={} delay={500} > {(triggerRef) => ( @@ -277,12 +277,7 @@ export function Toolbar() { - } + tooltip={} /> } + tooltip={} /> } + tooltip={} /> @@ -335,7 +330,7 @@ export function Toolbar() { } + tooltip={} delay={500} > {(triggerRef) => ( diff --git a/src/app/components/editor/input.ts b/src/app/components/editor/input.ts index 5860df04f..272b9707a 100644 --- a/src/app/components/editor/input.ts +++ b/src/app/components/editor/input.ts @@ -13,11 +13,9 @@ import { HeadingElement, HeadingLevel, InlineElement, - ListItemElement, MentionElement, OrderedListElement, ParagraphElement, - QuoteLineElement, UnorderedListElement, } from './slate'; import { parseMatrixToUrl } from '../../utils/matrix'; @@ -117,17 +115,14 @@ const parseInlineNodes = (node: ChildNode): InlineElement[] => { return []; }; -const parseBlockquoteNode = (node: Element): BlockQuoteElement => { - const children: QuoteLineElement[] = []; +const parseBlockquoteNode = (node: Element): BlockQuoteElement[] | ParagraphElement[] => { + const quoteLines: Array = []; let lineHolder: InlineElement[] = []; const appendLine = () => { if (lineHolder.length === 0) return; - children.push({ - type: BlockType.QuoteLine, - children: lineHolder, - }); + quoteLines.push(lineHolder); lineHolder = []; }; @@ -145,10 +140,7 @@ const parseBlockquoteNode = (node: Element): BlockQuoteElement => { if (child.name === 'p') { appendLine(); - children.push({ - type: BlockType.QuoteLine, - children: child.children.flatMap((c) => parseInlineNodes(c)), - }); + quoteLines.push(child.children.flatMap((c) => parseInlineNodes(c))); return; } @@ -157,42 +149,71 @@ const parseBlockquoteNode = (node: Element): BlockQuoteElement => { }); appendLine(); - return { - type: BlockType.BlockQuote, - children, - }; -}; -const parseCodeBlockNode = (node: Element): CodeBlockElement => { - const children: CodeLineElement[] = []; + if (node.attribs['data-md'] !== undefined) { + return quoteLines.map((lineChildren) => ({ + type: BlockType.Paragraph, + children: [{ text: `${node.attribs['data-md']} ` }, ...lineChildren], + })); + } - const code = parseNodeText(node).trim(); - code.split('\n').forEach((lineTxt) => - children.push({ - type: BlockType.CodeLine, + return [ + { + type: BlockType.BlockQuote, + children: quoteLines.map((lineChildren) => ({ + type: BlockType.QuoteLine, + children: lineChildren, + })), + }, + ]; +}; +const parseCodeBlockNode = (node: Element): CodeBlockElement[] | ParagraphElement[] => { + const codeLines = parseNodeText(node).trim().split('\n'); + + if (node.attribs['data-md'] !== undefined) { + const pLines = codeLines.map((lineText) => ({ + type: BlockType.Paragraph, children: [ { - text: lineTxt, + text: lineText, }, ], - }) - ); + })); + const childCode = node.children[0]; + const className = + isTag(childCode) && childCode.tagName === 'code' ? childCode.attribs.class ?? '' : ''; + const prefix = { text: `${node.attribs['data-md']}${className.replace('language-', '')}` }; + const suffix = { text: node.attribs['data-md'] }; + return [ + { type: BlockType.Paragraph, children: [prefix] }, + ...pLines, + { type: BlockType.Paragraph, children: [suffix] }, + ]; + } - return { - type: BlockType.CodeBlock, - children, - }; + return [ + { + type: BlockType.CodeBlock, + children: codeLines.map((lineTxt) => ({ + type: BlockType.CodeLine, + children: [ + { + text: lineTxt, + }, + ], + })), + }, + ]; }; -const parseListNode = (node: Element): OrderedListElement | UnorderedListElement => { - const children: ListItemElement[] = []; +const parseListNode = ( + node: Element +): OrderedListElement[] | UnorderedListElement[] | ParagraphElement[] => { + const listLines: Array = []; let lineHolder: InlineElement[] = []; const appendLine = () => { if (lineHolder.length === 0) return; - children.push({ - type: BlockType.ListItem, - children: lineHolder, - }); + listLines.push(lineHolder); lineHolder = []; }; @@ -210,10 +231,7 @@ const parseListNode = (node: Element): OrderedListElement | UnorderedListElement if (child.name === 'li') { appendLine(); - children.push({ - type: BlockType.ListItem, - children: child.children.flatMap((c) => parseInlineNodes(c)), - }); + listLines.push(child.children.flatMap((c) => parseInlineNodes(c))); return; } @@ -222,17 +240,54 @@ const parseListNode = (node: Element): OrderedListElement | UnorderedListElement }); appendLine(); - return { - type: node.name === 'ol' ? BlockType.OrderedList : BlockType.UnorderedList, - children, - }; + if (node.attribs['data-md'] !== undefined) { + const prefix = node.attribs['data-md'] || '-'; + const [starOrHyphen] = prefix.match(/^\*|-$/) ?? []; + return listLines.map((lineChildren) => ({ + type: BlockType.Paragraph, + children: [ + { text: `${starOrHyphen ? `${starOrHyphen} ` : `${prefix}. `} ` }, + ...lineChildren, + ], + })); + } + + if (node.name === 'ol') { + return [ + { + type: BlockType.OrderedList, + children: listLines.map((lineChildren) => ({ + type: BlockType.ListItem, + children: lineChildren, + })), + }, + ]; + } + + return [ + { + type: BlockType.UnorderedList, + children: listLines.map((lineChildren) => ({ + type: BlockType.ListItem, + children: lineChildren, + })), + }, + ]; }; -const parseHeadingNode = (node: Element): HeadingElement => { +const parseHeadingNode = (node: Element): HeadingElement | ParagraphElement => { const children = node.children.flatMap((child) => parseInlineNodes(child)); const headingMatch = node.name.match(/^h([123456])$/); const [, g1AsLevel] = headingMatch ?? ['h3', '3']; const level = parseInt(g1AsLevel, 10); + + if (node.attribs['data-md'] !== undefined) { + return { + type: BlockType.Paragraph, + children: [{ text: `${node.attribs['data-md']} ` }, ...children], + }; + } + return { type: BlockType.Heading, level: (level <= 3 ? level : 3) as HeadingLevel, @@ -278,17 +333,17 @@ export const domToEditorInput = (domNodes: ChildNode[]): Descendant[] => { if (node.name === 'blockquote') { appendLine(); - children.push(parseBlockquoteNode(node)); + children.push(...parseBlockquoteNode(node)); return; } if (node.name === 'pre') { appendLine(); - children.push(parseCodeBlockNode(node)); + children.push(...parseCodeBlockNode(node)); return; } if (node.name === 'ol' || node.name === 'ul') { appendLine(); - children.push(parseListNode(node)); + children.push(...parseListNode(node)); return; } diff --git a/src/app/components/editor/keyboard.ts b/src/app/components/editor/keyboard.ts index 370f3e827..19c05bac7 100644 --- a/src/app/components/editor/keyboard.ts +++ b/src/app/components/editor/keyboard.ts @@ -8,22 +8,22 @@ export const INLINE_HOTKEYS: Record = { 'mod+b': MarkType.Bold, 'mod+i': MarkType.Italic, 'mod+u': MarkType.Underline, - 'mod+shift+u': MarkType.StrikeThrough, + 'mod+s': MarkType.StrikeThrough, 'mod+[': MarkType.Code, 'mod+h': MarkType.Spoiler, }; const INLINE_KEYS = Object.keys(INLINE_HOTKEYS); export const BLOCK_HOTKEYS: Record = { - 'mod+shift+7': BlockType.OrderedList, - 'mod+shift+8': BlockType.UnorderedList, + 'mod+7': BlockType.OrderedList, + 'mod+8': BlockType.UnorderedList, "mod+'": BlockType.BlockQuote, 'mod+;': BlockType.CodeBlock, }; const BLOCK_KEYS = Object.keys(BLOCK_HOTKEYS); -const isHeading1 = isKeyHotkey('mod+shift+1'); -const isHeading2 = isKeyHotkey('mod+shift+2'); -const isHeading3 = isKeyHotkey('mod+shift+3'); +const isHeading1 = isKeyHotkey('mod+1'); +const isHeading2 = isKeyHotkey('mod+2'); +const isHeading3 = isKeyHotkey('mod+3'); /** * @return boolean true if shortcut is toggled. diff --git a/src/app/components/editor/output.ts b/src/app/components/editor/output.ts index 307ef8a2b..fa15bb582 100644 --- a/src/app/components/editor/output.ts +++ b/src/app/components/editor/output.ts @@ -3,11 +3,12 @@ import { Descendant, Text } from 'slate'; import { sanitizeText } from '../../utils/sanitize'; import { BlockType } from './types'; import { CustomElement } from './slate'; -import { parseInlineMD } from '../../utils/markdown'; +import { parseBlockMD, parseInlineMD, replaceMatch } from '../../utils/markdown'; export type OutputOptions = { allowTextFormatting?: boolean; - allowMarkdown?: boolean; + allowInlineMarkdown?: boolean; + allowBlockMarkdown?: boolean; }; const textToCustomHtml = (node: Text, opts: OutputOptions): string => { @@ -21,7 +22,7 @@ const textToCustomHtml = (node: Text, opts: OutputOptions): string => { if (node.spoiler) string = `${string}`; } - if (opts.allowMarkdown && string === sanitizeText(node.text)) { + if (opts.allowInlineMarkdown && string === sanitizeText(node.text)) { string = parseInlineMD(string); } @@ -64,14 +65,42 @@ const elementToCustomHtml = (node: CustomElement, children: string): string => { } }; +const HTML_TAG_REG = /<([a-z]+)(?![^>]*\/>)[^<]*<\/\1>/; +const ignoreHTMLParseInlineMD = (text: string): string => { + if (text === '') return text; + const match = text.match(HTML_TAG_REG); + if (!match) return parseInlineMD(text); + const [matchedTxt] = match; + return replaceMatch((txt) => [ignoreHTMLParseInlineMD(txt)], text, match, matchedTxt).join(''); +}; + export const toMatrixCustomHTML = ( node: Descendant | Descendant[], opts: OutputOptions ): string => { - const parseNode = (n: Descendant) => { + let markdownLines = ''; + const parseNode = (n: Descendant, index: number, targetNodes: Descendant[]) => { + if (opts.allowBlockMarkdown && 'type' in n && n.type === BlockType.Paragraph) { + const line = toMatrixCustomHTML(n, { + ...opts, + allowInlineMarkdown: false, + allowBlockMarkdown: false, + }) + .replace(/$/, '\n') + .replace(/^>/, '>'); + markdownLines += line; + if (index === targetNodes.length - 1) { + return parseBlockMD(markdownLines, ignoreHTMLParseInlineMD); + } + return ''; + } + + const parsedMarkdown = parseBlockMD(markdownLines, ignoreHTMLParseInlineMD); + markdownLines = ''; const isCodeLine = 'type' in n && n.type === BlockType.CodeLine; - if (isCodeLine) return toMatrixCustomHTML(n, {}); - return toMatrixCustomHTML(n, opts); + if (isCodeLine) return `${parsedMarkdown}${toMatrixCustomHTML(n, {})}`; + + return `${parsedMarkdown}${toMatrixCustomHTML(n, { ...opts, allowBlockMarkdown: false })}`; }; if (Array.isArray(node)) return node.map(parseNode).join(''); if (Text.isText(node)) return textToCustomHtml(node, opts); diff --git a/src/app/components/message/Reply.tsx b/src/app/components/message/Reply.tsx index 6eaab31ed..c9b6b8d8b 100644 --- a/src/app/components/message/Reply.tsx +++ b/src/app/components/message/Reply.tsx @@ -59,6 +59,9 @@ export const Reply = as<'div', ReplyProps>( }; }, [replyEvent, mx, room, eventId]); + const badEncryption = replyEvent?.getContent().msgtype === 'm.bad.encrypted'; + const bodyJSX = body ? trimReplyFromBody(body) : fallbackBody; + return ( ( {replyEvent !== undefined ? ( - {replyEvent?.getContent().msgtype === 'm.bad.encrypted' ? ( - - ) : ( - (body && trimReplyFromBody(body)) ?? fallbackBody - )} + {badEncryption ? : bodyJSX} ) : ( ( let customHtml = trimCustomHtml( toMatrixCustomHTML(editor.children, { allowTextFormatting: true, - allowMarkdown: isMarkdown, + allowBlockMarkdown: isMarkdown, + allowInlineMarkdown: isMarkdown, }) ); let msgType = MsgType.Text; diff --git a/src/app/organisms/room/RoomTimeline.tsx b/src/app/organisms/room/RoomTimeline.tsx index 2d3824548..c1b044583 100644 --- a/src/app/organisms/room/RoomTimeline.tsx +++ b/src/app/organisms/room/RoomTimeline.tsx @@ -89,6 +89,7 @@ import { getReactionContent, isMembershipChanged, reactionOrEditEvent, + trimReplyFromBody, } from '../../utils/room'; import { useSetting } from '../../state/hooks/settings'; import { settingsAtom } from '../../state/settings'; @@ -999,7 +1000,7 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli editedEvent?.getContent()['m.new_content'] ?? mEvent.getContent(); if (typeof body !== 'string') return null; - const jumboEmoji = JUMBO_EMOJI_REG.test(body); + const jumboEmoji = JUMBO_EMOJI_REG.test(trimReplyFromBody(body)); return ( ( const customHtml = trimCustomHtml( toMatrixCustomHTML(editor.children, { allowTextFormatting: true, - allowMarkdown: isMarkdown, + allowBlockMarkdown: isMarkdown, + allowInlineMarkdown: isMarkdown, }) ); diff --git a/src/app/organisms/room/message/styles.css.ts b/src/app/organisms/room/message/styles.css.ts index a5f2f6b5e..801f698d7 100644 --- a/src/app/organisms/room/message/styles.css.ts +++ b/src/app/organisms/room/message/styles.css.ts @@ -81,5 +81,5 @@ export const ReactionsContainer = style({ }); export const ReactionsTooltipText = style({ - wordBreak: 'break-all', + wordBreak: 'break-word', }); diff --git a/src/app/organisms/settings/Settings.jsx b/src/app/organisms/settings/Settings.jsx index 2b706edad..1b04669cb 100644 --- a/src/app/organisms/settings/Settings.jsx +++ b/src/app/organisms/settings/Settings.jsx @@ -152,14 +152,14 @@ function AppearanceSection() { content={{`Use ${isMacOS() ? KeySymbol.Command : 'Ctrl'} + ENTER to send message and ENTER for newline.`}} /> setIsMarkdown(!isMarkdown) } /> )} - content={Format messages with inline markdown syntax before sending.} + content={Format messages with markdown syntax before sending.} /> import('./react-prism/ReactPrism')); -const EMOJI_REG = new RegExp(`${URL_NEG_LB}(${EMOJI_PATTERN})`, 'g'); +const EMOJI_REG = new RegExp(`${URL_NEG_LB}(${EMOJI_PATTERN})`); export const LINKIFY_OPTS: LinkifyOpts = { attributes: { @@ -35,25 +35,31 @@ export const LINKIFY_OPTS: LinkifyOpts = { ignoreTags: ['span'], }; -const emojifyParserOptions: HTMLReactParserOptions = { - replace: (domNode) => { - if (domNode instanceof DOMText) { - return {domNode.data}; - } - return undefined; - }, +const stringToEmojifyJSX = (text: string): (string | JSX.Element)[] => { + const match = text.match(EMOJI_REG); + if (!match) return [text]; + + const [emoji] = match; + + return replaceMatch( + stringToEmojifyJSX, + text, + match, + + + {emoji} + + + ); }; -export const emojifyAndLinkify = (unsafeText: string, linkify?: boolean) => { - const emojifyHtml = sanitizeText(unsafeText).replace( - EMOJI_REG, - (emoji) => - `${emoji}` - ); +export const emojifyAndLinkify = (text: string, linkify?: boolean) => { + const emojifyJSX = stringToEmojifyJSX(text); - return <>{parse(emojifyHtml, linkify ? emojifyParserOptions : undefined)}; + if (linkify) { + return {emojifyJSX}; + } + return emojifyJSX; }; export const getReactCustomHtmlParser = ( @@ -171,6 +177,8 @@ export const getReactCustomHtmlParser = ( if (typeof codeReact === 'string') { let lang = props.className; if (lang === 'language-rs') lang = 'language-rust'; + else if (lang === 'language-js') lang = 'language-javascript'; + else if (lang === 'language-ts') lang = 'language-typescript'; return ( {codeReact}}> {codeReact}}> diff --git a/src/app/state/settings.ts b/src/app/state/settings.ts index 3a7832cd9..4393b64db 100644 --- a/src/app/state/settings.ts +++ b/src/app/state/settings.ts @@ -28,7 +28,7 @@ export interface Settings { const defaultSettings: Settings = { themeIndex: 0, useSystemTheme: true, - isMarkdown: false, + isMarkdown: true, editorToolbar: false, twitterEmoji: false, diff --git a/src/app/utils/markdown.ts b/src/app/utils/markdown.ts index 9fda6794d..c6bb3914a 100644 --- a/src/app/utils/markdown.ts +++ b/src/app/utils/markdown.ts @@ -1,25 +1,46 @@ -export type PlainMDParser = (text: string) => string; export type MatchResult = RegExpMatchArray | RegExpExecArray; export type RuleMatch = (text: string) => MatchResult | null; -export type MatchConverter = (parse: PlainMDParser, match: MatchResult) => string; -export type MDRule = { - match: RuleMatch; - html: MatchConverter; -}; +export const beforeMatch = (text: string, match: RegExpMatchArray | RegExpExecArray): string => + text.slice(0, match.index); +export const afterMatch = (text: string, match: RegExpMatchArray | RegExpExecArray): string => + text.slice((match.index ?? 0) + match[0].length); -export type MatchReplacer = ( - parse: PlainMDParser, +export const replaceMatch = ( + convertPart: (txt: string) => Array, text: string, match: MatchResult, - content: string -) => string; + content: C +): Array => [ + ...convertPart(beforeMatch(text, match)), + content, + ...convertPart(afterMatch(text, match)), +]; -export type RuleRunner = (parse: PlainMDParser, text: string, rule: MDRule) => string | undefined; -export type RulesRunner = ( - parse: PlainMDParser, +/* + ***************** + * INLINE PARSER * + ***************** + */ + +export type InlineMDParser = (text: string) => string; + +export type InlineMatchConverter = (parse: InlineMDParser, match: MatchResult) => string; + +export type InlineMDRule = { + match: RuleMatch; + html: InlineMatchConverter; +}; + +export type InlineRuleRunner = ( + parse: InlineMDParser, text: string, - rules: MDRule[] + rule: InlineMDRule +) => string | undefined; +export type InlineRulesRunner = ( + parse: InlineMDParser, + text: string, + rules: InlineMDRule[] ) => string | undefined; const MIN_ANY = '(.+?)'; @@ -31,11 +52,11 @@ const BOLD_NEG_LA_1 = '(?!\\*)'; const BOLD_REG_1 = new RegExp( `${URL_NEG_LB}${BOLD_PREFIX_1}${MIN_ANY}${BOLD_PREFIX_1}${BOLD_NEG_LA_1}` ); -const BoldRule: MDRule = { +const BoldRule: InlineMDRule = { match: (text) => text.match(BOLD_REG_1), html: (parse, match) => { - const [, g1] = match; - return `${parse(g1)}`; + const [, , g2] = match; + return `${parse(g2)}`; }, }; @@ -45,11 +66,11 @@ const ITALIC_NEG_LA_1 = '(?!\\*)'; const ITALIC_REG_1 = new RegExp( `${URL_NEG_LB}${ITALIC_PREFIX_1}${MIN_ANY}${ITALIC_PREFIX_1}${ITALIC_NEG_LA_1}` ); -const ItalicRule1: MDRule = { +const ItalicRule1: InlineMDRule = { match: (text) => text.match(ITALIC_REG_1), html: (parse, match) => { - const [, g1] = match; - return `${parse(g1)}`; + const [, , g2] = match; + return `${parse(g2)}`; }, }; @@ -59,11 +80,11 @@ const ITALIC_NEG_LA_2 = '(?!_)'; const ITALIC_REG_2 = new RegExp( `${URL_NEG_LB}${ITALIC_PREFIX_2}${MIN_ANY}${ITALIC_PREFIX_2}${ITALIC_NEG_LA_2}` ); -const ItalicRule2: MDRule = { +const ItalicRule2: InlineMDRule = { match: (text) => text.match(ITALIC_REG_2), html: (parse, match) => { - const [, g1] = match; - return `${parse(g1)}`; + const [, , g2] = match; + return `${parse(g2)}`; }, }; @@ -73,11 +94,11 @@ const UNDERLINE_NEG_LA_1 = '(?!_)'; const UNDERLINE_REG_1 = new RegExp( `${URL_NEG_LB}${UNDERLINE_PREFIX_1}${MIN_ANY}${UNDERLINE_PREFIX_1}${UNDERLINE_NEG_LA_1}` ); -const UnderlineRule: MDRule = { +const UnderlineRule: InlineMDRule = { match: (text) => text.match(UNDERLINE_REG_1), html: (parse, match) => { - const [, g1] = match; - return `${parse(g1)}`; + const [, , g2] = match; + return `${parse(g2)}`; }, }; @@ -87,25 +108,23 @@ const STRIKE_NEG_LA_1 = '(?!~)'; const STRIKE_REG_1 = new RegExp( `${URL_NEG_LB}${STRIKE_PREFIX_1}${MIN_ANY}${STRIKE_PREFIX_1}${STRIKE_NEG_LA_1}` ); -const StrikeRule: MDRule = { +const StrikeRule: InlineMDRule = { match: (text) => text.match(STRIKE_REG_1), html: (parse, match) => { - const [, g1] = match; - return `${parse(g1)}`; + const [, , g2] = match; + return `${parse(g2)}`; }, }; const CODE_MD_1 = '`'; const CODE_PREFIX_1 = '`'; const CODE_NEG_LA_1 = '(?!`)'; -const CODE_REG_1 = new RegExp( - `${URL_NEG_LB}${CODE_PREFIX_1}${MIN_ANY}${CODE_PREFIX_1}${CODE_NEG_LA_1}` -); -const CodeRule: MDRule = { +const CODE_REG_1 = new RegExp(`${URL_NEG_LB}${CODE_PREFIX_1}(.+?)${CODE_PREFIX_1}${CODE_NEG_LA_1}`); +const CodeRule: InlineMDRule = { match: (text) => text.match(CODE_REG_1), html: (parse, match) => { - const [, g1] = match; - return `${g1}`; + const [, , g2] = match; + return `${g2}`; }, }; @@ -115,18 +134,18 @@ const SPOILER_NEG_LA_1 = '(?!\\|)'; const SPOILER_REG_1 = new RegExp( `${URL_NEG_LB}${SPOILER_PREFIX_1}${MIN_ANY}${SPOILER_PREFIX_1}${SPOILER_NEG_LA_1}` ); -const SpoilerRule: MDRule = { +const SpoilerRule: InlineMDRule = { match: (text) => text.match(SPOILER_REG_1), html: (parse, match) => { - const [, g1] = match; - return `${parse(g1)}`; + const [, , g2] = match; + return `${parse(g2)}`; }, }; const LINK_ALT = `\\[${MIN_ANY}\\]`; const LINK_URL = `\\((https?:\\/\\/.+?)\\)`; const LINK_REG_1 = new RegExp(`${LINK_ALT}${LINK_URL}`); -const LinkRule: MDRule = { +const LinkRule: InlineMDRule = { match: (text) => text.match(LINK_REG_1), html: (parse, match) => { const [, g1, g2] = match; @@ -134,19 +153,11 @@ const LinkRule: MDRule = { }, }; -const beforeMatch = (text: string, match: RegExpMatchArray | RegExpExecArray): string => - text.slice(0, match.index); -const afterMatch = (text: string, match: RegExpMatchArray | RegExpExecArray): string => - text.slice((match.index ?? 0) + match[0].length); - -const replaceMatch: MatchReplacer = (parse, text, match, content) => - `${parse(beforeMatch(text, match))}${content}${parse(afterMatch(text, match))}`; - -const runRule: RuleRunner = (parse, text, rule) => { +const runInlineRule: InlineRuleRunner = (parse, text, rule) => { const matchResult = rule.match(text); if (matchResult) { const content = rule.html(parse, matchResult); - return replaceMatch(parse, text, matchResult, content); + return replaceMatch((txt) => [parse(txt)], text, matchResult, content).join(''); } return undefined; }; @@ -155,10 +166,10 @@ const runRule: RuleRunner = (parse, text, rule) => { * Runs multiple rules at the same time to better handle nested rules. * Rules will be run in the order they appear. */ -const runRules: RulesRunner = (parse, text, rules) => { +const runInlineRules: InlineRulesRunner = (parse, text, rules) => { const matchResults = rules.map((rule) => rule.match(text)); - let targetRule: MDRule | undefined; + let targetRule: InlineMDRule | undefined; let targetResult: MatchResult | undefined; for (let i = 0; i < matchResults.length; i += 1) { @@ -176,7 +187,7 @@ const runRules: RulesRunner = (parse, text, rules) => { if (targetRule && targetResult) { const content = targetRule.html(parse, targetResult); - return replaceMatch(parse, text, targetResult, content); + return replaceMatch((txt) => [parse(txt)], text, targetResult, content).join(''); } return undefined; }; @@ -191,11 +202,167 @@ const LeveledRules = [ LinkRule, ]; -export const parseInlineMD = (text: string): string => { +export const parseInlineMD: InlineMDParser = (text) => { + if (text === '') return text; let result: string | undefined; - if (!result) result = runRule(parseInlineMD, text, CodeRule); + if (!result) result = runInlineRule(parseInlineMD, text, CodeRule); - if (!result) result = runRules(parseInlineMD, text, LeveledRules); + if (!result) result = runInlineRules(parseInlineMD, text, LeveledRules); + + return result ?? text; +}; + +/* + **************** + * BLOCK PARSER * + **************** + */ + +export type BlockMDParser = (test: string, parseInline?: (txt: string) => string) => string; + +export type BlockMatchConverter = ( + match: MatchResult, + parseInline?: (txt: string) => string +) => string; + +export type BlockMDRule = { + match: RuleMatch; + html: BlockMatchConverter; +}; + +export type BlockRuleRunner = ( + parse: BlockMDParser, + text: string, + rule: BlockMDRule, + parseInline?: (txt: string) => string +) => string | undefined; + +const HEADING_REG_1 = /^(#{1,6}) +(.+)\n?/m; +const HeadingRule: BlockMDRule = { + match: (text) => text.match(HEADING_REG_1), + html: (match, parseInline) => { + const [, g1, g2] = match; + const level = g1.length; + return `${parseInline ? parseInline(g2) : g2}`; + }, +}; + +const CODEBLOCK_MD_1 = '```'; +const CODEBLOCK_REG_1 = /^`{3}(\S*)\n((.+\n)+)`{3} *(?!.)\n?/m; +const CodeBlockRule: BlockMDRule = { + match: (text) => text.match(CODEBLOCK_REG_1), + html: (match) => { + const [, g1, g2] = match; + const classNameAtt = g1 ? ` class="language-${g1}"` : ''; + return `
          ${g2}
          `; + }, +}; + +const BLOCKQUOTE_MD_1 = '>'; +const QUOTE_LINE_PREFIX = /^> */; +const BLOCKQUOTE_TRAILING_NEWLINE = /\n$/; +const BLOCKQUOTE_REG_1 = /(^>.*\n?)+/m; +const BlockQuoteRule: BlockMDRule = { + match: (text) => text.match(BLOCKQUOTE_REG_1), + html: (match, parseInline) => { + const [blockquoteText] = match; + + const lines = blockquoteText + .replace(BLOCKQUOTE_TRAILING_NEWLINE, '') + .split('\n') + .map((lineText) => { + const line = lineText.replace(QUOTE_LINE_PREFIX, ''); + if (parseInline) return `${parseInline(line)}
          `; + return `${line}
          `; + }) + .join(''); + return `
          ${lines}
          `; + }, +}; + +const ORDERED_LIST_MD_1 = '-'; +const O_LIST_ITEM_PREFIX = /^(-|[\da-zA-Z]\.) */; +const O_LIST_START = /^([\d])\./; +const O_LIST_TYPE = /^([aAiI])\./; +const O_LIST_TRAILING_NEWLINE = /\n$/; +const ORDERED_LIST_REG_1 = /(^(-|[\da-zA-Z]\.) +.+\n?)+/m; +const OrderedListRule: BlockMDRule = { + match: (text) => text.match(ORDERED_LIST_REG_1), + html: (match, parseInline) => { + const [listText] = match; + const [, listStart] = listText.match(O_LIST_START) ?? []; + const [, listType] = listText.match(O_LIST_TYPE) ?? []; + + const lines = listText + .replace(O_LIST_TRAILING_NEWLINE, '') + .split('\n') + .map((lineText) => { + const line = lineText.replace(O_LIST_ITEM_PREFIX, ''); + const txt = parseInline ? parseInline(line) : line; + return `
        1. ${txt}

        2. `; + }) + .join(''); + + const dataMdAtt = `data-md="${listType || listStart || ORDERED_LIST_MD_1}"`; + const startAtt = listStart ? ` start="${listStart}"` : ''; + const typeAtt = listType ? ` type="${listType}"` : ''; + return `
            ${lines}
          `; + }, +}; + +const UNORDERED_LIST_MD_1 = '*'; +const U_LIST_ITEM_PREFIX = /^\* */; +const U_LIST_TRAILING_NEWLINE = /\n$/; +const UNORDERED_LIST_REG_1 = /(^\* +.+\n?)+/m; +const UnorderedListRule: BlockMDRule = { + match: (text) => text.match(UNORDERED_LIST_REG_1), + html: (match, parseInline) => { + const [listText] = match; + + const lines = listText + .replace(U_LIST_TRAILING_NEWLINE, '') + .split('\n') + .map((lineText) => { + const line = lineText.replace(U_LIST_ITEM_PREFIX, ''); + const txt = parseInline ? parseInline(line) : line; + return `
        3. ${txt}

        4. `; + }) + .join(''); + + return `
            ${lines}
          `; + }, +}; + +const runBlockRule: BlockRuleRunner = (parse, text, rule, parseInline) => { + const matchResult = rule.match(text); + if (matchResult) { + const content = rule.html(matchResult, parseInline); + return replaceMatch((txt) => [parse(txt, parseInline)], text, matchResult, content).join(''); + } + return undefined; +}; + +export const parseBlockMD: BlockMDParser = (text, parseInline) => { + if (text === '') return text; + let result: string | undefined; + + if (!result) result = runBlockRule(parseBlockMD, text, CodeBlockRule, parseInline); + if (!result) result = runBlockRule(parseBlockMD, text, BlockQuoteRule, parseInline); + if (!result) result = runBlockRule(parseBlockMD, text, OrderedListRule, parseInline); + if (!result) result = runBlockRule(parseBlockMD, text, UnorderedListRule, parseInline); + if (!result) result = runBlockRule(parseBlockMD, text, HeadingRule, parseInline); + + // replace \n with
          because want to preserve empty lines + if (!result) { + if (parseInline) { + result = text + .split('\n') + .map((lineText) => parseInline(lineText)) + .join('
          '); + } else { + result = text.replace(/\n/g, '
          '); + } + } return result ?? text; }; diff --git a/src/app/utils/room.ts b/src/app/utils/room.ts index adb6dc088..a2cb3a9f1 100644 --- a/src/app/utils/room.ts +++ b/src/app/utils/room.ts @@ -256,7 +256,7 @@ export const getRoomAvatarUrl = (mx: MatrixClient, room: Room): string | undefin }; export const trimReplyFromBody = (body: string): string => { - const match = body.match(/^>\s<.+?>\s.+\n\n/); + const match = body.match(/^> <.+?> .+\n(>.*\n)*?\n/m); if (!match) return body; return body.slice(match[0].length); }; diff --git a/src/app/utils/sanitize.ts b/src/app/utils/sanitize.ts index 8e7c1283b..48ab0b8d1 100644 --- a/src/app/utils/sanitize.ts +++ b/src/app/utils/sanitize.ts @@ -59,9 +59,18 @@ const permittedTagToAttributes = { 'data-md', ], div: ['data-mx-maths'], + blockquote: ['data-md'], + h1: ['data-md'], + h2: ['data-md'], + h3: ['data-md'], + h4: ['data-md'], + h5: ['data-md'], + h6: ['data-md'], + pre: ['data-md', 'class'], + ol: ['start', 'type', 'data-md'], + ul: ['data-md'], a: ['name', 'target', 'href', 'rel', 'data-md'], img: ['width', 'height', 'alt', 'title', 'src', 'data-mx-emoticon'], - ol: ['start'], code: ['class', 'data-md'], strong: ['data-md'], i: ['data-md'], From 3cef074c9ef6744278e84b97580049a427d81121 Mon Sep 17 00:00:00 2001 From: Krishan <33421343+kfiven@users.noreply.github.com> Date: Fri, 27 Oct 2023 22:11:08 +1100 Subject: [PATCH 1092/1531] Release v3.1.0 (#1510) * Update package.json * Update cons.js * Update package-lock.json --- package-lock.json | 4 ++-- package.json | 2 +- src/client/state/cons.js | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8c2e80d01..6e581863b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "cinny", - "version": "3.0.0", + "version": "3.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "cinny", - "version": "3.0.0", + "version": "3.1.0", "license": "AGPL-3.0-only", "dependencies": { "@fontsource/inter": "4.5.14", diff --git a/package.json b/package.json index 0f1bfa75e..17fbf168a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cinny", - "version": "3.0.0", + "version": "3.1.0", "description": "Yet another matrix client", "main": "index.js", "engines": { diff --git a/src/client/state/cons.js b/src/client/state/cons.js index 5d29d1df7..b8074d90d 100644 --- a/src/client/state/cons.js +++ b/src/client/state/cons.js @@ -1,5 +1,5 @@ const cons = { - version: '3.0.0', + version: '3.1.0', secretKey: { ACCESS_TOKEN: 'cinny_access_token', DEVICE_ID: 'cinny_device_id', From a2cbe797875ca96394c5af1e69093c32b169eff0 Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Sun, 29 Oct 2023 21:53:44 +1100 Subject: [PATCH 1093/1531] Fix broken emoji with md pattern in shortcode (#1514) * fix broken emoji with md pattern in shortcode * fix html regex when generating editor output --- src/app/components/editor/output.ts | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/app/components/editor/output.ts b/src/app/components/editor/output.ts index fa15bb582..1fb2d590a 100644 --- a/src/app/components/editor/output.ts +++ b/src/app/components/editor/output.ts @@ -51,21 +51,25 @@ const elementToCustomHtml = (node: CustomElement, children: string): string => { return `
            ${children}
          `; case BlockType.Mention: - return `${node.name}`; + return `${sanitizeText( + node.name + )}`; case BlockType.Emoticon: return node.key.startsWith('mxc://') - ? `${node.shortcode}` - : node.key; + ? `${sanitizeText(
+            node.shortcode
+          )}` + : sanitizeText(node.key); case BlockType.Link: - return `${node.children}`; + return `${node.children}`; case BlockType.Command: - return `/${node.command}`; + return `/${sanitizeText(node.command)}`; default: return children; } }; -const HTML_TAG_REG = /<([a-z]+)(?![^>]*\/>)[^<]*<\/\1>/; +const HTML_TAG_REG = /<([\w-]+)(?:[^/>]*)(?:(?:\/>)|(?:>.*?<\/\1>))/; const ignoreHTMLParseInlineMD = (text: string): string => { if (text === '') return text; const match = text.match(HTML_TAG_REG); From a98903a85b81d5d799bb65dee9713499ea0ac029 Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Sun, 29 Oct 2023 22:42:05 +1100 Subject: [PATCH 1094/1531] Fix regex to ignore html tag in editor output (#1515) --- src/app/components/editor/output.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/components/editor/output.ts b/src/app/components/editor/output.ts index 1fb2d590a..9a03604c1 100644 --- a/src/app/components/editor/output.ts +++ b/src/app/components/editor/output.ts @@ -69,7 +69,7 @@ const elementToCustomHtml = (node: CustomElement, children: string): string => { } }; -const HTML_TAG_REG = /<([\w-]+)(?:[^/>]*)(?:(?:\/>)|(?:>.*?<\/\1>))/; +const HTML_TAG_REG = /<([\w-]+)(?: [^>]*)?(?:(?:\/>)|(?:>.*?<\/\1>))/; const ignoreHTMLParseInlineMD = (text: string): string => { if (text === '') return text; const match = text.match(HTML_TAG_REG); From 9f9173c691aa61d3dff87aa2d26e4231452ab755 Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Mon, 30 Oct 2023 07:14:58 +1100 Subject: [PATCH 1095/1531] Add URL preview (#1511) * URL preview - WIP * fix url preview regex * update url match regex * add url preview components * add scroll btn url preview holder * add message body component * add url preview toggle in settings * update url regex * improve url regex * increase thumbnail size in url preview * hide url preview in encrypted rooms * add encrypted room url preview toggle --- src/app/components/message/layout/Base.tsx | 15 +- .../components/message/layout/layout.css.ts | 27 +++ .../components/url-preview/UrlPreview.css.tsx | 45 +++++ src/app/components/url-preview/UrlPreview.tsx | 27 +++ src/app/components/url-preview/index.ts | 1 + src/app/organisms/room/RoomTimeline.tsx | 112 +++++++---- .../organisms/room/message/UrlPreviewCard.tsx | 183 ++++++++++++++++++ src/app/organisms/room/message/styles.css.ts | 48 ++++- src/app/organisms/settings/Settings.jsx | 22 +++ src/app/state/settings.ts | 4 + src/app/utils/regex.ts | 2 + 11 files changed, 444 insertions(+), 42 deletions(-) create mode 100644 src/app/components/url-preview/UrlPreview.css.tsx create mode 100644 src/app/components/url-preview/UrlPreview.tsx create mode 100644 src/app/components/url-preview/index.ts create mode 100644 src/app/organisms/room/message/UrlPreviewCard.tsx diff --git a/src/app/components/message/layout/Base.tsx b/src/app/components/message/layout/Base.tsx index 9439ec572..1ce764b51 100644 --- a/src/app/components/message/layout/Base.tsx +++ b/src/app/components/message/layout/Base.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { as } from 'folds'; +import { Text, as } from 'folds'; import classNames from 'classnames'; import * as css from './layout.css'; @@ -23,3 +23,16 @@ export const AvatarBase = as<'span'>(({ className, ...props }, ref) => ( export const Username = as<'span'>(({ as: AsUsername = 'span', className, ...props }, ref) => ( )); + +export const MessageTextBody = as<'div', css.MessageTextBodyVariants & { notice?: boolean }>( + ({ as: asComp = 'div', className, preWrap, jumboEmoji, emote, notice, ...props }, ref) => ( + + ) +); diff --git a/src/app/components/message/layout/layout.css.ts b/src/app/components/message/layout/layout.css.ts index 7b1a267df..a6b7db0df 100644 --- a/src/app/components/message/layout/layout.css.ts +++ b/src/app/components/message/layout/layout.css.ts @@ -153,3 +153,30 @@ export const Username = style({ }, }, }); + +export const MessageTextBody = recipe({ + base: { + wordBreak: 'break-word', + }, + variants: { + preWrap: { + true: { + whiteSpace: 'pre-wrap', + }, + }, + jumboEmoji: { + true: { + fontSize: '1.504em', + lineHeight: '1.4962em', + }, + }, + emote: { + true: { + color: color.Success.Main, + fontStyle: 'italic', + }, + }, + }, +}); + +export type MessageTextBodyVariants = RecipeVariants; diff --git a/src/app/components/url-preview/UrlPreview.css.tsx b/src/app/components/url-preview/UrlPreview.css.tsx new file mode 100644 index 000000000..3e97c1166 --- /dev/null +++ b/src/app/components/url-preview/UrlPreview.css.tsx @@ -0,0 +1,45 @@ +import { style } from '@vanilla-extract/css'; +import { DefaultReset, color, config, toRem } from 'folds'; + +export const UrlPreview = style([ + DefaultReset, + { + width: toRem(400), + minHeight: toRem(102), + backgroundColor: color.SurfaceVariant.Container, + color: color.SurfaceVariant.OnContainer, + border: `${config.borderWidth.B300} solid ${color.SurfaceVariant.ContainerLine}`, + borderRadius: config.radii.R300, + overflow: 'hidden', + }, +]); + +export const UrlPreviewImg = style([ + DefaultReset, + { + width: toRem(100), + height: toRem(100), + objectFit: 'cover', + objectPosition: 'left', + backgroundPosition: 'start', + flexShrink: 0, + overflow: 'hidden', + }, +]); + +export const UrlPreviewContent = style([ + DefaultReset, + { + padding: config.space.S200, + }, +]); + +export const UrlPreviewDescription = style([ + DefaultReset, + { + display: '-webkit-box', + WebkitLineClamp: 2, + WebkitBoxOrient: 'vertical', + overflow: 'hidden', + }, +]); diff --git a/src/app/components/url-preview/UrlPreview.tsx b/src/app/components/url-preview/UrlPreview.tsx new file mode 100644 index 000000000..4ba3e4e22 --- /dev/null +++ b/src/app/components/url-preview/UrlPreview.tsx @@ -0,0 +1,27 @@ +import React from 'react'; +import classNames from 'classnames'; +import { Box, as } from 'folds'; +import * as css from './UrlPreview.css'; + +export const UrlPreview = as<'div'>(({ className, ...props }, ref) => ( + +)); + +export const UrlPreviewImg = as<'img'>(({ className, alt, ...props }, ref) => ( + {alt} +)); + +export const UrlPreviewContent = as<'div'>(({ className, ...props }, ref) => ( + +)); + +export const UrlPreviewDescription = as<'span'>(({ className, ...props }, ref) => ( + +)); diff --git a/src/app/components/url-preview/index.ts b/src/app/components/url-preview/index.ts new file mode 100644 index 000000000..6d4dc333c --- /dev/null +++ b/src/app/components/url-preview/index.ts @@ -0,0 +1 @@ +export * from './UrlPreview'; diff --git a/src/app/organisms/room/RoomTimeline.tsx b/src/app/organisms/room/RoomTimeline.tsx index c1b044583..9603209df 100644 --- a/src/app/organisms/room/RoomTimeline.tsx +++ b/src/app/organisms/room/RoomTimeline.tsx @@ -74,6 +74,7 @@ import { Time, MessageBadEncryptedContent, MessageNotDecryptedContent, + MessageTextBody, } from '../../components/message'; import { emojifyAndLinkify, @@ -138,13 +139,15 @@ import initMatrix from '../../../client/initMatrix'; import { useKeyDown } from '../../hooks/useKeyDown'; import cons from '../../../client/state/cons'; import { useDocumentFocusChange } from '../../hooks/useDocumentFocusChange'; -import { EMOJI_PATTERN, VARIATION_SELECTOR_PATTERN } from '../../utils/regex'; +import { EMOJI_PATTERN, HTTP_URL_PATTERN, VARIATION_SELECTOR_PATTERN } from '../../utils/regex'; +import { UrlPreviewCard, UrlPreviewHolder } from './message/UrlPreviewCard'; // Thumbs up emoji found to have Variation Selector 16 at the end // so included variation selector pattern in regex const JUMBO_EMOJI_REG = new RegExp( `^(((${EMOJI_PATTERN})|(:.+?:))(${VARIATION_SELECTOR_PATTERN}|\\s)*){1,10}$` ); +const URL_REG = new RegExp(HTTP_URL_PATTERN, 'g'); const TimelineFloat = as<'div', css.TimelineFloatVariants>( ({ position, className, ...props }, ref) => ( @@ -462,11 +465,15 @@ const getRoomUnreadInfo = (room: Room, scrollTo = false) => { export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimelineProps) { const mx = useMatrixClient(); + const encryptedRoom = mx.isRoomEncrypted(room.roomId); const [messageLayout] = useSetting(settingsAtom, 'messageLayout'); const [messageSpacing] = useSetting(settingsAtom, 'messageSpacing'); const [hideMembershipEvents] = useSetting(settingsAtom, 'hideMembershipEvents'); const [hideNickAvatarEvents] = useSetting(settingsAtom, 'hideNickAvatarEvents'); const [mediaAutoLoad] = useSetting(settingsAtom, 'mediaAutoLoad'); + const [urlPreview] = useSetting(settingsAtom, 'urlPreview'); + const [encUrlPreview] = useSetting(settingsAtom, 'encUrlPreview'); + const showUrlPreview = encryptedRoom ? encUrlPreview : urlPreview; const [showHiddenEvents] = useSetting(settingsAtom, 'showHiddenEvents'); const setReplyDraft = useSetAtom(roomIdToReplyDraftAtomFamily(room.roomId)); const { canDoAction, canSendEvent, getPowerLevel } = usePowerLevelsAPI(); @@ -1000,22 +1007,27 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli editedEvent?.getContent()['m.new_content'] ?? mEvent.getContent(); if (typeof body !== 'string') return null; - const jumboEmoji = JUMBO_EMOJI_REG.test(trimReplyFromBody(body)); + const trimmedBody = trimReplyFromBody(body); + const urlsMatch = showUrlPreview && trimmedBody.match(URL_REG); + const urls = urlsMatch ? [...new Set(urlsMatch)] : undefined; return ( - - {renderBody(body, typeof customBody === 'string' ? customBody : undefined)} - {!!editedEvent && } - + <> + + {renderBody(trimmedBody, typeof customBody === 'string' ? customBody : undefined)} + {!!editedEvent && } + + {urls && urls.length > 0 && ( + + {urls.map((url) => ( + + ))} + + )} + ); }, renderEmote: (mEventId, mEvent, timelineSet) => { @@ -1026,21 +1038,31 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli const senderDisplayName = getMemberDisplayName(room, senderId) ?? getMxIdLocalPart(senderId) ?? senderId; + + if (typeof body !== 'string') return null; + const trimmedBody = trimReplyFromBody(body); + const urlsMatch = showUrlPreview && trimmedBody.match(URL_REG); + const urls = urlsMatch ? [...new Set(urlsMatch)] : undefined; + return ( - - {`${senderDisplayName} `} - {renderBody(body, typeof customBody === 'string' ? customBody : undefined)} - {!!editedEvent && } - + <> + + {`${senderDisplayName} `} + {renderBody(trimmedBody, typeof customBody === 'string' ? customBody : undefined)} + {!!editedEvent && } + + {urls && urls.length > 0 && ( + + {urls.map((url) => ( + + ))} + + )} + ); }, renderNotice: (mEventId, mEvent, timelineSet) => { @@ -1049,18 +1071,28 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli editedEvent?.getContent()['m.new_content'] ?? mEvent.getContent(); if (typeof body !== 'string') return null; + const trimmedBody = trimReplyFromBody(body); + const urlsMatch = showUrlPreview && trimmedBody.match(URL_REG); + const urls = urlsMatch ? [...new Set(urlsMatch)] : undefined; + return ( - - {renderBody(body, typeof customBody === 'string' ? customBody : undefined)} - {!!editedEvent && } - + <> + + {renderBody(trimmedBody, typeof customBody === 'string' ? customBody : undefined)} + {!!editedEvent && } + + {urls && urls.length > 0 && ( + + {urls.map((url) => ( + + ))} + + )} + ); }, renderImage: (mEventId, mEvent) => { diff --git a/src/app/organisms/room/message/UrlPreviewCard.tsx b/src/app/organisms/room/message/UrlPreviewCard.tsx new file mode 100644 index 000000000..9ae4d298b --- /dev/null +++ b/src/app/organisms/room/message/UrlPreviewCard.tsx @@ -0,0 +1,183 @@ +import React, { useCallback, useEffect, useRef, useState } from 'react'; +import { IPreviewUrlResponse } from 'matrix-js-sdk'; +import { Box, Icon, IconButton, Icons, Scroll, Spinner, Text, as, color, config } from 'folds'; +import { AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback'; +import { useMatrixClient } from '../../../hooks/useMatrixClient'; +import { + UrlPreview, + UrlPreviewContent, + UrlPreviewDescription, + UrlPreviewImg, +} from '../../../components/url-preview'; +import { + getIntersectionObserverEntry, + useIntersectionObserver, +} from '../../../hooks/useIntersectionObserver'; +import * as css from './styles.css'; + +const linkStyles = { color: color.Success.Main }; + +export const UrlPreviewCard = as<'div', { url: string; ts: number }>( + ({ url, ts, ...props }, ref) => { + const mx = useMatrixClient(); + const [previewStatus, loadPreview] = useAsyncCallback( + useCallback(() => mx.getUrlPreview(url, ts), [url, ts, mx]) + ); + if (previewStatus.status === AsyncStatus.Idle) loadPreview(); + + if (previewStatus.status === AsyncStatus.Error) return null; + + const renderContent = (prev: IPreviewUrlResponse) => { + const imgUrl = mx.mxcUrlToHttp(prev['og:image'] || '', 256, 256, 'scale', false); + + return ( + <> + {imgUrl && } + + + {typeof prev['og:site_name'] === 'string' && `${prev['og:site_name']} | `} + {decodeURIComponent(url)} + + + {prev['og:title']} + + + {prev['og:description']} + + + + ); + }; + + return ( + + {previewStatus.status === AsyncStatus.Success ? ( + renderContent(previewStatus.data) + ) : ( + + + + )} + + ); + } +); + +export const UrlPreviewHolder = as<'div'>(({ children, ...props }, ref) => { + const scrollRef = useRef(null); + const backAnchorRef = useRef(null); + const frontAnchorRef = useRef(null); + const [backVisible, setBackVisible] = useState(true); + const [frontVisible, setFrontVisible] = useState(true); + + const intersectionObserver = useIntersectionObserver( + useCallback((entries) => { + const backAnchor = backAnchorRef.current; + const frontAnchor = frontAnchorRef.current; + const backEntry = backAnchor && getIntersectionObserverEntry(backAnchor, entries); + const frontEntry = frontAnchor && getIntersectionObserverEntry(frontAnchor, entries); + if (backEntry) { + setBackVisible(backEntry.isIntersecting); + } + if (frontEntry) { + setFrontVisible(frontEntry.isIntersecting); + } + }, []), + useCallback( + () => ({ + root: scrollRef.current, + rootMargin: '10px', + }), + [] + ) + ); + + useEffect(() => { + const backAnchor = backAnchorRef.current; + const frontAnchor = frontAnchorRef.current; + if (backAnchor) intersectionObserver?.observe(backAnchor); + if (frontAnchor) intersectionObserver?.observe(frontAnchor); + return () => { + if (backAnchor) intersectionObserver?.unobserve(backAnchor); + if (frontAnchor) intersectionObserver?.unobserve(frontAnchor); + }; + }, [intersectionObserver]); + + const handleScrollBack = () => { + const scroll = scrollRef.current; + if (!scroll) return; + const { offsetWidth, scrollLeft } = scroll; + scroll.scrollTo({ + left: scrollLeft - offsetWidth / 1.3, + behavior: 'smooth', + }); + }; + const handleScrollFront = () => { + const scroll = scrollRef.current; + if (!scroll) return; + const { offsetWidth, scrollLeft } = scroll; + scroll.scrollTo({ + left: scrollLeft + offsetWidth / 1.3, + behavior: 'smooth', + }); + }; + + return ( + + + +
          + {!backVisible && ( + <> +
          + + + + + )} + + {children} + + {!frontVisible && ( + <> +
          + + + + + )} +
          + + + + + ); +}); diff --git a/src/app/organisms/room/message/styles.css.ts b/src/app/organisms/room/message/styles.css.ts index 801f698d7..d42cf05bf 100644 --- a/src/app/organisms/room/message/styles.css.ts +++ b/src/app/organisms/room/message/styles.css.ts @@ -1,5 +1,6 @@ import { style } from '@vanilla-extract/css'; -import { DefaultReset, config, toRem } from 'folds'; +import { recipe } from '@vanilla-extract/recipes'; +import { DefaultReset, color, config, toRem } from 'folds'; export const RelativeBase = style([ DefaultReset, @@ -83,3 +84,48 @@ export const ReactionsContainer = style({ export const ReactionsTooltipText = style({ wordBreak: 'break-word', }); + +export const UrlPreviewHolderGradient = recipe({ + base: [ + DefaultReset, + { + position: 'absolute', + height: '100%', + width: toRem(10), + zIndex: 1, + }, + ], + variants: { + position: { + Left: { + left: 0, + background: `linear-gradient(to right,${color.Surface.Container} , rgba(116,116,116,0))`, + }, + Right: { + right: 0, + background: `linear-gradient(to left,${color.Surface.Container} , rgba(116,116,116,0))`, + }, + }, + }, +}); +export const UrlPreviewHolderBtn = recipe({ + base: [ + DefaultReset, + { + position: 'absolute', + zIndex: 1, + }, + ], + variants: { + position: { + Left: { + left: 0, + transform: 'translateX(-25%)', + }, + Right: { + right: 0, + transform: 'translateX(25%)', + }, + }, + }, +}); diff --git a/src/app/organisms/settings/Settings.jsx b/src/app/organisms/settings/Settings.jsx index 1b04669cb..47abb45c0 100644 --- a/src/app/organisms/settings/Settings.jsx +++ b/src/app/organisms/settings/Settings.jsx @@ -59,6 +59,8 @@ function AppearanceSection() { const [hideMembershipEvents, setHideMembershipEvents] = useSetting(settingsAtom, 'hideMembershipEvents'); const [hideNickAvatarEvents, setHideNickAvatarEvents] = useSetting(settingsAtom, 'hideNickAvatarEvents'); const [mediaAutoLoad, setMediaAutoLoad] = useSetting(settingsAtom, 'mediaAutoLoad'); + const [urlPreview, setUrlPreview] = useSetting(settingsAtom, 'urlPreview'); + const [encUrlPreview, setEncUrlPreview] = useSetting(settingsAtom, 'encUrlPreview'); const [showHiddenEvents, setShowHiddenEvents] = useSetting(settingsAtom, 'showHiddenEvents'); const spacings = ['0', '100', '200', '300', '400', '500'] @@ -191,6 +193,26 @@ function AppearanceSection() { )} content={Prevent images and videos from auto loading to save bandwidth.} /> + setUrlPreview(!urlPreview)} + /> + )} + content={Show url preview for link in messages.} + /> + setEncUrlPreview(!encUrlPreview)} + /> + )} + content={Show url preview for link in encrypted messages.} + /> Date: Mon, 30 Oct 2023 16:58:30 +1100 Subject: [PATCH 1096/1531] Fix grammer in membership event messages (#1520) --- src/app/hooks/useMemberEventParser.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/hooks/useMemberEventParser.tsx b/src/app/hooks/useMemberEventParser.tsx index 367e76d95..6ceca1b1d 100644 --- a/src/app/hooks/useMemberEventParser.tsx +++ b/src/app/hooks/useMemberEventParser.tsx @@ -90,13 +90,13 @@ export const useMemberEventParser = (): MemberEventParser => { senderId === userId ? ( <> {userName} - {' reject the invitation '} + {' rejected the invitation '} {content.reason} ) : ( <> {senderName} - {' reject '} + {' rejected '} {userName} {`'s join request `} {content.reason} From c854c7f9d2167e1e38baf90d17afa0ee1f77033b Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Mon, 30 Oct 2023 16:58:47 +1100 Subject: [PATCH 1097/1531] Timeline Perf Improvement (#1521) * emojify msg txt find&replace instead of recursion * move findAndReplace func in its own file * improve find and replace * move markdown file to plugins * make find and replace work without g flag regex * fix pagination stop on msg arrive * render blurhash in small size --- src/app/components/editor/output.ts | 19 ++++++------ src/app/organisms/room/RoomTimeline.tsx | 2 -- .../organisms/room/message/ImageContent.tsx | 8 ++++- .../organisms/room/message/VideoContent.tsx | 8 ++++- src/app/{utils => plugins}/markdown.ts | 0 src/app/plugins/react-custom-html-parser.tsx | 30 ++++++++----------- src/app/utils/findAndReplace.ts | 28 +++++++++++++++++ 7 files changed, 65 insertions(+), 30 deletions(-) rename src/app/{utils => plugins}/markdown.ts (100%) create mode 100644 src/app/utils/findAndReplace.ts diff --git a/src/app/components/editor/output.ts b/src/app/components/editor/output.ts index 9a03604c1..53ee6ddf5 100644 --- a/src/app/components/editor/output.ts +++ b/src/app/components/editor/output.ts @@ -3,7 +3,8 @@ import { Descendant, Text } from 'slate'; import { sanitizeText } from '../../utils/sanitize'; import { BlockType } from './types'; import { CustomElement } from './slate'; -import { parseBlockMD, parseInlineMD, replaceMatch } from '../../utils/markdown'; +import { parseBlockMD, parseInlineMD } from '../../plugins/markdown'; +import { findAndReplace } from '../../utils/findAndReplace'; export type OutputOptions = { allowTextFormatting?: boolean; @@ -69,14 +70,14 @@ const elementToCustomHtml = (node: CustomElement, children: string): string => { } }; -const HTML_TAG_REG = /<([\w-]+)(?: [^>]*)?(?:(?:\/>)|(?:>.*?<\/\1>))/; -const ignoreHTMLParseInlineMD = (text: string): string => { - if (text === '') return text; - const match = text.match(HTML_TAG_REG); - if (!match) return parseInlineMD(text); - const [matchedTxt] = match; - return replaceMatch((txt) => [ignoreHTMLParseInlineMD(txt)], text, match, matchedTxt).join(''); -}; +const HTML_TAG_REG_G = /<([\w-]+)(?: [^>]*)?(?:(?:\/>)|(?:>.*?<\/\1>))/g; +const ignoreHTMLParseInlineMD = (text: string): string => + findAndReplace( + text, + HTML_TAG_REG_G, + (match) => match[0], + (txt) => parseInlineMD(txt) + ).join(''); export const toMatrixCustomHTML = ( node: Descendant | Descendant[], diff --git a/src/app/organisms/room/RoomTimeline.tsx b/src/app/organisms/room/RoomTimeline.tsx index 9603209df..0c74de520 100644 --- a/src/app/organisms/room/RoomTimeline.tsx +++ b/src/app/organisms/room/RoomTimeline.tsx @@ -345,7 +345,6 @@ const useTimelinePagination = ( return async (backwards: boolean) => { if (fetching) return; - const targetTimeline = timelineRef.current; const { linkedTimelines: lTimelines } = timelineRef.current; const timelinesEventsCount = lTimelines.map(timelineToEventsCount); @@ -385,7 +384,6 @@ const useTimelinePagination = ( } fetching = false; - if (targetTimeline !== timelineRef.current) return; if (alive()) { recalibratePagination(lTimelines, timelinesEventsCount, backwards); } diff --git a/src/app/organisms/room/message/ImageContent.tsx b/src/app/organisms/room/message/ImageContent.tsx index c8b32cc1c..6e2880264 100644 --- a/src/app/organisms/room/message/ImageContent.tsx +++ b/src/app/organisms/room/message/ImageContent.tsx @@ -98,7 +98,13 @@ export const ImageContent = as<'div', ImageContentProps>( )} {typeof blurHash === 'string' && !load && ( - + )} {!autoPlay && srcState.status === AsyncStatus.Idle && ( diff --git a/src/app/organisms/room/message/VideoContent.tsx b/src/app/organisms/room/message/VideoContent.tsx index 107d5f9ac..8b3bd34d4 100644 --- a/src/app/organisms/room/message/VideoContent.tsx +++ b/src/app/organisms/room/message/VideoContent.tsx @@ -88,7 +88,13 @@ export const VideoContent = as<'div', VideoContentProps>( return ( {typeof blurHash === 'string' && !load && ( - + )} {thumbSrcState.status === AsyncStatus.Success && !load && ( diff --git a/src/app/utils/markdown.ts b/src/app/plugins/markdown.ts similarity index 100% rename from src/app/utils/markdown.ts rename to src/app/plugins/markdown.ts diff --git a/src/app/plugins/react-custom-html-parser.tsx b/src/app/plugins/react-custom-html-parser.tsx index 928419c54..ee41687de 100644 --- a/src/app/plugins/react-custom-html-parser.tsx +++ b/src/app/plugins/react-custom-html-parser.tsx @@ -18,11 +18,11 @@ import { getMxIdLocalPart, getRoomWithCanonicalAlias } from '../utils/matrix'; import { getMemberDisplayName } from '../utils/room'; import { EMOJI_PATTERN, URL_NEG_LB } from '../utils/regex'; import { getHexcodeForEmoji, getShortcodeFor } from './emoji'; -import { replaceMatch } from '../utils/markdown'; +import { findAndReplace } from '../utils/findAndReplace'; const ReactPrism = lazy(() => import('./react-prism/ReactPrism')); -const EMOJI_REG = new RegExp(`${URL_NEG_LB}(${EMOJI_PATTERN})`); +const EMOJI_REG_G = new RegExp(`${URL_NEG_LB}(${EMOJI_PATTERN})`, 'g'); export const LINKIFY_OPTS: LinkifyOpts = { attributes: { @@ -35,26 +35,22 @@ export const LINKIFY_OPTS: LinkifyOpts = { ignoreTags: ['span'], }; -const stringToEmojifyJSX = (text: string): (string | JSX.Element)[] => { - const match = text.match(EMOJI_REG); - if (!match) return [text]; - - const [emoji] = match; - - return replaceMatch( - stringToEmojifyJSX, +const textToEmojifyJSX = (text: string): (string | JSX.Element)[] => + findAndReplace( text, - match, - - - {emoji} + EMOJI_REG_G, + (match, pushIndex) => ( + + + {match[0]} + - + ), + (txt) => txt ); -}; export const emojifyAndLinkify = (text: string, linkify?: boolean) => { - const emojifyJSX = stringToEmojifyJSX(text); + const emojifyJSX = textToEmojifyJSX(text); if (linkify) { return {emojifyJSX}; diff --git a/src/app/utils/findAndReplace.ts b/src/app/utils/findAndReplace.ts new file mode 100644 index 000000000..a4bd1edb9 --- /dev/null +++ b/src/app/utils/findAndReplace.ts @@ -0,0 +1,28 @@ +export type ReplaceCallback = ( + match: RegExpExecArray | RegExpMatchArray, + pushIndex: number +) => R; +export type ConvertPartCallback = (text: string, pushIndex: number) => R; + +export const findAndReplace = ( + text: string, + regex: RegExp, + replace: ReplaceCallback, + convertPart: ConvertPartCallback +): Array => { + const result: Array = []; + let lastEnd = 0; + + let match: RegExpExecArray | RegExpMatchArray | null = regex.exec(text); + while (match !== null && typeof match.index === 'number') { + result.push(convertPart(text.slice(lastEnd, match.index), result.length)); + result.push(replace(match, result.length)); + + lastEnd = match.index + match[0].length; + if (regex.global) match = regex.exec(text); + } + + result.push(convertPart(text.slice(lastEnd), result.length)); + + return result; +}; From c3f564605fd9653a593d0685cc8b8e2addd1281e Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Tue, 31 Oct 2023 14:17:57 +1100 Subject: [PATCH 1098/1531] Render reaction with string only key (#1522) --- src/app/organisms/room/message/Reactions.tsx | 3 +- .../room/reaction-viewer/ReactionViewer.tsx | 30 ++++++++++++------- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/src/app/organisms/room/message/Reactions.tsx b/src/app/organisms/room/message/Reactions.tsx index 17b914e5f..728cf8107 100644 --- a/src/app/organisms/room/message/Reactions.tsx +++ b/src/app/organisms/room/message/Reactions.tsx @@ -43,7 +43,6 @@ export const Reactions = as<'div', ReactionsProps>( evt.stopPropagation(); evt.preventDefault(); const key = evt.currentTarget.getAttribute('data-reaction-key'); - console.log(key); if (!key) setViewer(true); else setViewer(key); }; @@ -58,7 +57,7 @@ export const Reactions = as<'div', ReactionsProps>( > {reactions.map(([key, events]) => { const rEvents = Array.from(events); - if (rEvents.length === 0) return null; + if (rEvents.length === 0 || typeof key !== 'string') return null; const myREvent = myUserId ? rEvents.find(factoryEventSentBy(myUserId)) : undefined; const isPressed = !!myREvent?.getRelation(); diff --git a/src/app/organisms/room/reaction-viewer/ReactionViewer.tsx b/src/app/organisms/room/reaction-viewer/ReactionViewer.tsx index 5626981ef..7bcc0ccf8 100644 --- a/src/app/organisms/room/reaction-viewer/ReactionViewer.tsx +++ b/src/app/organisms/room/reaction-viewer/ReactionViewer.tsx @@ -41,7 +41,12 @@ export const ReactionViewer = as<'div', ReactionViewerProps>( relations, useCallback((rel) => [...(rel.getSortedAnnotationsByKey() ?? [])], []) ); - const [selectedKey, setSelectedKey] = useState(initialKey ?? reactions[0][0]); + + const [selectedKey, setSelectedKey] = useState(() => { + if (initialKey) return initialKey; + const defaultReaction = reactions.find((reaction) => typeof reaction[0] === 'string'); + return defaultReaction ? defaultReaction[0] : ''; + }); const getName = (member: RoomMember) => getMemberDisplayName(room, member.userId) ?? getMxIdLocalPart(member.userId) ?? member.userId; @@ -68,16 +73,19 @@ export const ReactionViewer = as<'div', ReactionViewerProps>( - {reactions.map(([key, evts]) => ( - setSelectedKey(key)} - /> - ))} + {reactions.map(([key, evts]) => { + if (typeof key !== 'string') return null; + return ( + setSelectedKey(key)} + /> + ); + })} From 687ad8d0f0b30146d4cad585d73e79dba57ed729 Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Tue, 31 Oct 2023 14:18:30 +1100 Subject: [PATCH 1099/1531] Fix blockcode with empty lines not rendered (#1524) --- src/app/plugins/markdown.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/plugins/markdown.ts b/src/app/plugins/markdown.ts index c6bb3914a..40427a7fc 100644 --- a/src/app/plugins/markdown.ts +++ b/src/app/plugins/markdown.ts @@ -248,7 +248,7 @@ const HeadingRule: BlockMDRule = { }; const CODEBLOCK_MD_1 = '```'; -const CODEBLOCK_REG_1 = /^`{3}(\S*)\n((.+\n)+)`{3} *(?!.)\n?/m; +const CODEBLOCK_REG_1 = /^`{3}(\S*)\n((?:.*\n)+?)`{3} *(?!.)\n?/m; const CodeBlockRule: BlockMDRule = { match: (text) => text.match(CODEBLOCK_REG_1), html: (match) => { @@ -285,7 +285,7 @@ const O_LIST_ITEM_PREFIX = /^(-|[\da-zA-Z]\.) */; const O_LIST_START = /^([\d])\./; const O_LIST_TYPE = /^([aAiI])\./; const O_LIST_TRAILING_NEWLINE = /\n$/; -const ORDERED_LIST_REG_1 = /(^(-|[\da-zA-Z]\.) +.+\n?)+/m; +const ORDERED_LIST_REG_1 = /(^(?:-|[\da-zA-Z]\.) +.+\n?)+/m; const OrderedListRule: BlockMDRule = { match: (text) => text.match(ORDERED_LIST_REG_1), html: (match, parseInline) => { From 1db0a9eaa8349bb19b545c7827bc37dacbb1b868 Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Tue, 31 Oct 2023 08:57:59 +0530 Subject: [PATCH 1100/1531] fix typo in codeblock markdown output --- src/app/plugins/markdown.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/plugins/markdown.ts b/src/app/plugins/markdown.ts index 40427a7fc..9b3b82f78 100644 --- a/src/app/plugins/markdown.ts +++ b/src/app/plugins/markdown.ts @@ -254,7 +254,7 @@ const CodeBlockRule: BlockMDRule = { html: (match) => { const [, g1, g2] = match; const classNameAtt = g1 ? ` class="language-${g1}"` : ''; - return `
          ${g2}
          `; + return `
          ${g2}
          `; }, }; From 9ecb233763048c730d24ddacecc8c002d3c8fc89 Mon Sep 17 00:00:00 2001 From: Krishan <33421343+kfiven@users.noreply.github.com> Date: Tue, 31 Oct 2023 21:20:49 +1100 Subject: [PATCH 1101/1531] Release v3.2.0 (#1531) * Release v3.2.0 * Update cons.js --- package-lock.json | 4 ++-- package.json | 2 +- src/client/state/cons.js | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6e581863b..677848231 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "cinny", - "version": "3.1.0", + "version": "3.2.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "cinny", - "version": "3.1.0", + "version": "3.2.0", "license": "AGPL-3.0-only", "dependencies": { "@fontsource/inter": "4.5.14", diff --git a/package.json b/package.json index 17fbf168a..69bcd8f0e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cinny", - "version": "3.1.0", + "version": "3.2.0", "description": "Yet another matrix client", "main": "index.js", "engines": { diff --git a/src/client/state/cons.js b/src/client/state/cons.js index b8074d90d..62c0cacc9 100644 --- a/src/client/state/cons.js +++ b/src/client/state/cons.js @@ -1,5 +1,5 @@ const cons = { - version: '3.1.0', + version: '3.2.0', secretKey: { ACCESS_TOKEN: 'cinny_access_token', DEVICE_ID: 'cinny_device_id', From 2889a72b8171191b98eb3e4ef7bf98a2ba3b8781 Mon Sep 17 00:00:00 2001 From: Jan Jurzitza Date: Tue, 28 Nov 2023 15:52:20 +0100 Subject: [PATCH 1102/1531] Make small images not scale up in image viewer (#1554) Instead show them in real resolution --- src/app/components/image-viewer/ImageViewer.css.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/app/components/image-viewer/ImageViewer.css.ts b/src/app/components/image-viewer/ImageViewer.css.ts index fc2f50884..d688afcb7 100644 --- a/src/app/components/image-viewer/ImageViewer.css.ts +++ b/src/app/components/image-viewer/ImageViewer.css.ts @@ -32,8 +32,10 @@ export const ImageViewerImg = style([ DefaultReset, { objectFit: 'contain', - width: '100%', - height: '100%', + width: 'auto', + height: 'auto', + maxWidth: '100%', + maxHeight: '100%', backgroundColor: color.Surface.Container, transition: 'transform 100ms linear', }, From 2a1bf4a42ad6ed887c7e1c47538e61a77d7c86f1 Mon Sep 17 00:00:00 2001 From: Krishan <33421343+kfiven@users.noreply.github.com> Date: Sun, 3 Dec 2023 14:58:01 +1100 Subject: [PATCH 1103/1531] Update default server list (#1571) Remvoe 0wnz.at from list as it seems to need registeration token which we don't support. --- config.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/config.json b/config.json index ac7b1f323..0ff493a17 100644 --- a/config.json +++ b/config.json @@ -1,7 +1,6 @@ { - "defaultHomeserver": 3, + "defaultHomeserver": 2, "homeserverList": [ - "0wnz.at", "converser.eu", "envs.net", "matrix.org", From bb88eb715484ffb46b9e56368f1d92651dc4c6bb Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Mon, 25 Dec 2023 01:08:17 +1100 Subject: [PATCH 1104/1531] Up-mx-js-sdk-29 (#1533) * update matrix-js-sdk * replace deprecated resolveRoomAlias --- package-lock.json | 58 +++++++++++++++------- package.json | 2 +- src/app/organisms/join-alias/JoinAlias.jsx | 2 +- src/util/matrixUtil.js | 2 +- 4 files changed, 44 insertions(+), 20 deletions(-) diff --git a/package-lock.json b/package-lock.json index 677848231..6c944cea5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -40,7 +40,7 @@ "linkify-html": "4.0.2", "linkify-react": "4.1.1", "linkifyjs": "4.0.2", - "matrix-js-sdk": "24.1.0", + "matrix-js-sdk": "29.1.0", "millify": "6.1.0", "pdfjs-dist": "3.10.111", "prismjs": "1.29.0", @@ -1106,10 +1106,10 @@ "node": ">=10" } }, - "node_modules/@matrix-org/matrix-sdk-crypto-js": { - "version": "0.1.0-alpha.5", - "resolved": "https://registry.npmjs.org/@matrix-org/matrix-sdk-crypto-js/-/matrix-sdk-crypto-js-0.1.0-alpha.5.tgz", - "integrity": "sha512-2KjAgWNGfuGLNjJwsrs6gGX157vmcTfNrA4u249utgnMPbJl7QwuUqh1bGxQ0PpK06yvZjgPlkna0lTbuwtuQw==", + "node_modules/@matrix-org/matrix-sdk-crypto-wasm": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@matrix-org/matrix-sdk-crypto-wasm/-/matrix-sdk-crypto-wasm-2.2.0.tgz", + "integrity": "sha512-txmvaTiZpVV0/kWCRcE7tZvRESCEc1ynLJDVh9OUsFlaXfl13c7qdD3E6IJEJ8YiPMIn+PHogdfBZsO84reaMg==", "engines": { "node": ">= 10" } @@ -2712,9 +2712,9 @@ "dev": true }, "node_modules/@types/events": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", - "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==" + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.2.tgz", + "integrity": "sha512-v4Mr60wJuF069iZZCdY5DKhfj0l6eXNJtbSM/oMDNdRLoBEUsktmKnswkz0X3OAic5W8Qy/YU6owKE4A66Y46A==" }, "node_modules/@types/file-saver": { "version": "2.0.5", @@ -3843,6 +3843,11 @@ "node": ">= 8" } }, + "node_modules/crypto-js": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz", + "integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==" + }, "node_modules/css-what": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/css-what/-/css-what-5.1.0.tgz", @@ -5894,6 +5899,11 @@ "node": ">=4.0" } }, + "node_modules/jwt-decode": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-3.1.2.tgz", + "integrity": "sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A==" + }, "node_modules/katex": { "version": "0.16.4", "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.4.tgz", @@ -6098,31 +6108,33 @@ "integrity": "sha512-1QEOsXO+bhyCroIe2/A5OwaxHvBm7EsSQ46DEDn8RBIfQwN5HWBpFvyWWR4QY0KHPPnnJdI99wgRiAl7Ad5qaA==" }, "node_modules/matrix-js-sdk": { - "version": "24.1.0", - "resolved": "https://registry.npmjs.org/matrix-js-sdk/-/matrix-js-sdk-24.1.0.tgz", - "integrity": "sha512-xEx2ZoNsS56dwgqLJ3rIv2SUpFxdQLrLKmJCpMatMUKCAg+NGuZfpQ3QXblIbGaqFNQZCH7fC7S48AeTMZp1Jw==", + "version": "29.1.0", + "resolved": "https://registry.npmjs.org/matrix-js-sdk/-/matrix-js-sdk-29.1.0.tgz", + "integrity": "sha512-nF+ACFioDltGCf2KFfXK7QoJ70Ytnzm4Jse2UI+BDXeR9WCjtKefXJtboN2rmU4MFmLCTHcnBTmu6yig67YUqw==", "dependencies": { "@babel/runtime": "^7.12.5", - "@matrix-org/matrix-sdk-crypto-js": "^0.1.0-alpha.5", + "@matrix-org/matrix-sdk-crypto-wasm": "^2.0.0", "another-json": "^0.2.0", "bs58": "^5.0.0", "content-type": "^1.0.4", + "jwt-decode": "^3.1.2", "loglevel": "^1.7.1", "matrix-events-sdk": "0.0.1", - "matrix-widget-api": "^1.3.1", + "matrix-widget-api": "^1.6.0", + "oidc-client-ts": "^2.2.4", "p-retry": "4", "sdp-transform": "^2.14.1", "unhomoglyph": "^1.0.6", "uuid": "9" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/matrix-widget-api": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/matrix-widget-api/-/matrix-widget-api-1.4.0.tgz", - "integrity": "sha512-dw0dRylGQzDUoiaY/g5xx1tBbS7aoov31PRtFMAvG58/4uerYllV9Gfou7w+I1aglwB6hihTREzKltVjARWV6A==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/matrix-widget-api/-/matrix-widget-api-1.6.0.tgz", + "integrity": "sha512-VXIJyAZ/WnBmT4C7ePqevgMYGneKMCP/0JuCOqntSsaNlCRHJvwvTxmqUU+ufOpzIF5gYNyIrAjbgrEbK3iqJQ==", "dependencies": { "@types/events": "^3.0.0", "events": "^3.2.0" @@ -6462,6 +6474,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/oidc-client-ts": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/oidc-client-ts/-/oidc-client-ts-2.4.0.tgz", + "integrity": "sha512-WijhkTrlXK2VvgGoakWJiBdfIsVGz6CFzgjNNqZU1hPKV2kyeEaJgLs7RwuiSp2WhLfWBQuLvr2SxVlZnk3N1w==", + "dependencies": { + "crypto-js": "^4.2.0", + "jwt-decode": "^3.1.2" + }, + "engines": { + "node": ">=12.13.0" + } + }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", diff --git a/package.json b/package.json index 69bcd8f0e..cb6111b5d 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,7 @@ "linkify-html": "4.0.2", "linkify-react": "4.1.1", "linkifyjs": "4.0.2", - "matrix-js-sdk": "24.1.0", + "matrix-js-sdk": "29.1.0", "millify": "6.1.0", "pdfjs-dist": "3.10.111", "prismjs": "1.29.0", diff --git a/src/app/organisms/join-alias/JoinAlias.jsx b/src/app/organisms/join-alias/JoinAlias.jsx index bb90bf354..bc0a8adb7 100644 --- a/src/app/organisms/join-alias/JoinAlias.jsx +++ b/src/app/organisms/join-alias/JoinAlias.jsx @@ -62,7 +62,7 @@ function JoinAliasContent({ term, requestClose }) { let via; if (alias.startsWith('#')) { try { - const aliasData = await mx.resolveRoomAlias(alias); + const aliasData = await mx.getRoomIdForAlias(alias); via = aliasData?.servers.slice(0, 3) || []; if (mountStore.getItem()) { setProcess(`Joining ${alias}...`); diff --git a/src/util/matrixUtil.js b/src/util/matrixUtil.js index 54ee31bbb..a776fb2be 100644 --- a/src/util/matrixUtil.js +++ b/src/util/matrixUtil.js @@ -41,7 +41,7 @@ export function getUsernameOfRoomMember(roomMember) { export async function isRoomAliasAvailable(alias) { try { - const result = await initMatrix.matrixClient.resolveRoomAlias(alias); + const result = await initMatrix.matrixClient.getRoomIdForAlias(alias); if (result.room_id) return false; return false; } catch (e) { From 20db27fa7ef1cbb9682780ecb4dbdf96cc4540ec Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Sun, 21 Jan 2024 23:50:56 +1100 Subject: [PATCH 1105/1531] feat: URL navigation in auth (#1603) * bump to react 18 and install react-router-dom * Upgrade to react 18 root * update vite * add cs api's * convert state/auth to ts * add client config context * add auto discovery context * add spec version context * add auth flow context * add background dot pattern css * add promise utils * init url based routing * update auth route server path as effect * add auth server hook * always use server from discovery info in context * login - WIP * upgrade jotai to v2 * add atom with localStorage util * add multi account sessions atom * add default IGNORE res to auto discovery * add error type in async callback hook * handle password login error * fix async callback hook * allow password login * Show custom server not allowed error in mxId login * add sso login component * add token login * fix hardcoded m.login.password in login func * update server input on url change * Improve sso login labels * update folds * fix async callback batching state update in safari * wrap async callback set state in queueMicrotask * wip * wip - register * arrange auth file structure * add error codes * extract filed error component form password login * add register util function * handle register flow - WIP * update unsupported auth flow method reasons * improve password input styles * Improve UIA flow next stage calculation complete stages can have any order so we will look for first stage which is not in completed * process register UIA flow stages * Extract register UIA stages component * improve register error messages * add focus trap & step count in UIA stages * add reset password path and path utils * add path with origin hook * fix sso redirect url * rename register token query param to token * restyle auth screen header * add reset password component - WIP * add reset password form * add netlify rewrites * fix netlify file indentation * test netlify redirect * fix vite to include netlify toml * add more netlify redirects * add splat to public and assets path * fix vite base name * add option to use hash router in config and remove appVersion * add splash screen component * add client config loading and error screen * fix server picker bug * fix reset password email input type * make auth page small screen responsive * fix typo in reset password screen --- _redirects | 3 - build.config.ts | 3 + config.json | 7 +- index.html | 2 +- netlify.toml | 34 + package-lock.json | 1018 ++++++++++------- package.json | 22 +- src/app/components/AuthFlowsLoader.tsx | 64 ++ src/app/components/ClientConfigLoader.tsx | 38 + src/app/components/ConfirmPasswordMatch.tsx | 35 + src/app/components/SpecVersionsLoader.tsx | 32 + .../components/SupportedUIAFlowsLoader.tsx | 17 + src/app/components/UIAFlowOverlay.tsx | 72 ++ .../password-input/PasswordInput.tsx | 45 + .../splash-screen/SplashScreen.css.ts | 12 + .../components/splash-screen/SplashScreen.tsx | 29 + src/app/components/splash-screen/index.ts | 1 + src/app/components/uia-stages/DummyStage.tsx | 65 ++ src/app/components/uia-stages/EmailStage.tsx | 172 +++ .../components/uia-stages/ReCaptchaStage.tsx | 64 ++ .../uia-stages/RegistrationTokenStage.tsx | 117 ++ src/app/components/uia-stages/TermsStage.tsx | 69 ++ src/app/components/uia-stages/index.ts | 6 + src/app/components/uia-stages/types.ts | 8 + src/app/cs-api.ts | 115 ++ src/app/cs-errorcode.ts | 37 + src/app/hooks/types.ts | 12 + src/app/hooks/useAsyncCallback.ts | 48 +- src/app/hooks/useAuthFlows.ts | 59 + src/app/hooks/useAuthServer.ts | 14 + src/app/hooks/useAutoDiscoveryInfo.ts | 15 + src/app/hooks/useClientConfig.ts | 33 + src/app/hooks/useCrossSigningStatus.js | 2 +- src/app/hooks/useParsedLoginFlows.ts | 38 + src/app/hooks/usePasswordEmail.ts | 32 + src/app/hooks/usePathWithOrigin.ts | 26 + src/app/hooks/useRegisterEmail.ts | 32 + src/app/hooks/useSpecVersions.ts | 12 + src/app/hooks/useUIAFlows.ts | 96 ++ .../molecules/room-aliases/RoomAliases.jsx | 4 +- .../RoomHistoryVisibility.jsx | 4 +- .../room-notification/RoomNotification.jsx | 4 +- src/app/molecules/room-search/RoomSearch.jsx | 4 +- .../room-visibility/RoomVisibility.jsx | 4 +- .../emoji-verification/EmojiVerification.jsx | 2 +- .../organisms/room/message/UrlPreviewCard.tsx | 5 +- .../organisms/space-manage/SpaceManage.jsx | 4 +- src/app/pages/App.jsx | 17 - src/app/pages/App.tsx | 82 ++ src/app/pages/ConfigConfig.tsx | 53 + src/app/pages/auth/AuthFooter.tsx | 28 + src/app/pages/auth/AuthLayout.tsx | 215 ++++ src/app/pages/auth/FiledError.tsx | 13 + src/app/pages/auth/OrDivider.tsx | 12 + src/app/pages/auth/SSOLogin.tsx | 68 ++ src/app/pages/auth/ServerPicker.tsx | 140 +++ src/app/pages/auth/index.ts | 4 + src/app/pages/auth/login/Login.tsx | 73 ++ .../pages/auth/login/PasswordLoginForm.tsx | 272 +++++ src/app/pages/auth/login/TokenLogin.tsx | 94 ++ src/app/pages/auth/login/index.ts | 1 + src/app/pages/auth/login/loginUtil.ts | 118 ++ .../auth/register/PasswordRegisterForm.tsx | 420 +++++++ src/app/pages/auth/register/Register.tsx | 95 ++ src/app/pages/auth/register/index.ts | 1 + src/app/pages/auth/register/registerUtil.ts | 125 ++ .../auth/reset-password/PasswordResetForm.tsx | 274 +++++ .../auth/reset-password/ResetPassword.tsx | 36 + src/app/pages/auth/reset-password/index.ts | 1 + .../auth/reset-password/resetPasswordUtil.ts | 23 + src/app/pages/auth/styles.css.ts | 53 + src/app/pages/pathUtils.ts | 28 + src/app/pages/paths.ts | 17 + src/app/state/hooks/inviteList.ts | 37 +- src/app/state/hooks/roomList.ts | 34 +- src/app/state/hooks/settings.ts | 20 +- src/app/state/inviteList.ts | 4 +- src/app/state/list.ts | 2 +- src/app/state/mDirectList.ts | 9 +- src/app/state/mutedRoomList.ts | 9 +- src/app/state/roomList.ts | 9 +- src/app/state/roomToParents.ts | 6 +- src/app/state/roomToUnread.ts | 6 +- src/app/state/sessions.ts | 129 +++ src/app/state/settings.ts | 2 +- src/app/state/tabToRoom.ts | 2 +- src/app/state/typingMembers.ts | 6 +- src/app/state/upload.ts | 2 +- src/app/state/utils.ts | 2 +- src/app/state/utils/atomWithLocalStorage.ts | 51 + src/app/styles/Patterns.css.ts | 9 + src/app/utils/common.ts | 18 + src/app/utils/matrix-uia.ts | 84 ++ src/app/utils/regex.ts | 3 + src/client/action/auth.js | 2 +- src/client/initMatrix.js | 3 +- src/client/state/auth.js | 19 - src/client/state/auth.ts | 12 + src/ext.d.ts | 7 + src/{index.jsx => index.tsx} | 17 +- src/types/utils.ts | 3 + tsconfig.json | 1 + vite.config.js | 7 +- 103 files changed, 4772 insertions(+), 543 deletions(-) delete mode 100644 _redirects create mode 100644 build.config.ts create mode 100644 netlify.toml create mode 100644 src/app/components/AuthFlowsLoader.tsx create mode 100644 src/app/components/ClientConfigLoader.tsx create mode 100644 src/app/components/ConfirmPasswordMatch.tsx create mode 100644 src/app/components/SpecVersionsLoader.tsx create mode 100644 src/app/components/SupportedUIAFlowsLoader.tsx create mode 100644 src/app/components/UIAFlowOverlay.tsx create mode 100644 src/app/components/password-input/PasswordInput.tsx create mode 100644 src/app/components/splash-screen/SplashScreen.css.ts create mode 100644 src/app/components/splash-screen/SplashScreen.tsx create mode 100644 src/app/components/splash-screen/index.ts create mode 100644 src/app/components/uia-stages/DummyStage.tsx create mode 100644 src/app/components/uia-stages/EmailStage.tsx create mode 100644 src/app/components/uia-stages/ReCaptchaStage.tsx create mode 100644 src/app/components/uia-stages/RegistrationTokenStage.tsx create mode 100644 src/app/components/uia-stages/TermsStage.tsx create mode 100644 src/app/components/uia-stages/index.ts create mode 100644 src/app/components/uia-stages/types.ts create mode 100644 src/app/cs-api.ts create mode 100644 src/app/cs-errorcode.ts create mode 100644 src/app/hooks/types.ts create mode 100644 src/app/hooks/useAuthFlows.ts create mode 100644 src/app/hooks/useAuthServer.ts create mode 100644 src/app/hooks/useAutoDiscoveryInfo.ts create mode 100644 src/app/hooks/useClientConfig.ts create mode 100644 src/app/hooks/useParsedLoginFlows.ts create mode 100644 src/app/hooks/usePasswordEmail.ts create mode 100644 src/app/hooks/usePathWithOrigin.ts create mode 100644 src/app/hooks/useRegisterEmail.ts create mode 100644 src/app/hooks/useSpecVersions.ts create mode 100644 src/app/hooks/useUIAFlows.ts delete mode 100644 src/app/pages/App.jsx create mode 100644 src/app/pages/App.tsx create mode 100644 src/app/pages/ConfigConfig.tsx create mode 100644 src/app/pages/auth/AuthFooter.tsx create mode 100644 src/app/pages/auth/AuthLayout.tsx create mode 100644 src/app/pages/auth/FiledError.tsx create mode 100644 src/app/pages/auth/OrDivider.tsx create mode 100644 src/app/pages/auth/SSOLogin.tsx create mode 100644 src/app/pages/auth/ServerPicker.tsx create mode 100644 src/app/pages/auth/index.ts create mode 100644 src/app/pages/auth/login/Login.tsx create mode 100644 src/app/pages/auth/login/PasswordLoginForm.tsx create mode 100644 src/app/pages/auth/login/TokenLogin.tsx create mode 100644 src/app/pages/auth/login/index.ts create mode 100644 src/app/pages/auth/login/loginUtil.ts create mode 100644 src/app/pages/auth/register/PasswordRegisterForm.tsx create mode 100644 src/app/pages/auth/register/Register.tsx create mode 100644 src/app/pages/auth/register/index.ts create mode 100644 src/app/pages/auth/register/registerUtil.ts create mode 100644 src/app/pages/auth/reset-password/PasswordResetForm.tsx create mode 100644 src/app/pages/auth/reset-password/ResetPassword.tsx create mode 100644 src/app/pages/auth/reset-password/index.ts create mode 100644 src/app/pages/auth/reset-password/resetPasswordUtil.ts create mode 100644 src/app/pages/auth/styles.css.ts create mode 100644 src/app/pages/pathUtils.ts create mode 100644 src/app/pages/paths.ts create mode 100644 src/app/state/sessions.ts create mode 100644 src/app/state/utils/atomWithLocalStorage.ts create mode 100644 src/app/styles/Patterns.css.ts create mode 100644 src/app/utils/matrix-uia.ts delete mode 100644 src/client/state/auth.js create mode 100644 src/client/state/auth.ts rename src/{index.jsx => index.tsx} (57%) create mode 100644 src/types/utils.ts diff --git a/_redirects b/_redirects deleted file mode 100644 index 270cd3386..000000000 --- a/_redirects +++ /dev/null @@ -1,3 +0,0 @@ -# Redirects from what the browser requests to what we serve -/login / -/register / diff --git a/build.config.ts b/build.config.ts new file mode 100644 index 000000000..ec8a41d08 --- /dev/null +++ b/build.config.ts @@ -0,0 +1,3 @@ +export default { + base: '/', +}; diff --git a/config.json b/config.json index 0ff493a17..484c7cd78 100644 --- a/config.json +++ b/config.json @@ -8,5 +8,10 @@ "mozilla.org", "xmr.se" ], - "allowCustomHomeservers": true + "allowCustomHomeservers": true, + + "hashRouter": { + "enabled": false, + "basename": "/" + } } diff --git a/index.html b/index.html index 6bc955c14..48f8e69eb 100644 --- a/index.html +++ b/index.html @@ -96,6 +96,6 @@ - + diff --git a/netlify.toml b/netlify.toml new file mode 100644 index 000000000..e7d948e62 --- /dev/null +++ b/netlify.toml @@ -0,0 +1,34 @@ +[[redirects]] + from = "/config.json" + to = "/config.json" + status = 200 + +[[redirects]] + from = "/manifest.json" + to = "/manifest.json" + status = 200 + +[[redirects]] + from = "/olm.wasm" + to = "/olm.wasm" + status = 200 + +[[redirects]] + from = "/pdf.worker.min.js" + to = "/pdf.worker.min.js" + status = 200 + +[[redirects]] + from = "/public/*" + to = "/public/:splat" + status = 200 + +[[redirects]] + from = "/assets/*" + to = "/assets/:splat" + status = 200 + +[[redirects]] + from = "/*" + to = "/index.html" + status = 200 \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 6c944cea5..fba4072e6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -29,13 +29,13 @@ "file-saver": "2.0.5", "flux": "4.0.3", "focus-trap-react": "10.0.2", - "folds": "1.5.0", + "folds": "1.5.1", "formik": "2.2.9", "html-dom-parser": "4.0.0", "html-react-parser": "4.2.0", "immer": "9.0.16", "is-hotkey": "0.2.0", - "jotai": "1.12.0", + "jotai": "2.6.0", "katex": "0.16.4", "linkify-html": "4.0.2", "linkify-react": "4.1.1", @@ -45,17 +45,18 @@ "pdfjs-dist": "3.10.111", "prismjs": "1.29.0", "prop-types": "15.8.1", - "react": "17.0.2", + "react": "18.2.0", "react-aria": "3.29.1", "react-autosize-textarea": "7.1.0", "react-blurhash": "0.2.0", - "react-dnd": "15.1.2", - "react-dnd-html5-backend": "15.1.3", - "react-dom": "17.0.2", + "react-dnd": "16.0.1", + "react-dnd-html5-backend": "16.0.1", + "react-dom": "18.2.0", "react-error-boundary": "4.0.10", "react-google-recaptcha": "2.1.0", "react-modal": "3.16.1", "react-range": "1.8.14", + "react-router-dom": "6.20.0", "sanitize-html": "2.8.0", "slate": "0.94.1", "slate-history": "0.93.0", @@ -71,13 +72,14 @@ "@types/file-saver": "2.0.5", "@types/node": "18.11.18", "@types/prismjs": "1.26.0", - "@types/react": "18.0.26", - "@types/react-dom": "18.0.9", + "@types/react": "18.2.39", + "@types/react-dom": "18.2.17", + "@types/react-google-recaptcha": "2.1.8", "@types/sanitize-html": "2.9.0", "@types/ua-parser-js": "0.7.36", "@typescript-eslint/eslint-plugin": "5.46.1", "@typescript-eslint/parser": "5.46.1", - "@vitejs/plugin-react": "3.0.0", + "@vitejs/plugin-react": "4.2.0", "buffer": "6.0.3", "eslint": "8.29.0", "eslint-config-airbnb": "19.0.4", @@ -90,7 +92,7 @@ "prettier": "2.8.1", "sass": "1.56.2", "typescript": "4.9.4", - "vite": "4.3.9", + "vite": "5.0.8", "vite-plugin-static-copy": "0.13.0" }, "engines": { @@ -110,44 +112,45 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", - "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.4.tgz", + "integrity": "sha512-r1IONyb6Ia+jYR2vvIDhdWdlTGhqbBoFqLTQidzZ4kepUFH15ejXvFHxCVbtl7BOXIudsIubf4E81xeA3h3IXA==", "dependencies": { - "@babel/highlight": "^7.18.6" + "@babel/highlight": "^7.23.4", + "chalk": "^2.4.2" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/compat-data": { - "version": "7.20.10", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.10.tgz", - "integrity": "sha512-sEnuDPpOJR/fcafHMjpcpGN5M2jbUGUHwmuWKM/YdPzeEDJg8bgmbcWQFUfE32MQjti1koACvoPVsDe8Uq+idg==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.3.tgz", + "integrity": "sha512-BmR4bWbDIoFJmJ9z2cZ8Gmm2MXgEDgjdWgpKmKWUt54UGFJdlj31ECtbaDvCG/qVdG3AQ1SfpZEs01lUFbzLOQ==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.20.12", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.12.tgz", - "integrity": "sha512-XsMfHovsUYHFMdrIHkZphTN/2Hzzi78R08NuHfDBehym2VsPDL6Zn/JAD/JQdnRvbSsbQc4mVaU1m6JgtTEElg==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.3.tgz", + "integrity": "sha512-Jg+msLuNuCJDyBvFv5+OKOUjWMZgd85bKjbICd3zWrKAo+bJ49HJufi7CQE0q0uR8NGyO6xkCACScNqyjHSZew==", "dependencies": { - "@ampproject/remapping": "^2.1.0", - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.20.7", - "@babel/helper-compilation-targets": "^7.20.7", - "@babel/helper-module-transforms": "^7.20.11", - "@babel/helpers": "^7.20.7", - "@babel/parser": "^7.20.7", - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.20.12", - "@babel/types": "^7.20.7", - "convert-source-map": "^1.7.0", + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.22.13", + "@babel/generator": "^7.23.3", + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helpers": "^7.23.2", + "@babel/parser": "^7.23.3", + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.3", + "@babel/types": "^7.23.3", + "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", - "json5": "^2.2.2", - "semver": "^6.3.0" + "json5": "^2.2.3", + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" @@ -158,12 +161,13 @@ } }, "node_modules/@babel/generator": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.7.tgz", - "integrity": "sha512-7wqMOJq8doJMZmP4ApXTzLxSr7+oO2jroJURrVEp6XShrQUObV8Tq/D0NCcoYg2uHqUrjzO0zwBjoYzelxK+sw==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.4.tgz", + "integrity": "sha512-esuS49Cga3HcThFNebGhlgsrVLkvhqvYDTzgjfFFlHJcIfLe5jFmRRfCQ1KuBfc4Jrtn3ndLgKWAKjBE+IraYQ==", "dependencies": { - "@babel/types": "^7.20.7", + "@babel/types": "^7.23.4", "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" }, "engines": { @@ -171,9 +175,9 @@ } }, "node_modules/@babel/generator/node_modules/@jridgewell/gen-mapping": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", - "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", "dependencies": { "@jridgewell/set-array": "^1.0.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -184,21 +188,18 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz", - "integrity": "sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz", + "integrity": "sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==", "dependencies": { - "@babel/compat-data": "^7.20.5", - "@babel/helper-validator-option": "^7.18.6", - "browserslist": "^4.21.3", + "@babel/compat-data": "^7.22.9", + "@babel/helper-validator-option": "^7.22.15", + "browserslist": "^4.21.9", "lru-cache": "^5.1.1", - "semver": "^6.3.0" + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" } }, "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": { @@ -215,139 +216,139 @@ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" }, "node_modules/@babel/helper-environment-visitor": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", - "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-function-name": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", - "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", "dependencies": { - "@babel/template": "^7.18.10", - "@babel/types": "^7.19.0" + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-hoist-variables": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", - "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", "dependencies": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", - "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", + "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", "dependencies": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.22.15" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.20.11", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.11.tgz", - "integrity": "sha512-uRy78kN4psmji1s2QtbtcCSaj/LILFDp0f/ymhpQH5QY3nljUZCaNWz9X1dEj/8MBdBEFECs7yRhKn8i7NjZgg==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", + "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", "dependencies": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-simple-access": "^7.20.2", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/helper-validator-identifier": "^7.19.1", - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.20.10", - "@babel/types": "^7.20.7" + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-simple-access": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/helper-validator-identifier": "^7.22.20" }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz", - "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", + "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-simple-access": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", - "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", + "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", "dependencies": { - "@babel/types": "^7.20.2" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-split-export-declaration": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", - "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", "dependencies": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-string-parser": { - "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", - "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", + "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", - "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", - "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz", + "integrity": "sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.20.13", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.13.tgz", - "integrity": "sha512-nzJ0DWCL3gB5RCXbUO3KIMMsBY2Eqbx8mBpKGE/02PgyRQFcPQLbkQ1vyy596mZLaP+dAfD+R4ckASzNVmW3jg==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.4.tgz", + "integrity": "sha512-HfcMizYz10cr3h29VqyfGL6ZWIjTwWfvYBMsBVGwpcbhNGe3wQ1ZXZRPzZoAHhd9OqHadHqjQ89iVKINXnbzuw==", "dependencies": { - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.20.13", - "@babel/types": "^7.20.7" + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.4", + "@babel/types": "^7.23.4" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", - "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", + "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", "dependencies": { - "@babel/helper-validator-identifier": "^7.18.6", - "chalk": "^2.0.0", + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", "js-tokens": "^4.0.0" }, "engines": { @@ -355,9 +356,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.20.13", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.13.tgz", - "integrity": "sha512-gFDLKMfpiXCsjt4za2JA9oTMn70CeseCehb11kRZgvd7+F67Hih3OHOK24cRrWECJ/ljfPGac6ygXAs/C8kIvw==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.4.tgz", + "integrity": "sha512-vf3Xna6UEprW+7t6EtOmFpHNAuxw3xqPZghy+brsnusscJRW5BMUzzHZc5ICjULee81WeUV2jjakG09MDglJXQ==", "bin": { "parser": "bin/babel-parser.js" }, @@ -380,12 +381,12 @@ } }, "node_modules/@babel/plugin-transform-react-jsx-self": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.18.6.tgz", - "integrity": "sha512-A0LQGx4+4Jv7u/tWzoJF7alZwnBDQd6cGLh9P+Ttk4dpiL+J5p7NSNv/9tlEFFJDq3kjxOavWmbm6t0Gk+A3Ig==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.23.3.tgz", + "integrity": "sha512-qXRvbeKDSfwnlJnanVRp0SfuWE5DQhwQr5xtLBzp56Wabyo+4CMosF6Kfp+eOD/4FYpql64XVJ2W0pVLlJZxOQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -395,12 +396,12 @@ } }, "node_modules/@babel/plugin-transform-react-jsx-source": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.19.6.tgz", - "integrity": "sha512-RpAi004QyMNisst/pvSanoRdJ4q+jMCWyk9zdw/CyLB9j8RXEahodR6l2GyttDRyEVWZtbN+TpLiHJ3t34LbsQ==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.23.3.tgz", + "integrity": "sha512-91RS0MDnAWDNvGC6Wio5XYkyWI39FMFO+JK9+4AlgaTH+yWwVTsw7/sn6LK0lH7c5F+TFkpv/3LfCJ1Ydwof/g==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.19.0" + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -445,31 +446,31 @@ "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" }, "node_modules/@babel/template": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz", - "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", "dependencies": { - "@babel/code-frame": "^7.18.6", - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7" + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.20.13", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.13.tgz", - "integrity": "sha512-kMJXfF0T6DIS9E8cgdLCSAL+cuCK+YEZHWiLK0SXpTo8YRj5lpJu3CDNKiIBCne4m9hhTIqUg6SYTAI39tAiVQ==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.4.tgz", + "integrity": "sha512-IYM8wSUwunWTB6tFC2dkKZhxbIjHoWemdK+3f8/wq8aKhbUscxD5MX72ubd90fxvFknaLPeGw5ycU84V1obHJg==", "dependencies": { - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.20.7", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.20.13", - "@babel/types": "^7.20.7", + "@babel/code-frame": "^7.23.4", + "@babel/generator": "^7.23.4", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.23.4", + "@babel/types": "^7.23.4", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -478,12 +479,12 @@ } }, "node_modules/@babel/types": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.7.tgz", - "integrity": "sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.4.tgz", + "integrity": "sha512-7uIFwVYpoplT5jp/kVv6EF93VaJ8H+Yn5IczYiaAi98ajzjfoZfslet/e0sLh+wVBjb2qqIut1b0S26VSafsSQ==", "dependencies": { - "@babel/helper-string-parser": "^7.19.4", - "@babel/helper-validator-identifier": "^7.19.1", + "@babel/helper-string-parser": "^7.23.4", + "@babel/helper-validator-identifier": "^7.22.20", "to-fast-properties": "^2.0.0" }, "engines": { @@ -1893,19 +1894,19 @@ } }, "node_modules/@react-dnd/asap": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@react-dnd/asap/-/asap-4.0.1.tgz", - "integrity": "sha512-kLy0PJDDwvwwTXxqTFNAAllPHD73AycE9ypWeln/IguoGBEbvFcPDbCV03G52bEcC5E+YgupBE0VzHGdC8SIXg==" + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@react-dnd/asap/-/asap-5.0.2.tgz", + "integrity": "sha512-WLyfoHvxhs0V9U+GTsGilGgf2QsPl6ZZ44fnv0/b8T3nQyvzxidxsg/ZltbWssbsRDlYW8UKSQMTGotuTotZ6A==" }, "node_modules/@react-dnd/invariant": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@react-dnd/invariant/-/invariant-3.0.1.tgz", - "integrity": "sha512-blqduwV86oiKw2Gr44wbe3pj3Z/OsXirc7ybCv9F/pLAR+Aih8F3rjeJzK0ANgtYKv5lCpkGVoZAeKitKDaD/g==" + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@react-dnd/invariant/-/invariant-4.0.2.tgz", + "integrity": "sha512-xKCTqAK/FFauOM9Ta2pswIyT3D8AQlfrYdOi/toTPEhqCuAs1v5tcJ3Y08Izh1cJ5Jchwy9SeAXmMg6zrKs2iw==" }, "node_modules/@react-dnd/shallowequal": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@react-dnd/shallowequal/-/shallowequal-3.0.1.tgz", - "integrity": "sha512-XjDVbs3ZU16CO1h5Q3Ew2RPJqmZBDE/EVf1LYp6ePEffs3V/MX9ZbL5bJr8qiK5SbGmUMuDoaFgyKacYz8prRA==" + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@react-dnd/shallowequal/-/shallowequal-4.0.2.tgz", + "integrity": "sha512-/RVXdLvJxLg4QKvMoM5WlwNR9ViO9z8B/qPcc+C0Sa/teJY7QG7kJ441DwzOjMYEY7GmU4dj5EcGHIkKZiQZCA==" }, "node_modules/@react-stately/calendar": { "version": "3.4.1", @@ -2583,6 +2584,14 @@ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" } }, + "node_modules/@remix-run/router": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.13.0.tgz", + "integrity": "sha512-5dMOnVnefRsl4uRnAdoWjtVTdh8e6aZqgM4puy9nmEADH72ck+uXwzpJLEKE9Q6F8ZljNewLgmTfkxUrBdv4WA==", + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@rollup/plugin-inject": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/@rollup/plugin-inject/-/plugin-inject-5.0.3.tgz", @@ -2656,6 +2665,175 @@ "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", "dev": true }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.8.0.tgz", + "integrity": "sha512-zdTObFRoNENrdPpnTNnhOljYIcOX7aI7+7wyrSpPFFIOf/nRdedE6IYsjaBE7tjukphh1tMTojgJ7p3lKY8x6Q==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.8.0.tgz", + "integrity": "sha512-aiItwP48BiGpMFS9Znjo/xCNQVwTQVcRKkFKsO81m8exrGjHkCBDvm9PHay2kpa8RPnZzzKcD1iQ9KaLY4fPQQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.8.0.tgz", + "integrity": "sha512-zhNIS+L4ZYkYQUjIQUR6Zl0RXhbbA0huvNIWjmPc2SL0cB1h5Djkcy+RZ3/Bwszfb6vgwUvcVJYD6e6Zkpsi8g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.8.0.tgz", + "integrity": "sha512-A/FAHFRNQYrELrb/JHncRWzTTXB2ticiRFztP4ggIUAfa9Up1qfW8aG2w/mN9jNiZ+HB0t0u0jpJgFXG6BfRTA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.8.0.tgz", + "integrity": "sha512-JsidBnh3p2IJJA4/2xOF2puAYqbaczB3elZDT0qHxn362EIoIkq7hrR43Xa8RisgI6/WPfvb2umbGsuvf7E37A==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.8.0.tgz", + "integrity": "sha512-hBNCnqw3EVCkaPB0Oqd24bv8SklETptQWcJz06kb9OtiShn9jK1VuTgi7o4zPSt6rNGWQOTDEAccbk0OqJmS+g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.8.0.tgz", + "integrity": "sha512-Fw9ChYfJPdltvi9ALJ9wzdCdxGw4wtq4t1qY028b2O7GwB5qLNSGtqMsAel1lfWTZvf4b6/+4HKp0GlSYg0ahA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.8.0.tgz", + "integrity": "sha512-BH5xIh7tOzS9yBi8dFrCTG8Z6iNIGWGltd3IpTSKp6+pNWWO6qy8eKoRxOtwFbMrid5NZaidLYN6rHh9aB8bEw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.8.0.tgz", + "integrity": "sha512-PmvAj8k6EuWiyLbkNpd6BLv5XeYFpqWuRvRNRl80xVfpGXK/z6KYXmAgbI4ogz7uFiJxCnYcqyvZVD0dgFog7Q==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.8.0.tgz", + "integrity": "sha512-mdxnlW2QUzXwY+95TuxZ+CurrhgrPAMveDWI97EQlA9bfhR8tw3Pt7SUlc/eSlCNxlWktpmT//EAA8UfCHOyXg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.8.0.tgz", + "integrity": "sha512-ge7saUz38aesM4MA7Cad8CHo0Fyd1+qTaqoIo+Jtk+ipBi4ATSrHWov9/S4u5pbEQmLjgUjB7BJt+MiKG2kzmA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.8.0.tgz", + "integrity": "sha512-p9E3PZlzurhlsN5h9g7zIP1DnqKXJe8ZUkFwAazqSvHuWfihlIISPxG9hCHCoA+dOOspL/c7ty1eeEVFTE0UTw==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.8.0.tgz", + "integrity": "sha512-kb4/auKXkYKqlUYTE8s40FcJIj5soOyRLHKd4ugR0dCq0G2EfcF54eYcfQiGkHzjidZ40daB4ulsFdtqNKZtBg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/@swc/helpers": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.3.tgz", @@ -2705,6 +2883,47 @@ "react-dom": ">=16.8" } }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.6.7", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.7.tgz", + "integrity": "sha512-6Sfsq+EaaLrw4RmdFWE9Onp63TOUue71AWb4Gpa6JxzgTYtimbM086WnYTy2U67AofR++QKCo08ZP6pwx8YFHQ==", + "dev": true, + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.20.4", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.4.tgz", + "integrity": "sha512-mSM/iKUk5fDDrEV/e83qY+Cr3I1+Q3qqTuEn++HAWYjEa1+NxZr6CNrcJGf2ZTnq4HoFGC3zaTPZTobCzCFukA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.20.7" + } + }, "node_modules/@types/estree": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.0.tgz", @@ -2762,9 +2981,9 @@ "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==" }, "node_modules/@types/react": { - "version": "18.0.26", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.26.tgz", - "integrity": "sha512-hCR3PJQsAIXyxhTNSiDFY//LhnMZWpNNr5etoCqx/iUfGc5gXWtQR2Phl908jVR6uPXacojQWTg4qRpkxTuGug==", + "version": "18.2.39", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.39.tgz", + "integrity": "sha512-Oiw+ppED6IremMInLV4HXGbfbG6GyziY3kqAwJYOR0PNbkYDmLWQA3a95EhdSmamsvbkJN96ZNN+YD+fGjzSBA==", "dependencies": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -2772,9 +2991,18 @@ } }, "node_modules/@types/react-dom": { - "version": "18.0.9", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.0.9.tgz", - "integrity": "sha512-qnVvHxASt/H7i+XG1U1xMiY5t+IHcPGUK7TDMDzom08xa7e86eCeKOiLZezwCKVxJn6NEiiy2ekgX8aQssjIKg==", + "version": "18.2.17", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.17.tgz", + "integrity": "sha512-rvrT/M7Df5eykWFxn6MYt5Pem/Dbyc1N8Y0S9Mrkw2WFCRiqUgw9P7ul2NpwsXCSM1DVdENzdG9J5SreqfAIWg==", + "dev": true, + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/react-google-recaptcha": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/@types/react-google-recaptcha/-/react-google-recaptcha-2.1.8.tgz", + "integrity": "sha512-nYI3ZDoteZ0g4FYusyKWqz7AZqRdu70R3wDkosCcN0peb2WLn57i0Alm4IPiCRIx59yTUVPTiOELZH08gV1wXA==", "dev": true, "dependencies": { "@types/react": "*" @@ -3208,22 +3436,22 @@ } }, "node_modules/@vitejs/plugin-react": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-3.0.0.tgz", - "integrity": "sha512-1mvyPc0xYW5G8CHQvJIJXLoMjl5Ct3q2g5Y2s6Ccfgwm45y48LBvsla7az+GkkAtYikWQ4Lxqcsq5RHLcZgtNQ==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.2.0.tgz", + "integrity": "sha512-+MHTH/e6H12kRp5HUkzOGqPMksezRMmW+TNzlh/QXfI8rRf6l2Z2yH/v12no1UvTwhZgEDMuQ7g7rrfMseU6FQ==", "dev": true, "dependencies": { - "@babel/core": "^7.20.5", - "@babel/plugin-transform-react-jsx-self": "^7.18.6", - "@babel/plugin-transform-react-jsx-source": "^7.19.6", - "magic-string": "^0.27.0", + "@babel/core": "^7.23.3", + "@babel/plugin-transform-react-jsx-self": "^7.23.3", + "@babel/plugin-transform-react-jsx-source": "^7.23.3", + "@types/babel__core": "^7.20.4", "react-refresh": "^0.14.0" }, "engines": { "node": "^14.18.0 || >=16.0.0" }, "peerDependencies": { - "vite": "^4.0.0" + "vite": "^4.2.0 || ^5.0.0" } }, "node_modules/abbrev": { @@ -3550,9 +3778,9 @@ "integrity": "sha512-L7siI766UCH6+arP9yT5wpA5AFxnmGbKiGSsxEVACl1tE0pvDJeQvMmbY2UmJiuffrr0ZJ2+U6Om46wQBqh1Lw==" }, "node_modules/browserslist": { - "version": "4.21.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", - "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", + "version": "4.22.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.1.tgz", + "integrity": "sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==", "funding": [ { "type": "opencollective", @@ -3561,13 +3789,17 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ], "dependencies": { - "caniuse-lite": "^1.0.30001400", - "electron-to-chromium": "^1.4.251", - "node-releases": "^2.0.6", - "update-browserslist-db": "^1.0.9" + "caniuse-lite": "^1.0.30001541", + "electron-to-chromium": "^1.4.535", + "node-releases": "^2.0.13", + "update-browserslist-db": "^1.0.13" }, "bin": { "browserslist": "cli.js" @@ -3631,9 +3863,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001446", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001446.tgz", - "integrity": "sha512-fEoga4PrImGcwUUGEol/PoFCSBnSkA9drgdkxXkJLsUBOnJ8rs3zDv6ApqYXGQFOyMPsjh79naWhF4DAxbF8rw==", + "version": "1.0.30001565", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001565.tgz", + "integrity": "sha512-xrE//a3O7TP0vaJ8ikzkD2c2NgcVUvsEe2IvFTntV4Yd1Z9FVzh+gW+enX96L0psrbaFMcVcH2l90xNuGDWc8w==", "funding": [ { "type": "opencollective", @@ -3642,6 +3874,10 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ] }, @@ -3806,9 +4042,9 @@ } }, "node_modules/convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==" }, "node_modules/core-js-pure": { "version": "3.26.1", @@ -3997,13 +4233,13 @@ } }, "node_modules/dnd-core": { - "version": "15.1.2", - "resolved": "https://registry.npmjs.org/dnd-core/-/dnd-core-15.1.2.tgz", - "integrity": "sha512-EOec1LyJUuGRFg0LDa55rSRAUe97uNVKVkUo8iyvzQlcECYTuPblVQfRWXWj1OyPseFIeebWpNmKFy0h6BcF1A==", + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/dnd-core/-/dnd-core-16.0.1.tgz", + "integrity": "sha512-HK294sl7tbw6F6IeuK16YSBUoorvHpY8RHO+9yFfaJyCDVb6n7PRcezrOEOa2SBCqiYpemh5Jx20ZcjKdFAVng==", "dependencies": { - "@react-dnd/asap": "4.0.1", - "@react-dnd/invariant": "3.0.1", - "redux": "^4.1.2" + "@react-dnd/asap": "^5.0.1", + "@react-dnd/invariant": "^4.0.1", + "redux": "^4.2.0" } }, "node_modules/doctrine": { @@ -4070,9 +4306,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.284", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz", - "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==" + "version": "1.4.596", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.596.tgz", + "integrity": "sha512-zW3zbZ40Icb2BCWjm47nxwcFGYlIgdXkAx85XDO7cyky9J4QQfq8t0W19/TLZqq3JPQXtlv8BPIGmfa9Jb4scg==" }, "node_modules/emoji-regex": { "version": "9.2.2", @@ -4959,9 +5195,9 @@ } }, "node_modules/folds": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/folds/-/folds-1.5.0.tgz", - "integrity": "sha512-1QNHzD57OxFZT5SOe0nWcrKQvWmfMRv1f5sTF8xhGtwx9rajjv36T9SwCcj9Fh58PbERqOdBiwvpdhu+BQTVjg==", + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/folds/-/folds-1.5.1.tgz", + "integrity": "sha512-2QxyA+FRKjPKXDTMDoD7NmOUiReWrKYO0Msg44QqlzTkTrRVEzJgyPIfC/Ia4/u0ByQpk6dbq8UQxomKmneJ/g==", "peerDependencies": { "@vanilla-extract/css": "^1.9.2", "@vanilla-extract/recipes": "^0.3.0", @@ -5045,9 +5281,9 @@ "devOptional": true }, "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, "hasInstallScript": true, "optional": true, @@ -5762,54 +5998,21 @@ "integrity": "sha512-JVAfqNPTvNq3sB/VHQJAFxN/sPgKnsKrCwyRt15zwNCdrMMJDdcEOdubuy+DuJYYdm0ox1J4uzEuYKkN+9yhVg==" }, "node_modules/jotai": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/jotai/-/jotai-1.12.0.tgz", - "integrity": "sha512-IhyBmjxU1sE2Ni/MUK7gQAb8QvCM6yd1/K5jtQzgQBmmjCjgfXZkkk1rYlQAIRp2KoQk0Y+yzhm1f5cZ7kegnw==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/jotai/-/jotai-2.6.0.tgz", + "integrity": "sha512-Vt6hsc04Km4j03l+Ax+Sc+FVft5cRJhqgxt6GTz6GM2eM3DyX3CdBdzcG0z2FrlZToL1/0OAkqDghIyARWnSuQ==", "engines": { "node": ">=12.20.0" }, "peerDependencies": { - "@babel/core": "*", - "@babel/template": "*", - "jotai-immer": "*", - "jotai-optics": "*", - "jotai-redux": "*", - "jotai-tanstack-query": "*", - "jotai-urql": "*", - "jotai-valtio": "*", - "jotai-xstate": "*", - "jotai-zustand": "*", - "react": ">=16.8" + "@types/react": ">=17.0.0", + "react": ">=17.0.0" }, "peerDependenciesMeta": { - "@babel/core": { + "@types/react": { "optional": true }, - "@babel/template": { - "optional": true - }, - "jotai-immer": { - "optional": true - }, - "jotai-optics": { - "optional": true - }, - "jotai-redux": { - "optional": true - }, - "jotai-tanstack-query": { - "optional": true - }, - "jotai-urql": { - "optional": true - }, - "jotai-valtio": { - "optional": true - }, - "jotai-xstate": { - "optional": true - }, - "jotai-zustand": { + "react": { "optional": true } } @@ -6281,9 +6484,9 @@ "optional": true }, "node_modules/nanoid": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", - "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", "funding": [ { "type": "github", @@ -6329,9 +6532,9 @@ } }, "node_modules/node-releases": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.8.tgz", - "integrity": "sha512-dFSmB8fFHEH/s81Xi+Y/15DQY6VHW81nXRj86EMSL3lmuTmK1e+aT4wrFCkTbm+gSwkw4KpX+rT/pMM2c1mF+A==" + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", + "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==" }, "node_modules/nopt": { "version": "5.0.0", @@ -6654,9 +6857,9 @@ } }, "node_modules/postcss": { - "version": "8.4.24", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.24.tgz", - "integrity": "sha512-M0RzbcI0sO/XJNucsGjvWU9ERWxb/ytp1w6dKtxTKgixdtQDq4rmx/g8W1hnaheq9jgwL/oyEdH5Bc4WwJKMqg==", + "version": "8.4.32", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.32.tgz", + "integrity": "sha512-D/kj5JNu6oo2EIy+XL/26JEDTlIbB8hw85G8StOE6L74RQAVVP5rej6wxCNqyMbR4RkPfqvezVbPw81Ngd6Kcw==", "funding": [ { "type": "opencollective", @@ -6672,7 +6875,7 @@ } ], "dependencies": { - "nanoid": "^3.3.6", + "nanoid": "^3.3.7", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" }, @@ -6788,12 +6991,11 @@ ] }, "node_modules/react": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", - "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==", + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", + "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", "dependencies": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" + "loose-envify": "^1.1.0" }, "engines": { "node": ">=0.10.0" @@ -6882,13 +7084,13 @@ } }, "node_modules/react-dnd": { - "version": "15.1.2", - "resolved": "https://registry.npmjs.org/react-dnd/-/react-dnd-15.1.2.tgz", - "integrity": "sha512-EaSbMD9iFJDY/o48T3c8wn3uWU+2uxfFojhesZN3LhigJoAIvH2iOjxofSA9KbqhAKP6V9P853G6XG8JngKVtA==", + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/react-dnd/-/react-dnd-16.0.1.tgz", + "integrity": "sha512-QeoM/i73HHu2XF9aKksIUuamHPDvRglEwdHL4jsp784BgUuWcg6mzfxT0QDdQz8Wj0qyRKx2eMg8iZtWvU4E2Q==", "dependencies": { - "@react-dnd/invariant": "3.0.1", - "@react-dnd/shallowequal": "3.0.1", - "dnd-core": "15.1.2", + "@react-dnd/invariant": "^4.0.1", + "@react-dnd/shallowequal": "^4.0.1", + "dnd-core": "^16.0.1", "fast-deep-equal": "^3.1.3", "hoist-non-react-statics": "^3.3.2" }, @@ -6911,24 +7113,23 @@ } }, "node_modules/react-dnd-html5-backend": { - "version": "15.1.3", - "resolved": "https://registry.npmjs.org/react-dnd-html5-backend/-/react-dnd-html5-backend-15.1.3.tgz", - "integrity": "sha512-HH/8nOEmrrcRGHMqJR91FOwhnLlx5SRLXmsQwZT3IPcBjx88WT+0pWC5A4tDOYDdoooh9k+KMPvWfxooR5TcOA==", + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/react-dnd-html5-backend/-/react-dnd-html5-backend-16.0.1.tgz", + "integrity": "sha512-Wu3dw5aDJmOGw8WjH1I1/yTH+vlXEL4vmjk5p+MHxP8HuHJS1lAGeIdG/hze1AvNeXWo/JgULV87LyQOr+r5jw==", "dependencies": { - "dnd-core": "15.1.2" + "dnd-core": "^16.0.1" } }, "node_modules/react-dom": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz", - "integrity": "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==", + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", + "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", "dependencies": { "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "scheduler": "^0.20.2" + "scheduler": "^0.23.0" }, "peerDependencies": { - "react": "17.0.2" + "react": "^18.2.0" } }, "node_modules/react-error-boundary": { @@ -7010,6 +7211,36 @@ "node": ">=0.10.0" } }, + "node_modules/react-router": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.20.0.tgz", + "integrity": "sha512-pVvzsSsgUxxtuNfTHC4IxjATs10UaAtvLGVSA1tbUE4GDaOSU1Esu2xF5nWLz7KPiMuW8BJWuPFdlGYJ7/rW0w==", + "dependencies": { + "@remix-run/router": "1.13.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8" + } + }, + "node_modules/react-router-dom": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.20.0.tgz", + "integrity": "sha512-CbcKjEyiSVpA6UtCHOIYLUYn/UJfwzp55va4yEfpk7JBN3GPqWfHrdLkAvNCcpXr8QoihcDMuk0dzWZxtlB/mQ==", + "dependencies": { + "@remix-run/router": "1.13.0", + "react-router": "6.20.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8", + "react-dom": ">=16.8" + } + }, "node_modules/readable-stream": { "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", @@ -7037,9 +7268,9 @@ } }, "node_modules/redux": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.0.tgz", - "integrity": "sha512-oSBmcKKIuIR4ME29/AeNUnl5L+hvBq7OaJWzaptTQJAntaPvxIJqfnjbaEiCzzaIz+XmVILfqAM3Ob0aXLPfjA==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz", + "integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==", "dependencies": { "@babel/runtime": "^7.9.2" } @@ -7149,18 +7380,31 @@ } }, "node_modules/rollup": { - "version": "3.25.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.25.1.tgz", - "integrity": "sha512-tywOR+rwIt5m2ZAWSe5AIJcTat8vGlnPFAv15ycCrw33t6iFsXZ6mzHVFh2psSjxQPmI+xgzMZZizUAukBI4aQ==", + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.8.0.tgz", + "integrity": "sha512-NpsklK2fach5CdI+PScmlE5R4Ao/FSWtF7LkoIrHDxPACY/xshNasPsbpG0VVHxUTbf74tJbVT4PrP8JsJ6ZDA==", "dev": true, "bin": { "rollup": "dist/bin/rollup" }, "engines": { - "node": ">=14.18.0", + "node": ">=18.0.0", "npm": ">=8.0.0" }, "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.8.0", + "@rollup/rollup-android-arm64": "4.8.0", + "@rollup/rollup-darwin-arm64": "4.8.0", + "@rollup/rollup-darwin-x64": "4.8.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.8.0", + "@rollup/rollup-linux-arm64-gnu": "4.8.0", + "@rollup/rollup-linux-arm64-musl": "4.8.0", + "@rollup/rollup-linux-riscv64-gnu": "4.8.0", + "@rollup/rollup-linux-x64-gnu": "4.8.0", + "@rollup/rollup-linux-x64-musl": "4.8.0", + "@rollup/rollup-win32-arm64-msvc": "4.8.0", + "@rollup/rollup-win32-ia32-msvc": "4.8.0", + "@rollup/rollup-win32-x64-msvc": "4.8.0", "fsevents": "~2.3.2" } }, @@ -7271,12 +7515,11 @@ } }, "node_modules/scheduler": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", - "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", + "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", "dependencies": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" + "loose-envify": "^1.1.0" } }, "node_modules/scroll-into-view-if-needed": { @@ -7296,9 +7539,9 @@ } }, "node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "bin": { "semver": "bin/semver.js" } @@ -7810,9 +8053,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", - "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", + "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", "funding": [ { "type": "opencollective", @@ -7821,6 +8064,10 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ], "dependencies": { @@ -7828,7 +8075,7 @@ "picocolors": "^1.0.0" }, "bin": { - "browserslist-lint": "cli.js" + "update-browserslist-db": "cli.js" }, "peerDependencies": { "browserslist": ">= 4.21.0" @@ -7858,27 +8105,31 @@ } }, "node_modules/vite": { - "version": "4.3.9", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.3.9.tgz", - "integrity": "sha512-qsTNZjO9NoJNW7KnOrgYwczm0WctJ8m/yqYAMAK9Lxt4SoySUfS5S8ia9K7JHpa3KEeMfyF8LoJ3c5NeBJy6pg==", + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.0.8.tgz", + "integrity": "sha512-jYMALd8aeqR3yS9xlHd0OzQJndS9fH5ylVgWdB+pxTwxLKdO1pgC5Dlb398BUxpfaBxa4M9oT7j1g503Gaj5IQ==", "dev": true, "dependencies": { - "esbuild": "^0.17.5", - "postcss": "^8.4.23", - "rollup": "^3.21.0" + "esbuild": "^0.19.3", + "postcss": "^8.4.32", + "rollup": "^4.2.0" }, "bin": { "vite": "bin/vite.js" }, "engines": { - "node": "^14.18.0 || >=16.0.0" + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" }, "optionalDependencies": { - "fsevents": "~2.3.2" + "fsevents": "~2.3.3" }, "peerDependencies": { - "@types/node": ">= 14", + "@types/node": "^18.0.0 || >=20.0.0", "less": "*", + "lightningcss": "^1.21.0", "sass": "*", "stylus": "*", "sugarss": "*", @@ -7891,6 +8142,9 @@ "less": { "optional": true }, + "lightningcss": { + "optional": true + }, "sass": { "optional": true }, @@ -7959,9 +8213,9 @@ } }, "node_modules/vite/node_modules/@esbuild/android-arm": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.19.tgz", - "integrity": "sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A==", + "version": "0.19.9", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.9.tgz", + "integrity": "sha512-jkYjjq7SdsWuNI6b5quymW0oC83NN5FdRPuCbs9HZ02mfVdAP8B8eeqLSYU3gb6OJEaY5CQabtTFbqBf26H3GA==", "cpu": [ "arm" ], @@ -7975,9 +8229,9 @@ } }, "node_modules/vite/node_modules/@esbuild/android-arm64": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.19.tgz", - "integrity": "sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==", + "version": "0.19.9", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.9.tgz", + "integrity": "sha512-q4cR+6ZD0938R19MyEW3jEsMzbb/1rulLXiNAJQADD/XYp7pT+rOS5JGxvpRW8dFDEfjW4wLgC/3FXIw4zYglQ==", "cpu": [ "arm64" ], @@ -7991,9 +8245,9 @@ } }, "node_modules/vite/node_modules/@esbuild/android-x64": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.19.tgz", - "integrity": "sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww==", + "version": "0.19.9", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.9.tgz", + "integrity": "sha512-KOqoPntWAH6ZxDwx1D6mRntIgZh9KodzgNOy5Ebt9ghzffOk9X2c1sPwtM9P+0eXbefnDhqYfkh5PLP5ULtWFA==", "cpu": [ "x64" ], @@ -8007,9 +8261,9 @@ } }, "node_modules/vite/node_modules/@esbuild/darwin-arm64": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.19.tgz", - "integrity": "sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg==", + "version": "0.19.9", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.9.tgz", + "integrity": "sha512-KBJ9S0AFyLVx2E5D8W0vExqRW01WqRtczUZ8NRu+Pi+87opZn5tL4Y0xT0mA4FtHctd0ZgwNoN639fUUGlNIWw==", "cpu": [ "arm64" ], @@ -8023,9 +8277,9 @@ } }, "node_modules/vite/node_modules/@esbuild/darwin-x64": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.19.tgz", - "integrity": "sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw==", + "version": "0.19.9", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.9.tgz", + "integrity": "sha512-vE0VotmNTQaTdX0Q9dOHmMTao6ObjyPm58CHZr1UK7qpNleQyxlFlNCaHsHx6Uqv86VgPmR4o2wdNq3dP1qyDQ==", "cpu": [ "x64" ], @@ -8039,9 +8293,9 @@ } }, "node_modules/vite/node_modules/@esbuild/freebsd-arm64": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.19.tgz", - "integrity": "sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ==", + "version": "0.19.9", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.9.tgz", + "integrity": "sha512-uFQyd/o1IjiEk3rUHSwUKkqZwqdvuD8GevWF065eqgYfexcVkxh+IJgwTaGZVu59XczZGcN/YMh9uF1fWD8j1g==", "cpu": [ "arm64" ], @@ -8055,9 +8309,9 @@ } }, "node_modules/vite/node_modules/@esbuild/freebsd-x64": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.19.tgz", - "integrity": "sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ==", + "version": "0.19.9", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.9.tgz", + "integrity": "sha512-WMLgWAtkdTbTu1AWacY7uoj/YtHthgqrqhf1OaEWnZb7PQgpt8eaA/F3LkV0E6K/Lc0cUr/uaVP/49iE4M4asA==", "cpu": [ "x64" ], @@ -8071,9 +8325,9 @@ } }, "node_modules/vite/node_modules/@esbuild/linux-arm": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.19.tgz", - "integrity": "sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA==", + "version": "0.19.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.9.tgz", + "integrity": "sha512-C/ChPohUYoyUaqn1h17m/6yt6OB14hbXvT8EgM1ZWaiiTYz7nWZR0SYmMnB5BzQA4GXl3BgBO1l8MYqL/He3qw==", "cpu": [ "arm" ], @@ -8087,9 +8341,9 @@ } }, "node_modules/vite/node_modules/@esbuild/linux-arm64": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.19.tgz", - "integrity": "sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg==", + "version": "0.19.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.9.tgz", + "integrity": "sha512-PiPblfe1BjK7WDAKR1Cr9O7VVPqVNpwFcPWgfn4xu0eMemzRp442hXyzF/fSwgrufI66FpHOEJk0yYdPInsmyQ==", "cpu": [ "arm64" ], @@ -8103,9 +8357,9 @@ } }, "node_modules/vite/node_modules/@esbuild/linux-ia32": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.19.tgz", - "integrity": "sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ==", + "version": "0.19.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.9.tgz", + "integrity": "sha512-f37i/0zE0MjDxijkPSQw1CO/7C27Eojqb+r3BbHVxMLkj8GCa78TrBZzvPyA/FNLUMzP3eyHCVkAopkKVja+6Q==", "cpu": [ "ia32" ], @@ -8119,9 +8373,9 @@ } }, "node_modules/vite/node_modules/@esbuild/linux-loong64": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.19.tgz", - "integrity": "sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ==", + "version": "0.19.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.9.tgz", + "integrity": "sha512-t6mN147pUIf3t6wUt3FeumoOTPfmv9Cc6DQlsVBpB7eCpLOqQDyWBP1ymXn1lDw4fNUSb/gBcKAmvTP49oIkaA==", "cpu": [ "loong64" ], @@ -8135,9 +8389,9 @@ } }, "node_modules/vite/node_modules/@esbuild/linux-mips64el": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.19.tgz", - "integrity": "sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A==", + "version": "0.19.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.9.tgz", + "integrity": "sha512-jg9fujJTNTQBuDXdmAg1eeJUL4Jds7BklOTkkH80ZgQIoCTdQrDaHYgbFZyeTq8zbY+axgptncko3v9p5hLZtw==", "cpu": [ "mips64el" ], @@ -8151,9 +8405,9 @@ } }, "node_modules/vite/node_modules/@esbuild/linux-ppc64": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.19.tgz", - "integrity": "sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg==", + "version": "0.19.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.9.tgz", + "integrity": "sha512-tkV0xUX0pUUgY4ha7z5BbDS85uI7ABw3V1d0RNTii7E9lbmV8Z37Pup2tsLV46SQWzjOeyDi1Q7Wx2+QM8WaCQ==", "cpu": [ "ppc64" ], @@ -8167,9 +8421,9 @@ } }, "node_modules/vite/node_modules/@esbuild/linux-riscv64": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.19.tgz", - "integrity": "sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA==", + "version": "0.19.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.9.tgz", + "integrity": "sha512-DfLp8dj91cufgPZDXr9p3FoR++m3ZJ6uIXsXrIvJdOjXVREtXuQCjfMfvmc3LScAVmLjcfloyVtpn43D56JFHg==", "cpu": [ "riscv64" ], @@ -8183,9 +8437,9 @@ } }, "node_modules/vite/node_modules/@esbuild/linux-s390x": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.19.tgz", - "integrity": "sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q==", + "version": "0.19.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.9.tgz", + "integrity": "sha512-zHbglfEdC88KMgCWpOl/zc6dDYJvWGLiUtmPRsr1OgCViu3z5GncvNVdf+6/56O2Ca8jUU+t1BW261V6kp8qdw==", "cpu": [ "s390x" ], @@ -8199,9 +8453,9 @@ } }, "node_modules/vite/node_modules/@esbuild/linux-x64": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.19.tgz", - "integrity": "sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw==", + "version": "0.19.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.9.tgz", + "integrity": "sha512-JUjpystGFFmNrEHQnIVG8hKwvA2DN5o7RqiO1CVX8EN/F/gkCjkUMgVn6hzScpwnJtl2mPR6I9XV1oW8k9O+0A==", "cpu": [ "x64" ], @@ -8215,9 +8469,9 @@ } }, "node_modules/vite/node_modules/@esbuild/netbsd-x64": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.19.tgz", - "integrity": "sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q==", + "version": "0.19.9", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.9.tgz", + "integrity": "sha512-GThgZPAwOBOsheA2RUlW5UeroRfESwMq/guy8uEe3wJlAOjpOXuSevLRd70NZ37ZrpO6RHGHgEHvPg1h3S1Jug==", "cpu": [ "x64" ], @@ -8231,9 +8485,9 @@ } }, "node_modules/vite/node_modules/@esbuild/openbsd-x64": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.19.tgz", - "integrity": "sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g==", + "version": "0.19.9", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.9.tgz", + "integrity": "sha512-Ki6PlzppaFVbLnD8PtlVQfsYw4S9n3eQl87cqgeIw+O3sRr9IghpfSKY62mggdt1yCSZ8QWvTZ9jo9fjDSg9uw==", "cpu": [ "x64" ], @@ -8247,9 +8501,9 @@ } }, "node_modules/vite/node_modules/@esbuild/sunos-x64": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.19.tgz", - "integrity": "sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg==", + "version": "0.19.9", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.9.tgz", + "integrity": "sha512-MLHj7k9hWh4y1ddkBpvRj2b9NCBhfgBt3VpWbHQnXRedVun/hC7sIyTGDGTfsGuXo4ebik2+3ShjcPbhtFwWDw==", "cpu": [ "x64" ], @@ -8263,9 +8517,9 @@ } }, "node_modules/vite/node_modules/@esbuild/win32-arm64": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.19.tgz", - "integrity": "sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag==", + "version": "0.19.9", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.9.tgz", + "integrity": "sha512-GQoa6OrQ8G08guMFgeXPH7yE/8Dt0IfOGWJSfSH4uafwdC7rWwrfE6P9N8AtPGIjUzdo2+7bN8Xo3qC578olhg==", "cpu": [ "arm64" ], @@ -8279,9 +8533,9 @@ } }, "node_modules/vite/node_modules/@esbuild/win32-ia32": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.19.tgz", - "integrity": "sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw==", + "version": "0.19.9", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.9.tgz", + "integrity": "sha512-UOozV7Ntykvr5tSOlGCrqU3NBr3d8JqPes0QWN2WOXfvkWVGRajC+Ym0/Wj88fUgecUCLDdJPDF0Nna2UK3Qtg==", "cpu": [ "ia32" ], @@ -8295,9 +8549,9 @@ } }, "node_modules/vite/node_modules/@esbuild/win32-x64": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.19.tgz", - "integrity": "sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA==", + "version": "0.19.9", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.9.tgz", + "integrity": "sha512-oxoQgglOP7RH6iasDrhY+R/3cHrfwIDvRlT4CGChflq6twk8iENeVvMJjmvBb94Ik1Z+93iGO27err7w6l54GQ==", "cpu": [ "x64" ], @@ -8311,9 +8565,9 @@ } }, "node_modules/vite/node_modules/esbuild": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.19.tgz", - "integrity": "sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==", + "version": "0.19.9", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.9.tgz", + "integrity": "sha512-U9CHtKSy+EpPsEBa+/A2gMs/h3ylBC0H0KSqIg7tpztHerLi6nrrcoUJAkNCEPumx8yJ+Byic4BVwHgRbN0TBg==", "dev": true, "hasInstallScript": true, "bin": { @@ -8323,28 +8577,28 @@ "node": ">=12" }, "optionalDependencies": { - "@esbuild/android-arm": "0.17.19", - "@esbuild/android-arm64": "0.17.19", - "@esbuild/android-x64": "0.17.19", - "@esbuild/darwin-arm64": "0.17.19", - "@esbuild/darwin-x64": "0.17.19", - "@esbuild/freebsd-arm64": "0.17.19", - "@esbuild/freebsd-x64": "0.17.19", - "@esbuild/linux-arm": "0.17.19", - "@esbuild/linux-arm64": "0.17.19", - "@esbuild/linux-ia32": "0.17.19", - "@esbuild/linux-loong64": "0.17.19", - "@esbuild/linux-mips64el": "0.17.19", - "@esbuild/linux-ppc64": "0.17.19", - "@esbuild/linux-riscv64": "0.17.19", - "@esbuild/linux-s390x": "0.17.19", - "@esbuild/linux-x64": "0.17.19", - "@esbuild/netbsd-x64": "0.17.19", - "@esbuild/openbsd-x64": "0.17.19", - "@esbuild/sunos-x64": "0.17.19", - "@esbuild/win32-arm64": "0.17.19", - "@esbuild/win32-ia32": "0.17.19", - "@esbuild/win32-x64": "0.17.19" + "@esbuild/android-arm": "0.19.9", + "@esbuild/android-arm64": "0.19.9", + "@esbuild/android-x64": "0.19.9", + "@esbuild/darwin-arm64": "0.19.9", + "@esbuild/darwin-x64": "0.19.9", + "@esbuild/freebsd-arm64": "0.19.9", + "@esbuild/freebsd-x64": "0.19.9", + "@esbuild/linux-arm": "0.19.9", + "@esbuild/linux-arm64": "0.19.9", + "@esbuild/linux-ia32": "0.19.9", + "@esbuild/linux-loong64": "0.19.9", + "@esbuild/linux-mips64el": "0.19.9", + "@esbuild/linux-ppc64": "0.19.9", + "@esbuild/linux-riscv64": "0.19.9", + "@esbuild/linux-s390x": "0.19.9", + "@esbuild/linux-x64": "0.19.9", + "@esbuild/netbsd-x64": "0.19.9", + "@esbuild/openbsd-x64": "0.19.9", + "@esbuild/sunos-x64": "0.19.9", + "@esbuild/win32-arm64": "0.19.9", + "@esbuild/win32-ia32": "0.19.9", + "@esbuild/win32-x64": "0.19.9" } }, "node_modules/warning": { diff --git a/package.json b/package.json index cb6111b5d..56e7b8c01 100644 --- a/package.json +++ b/package.json @@ -39,13 +39,13 @@ "file-saver": "2.0.5", "flux": "4.0.3", "focus-trap-react": "10.0.2", - "folds": "1.5.0", + "folds": "1.5.1", "formik": "2.2.9", "html-dom-parser": "4.0.0", "html-react-parser": "4.2.0", "immer": "9.0.16", "is-hotkey": "0.2.0", - "jotai": "1.12.0", + "jotai": "2.6.0", "katex": "0.16.4", "linkify-html": "4.0.2", "linkify-react": "4.1.1", @@ -55,17 +55,18 @@ "pdfjs-dist": "3.10.111", "prismjs": "1.29.0", "prop-types": "15.8.1", - "react": "17.0.2", + "react": "18.2.0", "react-aria": "3.29.1", "react-autosize-textarea": "7.1.0", "react-blurhash": "0.2.0", - "react-dnd": "15.1.2", - "react-dnd-html5-backend": "15.1.3", - "react-dom": "17.0.2", + "react-dnd": "16.0.1", + "react-dnd-html5-backend": "16.0.1", + "react-dom": "18.2.0", "react-error-boundary": "4.0.10", "react-google-recaptcha": "2.1.0", "react-modal": "3.16.1", "react-range": "1.8.14", + "react-router-dom": "6.20.0", "sanitize-html": "2.8.0", "slate": "0.94.1", "slate-history": "0.93.0", @@ -81,13 +82,14 @@ "@types/file-saver": "2.0.5", "@types/node": "18.11.18", "@types/prismjs": "1.26.0", - "@types/react": "18.0.26", - "@types/react-dom": "18.0.9", + "@types/react": "18.2.39", + "@types/react-dom": "18.2.17", + "@types/react-google-recaptcha": "2.1.8", "@types/sanitize-html": "2.9.0", "@types/ua-parser-js": "0.7.36", "@typescript-eslint/eslint-plugin": "5.46.1", "@typescript-eslint/parser": "5.46.1", - "@vitejs/plugin-react": "3.0.0", + "@vitejs/plugin-react": "4.2.0", "buffer": "6.0.3", "eslint": "8.29.0", "eslint-config-airbnb": "19.0.4", @@ -100,7 +102,7 @@ "prettier": "2.8.1", "sass": "1.56.2", "typescript": "4.9.4", - "vite": "4.3.9", + "vite": "5.0.8", "vite-plugin-static-copy": "0.13.0" } } diff --git a/src/app/components/AuthFlowsLoader.tsx b/src/app/components/AuthFlowsLoader.tsx new file mode 100644 index 000000000..f21bad044 --- /dev/null +++ b/src/app/components/AuthFlowsLoader.tsx @@ -0,0 +1,64 @@ +import { ReactNode, useCallback, useEffect, useMemo } from 'react'; +import { MatrixError, createClient } from 'matrix-js-sdk'; +import { AsyncStatus, useAsyncCallback } from '../hooks/useAsyncCallback'; +import { useAutoDiscoveryInfo } from '../hooks/useAutoDiscoveryInfo'; +import { promiseFulfilledResult, promiseRejectedResult } from '../utils/common'; +import { + AuthFlows, + RegisterFlowStatus, + RegisterFlowsResponse, + parseRegisterErrResp, +} from '../hooks/useAuthFlows'; + +type AuthFlowsLoaderProps = { + fallback?: () => ReactNode; + error?: (err: unknown) => ReactNode; + children: (authFlows: AuthFlows) => ReactNode; +}; +export function AuthFlowsLoader({ fallback, error, children }: AuthFlowsLoaderProps) { + const autoDiscoveryInfo = useAutoDiscoveryInfo(); + const baseUrl = autoDiscoveryInfo['m.homeserver'].base_url; + + const mx = useMemo(() => createClient({ baseUrl }), [baseUrl]); + + const [state, load] = useAsyncCallback( + useCallback(async () => { + const result = await Promise.allSettled([mx.loginFlows(), mx.registerRequest({})]); + const loginFlows = promiseFulfilledResult(result[0]); + const registerResp = promiseRejectedResult(result[1]) as MatrixError | undefined; + let registerFlows: RegisterFlowsResponse = { status: RegisterFlowStatus.InvalidRequest }; + + if (typeof registerResp === 'object' && registerResp.httpStatus) { + registerFlows = parseRegisterErrResp(registerResp); + } + + if (!loginFlows) { + throw new Error('Missing auth flow!'); + } + if ('errcode' in loginFlows) { + throw new Error('Failed to load auth flow!'); + } + + const authFlows: AuthFlows = { + loginFlows, + registerFlows, + }; + + return authFlows; + }, [mx]) + ); + + useEffect(() => { + load(); + }, [load]); + + if (state.status === AsyncStatus.Idle || state.status === AsyncStatus.Loading) { + return fallback?.(); + } + + if (state.status === AsyncStatus.Error) { + return error?.(state.error); + } + + return children(state.data); +} diff --git a/src/app/components/ClientConfigLoader.tsx b/src/app/components/ClientConfigLoader.tsx new file mode 100644 index 000000000..72d367c06 --- /dev/null +++ b/src/app/components/ClientConfigLoader.tsx @@ -0,0 +1,38 @@ +import { ReactNode, useCallback, useEffect, useState } from 'react'; +import { AsyncStatus, useAsyncCallback } from '../hooks/useAsyncCallback'; +import { ClientConfig } from '../hooks/useClientConfig'; +import { trimTrailingSlash } from '../utils/common'; + +const getClientConfig = async (): Promise => { + const url = `${trimTrailingSlash(import.meta.env.BASE_URL)}/config.json`; + const config = await fetch(url, { method: 'GET' }); + return config.json(); +}; + +type ClientConfigLoaderProps = { + fallback?: () => ReactNode; + error?: (err: unknown, retry: () => void, ignore: () => void) => ReactNode; + children: (config: ClientConfig) => ReactNode; +}; +export function ClientConfigLoader({ fallback, error, children }: ClientConfigLoaderProps) { + const [state, load] = useAsyncCallback(getClientConfig); + const [ignoreError, setIgnoreError] = useState(false); + + const ignoreCallback = useCallback(() => setIgnoreError(true), []); + + useEffect(() => { + load(); + }, [load]); + + if (state.status === AsyncStatus.Idle || state.status === AsyncStatus.Loading) { + return fallback?.(); + } + + if (!ignoreError && state.status === AsyncStatus.Error) { + return error?.(state.error, load, ignoreCallback); + } + + const config: ClientConfig = state.status === AsyncStatus.Success ? state.data : {}; + + return children(config); +} diff --git a/src/app/components/ConfirmPasswordMatch.tsx b/src/app/components/ConfirmPasswordMatch.tsx new file mode 100644 index 000000000..bb50eb60f --- /dev/null +++ b/src/app/components/ConfirmPasswordMatch.tsx @@ -0,0 +1,35 @@ +import { ReactNode, RefObject, useCallback, useRef, useState } from 'react'; +import { useDebounce } from '../hooks/useDebounce'; + +type ConfirmPasswordMatchProps = { + initialValue: boolean; + children: ( + match: boolean, + doMatch: () => void, + passRef: RefObject, + confPassRef: RefObject + ) => ReactNode; +}; +export function ConfirmPasswordMatch({ initialValue, children }: ConfirmPasswordMatchProps) { + const [match, setMatch] = useState(initialValue); + const passRef = useRef(null); + const confPassRef = useRef(null); + + const doMatch = useDebounce( + useCallback(() => { + const pass = passRef.current?.value; + const confPass = confPassRef.current?.value; + if (!confPass) { + setMatch(initialValue); + return; + } + setMatch(pass === confPass); + }, [initialValue]), + { + wait: 500, + immediate: false, + } + ); + + return children(match, doMatch, passRef, confPassRef); +} diff --git a/src/app/components/SpecVersionsLoader.tsx b/src/app/components/SpecVersionsLoader.tsx new file mode 100644 index 000000000..56d7f8b05 --- /dev/null +++ b/src/app/components/SpecVersionsLoader.tsx @@ -0,0 +1,32 @@ +import { ReactNode, useCallback, useEffect } from 'react'; +import { AsyncStatus, useAsyncCallback } from '../hooks/useAsyncCallback'; +import { SpecVersions, specVersions } from '../cs-api'; +import { useAutoDiscoveryInfo } from '../hooks/useAutoDiscoveryInfo'; + +type SpecVersionsLoaderProps = { + fallback?: () => ReactNode; + error?: (err: unknown) => ReactNode; + children: (versions: SpecVersions) => ReactNode; +}; +export function SpecVersionsLoader({ fallback, error, children }: SpecVersionsLoaderProps) { + const autoDiscoveryInfo = useAutoDiscoveryInfo(); + const baseUrl = autoDiscoveryInfo['m.homeserver'].base_url; + + const [state, load] = useAsyncCallback( + useCallback(() => specVersions(fetch, baseUrl), [baseUrl]) + ); + + useEffect(() => { + load(); + }, [load]); + + if (state.status === AsyncStatus.Idle || state.status === AsyncStatus.Loading) { + return fallback?.(); + } + + if (state.status === AsyncStatus.Error) { + return error?.(state.error); + } + + return children(state.data); +} diff --git a/src/app/components/SupportedUIAFlowsLoader.tsx b/src/app/components/SupportedUIAFlowsLoader.tsx new file mode 100644 index 000000000..442eb5729 --- /dev/null +++ b/src/app/components/SupportedUIAFlowsLoader.tsx @@ -0,0 +1,17 @@ +import { ReactNode } from 'react'; +import { UIAFlow } from 'matrix-js-sdk'; +import { useSupportedUIAFlows } from '../hooks/useUIAFlows'; + +export function SupportedUIAFlowsLoader({ + flows, + supportedStages, + children, +}: { + supportedStages: string[]; + flows: UIAFlow[]; + children: (supportedFlows: UIAFlow[]) => ReactNode; +}) { + const supportedFlows = useSupportedUIAFlows(flows, supportedStages); + + return children(supportedFlows); +} diff --git a/src/app/components/UIAFlowOverlay.tsx b/src/app/components/UIAFlowOverlay.tsx new file mode 100644 index 000000000..f788eb0fd --- /dev/null +++ b/src/app/components/UIAFlowOverlay.tsx @@ -0,0 +1,72 @@ +import React, { ReactNode } from 'react'; +import { + Overlay, + OverlayBackdrop, + Box, + config, + Text, + TooltipProvider, + Tooltip, + Icons, + Icon, + Chip, + IconButton, +} from 'folds'; +import FocusTrap from 'focus-trap-react'; + +export type UIAFlowOverlayProps = { + currentStep: number; + stepCount: number; + children: ReactNode; + onCancel: () => void; +}; +export function UIAFlowOverlay({ + currentStep, + stepCount, + children, + onCancel, +}: UIAFlowOverlayProps) { + return ( + }> + + + + {children} + + + + {`Step ${currentStep}/${stepCount}`} + + + Exit + + } + position="Top" + > + {(anchorRef) => ( + + + + )} + + + + + + ); +} diff --git a/src/app/components/password-input/PasswordInput.tsx b/src/app/components/password-input/PasswordInput.tsx new file mode 100644 index 000000000..184a097c4 --- /dev/null +++ b/src/app/components/password-input/PasswordInput.tsx @@ -0,0 +1,45 @@ +import React, { ComponentProps, forwardRef } from 'react'; +import { Icon, IconButton, Input, config, Icons } from 'folds'; +import { UseStateProvider } from '../UseStateProvider'; + +type PasswordInputProps = Omit, 'type' | 'size'> & { + size: '400' | '500'; +}; +export const PasswordInput = forwardRef( + ({ variant, size, style, after, ...props }, ref) => { + const paddingRight: string = size === '500' ? config.space.S300 : config.space.S200; + + return ( + + {(visible, setVisible) => ( + + {after} + setVisible(!visible)} + type="button" + variant={visible ? 'Warning' : variant} + size="300" + radii="300" + > + + + + } + /> + )} + + ); + } +); diff --git a/src/app/components/splash-screen/SplashScreen.css.ts b/src/app/components/splash-screen/SplashScreen.css.ts new file mode 100644 index 000000000..bd3c300a7 --- /dev/null +++ b/src/app/components/splash-screen/SplashScreen.css.ts @@ -0,0 +1,12 @@ +import { style } from '@vanilla-extract/css'; +import { color, config } from 'folds'; + +export const SplashScreen = style({ + minHeight: '100%', + backgroundColor: color.Background.Container, + color: color.Background.OnContainer, +}); + +export const SplashScreenFooter = style({ + padding: config.space.S400, +}); diff --git a/src/app/components/splash-screen/SplashScreen.tsx b/src/app/components/splash-screen/SplashScreen.tsx new file mode 100644 index 000000000..27adadbad --- /dev/null +++ b/src/app/components/splash-screen/SplashScreen.tsx @@ -0,0 +1,29 @@ +import { Box, Text } from 'folds'; +import React, { ReactNode } from 'react'; +import classNames from 'classnames'; +import * as patternsCSS from '../../styles/Patterns.css'; +import * as css from './SplashScreen.css'; + +type SplashScreenProps = { + children: ReactNode; +}; +export function SplashScreen({ children }: SplashScreenProps) { + return ( + + {children} + + + Cinny + + + + ); +} diff --git a/src/app/components/splash-screen/index.ts b/src/app/components/splash-screen/index.ts new file mode 100644 index 000000000..e3e5dd34d --- /dev/null +++ b/src/app/components/splash-screen/index.ts @@ -0,0 +1 @@ +export * from './SplashScreen'; diff --git a/src/app/components/uia-stages/DummyStage.tsx b/src/app/components/uia-stages/DummyStage.tsx new file mode 100644 index 000000000..7e0f85861 --- /dev/null +++ b/src/app/components/uia-stages/DummyStage.tsx @@ -0,0 +1,65 @@ +import React, { useEffect, useCallback } from 'react'; +import { Dialog, Text, Box, Button, config } from 'folds'; +import { AuthType } from 'matrix-js-sdk'; +import { StageComponentProps } from './types'; + +function DummyErrorDialog({ + title, + message, + onRetry, + onCancel, +}: { + title: string; + message: string; + onRetry: () => void; + onCancel: () => void; +}) { + return ( + + + + {title} + {message} + + + + + + ); +} + +export function AutoDummyStageDialog({ stageData, submitAuthDict, onCancel }: StageComponentProps) { + const { errorCode, error, session } = stageData; + + const handleSubmit = useCallback(() => { + submitAuthDict({ + type: AuthType.Dummy, + session, + }); + }, [session, submitAuthDict]); + + useEffect(() => { + if (!errorCode) handleSubmit(); + }, [handleSubmit, errorCode]); + + if (errorCode) { + return ( + + ); + } + + return null; +} diff --git a/src/app/components/uia-stages/EmailStage.tsx b/src/app/components/uia-stages/EmailStage.tsx new file mode 100644 index 000000000..fdc2b61aa --- /dev/null +++ b/src/app/components/uia-stages/EmailStage.tsx @@ -0,0 +1,172 @@ +import React, { useEffect, useCallback, FormEventHandler } from 'react'; +import { Dialog, Text, Box, Button, config, Input, color, Spinner } from 'folds'; +import { AuthType, MatrixError } from 'matrix-js-sdk'; +import { StageComponentProps } from './types'; +import { AsyncState, AsyncStatus } from '../../hooks/useAsyncCallback'; +import { RequestEmailTokenCallback, RequestEmailTokenResponse } from '../../hooks/types'; + +function EmailErrorDialog({ + title, + message, + defaultEmail, + onRetry, + onCancel, +}: { + title: string; + message: string; + defaultEmail?: string; + onRetry: (email: string) => void; + onCancel: () => void; +}) { + const handleFormSubmit: FormEventHandler = (evt) => { + evt.preventDefault(); + const { retryEmailInput } = evt.target as HTMLFormElement & { + retryEmailInput: HTMLInputElement; + }; + const t = retryEmailInput.value; + onRetry(t); + }; + + return ( + + + + {title} + {message} + + Email + + + + + + + + ); +} + +export function EmailStageDialog({ + email, + clientSecret, + stageData, + emailTokenState, + requestEmailToken, + submitAuthDict, + onCancel, +}: StageComponentProps & { + email?: string; + clientSecret: string; + emailTokenState: AsyncState; + requestEmailToken: RequestEmailTokenCallback; +}) { + const { errorCode, error, session } = stageData; + + const handleSubmit = useCallback( + (sessionId: string) => { + const threepIDCreds = { + sid: sessionId, + client_secret: clientSecret, + }; + submitAuthDict({ + type: AuthType.Email, + threepid_creds: threepIDCreds, + threepidCreds: threepIDCreds, + session, + }); + }, + [submitAuthDict, session, clientSecret] + ); + + const handleEmailSubmit = useCallback( + (userEmail: string) => { + requestEmailToken(userEmail, clientSecret); + }, + [clientSecret, requestEmailToken] + ); + + useEffect(() => { + if (email && !errorCode && emailTokenState.status === AsyncStatus.Idle) { + requestEmailToken(email, clientSecret); + } + }, [email, errorCode, clientSecret, emailTokenState, requestEmailToken]); + + if (emailTokenState.status === AsyncStatus.Loading) { + return ( + + + Sending verification email... + + ); + } + + if (emailTokenState.status === AsyncStatus.Error) { + return ( + + ); + } + + if (emailTokenState.status === AsyncStatus.Success) { + return ( + + + + Verification Request Sent + {`Please check your email "${emailTokenState.data.email}" and validate before continuing further.`} + + {errorCode && ( + {`${errorCode}: ${error}`} + )} + + + + + ); + } + + if (!email) { + return ( + + ); + } + + return null; +} diff --git a/src/app/components/uia-stages/ReCaptchaStage.tsx b/src/app/components/uia-stages/ReCaptchaStage.tsx new file mode 100644 index 000000000..68b3fcf48 --- /dev/null +++ b/src/app/components/uia-stages/ReCaptchaStage.tsx @@ -0,0 +1,64 @@ +import React from 'react'; +import { Dialog, Text, Box, Button, config } from 'folds'; +import { AuthType } from 'matrix-js-sdk'; +import ReCAPTCHA from 'react-google-recaptcha'; +import { StageComponentProps } from './types'; + +function ReCaptchaErrorDialog({ + title, + message, + onCancel, +}: { + title: string; + message: string; + onCancel: () => void; +}) { + return ( + + + + {title} + {message} + + + + + ); +} + +export function ReCaptchaStageDialog({ stageData, submitAuthDict, onCancel }: StageComponentProps) { + const { info, session } = stageData; + + const publicKey = info?.public_key; + + const handleChange = (token: string | null) => { + submitAuthDict({ + type: AuthType.Recaptcha, + response: token, + session, + }); + }; + + if (typeof publicKey !== 'string' || !session) { + return ( + + ); + } + + return ( + + + Please check the box below to proceed. + + + + ); +} diff --git a/src/app/components/uia-stages/RegistrationTokenStage.tsx b/src/app/components/uia-stages/RegistrationTokenStage.tsx new file mode 100644 index 000000000..ed8a30458 --- /dev/null +++ b/src/app/components/uia-stages/RegistrationTokenStage.tsx @@ -0,0 +1,117 @@ +import React, { useEffect, useCallback, FormEventHandler } from 'react'; +import { Dialog, Text, Box, Button, config, Input } from 'folds'; +import { AuthType } from 'matrix-js-sdk'; +import { StageComponentProps } from './types'; + +function RegistrationTokenErrorDialog({ + title, + message, + defaultToken, + onRetry, + onCancel, +}: { + title: string; + message: string; + defaultToken?: string; + onRetry: (token: string) => void; + onCancel: () => void; +}) { + const handleFormSubmit: FormEventHandler = (evt) => { + evt.preventDefault(); + const { retryTokenInput } = evt.target as HTMLFormElement & { + retryTokenInput: HTMLInputElement; + }; + const t = retryTokenInput.value; + onRetry(t); + }; + + return ( + + + + {title} + {message} + + Registration Token + + + + + + + + ); +} + +export function RegistrationTokenStageDialog({ + token, + stageData, + submitAuthDict, + onCancel, +}: StageComponentProps & { + token?: string; +}) { + const { errorCode, error, session } = stageData; + + const handleSubmit = useCallback( + (t: string) => { + submitAuthDict({ + type: AuthType.RegistrationToken, + token: t, + session, + }); + }, + [session, submitAuthDict] + ); + + useEffect(() => { + if (token && !errorCode) handleSubmit(token); + }, [handleSubmit, token, errorCode]); + + if (errorCode) { + return ( + + ); + } + + if (!token) { + return ( + + ); + } + + return null; +} diff --git a/src/app/components/uia-stages/TermsStage.tsx b/src/app/components/uia-stages/TermsStage.tsx new file mode 100644 index 000000000..f69770534 --- /dev/null +++ b/src/app/components/uia-stages/TermsStage.tsx @@ -0,0 +1,69 @@ +import React, { useEffect, useCallback } from 'react'; +import { Dialog, Text, Box, Button, config } from 'folds'; +import { AuthType } from 'matrix-js-sdk'; +import { StageComponentProps } from './types'; + +function TermsErrorDialog({ + title, + message, + onRetry, + onCancel, +}: { + title: string; + message: string; + onRetry: () => void; + onCancel: () => void; +}) { + return ( + + + + {title} + {message} + + + + + + ); +} + +export function AutoTermsStageDialog({ stageData, submitAuthDict, onCancel }: StageComponentProps) { + const { errorCode, error, session } = stageData; + + const handleSubmit = useCallback( + () => + submitAuthDict({ + type: AuthType.Terms, + session, + }), + [session, submitAuthDict] + ); + + useEffect(() => { + if (!errorCode) { + handleSubmit(); + } + }, [session, errorCode, handleSubmit]); + + if (errorCode) { + return ( + + ); + } + + return null; +} diff --git a/src/app/components/uia-stages/index.ts b/src/app/components/uia-stages/index.ts new file mode 100644 index 000000000..95c19a79c --- /dev/null +++ b/src/app/components/uia-stages/index.ts @@ -0,0 +1,6 @@ +export * from './types'; +export * from './DummyStage'; +export * from './EmailStage'; +export * from './ReCaptchaStage'; +export * from './RegistrationTokenStage'; +export * from './TermsStage'; diff --git a/src/app/components/uia-stages/types.ts b/src/app/components/uia-stages/types.ts new file mode 100644 index 000000000..cc6674c5e --- /dev/null +++ b/src/app/components/uia-stages/types.ts @@ -0,0 +1,8 @@ +import { AuthDict } from 'matrix-js-sdk'; +import { AuthStageData } from '../../hooks/useUIAFlows'; + +export type StageComponentProps = { + stageData: AuthStageData; + submitAuthDict: (authDict: AuthDict) => void; + onCancel: () => void; +}; diff --git a/src/app/cs-api.ts b/src/app/cs-api.ts new file mode 100644 index 000000000..b9c677192 --- /dev/null +++ b/src/app/cs-api.ts @@ -0,0 +1,115 @@ +import to from 'await-to-js'; +import { trimTrailingSlash } from './utils/common'; + +export enum AutoDiscoveryAction { + PROMPT = 'PROMPT', + IGNORE = 'IGNORE', + FAIL_PROMPT = 'FAIL_PROMPT', + FAIL_ERROR = 'FAIL_ERROR', +} + +export type AutoDiscoveryError = { + host: string; + action: AutoDiscoveryAction; +}; + +export type AutoDiscoveryInfo = Record & { + 'm.homeserver': { + base_url: string; + }; + 'm.identity_server'?: { + base_url: string; + }; +}; + +export const autoDiscovery = async ( + request: typeof fetch, + server: string +): Promise<[AutoDiscoveryError, undefined] | [undefined, AutoDiscoveryInfo]> => { + const host = /^https?:\/\//.test(server) ? trimTrailingSlash(server) : `https://${server}`; + const autoDiscoveryUrl = `${host}/.well-known/matrix/client`; + + const [err, response] = await to(request(autoDiscoveryUrl, { method: 'GET' })); + + if (err || response.status === 404) { + // AutoDiscoveryAction.IGNORE + // We will use default value for IGNORE action + return [ + undefined, + { + 'm.homeserver': { + base_url: host, + }, + }, + ]; + } + if (response.status !== 200) { + return [ + { + host, + action: AutoDiscoveryAction.FAIL_PROMPT, + }, + undefined, + ]; + } + + const [contentErr, content] = await to(response.json()); + + if (contentErr || typeof content !== 'object') { + return [ + { + host, + action: AutoDiscoveryAction.FAIL_PROMPT, + }, + undefined, + ]; + } + + const baseUrl = content['m.homeserver']?.base_url; + if (typeof baseUrl !== 'string') { + return [ + { + host, + action: AutoDiscoveryAction.FAIL_PROMPT, + }, + undefined, + ]; + } + + if (/^https?:\/\//.test(baseUrl) === false) { + return [ + { + host, + action: AutoDiscoveryAction.FAIL_ERROR, + }, + undefined, + ]; + } + + content['m.homeserver'].base_url = trimTrailingSlash(baseUrl); + if (content['m.identity_server']) { + content['m.identity_server'].base_url = trimTrailingSlash( + content['m.identity_server'].base_url + ); + } + + return [undefined, content]; +}; + +export type SpecVersions = { + versions: string[]; + unstable_features?: Record; +}; +export const specVersions = async ( + request: typeof fetch, + baseUrl: string +): Promise => { + const res = await request(`${baseUrl}/_matrix/client/versions`); + + const data = (await res.json()) as unknown; + + if (data && typeof data === 'object' && 'versions' in data && Array.isArray(data.versions)) { + return data as SpecVersions; + } + throw new Error('Homeserver URL does not appear to be a valid Matrix homeserver'); +}; diff --git a/src/app/cs-errorcode.ts b/src/app/cs-errorcode.ts new file mode 100644 index 000000000..6c21d670c --- /dev/null +++ b/src/app/cs-errorcode.ts @@ -0,0 +1,37 @@ +export enum ErrorCode { + M_FORBIDDEN = 'M_FORBIDDEN', + M_UNKNOWN_TOKEN = 'M_UNKNOWN_TOKEN', + M_MISSING_TOKEN = 'M_MISSING_TOKEN', + M_BAD_JSON = 'M_BAD_JSON', + M_NOT_JSON = 'M_NOT_JSON', + M_NOT_FOUND = 'M_NOT_FOUND', + M_LIMIT_EXCEEDED = 'M_LIMIT_EXCEEDED', + M_UNRECOGNIZED = 'M_UNRECOGNIZED', + M_UNKNOWN = 'M_UNKNOWN', + + M_UNAUTHORIZED = 'M_UNAUTHORIZED', + M_USER_DEACTIVATED = 'M_USER_DEACTIVATED', + M_USER_IN_USE = 'M_USER_IN_USE', + M_INVALID_USERNAME = 'M_INVALID_USERNAME', + M_WEAK_PASSWORD = 'M_WEAK_PASSWORD', + M_PASSWORD_TOO_SHORT = 'M_PASSWORD_TOO_SHORT', + M_ROOM_IN_USE = 'M_ROOM_IN_USE', + M_INVALID_ROOM_STATE = 'M_INVALID_ROOM_STATE', + M_THREEPID_IN_USE = 'M_THREEPID_IN_USE', + M_THREEPID_NOT_FOUND = 'M_THREEPID_NOT_FOUND', + M_THREEPID_AUTH_FAILED = 'M_THREEPID_AUTH_FAILED', + M_THREEPID_DENIED = 'M_THREEPID_DENIED', + M_SERVER_NOT_TRUSTED = 'M_SERVER_NOT_TRUSTED', + M_UNSUPPORTED_ROOM_VERSION = 'M_UNSUPPORTED_ROOM_VERSION', + M_INCOMPATIBLE_ROOM_VERSION = 'M_INCOMPATIBLE_ROOM_VERSION', + M_BAD_STATE = 'M_BAD_STATE', + M_GUEST_ACCESS_FORBIDDEN = 'M_GUEST_ACCESS_FORBIDDEN', + M_CAPTCHA_NEEDED = 'M_CAPTCHA_NEEDED', + M_CAPTCHA_INVALID = 'M_CAPTCHA_INVALID', + M_MISSING_PARAM = 'M_MISSING_PARAM', + M_INVALID_PARAM = 'M_INVALID_PARAM', + M_TOO_LARGE = 'M_TOO_LARGE', + M_EXCLUSIVE = 'M_EXCLUSIVE', + M_RESOURCE_LIMIT_EXCEEDED = 'M_RESOURCE_LIMIT_EXCEEDED', + M_CANNOT_LEAVE_SERVER_NOTICE_ROOM = 'M_CANNOT_LEAVE_SERVER_NOTICE_ROOM', +} diff --git a/src/app/hooks/types.ts b/src/app/hooks/types.ts new file mode 100644 index 000000000..9aac2b314 --- /dev/null +++ b/src/app/hooks/types.ts @@ -0,0 +1,12 @@ +import { IRequestTokenResponse } from 'matrix-js-sdk'; + +export type RequestEmailTokenResponse = { + email: string; + clientSecret: string; + result: IRequestTokenResponse; +}; +export type RequestEmailTokenCallback = ( + email: string, + clientSecret: string, + nextLink?: string +) => Promise; diff --git a/src/app/hooks/useAsyncCallback.ts b/src/app/hooks/useAsyncCallback.ts index 18b63ecc6..fc7dca63f 100644 --- a/src/app/hooks/useAsyncCallback.ts +++ b/src/app/hooks/useAsyncCallback.ts @@ -1,4 +1,5 @@ -import { useCallback, useState } from 'react'; +import { useCallback, useRef, useState } from 'react'; +import { flushSync } from 'react-dom'; import { useAlive } from './useAlive'; export enum AsyncStatus { @@ -16,36 +17,56 @@ export type AsyncLoading = { status: AsyncStatus.Loading; }; -export type AsyncSuccess = { +export type AsyncSuccess = { status: AsyncStatus.Success; - data: T; + data: D; }; -export type AsyncError = { +export type AsyncError = { status: AsyncStatus.Error; - error: unknown; + error: E; }; -export type AsyncState = AsyncIdle | AsyncLoading | AsyncSuccess | AsyncError; +export type AsyncState = AsyncIdle | AsyncLoading | AsyncSuccess | AsyncError; export type AsyncCallback = (...args: TArgs) => Promise; -export const useAsyncCallback = ( +export const useAsyncCallback = ( asyncCallback: AsyncCallback -): [AsyncState, AsyncCallback] => { - const [state, setState] = useState>({ +): [AsyncState, AsyncCallback] => { + const [state, setState] = useState>({ status: AsyncStatus.Idle, }); const alive = useAlive(); + // Tracks the request number. + // If two or more requests are made subsequently + // we will throw all old request's response after they resolved. + const reqNumberRef = useRef(0); + const callback: AsyncCallback = useCallback( async (...args) => { - setState({ - status: AsyncStatus.Loading, + queueMicrotask(() => { + // Warning: flushSync was called from inside a lifecycle method. + // React cannot flush when React is already rendering. + // Consider moving this call to a scheduler task or micro task. + flushSync(() => { + // flushSync because + // https://github.com/facebook/react/issues/26713#issuecomment-1872085134 + setState({ + status: AsyncStatus.Loading, + }); + }); }); + reqNumberRef.current += 1; + + const currentReqNumber = reqNumberRef.current; try { const data = await asyncCallback(...args); + if (currentReqNumber !== reqNumberRef.current) { + throw new Error('AsyncCallbackHook: Request replaced!'); + } if (alive()) { setState({ status: AsyncStatus.Success, @@ -54,10 +75,13 @@ export const useAsyncCallback = ( } return data; } catch (e) { + if (currentReqNumber !== reqNumberRef.current) { + throw new Error('AsyncCallbackHook: Request replaced!'); + } if (alive()) { setState({ status: AsyncStatus.Error, - error: e, + error: e as TError, }); } throw e; diff --git a/src/app/hooks/useAuthFlows.ts b/src/app/hooks/useAuthFlows.ts new file mode 100644 index 000000000..7bb7ddc55 --- /dev/null +++ b/src/app/hooks/useAuthFlows.ts @@ -0,0 +1,59 @@ +import { createContext, useContext } from 'react'; +import { IAuthData, MatrixError } from 'matrix-js-sdk'; +import { ILoginFlowsResponse } from 'matrix-js-sdk/lib/@types/auth'; + +export enum RegisterFlowStatus { + FlowRequired = 401, + InvalidRequest = 400, + RegistrationDisabled = 403, + RateLimited = 429, +} + +export type RegisterFlowsResponse = + | { + status: RegisterFlowStatus.FlowRequired; + data: IAuthData; + } + | { + status: Exclude; + }; + +export const parseRegisterErrResp = (matrixError: MatrixError): RegisterFlowsResponse => { + switch (matrixError.httpStatus) { + case RegisterFlowStatus.InvalidRequest: { + return { status: RegisterFlowStatus.InvalidRequest }; + } + case RegisterFlowStatus.RateLimited: { + return { status: RegisterFlowStatus.RateLimited }; + } + case RegisterFlowStatus.RegistrationDisabled: { + return { status: RegisterFlowStatus.RegistrationDisabled }; + } + case RegisterFlowStatus.FlowRequired: { + return { + status: RegisterFlowStatus.FlowRequired, + data: matrixError.data as IAuthData, + }; + } + default: { + return { status: RegisterFlowStatus.InvalidRequest }; + } + } +}; + +export type AuthFlows = { + loginFlows: ILoginFlowsResponse; + registerFlows: RegisterFlowsResponse; +}; + +const AuthFlowsContext = createContext(null); + +export const AuthFlowsProvider = AuthFlowsContext.Provider; + +export const useAuthFlows = (): AuthFlows => { + const authFlows = useContext(AuthFlowsContext); + if (!authFlows) { + throw new Error('Auth Flow info is not loaded!'); + } + return authFlows; +}; diff --git a/src/app/hooks/useAuthServer.ts b/src/app/hooks/useAuthServer.ts new file mode 100644 index 000000000..f77566f5f --- /dev/null +++ b/src/app/hooks/useAuthServer.ts @@ -0,0 +1,14 @@ +import { createContext, useContext } from 'react'; + +const AuthServerContext = createContext(null); + +export const AuthServerProvider = AuthServerContext.Provider; + +export const useAuthServer = (): string => { + const server = useContext(AuthServerContext); + if (server === null) { + throw new Error('Auth server is not provided!'); + } + + return server; +}; diff --git a/src/app/hooks/useAutoDiscoveryInfo.ts b/src/app/hooks/useAutoDiscoveryInfo.ts new file mode 100644 index 000000000..b2f8bcb56 --- /dev/null +++ b/src/app/hooks/useAutoDiscoveryInfo.ts @@ -0,0 +1,15 @@ +import { createContext, useContext } from 'react'; +import { AutoDiscoveryInfo } from '../cs-api'; + +const AutoDiscoverInfoContext = createContext(null); + +export const AutoDiscoveryInfoProvider = AutoDiscoverInfoContext.Provider; + +export const useAutoDiscoveryInfo = (): AutoDiscoveryInfo => { + const autoDiscoveryInfo = useContext(AutoDiscoverInfoContext); + if (!autoDiscoveryInfo) { + throw new Error('Auto Discovery Info not loaded'); + } + + return autoDiscoveryInfo; +}; diff --git a/src/app/hooks/useClientConfig.ts b/src/app/hooks/useClientConfig.ts new file mode 100644 index 000000000..8406668de --- /dev/null +++ b/src/app/hooks/useClientConfig.ts @@ -0,0 +1,33 @@ +import { createContext, useContext } from 'react'; + +export type ClientConfig = { + defaultHomeserver?: number; + homeserverList?: string[]; + allowCustomHomeservers?: boolean; + + hashRouter?: { + enabled?: boolean; + basename?: string; + }; +}; + +const ClientConfigContext = createContext(null); + +export const ClientConfigProvider = ClientConfigContext.Provider; + +export function useClientConfig(): ClientConfig { + const config = useContext(ClientConfigContext); + if (!config) throw new Error('Client config are not provided!'); + return config; +} + +export const clientDefaultServer = (clientConfig: ClientConfig): string => + clientConfig.homeserverList?.[clientConfig.defaultHomeserver ?? 0] ?? 'matrix.org'; + +export const clientAllowedServer = (clientConfig: ClientConfig, server: string): boolean => { + const { homeserverList, allowCustomHomeservers } = clientConfig; + + if (allowCustomHomeservers) return true; + + return homeserverList?.includes(server) === true; +}; diff --git a/src/app/hooks/useCrossSigningStatus.js b/src/app/hooks/useCrossSigningStatus.js index 61b69d1dc..845c54629 100644 --- a/src/app/hooks/useCrossSigningStatus.js +++ b/src/app/hooks/useCrossSigningStatus.js @@ -9,7 +9,7 @@ export function useCrossSigningStatus() { const [isCSEnabled, setIsCSEnabled] = useState(hasCrossSigningAccountData()); useEffect(() => { - if (isCSEnabled) return null; + if (isCSEnabled) return undefined; const handleAccountData = (event) => { if (event.getType() === 'm.cross_signing.master') { setIsCSEnabled(true); diff --git a/src/app/hooks/useParsedLoginFlows.ts b/src/app/hooks/useParsedLoginFlows.ts new file mode 100644 index 000000000..14ecfb9dd --- /dev/null +++ b/src/app/hooks/useParsedLoginFlows.ts @@ -0,0 +1,38 @@ +import { useMemo } from 'react'; +import { ILoginFlow, IPasswordFlow, ISSOFlow, LoginFlow } from 'matrix-js-sdk/lib/@types/auth'; +import { WithRequiredProp } from '../../types/utils'; + +export type Required_SSOFlow = WithRequiredProp; +export const getSSOFlow = (loginFlows: LoginFlow[]): Required_SSOFlow | undefined => + loginFlows.find( + (flow) => + (flow.type === 'm.login.sso' || flow.type === 'm.login.cas') && + 'identity_providers' in flow && + Array.isArray(flow.identity_providers) && + flow.identity_providers.length > 0 + ) as Required_SSOFlow | undefined; + +export const getPasswordFlow = (loginFlows: LoginFlow[]): IPasswordFlow | undefined => + loginFlows.find((flow) => flow.type === 'm.login.password') as IPasswordFlow; +export const getTokenFlow = (loginFlows: LoginFlow[]): LoginFlow | undefined => + loginFlows.find((flow) => flow.type === 'm.login.token') as ILoginFlow & { + type: 'm.login.token'; + }; + +export type ParsedLoginFlows = { + password?: LoginFlow; + token?: LoginFlow; + sso?: Required_SSOFlow; +}; +export const useParsedLoginFlows = (loginFlows: LoginFlow[]) => { + const parsedFlow: ParsedLoginFlows = useMemo( + () => ({ + password: getPasswordFlow(loginFlows), + token: getTokenFlow(loginFlows), + sso: getSSOFlow(loginFlows), + }), + [loginFlows] + ); + + return parsedFlow; +}; diff --git a/src/app/hooks/usePasswordEmail.ts b/src/app/hooks/usePasswordEmail.ts new file mode 100644 index 000000000..37e96433f --- /dev/null +++ b/src/app/hooks/usePasswordEmail.ts @@ -0,0 +1,32 @@ +import { MatrixClient, MatrixError } from 'matrix-js-sdk'; +import { useCallback, useRef } from 'react'; +import { AsyncState, useAsyncCallback } from './useAsyncCallback'; +import { RequestEmailTokenCallback, RequestEmailTokenResponse } from './types'; + +export const usePasswordEmail = ( + mx: MatrixClient +): [AsyncState, RequestEmailTokenCallback] => { + const sendAttemptRef = useRef(1); + + const passwordEmailCallback: RequestEmailTokenCallback = useCallback( + async (email, clientSecret, nextLink) => { + const sendAttempt = sendAttemptRef.current; + sendAttemptRef.current += 1; + const result = await mx.requestPasswordEmailToken(email, clientSecret, sendAttempt, nextLink); + return { + email, + clientSecret, + result, + }; + }, + [mx] + ); + + const [passwordEmailState, passwordEmail] = useAsyncCallback< + RequestEmailTokenResponse, + MatrixError, + Parameters + >(passwordEmailCallback); + + return [passwordEmailState, passwordEmail]; +}; diff --git a/src/app/hooks/usePathWithOrigin.ts b/src/app/hooks/usePathWithOrigin.ts new file mode 100644 index 000000000..4430d06c0 --- /dev/null +++ b/src/app/hooks/usePathWithOrigin.ts @@ -0,0 +1,26 @@ +import { useMemo } from 'react'; +import { useClientConfig } from './useClientConfig'; +import { trimLeadingSlash, trimSlash, trimTrailingSlash } from '../utils/common'; + +export const usePathWithOrigin = (path: string): string => { + const { hashRouter } = useClientConfig(); + const { origin } = window.location; + + const pathWithOrigin = useMemo(() => { + let url: string = trimSlash(origin); + + url += `/${trimSlash(import.meta.env.BASE_URL ?? '')}`; + url = trimTrailingSlash(url); + + if (hashRouter?.enabled) { + url += `/#/${trimSlash(hashRouter.basename ?? '')}`; + url = trimTrailingSlash(url); + } + + url += `/${trimLeadingSlash(path)}`; + + return url; + }, [path, hashRouter, origin]); + + return pathWithOrigin; +}; diff --git a/src/app/hooks/useRegisterEmail.ts b/src/app/hooks/useRegisterEmail.ts new file mode 100644 index 000000000..d29c9e6d1 --- /dev/null +++ b/src/app/hooks/useRegisterEmail.ts @@ -0,0 +1,32 @@ +import { MatrixClient, MatrixError } from 'matrix-js-sdk'; +import { useCallback, useRef } from 'react'; +import { AsyncState, useAsyncCallback } from './useAsyncCallback'; +import { RequestEmailTokenCallback, RequestEmailTokenResponse } from './types'; + +export const useRegisterEmail = ( + mx: MatrixClient +): [AsyncState, RequestEmailTokenCallback] => { + const sendAttemptRef = useRef(1); + + const registerEmailCallback: RequestEmailTokenCallback = useCallback( + async (email, clientSecret, nextLink) => { + const sendAttempt = sendAttemptRef.current; + sendAttemptRef.current += 1; + const result = await mx.requestRegisterEmailToken(email, clientSecret, sendAttempt, nextLink); + return { + email, + clientSecret, + result, + }; + }, + [mx] + ); + + const [registerEmailState, registerEmail] = useAsyncCallback< + RequestEmailTokenResponse, + MatrixError, + Parameters + >(registerEmailCallback); + + return [registerEmailState, registerEmail]; +}; diff --git a/src/app/hooks/useSpecVersions.ts b/src/app/hooks/useSpecVersions.ts new file mode 100644 index 000000000..42403c61c --- /dev/null +++ b/src/app/hooks/useSpecVersions.ts @@ -0,0 +1,12 @@ +import { createContext, useContext } from 'react'; +import { SpecVersions } from '../cs-api'; + +const SpecVersionsContext = createContext(null); + +export const SpecVersionsProvider = SpecVersionsContext.Provider; + +export function useSpecVersions(): SpecVersions { + const versions = useContext(SpecVersionsContext); + if (!versions) throw new Error('Server versions are not provided!'); + return versions; +} diff --git a/src/app/hooks/useUIAFlows.ts b/src/app/hooks/useUIAFlows.ts new file mode 100644 index 000000000..22acd6bac --- /dev/null +++ b/src/app/hooks/useUIAFlows.ts @@ -0,0 +1,96 @@ +import { AuthType, IAuthData, UIAFlow } from 'matrix-js-sdk'; +import { useCallback, useMemo } from 'react'; +import { + getSupportedUIAFlows, + getUIACompleted, + getUIAError, + getUIAErrorCode, + getUIAParams, + getUIASession, +} from '../utils/matrix-uia'; + +export const SUPPORTED_FLOW_TYPES = [ + AuthType.Dummy, + AuthType.Password, + AuthType.Email, + AuthType.Terms, + AuthType.Recaptcha, + AuthType.RegistrationToken, +] as const; + +export const useSupportedUIAFlows = (uiaFlows: UIAFlow[], supportedStages: string[]): UIAFlow[] => + useMemo(() => getSupportedUIAFlows(uiaFlows, supportedStages), [uiaFlows, supportedStages]); + +export const useUIACompleted = (authData: IAuthData): string[] => + useMemo(() => getUIACompleted(authData), [authData]); + +export const useUIAParams = (authData: IAuthData) => + useMemo(() => getUIAParams(authData), [authData]); + +export const useUIASession = (authData: IAuthData) => + useMemo(() => getUIASession(authData), [authData]); + +export const useUIAErrorCode = (authData: IAuthData) => + useMemo(() => getUIAErrorCode(authData), [authData]); + +export const useUIAError = (authData: IAuthData) => + useMemo(() => getUIAError(authData), [authData]); + +export type StageInfo = Record; +export type AuthStageData = { + type: string; + info?: StageInfo; + session?: string; + errorCode?: string; + error?: string; +}; +export type AuthStageDataGetter = () => AuthStageData | undefined; + +export type UIAFlowInterface = { + getStageToComplete: AuthStageDataGetter; + hasStage: (stageType: string) => boolean; + getStageInfo: (stageType: string) => StageInfo | undefined; +}; +export const useUIAFlow = (authData: IAuthData, uiaFlow: UIAFlow): UIAFlowInterface => { + const completed = useUIACompleted(authData); + const params = useUIAParams(authData); + const session = useUIASession(authData); + const errorCode = useUIAErrorCode(authData); + const error = useUIAError(authData); + + const getStageToComplete: AuthStageDataGetter = useCallback(() => { + const { stages } = uiaFlow; + const nextStage = stages.find((stage) => !completed.includes(stage)); + if (!nextStage) return undefined; + + const info = params[nextStage]; + + return { + type: nextStage, + info, + session, + errorCode, + error, + }; + }, [uiaFlow, completed, params, errorCode, error, session]); + + const hasStage = useCallback( + (stageType: string): boolean => uiaFlow.stages.includes(stageType), + [uiaFlow] + ); + + const getStageInfo = useCallback( + (stageType: string): StageInfo | undefined => { + if (!hasStage(stageType)) return undefined; + + return params[stageType]; + }, + [hasStage, params] + ); + + return { + getStageToComplete, + hasStage, + getStageInfo, + }; +}; diff --git a/src/app/molecules/room-aliases/RoomAliases.jsx b/src/app/molecules/room-aliases/RoomAliases.jsx index 201c523ae..d573f7d6a 100644 --- a/src/app/molecules/room-aliases/RoomAliases.jsx +++ b/src/app/molecules/room-aliases/RoomAliases.jsx @@ -110,7 +110,9 @@ function RoomAliases({ roomId }) { const canPublishAlias = room.currentState.maySendStateEvent('m.room.canonical_alias', userId); - useEffect(() => isMountedStore.setItem(true), []); + useEffect(() => { + isMountedStore.setItem(true) + }, []); useEffect(() => { let isUnmounted = false; diff --git a/src/app/molecules/room-history-visibility/RoomHistoryVisibility.jsx b/src/app/molecules/room-history-visibility/RoomHistoryVisibility.jsx index 6a72a99bb..d9dd9540f 100644 --- a/src/app/molecules/room-history-visibility/RoomHistoryVisibility.jsx +++ b/src/app/molecules/room-history-visibility/RoomHistoryVisibility.jsx @@ -49,7 +49,9 @@ function useVisibility(roomId) { const room = mx.getRoom(roomId); const [activeType, setActiveType] = useState(room.getHistoryVisibility()); - useEffect(() => setActiveType(room.getHistoryVisibility()), [roomId]); + useEffect(() => { + setActiveType(room.getHistoryVisibility()); + }, [roomId]); const setVisibility = useCallback((item) => { if (item.type === activeType.type) return; diff --git a/src/app/molecules/room-notification/RoomNotification.jsx b/src/app/molecules/room-notification/RoomNotification.jsx index 1c088e5f0..4adb1169e 100644 --- a/src/app/molecules/room-notification/RoomNotification.jsx +++ b/src/app/molecules/room-notification/RoomNotification.jsx @@ -103,7 +103,9 @@ function setRoomNotifType(roomId, newType) { function useNotifications(roomId) { const { notifications } = initMatrix; const [activeType, setActiveType] = useState(notifications.getNotiType(roomId)); - useEffect(() => setActiveType(notifications.getNotiType(roomId)), [roomId]); + useEffect(() => { + setActiveType(notifications.getNotiType(roomId)); + }, [roomId]); const setNotification = useCallback((item) => { if (item.type === activeType.type) return; diff --git a/src/app/molecules/room-search/RoomSearch.jsx b/src/app/molecules/room-search/RoomSearch.jsx index 2612aed13..6009649f1 100644 --- a/src/app/molecules/room-search/RoomSearch.jsx +++ b/src/app/molecules/room-search/RoomSearch.jsx @@ -29,7 +29,9 @@ function useRoomSearch(roomId) { const mountStore = useStore(roomId); const mx = initMatrix.matrixClient; - useEffect(() => mountStore.setItem(true), [roomId]); + useEffect(() => { + mountStore.setItem(true) + }, [roomId]); useEffect(() => { if (searchData?.results?.length > 0) { diff --git a/src/app/molecules/room-visibility/RoomVisibility.jsx b/src/app/molecules/room-visibility/RoomVisibility.jsx index 7a8528765..a5e8e2d08 100644 --- a/src/app/molecules/room-visibility/RoomVisibility.jsx +++ b/src/app/molecules/room-visibility/RoomVisibility.jsx @@ -50,7 +50,9 @@ function useVisibility(roomId) { const room = mx.getRoom(roomId); const [activeType, setActiveType] = useState(room.getJoinRule()); - useEffect(() => setActiveType(room.getJoinRule()), [roomId]); + useEffect(() => { + setActiveType(room.getJoinRule()); + }, [roomId]); const setNotification = useCallback((item) => { if (item.type === activeType.type) return; diff --git a/src/app/organisms/emoji-verification/EmojiVerification.jsx b/src/app/organisms/emoji-verification/EmojiVerification.jsx index 6fe81cddf..3ae1f2948 100644 --- a/src/app/organisms/emoji-verification/EmojiVerification.jsx +++ b/src/app/organisms/emoji-verification/EmojiVerification.jsx @@ -80,7 +80,7 @@ function EmojiVerificationContent({ data, requestClose }) { } }; - if (request === null) return null; + if (request === null) return undefined; const req = request; req.on('change', handleChange); return () => { diff --git a/src/app/organisms/room/message/UrlPreviewCard.tsx b/src/app/organisms/room/message/UrlPreviewCard.tsx index 9ae4d298b..b085e184a 100644 --- a/src/app/organisms/room/message/UrlPreviewCard.tsx +++ b/src/app/organisms/room/message/UrlPreviewCard.tsx @@ -23,7 +23,10 @@ export const UrlPreviewCard = as<'div', { url: string; ts: number }>( const [previewStatus, loadPreview] = useAsyncCallback( useCallback(() => mx.getUrlPreview(url, ts), [url, ts, mx]) ); - if (previewStatus.status === AsyncStatus.Idle) loadPreview(); + + useEffect(() => { + loadPreview(); + }, [loadPreview]); if (previewStatus.status === AsyncStatus.Error) return null; diff --git a/src/app/organisms/space-manage/SpaceManage.jsx b/src/app/organisms/space-manage/SpaceManage.jsx index cf042da46..60f00ad31 100644 --- a/src/app/organisms/space-manage/SpaceManage.jsx +++ b/src/app/organisms/space-manage/SpaceManage.jsx @@ -302,7 +302,9 @@ function SpaceManageContent({ roomId, requestClose }) { }; }, [roomId]); - useEffect(() => setSelected([]), [spacePath]); + useEffect(() => { + setSelected([]); + }, [spacePath]); const handleSelected = (selectedRoomId) => { const newSelected = [...selected]; diff --git a/src/app/pages/App.jsx b/src/app/pages/App.jsx deleted file mode 100644 index 2828d7be8..000000000 --- a/src/app/pages/App.jsx +++ /dev/null @@ -1,17 +0,0 @@ -import React, { StrictMode } from 'react'; -import { Provider } from 'jotai'; - -import { isAuthenticated } from '../../client/state/auth'; - -import Auth from '../templates/auth/Auth'; -import Client from '../templates/client/Client'; - -function App() { - return ( - - {isAuthenticated() ? : } - - ); -} - -export default App; diff --git a/src/app/pages/App.tsx b/src/app/pages/App.tsx new file mode 100644 index 000000000..6cefe999c --- /dev/null +++ b/src/app/pages/App.tsx @@ -0,0 +1,82 @@ +import React from 'react'; +import { Provider as JotaiProvider } from 'jotai'; +import { + Route, + RouterProvider, + createBrowserRouter, + createHashRouter, + createRoutesFromElements, + redirect, +} from 'react-router-dom'; + +import { ClientConfigLoader } from '../components/ClientConfigLoader'; +import { ClientConfig, ClientConfigProvider } from '../hooks/useClientConfig'; +import { AuthLayout, Login, Register, ResetPassword, authLayoutLoader } from './auth'; +import { LOGIN_PATH, REGISTER_PATH, RESET_PASSWORD_PATH, ROOT_PATH } from './paths'; +import { isAuthenticated } from '../../client/state/auth'; +import Client from '../templates/client/Client'; +import { getLoginPath } from './pathUtils'; +import { ConfigConfigError, ConfigConfigLoading } from './ConfigConfig'; + +const createRouter = (clientConfig: ClientConfig) => { + const { hashRouter } = clientConfig; + + const routes = createRoutesFromElements( + + { + if (isAuthenticated()) return redirect('/home'); + return redirect(getLoginPath()); + }} + /> + }> + } /> + } /> + } /> + + + { + if (!isAuthenticated()) return redirect(getLoginPath()); + return null; + }} + > + } /> + direct

          } /> + :spaceIdOrAlias

          } /> + explore

          } /> +
          + Page not found

          } /> +
          + ); + + if (hashRouter?.enabled) { + return createHashRouter(routes, { basename: hashRouter.basename }); + } + return createBrowserRouter(routes, { + basename: import.meta.env.BASE_URL, + }); +}; + +// TODO: app crash boundary +function App() { + return ( + } + error={(err, retry, ignore) => ( + + )} + > + {(clientConfig) => ( + + + + + + )} + + ); +} + +export default App; diff --git a/src/app/pages/ConfigConfig.tsx b/src/app/pages/ConfigConfig.tsx new file mode 100644 index 000000000..dbcdca736 --- /dev/null +++ b/src/app/pages/ConfigConfig.tsx @@ -0,0 +1,53 @@ +import { Box, Button, Dialog, Spinner, Text, color, config } from 'folds'; +import React from 'react'; +import { SplashScreen } from '../components/splash-screen'; + +export function ConfigConfigLoading() { + return ( + + + + Heating up + + + ); +} + +type ConfigConfigErrorProps = { + error: unknown; + retry: () => void; + ignore: () => void; +}; +export function ConfigConfigError({ error, retry, ignore }: ConfigConfigErrorProps) { + return ( + + + + + + Failed to load client configuration file. + {typeof error === 'object' && + error && + 'message' in error && + typeof error.message === 'string' && ( + + {error.message} + + )} + + + + + + + + ); +} diff --git a/src/app/pages/auth/AuthFooter.tsx b/src/app/pages/auth/AuthFooter.tsx new file mode 100644 index 000000000..645416183 --- /dev/null +++ b/src/app/pages/auth/AuthFooter.tsx @@ -0,0 +1,28 @@ +import React from 'react'; +import { Box, Text } from 'folds'; +import * as css from './styles.css'; + +export function AuthFooter() { + return ( + + + About + + + v3.2.0 + + + Twitter + + + Powered by Matrix + + + ); +} diff --git a/src/app/pages/auth/AuthLayout.tsx b/src/app/pages/auth/AuthLayout.tsx new file mode 100644 index 000000000..c58ecdd5f --- /dev/null +++ b/src/app/pages/auth/AuthLayout.tsx @@ -0,0 +1,215 @@ +import React, { useCallback, useEffect } from 'react'; +import { Box, Header, Scroll, Spinner, Text, color } from 'folds'; +import { + LoaderFunction, + Outlet, + generatePath, + matchPath, + redirect, + useLocation, + useNavigate, + useParams, +} from 'react-router-dom'; +import classNames from 'classnames'; + +import { AuthFooter } from './AuthFooter'; +import * as css from './styles.css'; +import * as PatternsCss from '../../styles/Patterns.css'; +import { isAuthenticated } from '../../../client/state/auth'; +import { + clientAllowedServer, + clientDefaultServer, + useClientConfig, +} from '../../hooks/useClientConfig'; +import { AsyncStatus, useAsyncCallback } from '../../hooks/useAsyncCallback'; +import { LOGIN_PATH, REGISTER_PATH } from '../paths'; +import CinnySVG from '../../../../public/res/svg/cinny.svg'; +import { ServerPicker } from './ServerPicker'; +import { AutoDiscoveryAction, autoDiscovery } from '../../cs-api'; +import { SpecVersionsLoader } from '../../components/SpecVersionsLoader'; +import { SpecVersionsProvider } from '../../hooks/useSpecVersions'; +import { AutoDiscoveryInfoProvider } from '../../hooks/useAutoDiscoveryInfo'; +import { AuthFlowsLoader } from '../../components/AuthFlowsLoader'; +import { AuthFlowsProvider } from '../../hooks/useAuthFlows'; +import { AuthServerProvider } from '../../hooks/useAuthServer'; + +export const authLayoutLoader: LoaderFunction = () => { + if (isAuthenticated()) { + return redirect('/'); + } + + return null; +}; + +const currentAuthPath = (pathname: string): string => { + if (matchPath(LOGIN_PATH, pathname)) { + return LOGIN_PATH; + } + if (matchPath(REGISTER_PATH, pathname)) { + return REGISTER_PATH; + } + return LOGIN_PATH; +}; + +function AuthLayoutLoading({ message }: { message: string }) { + return ( + + + + {message} + + + ); +} + +function AuthLayoutError({ message }: { message: string }) { + return ( + + + {message} + + + ); +} + +export function AuthLayout() { + const navigate = useNavigate(); + const location = useLocation(); + const { server: urlEncodedServer } = useParams(); + + const clientConfig = useClientConfig(); + + const defaultServer = clientDefaultServer(clientConfig); + let server: string = urlEncodedServer ? decodeURIComponent(urlEncodedServer) : defaultServer; + + if (!clientAllowedServer(clientConfig, server)) { + server = defaultServer; + } + + const [discoveryState, discoverServer] = useAsyncCallback( + useCallback(async (serverName: string) => { + const response = await autoDiscovery(fetch, serverName); + return { + serverName, + response, + }; + }, []) + ); + + useEffect(() => { + if (server) discoverServer(server); + }, [discoverServer, server]); + + // if server is mismatches with path server, update path + useEffect(() => { + if (!urlEncodedServer || decodeURIComponent(urlEncodedServer) !== server) { + navigate( + generatePath(currentAuthPath(location.pathname), { + server: encodeURIComponent(server), + }), + { replace: true } + ); + } + }, [urlEncodedServer, navigate, location, server]); + + const selectServer = useCallback( + (newServer: string) => { + if (newServer === server) { + if (discoveryState.status === AsyncStatus.Loading) return; + discoverServer(server); + return; + } + navigate( + generatePath(currentAuthPath(location.pathname), { server: encodeURIComponent(newServer) }) + ); + }, + [navigate, location, discoveryState, server, discoverServer] + ); + + const [autoDiscoveryError, autoDiscoveryInfo] = + discoveryState.status === AsyncStatus.Success ? discoveryState.data.response : []; + + return ( + + + +
          + + Cinny Logo + Cinny + +
          + + + + Homeserver + + + + {discoveryState.status === AsyncStatus.Loading && ( + + )} + {discoveryState.status === AsyncStatus.Error && ( + + )} + {autoDiscoveryError?.action === AutoDiscoveryAction.FAIL_PROMPT && ( + + )} + {autoDiscoveryError?.action === AutoDiscoveryAction.FAIL_ERROR && ( + + )} + {discoveryState.status === AsyncStatus.Success && autoDiscoveryInfo && ( + + + ( + + )} + error={() => ( + + )} + > + {(specVersions) => ( + + ( + + )} + error={() => ( + + )} + > + {(authFlows) => ( + + + + )} + + + )} + + + + )} + +
          + +
          +
          + ); +} diff --git a/src/app/pages/auth/FiledError.tsx b/src/app/pages/auth/FiledError.tsx new file mode 100644 index 000000000..d96fc8725 --- /dev/null +++ b/src/app/pages/auth/FiledError.tsx @@ -0,0 +1,13 @@ +import React from 'react'; +import { Box, Icon, Icons, color, Text } from 'folds'; + +export function FieldError({ message }: { message: string }) { + return ( + + + + {message} + + + ); +} diff --git a/src/app/pages/auth/OrDivider.tsx b/src/app/pages/auth/OrDivider.tsx new file mode 100644 index 000000000..629d3f520 --- /dev/null +++ b/src/app/pages/auth/OrDivider.tsx @@ -0,0 +1,12 @@ +import React from 'react'; +import { Box, Line, Text } from 'folds'; + +export function OrDivider() { + return ( + + + OR + + + ); +} diff --git a/src/app/pages/auth/SSOLogin.tsx b/src/app/pages/auth/SSOLogin.tsx new file mode 100644 index 000000000..a9c1c54bc --- /dev/null +++ b/src/app/pages/auth/SSOLogin.tsx @@ -0,0 +1,68 @@ +import { Avatar, AvatarImage, Box, Button, Text } from 'folds'; +import { IIdentityProvider, createClient } from 'matrix-js-sdk'; +import React, { useMemo } from 'react'; +import { useAutoDiscoveryInfo } from '../../hooks/useAutoDiscoveryInfo'; + +type SSOLoginProps = { + providers: IIdentityProvider[]; + asIcons?: boolean; + redirectUrl: string; +}; +export function SSOLogin({ providers, redirectUrl, asIcons }: SSOLoginProps) { + const discovery = useAutoDiscoveryInfo(); + const baseUrl = discovery['m.homeserver'].base_url; + const mx = useMemo(() => createClient({ baseUrl }), [baseUrl]); + + const getSSOIdUrl = (ssoId: string): string => mx.getSsoLoginUrl(redirectUrl, 'sso', ssoId); + + return ( + + {providers.map((provider) => { + const { id, name, icon } = provider; + const iconUrl = icon && mx.mxcUrlToHttp(icon, 96, 96, 'crop', false); + + const buttonTitle = `Continue with ${name}`; + + if (iconUrl && asIcons) { + return ( + + + + ); + } + + return ( + + ); + })} + + ); +} diff --git a/src/app/pages/auth/ServerPicker.tsx b/src/app/pages/auth/ServerPicker.tsx new file mode 100644 index 000000000..5f5dcf65c --- /dev/null +++ b/src/app/pages/auth/ServerPicker.tsx @@ -0,0 +1,140 @@ +import React, { + ChangeEventHandler, + KeyboardEventHandler, + MouseEventHandler, + useEffect, + useRef, + useState, +} from 'react'; +import { + Header, + Icon, + IconButton, + Icons, + Input, + Menu, + MenuItem, + PopOut, + Text, + config, +} from 'folds'; +import FocusTrap from 'focus-trap-react'; + +import { useDebounce } from '../../hooks/useDebounce'; + +export function ServerPicker({ + server, + serverList, + allowCustomServer, + onServerChange, +}: { + server: string; + serverList: string[]; + allowCustomServer?: boolean; + onServerChange: (server: string) => void; +}) { + const [serverMenu, setServerMenu] = useState(false); + const serverInputRef = useRef(null); + + useEffect(() => { + // sync input with it outside server changes + if (serverInputRef.current && serverInputRef.current.value !== server) { + serverInputRef.current.value = server; + } + }, [server]); + + const debounceServerSelect = useDebounce(onServerChange, { wait: 700 }); + + const handleServerChange: ChangeEventHandler = (evt) => { + const inputServer = evt.target.value.trim(); + if (inputServer) debounceServerSelect(inputServer); + }; + + const handleKeyDown: KeyboardEventHandler = (evt) => { + if (evt.key === 'ArrowDown') { + evt.preventDefault(); + setServerMenu(true); + } + if (evt.key === 'Enter') { + evt.preventDefault(); + const inputServer = evt.currentTarget.value.trim(); + if (inputServer) onServerChange(inputServer); + } + }; + + const handleServerSelect: MouseEventHandler = (evt) => { + const selectedServer = evt.currentTarget.getAttribute('data-server'); + if (selectedServer) { + onServerChange(selectedServer); + } + setServerMenu(false); + }; + + return ( + setServerMenu(true)} + after={ + serverList.length === 0 || (serverList.length === 1 && !allowCustomServer) ? undefined : ( + setServerMenu(false), + clickOutsideDeactivates: true, + isKeyForward: (evt: KeyboardEvent) => evt.key === 'ArrowDown', + isKeyBackward: (evt: KeyboardEvent) => evt.key === 'ArrowUp', + }} + > + +
          + Homeserver List +
          +
          + {serverList?.map((serverName) => ( + + {serverName} + + ))} +
          +
          + + } + > + {(anchorRef) => ( + setServerMenu(true)} + variant={allowCustomServer ? 'Background' : 'Surface'} + size="300" + aria-pressed={serverMenu} + radii="300" + > + + + )} +
          + ) + } + /> + ); +} diff --git a/src/app/pages/auth/index.ts b/src/app/pages/auth/index.ts new file mode 100644 index 000000000..c4bd0476e --- /dev/null +++ b/src/app/pages/auth/index.ts @@ -0,0 +1,4 @@ +export * from './AuthLayout'; +export * from './login'; +export * from './register'; +export * from './reset-password'; diff --git a/src/app/pages/auth/login/Login.tsx b/src/app/pages/auth/login/Login.tsx new file mode 100644 index 000000000..29a7b0ce7 --- /dev/null +++ b/src/app/pages/auth/login/Login.tsx @@ -0,0 +1,73 @@ +import React from 'react'; +import { Box, Text, color } from 'folds'; +import { Link, useSearchParams } from 'react-router-dom'; +import { useAuthFlows } from '../../../hooks/useAuthFlows'; +import { useAuthServer } from '../../../hooks/useAuthServer'; +import { useParsedLoginFlows } from '../../../hooks/useParsedLoginFlows'; +import { PasswordLoginForm } from './PasswordLoginForm'; +import { SSOLogin } from '../SSOLogin'; +import { TokenLogin } from './TokenLogin'; +import { OrDivider } from '../OrDivider'; +import { getLoginPath, getRegisterPath } from '../../pathUtils'; +import { usePathWithOrigin } from '../../../hooks/usePathWithOrigin'; +import { LoginPathSearchParams } from '../../paths'; + +const getLoginSearchParams = (searchParams: URLSearchParams): LoginPathSearchParams => ({ + username: searchParams.get('username') ?? undefined, + email: searchParams.get('email') ?? undefined, + loginToken: searchParams.get('loginToken') ?? undefined, +}); + +export function Login() { + const server = useAuthServer(); + const { loginFlows } = useAuthFlows(); + const [searchParams] = useSearchParams(); + const loginSearchParams = getLoginSearchParams(searchParams); + const ssoRedirectUrl = usePathWithOrigin(getLoginPath(server)); + + const parsedFlows = useParsedLoginFlows(loginFlows.flows); + + return ( + + + Login + + {parsedFlows.token && loginSearchParams.loginToken && ( + + )} + {parsedFlows.password && ( + <> + + + {parsedFlows.sso && } + + )} + {parsedFlows.sso && ( + <> + 2 + } + /> + + + )} + {!parsedFlows.password && !parsedFlows.sso && ( + <> + + {`This client does not support login on "${server}" homeserver. Password and SSO based login method not found.`} + + + + )} + + Do not have an account? Register + + + ); +} diff --git a/src/app/pages/auth/login/PasswordLoginForm.tsx b/src/app/pages/auth/login/PasswordLoginForm.tsx new file mode 100644 index 000000000..ea52aad8c --- /dev/null +++ b/src/app/pages/auth/login/PasswordLoginForm.tsx @@ -0,0 +1,272 @@ +import React, { FormEventHandler, useCallback, useState } from 'react'; +import { + Box, + Button, + Header, + Icon, + IconButton, + Icons, + Input, + Menu, + Overlay, + OverlayBackdrop, + OverlayCenter, + PopOut, + Spinner, + Text, + config, +} from 'folds'; +import FocusTrap from 'focus-trap-react'; +import { Link } from 'react-router-dom'; +import { MatrixError } from 'matrix-js-sdk'; +import { getMxIdLocalPart, getMxIdServer, isUserId } from '../../../utils/matrix'; +import { EMAIL_REGEX } from '../../../utils/regex'; +import { useAutoDiscoveryInfo } from '../../../hooks/useAutoDiscoveryInfo'; +import { AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback'; +import { useAuthServer } from '../../../hooks/useAuthServer'; +import { useClientConfig } from '../../../hooks/useClientConfig'; +import { + CustomLoginResponse, + LoginError, + factoryGetBaseUrl, + login, + useLoginComplete, +} from './loginUtil'; +import { PasswordInput } from '../../../components/password-input/PasswordInput'; +import { FieldError } from '../FiledError'; +import { getResetPasswordPath } from '../../pathUtils'; + +function UsernameHint({ server }: { server: string }) { + const [open, setOpen] = useState(false); + return ( + setOpen(false), + clickOutsideDeactivates: true, + }} + > + +
          + Hint +
          + + + + Username: + {' '} + johndoe + + + + Matrix ID: + + {` @johndoe:${server}`} + + + + Email: + + {` johndoe@${server}`} + + +
          + + } + > + {(targetRef) => ( + setOpen(true)} + ref={targetRef} + type="button" + variant="Background" + size="300" + radii="300" + aria-pressed={open} + > + + + )} +
          + ); +} + +type PasswordLoginFormProps = { + defaultUsername?: string; + defaultEmail?: string; +}; +export function PasswordLoginForm({ defaultUsername, defaultEmail }: PasswordLoginFormProps) { + const server = useAuthServer(); + const clientConfig = useClientConfig(); + + const serverDiscovery = useAutoDiscoveryInfo(); + const baseUrl = serverDiscovery['m.homeserver'].base_url; + + const [loginState, startLogin] = useAsyncCallback< + CustomLoginResponse, + MatrixError, + Parameters + >(useCallback(login, [])); + + useLoginComplete(loginState.status === AsyncStatus.Success ? loginState.data : undefined); + + const handleUsernameLogin = (username: string, password: string) => { + startLogin(baseUrl, { + type: 'm.login.password', + identifier: { + type: 'm.id.user', + user: username, + }, + password, + initial_device_display_name: 'Cinny Web', + }); + }; + + const handleMxIdLogin = async (mxId: string, password: string) => { + const mxIdServer = getMxIdServer(mxId); + const mxIdUsername = getMxIdLocalPart(mxId); + if (!mxIdServer || !mxIdUsername) return; + + const getBaseUrl = factoryGetBaseUrl(clientConfig, mxIdServer); + + startLogin(getBaseUrl, { + type: 'm.login.password', + identifier: { + type: 'm.id.user', + user: mxIdUsername, + }, + password, + initial_device_display_name: 'Cinny Web', + }); + }; + const handleEmailLogin = (email: string, password: string) => { + startLogin(baseUrl, { + type: 'm.login.password', + identifier: { + type: 'm.id.thirdparty', + medium: 'email', + address: email, + }, + password, + initial_device_display_name: 'Cinny Web', + }); + }; + + const handleSubmit: FormEventHandler = (evt) => { + evt.preventDefault(); + const { usernameInput, passwordInput } = evt.target as HTMLFormElement & { + usernameInput: HTMLInputElement; + passwordInput: HTMLInputElement; + }; + + const username = usernameInput.value.trim(); + const password = passwordInput.value; + if (!username) { + usernameInput.focus(); + return; + } + if (!password) { + passwordInput.focus(); + return; + } + + if (isUserId(username)) { + handleMxIdLogin(username, password); + return; + } + if (EMAIL_REGEX.test(username)) { + handleEmailLogin(username, password); + return; + } + handleUsernameLogin(username, password); + }; + + return ( + + + + Username + + } + /> + {loginState.status === AsyncStatus.Error && ( + <> + {loginState.error.errcode === LoginError.ServerNotAllowed && ( + + )} + {loginState.error.errcode === LoginError.InvalidServer && ( + + )} + + )} + + + + Password + + + + {loginState.status === AsyncStatus.Error && ( + <> + {loginState.error.errcode === LoginError.Forbidden && ( + + )} + {loginState.error.errcode === LoginError.UserDeactivated && ( + + )} + {loginState.error.errcode === LoginError.InvalidRequest && ( + + )} + {loginState.error.errcode === LoginError.RateLimited && ( + + )} + {loginState.error.errcode === LoginError.Unknown && ( + + )} + + )} + + + Forget Password? + + + + + + + } + > + + + + + + ); +} diff --git a/src/app/pages/auth/login/TokenLogin.tsx b/src/app/pages/auth/login/TokenLogin.tsx new file mode 100644 index 000000000..761d5dc53 --- /dev/null +++ b/src/app/pages/auth/login/TokenLogin.tsx @@ -0,0 +1,94 @@ +import { + Box, + Icon, + Icons, + Overlay, + OverlayBackdrop, + OverlayCenter, + Spinner, + Text, + color, + config, +} from 'folds'; +import React, { useCallback, useEffect } from 'react'; +import { MatrixError } from 'matrix-js-sdk'; +import { useAutoDiscoveryInfo } from '../../../hooks/useAutoDiscoveryInfo'; +import { AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback'; +import { CustomLoginResponse, LoginError, login, useLoginComplete } from './loginUtil'; + +function LoginTokenError({ message }: { message: string }) { + return ( + + + + Token Login + + {message} + + + + ); +} + +type TokenLoginProps = { + token: string; +}; +export function TokenLogin({ token }: TokenLoginProps) { + const discovery = useAutoDiscoveryInfo(); + const baseUrl = discovery['m.homeserver'].base_url; + + const [loginState, startLogin] = useAsyncCallback< + CustomLoginResponse, + MatrixError, + Parameters + >(useCallback(login, [])); + + useEffect(() => { + startLogin(baseUrl, { + type: 'm.login.token', + token, + initial_device_display_name: 'Cinny Web', + }); + }, [baseUrl, token, startLogin]); + + useLoginComplete(loginState.status === AsyncStatus.Success ? loginState.data : undefined); + + return ( + <> + {loginState.status === AsyncStatus.Error && ( + <> + {loginState.error.errcode === LoginError.Forbidden && ( + + )} + {loginState.error.errcode === LoginError.UserDeactivated && ( + + )} + {loginState.error.errcode === LoginError.InvalidRequest && ( + + )} + {loginState.error.errcode === LoginError.RateLimited && ( + + )} + {loginState.error.errcode === LoginError.Unknown && ( + + )} + + )} + }> + + + + + + ); +} diff --git a/src/app/pages/auth/login/index.ts b/src/app/pages/auth/login/index.ts new file mode 100644 index 000000000..a10c3a83a --- /dev/null +++ b/src/app/pages/auth/login/index.ts @@ -0,0 +1 @@ +export * from './Login'; diff --git a/src/app/pages/auth/login/loginUtil.ts b/src/app/pages/auth/login/loginUtil.ts new file mode 100644 index 000000000..b2fd38709 --- /dev/null +++ b/src/app/pages/auth/login/loginUtil.ts @@ -0,0 +1,118 @@ +import to from 'await-to-js'; +import { LoginRequest, LoginResponse, MatrixError, createClient } from 'matrix-js-sdk'; +import { useEffect } from 'react'; +import { useNavigate } from 'react-router-dom'; +import { ClientConfig, clientAllowedServer } from '../../../hooks/useClientConfig'; +import { autoDiscovery, specVersions } from '../../../cs-api'; +import { updateLocalStore } from '../../../../client/action/auth'; +import { ROOT_PATH } from '../../paths'; +import { ErrorCode } from '../../../cs-errorcode'; + +export enum GetBaseUrlError { + NotAllow = 'NotAllow', + NotFound = 'NotFound', +} +export const factoryGetBaseUrl = (clientConfig: ClientConfig, server: string) => { + const getBaseUrl = async (): Promise => { + if (!clientAllowedServer(clientConfig, server)) { + throw new Error(GetBaseUrlError.NotAllow); + } + + const [, discovery] = await to(autoDiscovery(fetch, server)); + + let mxIdBaseUrl: string | undefined; + const [, discoveryInfo] = discovery ?? []; + + if (discoveryInfo) { + mxIdBaseUrl = discoveryInfo['m.homeserver'].base_url; + } + + if (!mxIdBaseUrl) { + throw new Error(GetBaseUrlError.NotFound); + } + const [, versions] = await to(specVersions(fetch, mxIdBaseUrl)); + if (!versions) { + throw new Error(GetBaseUrlError.NotFound); + } + return mxIdBaseUrl; + }; + return getBaseUrl; +}; + +export enum LoginError { + ServerNotAllowed = 'ServerNotAllowed', + InvalidServer = 'InvalidServer', + Forbidden = 'Forbidden', + UserDeactivated = 'UserDeactivated', + InvalidRequest = 'InvalidRequest', + RateLimited = 'RateLimited', + Unknown = 'Unknown', +} + +export type CustomLoginResponse = { + baseUrl: string; + response: LoginResponse; +}; +export const login = async ( + serverBaseUrl: string | (() => Promise), + data: LoginRequest +): Promise => { + const [urlError, url] = + typeof serverBaseUrl === 'function' ? await to(serverBaseUrl()) : [undefined, serverBaseUrl]; + if (urlError) { + throw new MatrixError({ + errcode: + urlError.message === GetBaseUrlError.NotAllow + ? LoginError.ServerNotAllowed + : LoginError.InvalidServer, + }); + } + + const mx = createClient({ baseUrl: url }); + const [err, res] = await to(mx.login(data.type, data)); + + if (err) { + if (err.httpStatus === 400) { + throw new MatrixError({ + errcode: LoginError.InvalidRequest, + }); + } + if (err.httpStatus === 429) { + throw new MatrixError({ + errcode: LoginError.RateLimited, + }); + } + if (err.errcode === ErrorCode.M_USER_DEACTIVATED) { + throw new MatrixError({ + errcode: LoginError.UserDeactivated, + }); + } + + if (err.httpStatus === 403) { + throw new MatrixError({ + errcode: LoginError.Forbidden, + }); + } + + throw new MatrixError({ + errcode: LoginError.Unknown, + }); + } + return { + baseUrl: url, + response: res, + }; +}; + +export const useLoginComplete = (data?: CustomLoginResponse) => { + const navigate = useNavigate(); + + useEffect(() => { + if (data) { + const { response: loginRes, baseUrl: loginBaseUrl } = data; + updateLocalStore(loginRes.access_token, loginRes.device_id, loginRes.user_id, loginBaseUrl); + // TODO: add after login redirect url + navigate(ROOT_PATH, { replace: true }); + } + }, [data, navigate]); +}; diff --git a/src/app/pages/auth/register/PasswordRegisterForm.tsx b/src/app/pages/auth/register/PasswordRegisterForm.tsx new file mode 100644 index 000000000..f4439dd6c --- /dev/null +++ b/src/app/pages/auth/register/PasswordRegisterForm.tsx @@ -0,0 +1,420 @@ +import { + Box, + Button, + Checkbox, + Input, + Overlay, + OverlayBackdrop, + OverlayCenter, + Spinner, + Text, + color, +} from 'folds'; +import React, { ChangeEventHandler, useCallback, useMemo, useState } from 'react'; +import { + AuthDict, + AuthType, + IAuthData, + MatrixError, + RegisterRequest, + UIAFlow, + createClient, +} from 'matrix-js-sdk'; +import { PasswordInput } from '../../../components/password-input/PasswordInput'; +import { + getLoginTermUrl, + getUIAFlowForStages, + hasStageInFlows, + requiredStageInFlows, +} from '../../../utils/matrix-uia'; +import { useUIACompleted, useUIAFlow, useUIAParams } from '../../../hooks/useUIAFlows'; +import { AsyncState, AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback'; +import { useAutoDiscoveryInfo } from '../../../hooks/useAutoDiscoveryInfo'; +import { RegisterError, RegisterResult, register, useRegisterComplete } from './registerUtil'; +import { FieldError } from '../FiledError'; +import { + AutoDummyStageDialog, + AutoTermsStageDialog, + EmailStageDialog, + ReCaptchaStageDialog, + RegistrationTokenStageDialog, +} from '../../../components/uia-stages'; +import { useRegisterEmail } from '../../../hooks/useRegisterEmail'; +import { ConfirmPasswordMatch } from '../../../components/ConfirmPasswordMatch'; +import { UIAFlowOverlay } from '../../../components/UIAFlowOverlay'; +import { RequestEmailTokenCallback, RequestEmailTokenResponse } from '../../../hooks/types'; + +export const SUPPORTED_REGISTER_STAGES = [ + AuthType.RegistrationToken, + AuthType.Terms, + AuthType.Recaptcha, + AuthType.Email, + AuthType.Dummy, +]; +type RegisterFormInputs = { + usernameInput: HTMLInputElement; + passwordInput: HTMLInputElement; + confirmPasswordInput: HTMLInputElement; + tokenInput?: HTMLInputElement; + emailInput?: HTMLInputElement; + termsInput?: HTMLInputElement; +}; + +type FormData = { + username: string; + password: string; + token?: string; + email?: string; + terms?: boolean; + clientSecret: string; +}; + +const pickStages = (uiaFlows: UIAFlow[], formData: FormData): string[] => { + const pickedStages: string[] = []; + if (formData.token) pickedStages.push(AuthType.RegistrationToken); + if (formData.email) pickedStages.push(AuthType.Email); + if (formData.terms) pickedStages.push(AuthType.Terms); + if (hasStageInFlows(uiaFlows, AuthType.Recaptcha)) { + pickedStages.push(AuthType.Recaptcha); + } + + return pickedStages; +}; + +type RegisterUIAFlowProps = { + formData: FormData; + flow: UIAFlow; + authData: IAuthData; + registerEmailState: AsyncState; + registerEmail: RequestEmailTokenCallback; + onRegister: (registerReqData: RegisterRequest) => void; +}; +function RegisterUIAFlow({ + formData, + flow, + authData, + registerEmailState, + registerEmail, + onRegister, +}: RegisterUIAFlowProps) { + const completed = useUIACompleted(authData); + const { getStageToComplete } = useUIAFlow(authData, flow); + + const stageToComplete = getStageToComplete(); + + const handleAuthDict = useCallback( + (authDict: AuthDict) => { + const { password, username } = formData; + onRegister({ + auth: authDict, + password, + username, + initial_device_display_name: 'Cinny Web', + }); + }, + [onRegister, formData] + ); + + const handleCancel = useCallback(() => { + window.location.reload(); + }, []); + + if (!stageToComplete) return null; + return ( + + {stageToComplete.type === AuthType.RegistrationToken && ( + + )} + {stageToComplete.type === AuthType.Terms && ( + + )} + {stageToComplete.type === AuthType.Recaptcha && ( + + )} + {stageToComplete.type === AuthType.Email && ( + + )} + {stageToComplete.type === AuthType.Dummy && ( + + )} + + ); +} + +type PasswordRegisterFormProps = { + authData: IAuthData; + uiaFlows: UIAFlow[]; + defaultUsername?: string; + defaultEmail?: string; + defaultRegisterToken?: string; +}; +export function PasswordRegisterForm({ + authData, + uiaFlows, + defaultUsername, + defaultEmail, + defaultRegisterToken, +}: PasswordRegisterFormProps) { + const serverDiscovery = useAutoDiscoveryInfo(); + const baseUrl = serverDiscovery['m.homeserver'].base_url; + const mx = useMemo(() => createClient({ baseUrl }), [baseUrl]); + const params = useUIAParams(authData); + const termUrl = getLoginTermUrl(params); + const [formData, setFormData] = useState(); + + const [ongoingFlow, setOngoingFlow] = useState(); + + const [registerEmailState, registerEmail] = useRegisterEmail(mx); + + const [registerState, handleRegister] = useAsyncCallback< + RegisterResult, + MatrixError, + [RegisterRequest] + >(useCallback(async (registerReqData) => register(mx, registerReqData), [mx])); + const [ongoingAuthData, customRegisterResp] = + registerState.status === AsyncStatus.Success ? registerState.data : []; + const registerError = + registerState.status === AsyncStatus.Error ? registerState.error : undefined; + + useRegisterComplete(customRegisterResp); + + const handleSubmit: ChangeEventHandler = (evt) => { + evt.preventDefault(); + const { + usernameInput, + passwordInput, + confirmPasswordInput, + emailInput, + tokenInput, + termsInput, + } = evt.target as HTMLFormElement & RegisterFormInputs; + const token = tokenInput?.value.trim(); + const username = usernameInput.value.trim(); + const password = passwordInput.value; + const confirmPassword = confirmPasswordInput.value; + if (password !== confirmPassword) { + return; + } + const email = emailInput?.value.trim(); + const terms = termsInput?.value === 'on'; + + if (!username) { + usernameInput.focus(); + return; + } + + const fData: FormData = { + username, + password, + token, + email, + terms, + clientSecret: mx.generateClientSecret(), + }; + const pickedStages = pickStages(uiaFlows, fData); + const pickedFlow = getUIAFlowForStages(uiaFlows, pickedStages); + setOngoingFlow(pickedFlow); + setFormData(fData); + handleRegister({ + username, + password, + auth: { + session: authData.session, + }, + initial_device_display_name: 'Cinny Web', + }); + }; + + return ( + <> + + + + Username + + + {registerError?.errcode === RegisterError.UserTaken && ( + + )} + {registerError?.errcode === RegisterError.UserInvalid && ( + + )} + {registerError?.errcode === RegisterError.UserExclusive && ( + + )} + + + {(match, doMatch, passRef, confPassRef) => ( + <> + + + Password + + + {registerError?.errcode === RegisterError.PasswordWeak && ( + + )} + {registerError?.errcode === RegisterError.PasswordShort && ( + + )} + + + + Confirm Password + + + + + )} + + {hasStageInFlows(uiaFlows, AuthType.RegistrationToken) && ( + + + {requiredStageInFlows(uiaFlows, AuthType.RegistrationToken) + ? 'Registration Token' + : 'Registration Token (Optional)'} + + + + )} + {hasStageInFlows(uiaFlows, AuthType.Email) && ( + + + {requiredStageInFlows(uiaFlows, AuthType.Email) ? 'Email' : 'Email (Optional)'} + + + + )} + + {hasStageInFlows(uiaFlows, AuthType.Terms) && termUrl && ( + + + + I accept server{' '} + + Terms and Conditions + + . + + + )} + {registerError?.errcode === RegisterError.RateLimited && ( + + )} + {registerError?.errcode === RegisterError.Forbidden && ( + + )} + {registerError?.errcode === RegisterError.InvalidRequest && ( + + )} + {registerError?.errcode === RegisterError.Unknown && ( + + )} + + + + {registerState.status === AsyncStatus.Success && + formData && + ongoingFlow && + ongoingAuthData && ( + + )} + {registerState.status === AsyncStatus.Loading && ( + }> + + + + + )} + + ); +} diff --git a/src/app/pages/auth/register/Register.tsx b/src/app/pages/auth/register/Register.tsx new file mode 100644 index 000000000..756b13b30 --- /dev/null +++ b/src/app/pages/auth/register/Register.tsx @@ -0,0 +1,95 @@ +import React from 'react'; +import { Box, Text, color } from 'folds'; +import { Link, useSearchParams } from 'react-router-dom'; +import { useAuthServer } from '../../../hooks/useAuthServer'; +import { RegisterFlowStatus, useAuthFlows } from '../../../hooks/useAuthFlows'; +import { useParsedLoginFlows } from '../../../hooks/useParsedLoginFlows'; +import { PasswordRegisterForm, SUPPORTED_REGISTER_STAGES } from '../register/PasswordRegisterForm'; +import { OrDivider } from '../OrDivider'; +import { SSOLogin } from '../SSOLogin'; +import { SupportedUIAFlowsLoader } from '../../../components/SupportedUIAFlowsLoader'; +import { getLoginPath } from '../../pathUtils'; +import { usePathWithOrigin } from '../../../hooks/usePathWithOrigin'; +import { RegisterPathSearchParams } from '../../paths'; + +const getRegisterSearchParams = (searchParams: URLSearchParams): RegisterPathSearchParams => ({ + username: searchParams.get('username') ?? undefined, + email: searchParams.get('email') ?? undefined, + token: searchParams.get('token') ?? undefined, +}); + +export function Register() { + const server = useAuthServer(); + const { loginFlows, registerFlows } = useAuthFlows(); + const [searchParams] = useSearchParams(); + const registerSearchParams = getRegisterSearchParams(searchParams); + const { sso } = useParsedLoginFlows(loginFlows.flows); + + // redirect to /login because only that path handle m.login.token + const ssoRedirectUrl = usePathWithOrigin(getLoginPath(server)); + + return ( + + + Register + + {registerFlows.status === RegisterFlowStatus.RegistrationDisabled && !sso && ( + + Registration has been disabled on this homeserver. + + )} + {registerFlows.status === RegisterFlowStatus.RateLimited && !sso && ( + + You have been rate-limited! Please try after some time. + + )} + {registerFlows.status === RegisterFlowStatus.InvalidRequest && !sso && ( + + Invalid Request! Failed to get any registration options. + + )} + {registerFlows.status === RegisterFlowStatus.FlowRequired && ( + <> + + {(supportedFlows) => + supportedFlows.length === 0 ? ( + + This application does not support registration on this homeserver. + + ) : ( + + ) + } + + + {sso && } + + )} + {sso && ( + <> + 2 + } + /> + + + )} + + Already have an account? Login + + + ); +} diff --git a/src/app/pages/auth/register/index.ts b/src/app/pages/auth/register/index.ts new file mode 100644 index 000000000..7eb55fd55 --- /dev/null +++ b/src/app/pages/auth/register/index.ts @@ -0,0 +1 @@ +export * from './Register'; diff --git a/src/app/pages/auth/register/registerUtil.ts b/src/app/pages/auth/register/registerUtil.ts new file mode 100644 index 000000000..23c3d6a1d --- /dev/null +++ b/src/app/pages/auth/register/registerUtil.ts @@ -0,0 +1,125 @@ +import to from 'await-to-js'; +import { + IAuthData, + MatrixClient, + MatrixError, + RegisterRequest, + RegisterResponse, +} from 'matrix-js-sdk'; +import { useEffect } from 'react'; +import { useNavigate } from 'react-router-dom'; +import { updateLocalStore } from '../../../../client/action/auth'; +import { ROOT_PATH } from '../../paths'; +import { ErrorCode } from '../../../cs-errorcode'; + +export enum RegisterError { + UserTaken = 'UserTaken', + UserInvalid = 'UserInvalid', + UserExclusive = 'UserExclusive', + PasswordWeak = 'PasswordWeak', + PasswordShort = 'PasswordShort', + InvalidRequest = 'InvalidRequest', + Forbidden = 'Forbidden', + RateLimited = 'RateLimited', + Unknown = 'Unknown', +} + +export type CustomRegisterResponse = { + baseUrl: string; + response: RegisterResponse; +}; +export type RegisterResult = [IAuthData, undefined] | [undefined, CustomRegisterResponse]; +export const register = async ( + mx: MatrixClient, + requestData: RegisterRequest +): Promise => { + const [err, res] = await to(mx.registerRequest(requestData)); + + if (err) { + if (err.httpStatus === 401) { + const authData = err.data as IAuthData; + return [authData, undefined]; + } + + if (err.errcode === ErrorCode.M_USER_IN_USE) { + throw new MatrixError({ + errcode: RegisterError.UserTaken, + }); + } + if (err.errcode === ErrorCode.M_INVALID_USERNAME) { + throw new MatrixError({ + errcode: RegisterError.UserInvalid, + }); + } + if (err.errcode === ErrorCode.M_EXCLUSIVE) { + throw new MatrixError({ + errcode: RegisterError.UserExclusive, + }); + } + if (err.errcode === ErrorCode.M_WEAK_PASSWORD) { + throw new MatrixError({ + errcode: RegisterError.PasswordWeak, + error: err.data.error, + }); + } + if (err.errcode === ErrorCode.M_PASSWORD_TOO_SHORT) { + throw new MatrixError({ + errcode: RegisterError.PasswordShort, + error: err.data.error, + }); + } + + if (err.httpStatus === 429) { + throw new MatrixError({ + errcode: RegisterError.RateLimited, + }); + } + + if (err.httpStatus === 400) { + throw new MatrixError({ + errcode: RegisterError.InvalidRequest, + }); + } + + if (err.httpStatus === 403) { + throw new MatrixError({ + errcode: RegisterError.Forbidden, + }); + } + + throw new MatrixError({ + errcode: RegisterError.Unknown, + error: err.data.error, + }); + } + return [ + undefined, + { + baseUrl: mx.baseUrl, + response: res, + }, + ]; +}; + +export const useRegisterComplete = (data?: CustomRegisterResponse) => { + const navigate = useNavigate(); + + useEffect(() => { + if (data) { + const { response, baseUrl } = data; + + const userId = response.user_id; + const accessToken = response.access_token; + const deviceId = response.device_id; + + if (accessToken && deviceId) { + updateLocalStore(accessToken, deviceId, userId, baseUrl); + // TODO: add after register redirect url + navigate(ROOT_PATH, { replace: true }); + } else { + // TODO: navigate to login with userId + navigate(ROOT_PATH, { replace: true }); + } + } + }, [data, navigate]); +}; diff --git a/src/app/pages/auth/reset-password/PasswordResetForm.tsx b/src/app/pages/auth/reset-password/PasswordResetForm.tsx new file mode 100644 index 000000000..7c71de021 --- /dev/null +++ b/src/app/pages/auth/reset-password/PasswordResetForm.tsx @@ -0,0 +1,274 @@ +import React, { FormEventHandler, useCallback, useEffect, useMemo, useState } from 'react'; +import { + Box, + Button, + Dialog, + Input, + Overlay, + OverlayBackdrop, + OverlayCenter, + Spinner, + Text, + color, + config, +} from 'folds'; +import { useNavigate } from 'react-router-dom'; +import FocusTrap from 'focus-trap-react'; +import { AuthDict, AuthType, MatrixError, createClient } from 'matrix-js-sdk'; +import { useAutoDiscoveryInfo } from '../../../hooks/useAutoDiscoveryInfo'; +import { AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback'; +import { useAuthServer } from '../../../hooks/useAuthServer'; +import { usePasswordEmail } from '../../../hooks/usePasswordEmail'; +import { PasswordInput } from '../../../components/password-input/PasswordInput'; +import { ConfirmPasswordMatch } from '../../../components/ConfirmPasswordMatch'; +import { FieldError } from '../FiledError'; +import { UIAFlowOverlay } from '../../../components/UIAFlowOverlay'; +import { EmailStageDialog } from '../../../components/uia-stages'; +import { ResetPasswordResult, resetPassword } from './resetPasswordUtil'; +import { getLoginPath, withSearchParam } from '../../pathUtils'; +import { LoginPathSearchParams } from '../../paths'; +import { getUIAError, getUIAErrorCode } from '../../../utils/matrix-uia'; + +type FormData = { + email: string; + password: string; + clientSecret: string; +}; + +function ResetPasswordComplete({ email }: { email?: string }) { + const server = useAuthServer(); + + const navigate = useNavigate(); + + const handleClick = () => { + const path = getLoginPath(server); + if (email) { + navigate(withSearchParam(path, { email })); + return; + } + navigate(path); + }; + + return ( + }> + + + + + + Password has been reset successfully. Please login with your new password. + + + + + + + + ); +} + +type PasswordResetFormProps = { + defaultEmail?: string; +}; +export function PasswordResetForm({ defaultEmail }: PasswordResetFormProps) { + const server = useAuthServer(); + + const serverDiscovery = useAutoDiscoveryInfo(); + const baseUrl = serverDiscovery['m.homeserver'].base_url; + const mx = useMemo(() => createClient({ baseUrl }), [baseUrl]); + + const [formData, setFormData] = useState(); + + const [passwordEmailState, passwordEmail] = usePasswordEmail(mx); + + const [resetPasswordState, handleResetPassword] = useAsyncCallback< + ResetPasswordResult, + MatrixError, + [AuthDict, string] + >(useCallback(async (authDict, newPassword) => resetPassword(mx, authDict, newPassword), [mx])); + + const [ongoingAuthData, resetPasswordResult] = + resetPasswordState.status === AsyncStatus.Success ? resetPasswordState.data : []; + const resetPasswordError = + resetPasswordState.status === AsyncStatus.Error ? resetPasswordState.error : undefined; + + const flowErrorCode = ongoingAuthData && getUIAErrorCode(ongoingAuthData); + const flowError = ongoingAuthData && getUIAError(ongoingAuthData); + + let waitingToVerifyEmail = true; + if (resetPasswordResult) waitingToVerifyEmail = false; + if (ongoingAuthData && flowErrorCode === undefined) waitingToVerifyEmail = false; + if (resetPasswordError) waitingToVerifyEmail = false; + if (resetPasswordState.status === AsyncStatus.Loading) waitingToVerifyEmail = false; + + // We only support UIA m.login.password stage for reset password + // So we will assume to process it as soon as + // we have 401 with no error on initial request. + useEffect(() => { + if (formData && ongoingAuthData && !flowErrorCode) { + handleResetPassword( + { + type: AuthType.Password, + identifier: { + type: 'm.id.thirdparty', + medium: 'email', + address: formData.email, + }, + password: formData.password, + }, + formData.password + ); + } + }, [ongoingAuthData, flowErrorCode, formData, handleResetPassword]); + + const handleSubmit: FormEventHandler = (evt) => { + evt.preventDefault(); + const { emailInput, passwordInput, confirmPasswordInput } = evt.target as HTMLFormElement & { + emailInput: HTMLInputElement; + passwordInput: HTMLInputElement; + confirmPasswordInput: HTMLInputElement; + }; + + const email = emailInput.value.trim(); + const password = passwordInput.value; + const confirmPassword = confirmPasswordInput.value; + if (!email) { + emailInput.focus(); + return; + } + if (password !== confirmPassword) return; + + const clientSecret = mx.generateClientSecret(); + passwordEmail(email, clientSecret); + setFormData({ + email, + password, + clientSecret, + }); + }; + + const handleCancel = () => { + window.location.reload(); + }; + + const handleSubmitRequest = useCallback( + (authDict: AuthDict) => { + if (!formData) return; + const { password } = formData; + handleResetPassword(authDict, password); + }, + [formData, handleResetPassword] + ); + + return ( + + + Homeserver {server} will send you an email to let you reset your password. + + + + Email + + + {passwordEmailState.status === AsyncStatus.Error && ( + + )} + + + {(match, doMatch, passRef, confPassRef) => ( + <> + + + New Password + + + + + + Confirm Password + + + + + )} + + {resetPasswordError && ( + + )} + + + + {resetPasswordResult && } + + {passwordEmailState.status === AsyncStatus.Success && formData && waitingToVerifyEmail && ( + + + + )} + + } + > + + + + + + ); +} diff --git a/src/app/pages/auth/reset-password/ResetPassword.tsx b/src/app/pages/auth/reset-password/ResetPassword.tsx new file mode 100644 index 000000000..1ada9afd7 --- /dev/null +++ b/src/app/pages/auth/reset-password/ResetPassword.tsx @@ -0,0 +1,36 @@ +import { Box, Text } from 'folds'; +import React from 'react'; +import { Link, useSearchParams } from 'react-router-dom'; +import { getLoginPath } from '../../pathUtils'; +import { useAuthServer } from '../../../hooks/useAuthServer'; +import { PasswordResetForm } from './PasswordResetForm'; + +export type ResetPasswordSearchParams = { + email?: string; +}; + +const getResetPasswordSearchParams = ( + searchParams: URLSearchParams +): ResetPasswordSearchParams => ({ + email: searchParams.get('email') ?? undefined, +}); + +export function ResetPassword() { + const server = useAuthServer(); + const [searchParams] = useSearchParams(); + const resetPasswordSearchParams = getResetPasswordSearchParams(searchParams); + + return ( + + + Reset Password + + + + + + Remember your password? Login + + + ); +} diff --git a/src/app/pages/auth/reset-password/index.ts b/src/app/pages/auth/reset-password/index.ts new file mode 100644 index 000000000..0e85ecf3f --- /dev/null +++ b/src/app/pages/auth/reset-password/index.ts @@ -0,0 +1 @@ +export * from './ResetPassword'; diff --git a/src/app/pages/auth/reset-password/resetPasswordUtil.ts b/src/app/pages/auth/reset-password/resetPasswordUtil.ts new file mode 100644 index 000000000..5eb436fa4 --- /dev/null +++ b/src/app/pages/auth/reset-password/resetPasswordUtil.ts @@ -0,0 +1,23 @@ +import to from 'await-to-js'; +import { AuthDict, IAuthData, MatrixClient, MatrixError } from 'matrix-js-sdk'; + +export type ResetPasswordResponse = Record; +export type ResetPasswordResult = [IAuthData, undefined] | [undefined, ResetPasswordResponse]; +export const resetPassword = async ( + mx: MatrixClient, + authDict: AuthDict, + newPassword: string +): Promise => { + const [err, res] = await to( + mx.setPassword(authDict, newPassword, false) + ); + + if (err) { + if (err.httpStatus === 401) { + const authData = err.data as IAuthData; + return [authData, undefined]; + } + throw err; + } + return [undefined, res]; +}; diff --git a/src/app/pages/auth/styles.css.ts b/src/app/pages/auth/styles.css.ts new file mode 100644 index 000000000..5834ad849 --- /dev/null +++ b/src/app/pages/auth/styles.css.ts @@ -0,0 +1,53 @@ +import { style } from '@vanilla-extract/css'; +import { DefaultReset, color, config, toRem } from 'folds'; + +export const AuthLayout = style({ + minHeight: '100%', + backgroundColor: color.Background.Container, + color: color.Background.OnContainer, + padding: config.space.S400, + paddingRight: config.space.S200, + paddingBottom: 0, + position: 'relative', +}); + +export const AuthCard = style({ + marginTop: '1vh', + maxWidth: toRem(460), + width: '100%', + backgroundColor: color.Surface.Container, + color: color.Surface.OnContainer, + borderRadius: config.radii.R400, + boxShadow: config.shadow.E100, + border: `${config.borderWidth.B300} solid ${color.Surface.ContainerLine}`, + overflow: 'hidden', +}); + +export const AuthLogo = style([ + DefaultReset, + { + width: toRem(26), + height: toRem(26), + + borderRadius: '50%', + }, +]); + +export const AuthHeader = style({ + padding: `0 ${config.space.S400}`, + borderBottomWidth: config.borderWidth.B300, +}); + +export const AuthCardContent = style({ + maxWidth: toRem(402), + width: '100%', + margin: 'auto', + padding: config.space.S400, + paddingTop: config.space.S700, + paddingBottom: toRem(44), + gap: toRem(44), +}); + +export const AuthFooter = style({ + padding: config.space.S200, +}); diff --git a/src/app/pages/pathUtils.ts b/src/app/pages/pathUtils.ts new file mode 100644 index 000000000..db39ce391 --- /dev/null +++ b/src/app/pages/pathUtils.ts @@ -0,0 +1,28 @@ +import { generatePath } from 'react-router-dom'; +import { LOGIN_PATH, REGISTER_PATH, RESET_PASSWORD_PATH, ROOT_PATH } from './paths'; + +export const withSearchParam = >( + path: string, + searchParam: T +): string => { + const params = new URLSearchParams(searchParam); + + return `${path}?${params}`; +}; + +export const getRootPath = (): string => ROOT_PATH; + +export const getLoginPath = (server?: string): string => { + const params = server ? { server: encodeURIComponent(server) } : undefined; + return generatePath(LOGIN_PATH, params); +}; + +export const getRegisterPath = (server?: string): string => { + const params = server ? { server: encodeURIComponent(server) } : undefined; + return generatePath(REGISTER_PATH, params); +}; + +export const getResetPasswordPath = (server?: string): string => { + const params = server ? { server: encodeURIComponent(server) } : undefined; + return generatePath(RESET_PASSWORD_PATH, params); +}; diff --git a/src/app/pages/paths.ts b/src/app/pages/paths.ts new file mode 100644 index 000000000..cd6226414 --- /dev/null +++ b/src/app/pages/paths.ts @@ -0,0 +1,17 @@ +export const ROOT_PATH = '/'; + +export type LoginPathSearchParams = { + username?: string; + email?: string; + loginToken?: string; +}; +export const LOGIN_PATH = '/login/:server?/'; + +export type RegisterPathSearchParams = { + username?: string; + email?: string; + token?: string; +}; +export const REGISTER_PATH = '/register/:server?/'; + +export const RESET_PASSWORD_PATH = '/reset-password/:server?/'; diff --git a/src/app/state/hooks/inviteList.ts b/src/app/state/hooks/inviteList.ts index f8b7e057c..ffe44445d 100644 --- a/src/app/state/hooks/inviteList.ts +++ b/src/app/state/hooks/inviteList.ts @@ -1,28 +1,26 @@ -import { useAtomValue, WritableAtom } from 'jotai'; +import { useAtomValue } from 'jotai'; import { selectAtom } from 'jotai/utils'; import { MatrixClient } from 'matrix-js-sdk'; import { useCallback } from 'react'; import { isDirectInvite, isRoom, isSpace, isUnsupportedRoom } from '../../utils/room'; -import { compareRoomsEqual, RoomsAction } from '../utils'; -import { MDirectAction } from '../mDirectList'; +import { compareRoomsEqual } from '../utils'; +import { mDirectAtom } from '../mDirectList'; +import { allInvitesAtom } from '../inviteList'; -export const useSpaceInvites = ( - mx: MatrixClient, - allInvitesAtom: WritableAtom -) => { +export const useSpaceInvites = (mx: MatrixClient, invitesAtom: typeof allInvitesAtom) => { const selector = useCallback( (rooms: string[]) => rooms.filter((roomId) => isSpace(mx.getRoom(roomId))), [mx] ); - return useAtomValue(selectAtom(allInvitesAtom, selector, compareRoomsEqual)); + return useAtomValue(selectAtom(invitesAtom, selector, compareRoomsEqual)); }; export const useRoomInvites = ( mx: MatrixClient, - allInvitesAtom: WritableAtom, - mDirectAtom: WritableAtom, MDirectAction> + invitesAtom: typeof allInvitesAtom, + directAtom: typeof mDirectAtom ) => { - const mDirects = useAtomValue(mDirectAtom); + const mDirects = useAtomValue(directAtom); const selector = useCallback( (rooms: string[]) => rooms.filter( @@ -32,15 +30,15 @@ export const useRoomInvites = ( ), [mx, mDirects] ); - return useAtomValue(selectAtom(allInvitesAtom, selector, compareRoomsEqual)); + return useAtomValue(selectAtom(invitesAtom, selector, compareRoomsEqual)); }; export const useDirectInvites = ( mx: MatrixClient, - allInvitesAtom: WritableAtom, - mDirectAtom: WritableAtom, MDirectAction> + invitesAtom: typeof allInvitesAtom, + directAtom: typeof mDirectAtom ) => { - const mDirects = useAtomValue(mDirectAtom); + const mDirects = useAtomValue(directAtom); const selector = useCallback( (rooms: string[]) => rooms.filter( @@ -48,16 +46,13 @@ export const useDirectInvites = ( ), [mx, mDirects] ); - return useAtomValue(selectAtom(allInvitesAtom, selector, compareRoomsEqual)); + return useAtomValue(selectAtom(invitesAtom, selector, compareRoomsEqual)); }; -export const useUnsupportedInvites = ( - mx: MatrixClient, - allInvitesAtom: WritableAtom -) => { +export const useUnsupportedInvites = (mx: MatrixClient, invitesAtom: typeof allInvitesAtom) => { const selector = useCallback( (rooms: string[]) => rooms.filter((roomId) => isUnsupportedRoom(mx.getRoom(roomId))), [mx] ); - return useAtomValue(selectAtom(allInvitesAtom, selector, compareRoomsEqual)); + return useAtomValue(selectAtom(invitesAtom, selector, compareRoomsEqual)); }; diff --git a/src/app/state/hooks/roomList.ts b/src/app/state/hooks/roomList.ts index 5d0890bdd..c0a7bfb88 100644 --- a/src/app/state/hooks/roomList.ts +++ b/src/app/state/hooks/roomList.ts @@ -1,54 +1,52 @@ -import { useAtomValue, WritableAtom } from 'jotai'; +import { useAtomValue } from 'jotai'; import { selectAtom } from 'jotai/utils'; import { MatrixClient } from 'matrix-js-sdk'; import { useCallback } from 'react'; import { isRoom, isSpace, isUnsupportedRoom } from '../../utils/room'; -import { compareRoomsEqual, RoomsAction } from '../utils'; -import { MDirectAction } from '../mDirectList'; +import { compareRoomsEqual } from '../utils'; +import { mDirectAtom } from '../mDirectList'; +import { allRoomsAtom } from '../roomList'; -export const useSpaces = (mx: MatrixClient, allRoomsAtom: WritableAtom) => { +export const useSpaces = (mx: MatrixClient, roomsAtom: typeof allRoomsAtom) => { const selector = useCallback( (rooms: string[]) => rooms.filter((roomId) => isSpace(mx.getRoom(roomId))), [mx] ); - return useAtomValue(selectAtom(allRoomsAtom, selector, compareRoomsEqual)); + return useAtomValue(selectAtom(roomsAtom, selector, compareRoomsEqual)); }; export const useRooms = ( mx: MatrixClient, - allRoomsAtom: WritableAtom, - mDirectAtom: WritableAtom, MDirectAction> + roomsAtom: typeof allRoomsAtom, + directAtom: typeof mDirectAtom ) => { - const mDirects = useAtomValue(mDirectAtom); + const mDirects = useAtomValue(directAtom); const selector = useCallback( (rooms: string[]) => rooms.filter((roomId) => isRoom(mx.getRoom(roomId)) && !mDirects.has(roomId)), [mx, mDirects] ); - return useAtomValue(selectAtom(allRoomsAtom, selector, compareRoomsEqual)); + return useAtomValue(selectAtom(roomsAtom, selector, compareRoomsEqual)); }; export const useDirects = ( mx: MatrixClient, - allRoomsAtom: WritableAtom, - mDirectAtom: WritableAtom, MDirectAction> + roomsAtom: typeof allRoomsAtom, + directAtom: typeof mDirectAtom ) => { - const mDirects = useAtomValue(mDirectAtom); + const mDirects = useAtomValue(directAtom); const selector = useCallback( (rooms: string[]) => rooms.filter((roomId) => isRoom(mx.getRoom(roomId)) && mDirects.has(roomId)), [mx, mDirects] ); - return useAtomValue(selectAtom(allRoomsAtom, selector, compareRoomsEqual)); + return useAtomValue(selectAtom(roomsAtom, selector, compareRoomsEqual)); }; -export const useUnsupportedRooms = ( - mx: MatrixClient, - allRoomsAtom: WritableAtom -) => { +export const useUnsupportedRooms = (mx: MatrixClient, roomsAtom: typeof allRoomsAtom) => { const selector = useCallback( (rooms: string[]) => rooms.filter((roomId) => isUnsupportedRoom(mx.getRoom(roomId))), [mx] ); - return useAtomValue(selectAtom(allRoomsAtom, selector, compareRoomsEqual)); + return useAtomValue(selectAtom(roomsAtom, selector, compareRoomsEqual)); }; diff --git a/src/app/state/hooks/settings.ts b/src/app/state/hooks/settings.ts index 43b565534..d90c76646 100644 --- a/src/app/state/hooks/settings.ts +++ b/src/app/state/hooks/settings.ts @@ -1,16 +1,16 @@ -import { atom, useAtomValue, useSetAtom, WritableAtom } from 'jotai'; -import { SetAtom } from 'jotai/core/atom'; +import { atom, useAtomValue, useSetAtom } from 'jotai'; import { selectAtom } from 'jotai/utils'; import { useMemo } from 'react'; -import { Settings } from '../settings'; +import { Settings, settingsAtom as sAtom } from '../settings'; -export const useSetSetting = ( - settingsAtom: WritableAtom, - key: K -) => { +export type SettingSetter = + | Settings[K] + | ((s: Settings[K]) => Settings[K]); + +export const useSetSetting = (settingsAtom: typeof sAtom, key: K) => { const setterAtom = useMemo( () => - atom Settings[K])>(null, (get, set, value) => { + atom], undefined>(null, (get, set, value) => { const s = { ...get(settingsAtom) }; s[key] = typeof value === 'function' ? value(s[key]) : value; set(settingsAtom, s); @@ -22,9 +22,9 @@ export const useSetSetting = ( }; export const useSetting = ( - settingsAtom: WritableAtom, + settingsAtom: typeof sAtom, key: K -): [Settings[K], SetAtom Settings[K]), void>] => { +): [Settings[K], ReturnType>] => { const selector = useMemo(() => (s: Settings) => s[key], [key]); const setting = useAtomValue(selectAtom(settingsAtom, selector)); diff --git a/src/app/state/inviteList.ts b/src/app/state/inviteList.ts index 463fd352d..a6dc79668 100644 --- a/src/app/state/inviteList.ts +++ b/src/app/state/inviteList.ts @@ -5,7 +5,7 @@ import { Membership } from '../../types/matrix/room'; import { RoomsAction, useBindRoomsWithMembershipsAtom } from './utils'; const baseRoomsAtom = atom([]); -export const allInvitesAtom = atom( +export const allInvitesAtom = atom( (get) => get(baseRoomsAtom), (get, set, action) => { if (action.type === 'INITIALIZE') { @@ -22,7 +22,7 @@ export const allInvitesAtom = atom( export const useBindAllInvitesAtom = ( mx: MatrixClient, - allRooms: WritableAtom + allRooms: WritableAtom ) => { useBindRoomsWithMembershipsAtom( mx, diff --git a/src/app/state/list.ts b/src/app/state/list.ts index 4f5a61914..670e6db18 100644 --- a/src/app/state/list.ts +++ b/src/app/state/list.ts @@ -12,7 +12,7 @@ export type ListAction = export const createListAtom = () => { const baseListAtom = atom([]); - return atom>( + return atom], undefined>( (get) => get(baseListAtom), (get, set, action) => { const items = get(baseListAtom); diff --git a/src/app/state/mDirectList.ts b/src/app/state/mDirectList.ts index 96e2f0d03..1fa8311f4 100644 --- a/src/app/state/mDirectList.ts +++ b/src/app/state/mDirectList.ts @@ -1,4 +1,4 @@ -import { atom, useSetAtom, WritableAtom } from 'jotai'; +import { atom, useSetAtom } from 'jotai'; import { ClientEvent, MatrixClient, MatrixEvent } from 'matrix-js-sdk'; import { useEffect } from 'react'; import { AccountDataEvent } from '../../types/matrix/accountData'; @@ -10,17 +10,14 @@ export type MDirectAction = { }; const baseMDirectAtom = atom(new Set()); -export const mDirectAtom = atom, MDirectAction>( +export const mDirectAtom = atom, [MDirectAction], undefined>( (get) => get(baseMDirectAtom), (get, set, action) => { set(baseMDirectAtom, action.rooms); } ); -export const useBindMDirectAtom = ( - mx: MatrixClient, - mDirect: WritableAtom, MDirectAction> -) => { +export const useBindMDirectAtom = (mx: MatrixClient, mDirect: typeof mDirectAtom) => { const setMDirect = useSetAtom(mDirect); useEffect(() => { diff --git a/src/app/state/mutedRoomList.ts b/src/app/state/mutedRoomList.ts index d456f8533..f818450bb 100644 --- a/src/app/state/mutedRoomList.ts +++ b/src/app/state/mutedRoomList.ts @@ -1,4 +1,4 @@ -import { atom, WritableAtom, useSetAtom } from 'jotai'; +import { atom, useSetAtom } from 'jotai'; import { ClientEvent, IPushRule, IPushRules, MatrixClient, MatrixEvent } from 'matrix-js-sdk'; import { useEffect } from 'react'; import { MuteChanges } from '../../types/matrix/room'; @@ -21,7 +21,7 @@ export const muteChangesAtom = atom({ }); const baseMutedRoomsAtom = atom(new Set()); -export const mutedRoomsAtom = atom, MutedRoomsUpdate>( +export const mutedRoomsAtom = atom, [MutedRoomsUpdate], undefined>( (get) => get(baseMutedRoomsAtom), (get, set, action) => { const mutedRooms = new Set([...get(mutedRoomsAtom)]); @@ -45,10 +45,7 @@ export const mutedRoomsAtom = atom, MutedRoomsUpdate>( } ); -export const useBindMutedRoomsAtom = ( - mx: MatrixClient, - mutedAtom: WritableAtom, MutedRoomsUpdate> -) => { +export const useBindMutedRoomsAtom = (mx: MatrixClient, mutedAtom: typeof mutedRoomsAtom) => { const setMuted = useSetAtom(mutedAtom); useEffect(() => { diff --git a/src/app/state/roomList.ts b/src/app/state/roomList.ts index 7a793d8c3..e0fa170fb 100644 --- a/src/app/state/roomList.ts +++ b/src/app/state/roomList.ts @@ -1,11 +1,11 @@ -import { atom, WritableAtom } from 'jotai'; +import { atom } from 'jotai'; import { MatrixClient } from 'matrix-js-sdk'; import { useMemo } from 'react'; import { Membership } from '../../types/matrix/room'; import { RoomsAction, useBindRoomsWithMembershipsAtom } from './utils'; const baseRoomsAtom = atom([]); -export const allRoomsAtom = atom( +export const allRoomsAtom = atom( (get) => get(baseRoomsAtom), (get, set, action) => { if (action.type === 'INITIALIZE') { @@ -19,10 +19,7 @@ export const allRoomsAtom = atom( }); } ); -export const useBindAllRoomsAtom = ( - mx: MatrixClient, - allRooms: WritableAtom -) => { +export const useBindAllRoomsAtom = (mx: MatrixClient, allRooms: typeof allRoomsAtom) => { useBindRoomsWithMembershipsAtom( mx, allRooms, diff --git a/src/app/state/roomToParents.ts b/src/app/state/roomToParents.ts index 374ddd575..1e2ef18c4 100644 --- a/src/app/state/roomToParents.ts +++ b/src/app/state/roomToParents.ts @@ -1,5 +1,5 @@ import produce from 'immer'; -import { atom, useSetAtom, WritableAtom } from 'jotai'; +import { atom, useSetAtom } from 'jotai'; import { ClientEvent, MatrixClient, @@ -34,7 +34,7 @@ export type RoomToParentsAction = }; const baseRoomToParents = atom(new Map()); -export const roomToParentsAtom = atom( +export const roomToParentsAtom = atom( (get) => get(baseRoomToParents), (get, set, action) => { if (action.type === 'INITIALIZE') { @@ -69,7 +69,7 @@ export const roomToParentsAtom = atom( export const useBindRoomToParentsAtom = ( mx: MatrixClient, - roomToParents: WritableAtom + roomToParents: typeof roomToParentsAtom ) => { const setRoomToParents = useSetAtom(roomToParents); diff --git a/src/app/state/roomToUnread.ts b/src/app/state/roomToUnread.ts index 0c7b6bd69..ad388763e 100644 --- a/src/app/state/roomToUnread.ts +++ b/src/app/state/roomToUnread.ts @@ -1,5 +1,5 @@ import produce from 'immer'; -import { atom, useSetAtom, PrimitiveAtom, WritableAtom, useAtomValue } from 'jotai'; +import { atom, useSetAtom, PrimitiveAtom, useAtomValue } from 'jotai'; import { IRoomTimelineData, MatrixClient, MatrixEvent, Room, RoomEvent } from 'matrix-js-sdk'; import { ReceiptContent, ReceiptType } from 'matrix-js-sdk/lib/@types/read_receipts'; import { useEffect } from 'react'; @@ -82,7 +82,7 @@ const deleteUnreadInfo = (roomToUnread: RoomToUnread, allParents: Set, r }; const baseRoomToUnread = atom(new Map()); -export const roomToUnreadAtom = atom( +export const roomToUnreadAtom = atom( (get) => get(baseRoomToUnread), (get, set, action) => { if (action.type === 'RESET') { @@ -127,7 +127,7 @@ export const roomToUnreadAtom = atom( export const useBindRoomToUnreadAtom = ( mx: MatrixClient, - unreadAtom: WritableAtom, + unreadAtom: typeof roomToUnreadAtom, muteChangesAtom: PrimitiveAtom ) => { const setUnreadAtom = useSetAtom(unreadAtom); diff --git a/src/app/state/sessions.ts b/src/app/state/sessions.ts new file mode 100644 index 000000000..85bcd10e2 --- /dev/null +++ b/src/app/state/sessions.ts @@ -0,0 +1,129 @@ +import { atom } from 'jotai'; +import { + atomWithLocalStorage, + getLocalStorageItem, + setLocalStorageItem, +} from './utils/atomWithLocalStorage'; + +export type Session = { + baseUrl: string; + userId: string; + deviceId: string; + accessToken: string; + expiresInMs?: number; + refreshToken?: string; + fallbackSdkStores?: boolean; +}; + +export type Sessions = Session[]; +export type SessionStoreName = { + sync: string; + crypto: string; +}; + +/** + * Migration code for old session + */ +const FALLBACK_STORE_NAME: SessionStoreName = { + sync: 'web-sync-store', + crypto: 'crypto-store', +} as const; + +const removeFallbackSession = () => { + localStorage.removeItem('cinny_hs_base_url'); + localStorage.removeItem('cinny_user_id'); + localStorage.removeItem('cinny_device_id'); + localStorage.removeItem('cinny_access_token'); +}; +const getFallbackSession = (): Session | undefined => { + const baseUrl = localStorage.getItem('cinny_hs_base_url'); + const userId = localStorage.getItem('cinny_user_id'); + const deviceId = localStorage.getItem('cinny_device_id'); + const accessToken = localStorage.getItem('cinny_access_token'); + + if (baseUrl && userId && deviceId && accessToken) { + const session: Session = { + baseUrl, + userId, + deviceId, + accessToken, + fallbackSdkStores: true, + }; + + return session; + } + + return undefined; +}; +/** + * End of migration code for old session + */ + +export const getSessionStoreName = (session: Session): SessionStoreName => { + if (session.fallbackSdkStores) { + return FALLBACK_STORE_NAME; + } + + return { + sync: `sync${session.userId}`, + crypto: `crypto${session.userId}`, + }; +}; + +export const MATRIX_SESSIONS_KEY = 'matrixSessions'; +const baseSessionsAtom = atomWithLocalStorage( + MATRIX_SESSIONS_KEY, + (key) => { + const defaultSessions: Sessions = []; + const sessions = getLocalStorageItem(key, defaultSessions); + + // Before multi account support session was stored + // as multiple item in local storage. + // So we need these migration code. + const fallbackSession = getFallbackSession(); + if (fallbackSession) { + removeFallbackSession(); + sessions.push(fallbackSession); + setLocalStorageItem(key, sessions); + } + return sessions; + }, + (key, value) => { + setLocalStorageItem(key, value); + } +); + +export type SessionsAction = + | { + type: 'PUT'; + session: Session; + } + | { + type: 'DELETE'; + session: Session; + }; + +export const sessionsAtom = atom( + (get) => get(baseSessionsAtom), + (get, set, action) => { + if (action.type === 'PUT') { + const sessions = [...get(baseSessionsAtom)]; + const sessionIndex = sessions.findIndex( + (session) => session.userId === action.session.userId + ); + if (sessionIndex === -1) { + sessions.push(action.session); + } else { + sessions.splice(sessionIndex, 1, action.session); + } + set(baseSessionsAtom, sessions); + return; + } + if (action.type === 'DELETE') { + const sessions = get(baseSessionsAtom).filter( + (session) => session.userId !== action.session.userId + ); + set(baseSessionsAtom, sessions); + } + } +); diff --git a/src/app/state/settings.ts b/src/app/state/settings.ts index 92d40ff8c..061931ea8 100644 --- a/src/app/state/settings.ts +++ b/src/app/state/settings.ts @@ -64,7 +64,7 @@ export const setSettings = (settings: Settings) => { }; const baseSettings = atom(getSettings()); -export const settingsAtom = atom( +export const settingsAtom = atom( (get) => get(baseSettings), (get, set, update) => { set(baseSettings, update); diff --git a/src/app/state/tabToRoom.ts b/src/app/state/tabToRoom.ts index 2f4ee92a4..b9472d9f9 100644 --- a/src/app/state/tabToRoom.ts +++ b/src/app/state/tabToRoom.ts @@ -14,7 +14,7 @@ type TabToRoomAction = { }; const baseTabToRoom = atom(new Map()); -export const tabToRoomAtom = atom( +export const tabToRoomAtom = atom( (get) => get(baseTabToRoom), (get, set, action) => { if (action.type === 'PUT') { diff --git a/src/app/state/typingMembers.ts b/src/app/state/typingMembers.ts index b87817d19..c77c91be6 100644 --- a/src/app/state/typingMembers.ts +++ b/src/app/state/typingMembers.ts @@ -23,7 +23,11 @@ export type IRoomIdToTypingMembersAction = }; const baseRoomIdToTypingMembersAtom = atom(new Map()); -export const roomIdToTypingMembersAtom = atom( +export const roomIdToTypingMembersAtom = atom< + IRoomIdToTypingMembers, + [IRoomIdToTypingMembersAction], + undefined +>( (get) => get(baseRoomIdToTypingMembersAtom), (get, set, action) => { const roomIdToTypingMembers = get(baseRoomIdToTypingMembersAtom); diff --git a/src/app/state/upload.ts b/src/app/state/upload.ts index d92b93d3d..13869afb2 100644 --- a/src/app/state/upload.ts +++ b/src/app/state/upload.ts @@ -57,7 +57,7 @@ export const createUploadAtom = (file: TUploadContent) => { file, status: UploadStatus.Idle, }); - return atom( + return atom( (get) => get(baseUploadAtom), (get, set, update) => { const uploadState = get(baseUploadAtom); diff --git a/src/app/state/utils.ts b/src/app/state/utils.ts index 355c94110..4c4caa5ca 100644 --- a/src/app/state/utils.ts +++ b/src/app/state/utils.ts @@ -15,7 +15,7 @@ export type RoomsAction = export const useBindRoomsWithMembershipsAtom = ( mx: MatrixClient, - roomsAtom: WritableAtom, + roomsAtom: WritableAtom, memberships: Membership[] ) => { const setRoomsAtom = useSetAtom(roomsAtom); diff --git a/src/app/state/utils/atomWithLocalStorage.ts b/src/app/state/utils/atomWithLocalStorage.ts new file mode 100644 index 000000000..f17d3a3d0 --- /dev/null +++ b/src/app/state/utils/atomWithLocalStorage.ts @@ -0,0 +1,51 @@ +import { atom } from 'jotai'; + +export const getLocalStorageItem = (key: string, defaultValue: T): T => { + const item = localStorage.getItem(key); + if (item === null) return defaultValue; + if (item === 'undefined') return undefined as T; + try { + return JSON.parse(item) as T; + } catch { + return defaultValue; + } +}; + +export const setLocalStorageItem = (key: string, value: T) => { + localStorage.setItem(key, JSON.stringify(value)); +}; + +export type GetLocalStorageItem = (key: string) => T; +export type SetLocalStorageItem = (key: string, value: T) => void; + +export const atomWithLocalStorage = ( + key: string, + getItem: GetLocalStorageItem, + setItem: SetLocalStorageItem +) => { + const value = getItem(key); + + const baseAtom = atom(value); + + baseAtom.onMount = (setAtom) => { + const handleChange = (evt: StorageEvent) => { + if (evt.key !== key) return; + setAtom(getItem(key)); + }; + + window.addEventListener('storage', handleChange); + return () => { + window.removeEventListener('storage', handleChange); + }; + }; + + const localStorageAtom = atom( + (get) => get(baseAtom), + (get, set, newValue) => { + set(baseAtom, newValue); + setItem(key, newValue); + } + ); + + return localStorageAtom; +}; diff --git a/src/app/styles/Patterns.css.ts b/src/app/styles/Patterns.css.ts new file mode 100644 index 000000000..e45594167 --- /dev/null +++ b/src/app/styles/Patterns.css.ts @@ -0,0 +1,9 @@ +import { style } from '@vanilla-extract/css'; +import { color, toRem } from 'folds'; + +export const BackgroundDotPattern = style({ + backgroundImage: `radial-gradient(${color.Background.ContainerActive} ${toRem(2)}, ${ + color.Background.Container + } ${toRem(2)})`, + backgroundSize: `${toRem(40)} ${toRem(40)}`, +}); diff --git a/src/app/utils/common.ts b/src/app/utils/common.ts index e007f222f..5cbe3806b 100644 --- a/src/app/utils/common.ts +++ b/src/app/utils/common.ts @@ -44,6 +44,17 @@ export const fulfilledPromiseSettledResult = (prs: PromiseSettledResult[]) return values; }, []); +export const promiseFulfilledResult = ( + settledResult: PromiseSettledResult +): T | undefined => { + if (settledResult.status === 'fulfilled') return settledResult.value; + return undefined; +}; +export const promiseRejectedResult = (settledResult: PromiseSettledResult): any => { + if (settledResult.status === 'rejected') return settledResult.reason; + return undefined; +}; + export const binarySearch = (items: T[], match: (item: T) => -1 | 0 | 1): T | undefined => { const search = (start: number, end: number): T | undefined => { if (start > end) return undefined; @@ -77,3 +88,10 @@ export const parseGeoUri = (location: string) => { longitude, }; }; + +const START_SLASHES_REG = /^\/+/g; +const END_SLASHES_REG = /\/+$/g; +export const trimLeadingSlash = (str: string): string => str.replace(START_SLASHES_REG, ''); +export const trimTrailingSlash = (str: string): string => str.replace(END_SLASHES_REG, ''); + +export const trimSlash = (str: string): string => trimLeadingSlash(trimTrailingSlash(str)); diff --git a/src/app/utils/matrix-uia.ts b/src/app/utils/matrix-uia.ts new file mode 100644 index 000000000..15c5799cf --- /dev/null +++ b/src/app/utils/matrix-uia.ts @@ -0,0 +1,84 @@ +import { AuthType, IAuthData, UIAFlow } from 'matrix-js-sdk'; + +export const getSupportedUIAFlows = (uiaFlows: UIAFlow[], supportedStages: string[]): UIAFlow[] => { + const supportedUIAFlows = uiaFlows.filter((flow) => + flow.stages.every((stage) => supportedStages.includes(stage)) + ); + + return supportedUIAFlows; +}; + +export const getUIACompleted = (authData: IAuthData): string[] => { + const completed = authData.completed ?? []; + return completed; +}; + +export type UIAParams = Record>; +export const getUIAParams = (authData: IAuthData): UIAParams => { + const params = authData.params ?? {}; + return params; +}; + +export const getUIASession = (authData: IAuthData): string | undefined => { + const session = authData.session ?? undefined; + return session; +}; + +export const getUIAErrorCode = (authData: IAuthData): string | undefined => { + const errorCode = + 'errcode' in authData && typeof authData.errcode === 'string' ? authData.errcode : undefined; + + return errorCode; +}; + +export const getUIAError = (authData: IAuthData): string | undefined => { + const errorCode = + 'error' in authData && typeof authData.error === 'string' ? authData.error : undefined; + + return errorCode; +}; + +export const getUIAFlowForStages = (uiaFlows: UIAFlow[], stages: string[]): UIAFlow | undefined => { + const matchedFlows = uiaFlows + .filter((flow) => { + if (flow.stages.length < stages.length) return false; + if (flow.stages.length > stages.length) { + // As a valid flow can also have m.login.dummy type, + // we will pick one extra length flow only if it has dummy + if (flow.stages.length > stages.length + 1) return false; + if (stages.includes(AuthType.Dummy)) return false; + if (flow.stages.includes(AuthType.Dummy)) return true; + return false; + } + return true; + }) + .filter((flow) => stages.every((stage) => flow.stages.includes(stage))); + + if (matchedFlows.length === 0) return undefined; + + matchedFlows.sort((a, b) => a.stages.length - b.stages.length); + return matchedFlows[0]; +}; + +export const hasStageInFlows = (uiaFlows: UIAFlow[], stage: string) => + uiaFlows.some((flow) => flow.stages.includes(stage)); + +export const requiredStageInFlows = (uiaFlows: UIAFlow[], stage: string) => + uiaFlows.every((flow) => flow.stages.includes(stage)); + +export const getLoginTermUrl = (params: UIAParams): string | undefined => { + const terms = params[AuthType.Terms]; + if (terms && 'policies' in terms && typeof terms.policies === 'object') { + if (terms.policies === null) return undefined; + if ('privacy_policy' in terms.policies && typeof terms.policies.privacy_policy === 'object') { + if (terms.policies.privacy_policy === null) return undefined; + const langToPolicy = terms.policies.privacy_policy as Record; + const url = langToPolicy.en?.url; + if (typeof url === 'string') return url; + + const firstKey = Object.keys(langToPolicy)[0]; + return langToPolicy[firstKey]?.url; + } + } + return undefined; +}; diff --git a/src/app/utils/regex.ts b/src/app/utils/regex.ts index 5188bef0f..281f12006 100644 --- a/src/app/utils/regex.ts +++ b/src/app/utils/regex.ts @@ -1,5 +1,8 @@ export const HTTP_URL_PATTERN = `https?:\\/\\/(?:www\\.)?(?:[^\\s)]*)(?()[\]\\.,;:\s@\\"]+(\.[^<>()[\]\\.,;:\s@\\"]+)*)|(\\".+\\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; + export const URL_NEG_LB = '(? getSecret(cons.secretKey.ACCESS_TOKEN) !== null; - -const secret = { - accessToken: getSecret(cons.secretKey.ACCESS_TOKEN), - deviceId: getSecret(cons.secretKey.DEVICE_ID), - userId: getSecret(cons.secretKey.USER_ID), - baseUrl: getSecret(cons.secretKey.BASE_URL), -}; - -export { - isAuthenticated, - secret, -}; diff --git a/src/client/state/auth.ts b/src/client/state/auth.ts new file mode 100644 index 000000000..9536a927e --- /dev/null +++ b/src/client/state/auth.ts @@ -0,0 +1,12 @@ +import cons from './cons'; + +const isAuthenticated = () => localStorage.getItem(cons.secretKey.ACCESS_TOKEN) !== null; + +const getSecret = () => ({ + accessToken: localStorage.getItem(cons.secretKey.ACCESS_TOKEN), + deviceId: localStorage.getItem(cons.secretKey.DEVICE_ID), + userId: localStorage.getItem(cons.secretKey.USER_ID), + baseUrl: localStorage.getItem(cons.secretKey.BASE_URL), +}); + +export { isAuthenticated, getSecret }; diff --git a/src/ext.d.ts b/src/ext.d.ts index 5593b6e7b..72acc587d 100644 --- a/src/ext.d.ts +++ b/src/ext.d.ts @@ -1,3 +1,5 @@ +/// + declare module 'browser-encrypt-attachment' { export interface EncryptedAttachmentInfo { v: string; @@ -26,3 +28,8 @@ declare module 'browser-encrypt-attachment' { info: EncryptedAttachmentInfo ): Promise; } + +declare module '*.svg' { + const content: string; + export default content; +} diff --git a/src/index.jsx b/src/index.tsx similarity index 57% rename from src/index.jsx rename to src/index.tsx index a8a765703..1d8642037 100644 --- a/src/index.jsx +++ b/src/index.tsx @@ -1,6 +1,6 @@ /* eslint-disable import/first */ import React from 'react'; -import ReactDom from 'react-dom'; +import { createRoot } from 'react-dom/client'; import { enableMapSet } from 'immer'; import '@fontsource/inter/variable.css'; import 'folds/dist/style.css'; @@ -15,7 +15,18 @@ import settings from './client/state/settings'; import App from './app/pages/App'; document.body.classList.add(configClass, varsClass); - settings.applyTheme(); -ReactDom.render(, document.getElementById('root')); +const mountApp = () => { + const rootContainer = document.getElementById('root'); + + if (rootContainer === null) { + console.error('Root container element not found!'); + return; + } + + const root = createRoot(rootContainer); + root.render(); +}; + +mountApp(); diff --git a/src/types/utils.ts b/src/types/utils.ts new file mode 100644 index 000000000..353ace6eb --- /dev/null +++ b/src/types/utils.ts @@ -0,0 +1,3 @@ +export type WithRequiredProp = Type & { + [Property in Key]-?: Type[Property]; +}; diff --git a/tsconfig.json b/tsconfig.json index d2f1e8a10..60ff18538 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -8,6 +8,7 @@ "strict": true, "esModuleInterop": true, "moduleResolution": "Node", + "resolveJsonModule": true, "outDir": "dist", "skipLibCheck": true }, diff --git a/vite.config.js b/vite.config.js index 835733984..20c7765c5 100644 --- a/vite.config.js +++ b/vite.config.js @@ -5,7 +5,8 @@ import { viteStaticCopy } from 'vite-plugin-static-copy'; import { vanillaExtractPlugin } from "@vanilla-extract/vite-plugin"; import { NodeGlobalsPolyfillPlugin } from '@esbuild-plugins/node-globals-polyfill'; import inject from '@rollup/plugin-inject'; -import { svgLoader } from './viteSvgLoader'; +import { svgLoader } from './viteSvgLoader' +import buildConfig from "./build.config" const copyFiles = { targets: [ @@ -18,7 +19,7 @@ const copyFiles = { dest: '', }, { - src: '_redirects', + src: 'netlify.toml', dest: '', }, { @@ -39,7 +40,7 @@ const copyFiles = { export default defineConfig({ appType: 'spa', publicDir: false, - base: "", + base: buildConfig.base, server: { port: 8080, host: true, From ef2733df4803aeedd6ff34832c62144cc6de0ca0 Mon Sep 17 00:00:00 2001 From: aceArt-GmbH <33117017+aceArt-GmbH@users.noreply.github.com> Date: Tue, 23 Jan 2024 14:05:50 +0100 Subject: [PATCH 1106/1531] Load assets from relative path (#1588) --- public/manifest.json | 20 ++++++++++---------- src/app/plugins/pdfjs-dist.ts | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/public/manifest.json b/public/manifest.json index f1d4a8827..acdcd0042 100644 --- a/public/manifest.json +++ b/public/manifest.json @@ -6,52 +6,52 @@ "lang": "en-US", "display": "standalone", "orientation": "portrait", - "start_url": "/", + "start_url": "./", "background_color": "#fff", "theme_color": "#fff", "icons": [ { - "src": "/public/android/android-chrome-36x36.png", + "src": "./public/android/android-chrome-36x36.png", "sizes": "36x36", "type": "image/png" }, { - "src": "/public/android/android-chrome-48x48.png", + "src": "./public/android/android-chrome-48x48.png", "sizes": "48x48", "type": "image/png" }, { - "src": "/public/android/android-chrome-72x72.png", + "src": "./public/android/android-chrome-72x72.png", "sizes": "72x72", "type": "image/png" }, { - "src": "/public/android/android-chrome-96x96.png", + "src": "./public/android/android-chrome-96x96.png", "sizes": "96x96", "type": "image/png" }, { - "src": "/public/android/android-chrome-144x144.png", + "src": "./public/android/android-chrome-144x144.png", "sizes": "144x144", "type": "image/png" }, { - "src": "/public/android/android-chrome-192x192.png", + "src": "./public/android/android-chrome-192x192.png", "sizes": "192x192", "type": "image/png" }, { - "src": "/public/android/android-chrome-256x256.png", + "src": "./public/android/android-chrome-256x256.png", "sizes": "256x256", "type": "image/png" }, { - "src": "/public/android/android-chrome-384x384.png", + "src": "./public/android/android-chrome-384x384.png", "sizes": "384x384", "type": "image/png" }, { - "src": "/public/android/android-chrome-512x512.png", + "src": "./public/android/android-chrome-512x512.png", "sizes": "512x512", "type": "image/png" } diff --git a/src/app/plugins/pdfjs-dist.ts b/src/app/plugins/pdfjs-dist.ts index ccdef5e54..5412ea458 100644 --- a/src/app/plugins/pdfjs-dist.ts +++ b/src/app/plugins/pdfjs-dist.ts @@ -7,7 +7,7 @@ export const usePdfJSLoader = () => useAsyncCallback( useCallback(async () => { const pdf = await import('pdfjs-dist'); - pdf.GlobalWorkerOptions.workerSrc = '/pdf.worker.min.js'; + pdf.GlobalWorkerOptions.workerSrc = 'pdf.worker.min.js'; return pdf; }, []) ); From 983d533452b337b4dc4c9e496a08791193b2818f Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Wed, 24 Jan 2024 00:06:55 +1100 Subject: [PATCH 1107/1531] feat: check IndexedDB support (#1630) * check indexed db support and display message * fix typo --- src/app/pages/App.tsx | 31 +++++++++++++------------ src/app/pages/FeatureCheck.tsx | 42 ++++++++++++++++++++++++++++++++++ src/app/utils/featureCheck.ts | 21 +++++++++++++++++ 3 files changed, 80 insertions(+), 14 deletions(-) create mode 100644 src/app/pages/FeatureCheck.tsx create mode 100644 src/app/utils/featureCheck.ts diff --git a/src/app/pages/App.tsx b/src/app/pages/App.tsx index 6cefe999c..62c173f91 100644 --- a/src/app/pages/App.tsx +++ b/src/app/pages/App.tsx @@ -17,6 +17,7 @@ import { isAuthenticated } from '../../client/state/auth'; import Client from '../templates/client/Client'; import { getLoginPath } from './pathUtils'; import { ConfigConfigError, ConfigConfigLoading } from './ConfigConfig'; +import { FeatureCheck } from './FeatureCheck'; const createRouter = (clientConfig: ClientConfig) => { const { hashRouter } = clientConfig; @@ -62,20 +63,22 @@ const createRouter = (clientConfig: ClientConfig) => { // TODO: app crash boundary function App() { return ( - } - error={(err, retry, ignore) => ( - - )} - > - {(clientConfig) => ( - - - - - - )} - + + } + error={(err, retry, ignore) => ( + + )} + > + {(clientConfig) => ( + + + + + + )} + + ); } diff --git a/src/app/pages/FeatureCheck.tsx b/src/app/pages/FeatureCheck.tsx new file mode 100644 index 000000000..abb366a85 --- /dev/null +++ b/src/app/pages/FeatureCheck.tsx @@ -0,0 +1,42 @@ +import React, { ReactNode, useEffect } from 'react'; +import { Box, Dialog, Text, config } from 'folds'; +import { AsyncStatus, useAsyncCallback } from '../hooks/useAsyncCallback'; +import { checkIndexedDBSupport } from '../utils/featureCheck'; +import { SplashScreen } from '../components/splash-screen'; + +export function FeatureCheck({ children }: { children: ReactNode }) { + const [idbSupportState, checkIDBSupport] = useAsyncCallback(checkIndexedDBSupport); + + useEffect(() => { + checkIDBSupport(); + }, [checkIDBSupport]); + + if (idbSupportState.status === AsyncStatus.Success && idbSupportState.data === false) { + return ( + + + + + Missing Browser Feature + + No IndexedDB support found. This application requires IndexedDB to store session + data locally. Please make sure your browser support IndexedDB and have it enabled. + + + + What is IndexedDB? + + + + + + + ); + } + + return children; +} diff --git a/src/app/utils/featureCheck.ts b/src/app/utils/featureCheck.ts new file mode 100644 index 000000000..a9474c317 --- /dev/null +++ b/src/app/utils/featureCheck.ts @@ -0,0 +1,21 @@ +export const checkIndexedDBSupport = async (): Promise => { + const ts = new Date().getTime(); + const dbName = `checkIndexedDBSupport-${ts}`; + return new Promise((resolve) => { + let db; + try { + db = indexedDB.open(dbName); + } catch { + resolve(false); + return; + } + db.onsuccess = () => { + resolve(true); + indexedDB.deleteDatabase(dbName); + }; + db.onerror = () => { + resolve(false); + indexedDB.deleteDatabase(dbName); + }; + }); +}; From 689adde8ae148d2de76bab0d11d7e0e8f35b7439 Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Wed, 24 Jan 2024 00:07:22 +1100 Subject: [PATCH 1108/1531] fix: login with sso when app using hash router (#1631) * fix login with sso when app using hash router * disable hash router --- src/app/pages/auth/login/Login.tsx | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/app/pages/auth/login/Login.tsx b/src/app/pages/auth/login/Login.tsx index 29a7b0ce7..901b19cbe 100644 --- a/src/app/pages/auth/login/Login.tsx +++ b/src/app/pages/auth/login/Login.tsx @@ -8,9 +8,20 @@ import { PasswordLoginForm } from './PasswordLoginForm'; import { SSOLogin } from '../SSOLogin'; import { TokenLogin } from './TokenLogin'; import { OrDivider } from '../OrDivider'; -import { getLoginPath, getRegisterPath } from '../../pathUtils'; +import { getLoginPath, getRegisterPath, withSearchParam } from '../../pathUtils'; import { usePathWithOrigin } from '../../../hooks/usePathWithOrigin'; import { LoginPathSearchParams } from '../../paths'; +import { useClientConfig } from '../../../hooks/useClientConfig'; + +const getLoginTokenSearchParam = () => { + // when using hasRouter query params in existing route + // gets ignored by react-router, so we need to read it ourself + // we only need to read loginToken as it's the only param that + // is provided by external entity. example: SSO login + const parmas = new URLSearchParams(window.location.search); + const loginToken = parmas.get('loginToken'); + return loginToken ?? undefined; +}; const getLoginSearchParams = (searchParams: URLSearchParams): LoginPathSearchParams => ({ username: searchParams.get('username') ?? undefined, @@ -20,10 +31,21 @@ const getLoginSearchParams = (searchParams: URLSearchParams): LoginPathSearchPar export function Login() { const server = useAuthServer(); + const { hashRouter } = useClientConfig(); const { loginFlows } = useAuthFlows(); const [searchParams] = useSearchParams(); const loginSearchParams = getLoginSearchParams(searchParams); const ssoRedirectUrl = usePathWithOrigin(getLoginPath(server)); + const loginTokenForHashRouter = getLoginTokenSearchParam(); + const absoluteLoginPath = usePathWithOrigin(getLoginPath(server)); + + if (hashRouter?.enabled && loginTokenForHashRouter) { + window.location.replace( + withSearchParam(absoluteLoginPath, { + loginToken: loginTokenForHashRouter, + }) + ); + } const parsedFlows = useParsedLoginFlows(loginFlows.flows); From b0796f72d3d1c746825e728ff0e5369f78ed1e1e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 30 Mar 2024 12:57:56 +1100 Subject: [PATCH 1109/1531] fix(deps): update dependency katex to v0.16.10 [security] (#1654) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package-lock.json | 26 +++++++++++++------------- package.json | 2 +- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/package-lock.json b/package-lock.json index fba4072e6..d35789355 100644 --- a/package-lock.json +++ b/package-lock.json @@ -36,7 +36,7 @@ "immer": "9.0.16", "is-hotkey": "0.2.0", "jotai": "2.6.0", - "katex": "0.16.4", + "katex": "0.16.10", "linkify-html": "4.0.2", "linkify-react": "4.1.1", "linkifyjs": "4.0.2", @@ -4005,6 +4005,14 @@ "color-support": "bin.js" } }, + "node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "engines": { + "node": ">= 12" + } + }, "node_modules/compute-scroll-into-view": { "version": "1.0.20", "resolved": "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-1.0.20.tgz", @@ -6108,28 +6116,20 @@ "integrity": "sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A==" }, "node_modules/katex": { - "version": "0.16.4", - "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.4.tgz", - "integrity": "sha512-WudRKUj8yyBeVDI4aYMNxhx5Vhh2PjpzQw1GRu/LVGqL4m1AxwD1GcUp0IMbdJaf5zsjtj8ghP0DOQRYhroNkw==", + "version": "0.16.10", + "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.10.tgz", + "integrity": "sha512-ZiqaC04tp2O5utMsl2TEZTXxa6WSC4yo0fv5ML++D3QZv/vx2Mct0mTlRx3O+uUkjfuAgOkzsCmq5MiUEsDDdA==", "funding": [ "https://opencollective.com/katex", "https://github.com/sponsors/katex" ], "dependencies": { - "commander": "^8.0.0" + "commander": "^8.3.0" }, "bin": { "katex": "cli.js" } }, - "node_modules/katex/node_modules/commander": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", - "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", - "engines": { - "node": ">= 12" - } - }, "node_modules/language-subtag-registry": { "version": "0.3.22", "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz", diff --git a/package.json b/package.json index 56e7b8c01..84b1868da 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,7 @@ "immer": "9.0.16", "is-hotkey": "0.2.0", "jotai": "2.6.0", - "katex": "0.16.4", + "katex": "0.16.10", "linkify-html": "4.0.2", "linkify-react": "4.1.1", "linkifyjs": "4.0.2", From 372d4d5c3455b5c61e9a82ec8d64780e3d9caf49 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 8 Apr 2024 15:18:29 +1000 Subject: [PATCH 1110/1531] chore(deps): update dependency vite to v5.0.13 [security] (#1680) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package-lock.json | 207 +++++++++++++++++++++++++--------------------- package.json | 2 +- 2 files changed, 113 insertions(+), 96 deletions(-) diff --git a/package-lock.json b/package-lock.json index d35789355..5b3ebdc04 100644 --- a/package-lock.json +++ b/package-lock.json @@ -92,7 +92,7 @@ "prettier": "2.8.1", "sass": "1.56.2", "typescript": "4.9.4", - "vite": "5.0.8", + "vite": "5.0.13", "vite-plugin-static-copy": "0.13.0" }, "engines": { @@ -505,6 +505,22 @@ "esbuild": "*" } }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz", + "integrity": "sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/@esbuild/android-arm": { "version": "0.16.9", "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.16.9.tgz", @@ -8105,9 +8121,9 @@ } }, "node_modules/vite": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.0.8.tgz", - "integrity": "sha512-jYMALd8aeqR3yS9xlHd0OzQJndS9fH5ylVgWdB+pxTwxLKdO1pgC5Dlb398BUxpfaBxa4M9oT7j1g503Gaj5IQ==", + "version": "5.0.13", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.0.13.tgz", + "integrity": "sha512-/9ovhv2M2dGTuA+dY93B9trfyWMDRQw2jdVBhHNP6wr0oF34wG2i/N55801iZIpgUpnHDm4F/FabGQLyc+eOgg==", "dev": true, "dependencies": { "esbuild": "^0.19.3", @@ -8213,9 +8229,9 @@ } }, "node_modules/vite/node_modules/@esbuild/android-arm": { - "version": "0.19.9", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.9.tgz", - "integrity": "sha512-jkYjjq7SdsWuNI6b5quymW0oC83NN5FdRPuCbs9HZ02mfVdAP8B8eeqLSYU3gb6OJEaY5CQabtTFbqBf26H3GA==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.12.tgz", + "integrity": "sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==", "cpu": [ "arm" ], @@ -8229,9 +8245,9 @@ } }, "node_modules/vite/node_modules/@esbuild/android-arm64": { - "version": "0.19.9", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.9.tgz", - "integrity": "sha512-q4cR+6ZD0938R19MyEW3jEsMzbb/1rulLXiNAJQADD/XYp7pT+rOS5JGxvpRW8dFDEfjW4wLgC/3FXIw4zYglQ==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz", + "integrity": "sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==", "cpu": [ "arm64" ], @@ -8245,9 +8261,9 @@ } }, "node_modules/vite/node_modules/@esbuild/android-x64": { - "version": "0.19.9", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.9.tgz", - "integrity": "sha512-KOqoPntWAH6ZxDwx1D6mRntIgZh9KodzgNOy5Ebt9ghzffOk9X2c1sPwtM9P+0eXbefnDhqYfkh5PLP5ULtWFA==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.12.tgz", + "integrity": "sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==", "cpu": [ "x64" ], @@ -8261,9 +8277,9 @@ } }, "node_modules/vite/node_modules/@esbuild/darwin-arm64": { - "version": "0.19.9", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.9.tgz", - "integrity": "sha512-KBJ9S0AFyLVx2E5D8W0vExqRW01WqRtczUZ8NRu+Pi+87opZn5tL4Y0xT0mA4FtHctd0ZgwNoN639fUUGlNIWw==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz", + "integrity": "sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==", "cpu": [ "arm64" ], @@ -8277,9 +8293,9 @@ } }, "node_modules/vite/node_modules/@esbuild/darwin-x64": { - "version": "0.19.9", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.9.tgz", - "integrity": "sha512-vE0VotmNTQaTdX0Q9dOHmMTao6ObjyPm58CHZr1UK7qpNleQyxlFlNCaHsHx6Uqv86VgPmR4o2wdNq3dP1qyDQ==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz", + "integrity": "sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==", "cpu": [ "x64" ], @@ -8293,9 +8309,9 @@ } }, "node_modules/vite/node_modules/@esbuild/freebsd-arm64": { - "version": "0.19.9", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.9.tgz", - "integrity": "sha512-uFQyd/o1IjiEk3rUHSwUKkqZwqdvuD8GevWF065eqgYfexcVkxh+IJgwTaGZVu59XczZGcN/YMh9uF1fWD8j1g==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz", + "integrity": "sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==", "cpu": [ "arm64" ], @@ -8309,9 +8325,9 @@ } }, "node_modules/vite/node_modules/@esbuild/freebsd-x64": { - "version": "0.19.9", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.9.tgz", - "integrity": "sha512-WMLgWAtkdTbTu1AWacY7uoj/YtHthgqrqhf1OaEWnZb7PQgpt8eaA/F3LkV0E6K/Lc0cUr/uaVP/49iE4M4asA==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz", + "integrity": "sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==", "cpu": [ "x64" ], @@ -8325,9 +8341,9 @@ } }, "node_modules/vite/node_modules/@esbuild/linux-arm": { - "version": "0.19.9", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.9.tgz", - "integrity": "sha512-C/ChPohUYoyUaqn1h17m/6yt6OB14hbXvT8EgM1ZWaiiTYz7nWZR0SYmMnB5BzQA4GXl3BgBO1l8MYqL/He3qw==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz", + "integrity": "sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==", "cpu": [ "arm" ], @@ -8341,9 +8357,9 @@ } }, "node_modules/vite/node_modules/@esbuild/linux-arm64": { - "version": "0.19.9", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.9.tgz", - "integrity": "sha512-PiPblfe1BjK7WDAKR1Cr9O7VVPqVNpwFcPWgfn4xu0eMemzRp442hXyzF/fSwgrufI66FpHOEJk0yYdPInsmyQ==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz", + "integrity": "sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==", "cpu": [ "arm64" ], @@ -8357,9 +8373,9 @@ } }, "node_modules/vite/node_modules/@esbuild/linux-ia32": { - "version": "0.19.9", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.9.tgz", - "integrity": "sha512-f37i/0zE0MjDxijkPSQw1CO/7C27Eojqb+r3BbHVxMLkj8GCa78TrBZzvPyA/FNLUMzP3eyHCVkAopkKVja+6Q==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz", + "integrity": "sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==", "cpu": [ "ia32" ], @@ -8373,9 +8389,9 @@ } }, "node_modules/vite/node_modules/@esbuild/linux-loong64": { - "version": "0.19.9", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.9.tgz", - "integrity": "sha512-t6mN147pUIf3t6wUt3FeumoOTPfmv9Cc6DQlsVBpB7eCpLOqQDyWBP1ymXn1lDw4fNUSb/gBcKAmvTP49oIkaA==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz", + "integrity": "sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==", "cpu": [ "loong64" ], @@ -8389,9 +8405,9 @@ } }, "node_modules/vite/node_modules/@esbuild/linux-mips64el": { - "version": "0.19.9", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.9.tgz", - "integrity": "sha512-jg9fujJTNTQBuDXdmAg1eeJUL4Jds7BklOTkkH80ZgQIoCTdQrDaHYgbFZyeTq8zbY+axgptncko3v9p5hLZtw==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz", + "integrity": "sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==", "cpu": [ "mips64el" ], @@ -8405,9 +8421,9 @@ } }, "node_modules/vite/node_modules/@esbuild/linux-ppc64": { - "version": "0.19.9", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.9.tgz", - "integrity": "sha512-tkV0xUX0pUUgY4ha7z5BbDS85uI7ABw3V1d0RNTii7E9lbmV8Z37Pup2tsLV46SQWzjOeyDi1Q7Wx2+QM8WaCQ==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz", + "integrity": "sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==", "cpu": [ "ppc64" ], @@ -8421,9 +8437,9 @@ } }, "node_modules/vite/node_modules/@esbuild/linux-riscv64": { - "version": "0.19.9", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.9.tgz", - "integrity": "sha512-DfLp8dj91cufgPZDXr9p3FoR++m3ZJ6uIXsXrIvJdOjXVREtXuQCjfMfvmc3LScAVmLjcfloyVtpn43D56JFHg==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz", + "integrity": "sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==", "cpu": [ "riscv64" ], @@ -8437,9 +8453,9 @@ } }, "node_modules/vite/node_modules/@esbuild/linux-s390x": { - "version": "0.19.9", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.9.tgz", - "integrity": "sha512-zHbglfEdC88KMgCWpOl/zc6dDYJvWGLiUtmPRsr1OgCViu3z5GncvNVdf+6/56O2Ca8jUU+t1BW261V6kp8qdw==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz", + "integrity": "sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==", "cpu": [ "s390x" ], @@ -8453,9 +8469,9 @@ } }, "node_modules/vite/node_modules/@esbuild/linux-x64": { - "version": "0.19.9", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.9.tgz", - "integrity": "sha512-JUjpystGFFmNrEHQnIVG8hKwvA2DN5o7RqiO1CVX8EN/F/gkCjkUMgVn6hzScpwnJtl2mPR6I9XV1oW8k9O+0A==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz", + "integrity": "sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==", "cpu": [ "x64" ], @@ -8469,9 +8485,9 @@ } }, "node_modules/vite/node_modules/@esbuild/netbsd-x64": { - "version": "0.19.9", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.9.tgz", - "integrity": "sha512-GThgZPAwOBOsheA2RUlW5UeroRfESwMq/guy8uEe3wJlAOjpOXuSevLRd70NZ37ZrpO6RHGHgEHvPg1h3S1Jug==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz", + "integrity": "sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==", "cpu": [ "x64" ], @@ -8485,9 +8501,9 @@ } }, "node_modules/vite/node_modules/@esbuild/openbsd-x64": { - "version": "0.19.9", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.9.tgz", - "integrity": "sha512-Ki6PlzppaFVbLnD8PtlVQfsYw4S9n3eQl87cqgeIw+O3sRr9IghpfSKY62mggdt1yCSZ8QWvTZ9jo9fjDSg9uw==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz", + "integrity": "sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==", "cpu": [ "x64" ], @@ -8501,9 +8517,9 @@ } }, "node_modules/vite/node_modules/@esbuild/sunos-x64": { - "version": "0.19.9", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.9.tgz", - "integrity": "sha512-MLHj7k9hWh4y1ddkBpvRj2b9NCBhfgBt3VpWbHQnXRedVun/hC7sIyTGDGTfsGuXo4ebik2+3ShjcPbhtFwWDw==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz", + "integrity": "sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==", "cpu": [ "x64" ], @@ -8517,9 +8533,9 @@ } }, "node_modules/vite/node_modules/@esbuild/win32-arm64": { - "version": "0.19.9", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.9.tgz", - "integrity": "sha512-GQoa6OrQ8G08guMFgeXPH7yE/8Dt0IfOGWJSfSH4uafwdC7rWwrfE6P9N8AtPGIjUzdo2+7bN8Xo3qC578olhg==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz", + "integrity": "sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==", "cpu": [ "arm64" ], @@ -8533,9 +8549,9 @@ } }, "node_modules/vite/node_modules/@esbuild/win32-ia32": { - "version": "0.19.9", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.9.tgz", - "integrity": "sha512-UOozV7Ntykvr5tSOlGCrqU3NBr3d8JqPes0QWN2WOXfvkWVGRajC+Ym0/Wj88fUgecUCLDdJPDF0Nna2UK3Qtg==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz", + "integrity": "sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==", "cpu": [ "ia32" ], @@ -8549,9 +8565,9 @@ } }, "node_modules/vite/node_modules/@esbuild/win32-x64": { - "version": "0.19.9", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.9.tgz", - "integrity": "sha512-oxoQgglOP7RH6iasDrhY+R/3cHrfwIDvRlT4CGChflq6twk8iENeVvMJjmvBb94Ik1Z+93iGO27err7w6l54GQ==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz", + "integrity": "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==", "cpu": [ "x64" ], @@ -8565,9 +8581,9 @@ } }, "node_modules/vite/node_modules/esbuild": { - "version": "0.19.9", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.9.tgz", - "integrity": "sha512-U9CHtKSy+EpPsEBa+/A2gMs/h3ylBC0H0KSqIg7tpztHerLi6nrrcoUJAkNCEPumx8yJ+Byic4BVwHgRbN0TBg==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.12.tgz", + "integrity": "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==", "dev": true, "hasInstallScript": true, "bin": { @@ -8577,28 +8593,29 @@ "node": ">=12" }, "optionalDependencies": { - "@esbuild/android-arm": "0.19.9", - "@esbuild/android-arm64": "0.19.9", - "@esbuild/android-x64": "0.19.9", - "@esbuild/darwin-arm64": "0.19.9", - "@esbuild/darwin-x64": "0.19.9", - "@esbuild/freebsd-arm64": "0.19.9", - "@esbuild/freebsd-x64": "0.19.9", - "@esbuild/linux-arm": "0.19.9", - "@esbuild/linux-arm64": "0.19.9", - "@esbuild/linux-ia32": "0.19.9", - "@esbuild/linux-loong64": "0.19.9", - "@esbuild/linux-mips64el": "0.19.9", - "@esbuild/linux-ppc64": "0.19.9", - "@esbuild/linux-riscv64": "0.19.9", - "@esbuild/linux-s390x": "0.19.9", - "@esbuild/linux-x64": "0.19.9", - "@esbuild/netbsd-x64": "0.19.9", - "@esbuild/openbsd-x64": "0.19.9", - "@esbuild/sunos-x64": "0.19.9", - "@esbuild/win32-arm64": "0.19.9", - "@esbuild/win32-ia32": "0.19.9", - "@esbuild/win32-x64": "0.19.9" + "@esbuild/aix-ppc64": "0.19.12", + "@esbuild/android-arm": "0.19.12", + "@esbuild/android-arm64": "0.19.12", + "@esbuild/android-x64": "0.19.12", + "@esbuild/darwin-arm64": "0.19.12", + "@esbuild/darwin-x64": "0.19.12", + "@esbuild/freebsd-arm64": "0.19.12", + "@esbuild/freebsd-x64": "0.19.12", + "@esbuild/linux-arm": "0.19.12", + "@esbuild/linux-arm64": "0.19.12", + "@esbuild/linux-ia32": "0.19.12", + "@esbuild/linux-loong64": "0.19.12", + "@esbuild/linux-mips64el": "0.19.12", + "@esbuild/linux-ppc64": "0.19.12", + "@esbuild/linux-riscv64": "0.19.12", + "@esbuild/linux-s390x": "0.19.12", + "@esbuild/linux-x64": "0.19.12", + "@esbuild/netbsd-x64": "0.19.12", + "@esbuild/openbsd-x64": "0.19.12", + "@esbuild/sunos-x64": "0.19.12", + "@esbuild/win32-arm64": "0.19.12", + "@esbuild/win32-ia32": "0.19.12", + "@esbuild/win32-x64": "0.19.12" } }, "node_modules/warning": { diff --git a/package.json b/package.json index 84b1868da..7660b1744 100644 --- a/package.json +++ b/package.json @@ -102,7 +102,7 @@ "prettier": "2.8.1", "sass": "1.56.2", "typescript": "4.9.4", - "vite": "5.0.8", + "vite": "5.0.13", "vite-plugin-static-copy": "0.13.0" } } From 8c5a1d15cb899cbac78641d5027390c1e40f9747 Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Wed, 24 Apr 2024 18:12:52 +0530 Subject: [PATCH 1111/1531] fix negative audio duration info crash react-range (#1701) --- src/app/organisms/room/message/AudioContent.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/app/organisms/room/message/AudioContent.tsx b/src/app/organisms/room/message/AudioContent.tsx index eae5447ba..83e5dc010 100644 --- a/src/app/organisms/room/message/AudioContent.tsx +++ b/src/app/organisms/room/message/AudioContent.tsx @@ -45,7 +45,8 @@ export const AudioContent = as<'div', AudioContentProps>( const [currentTime, setCurrentTime] = useState(0); // duration in seconds. (NOTE: info.duration is in milliseconds) - const [duration, setDuration] = useState((info.duration ?? 0) / 1000); + const infoDuration = info.duration ?? 0; + const [duration, setDuration] = useState((infoDuration >= 0 ? infoDuration : 0) / 1000); const getAudioRef = useCallback(() => audioRef.current, []); const { loading } = useMediaLoading(getAudioRef); From 743e916d12ba14cba5b2ee75cc02a7a65dd37db1 Mon Sep 17 00:00:00 2001 From: Arnaldo Gabriel <5076526+agmm@users.noreply.github.com> Date: Wed, 24 Apr 2024 08:44:32 -0400 Subject: [PATCH 1112/1531] Fix placement of emoji/sticker buttons (#1693) --- src/app/components/emoji-board/EmojiBoard.tsx | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/app/components/emoji-board/EmojiBoard.tsx b/src/app/components/emoji-board/EmojiBoard.tsx index 5452722fe..408ce85dd 100644 --- a/src/app/components/emoji-board/EmojiBoard.tsx +++ b/src/app/components/emoji-board/EmojiBoard.tsx @@ -174,18 +174,6 @@ function EmojiBoardTabs({ }) { return ( - onTabChange(EmojiBoardTab.Emoji)} - > - - Emoji - - + onTabChange(EmojiBoardTab.Emoji)} + > + + Emoji + + ); } From 3025133d18057075f34d0b7b7f20a75b55924bb8 Mon Sep 17 00:00:00 2001 From: Krishan <33421343+kfiven@users.noreply.github.com> Date: Thu, 25 Apr 2024 00:31:01 +1000 Subject: [PATCH 1113/1531] Update node to latest LTS (#1687) * Update node to latest LTS * Update node in Dockerfile --- .github/workflows/build-pull-request.yml | 6 +++--- .github/workflows/netlify-dev.yml | 10 +++++----- .github/workflows/prod-deploy.yml | 8 ++++---- Dockerfile | 2 +- README.md | 2 +- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/.github/workflows/build-pull-request.yml b/.github/workflows/build-pull-request.yml index f2f93feb4..5346a762f 100644 --- a/.github/workflows/build-pull-request.yml +++ b/.github/workflows/build-pull-request.yml @@ -16,13 +16,13 @@ jobs: - name: Setup node uses: actions/setup-node@v3.8.1 with: - node-version: 18.12.1 - cache: "npm" + node-version: 20.12.2 + cache: 'npm' - name: Install dependencies run: npm ci - name: Build app env: - NODE_OPTIONS: "--max_old_space_size=4096" + NODE_OPTIONS: '--max_old_space_size=4096' run: npm run build - name: Upload artifact uses: actions/upload-artifact@v3.1.2 diff --git a/.github/workflows/netlify-dev.yml b/.github/workflows/netlify-dev.yml index 411b6e3e3..c3de8811c 100644 --- a/.github/workflows/netlify-dev.yml +++ b/.github/workflows/netlify-dev.yml @@ -3,7 +3,7 @@ name: Deploy to Netlify (dev) on: push: branches: - - dev + - dev jobs: deploy-to-netlify: @@ -15,19 +15,19 @@ jobs: - name: Setup node uses: actions/setup-node@v3.8.1 with: - node-version: 18.12.1 - cache: "npm" + node-version: 20.12.2 + cache: 'npm' - name: Install dependencies run: npm ci - name: Build app env: - NODE_OPTIONS: "--max_old_space_size=4096" + NODE_OPTIONS: '--max_old_space_size=4096' run: npm run build - name: Deploy to Netlify uses: nwtgck/actions-netlify@7a92f00dde8c92a5a9e8385ec2919775f7647352 with: publish-dir: dist - deploy-message: "Dev deploy ${{ github.sha }}" + deploy-message: 'Dev deploy ${{ github.sha }}' enable-commit-comment: false github-token: ${{ secrets.GITHUB_TOKEN }} production-deploy: true diff --git a/.github/workflows/prod-deploy.yml b/.github/workflows/prod-deploy.yml index 63fc342c9..83e6ed8f7 100644 --- a/.github/workflows/prod-deploy.yml +++ b/.github/workflows/prod-deploy.yml @@ -14,19 +14,19 @@ jobs: - name: Setup node uses: actions/setup-node@v3.8.1 with: - node-version: 18.12.1 - cache: "npm" + node-version: 20.12.2 + cache: 'npm' - name: Install dependencies run: npm ci - name: Build app env: - NODE_OPTIONS: "--max_old_space_size=4096" + NODE_OPTIONS: '--max_old_space_size=4096' run: npm run build - name: Deploy to Netlify uses: nwtgck/actions-netlify@7a92f00dde8c92a5a9e8385ec2919775f7647352 with: publish-dir: dist - deploy-message: "Prod deploy ${{ github.ref_name }}" + deploy-message: 'Prod deploy ${{ github.ref_name }}' enable-commit-comment: false github-token: ${{ secrets.GITHUB_TOKEN }} production-deploy: true diff --git a/Dockerfile b/Dockerfile index da04492cd..b0d2a9356 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ ## Builder -FROM node:18.12.1-alpine3.15 as builder +FROM node:20.12.2-alpine3.18 as builder WORKDIR /src diff --git a/README.md b/README.md index 0910dfbb2..0fc928b6e 100644 --- a/README.md +++ b/README.md @@ -86,7 +86,7 @@ UeGsouhyuITLwEhScounZDqop+Dx ## Local development > We recommend using a version manager as versions change very quickly. You will likely need to switch -between multiple Node.js versions based on the needs of different projects you're working on. [NVM on windows](https://github.com/coreybutler/nvm-windows#installation--upgrades) on Windows and [nvm](https://github.com/nvm-sh/nvm) on Linux/macOS are pretty good choices. Also recommended nodejs version Hydrogen LTS (v18). +between multiple Node.js versions based on the needs of different projects you're working on. [NVM on windows](https://github.com/coreybutler/nvm-windows#installation--upgrades) on Windows and [nvm](https://github.com/nvm-sh/nvm) on Linux/macOS are pretty good choices. Recommended nodejs version is Iron LTS (v20). Execute the following commands to start a development server: ```sh From a18c2e5be18eb37bdd63a0edb61d1f0faa125605 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 Apr 2024 00:32:24 +1000 Subject: [PATCH 1114/1531] Bump actions/checkout from 3.5.3 to 4.1.3 (#1699) Bumps [actions/checkout](https://github.com/actions/checkout) from 3.5.3 to 4.1.3. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v3.5.3...v4.1.3) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build-pull-request.yml | 2 +- .github/workflows/docker-pr.yml | 2 +- .github/workflows/lockfile.yml | 2 +- .github/workflows/netlify-dev.yml | 2 +- .github/workflows/prod-deploy.yml | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build-pull-request.yml b/.github/workflows/build-pull-request.yml index 5346a762f..72ffd0e42 100644 --- a/.github/workflows/build-pull-request.yml +++ b/.github/workflows/build-pull-request.yml @@ -12,7 +12,7 @@ jobs: PR_NUMBER: ${{github.event.number}} steps: - name: Checkout repository - uses: actions/checkout@v3.5.3 + uses: actions/checkout@v4.1.3 - name: Setup node uses: actions/setup-node@v3.8.1 with: diff --git a/.github/workflows/docker-pr.yml b/.github/workflows/docker-pr.yml index 302351575..7d1f2b8d0 100644 --- a/.github/workflows/docker-pr.yml +++ b/.github/workflows/docker-pr.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v3.5.3 + uses: actions/checkout@v4.1.3 - name: Build Docker image uses: docker/build-push-action@v4.1.1 with: diff --git a/.github/workflows/lockfile.yml b/.github/workflows/lockfile.yml index 30d00760a..1b116b5a5 100644 --- a/.github/workflows/lockfile.yml +++ b/.github/workflows/lockfile.yml @@ -14,7 +14,7 @@ jobs: pull-requests: write steps: - name: Checkout - uses: actions/checkout@v3.5.3 + uses: actions/checkout@v4.1.3 - name: NPM Lockfile Changes uses: codepunkt/npm-lockfile-changes@b40543471c36394409466fdb277a73a0856d7891 with: diff --git a/.github/workflows/netlify-dev.yml b/.github/workflows/netlify-dev.yml index c3de8811c..0eb4ed725 100644 --- a/.github/workflows/netlify-dev.yml +++ b/.github/workflows/netlify-dev.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v3.5.3 + uses: actions/checkout@v4.1.3 - name: Setup node uses: actions/setup-node@v3.8.1 with: diff --git a/.github/workflows/prod-deploy.yml b/.github/workflows/prod-deploy.yml index 83e6ed8f7..70e40c076 100644 --- a/.github/workflows/prod-deploy.yml +++ b/.github/workflows/prod-deploy.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v3.5.3 + uses: actions/checkout@v4.1.3 - name: Setup node uses: actions/setup-node@v3.8.1 with: @@ -66,7 +66,7 @@ jobs: packages: write steps: - name: Checkout repository - uses: actions/checkout@v3.5.3 + uses: actions/checkout@v4.1.3 - name: Set up QEMU uses: docker/setup-qemu-action@v2.2.0 - name: Set up Docker Buildx From b97f410731847a4a82763b76483aa46dae3f6bc1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 Apr 2024 00:34:04 +1000 Subject: [PATCH 1115/1531] Bump nginx from 1.25.1-alpine to 1.25.5-alpine (#1700) Bumps nginx from 1.25.1-alpine to 1.25.5-alpine. --- updated-dependencies: - dependency-name: nginx dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index b0d2a9356..6cd3ebf61 100644 --- a/Dockerfile +++ b/Dockerfile @@ -11,7 +11,7 @@ RUN npm run build ## App -FROM nginx:1.25.1-alpine +FROM nginx:1.25.5-alpine COPY --from=builder /src/dist /app From 1d799185d61f60c22903f55346c92548c862c411 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 Apr 2024 22:26:46 +1000 Subject: [PATCH 1116/1531] Bump actions/upload-artifact from 3.1.2 to 4.3.3 (#1698) Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 3.1.2 to 4.3.3. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/v3.1.2...v4.3.3) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build-pull-request.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-pull-request.yml b/.github/workflows/build-pull-request.yml index 72ffd0e42..8163c6afc 100644 --- a/.github/workflows/build-pull-request.yml +++ b/.github/workflows/build-pull-request.yml @@ -25,7 +25,7 @@ jobs: NODE_OPTIONS: '--max_old_space_size=4096' run: npm run build - name: Upload artifact - uses: actions/upload-artifact@v3.1.2 + uses: actions/upload-artifact@v4.3.3 with: name: preview path: dist @@ -33,7 +33,7 @@ jobs: - name: Save pr number run: echo ${PR_NUMBER} > ./pr.txt - name: Upload pr number - uses: actions/upload-artifact@v3.1.2 + uses: actions/upload-artifact@v4.3.3 with: name: pr path: ./pr.txt From 71b2859440e8f0e95815e790af96284f90641357 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 Apr 2024 22:28:46 +1000 Subject: [PATCH 1117/1531] Bump docker/setup-qemu-action from 2.2.0 to 3.0.0 (#1662) Bumps [docker/setup-qemu-action](https://github.com/docker/setup-qemu-action) from 2.2.0 to 3.0.0. - [Release notes](https://github.com/docker/setup-qemu-action/releases) - [Commits](https://github.com/docker/setup-qemu-action/compare/v2.2.0...v3.0.0) --- updated-dependencies: - dependency-name: docker/setup-qemu-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/prod-deploy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/prod-deploy.yml b/.github/workflows/prod-deploy.yml index 70e40c076..e6de54f9c 100644 --- a/.github/workflows/prod-deploy.yml +++ b/.github/workflows/prod-deploy.yml @@ -68,7 +68,7 @@ jobs: - name: Checkout repository uses: actions/checkout@v4.1.3 - name: Set up QEMU - uses: docker/setup-qemu-action@v2.2.0 + uses: docker/setup-qemu-action@v3.0.0 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v2.7.0 - name: Login to Docker Hub From 2c1e51a8b8caa9dbb1af32f97b50bc692ac7bf63 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 Apr 2024 22:30:16 +1000 Subject: [PATCH 1118/1531] Bump docker/login-action from 2.2.0 to 3.1.0 (#1661) Bumps [docker/login-action](https://github.com/docker/login-action) from 2.2.0 to 3.1.0. - [Release notes](https://github.com/docker/login-action/releases) - [Commits](https://github.com/docker/login-action/compare/v2.2.0...v3.1.0) --- updated-dependencies: - dependency-name: docker/login-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/prod-deploy.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/prod-deploy.yml b/.github/workflows/prod-deploy.yml index e6de54f9c..7f24295cd 100644 --- a/.github/workflows/prod-deploy.yml +++ b/.github/workflows/prod-deploy.yml @@ -72,12 +72,12 @@ jobs: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v2.7.0 - name: Login to Docker Hub - uses: docker/login-action@v2.2.0 + uses: docker/login-action@v3.1.0 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} - name: Login to the Container registry - uses: docker/login-action@v2.2.0 + uses: docker/login-action@v3.1.0 with: registry: ghcr.io username: ${{ github.actor }} From ca3535b1a5d3214b22b6d48d30889ea48a89bb3f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 Apr 2024 22:31:41 +1000 Subject: [PATCH 1119/1531] Bump docker/metadata-action from 4.6.0 to 5.5.1 (#1658) Bumps [docker/metadata-action](https://github.com/docker/metadata-action) from 4.6.0 to 5.5.1. - [Release notes](https://github.com/docker/metadata-action/releases) - [Upgrade guide](https://github.com/docker/metadata-action/blob/master/UPGRADE.md) - [Commits](https://github.com/docker/metadata-action/compare/v4.6.0...v5.5.1) --- updated-dependencies: - dependency-name: docker/metadata-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/prod-deploy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/prod-deploy.yml b/.github/workflows/prod-deploy.yml index 7f24295cd..35f6d0f26 100644 --- a/.github/workflows/prod-deploy.yml +++ b/.github/workflows/prod-deploy.yml @@ -84,7 +84,7 @@ jobs: password: ${{ secrets.GITHUB_TOKEN }} - name: Extract metadata (tags, labels) for Docker id: meta - uses: docker/metadata-action@v4.6.0 + uses: docker/metadata-action@v5.5.1 with: images: | ${{ secrets.DOCKER_USERNAME }}/cinny From da5ebf7ab36a2c704986b120dd42768373e2eef9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 Apr 2024 22:56:29 +1000 Subject: [PATCH 1120/1531] Bump actions/setup-node from 3.8.1 to 4.0.2 (#1707) Bumps [actions/setup-node](https://github.com/actions/setup-node) from 3.8.1 to 4.0.2. - [Release notes](https://github.com/actions/setup-node/releases) - [Commits](https://github.com/actions/setup-node/compare/v3.8.1...v4.0.2) --- updated-dependencies: - dependency-name: actions/setup-node dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build-pull-request.yml | 2 +- .github/workflows/netlify-dev.yml | 2 +- .github/workflows/prod-deploy.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-pull-request.yml b/.github/workflows/build-pull-request.yml index 8163c6afc..a574c6782 100644 --- a/.github/workflows/build-pull-request.yml +++ b/.github/workflows/build-pull-request.yml @@ -14,7 +14,7 @@ jobs: - name: Checkout repository uses: actions/checkout@v4.1.3 - name: Setup node - uses: actions/setup-node@v3.8.1 + uses: actions/setup-node@v4.0.2 with: node-version: 20.12.2 cache: 'npm' diff --git a/.github/workflows/netlify-dev.yml b/.github/workflows/netlify-dev.yml index 0eb4ed725..7c90aec72 100644 --- a/.github/workflows/netlify-dev.yml +++ b/.github/workflows/netlify-dev.yml @@ -13,7 +13,7 @@ jobs: - name: Checkout repository uses: actions/checkout@v4.1.3 - name: Setup node - uses: actions/setup-node@v3.8.1 + uses: actions/setup-node@v4.0.2 with: node-version: 20.12.2 cache: 'npm' diff --git a/.github/workflows/prod-deploy.yml b/.github/workflows/prod-deploy.yml index 35f6d0f26..bec41af3b 100644 --- a/.github/workflows/prod-deploy.yml +++ b/.github/workflows/prod-deploy.yml @@ -12,7 +12,7 @@ jobs: - name: Checkout repository uses: actions/checkout@v4.1.3 - name: Setup node - uses: actions/setup-node@v3.8.1 + uses: actions/setup-node@v4.0.2 with: node-version: 20.12.2 cache: 'npm' From 53cd08f0da500f656ce2ee32e132a64d1b78570a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 Apr 2024 22:57:14 +1000 Subject: [PATCH 1121/1531] Bump dawidd6/action-download-artifact from 2.27.0 to 3.1.4 (#1706) Bumps [dawidd6/action-download-artifact](https://github.com/dawidd6/action-download-artifact) from 2.27.0 to 3.1.4. - [Release notes](https://github.com/dawidd6/action-download-artifact/releases) - [Commits](https://github.com/dawidd6/action-download-artifact/compare/246dbf436b23d7c49e21a7ab8204ca9ecd1fe615...09f2f74827fd3a8607589e5ad7f9398816f540fe) --- updated-dependencies: - dependency-name: dawidd6/action-download-artifact dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/deploy-pull-request.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/deploy-pull-request.yml b/.github/workflows/deploy-pull-request.yml index 12eabbe45..e73993161 100644 --- a/.github/workflows/deploy-pull-request.yml +++ b/.github/workflows/deploy-pull-request.yml @@ -15,7 +15,7 @@ jobs: if: ${{ github.event.workflow_run.conclusion == 'success' }} steps: - name: Download pr number - uses: dawidd6/action-download-artifact@246dbf436b23d7c49e21a7ab8204ca9ecd1fe615 + uses: dawidd6/action-download-artifact@09f2f74827fd3a8607589e5ad7f9398816f540fe with: workflow: ${{ github.event.workflow.id }} run_id: ${{ github.event.workflow_run.id }} @@ -24,7 +24,7 @@ jobs: id: pr run: echo "id=$(> $GITHUB_OUTPUT - name: Download artifact - uses: dawidd6/action-download-artifact@246dbf436b23d7c49e21a7ab8204ca9ecd1fe615 + uses: dawidd6/action-download-artifact@09f2f74827fd3a8607589e5ad7f9398816f540fe with: workflow: ${{ github.event.workflow.id }} run_id: ${{ github.event.workflow_run.id }} From d3f97ef93e990f83f2381ecb0597e1d732fd1108 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 Apr 2024 22:57:30 +1000 Subject: [PATCH 1122/1531] Bump cla-assistant/github-action from 2.3.0 to 2.3.2 (#1705) Bumps [cla-assistant/github-action](https://github.com/cla-assistant/github-action) from 2.3.0 to 2.3.2. - [Release notes](https://github.com/cla-assistant/github-action/releases) - [Commits](https://github.com/cla-assistant/github-action/compare/v2.3.0...v2.3.2) --- updated-dependencies: - dependency-name: cla-assistant/github-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/cla.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cla.yml b/.github/workflows/cla.yml index 1b9461b67..259ee5143 100644 --- a/.github/workflows/cla.yml +++ b/.github/workflows/cla.yml @@ -12,7 +12,7 @@ jobs: - name: 'CLA Assistant' if: (github.event.comment.body == 'recheck' || github.event.comment.body == 'I have read the CLA Document and I hereby sign the CLA') || github.event_name == 'pull_request_target' # Beta Release - uses: cla-assistant/github-action@v2.3.0 + uses: cla-assistant/github-action@v2.3.2 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # the below token should have repo scope and must be manually added by you in the repository's secret From ce347a0ff4bd769db2cf7977f618ba75702ff866 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 Apr 2024 22:58:56 +1000 Subject: [PATCH 1123/1531] Bump docker/build-push-action from 4.1.1 to 5.3.0 (#1704) Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 4.1.1 to 5.3.0. - [Release notes](https://github.com/docker/build-push-action/releases) - [Commits](https://github.com/docker/build-push-action/compare/v4.1.1...v5.3.0) --- updated-dependencies: - dependency-name: docker/build-push-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/docker-pr.yml | 2 +- .github/workflows/prod-deploy.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docker-pr.yml b/.github/workflows/docker-pr.yml index 7d1f2b8d0..f9a6eefe4 100644 --- a/.github/workflows/docker-pr.yml +++ b/.github/workflows/docker-pr.yml @@ -13,7 +13,7 @@ jobs: - name: Checkout repository uses: actions/checkout@v4.1.3 - name: Build Docker image - uses: docker/build-push-action@v4.1.1 + uses: docker/build-push-action@v5.3.0 with: context: . push: false diff --git a/.github/workflows/prod-deploy.yml b/.github/workflows/prod-deploy.yml index bec41af3b..56593834a 100644 --- a/.github/workflows/prod-deploy.yml +++ b/.github/workflows/prod-deploy.yml @@ -90,7 +90,7 @@ jobs: ${{ secrets.DOCKER_USERNAME }}/cinny ghcr.io/${{ github.repository }} - name: Build and push Docker image - uses: docker/build-push-action@v4.1.1 + uses: docker/build-push-action@v5.3.0 with: context: . platforms: linux/amd64,linux/arm64 From 3ae1e58ff2389d107f8a61442cd179882714887a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 Apr 2024 23:00:52 +1000 Subject: [PATCH 1124/1531] Bump softprops/action-gh-release from 1 to 2 (#1703) Bumps [softprops/action-gh-release](https://github.com/softprops/action-gh-release) from 1 to 2. - [Release notes](https://github.com/softprops/action-gh-release/releases) - [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md) - [Commits](https://github.com/softprops/action-gh-release/compare/de2c0eb89ae2a093876385947365aca7b0e5f844...9d7c94cfd0a1f3ed45544c887983e9fa900f0564) --- updated-dependencies: - dependency-name: softprops/action-gh-release dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/prod-deploy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/prod-deploy.yml b/.github/workflows/prod-deploy.yml index 56593834a..790e0c750 100644 --- a/.github/workflows/prod-deploy.yml +++ b/.github/workflows/prod-deploy.yml @@ -52,7 +52,7 @@ jobs: gpg --export | xxd -p echo '${{ secrets.GNUPG_PASSPHRASE }}' | gpg --batch --yes --pinentry-mode loopback --passphrase-fd 0 --armor --detach-sign cinny-${{ steps.vars.outputs.tag }}.tar.gz - name: Upload tagged release - uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 + uses: softprops/action-gh-release@9d7c94cfd0a1f3ed45544c887983e9fa900f0564 with: files: | cinny-${{ steps.vars.outputs.tag }}.tar.gz From b803ce99e3d8d7c2e14f7b3deeae6e0275a5871c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 Apr 2024 23:06:24 +1000 Subject: [PATCH 1125/1531] Bump nwtgck/actions-netlify from 2.1.0 to 3.0.0 (#1708) Bumps [nwtgck/actions-netlify](https://github.com/nwtgck/actions-netlify) from 2.1.0 to 3.0.0. - [Release notes](https://github.com/nwtgck/actions-netlify/releases) - [Changelog](https://github.com/nwtgck/actions-netlify/blob/develop/CHANGELOG.md) - [Commits](https://github.com/nwtgck/actions-netlify/compare/7a92f00dde8c92a5a9e8385ec2919775f7647352...4cbaf4c08f1a7bfa537d6113472ef4424e4eb654) --- updated-dependencies: - dependency-name: nwtgck/actions-netlify dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/deploy-pull-request.yml | 2 +- .github/workflows/netlify-dev.yml | 2 +- .github/workflows/prod-deploy.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/deploy-pull-request.yml b/.github/workflows/deploy-pull-request.yml index e73993161..0768e1854 100644 --- a/.github/workflows/deploy-pull-request.yml +++ b/.github/workflows/deploy-pull-request.yml @@ -32,7 +32,7 @@ jobs: path: dist - name: Deploy to Netlify id: netlify - uses: nwtgck/actions-netlify@7a92f00dde8c92a5a9e8385ec2919775f7647352 + uses: nwtgck/actions-netlify@4cbaf4c08f1a7bfa537d6113472ef4424e4eb654 with: publish-dir: dist deploy-message: "Deploy PR ${{ steps.pr.outputs.id }}" diff --git a/.github/workflows/netlify-dev.yml b/.github/workflows/netlify-dev.yml index 7c90aec72..e8371ff96 100644 --- a/.github/workflows/netlify-dev.yml +++ b/.github/workflows/netlify-dev.yml @@ -24,7 +24,7 @@ jobs: NODE_OPTIONS: '--max_old_space_size=4096' run: npm run build - name: Deploy to Netlify - uses: nwtgck/actions-netlify@7a92f00dde8c92a5a9e8385ec2919775f7647352 + uses: nwtgck/actions-netlify@4cbaf4c08f1a7bfa537d6113472ef4424e4eb654 with: publish-dir: dist deploy-message: 'Dev deploy ${{ github.sha }}' diff --git a/.github/workflows/prod-deploy.yml b/.github/workflows/prod-deploy.yml index 790e0c750..4a355a94a 100644 --- a/.github/workflows/prod-deploy.yml +++ b/.github/workflows/prod-deploy.yml @@ -23,7 +23,7 @@ jobs: NODE_OPTIONS: '--max_old_space_size=4096' run: npm run build - name: Deploy to Netlify - uses: nwtgck/actions-netlify@7a92f00dde8c92a5a9e8385ec2919775f7647352 + uses: nwtgck/actions-netlify@4cbaf4c08f1a7bfa537d6113472ef4424e4eb654 with: publish-dir: dist deploy-message: 'Prod deploy ${{ github.ref_name }}' From e5b980fbc78a3b1de2e6a7a893601d7f7fcdae05 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 Apr 2024 23:06:48 +1000 Subject: [PATCH 1126/1531] Bump thollander/actions-comment-pull-request from 2.4.3 to 2.5.0 (#1711) Bumps [thollander/actions-comment-pull-request](https://github.com/thollander/actions-comment-pull-request) from 2.4.3 to 2.5.0. - [Release notes](https://github.com/thollander/actions-comment-pull-request/releases) - [Commits](https://github.com/thollander/actions-comment-pull-request/compare/1d3973dc4b8e1399c0620d3f2b1aa5e795465308...fabd468d3a1a0b97feee5f6b9e499eab0dd903f6) --- updated-dependencies: - dependency-name: thollander/actions-comment-pull-request dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/deploy-pull-request.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deploy-pull-request.yml b/.github/workflows/deploy-pull-request.yml index 0768e1854..66e648b07 100644 --- a/.github/workflows/deploy-pull-request.yml +++ b/.github/workflows/deploy-pull-request.yml @@ -45,7 +45,7 @@ jobs: NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID_PR_CINNY }} timeout-minutes: 1 - name: Comment preview on PR - uses: thollander/actions-comment-pull-request@1d3973dc4b8e1399c0620d3f2b1aa5e795465308 + uses: thollander/actions-comment-pull-request@fabd468d3a1a0b97feee5f6b9e499eab0dd903f6 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: From e8020acabfebd761d2eaa1182d1355339e301760 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 Apr 2024 23:07:12 +1000 Subject: [PATCH 1127/1531] Bump actions/checkout from 4.1.3 to 4.1.4 (#1709) Bumps [actions/checkout](https://github.com/actions/checkout) from 4.1.3 to 4.1.4. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v4.1.3...v4.1.4) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build-pull-request.yml | 2 +- .github/workflows/docker-pr.yml | 2 +- .github/workflows/lockfile.yml | 2 +- .github/workflows/netlify-dev.yml | 2 +- .github/workflows/prod-deploy.yml | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build-pull-request.yml b/.github/workflows/build-pull-request.yml index a574c6782..f2af6b6f1 100644 --- a/.github/workflows/build-pull-request.yml +++ b/.github/workflows/build-pull-request.yml @@ -12,7 +12,7 @@ jobs: PR_NUMBER: ${{github.event.number}} steps: - name: Checkout repository - uses: actions/checkout@v4.1.3 + uses: actions/checkout@v4.1.4 - name: Setup node uses: actions/setup-node@v4.0.2 with: diff --git a/.github/workflows/docker-pr.yml b/.github/workflows/docker-pr.yml index f9a6eefe4..adfc7912a 100644 --- a/.github/workflows/docker-pr.yml +++ b/.github/workflows/docker-pr.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v4.1.3 + uses: actions/checkout@v4.1.4 - name: Build Docker image uses: docker/build-push-action@v5.3.0 with: diff --git a/.github/workflows/lockfile.yml b/.github/workflows/lockfile.yml index 1b116b5a5..0d58b2547 100644 --- a/.github/workflows/lockfile.yml +++ b/.github/workflows/lockfile.yml @@ -14,7 +14,7 @@ jobs: pull-requests: write steps: - name: Checkout - uses: actions/checkout@v4.1.3 + uses: actions/checkout@v4.1.4 - name: NPM Lockfile Changes uses: codepunkt/npm-lockfile-changes@b40543471c36394409466fdb277a73a0856d7891 with: diff --git a/.github/workflows/netlify-dev.yml b/.github/workflows/netlify-dev.yml index e8371ff96..07c0f50d9 100644 --- a/.github/workflows/netlify-dev.yml +++ b/.github/workflows/netlify-dev.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v4.1.3 + uses: actions/checkout@v4.1.4 - name: Setup node uses: actions/setup-node@v4.0.2 with: diff --git a/.github/workflows/prod-deploy.yml b/.github/workflows/prod-deploy.yml index 4a355a94a..ac4db5fc5 100644 --- a/.github/workflows/prod-deploy.yml +++ b/.github/workflows/prod-deploy.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v4.1.3 + uses: actions/checkout@v4.1.4 - name: Setup node uses: actions/setup-node@v4.0.2 with: @@ -66,7 +66,7 @@ jobs: packages: write steps: - name: Checkout repository - uses: actions/checkout@v4.1.3 + uses: actions/checkout@v4.1.4 - name: Set up QEMU uses: docker/setup-qemu-action@v3.0.0 - name: Set up Docker Buildx From 8267990e6f4c1cc9cef1326d1c7769ec527d9319 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 Apr 2024 23:07:32 +1000 Subject: [PATCH 1128/1531] Bump docker/setup-buildx-action from 2.7.0 to 3.3.0 (#1710) Bumps [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) from 2.7.0 to 3.3.0. - [Release notes](https://github.com/docker/setup-buildx-action/releases) - [Commits](https://github.com/docker/setup-buildx-action/compare/v2.7.0...v3.3.0) --- updated-dependencies: - dependency-name: docker/setup-buildx-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/prod-deploy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/prod-deploy.yml b/.github/workflows/prod-deploy.yml index ac4db5fc5..c9cc111fd 100644 --- a/.github/workflows/prod-deploy.yml +++ b/.github/workflows/prod-deploy.yml @@ -70,7 +70,7 @@ jobs: - name: Set up QEMU uses: docker/setup-qemu-action@v3.0.0 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2.7.0 + uses: docker/setup-buildx-action@v3.3.0 - name: Login to Docker Hub uses: docker/login-action@v3.1.0 with: From 565a6563e16ced2ffdf420fa29b6794045e69da2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 12 May 2024 14:06:53 +1000 Subject: [PATCH 1129/1531] Bump pdfjs-dist from 3.10.111 to 4.2.67 (#1717) * Bump pdfjs-dist from 3.10.111 to 4.2.67 Bumps [pdfjs-dist](https://github.com/mozilla/pdfjs-dist) from 3.10.111 to 4.2.67. - [Commits](https://github.com/mozilla/pdfjs-dist/commits) --- updated-dependencies: - dependency-name: pdfjs-dist dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] * Fix pdfjs top level await --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Krishan <33421343+kfiven@users.noreply.github.com> --- package-lock.json | 277 +++++++++++++++++++++++++++++++++++++++++++--- package.json | 5 +- vite.config.js | 43 +++---- 3 files changed, 290 insertions(+), 35 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5b3ebdc04..f6583b06d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -42,7 +42,7 @@ "linkifyjs": "4.0.2", "matrix-js-sdk": "29.1.0", "millify": "6.1.0", - "pdfjs-dist": "3.10.111", + "pdfjs-dist": "4.2.67", "prismjs": "1.29.0", "prop-types": "15.8.1", "react": "18.2.0", @@ -93,7 +93,8 @@ "sass": "1.56.2", "typescript": "4.9.4", "vite": "5.0.13", - "vite-plugin-static-copy": "0.13.0" + "vite-plugin-static-copy": "0.13.0", + "vite-plugin-top-level-await": "1.4.1" }, "engines": { "node": ">=16.0.0" @@ -2636,6 +2637,23 @@ "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", "dev": true }, + "node_modules/@rollup/plugin-virtual": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@rollup/plugin-virtual/-/plugin-virtual-3.0.2.tgz", + "integrity": "sha512-10monEYsBp3scM4/ND4LNH5Rxvh3e/cVeL3jWTgZ2SrQ+BmUoQcopVQvnaMcOnykb1VkxUFuDAN+0FnpTFRy2A==", + "dev": true, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, "node_modules/@rollup/plugin-wasm": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/@rollup/plugin-wasm/-/plugin-wasm-6.1.1.tgz", @@ -2850,6 +2868,210 @@ "win32" ] }, + "node_modules/@swc/core": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.5.5.tgz", + "integrity": "sha512-M8O22EEgdSONLd+7KRrXj8pn+RdAZZ7ISnPjE9KCQQlI0kkFNEquWR+uFdlFxQfwlyCe/Zb6uGXGDvtcov4IMg==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "@swc/counter": "^0.1.2", + "@swc/types": "^0.1.5" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/swc" + }, + "optionalDependencies": { + "@swc/core-darwin-arm64": "1.5.5", + "@swc/core-darwin-x64": "1.5.5", + "@swc/core-linux-arm-gnueabihf": "1.5.5", + "@swc/core-linux-arm64-gnu": "1.5.5", + "@swc/core-linux-arm64-musl": "1.5.5", + "@swc/core-linux-x64-gnu": "1.5.5", + "@swc/core-linux-x64-musl": "1.5.5", + "@swc/core-win32-arm64-msvc": "1.5.5", + "@swc/core-win32-ia32-msvc": "1.5.5", + "@swc/core-win32-x64-msvc": "1.5.5" + }, + "peerDependencies": { + "@swc/helpers": "^0.5.0" + }, + "peerDependenciesMeta": { + "@swc/helpers": { + "optional": true + } + } + }, + "node_modules/@swc/core-darwin-arm64": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.5.5.tgz", + "integrity": "sha512-Ol5ZwZYdTOZsv2NwjcT/qVVALKzVFeh+IJ4GNarr3P99+38Dkwi81OqCI1o/WaDXQYKAQC/V+CzMbkEuJJfq9Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-darwin-x64": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.5.5.tgz", + "integrity": "sha512-XHWpKBIPKYLgh5/lV2PYjO84lkzf5JR51kjiloyz2Pa9HIV8tHoAP8bYdJwm4nUp2I7KcEh3pPH0AVu5LpxMKw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm-gnueabihf": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.5.5.tgz", + "integrity": "sha512-vtoWNCWAe+CNSqtqIwFnIH48qgPPlUZKoQ4EVFeMM+7/kDi6SeNxoh5TierJs5bKAWxD49VkPvRoWFCk6V62mA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm64-gnu": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.5.5.tgz", + "integrity": "sha512-L4l7M78U6h/rCAxId+y5Vu+1KfDRF6dJZtitFcaT293guiUQFwJv8gLxI4Jh5wFtZ0fYd0QaCuvh2Ip79CzGMg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm64-musl": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.5.5.tgz", + "integrity": "sha512-DkzJc13ukXa7oJpyn24BjIgsiOybYrc+IxjsQyfNlDrrs1QXP4elStcpkD02SsIuSyHjZV8Hw2HFBMQB3OHPrA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-x64-gnu": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.5.5.tgz", + "integrity": "sha512-kj4ZwWJGeBEUzHrRQP2VudN+kkkYH7OI1dPVDc6kWQx5X4329JeKOas4qY0l7gDVjBbRwN9IbbPI6TIn2KfAug==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-x64-musl": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.5.5.tgz", + "integrity": "sha512-6pTorCs4mYhPhYtC4jNOnhGgjNd3DZcRoZ9P0tzXXP69aCbYjvlgNH/NRvAROp9AaVFeZ7a7PmCWb6+Rbe7NKg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-arm64-msvc": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.5.5.tgz", + "integrity": "sha512-o0/9pstmEjwZyrY/bA+mymF0zH7E+GT/XCVqdKeWW9Wn3gTTyWa5MZnrFgI2THQ+AXwdglMB/Zo76ARQPaz/+A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-ia32-msvc": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.5.5.tgz", + "integrity": "sha512-B+nypUwsmCuaH6RtKWgiPCb+ENjxstJPPJeMJvBqlJqyCaIkZzN4M07Ozi3xVv1VG21SRkd6G3xIqRoalrNc0Q==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-x64-msvc": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.5.5.tgz", + "integrity": "sha512-ry83ki9ZX0Q+GWGnqc2J618Z+FvKE8Ajn42F8EYi8Wj0q6Jz3mj+pJzgzakk2INm2ldEZ+FaRPipn4ozsZDcBg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/counter": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", + "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==", + "dev": true + }, "node_modules/@swc/helpers": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.3.tgz", @@ -2863,6 +3085,15 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" }, + "node_modules/@swc/types": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.6.tgz", + "integrity": "sha512-/JLo/l2JsT/LRd80C3HfbmVpxOAJ11FO2RCEslFrgzLltoP9j8XIbsyDcfCt2WWyX+CM96rBoNM+IToAkFOugg==", + "dev": true, + "dependencies": { + "@swc/counter": "^0.1.3" + } + }, "node_modules/@tanstack/react-virtual": { "version": "3.0.0-beta.54", "resolved": "https://registry.npmjs.org/@tanstack/react-virtual/-/react-virtual-3.0.0-beta.54.tgz", @@ -6834,25 +7065,25 @@ "node": ">=8" } }, - "node_modules/path2d-polyfill": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path2d-polyfill/-/path2d-polyfill-2.0.1.tgz", - "integrity": "sha512-ad/3bsalbbWhmBo0D6FZ4RNMwsLsPpL6gnvhuSaU5Vm7b06Kr5ubSltQQ0T7YKsiJQO+g22zJ4dJKNTXIyOXtA==", + "node_modules/path2d": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/path2d/-/path2d-0.2.0.tgz", + "integrity": "sha512-KdPAykQX6kmLSOO6Jpu2KNcCED7CKjmaBNGGNuctOsG0hgYO1OdYQaan6cYXJiG0WmXOwZZPILPBimu5QAIw3A==", "optional": true, "engines": { - "node": ">=8" + "node": ">=6" } }, "node_modules/pdfjs-dist": { - "version": "3.10.111", - "resolved": "https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-3.10.111.tgz", - "integrity": "sha512-+SXXGN/3YTNQSK5Ae7EyqQuR+4IAsNunJq/Us5ByOkRJ45qBXXOwkiWi3RIDU+CyF+ak5eSWXl2FQW2PKBrsRA==", + "version": "4.2.67", + "resolved": "https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-4.2.67.tgz", + "integrity": "sha512-rJmuBDFpD7cqC8WIkQUEClyB4UAH05K4AsyewToMTp2gSy3Rrx8c1ydAVqlJlGv3yZSOrhEERQU/4ScQQFlLHA==", "engines": { "node": ">=18" }, "optionalDependencies": { "canvas": "^2.11.2", - "path2d-polyfill": "^2.0.1" + "path2d": "^0.2.0" } }, "node_modules/picocolors": { @@ -8113,9 +8344,13 @@ "optional": true }, "node_modules/uuid": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", - "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], "bin": { "uuid": "dist/bin/uuid" } @@ -8228,6 +8463,20 @@ "node": ">= 10.0.0" } }, + "node_modules/vite-plugin-top-level-await": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/vite-plugin-top-level-await/-/vite-plugin-top-level-await-1.4.1.tgz", + "integrity": "sha512-hogbZ6yT7+AqBaV6lK9JRNvJDn4/IJvHLu6ET06arNfo0t2IsyCaon7el9Xa8OumH+ESuq//SDf8xscZFE0rWw==", + "dev": true, + "dependencies": { + "@rollup/plugin-virtual": "^3.0.2", + "@swc/core": "^1.3.100", + "uuid": "^9.0.1" + }, + "peerDependencies": { + "vite": ">=2.8" + } + }, "node_modules/vite/node_modules/@esbuild/android-arm": { "version": "0.19.12", "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.12.tgz", diff --git a/package.json b/package.json index 7660b1744..8c35e8021 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,7 @@ "linkifyjs": "4.0.2", "matrix-js-sdk": "29.1.0", "millify": "6.1.0", - "pdfjs-dist": "3.10.111", + "pdfjs-dist": "4.2.67", "prismjs": "1.29.0", "prop-types": "15.8.1", "react": "18.2.0", @@ -103,6 +103,7 @@ "sass": "1.56.2", "typescript": "4.9.4", "vite": "5.0.13", - "vite-plugin-static-copy": "0.13.0" + "vite-plugin-static-copy": "0.13.0", + "vite-plugin-top-level-await": "1.4.1" } } diff --git a/vite.config.js b/vite.config.js index 20c7765c5..e6ae956df 100644 --- a/vite.config.js +++ b/vite.config.js @@ -2,11 +2,12 @@ import { defineConfig } from 'vite'; import react from '@vitejs/plugin-react'; import { wasm } from '@rollup/plugin-wasm'; import { viteStaticCopy } from 'vite-plugin-static-copy'; -import { vanillaExtractPlugin } from "@vanilla-extract/vite-plugin"; +import { vanillaExtractPlugin } from '@vanilla-extract/vite-plugin'; import { NodeGlobalsPolyfillPlugin } from '@esbuild-plugins/node-globals-polyfill'; import inject from '@rollup/plugin-inject'; -import { svgLoader } from './viteSvgLoader' -import buildConfig from "./build.config" +import topLevelAwait from 'vite-plugin-top-level-await'; +import { svgLoader } from './viteSvgLoader'; +import buildConfig from './build.config'; const copyFiles = { targets: [ @@ -35,7 +36,7 @@ const copyFiles = { dest: 'public/', }, ], -} +}; export default defineConfig({ appType: 'spa', @@ -46,6 +47,12 @@ export default defineConfig({ host: true, }, plugins: [ + topLevelAwait({ + // The export name of top-level await promise for each chunk module + promiseExportName: '__tla', + // The function to generate import names of top-level await promise in each chunk module + promiseImportName: (i) => `__tla_${i}`, + }), viteStaticCopy(copyFiles), vanillaExtractPlugin(), svgLoader(), @@ -54,26 +61,24 @@ export default defineConfig({ ], optimizeDeps: { esbuildOptions: { - define: { - global: 'globalThis' - }, - plugins: [ - // Enable esbuild polyfill plugins - NodeGlobalsPolyfillPlugin({ - process: false, - buffer: true, - }), - ] - } + define: { + global: 'globalThis', + }, + plugins: [ + // Enable esbuild polyfill plugins + NodeGlobalsPolyfillPlugin({ + process: false, + buffer: true, + }), + ], + }, }, build: { outDir: 'dist', sourcemap: true, copyPublicDir: false, rollupOptions: { - plugins: [ - inject({ Buffer: ['buffer', 'Buffer'] }) - ] - } + plugins: [inject({ Buffer: ['buffer', 'Buffer'] })], + }, }, }); From 5259f1167908b4ddc193f22c90153287a7575d7f Mon Sep 17 00:00:00 2001 From: Krishan <33421343+kfiven@users.noreply.github.com> Date: Sun, 12 May 2024 14:17:41 +1000 Subject: [PATCH 1130/1531] Remove svg loader as available in Vite by default (#1728) --- package-lock.json | 10 ---------- package.json | 1 - vite.config.js | 2 -- viteSvgLoader.ts | 16 ---------------- 4 files changed, 29 deletions(-) delete mode 100644 viteSvgLoader.ts diff --git a/package-lock.json b/package-lock.json index f6583b06d..d8bd75885 100644 --- a/package-lock.json +++ b/package-lock.json @@ -88,7 +88,6 @@ "eslint-plugin-jsx-a11y": "6.6.1", "eslint-plugin-react": "7.31.11", "eslint-plugin-react-hooks": "4.6.0", - "mini-svg-data-uri": "1.4.4", "prettier": "2.8.1", "sass": "1.56.2", "typescript": "4.9.4", @@ -6643,15 +6642,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/mini-svg-data-uri": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/mini-svg-data-uri/-/mini-svg-data-uri-1.4.4.tgz", - "integrity": "sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==", - "dev": true, - "bin": { - "mini-svg-data-uri": "cli.js" - } - }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", diff --git a/package.json b/package.json index 8c35e8021..70dd6b527 100644 --- a/package.json +++ b/package.json @@ -98,7 +98,6 @@ "eslint-plugin-jsx-a11y": "6.6.1", "eslint-plugin-react": "7.31.11", "eslint-plugin-react-hooks": "4.6.0", - "mini-svg-data-uri": "1.4.4", "prettier": "2.8.1", "sass": "1.56.2", "typescript": "4.9.4", diff --git a/vite.config.js b/vite.config.js index e6ae956df..f77abfc57 100644 --- a/vite.config.js +++ b/vite.config.js @@ -6,7 +6,6 @@ import { vanillaExtractPlugin } from '@vanilla-extract/vite-plugin'; import { NodeGlobalsPolyfillPlugin } from '@esbuild-plugins/node-globals-polyfill'; import inject from '@rollup/plugin-inject'; import topLevelAwait from 'vite-plugin-top-level-await'; -import { svgLoader } from './viteSvgLoader'; import buildConfig from './build.config'; const copyFiles = { @@ -55,7 +54,6 @@ export default defineConfig({ }), viteStaticCopy(copyFiles), vanillaExtractPlugin(), - svgLoader(), wasm(), react(), ], diff --git a/viteSvgLoader.ts b/viteSvgLoader.ts deleted file mode 100644 index a119e3ed3..000000000 --- a/viteSvgLoader.ts +++ /dev/null @@ -1,16 +0,0 @@ -import svgToMiniDataURI from 'mini-svg-data-uri'; -import type { Plugin } from 'rollup'; -import fs from 'fs'; - -// TODO: remove this once https://github.com/vitejs/vite/pull/2909 gets merged -export const svgLoader = (): Plugin => ({ - name: 'vite-svg-patch-plugin', - transform: (code, id) => { - if (id.endsWith('.svg')) { - const extractedSvg = fs.readFileSync(id, 'utf8'); - const datauri = svgToMiniDataURI.toSrcset(extractedSvg); - return `export default "${datauri}"`; - } - return code; - }, -}); From f1c4a38a49ca1990d63539bc40d2ec2781704a78 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 12 May 2024 14:25:07 +1000 Subject: [PATCH 1131/1531] Update dependency sanitize-html to v2.12.1 [SECURITY] (#1729) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package-lock.json | 14 +++++++------- package.json | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index d8bd75885..478320ad2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -57,7 +57,7 @@ "react-modal": "3.16.1", "react-range": "1.8.14", "react-router-dom": "6.20.0", - "sanitize-html": "2.8.0", + "sanitize-html": "2.12.1", "slate": "0.94.1", "slate-history": "0.93.0", "slate-react": "0.98.4", @@ -7703,9 +7703,9 @@ } }, "node_modules/sanitize-html": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-2.8.0.tgz", - "integrity": "sha512-ZsGyc6avnqgvEm3eMKrcy8xa7WM1MrGrfkGsUgQee2CU+vg3PCfNCexXwBDF/6dEPvaQ4k/QqRjnYKHL8xgNjg==", + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-2.12.1.tgz", + "integrity": "sha512-Plh+JAn0UVDpBRP/xEjsk+xDCoOvMBwQUf/K+/cBAVuTbtX8bj2VB7S1sL1dssVpykqp0/KPSesHrqXtokVBpA==", "dependencies": { "deepmerge": "^4.2.2", "escape-string-regexp": "^4.0.0", @@ -7716,9 +7716,9 @@ } }, "node_modules/sanitize-html/node_modules/deepmerge": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", - "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", "engines": { "node": ">=0.10.0" } diff --git a/package.json b/package.json index 70dd6b527..f7ba24dca 100644 --- a/package.json +++ b/package.json @@ -67,7 +67,7 @@ "react-modal": "3.16.1", "react-range": "1.8.14", "react-router-dom": "6.20.0", - "sanitize-html": "2.8.0", + "sanitize-html": "2.12.1", "slate": "0.94.1", "slate-history": "0.93.0", "slate-react": "0.98.4", From ec65b98874f517d479c2e96f6b24c4feac3f4904 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 12 May 2024 14:27:02 +1000 Subject: [PATCH 1132/1531] Update dependency eslint-plugin-import to v2.29.1 (#1730) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package-lock.json | 888 ++++++++++++++++++++++++++++++++++++---------- package.json | 2 +- 2 files changed, 705 insertions(+), 185 deletions(-) diff --git a/package-lock.json b/package-lock.json index 478320ad2..90da965b0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -84,7 +84,7 @@ "eslint": "8.29.0", "eslint-config-airbnb": "19.0.4", "eslint-config-prettier": "8.5.0", - "eslint-plugin-import": "2.26.0", + "eslint-plugin-import": "2.29.1", "eslint-plugin-jsx-a11y": "6.6.1", "eslint-plugin-react": "7.31.11", "eslint-plugin-react-hooks": "4.6.0", @@ -3835,16 +3835,33 @@ "node": ">=6.0" } }, - "node_modules/array-includes": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.6.tgz", - "integrity": "sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==", + "node_modules/array-buffer-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", + "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", - "get-intrinsic": "^1.1.3", + "call-bind": "^1.0.5", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-includes": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", + "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", "is-string": "^1.0.7" }, "engines": { @@ -3863,15 +3880,35 @@ "node": ">=8" } }, + "node_modules/array.prototype.findlastindex": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", + "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/array.prototype.flat": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz", - "integrity": "sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", + "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", "dev": true, "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", "es-shim-unscopables": "^1.0.0" }, "engines": { @@ -3882,14 +3919,14 @@ } }, "node_modules/array.prototype.flatmap": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz", - "integrity": "sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", + "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", "dev": true, "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", "es-shim-unscopables": "^1.0.0" }, "engines": { @@ -3912,6 +3949,28 @@ "get-intrinsic": "^1.1.3" } }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", + "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.2.1", + "get-intrinsic": "^1.2.3", + "is-array-buffer": "^3.0.4", + "is-shared-array-buffer": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/asap": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", @@ -3928,6 +3987,21 @@ "resolved": "https://registry.npmjs.org/autosize/-/autosize-4.0.4.tgz", "integrity": "sha512-5yxLQ22O0fCRGoxGfeLSNt3J8LB1v+umtpMnPW6XjkTWXKoN0AmXAIhelJcDtFT/Y/wYWmfE+oqU10Q0b8FhaQ==" }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/await-to-js": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/await-to-js/-/await-to-js-3.0.0.tgz", @@ -4087,13 +4161,19 @@ } }, "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", "dev": true, "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -4371,6 +4451,57 @@ "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", "dev": true }, + "node_modules/data-view-buffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", + "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", + "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", + "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/dateformat": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-5.0.3.tgz", @@ -4431,12 +4562,30 @@ "node": ">=0.10.0" } }, - "node_modules/define-properties": { + "node_modules/define-data-property": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", - "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", "dev": true, "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "dependencies": { + "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", "object-keys": "^1.1.1" }, @@ -4603,36 +4752,57 @@ } }, "node_modules/es-abstract": { - "version": "1.20.5", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.5.tgz", - "integrity": "sha512-7h8MM2EQhsCA7pU/Nv78qOXFpD8Rhqd12gYiSJVkrH9+e8VuA8JlPJK/hQjjlLv6pJvx/z1iRFKzYb0XT/RuAQ==", + "version": "1.23.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", + "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", + "array-buffer-byte-length": "^1.0.1", + "arraybuffer.prototype.slice": "^1.0.3", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "data-view-buffer": "^1.0.1", + "data-view-byte-length": "^1.0.1", + "data-view-byte-offset": "^1.0.0", + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-set-tostringtag": "^2.0.3", "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "function.prototype.name": "^1.1.5", - "get-intrinsic": "^1.1.3", - "get-symbol-description": "^1.0.0", + "function.prototype.name": "^1.1.6", + "get-intrinsic": "^1.2.4", + "get-symbol-description": "^1.0.2", + "globalthis": "^1.0.3", "gopd": "^1.0.1", - "has": "^1.0.3", - "has-property-descriptors": "^1.0.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.3", "has-symbols": "^1.0.3", - "internal-slot": "^1.0.3", + "hasown": "^2.0.2", + "internal-slot": "^1.0.7", + "is-array-buffer": "^3.0.4", "is-callable": "^1.2.7", - "is-negative-zero": "^2.0.2", + "is-data-view": "^1.0.1", + "is-negative-zero": "^2.0.3", "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", + "is-shared-array-buffer": "^1.0.3", "is-string": "^1.0.7", + "is-typed-array": "^1.1.13", "is-weakref": "^1.0.2", - "object-inspect": "^1.12.2", + "object-inspect": "^1.13.1", "object-keys": "^1.1.1", - "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.4.3", - "safe-regex-test": "^1.0.0", - "string.prototype.trimend": "^1.0.6", - "string.prototype.trimstart": "^1.0.6", - "unbox-primitive": "^1.0.2" + "object.assign": "^4.1.5", + "regexp.prototype.flags": "^1.5.2", + "safe-array-concat": "^1.1.2", + "safe-regex-test": "^1.0.3", + "string.prototype.trim": "^1.2.9", + "string.prototype.trimend": "^1.0.8", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.2", + "typed-array-byte-length": "^1.0.1", + "typed-array-byte-offset": "^1.0.2", + "typed-array-length": "^1.0.6", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.15" }, "engines": { "node": ">= 0.4" @@ -4641,13 +4811,60 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/es-shim-unscopables": { + "node_modules/es-define-property": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", - "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", "dev": true, "dependencies": { - "has": "^1.0.3" + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", + "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", + "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.4", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", + "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", + "dev": true, + "dependencies": { + "hasown": "^2.0.0" } }, "node_modules/es-to-primitive": { @@ -4828,13 +5045,14 @@ } }, "node_modules/eslint-import-resolver-node": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", - "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", "dev": true, "dependencies": { "debug": "^3.2.7", - "resolve": "^1.20.0" + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" } }, "node_modules/eslint-import-resolver-node/node_modules/debug": { @@ -4847,9 +5065,9 @@ } }, "node_modules/eslint-module-utils": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.4.tgz", - "integrity": "sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==", + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.1.tgz", + "integrity": "sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==", "dev": true, "dependencies": { "debug": "^3.2.7" @@ -4873,24 +5091,28 @@ } }, "node_modules/eslint-plugin-import": { - "version": "2.26.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz", - "integrity": "sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==", + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", + "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", "dev": true, "dependencies": { - "array-includes": "^3.1.4", - "array.prototype.flat": "^1.2.5", - "debug": "^2.6.9", + "array-includes": "^3.1.7", + "array.prototype.findlastindex": "^1.2.3", + "array.prototype.flat": "^1.3.2", + "array.prototype.flatmap": "^1.3.2", + "debug": "^3.2.7", "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.6", - "eslint-module-utils": "^2.7.3", - "has": "^1.0.3", - "is-core-module": "^2.8.1", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.8.0", + "hasown": "^2.0.0", + "is-core-module": "^2.13.1", "is-glob": "^4.0.3", "minimatch": "^3.1.2", - "object.values": "^1.1.5", - "resolve": "^1.22.0", - "tsconfig-paths": "^3.14.1" + "object.fromentries": "^2.0.7", + "object.groupby": "^1.0.1", + "object.values": "^1.1.7", + "semver": "^6.3.1", + "tsconfig-paths": "^3.15.0" }, "engines": { "node": ">=4" @@ -4900,12 +5122,12 @@ } }, "node_modules/eslint-plugin-import/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, "dependencies": { - "ms": "2.0.0" + "ms": "^2.1.1" } }, "node_modules/eslint-plugin-import/node_modules/doctrine": { @@ -4920,12 +5142,6 @@ "node": ">=0.10.0" } }, - "node_modules/eslint-plugin-import/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, "node_modules/eslint-plugin-jsx-a11y": { "version": "6.6.1", "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.6.1.tgz", @@ -5460,6 +5676,15 @@ "react-dom": "^17.0.0" } }, + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.3" + } + }, "node_modules/formik": { "version": "2.2.9", "resolved": "https://registry.npmjs.org/formik/-/formik-2.2.9.tgz", @@ -5549,21 +5774,24 @@ } }, "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/function.prototype.name": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", - "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", + "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", "dev": true, "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.0", - "functions-have-names": "^1.2.2" + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" }, "engines": { "node": ">= 0.4" @@ -5618,27 +5846,33 @@ } }, "node_modules/get-intrinsic": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", - "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", "dev": true, "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.3" + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", + "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" + "call-bind": "^1.0.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4" }, "engines": { "node": ">= 0.4" @@ -5687,6 +5921,22 @@ "node": ">=4" } }, + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "dev": true, + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/globby": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", @@ -5760,12 +6010,24 @@ } }, "node_modules/has-property-descriptors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", - "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", "dev": true, "dependencies": { - "get-intrinsic": "^1.1.1" + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "dev": true, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -5784,12 +6046,12 @@ } }, "node_modules/has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", "dev": true, "dependencies": { - "has-symbols": "^1.0.2" + "has-symbols": "^1.0.3" }, "engines": { "node": ">= 0.4" @@ -5804,6 +6066,18 @@ "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", "optional": true }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/hoist-non-react-statics": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", @@ -5975,13 +6249,13 @@ "integrity": "sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==" }, "node_modules/internal-slot": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.4.tgz", - "integrity": "sha512-tA8URYccNzMo94s5MQZgH8NB/XTa6HsOo0MLfXTKKEnHVVdegzaQoFZ7Jp44bdvLvY2waT5dc+j5ICEswhi7UQ==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", + "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", "dev": true, "dependencies": { - "get-intrinsic": "^1.1.3", - "has": "^1.0.3", + "es-errors": "^1.3.0", + "hasown": "^2.0.0", "side-channel": "^1.0.4" }, "engines": { @@ -6004,6 +6278,22 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" }, + "node_modules/is-array-buffer": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", + "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-bigint": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", @@ -6057,12 +6347,27 @@ } }, "node_modules/is-core-module": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", - "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", "dev": true, "dependencies": { - "has": "^1.0.3" + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-view": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", + "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", + "dev": true, + "dependencies": { + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -6118,9 +6423,9 @@ "integrity": "sha512-UknnZK4RakDmTgz4PI1wIph5yxSs/mvChWs9ifnlXsKuXgWmOkY/hAE0H/k2MIqH0RlRye0i1oC07MCRSD28Mw==" }, "node_modules/is-negative-zero": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", - "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", "dev": true, "engines": { "node": ">= 0.4" @@ -6187,12 +6492,15 @@ } }, "node_modules/is-shared-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", - "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", + "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", "dev": true, "dependencies": { - "call-bind": "^1.0.2" + "call-bind": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -6228,6 +6536,21 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-typed-array": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", + "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "dev": true, + "dependencies": { + "which-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-weakref": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", @@ -6240,6 +6563,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -6655,9 +6984,9 @@ } }, "node_modules/minimist": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", - "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -6818,9 +7147,9 @@ } }, "node_modules/object-inspect": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", - "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -6836,13 +7165,13 @@ } }, "node_modules/object.assign": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", - "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", + "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", "has-symbols": "^1.0.3", "object-keys": "^1.1.1" }, @@ -6868,14 +7197,15 @@ } }, "node_modules/object.fromentries": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.6.tgz", - "integrity": "sha512-VciD13dswC4j1Xt5394WR4MzmAQmlgN72phd/riNp9vtD7tp4QQWJ0R4wvclXcafgcYK8veHRed2W6XeGBvcfg==", + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -6884,6 +7214,20 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/object.groupby": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", + "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/object.hasown": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.2.tgz", @@ -6898,14 +7242,14 @@ } }, "node_modules/object.values": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.6.tgz", - "integrity": "sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", + "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -7093,6 +7437,15 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/possible-typed-array-names": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", + "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/postcss": { "version": "8.4.32", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.32.tgz", @@ -7513,14 +7866,15 @@ } }, "node_modules/regexp.prototype.flags": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", - "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", + "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "functions-have-names": "^1.2.2" + "call-bind": "^1.0.6", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "set-function-name": "^2.0.1" }, "engines": { "node": ">= 0.4" @@ -7558,12 +7912,12 @@ } }, "node_modules/resolve": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", - "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", "dev": true, "dependencies": { - "is-core-module": "^2.9.0", + "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, @@ -7668,6 +8022,24 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/safe-array-concat": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", + "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4", + "has-symbols": "^1.0.3", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -7689,15 +8061,18 @@ "optional": true }, "node_modules/safe-regex-test": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", - "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", + "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.3", + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", "is-regex": "^1.1.4" }, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -7789,6 +8164,38 @@ "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", "optional": true }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/setimmediate": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", @@ -7976,29 +8383,50 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/string.prototype.trimend": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz", - "integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==", + "node_modules/string.prototype.trim": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", + "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", + "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/string.prototype.trimstart": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz", - "integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -8147,21 +8575,21 @@ "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" }, "node_modules/tsconfig-paths": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", - "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==", + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", "dev": true, "dependencies": { "@types/json5": "^0.0.29", - "json5": "^1.0.1", + "json5": "^1.0.2", "minimist": "^1.2.6", "strip-bom": "^3.0.0" } }, "node_modules/tsconfig-paths/node_modules/json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "dev": true, "dependencies": { "minimist": "^1.2.0" @@ -8230,6 +8658,79 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/typed-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", + "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", + "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", + "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", + "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/typescript": { "version": "4.9.4", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz", @@ -8910,6 +9411,25 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/which-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", + "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/wide-align": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", diff --git a/package.json b/package.json index f7ba24dca..8c8b87e78 100644 --- a/package.json +++ b/package.json @@ -94,7 +94,7 @@ "eslint": "8.29.0", "eslint-config-airbnb": "19.0.4", "eslint-config-prettier": "8.5.0", - "eslint-plugin-import": "2.26.0", + "eslint-plugin-import": "2.29.1", "eslint-plugin-jsx-a11y": "6.6.1", "eslint-plugin-react": "7.31.11", "eslint-plugin-react-hooks": "4.6.0", From 215537a26177558c61eb608866ce224953726f58 Mon Sep 17 00:00:00 2001 From: Krishan <33421343+kfiven@users.noreply.github.com> Date: Sun, 12 May 2024 14:36:35 +1000 Subject: [PATCH 1133/1531] Fix crash when img without src tag (#1731) --- src/app/utils/sanitize.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/utils/sanitize.ts b/src/app/utils/sanitize.ts index 48ab0b8d1..985c47b1e 100644 --- a/src/app/utils/sanitize.ts +++ b/src/app/utils/sanitize.ts @@ -107,7 +107,7 @@ const transformATag: Transformer = (tagName, attribs) => ({ const transformImgTag: Transformer = (tagName, attribs) => { const { src } = attribs; - if (src.startsWith('mxc://') === false) { + if (typeof src === 'string' && src.startsWith('mxc://') === false) { return { tagName: 'a', attribs: { From fe2332ee877e147b954f3b20b23a24d953f527d3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 12 May 2024 14:39:43 +1000 Subject: [PATCH 1134/1531] Bump actions/checkout from 4.1.4 to 4.1.5 (#1721) Bumps [actions/checkout](https://github.com/actions/checkout) from 4.1.4 to 4.1.5. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v4.1.4...v4.1.5) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build-pull-request.yml | 2 +- .github/workflows/docker-pr.yml | 2 +- .github/workflows/lockfile.yml | 2 +- .github/workflows/netlify-dev.yml | 2 +- .github/workflows/prod-deploy.yml | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build-pull-request.yml b/.github/workflows/build-pull-request.yml index f2af6b6f1..e651a344b 100644 --- a/.github/workflows/build-pull-request.yml +++ b/.github/workflows/build-pull-request.yml @@ -12,7 +12,7 @@ jobs: PR_NUMBER: ${{github.event.number}} steps: - name: Checkout repository - uses: actions/checkout@v4.1.4 + uses: actions/checkout@v4.1.5 - name: Setup node uses: actions/setup-node@v4.0.2 with: diff --git a/.github/workflows/docker-pr.yml b/.github/workflows/docker-pr.yml index adfc7912a..7deb40d10 100644 --- a/.github/workflows/docker-pr.yml +++ b/.github/workflows/docker-pr.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v4.1.4 + uses: actions/checkout@v4.1.5 - name: Build Docker image uses: docker/build-push-action@v5.3.0 with: diff --git a/.github/workflows/lockfile.yml b/.github/workflows/lockfile.yml index 0d58b2547..dda75783d 100644 --- a/.github/workflows/lockfile.yml +++ b/.github/workflows/lockfile.yml @@ -14,7 +14,7 @@ jobs: pull-requests: write steps: - name: Checkout - uses: actions/checkout@v4.1.4 + uses: actions/checkout@v4.1.5 - name: NPM Lockfile Changes uses: codepunkt/npm-lockfile-changes@b40543471c36394409466fdb277a73a0856d7891 with: diff --git a/.github/workflows/netlify-dev.yml b/.github/workflows/netlify-dev.yml index 07c0f50d9..518d554a7 100644 --- a/.github/workflows/netlify-dev.yml +++ b/.github/workflows/netlify-dev.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v4.1.4 + uses: actions/checkout@v4.1.5 - name: Setup node uses: actions/setup-node@v4.0.2 with: diff --git a/.github/workflows/prod-deploy.yml b/.github/workflows/prod-deploy.yml index c9cc111fd..eddae352f 100644 --- a/.github/workflows/prod-deploy.yml +++ b/.github/workflows/prod-deploy.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v4.1.4 + uses: actions/checkout@v4.1.5 - name: Setup node uses: actions/setup-node@v4.0.2 with: @@ -66,7 +66,7 @@ jobs: packages: write steps: - name: Checkout repository - uses: actions/checkout@v4.1.4 + uses: actions/checkout@v4.1.5 - name: Set up QEMU uses: docker/setup-qemu-action@v3.0.0 - name: Set up Docker Buildx From cd5d8e1c20532109a4d5a4738e4d2dfde1e288d7 Mon Sep 17 00:00:00 2001 From: Krishan <33421343+kfiven@users.noreply.github.com> Date: Sun, 12 May 2024 16:14:34 +1000 Subject: [PATCH 1135/1531] Fix pdf opening (#1732) --- vite.config.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/vite.config.js b/vite.config.js index f77abfc57..97f405007 100644 --- a/vite.config.js +++ b/vite.config.js @@ -15,8 +15,9 @@ const copyFiles = { dest: '', }, { - src: 'node_modules/pdfjs-dist/build/pdf.worker.min.js', + src: 'node_modules/pdfjs-dist/build/pdf.worker.min.mjs', dest: '', + rename: 'pdf.worker.min.js', }, { src: 'netlify.toml', From 2d6dd3b0b25db632fb1f2d93830ef1e1fff6d64b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 14 May 2024 13:33:58 +1000 Subject: [PATCH 1136/1531] Bump cla-assistant/github-action from 2.3.2 to 2.4.0 (#1735) Bumps [cla-assistant/github-action](https://github.com/cla-assistant/github-action) from 2.3.2 to 2.4.0. - [Release notes](https://github.com/cla-assistant/github-action/releases) - [Commits](https://github.com/cla-assistant/github-action/compare/v2.3.2...v2.4.0) --- updated-dependencies: - dependency-name: cla-assistant/github-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/cla.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cla.yml b/.github/workflows/cla.yml index 259ee5143..2ad3d1456 100644 --- a/.github/workflows/cla.yml +++ b/.github/workflows/cla.yml @@ -12,7 +12,7 @@ jobs: - name: 'CLA Assistant' if: (github.event.comment.body == 'recheck' || github.event.comment.body == 'I have read the CLA Document and I hereby sign the CLA') || github.event_name == 'pull_request_target' # Beta Release - uses: cla-assistant/github-action@v2.3.2 + uses: cla-assistant/github-action@v2.4.0 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # the below token should have repo scope and must be manually added by you in the repository's secret From 5817186129a4776f02ef69d03e5bdc391b98f639 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 14 May 2024 13:34:57 +1000 Subject: [PATCH 1137/1531] Bump softprops/action-gh-release from 2.0.4 to 2.0.5 (#1734) Bumps [softprops/action-gh-release](https://github.com/softprops/action-gh-release) from 2.0.4 to 2.0.5. - [Release notes](https://github.com/softprops/action-gh-release/releases) - [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md) - [Commits](https://github.com/softprops/action-gh-release/compare/9d7c94cfd0a1f3ed45544c887983e9fa900f0564...69320dbe05506a9a39fc8ae11030b214ec2d1f87) --- updated-dependencies: - dependency-name: softprops/action-gh-release dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/prod-deploy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/prod-deploy.yml b/.github/workflows/prod-deploy.yml index eddae352f..3d2f10942 100644 --- a/.github/workflows/prod-deploy.yml +++ b/.github/workflows/prod-deploy.yml @@ -52,7 +52,7 @@ jobs: gpg --export | xxd -p echo '${{ secrets.GNUPG_PASSPHRASE }}' | gpg --batch --yes --pinentry-mode loopback --passphrase-fd 0 --armor --detach-sign cinny-${{ steps.vars.outputs.tag }}.tar.gz - name: Upload tagged release - uses: softprops/action-gh-release@9d7c94cfd0a1f3ed45544c887983e9fa900f0564 + uses: softprops/action-gh-release@69320dbe05506a9a39fc8ae11030b214ec2d1f87 with: files: | cinny-${{ steps.vars.outputs.tag }}.tar.gz From 97d02fd7c84457b25a80e18974435ee8f8bb7b86 Mon Sep 17 00:00:00 2001 From: aceArt-GmbH <33117017+aceArt-GmbH@users.noreply.github.com> Date: Tue, 14 May 2024 05:49:04 +0200 Subject: [PATCH 1138/1531] Scroll tab target into view (#1580) --- src/app/atoms/tabs/Tabs.jsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/app/atoms/tabs/Tabs.jsx b/src/app/atoms/tabs/Tabs.jsx index 39800ce35..bcdc8ef7e 100644 --- a/src/app/atoms/tabs/Tabs.jsx +++ b/src/app/atoms/tabs/Tabs.jsx @@ -41,8 +41,9 @@ TabItem.propTypes = { function Tabs({ items, defaultSelected, onSelect }) { const [selectedItem, setSelectedItem] = useState(items[defaultSelected]); - const handleTabSelection = (item, index) => { + const handleTabSelection = (item, index, target) => { if (selectedItem === item) return; + target.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'center' }); setSelectedItem(item); onSelect(item, index); }; @@ -57,7 +58,7 @@ function Tabs({ items, defaultSelected, onSelect }) { selected={selectedItem.text === item.text} iconSrc={item.iconSrc} disabled={item.disabled} - onClick={() => handleTabSelection(item, index)} + onClick={(e) => handleTabSelection(item, index, e.currentTarget)} > {item.text} From 76d60b09581f735cc774db4110dba8ee02920902 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 14 May 2024 14:01:45 +1000 Subject: [PATCH 1139/1531] Bump vite-plugin-static-copy from 0.13.0 to 1.0.4 (#1722) * Bump vite-plugin-static-copy from 0.13.0 to 1.0.4 Bumps [vite-plugin-static-copy](https://github.com/sapphi-red/vite-plugin-static-copy) from 0.13.0 to 1.0.4. - [Release notes](https://github.com/sapphi-red/vite-plugin-static-copy/releases) - [Changelog](https://github.com/sapphi-red/vite-plugin-static-copy/blob/main/CHANGELOG.md) - [Commits](https://github.com/sapphi-red/vite-plugin-static-copy/compare/v0.13.0...vite-plugin-static-copy@1.0.4) --- updated-dependencies: - dependency-name: vite-plugin-static-copy dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] * Change type to module --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Krishan <33421343+kfiven@users.noreply.github.com> --- package-lock.json | 12 ++++++------ package.json | 3 ++- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index 90da965b0..2eec29124 100644 --- a/package-lock.json +++ b/package-lock.json @@ -92,7 +92,7 @@ "sass": "1.56.2", "typescript": "4.9.4", "vite": "5.0.13", - "vite-plugin-static-copy": "0.13.0", + "vite-plugin-static-copy": "1.0.4", "vite-plugin-top-level-await": "1.4.1" }, "engines": { @@ -8902,9 +8902,9 @@ } }, "node_modules/vite-plugin-static-copy": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/vite-plugin-static-copy/-/vite-plugin-static-copy-0.13.0.tgz", - "integrity": "sha512-cln+fvKMgwNBjxQ59QVblmExZrc9gGEdRmfqcPOOGpxT5KInfpkGMvmK4L+kCAeHHSSGNU1bM7BA9PQgaAJc6g==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/vite-plugin-static-copy/-/vite-plugin-static-copy-1.0.4.tgz", + "integrity": "sha512-UtyOttgoeotSCwmBugsEZCZJZcIpjE9NGO7jlZ9OeedYpBueBdspD8waRZrjE+yQLH6qGNU2CvYB2FILviCQjg==", "dev": true, "dependencies": { "chokidar": "^3.5.3", @@ -8913,10 +8913,10 @@ "picocolors": "^1.0.0" }, "engines": { - "node": "^14.18.0 || >=16.0.0" + "node": "^18.0.0 || >=20.0.0" }, "peerDependencies": { - "vite": "^3.0.0 || ^4.0.0" + "vite": "^5.0.0" } }, "node_modules/vite-plugin-static-copy/node_modules/fs-extra": { diff --git a/package.json b/package.json index 8c8b87e78..44c28d348 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,7 @@ "version": "3.2.0", "description": "Yet another matrix client", "main": "index.js", + "type": "module", "engines": { "node": ">=16.0.0" }, @@ -102,7 +103,7 @@ "sass": "1.56.2", "typescript": "4.9.4", "vite": "5.0.13", - "vite-plugin-static-copy": "0.13.0", + "vite-plugin-static-copy": "1.0.4", "vite-plugin-top-level-await": "1.4.1" } } From e15b16b19b7c95a4053dbbfa5ed1e7dffcc5320f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 14 May 2024 14:18:40 +1000 Subject: [PATCH 1140/1531] Bump nginx from 1.25.5-alpine to 1.26.0-alpine (#1718) Bumps nginx from 1.25.5-alpine to 1.26.0-alpine. --- updated-dependencies: - dependency-name: nginx dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 6cd3ebf61..f843fbf19 100644 --- a/Dockerfile +++ b/Dockerfile @@ -11,7 +11,7 @@ RUN npm run build ## App -FROM nginx:1.25.5-alpine +FROM nginx:1.26.0-alpine COPY --from=builder /src/dist /app From 07bfa0cf104608b74be1254b3870b8186b10730e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 22 May 2024 21:54:48 +1000 Subject: [PATCH 1141/1531] --- (#1741) updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build-pull-request.yml | 2 +- .github/workflows/docker-pr.yml | 2 +- .github/workflows/lockfile.yml | 2 +- .github/workflows/netlify-dev.yml | 2 +- .github/workflows/prod-deploy.yml | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build-pull-request.yml b/.github/workflows/build-pull-request.yml index e651a344b..133729f70 100644 --- a/.github/workflows/build-pull-request.yml +++ b/.github/workflows/build-pull-request.yml @@ -12,7 +12,7 @@ jobs: PR_NUMBER: ${{github.event.number}} steps: - name: Checkout repository - uses: actions/checkout@v4.1.5 + uses: actions/checkout@v4.1.6 - name: Setup node uses: actions/setup-node@v4.0.2 with: diff --git a/.github/workflows/docker-pr.yml b/.github/workflows/docker-pr.yml index 7deb40d10..de29ff35d 100644 --- a/.github/workflows/docker-pr.yml +++ b/.github/workflows/docker-pr.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v4.1.5 + uses: actions/checkout@v4.1.6 - name: Build Docker image uses: docker/build-push-action@v5.3.0 with: diff --git a/.github/workflows/lockfile.yml b/.github/workflows/lockfile.yml index dda75783d..af91698ea 100644 --- a/.github/workflows/lockfile.yml +++ b/.github/workflows/lockfile.yml @@ -14,7 +14,7 @@ jobs: pull-requests: write steps: - name: Checkout - uses: actions/checkout@v4.1.5 + uses: actions/checkout@v4.1.6 - name: NPM Lockfile Changes uses: codepunkt/npm-lockfile-changes@b40543471c36394409466fdb277a73a0856d7891 with: diff --git a/.github/workflows/netlify-dev.yml b/.github/workflows/netlify-dev.yml index 518d554a7..9252e3e4d 100644 --- a/.github/workflows/netlify-dev.yml +++ b/.github/workflows/netlify-dev.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v4.1.5 + uses: actions/checkout@v4.1.6 - name: Setup node uses: actions/setup-node@v4.0.2 with: diff --git a/.github/workflows/prod-deploy.yml b/.github/workflows/prod-deploy.yml index 3d2f10942..a203ea34c 100644 --- a/.github/workflows/prod-deploy.yml +++ b/.github/workflows/prod-deploy.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v4.1.5 + uses: actions/checkout@v4.1.6 - name: Setup node uses: actions/setup-node@v4.0.2 with: @@ -66,7 +66,7 @@ jobs: packages: write steps: - name: Checkout repository - uses: actions/checkout@v4.1.5 + uses: actions/checkout@v4.1.6 - name: Set up QEMU uses: docker/setup-qemu-action@v3.0.0 - name: Set up Docker Buildx From 2b7d8256943c2d2da5089b2626fd038c056672eb Mon Sep 17 00:00:00 2001 From: Majan Paul Date: Wed, 22 May 2024 04:56:44 -0700 Subject: [PATCH 1142/1531] Ignroe webstorm idea folder (#1638) --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 397d2434d..1af58a970 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ node_modules devAssets .DS_Store +.idea \ No newline at end of file From 4c76a7fd180c56daacae3fc3c01706aa3ea92bd2 Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Fri, 31 May 2024 19:49:46 +0530 Subject: [PATCH 1143/1531] URL navigation in interface and other improvements (#1633) * load room on url change * add direct room list * render space room list * fix css syntax error * update scroll virtualizer * render subspaces room list * improve sidebar notification badge perf * add nav category components * add space recursive direct component * use nav category component in home, direct and space room list * add empty home and direct list layout * fix unread room menu ref * add more navigation items in room, direct and space tab * add more navigation * fix unread room menu to links * fix space lobby and search link * add explore navigation section * add notifications navigation menu * redirect to initial path after login * include unsupported room in rooms * move router hooks in hooks/router folder * add featured explore - WIP * load featured room with room summary * fix room card topic line clamp * add react query * load room summary using react query * add join button in room card * add content component * use content component in featured community content * fix content width * add responsive room card grid * fix async callback error status * add room card error button * fix client drawer shrink * add room topic viewer * open room card topic in viewer * fix room topic close btn * add get orphan parent util * add room card error dialog * add view featured room or space btn * refactor orphanParent to orphanParents * WIP - explore server * show space hint in room card * add room type filters * add per page item limit popout * reset scroll on public rooms load * refactor explore ui * refactor public rooms component * reset search on server change * fix typo * add empty featured section info * display user server on top * make server room card view btn clickable * add user server as default redirect for explore path * make home empty btn clickable * add thirdparty instance filter in server explore * remove since param on instance change * add server button in explore menu * rename notifications path to inbox * update react-virtual * Add notification messages inbox - WIP * add scroll top container component * add useInterval hook * add visibility change callback prop to scroll top container component * auto refresh notifications every 10 seconds * make message related component reusable * refactor matrix event renderer hoook * render notification message content * refactor matrix event renderer hook * update sequence card styles * move room navigate hook in global hooks * add open message button in notifications * add mark room as read button in notification group * show error in notification messages * add more featured spaces * render reply in notification messages * make notification message reply clickable * add outline prop for attachments * make old settings dialog viewable * add open featured communities as default config option * add invite count notification badge in sidebar and inbox menu * add element size observer hook * improve element size observer hook props * improve screen size hook * fix room avatar util function * allow Text props in Time component * fix dm room util function * add invitations * add no invites and notification cards * fix inbox tab unread badge visible without invite count * update folds and change inbox icon * memo search param construction * add message search in home * fix default message search order * fix display edited message new content * highlight search text in search messages * fix message search loading * disable log in production * add use space context * add useRoom context * fix space room list * fix inbox tab active state * add hook to get space child room recursive * add search for space * add virtual tile component * virtualize home and directs room list * update nav category component * use virtual tile component in more places * fix message highlight when click on reply twice * virtualize space room list * fix space room list lag issue * update folds * add room nav item component in space room list * use room nav item in home and direct room list * make space categories closable and save it in local storage * show unread room when category is collapsed * make home and direct room list category closable * rename room nav item show avatar prop * fix explore server category text alignment * rename closedRoomCategories to closedNavCategories * add nav category handler hook * save and restore last navigation path on space select * filter space rooms category by activity when it is closed * save and restore home and direct nav path state * save and restore inbox active path on open * save and restore explore tab active path * remove notification badge unread menu * add join room or space before navigate screen * move room component to features folder and add new room header * update folds * add room header menu * fix home room list activity sorting * do not hide selected room item on category closed in home and direct tab * replace old select room/tab call with navigate hook * improve state event hooks * show room card summary for joined rooms * prevent room from opening in wrong tab * only show message sender id on hover in modern layout * revert state event hooks changes * add key prop to room provider components * add welcome page * prevent excessive redirects * fix sidebar style with no spaces * move room settings in popup window * remove invite option from room settings * fix open room list search * add leave room prompt * standardize room and user avatar * fix avatar text size * add new reply layout * rename space hierarchy hook * add room topic hook * add room name hook * add room avatar hook and add direct room avatar util * space lobby - WIP * hide invalid space child event from space hierarchy in lobby * move lobby to features * fix element size observer hook width and height * add lobby header and hero section * add hierarchy room item error and loading state * add first and last child prop in sequence card * redirect to lobby from index path * memo and retry hierarchy room summary error * fix hierarchy room item styles * rename lobby hierarchy item card to room item card * show direct room avatar in space lobby * add hierarchy space item * add space item unknown room join button * fix space hierarchy hook refresh after new space join * change user avatar color and fallback render to user icon * change room avatar fallback to room icon * rename room/user avatar renderInitial prop to renderFallback * add room join and view button in space lobby * make power level api more reusable * fix space hierarchy not updating on child update * add menu to suggest or remove space children * show reply arrow in place of reply bend in message * fix typeerror in search because of wrong js-sdk t.ds * do not refetch hierarchy room summary on window focus * make room/user avatar un-draggable * change welcome page support button copy * drag-and-drop ordering of lobby spaces/rooms - WIP * add ASCIILexicalTable algorithms * fix wrong power level check in lobby items options * fix lobby can drop checks * fix join button error crash * fix reply spacing * fix m direct updated with other account data * add option to open room/space settings from lobby * add option in lobby to add new or existing room/spaces * fix room nav item selected styles * add space children reorder mechanism * fix space child reorder bug * fix hierarchy item sort function * Apply reorder of lobby into room list * add and improve space lobby menu items * add existing spaces menu in lobby * change restricted room allow params when dragging outside space * move featured servers config from homeserver list * removed unused features from space settings * add canonical alias as name fallback in lobby item * fix unreliable unread count update bug * fix after login redirect * fix room card topic hover style * Add dnd and folders in sidebar spaces * fix orphan space not visible in sidebar * fix sso login has mix of icon and button * fix space children not visible in home upon leaving space * recalculate notification on updating any space child * fix user color saturation/lightness * add user color to user avatar * add background colors to room avatar * show 2 length initial in sidebar space avatar * improve link color * add nav button component * open legacy create room and create direct * improve page route structure * handle hash router in path utils * mobile friendly router and navigation * make room header member drawer icon mobile friendly * setup index redirect for inbox and explore server route * add leave space prompt * improve member drawer filter menu * add space context menu * add context menu in home * add leave button in lobby items * render user tab avatar on sidebar * force overwrite netlify - test * netlify test * fix reset-password path without server redirected to login * add message link copy button in message menu * reset unread on sync prepared * fix stuck typing notifications * show typing indication in room nav item * refactor closedNavCategories atom to use userId in store key * refactor closedLobbyCategoriesAtom to include userId in store key * refactor navToActivePathAtom to use userId in storage key * remove unused file * refactor openedSidebarFolderAtom to include userId in storage key * add context menu for sidebar space tab * fix eslint not working * add option to pin/unpin child spaces * add context menu for directs tab * add context menu for direct and home tab * show lock icon for non-public space in header * increase matrix max listener count * wrap lobby add space room in callback hook --- .eslintrc.js => .eslintrc.cjs | 0 config.json | 20 + netlify.toml | 6 +- package-lock.json | 121 +- package.json | 9 +- .../CapabilitiesAndMediaConfigLoader.tsx | 36 + src/app/components/CapabilitiesLoader.tsx | 19 + src/app/components/MediaConfigLoader.tsx | 19 + src/app/components/Pdf-viewer/PdfViewer.tsx | 34 +- src/app/components/RenderMessageContent.tsx | 245 ++++ src/app/components/RoomSummaryLoader.tsx | 90 ++ src/app/components/RoomUnreadProvider.tsx | 24 + .../components/SpaceChildDirectsProvider.tsx | 28 + .../components/SpaceChildRoomsProvider.tsx | 28 + src/app/components/SpecVersionsLoader.tsx | 31 +- src/app/components/editor/Toolbar.tsx | 43 +- .../autocomplete/RoomMentionAutocomplete.tsx | 56 +- .../autocomplete/UserMentionAutocomplete.tsx | 37 +- .../components/event-readers/EventReaders.tsx | 22 +- .../leave-room-prompt/LeaveRoomPrompt.tsx | 106 ++ src/app/components/leave-room-prompt/index.ts | 1 + .../leave-space-prompt/LeaveSpacePrompt.tsx | 106 ++ .../components/leave-space-prompt/index.ts | 1 + .../message/FileHeader.tsx | 2 +- .../components/message/MsgTypeRenderers.tsx | 398 ++++++ src/app/components/message/RenderBody.tsx | 37 + src/app/components/message/Reply.css.ts | 15 +- src/app/components/message/Reply.tsx | 171 +-- src/app/components/message/Time.tsx | 38 +- .../message/content/AudioContent.tsx | 199 +++ .../message/content}/EventContent.tsx | 2 +- .../FallbackContent.tsx} | 0 .../message/content}/FileContent.tsx | 99 +- .../message/content}/ImageContent.tsx | 67 +- .../message/content/ThumbnailContent.tsx | 34 + .../message/content}/VideoContent.tsx | 71 +- src/app/components/message/content/index.ts | 7 + .../components/message/content/style.css.ts | 37 + .../message/content}/util.ts | 0 src/app/components/message/index.ts | 5 +- .../components/message/layout/layout.css.ts | 7 +- src/app/components/nav/NavCategory.tsx | 11 + src/app/components/nav/NavCategoryHeader.tsx | 19 + src/app/components/nav/NavEmptyLayout.tsx | 40 + src/app/components/nav/NavItem.tsx | 33 + src/app/components/nav/NavItemContent.tsx | 10 + src/app/components/nav/NavItemOptions.tsx | 17 + src/app/components/nav/index.ts | 6 + src/app/components/nav/styles.css.ts | 127 ++ src/app/components/page/Page.tsx | 146 +++ src/app/components/page/index.tsx | 1 + src/app/components/page/style.css.ts | 69 ++ .../components/room-avatar/RoomAvatar.css.ts | 14 + src/app/components/room-avatar/RoomAvatar.tsx | 56 + src/app/components/room-avatar/index.ts | 1 + src/app/components/room-card/RoomCard.tsx | 314 +++++ src/app/components/room-card/index.ts | 1 + src/app/components/room-card/style.css.ts | 36 + src/app/components/room-intro/RoomIntro.tsx | 49 +- .../room-topic-viewer/RoomTopicViewer.tsx | 41 + src/app/components/room-topic-viewer/index.ts | 1 + .../components/room-topic-viewer/style.css.ts | 23 + .../ScrollTopContainer.tsx | 39 + .../components/scroll-top-container/index.ts | 1 + .../scroll-top-container/style.css.ts | 20 + .../components/sequence-card/SequenceCard.tsx | 18 + src/app/components/sequence-card/index.ts | 1 + src/app/components/sequence-card/style.css.ts | 52 + src/app/components/sidebar/Sidebar.css.ts | 162 ++- src/app/components/sidebar/SidebarAvatar.tsx | 75 -- src/app/components/sidebar/SidebarContent.tsx | 6 +- src/app/components/sidebar/SidebarItem.tsx | 81 ++ src/app/components/sidebar/index.ts | 2 +- .../typing-indicator/TypingIndicator.css.ts | 7 +- .../typing-indicator/TypingIndicator.tsx | 31 +- .../components/unread-badge/UnreadBadge.tsx | 36 + src/app/components/unread-badge/index.ts | 1 + .../url-preview/UrlPreviewCard.css.tsx | 47 + .../url-preview}/UrlPreviewCard.tsx | 15 +- src/app/components/url-preview/index.ts | 1 + .../components/user-avatar/UserAvatar.css.ts | 14 + src/app/components/user-avatar/UserAvatar.tsx | 40 + src/app/components/user-avatar/index.ts | 1 + .../components/virtualizer/VirtualTile.tsx | 20 + src/app/components/virtualizer/index.ts | 1 + src/app/components/virtualizer/style.css.ts | 11 + src/app/cs-api.ts | 2 +- .../JoinBeforeNavigate.tsx | 61 + .../features/join-before-navigate/index.ts | 1 + src/app/features/lobby/DnD.css.ts | 91 ++ src/app/features/lobby/DnD.tsx | 146 +++ src/app/features/lobby/HierarchyItemMenu.tsx | 306 +++++ src/app/features/lobby/Lobby.tsx | 528 ++++++++ src/app/features/lobby/LobbyHeader.css.ts | 13 + src/app/features/lobby/LobbyHeader.tsx | 214 ++++ src/app/features/lobby/LobbyHero.css.tsx | 15 + src/app/features/lobby/LobbyHero.tsx | 77 ++ src/app/features/lobby/RoomItem.css.ts | 22 + src/app/features/lobby/RoomItem.tsx | 441 +++++++ src/app/features/lobby/SpaceItem.css.ts | 39 + src/app/features/lobby/SpaceItem.tsx | 493 ++++++++ src/app/features/lobby/index.ts | 1 + src/app/features/lobby/style.css.ts | 15 + .../features/message-search/MessageSearch.tsx | 329 +++++ .../features/message-search/SearchFilters.tsx | 413 +++++++ .../features/message-search/SearchInput.tsx | 66 + .../message-search/SearchResultGroup.tsx | 262 ++++ src/app/features/message-search/index.ts | 1 + .../message-search/useMessageSearch.ts | 115 ++ .../room-nav/RoomNavCategoryButton.tsx | 27 + src/app/features/room-nav/RoomNavItem.tsx | 297 +++++ src/app/features/room-nav/index.ts | 2 + src/app/features/room-nav/styles.css.ts | 9 + .../room/CommandAutocomplete.tsx | 0 .../room/MembersDrawer.css.ts | 0 .../room/MembersDrawer.tsx | 174 ++- src/app/features/room/Room.tsx | 33 + .../room/RoomInput.tsx | 122 +- .../room/RoomInputPlaceholder.css.ts | 0 .../room/RoomInputPlaceholder.tsx | 0 .../room/RoomTimeline.css.ts | 0 .../room/RoomTimeline.tsx | 1085 +++++++---------- .../room/RoomTombstone.css.ts | 0 .../room/RoomTombstone.tsx | 8 +- src/app/features/room/RoomView.tsx | 84 ++ .../room/RoomViewFollowing.css.ts | 0 .../room/RoomViewFollowing.tsx | 0 src/app/features/room/RoomViewHeader.css.ts | 10 + src/app/features/room/RoomViewHeader.tsx | 348 ++++++ .../room/RoomViewTyping.css.ts | 0 src/app/features/room/RoomViewTyping.tsx | 121 ++ src/app/features/room/index.ts | 1 + .../room/message/EncryptedContent.tsx | 0 .../room/message/Message.tsx | 247 ++-- .../room/message/MessageEditor.tsx | 57 +- .../room/message/Reactions.tsx | 0 src/app/features/room/message/index.ts | 3 + src/app/features/room/message/styles.css.ts | 50 + .../room/msgContent.ts | 2 +- .../reaction-viewer/ReactionViewer.css.ts | 0 .../room/reaction-viewer/ReactionViewer.tsx | 22 +- .../room/reaction-viewer/index.ts | 0 src/app/hooks/router/useDirectSelected.ts | 22 + src/app/hooks/router/useExploreSelected.ts | 28 + src/app/hooks/router/useHomeSelected.ts | 47 + src/app/hooks/router/useInbox.ts | 36 + src/app/hooks/router/useSelectedRoom.ts | 15 + src/app/hooks/router/useSelectedSpace.ts | 37 + src/app/hooks/useAccountDataCallback.ts | 14 + src/app/hooks/useAsyncCallback.ts | 17 +- src/app/hooks/useCapabilities.ts | 12 + src/app/hooks/useCategoryHandler.ts | 27 + src/app/hooks/useClientConfig.ts | 15 +- src/app/hooks/useCommands.ts | 14 +- src/app/hooks/useElementSizeObserver.ts | 23 + src/app/hooks/useInterval.ts | 24 + src/app/hooks/useJoinedRoomId.ts | 19 + src/app/hooks/useLocalRoomSummary.ts | 44 + src/app/hooks/useMatrixEventRenderer.ts | 81 +- src/app/hooks/useMediaConfig.ts | 16 + src/app/hooks/useNavToActivePathMapper.ts | 18 + src/app/hooks/usePowerLevels.ts | 167 ++- src/app/hooks/useRoom.ts | 12 + src/app/hooks/useRoomMeta.ts | 41 + src/app/hooks/useRoomMsgContentRenderer.ts | 68 -- src/app/hooks/useRoomNavigate.ts | 55 + src/app/hooks/useRoomTypingMembers.ts | 10 + src/app/hooks/useScreenSize.ts | 35 +- src/app/hooks/useSidebarItems.ts | 138 +++ src/app/hooks/useSpace.ts | 17 + src/app/hooks/useSpaceHierarchy.ts | 253 ++++ src/app/hooks/useSyncState.ts | 14 + src/app/hooks/useTypingStatusUpdater.ts | 3 +- .../space-add-existing/SpaceAddExisting.jsx | 175 +-- src/app/organisms/navigation/Drawer.jsx | 12 +- src/app/organisms/navigation/Sidebar1.tsx | 125 -- src/app/organisms/pw/Windows.jsx | 14 +- src/app/organisms/room/Room.scss | 1 + src/app/organisms/room/Room.tsx | 46 - src/app/organisms/room/RoomSettings.jsx | 162 ++- src/app/organisms/room/RoomSettings.scss | 65 +- src/app/organisms/room/RoomView.jsx | 118 -- src/app/organisms/room/RoomViewTyping.tsx | 118 -- .../organisms/room/message/AudioContent.tsx | 194 --- .../organisms/room/message/StickerContent.tsx | 48 - .../organisms/room/message/fileRenderer.tsx | 45 - src/app/organisms/room/message/index.ts | 10 - src/app/organisms/room/message/styles.css.ts | 131 -- src/app/organisms/search/Search.jsx | 30 +- .../space-settings/SpaceSettings.jsx | 79 +- src/app/pages/App.tsx | 101 +- src/app/pages/MobileFriendly.tsx | 44 + src/app/pages/Router.tsx | 269 ++++ src/app/pages/afterLoginRedirectPath.ts | 12 + src/app/pages/auth/AuthLayout.tsx | 17 +- src/app/pages/auth/SSOLogin.tsx | 6 +- src/app/pages/auth/ServerPicker.tsx | 39 +- src/app/pages/auth/login/Login.tsx | 18 +- .../pages/auth/login/PasswordLoginForm.tsx | 38 +- src/app/pages/auth/login/loginUtil.ts | 11 +- src/app/pages/auth/register/Register.tsx | 18 +- src/app/pages/auth/register/registerUtil.ts | 23 +- .../auth/reset-password/ResetPassword.tsx | 21 +- src/app/pages/client/ClientBindAtoms.ts | 14 + .../pages/client/ClientInitStorageAtom.tsx | 38 + src/app/pages/client/ClientLayout.tsx | 15 + src/app/pages/client/ClientRoot.tsx | 87 ++ src/app/pages/client/SidebarNav.tsx | 76 ++ src/app/pages/client/SpecVersions.tsx | 46 + src/app/pages/client/WelcomePage.tsx | 64 + src/app/pages/client/direct/Direct.tsx | 263 ++++ src/app/pages/client/direct/RoomProvider.tsx | 26 + src/app/pages/client/direct/index.ts | 2 + src/app/pages/client/direct/useDirectRooms.ts | 12 + src/app/pages/client/explore/Explore.tsx | 269 ++++ src/app/pages/client/explore/Featured.tsx | 121 ++ src/app/pages/client/explore/Server.tsx | 645 ++++++++++ src/app/pages/client/explore/index.ts | 3 + src/app/pages/client/explore/style.css.ts | 19 + src/app/pages/client/home/Home.tsx | 315 +++++ src/app/pages/client/home/RoomProvider.tsx | 26 + src/app/pages/client/home/Search.tsx | 37 + src/app/pages/client/home/index.ts | 3 + src/app/pages/client/home/useHomeRooms.ts | 14 + src/app/pages/client/inbox/Inbox.tsx | 87 ++ src/app/pages/client/inbox/Invites.tsx | 288 +++++ src/app/pages/client/inbox/Notifications.tsx | 609 +++++++++ src/app/pages/client/inbox/index.ts | 3 + src/app/pages/client/index.ts | 3 + src/app/pages/client/sidebar/DirectTab.tsx | 132 ++ src/app/pages/client/sidebar/ExploreTab.tsx | 64 + src/app/pages/client/sidebar/HomeTab.tsx | 134 ++ src/app/pages/client/sidebar/InboxTab.tsx | 62 + src/app/pages/client/sidebar/SpaceTabs.tsx | 844 +++++++++++++ src/app/pages/client/sidebar/UserTab.tsx | 63 + src/app/pages/client/sidebar/index.ts | 6 + src/app/pages/client/space/RoomProvider.tsx | 37 + src/app/pages/client/space/Search.tsx | 52 + src/app/pages/client/space/Space.tsx | 417 +++++++ src/app/pages/client/space/SpaceProvider.tsx | 30 + src/app/pages/client/space/index.ts | 4 + src/app/pages/pathUtils.ts | 133 +- src/app/pages/paths.ts | 65 + src/app/plugins/millify.ts | 9 + src/app/plugins/pdfjs-dist.ts | 5 +- src/app/plugins/react-custom-html-parser.tsx | 56 +- src/app/state/closedLobbyCategories.ts | 68 ++ src/app/state/closedNavCategories.ts | 68 ++ src/app/state/hooks/closedLobbyCategories.ts | 15 + src/app/state/hooks/closedNavCategories.ts | 15 + src/app/state/hooks/inviteList.ts | 11 +- src/app/state/hooks/navToActivePath.ts | 15 + src/app/state/hooks/openedSidebarFolder.ts | 15 + src/app/state/hooks/roomList.ts | 189 ++- src/app/state/hooks/unread.ts | 46 + src/app/state/hooks/useBindAtoms.ts | 13 +- src/app/state/mDirectList.ts | 10 +- src/app/state/navToActivePath.ts | 66 + src/app/state/openedSidebarFolder.ts | 66 + src/app/state/{ => room-list}/inviteList.ts | 2 +- .../state/{ => room-list}/mutedRoomList.ts | 4 +- src/app/state/{ => room-list}/roomList.ts | 2 +- src/app/state/{ => room-list}/utils.ts | 6 +- src/app/state/{ => room}/roomInputDrafts.ts | 6 +- src/app/state/{ => room}/roomToParents.ts | 8 +- src/app/state/{ => room}/roomToUnread.ts | 94 +- src/app/state/selectedRoom.ts | 3 - src/app/state/selectedTab.ts | 8 - src/app/state/spaceRooms.ts | 54 + src/app/state/tabToRoom.ts | 34 - src/app/state/typingMembers.ts | 133 +- src/app/styles/ContainerColor.css.ts | 33 + src/app/styles/CustomHtml.css.ts | 8 + src/app/templates/client/Client.jsx | 94 +- src/app/templates/client/Client.scss | 3 +- src/app/templates/client/ClientContent.jsx | 2 +- src/app/utils/ASCIILexicalTable.ts | 393 ++++++ src/app/utils/common.ts | 17 + src/app/utils/keyboard.ts | 7 + src/app/utils/matrix.ts | 89 +- src/app/utils/regex.ts | 8 + src/app/utils/room.ts | 61 +- src/app/utils/sort.ts | 59 + src/client/action/navigation.js | 8 +- src/client/event/hotkeys.js | 6 +- src/client/initMatrix.js | 21 +- src/client/state/navigation.js | 12 +- src/index.scss | 40 +- src/types/matrix/room.ts | 22 +- vite.config.js | 6 + 290 files changed, 17447 insertions(+), 3224 deletions(-) rename .eslintrc.js => .eslintrc.cjs (100%) create mode 100644 src/app/components/CapabilitiesAndMediaConfigLoader.tsx create mode 100644 src/app/components/CapabilitiesLoader.tsx create mode 100644 src/app/components/MediaConfigLoader.tsx create mode 100644 src/app/components/RenderMessageContent.tsx create mode 100644 src/app/components/RoomSummaryLoader.tsx create mode 100644 src/app/components/RoomUnreadProvider.tsx create mode 100644 src/app/components/SpaceChildDirectsProvider.tsx create mode 100644 src/app/components/SpaceChildRoomsProvider.tsx create mode 100644 src/app/components/leave-room-prompt/LeaveRoomPrompt.tsx create mode 100644 src/app/components/leave-room-prompt/index.ts create mode 100644 src/app/components/leave-space-prompt/LeaveSpacePrompt.tsx create mode 100644 src/app/components/leave-space-prompt/index.ts rename src/app/{organisms/room => components}/message/FileHeader.tsx (91%) create mode 100644 src/app/components/message/MsgTypeRenderers.tsx create mode 100644 src/app/components/message/RenderBody.tsx create mode 100644 src/app/components/message/content/AudioContent.tsx rename src/app/{organisms/room/message => components/message/content}/EventContent.tsx (93%) rename src/app/components/message/{MessageContentFallback.tsx => content/FallbackContent.tsx} (100%) rename src/app/{organisms/room/message => components/message/content}/FileContent.tsx (76%) rename src/app/{organisms/room/message => components/message/content}/ImageContent.tsx (81%) create mode 100644 src/app/components/message/content/ThumbnailContent.tsx rename src/app/{organisms/room/message => components/message/content}/VideoContent.tsx (77%) create mode 100644 src/app/components/message/content/index.ts create mode 100644 src/app/components/message/content/style.css.ts rename src/app/{organisms/room/message => components/message/content}/util.ts (100%) create mode 100644 src/app/components/nav/NavCategory.tsx create mode 100644 src/app/components/nav/NavCategoryHeader.tsx create mode 100644 src/app/components/nav/NavEmptyLayout.tsx create mode 100644 src/app/components/nav/NavItem.tsx create mode 100644 src/app/components/nav/NavItemContent.tsx create mode 100644 src/app/components/nav/NavItemOptions.tsx create mode 100644 src/app/components/nav/index.ts create mode 100644 src/app/components/nav/styles.css.ts create mode 100644 src/app/components/page/Page.tsx create mode 100644 src/app/components/page/index.tsx create mode 100644 src/app/components/page/style.css.ts create mode 100644 src/app/components/room-avatar/RoomAvatar.css.ts create mode 100644 src/app/components/room-avatar/RoomAvatar.tsx create mode 100644 src/app/components/room-avatar/index.ts create mode 100644 src/app/components/room-card/RoomCard.tsx create mode 100644 src/app/components/room-card/index.ts create mode 100644 src/app/components/room-card/style.css.ts create mode 100644 src/app/components/room-topic-viewer/RoomTopicViewer.tsx create mode 100644 src/app/components/room-topic-viewer/index.ts create mode 100644 src/app/components/room-topic-viewer/style.css.ts create mode 100644 src/app/components/scroll-top-container/ScrollTopContainer.tsx create mode 100644 src/app/components/scroll-top-container/index.ts create mode 100644 src/app/components/scroll-top-container/style.css.ts create mode 100644 src/app/components/sequence-card/SequenceCard.tsx create mode 100644 src/app/components/sequence-card/index.ts create mode 100644 src/app/components/sequence-card/style.css.ts delete mode 100644 src/app/components/sidebar/SidebarAvatar.tsx create mode 100644 src/app/components/sidebar/SidebarItem.tsx create mode 100644 src/app/components/unread-badge/UnreadBadge.tsx create mode 100644 src/app/components/unread-badge/index.ts create mode 100644 src/app/components/url-preview/UrlPreviewCard.css.tsx rename src/app/{organisms/room/message => components/url-preview}/UrlPreviewCard.tsx (94%) create mode 100644 src/app/components/user-avatar/UserAvatar.css.ts create mode 100644 src/app/components/user-avatar/UserAvatar.tsx create mode 100644 src/app/components/user-avatar/index.ts create mode 100644 src/app/components/virtualizer/VirtualTile.tsx create mode 100644 src/app/components/virtualizer/index.ts create mode 100644 src/app/components/virtualizer/style.css.ts create mode 100644 src/app/features/join-before-navigate/JoinBeforeNavigate.tsx create mode 100644 src/app/features/join-before-navigate/index.ts create mode 100644 src/app/features/lobby/DnD.css.ts create mode 100644 src/app/features/lobby/DnD.tsx create mode 100644 src/app/features/lobby/HierarchyItemMenu.tsx create mode 100644 src/app/features/lobby/Lobby.tsx create mode 100644 src/app/features/lobby/LobbyHeader.css.ts create mode 100644 src/app/features/lobby/LobbyHeader.tsx create mode 100644 src/app/features/lobby/LobbyHero.css.tsx create mode 100644 src/app/features/lobby/LobbyHero.tsx create mode 100644 src/app/features/lobby/RoomItem.css.ts create mode 100644 src/app/features/lobby/RoomItem.tsx create mode 100644 src/app/features/lobby/SpaceItem.css.ts create mode 100644 src/app/features/lobby/SpaceItem.tsx create mode 100644 src/app/features/lobby/index.ts create mode 100644 src/app/features/lobby/style.css.ts create mode 100644 src/app/features/message-search/MessageSearch.tsx create mode 100644 src/app/features/message-search/SearchFilters.tsx create mode 100644 src/app/features/message-search/SearchInput.tsx create mode 100644 src/app/features/message-search/SearchResultGroup.tsx create mode 100644 src/app/features/message-search/index.ts create mode 100644 src/app/features/message-search/useMessageSearch.ts create mode 100644 src/app/features/room-nav/RoomNavCategoryButton.tsx create mode 100644 src/app/features/room-nav/RoomNavItem.tsx create mode 100644 src/app/features/room-nav/index.ts create mode 100644 src/app/features/room-nav/styles.css.ts rename src/app/{organisms => features}/room/CommandAutocomplete.tsx (100%) rename src/app/{organisms => features}/room/MembersDrawer.css.ts (100%) rename src/app/{organisms => features}/room/MembersDrawer.tsx (79%) create mode 100644 src/app/features/room/Room.tsx rename src/app/{organisms => features}/room/RoomInput.tsx (85%) rename src/app/{organisms => features}/room/RoomInputPlaceholder.css.ts (100%) rename src/app/{organisms => features}/room/RoomInputPlaceholder.tsx (100%) rename src/app/{organisms => features}/room/RoomTimeline.css.ts (100%) rename src/app/{organisms => features}/room/RoomTimeline.tsx (62%) rename src/app/{organisms => features}/room/RoomTombstone.css.ts (100%) rename src/app/{organisms => features}/room/RoomTombstone.tsx (90%) create mode 100644 src/app/features/room/RoomView.tsx rename src/app/{organisms => features}/room/RoomViewFollowing.css.ts (100%) rename src/app/{organisms => features}/room/RoomViewFollowing.tsx (100%) create mode 100644 src/app/features/room/RoomViewHeader.css.ts create mode 100644 src/app/features/room/RoomViewHeader.tsx rename src/app/{organisms => features}/room/RoomViewTyping.css.ts (100%) create mode 100644 src/app/features/room/RoomViewTyping.tsx create mode 100644 src/app/features/room/index.ts rename src/app/{organisms => features}/room/message/EncryptedContent.tsx (100%) rename src/app/{organisms => features}/room/message/Message.tsx (84%) rename src/app/{organisms => features}/room/message/MessageEditor.tsx (89%) rename src/app/{organisms => features}/room/message/Reactions.tsx (100%) create mode 100644 src/app/features/room/message/index.ts create mode 100644 src/app/features/room/message/styles.css.ts rename src/app/{organisms => features}/room/msgContent.ts (98%) rename src/app/{organisms => features}/room/reaction-viewer/ReactionViewer.css.ts (100%) rename src/app/{organisms => features}/room/reaction-viewer/ReactionViewer.tsx (89%) rename src/app/{organisms => features}/room/reaction-viewer/index.ts (100%) create mode 100644 src/app/hooks/router/useDirectSelected.ts create mode 100644 src/app/hooks/router/useExploreSelected.ts create mode 100644 src/app/hooks/router/useHomeSelected.ts create mode 100644 src/app/hooks/router/useInbox.ts create mode 100644 src/app/hooks/router/useSelectedRoom.ts create mode 100644 src/app/hooks/router/useSelectedSpace.ts create mode 100644 src/app/hooks/useAccountDataCallback.ts create mode 100644 src/app/hooks/useCapabilities.ts create mode 100644 src/app/hooks/useCategoryHandler.ts create mode 100644 src/app/hooks/useElementSizeObserver.ts create mode 100644 src/app/hooks/useInterval.ts create mode 100644 src/app/hooks/useJoinedRoomId.ts create mode 100644 src/app/hooks/useLocalRoomSummary.ts create mode 100644 src/app/hooks/useMediaConfig.ts create mode 100644 src/app/hooks/useNavToActivePathMapper.ts create mode 100644 src/app/hooks/useRoom.ts create mode 100644 src/app/hooks/useRoomMeta.ts delete mode 100644 src/app/hooks/useRoomMsgContentRenderer.ts create mode 100644 src/app/hooks/useRoomNavigate.ts create mode 100644 src/app/hooks/useRoomTypingMembers.ts create mode 100644 src/app/hooks/useSidebarItems.ts create mode 100644 src/app/hooks/useSpace.ts create mode 100644 src/app/hooks/useSpaceHierarchy.ts create mode 100644 src/app/hooks/useSyncState.ts delete mode 100644 src/app/organisms/navigation/Sidebar1.tsx delete mode 100644 src/app/organisms/room/Room.tsx delete mode 100644 src/app/organisms/room/RoomView.jsx delete mode 100644 src/app/organisms/room/RoomViewTyping.tsx delete mode 100644 src/app/organisms/room/message/AudioContent.tsx delete mode 100644 src/app/organisms/room/message/StickerContent.tsx delete mode 100644 src/app/organisms/room/message/fileRenderer.tsx delete mode 100644 src/app/organisms/room/message/index.ts delete mode 100644 src/app/organisms/room/message/styles.css.ts create mode 100644 src/app/pages/MobileFriendly.tsx create mode 100644 src/app/pages/Router.tsx create mode 100644 src/app/pages/afterLoginRedirectPath.ts create mode 100644 src/app/pages/client/ClientBindAtoms.ts create mode 100644 src/app/pages/client/ClientInitStorageAtom.tsx create mode 100644 src/app/pages/client/ClientLayout.tsx create mode 100644 src/app/pages/client/ClientRoot.tsx create mode 100644 src/app/pages/client/SidebarNav.tsx create mode 100644 src/app/pages/client/SpecVersions.tsx create mode 100644 src/app/pages/client/WelcomePage.tsx create mode 100644 src/app/pages/client/direct/Direct.tsx create mode 100644 src/app/pages/client/direct/RoomProvider.tsx create mode 100644 src/app/pages/client/direct/index.ts create mode 100644 src/app/pages/client/direct/useDirectRooms.ts create mode 100644 src/app/pages/client/explore/Explore.tsx create mode 100644 src/app/pages/client/explore/Featured.tsx create mode 100644 src/app/pages/client/explore/Server.tsx create mode 100644 src/app/pages/client/explore/index.ts create mode 100644 src/app/pages/client/explore/style.css.ts create mode 100644 src/app/pages/client/home/Home.tsx create mode 100644 src/app/pages/client/home/RoomProvider.tsx create mode 100644 src/app/pages/client/home/Search.tsx create mode 100644 src/app/pages/client/home/index.ts create mode 100644 src/app/pages/client/home/useHomeRooms.ts create mode 100644 src/app/pages/client/inbox/Inbox.tsx create mode 100644 src/app/pages/client/inbox/Invites.tsx create mode 100644 src/app/pages/client/inbox/Notifications.tsx create mode 100644 src/app/pages/client/inbox/index.ts create mode 100644 src/app/pages/client/index.ts create mode 100644 src/app/pages/client/sidebar/DirectTab.tsx create mode 100644 src/app/pages/client/sidebar/ExploreTab.tsx create mode 100644 src/app/pages/client/sidebar/HomeTab.tsx create mode 100644 src/app/pages/client/sidebar/InboxTab.tsx create mode 100644 src/app/pages/client/sidebar/SpaceTabs.tsx create mode 100644 src/app/pages/client/sidebar/UserTab.tsx create mode 100644 src/app/pages/client/sidebar/index.ts create mode 100644 src/app/pages/client/space/RoomProvider.tsx create mode 100644 src/app/pages/client/space/Search.tsx create mode 100644 src/app/pages/client/space/Space.tsx create mode 100644 src/app/pages/client/space/SpaceProvider.tsx create mode 100644 src/app/pages/client/space/index.ts create mode 100644 src/app/plugins/millify.ts create mode 100644 src/app/state/closedLobbyCategories.ts create mode 100644 src/app/state/closedNavCategories.ts create mode 100644 src/app/state/hooks/closedLobbyCategories.ts create mode 100644 src/app/state/hooks/closedNavCategories.ts create mode 100644 src/app/state/hooks/navToActivePath.ts create mode 100644 src/app/state/hooks/openedSidebarFolder.ts create mode 100644 src/app/state/hooks/unread.ts create mode 100644 src/app/state/navToActivePath.ts create mode 100644 src/app/state/openedSidebarFolder.ts rename src/app/state/{ => room-list}/inviteList.ts (94%) rename src/app/state/{ => room-list}/mutedRoomList.ts (96%) rename src/app/state/{ => room-list}/roomList.ts (93%) rename src/app/state/{ => room-list}/utils.ts (91%) rename src/app/state/{ => room}/roomInputDrafts.ts (88%) rename src/app/state/{ => room}/roomToParents.ts (93%) rename src/app/state/{ => room}/roomToUnread.ts (74%) delete mode 100644 src/app/state/selectedRoom.ts delete mode 100644 src/app/state/selectedTab.ts create mode 100644 src/app/state/spaceRooms.ts delete mode 100644 src/app/state/tabToRoom.ts create mode 100644 src/app/styles/ContainerColor.css.ts create mode 100644 src/app/utils/ASCIILexicalTable.ts create mode 100644 src/app/utils/sort.ts diff --git a/.eslintrc.js b/.eslintrc.cjs similarity index 100% rename from .eslintrc.js rename to .eslintrc.cjs diff --git a/config.json b/config.json index 484c7cd78..762c3a3bc 100644 --- a/config.json +++ b/config.json @@ -10,6 +10,26 @@ ], "allowCustomHomeservers": true, + "featuredCommunities": { + "openAsDefault": false, + "spaces": [ + "#cinny-space:matrix.org", + "#community:matrix.org", + "#space:envs.net", + "#science-space:matrix.org", + "#libregaming-games:tchncs.de", + "#mathematics-on:matrix.org" + ], + "rooms": [ + "#cinny:matrix.org", + "#foundation-office:matrix.org", + "#thisweekinmatrix:matrix.org", + "#matrix-dev:matrix.org", + "#matrix:matrix.org" + ], + "servers": ["envs.net", "matrix.org", "monero.social", "mozilla.org"] + }, + "hashRouter": { "enabled": false, "basename": "/" diff --git a/netlify.toml b/netlify.toml index e7d948e62..d79aa91c3 100644 --- a/netlify.toml +++ b/netlify.toml @@ -9,9 +9,10 @@ status = 200 [[redirects]] - from = "/olm.wasm" + from = "*/olm.wasm" to = "/olm.wasm" status = 200 + force = true [[redirects]] from = "/pdf.worker.min.js" @@ -31,4 +32,5 @@ [[redirects]] from = "/*" to = "/index.html" - status = 200 \ No newline at end of file + status = 200 + force = true \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 2eec29124..17e4dd509 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,10 +9,15 @@ "version": "3.2.0", "license": "AGPL-3.0-only", "dependencies": { + "@atlaskit/pragmatic-drag-and-drop": "1.1.6", + "@atlaskit/pragmatic-drag-and-drop-auto-scroll": "1.3.0", + "@atlaskit/pragmatic-drag-and-drop-hitbox": "1.0.3", "@fontsource/inter": "4.5.14", "@khanacademy/simple-markdown": "0.8.6", "@matrix-org/olm": "3.2.14", - "@tanstack/react-virtual": "3.0.0-beta.54", + "@tanstack/react-query": "5.24.1", + "@tanstack/react-query-devtools": "5.24.1", + "@tanstack/react-virtual": "3.2.0", "@tippyjs/react": "4.2.6", "@vanilla-extract/css": "1.9.3", "@vanilla-extract/recipes": "0.3.0", @@ -29,7 +34,7 @@ "file-saver": "2.0.5", "flux": "4.0.3", "focus-trap-react": "10.0.2", - "folds": "1.5.1", + "folds": "2.0.0", "formik": "2.2.9", "html-dom-parser": "4.0.0", "html-react-parser": "4.2.0", @@ -111,6 +116,34 @@ "node": ">=6.0.0" } }, + "node_modules/@atlaskit/pragmatic-drag-and-drop": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@atlaskit/pragmatic-drag-and-drop/-/pragmatic-drag-and-drop-1.1.6.tgz", + "integrity": "sha512-+jGspaRMyHWB6g9w+N1KImS5I+xt0ML89pwUyCueEhf2KGsl6zyH9ZxjTVKfrbY89FyZvuuXT9oFRHTUKGBi/w==", + "dependencies": { + "@babel/runtime": "^7.0.0", + "bind-event-listener": "^3.0.0", + "raf-schd": "^4.0.3" + } + }, + "node_modules/@atlaskit/pragmatic-drag-and-drop-auto-scroll": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@atlaskit/pragmatic-drag-and-drop-auto-scroll/-/pragmatic-drag-and-drop-auto-scroll-1.3.0.tgz", + "integrity": "sha512-8wjKAI5qSrLojt8ZJ2WhoS5P75oBu5g0yMpAnTDgfqFyQnkt5Uc1txCRWpG26SS1mv19nm8ak9XHF2DOugVfpw==", + "dependencies": { + "@atlaskit/pragmatic-drag-and-drop": "^1.1.0", + "@babel/runtime": "^7.0.0" + } + }, + "node_modules/@atlaskit/pragmatic-drag-and-drop-hitbox": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@atlaskit/pragmatic-drag-and-drop-hitbox/-/pragmatic-drag-and-drop-hitbox-1.0.3.tgz", + "integrity": "sha512-/Sbu/HqN2VGLYBhnsG7SbRNg98XKkbF6L7XDdBi+izRybfaK1FeMfodPpm/xnBHPJzwYMdkE0qtLyv6afhgMUA==", + "dependencies": { + "@atlaskit/pragmatic-drag-and-drop": "^1.1.0", + "@babel/runtime": "^7.0.0" + } + }, "node_modules/@babel/code-frame": { "version": "7.23.4", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.4.tgz", @@ -3093,25 +3126,75 @@ "@swc/counter": "^0.1.3" } }, - "node_modules/@tanstack/react-virtual": { - "version": "3.0.0-beta.54", - "resolved": "https://registry.npmjs.org/@tanstack/react-virtual/-/react-virtual-3.0.0-beta.54.tgz", - "integrity": "sha512-D1mDMf4UPbrtHRZZriCly5bXTBMhylslm4dhcHqTtDJ6brQcgGmk8YD9JdWBGWfGSWPKoh2x1H3e7eh+hgPXtQ==", + "node_modules/@tanstack/query-core": { + "version": "5.24.1", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.24.1.tgz", + "integrity": "sha512-DZ6Nx9p7BhjkG50ayJ+MKPgff+lMeol7QYXkvuU5jr2ryW/4ok5eanaS9W5eooA4xN0A/GPHdLGOZGzArgf5Cg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/query-devtools": { + "version": "5.24.0", + "resolved": "https://registry.npmjs.org/@tanstack/query-devtools/-/query-devtools-5.24.0.tgz", + "integrity": "sha512-pThim455t69zrZaQKa7IRkEIK8UBTS+gHVAdNfhO72Xh4rWpMc63ovRje5/n6iw63+d6QiJzVadsJVdPoodSeQ==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/react-query": { + "version": "5.24.1", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.24.1.tgz", + "integrity": "sha512-4+09JEdO4d6+Gc8Y/g2M/MuxDK5IY0QV8+2wL2304wPKJgJ54cBbULd3nciJ5uvh/as8rrxx6s0mtIwpRuGd1g==", "dependencies": { - "@tanstack/virtual-core": "3.0.0-beta.54" + "@tanstack/query-core": "5.24.1" }, "funding": { "type": "github", "url": "https://github.com/sponsors/tannerlinsley" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + "react": "^18.0.0" + } + }, + "node_modules/@tanstack/react-query-devtools": { + "version": "5.24.1", + "resolved": "https://registry.npmjs.org/@tanstack/react-query-devtools/-/react-query-devtools-5.24.1.tgz", + "integrity": "sha512-qa4SEugN+EF8JJXcpsM9Lu05HfUv5cvHvLuB0uw/81eJZyNHFdtHFBi5RLCgpBrOyVMDfH8UQ3VBMqXzFKV68A==", + "dependencies": { + "@tanstack/query-devtools": "5.24.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "@tanstack/react-query": "^5.24.1", + "react": "^18.0.0" + } + }, + "node_modules/@tanstack/react-virtual": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@tanstack/react-virtual/-/react-virtual-3.2.0.tgz", + "integrity": "sha512-OEdMByf2hEfDa6XDbGlZN8qO6bTjlNKqjM3im9JG+u3mCL8jALy0T/67oDI001raUUPh1Bdmfn4ZvPOV5knpcg==", + "dependencies": { + "@tanstack/virtual-core": "3.2.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, "node_modules/@tanstack/virtual-core": { - "version": "3.0.0-beta.54", - "resolved": "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.0.0-beta.54.tgz", - "integrity": "sha512-jtkwqdP2rY2iCCDVAFuaNBH3fiEi29aTn2RhtIoky8DTTiCdc48plpHHreLwmv1PICJ4AJUUESaq3xa8fZH8+g==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.2.0.tgz", + "integrity": "sha512-P5XgYoAw/vfW65byBbJQCw+cagdXDT/qH6wmABiLt4v4YBT2q2vqCOhihe+D1Nt325F/S/0Tkv6C5z0Lv+VBQQ==", "funding": { "type": "github", "url": "https://github.com/sponsors/tannerlinsley" @@ -4065,6 +4148,11 @@ "node": ">=8" } }, + "node_modules/bind-event-listener": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bind-event-listener/-/bind-event-listener-3.0.0.tgz", + "integrity": "sha512-PJvH288AWQhKs2v9zyfYdPzlPqf5bXbGMmhmUIY9x4dAUGIWgomO771oBQNwJnMQSnUIXhKu6sgzpBRXTlvb8Q==" + }, "node_modules/blurhash": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/blurhash/-/blurhash-2.0.4.tgz", @@ -5665,9 +5753,9 @@ } }, "node_modules/folds": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/folds/-/folds-1.5.1.tgz", - "integrity": "sha512-2QxyA+FRKjPKXDTMDoD7NmOUiReWrKYO0Msg44QqlzTkTrRVEzJgyPIfC/Ia4/u0ByQpk6dbq8UQxomKmneJ/g==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/folds/-/folds-2.0.0.tgz", + "integrity": "sha512-lKv31vij4GEpEzGKWk5c3ar78fMZ9Di5n1XFR14Z2wnnpqhiiM5JTIzr127Gk5dOfy4mJkjnv/ZfMZvM2k+OQg==", "peerDependencies": { "@vanilla-extract/css": "^1.9.2", "@vanilla-extract/recipes": "^0.3.0", @@ -7580,6 +7668,11 @@ } ] }, + "node_modules/raf-schd": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/raf-schd/-/raf-schd-4.0.3.tgz", + "integrity": "sha512-tQkJl2GRWh83ui2DiPTJz9wEiMN20syf+5oKfB03yYP7ioZcJwsIK8FjrtLwH1m7C7e+Tt2yYBlrOpdT+dyeIQ==" + }, "node_modules/react": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", diff --git a/package.json b/package.json index 44c28d348..e626e8373 100644 --- a/package.json +++ b/package.json @@ -20,10 +20,15 @@ "author": "Ajay Bura", "license": "AGPL-3.0-only", "dependencies": { + "@atlaskit/pragmatic-drag-and-drop": "1.1.6", + "@atlaskit/pragmatic-drag-and-drop-auto-scroll": "1.3.0", + "@atlaskit/pragmatic-drag-and-drop-hitbox": "1.0.3", "@fontsource/inter": "4.5.14", "@khanacademy/simple-markdown": "0.8.6", "@matrix-org/olm": "3.2.14", - "@tanstack/react-virtual": "3.0.0-beta.54", + "@tanstack/react-query": "5.24.1", + "@tanstack/react-query-devtools": "5.24.1", + "@tanstack/react-virtual": "3.2.0", "@tippyjs/react": "4.2.6", "@vanilla-extract/css": "1.9.3", "@vanilla-extract/recipes": "0.3.0", @@ -40,7 +45,7 @@ "file-saver": "2.0.5", "flux": "4.0.3", "focus-trap-react": "10.0.2", - "folds": "1.5.1", + "folds": "2.0.0", "formik": "2.2.9", "html-dom-parser": "4.0.0", "html-react-parser": "4.2.0", diff --git a/src/app/components/CapabilitiesAndMediaConfigLoader.tsx b/src/app/components/CapabilitiesAndMediaConfigLoader.tsx new file mode 100644 index 000000000..338e52805 --- /dev/null +++ b/src/app/components/CapabilitiesAndMediaConfigLoader.tsx @@ -0,0 +1,36 @@ +import { ReactNode, useCallback, useEffect } from 'react'; +import { Capabilities } from 'matrix-js-sdk'; +import { AsyncStatus, useAsyncCallback } from '../hooks/useAsyncCallback'; +import { useMatrixClient } from '../hooks/useMatrixClient'; +import { MediaConfig } from '../hooks/useMediaConfig'; +import { promiseFulfilledResult } from '../utils/common'; + +type CapabilitiesAndMediaConfigLoaderProps = { + children: (capabilities?: Capabilities, mediaConfig?: MediaConfig) => ReactNode; +}; +export function CapabilitiesAndMediaConfigLoader({ + children, +}: CapabilitiesAndMediaConfigLoaderProps) { + const mx = useMatrixClient(); + + const [state, load] = useAsyncCallback< + [Capabilities | undefined, MediaConfig | undefined], + unknown, + [] + >( + useCallback(async () => { + const result = await Promise.allSettled([mx.getCapabilities(true), mx.getMediaConfig()]); + const capabilities = promiseFulfilledResult(result[0]); + const mediaConfig = promiseFulfilledResult(result[1]); + return [capabilities, mediaConfig]; + }, [mx]) + ); + + useEffect(() => { + load(); + }, [load]); + + const [capabilities, mediaConfig] = + state.status === AsyncStatus.Success ? state.data : [undefined, undefined]; + return children(capabilities, mediaConfig); +} diff --git a/src/app/components/CapabilitiesLoader.tsx b/src/app/components/CapabilitiesLoader.tsx new file mode 100644 index 000000000..dad59ec84 --- /dev/null +++ b/src/app/components/CapabilitiesLoader.tsx @@ -0,0 +1,19 @@ +import { ReactNode, useCallback, useEffect } from 'react'; +import { Capabilities } from 'matrix-js-sdk'; +import { AsyncStatus, useAsyncCallback } from '../hooks/useAsyncCallback'; +import { useMatrixClient } from '../hooks/useMatrixClient'; + +type CapabilitiesLoaderProps = { + children: (capabilities: Capabilities | undefined) => ReactNode; +}; +export function CapabilitiesLoader({ children }: CapabilitiesLoaderProps) { + const mx = useMatrixClient(); + + const [state, load] = useAsyncCallback(useCallback(() => mx.getCapabilities(true), [mx])); + + useEffect(() => { + load(); + }, [load]); + + return children(state.status === AsyncStatus.Success ? state.data : undefined); +} diff --git a/src/app/components/MediaConfigLoader.tsx b/src/app/components/MediaConfigLoader.tsx new file mode 100644 index 000000000..9fd99330a --- /dev/null +++ b/src/app/components/MediaConfigLoader.tsx @@ -0,0 +1,19 @@ +import { ReactNode, useCallback, useEffect } from 'react'; +import { AsyncStatus, useAsyncCallback } from '../hooks/useAsyncCallback'; +import { useMatrixClient } from '../hooks/useMatrixClient'; +import { MediaConfig } from '../hooks/useMediaConfig'; + +type MediaConfigLoaderProps = { + children: (mediaConfig: MediaConfig | undefined) => ReactNode; +}; +export function MediaConfigLoader({ children }: MediaConfigLoaderProps) { + const mx = useMatrixClient(); + + const [state, load] = useAsyncCallback(useCallback(() => mx.getMediaConfig(), [mx])); + + useEffect(() => { + load(); + }, [load]); + + return children(state.status === AsyncStatus.Success ? state.data : undefined); +} diff --git a/src/app/components/Pdf-viewer/PdfViewer.tsx b/src/app/components/Pdf-viewer/PdfViewer.tsx index c440cce9b..a78c13f2a 100644 --- a/src/app/components/Pdf-viewer/PdfViewer.tsx +++ b/src/app/components/Pdf-viewer/PdfViewer.tsx @@ -1,6 +1,6 @@ /* eslint-disable no-param-reassign */ /* eslint-disable jsx-a11y/no-noninteractive-element-interactions */ -import React, { FormEventHandler, useEffect, useRef, useState } from 'react'; +import React, { FormEventHandler, MouseEventHandler, useEffect, useRef, useState } from 'react'; import classNames from 'classnames'; import { Box, @@ -13,6 +13,7 @@ import { Input, Menu, PopOut, + RectCords, Scroll, Spinner, Text, @@ -48,7 +49,7 @@ export const PdfViewer = as<'div', PdfViewerProps>( const isError = pdfJSState.status === AsyncStatus.Error || docState.status === AsyncStatus.Error; const [pageNo, setPageNo] = useState(1); - const [openJump, setOpenJump] = useState(false); + const [jumpAnchor, setJumpAnchor] = useState(); useEffect(() => { loadPdfJS(); @@ -86,7 +87,7 @@ export const PdfViewer = as<'div', PdfViewerProps>( if (!jumpInput) return; const jumpTo = parseInt(jumpInput.value, 10); setPageNo(Math.max(1, Math.min(docState.data.numPages, jumpTo))); - setOpenJump(false); + setJumpAnchor(undefined); }; const handlePrevPage = () => { @@ -98,6 +99,10 @@ export const PdfViewer = as<'div', PdfViewerProps>( setPageNo((n) => Math.min(n + 1, docState.data.numPages)); }; + const handleOpenJump: MouseEventHandler = (evt) => { + setJumpAnchor(evt.currentTarget.getBoundingClientRect()); + }; + return (
          @@ -187,14 +192,14 @@ export const PdfViewer = as<'div', PdfViewerProps>( setOpenJump(false), + onDeactivate: () => setJumpAnchor(undefined), clickOutsideDeactivates: true, }} > @@ -227,17 +232,14 @@ export const PdfViewer = as<'div', PdfViewerProps>( } > - {(anchorRef) => ( - setOpenJump(!openJump)} - ref={anchorRef} - variant="SurfaceVariant" - radii="300" - aria-pressed={openJump} - > - {`${pageNo}/${docState.data.numPages}`} - - )} + + {`${pageNo}/${docState.data.numPages}`} + () => T; + mediaAutoLoad?: boolean; + urlPreview?: boolean; + highlightRegex?: RegExp; + htmlReactParserOptions: HTMLReactParserOptions; + outlineAttachment?: boolean; +}; +export function RenderMessageContent({ + displayName, + msgType, + ts, + edited, + getContent, + mediaAutoLoad, + urlPreview, + highlightRegex, + htmlReactParserOptions, + outlineAttachment, +}: RenderMessageContentProps) { + const renderFile = () => ( + ( + ( + } + /> + )} + renderAsTextFile={() => ( + } + /> + )} + > + + + )} + outlined={outlineAttachment} + /> + ); + + if (msgType === MsgType.Text) { + return ( + ( + + )} + renderUrlsPreview={ + urlPreview + ? (urls) => ( + + {urls.map((url) => ( + + ))} + + ) + : undefined + } + /> + ); + } + + if (msgType === MsgType.Emote) { + return ( + ( + + )} + renderUrlsPreview={ + urlPreview + ? (urls) => ( + + {urls.map((url) => ( + + ))} + + ) + : undefined + } + /> + ); + } + + if (msgType === MsgType.Notice) { + return ( + ( + + )} + renderUrlsPreview={ + urlPreview + ? (urls) => ( + + {urls.map((url) => ( + + ))} + + ) + : undefined + } + /> + ); + } + + if (msgType === MsgType.Image) { + return ( + ( + } + renderViewer={(p) => } + /> + )} + outlined={outlineAttachment} + /> + ); + } + + if (msgType === MsgType.Video) { + return ( + ( + ( + ( + {body} + )} + /> + ) + : undefined + } + renderVideo={(p) =>
          + + } + > + } + > + Select Rooms + + + ); +} + +type SearchFiltersProps = { + defaultRoomsFilterName: string; + allowGlobal?: boolean; + roomList: string[]; + selectedRooms?: string[]; + onSelectedRoomsChange: (selectedRooms?: string[]) => void; + global?: boolean; + onGlobalChange: (global?: boolean) => void; + order?: string; + onOrderChange: (order?: string) => void; +}; +export function SearchFilters({ + defaultRoomsFilterName, + allowGlobal, + roomList, + selectedRooms, + onSelectedRoomsChange, + global, + order, + onGlobalChange, + onOrderChange, +}: SearchFiltersProps) { + const mx = useMatrixClient(); + + return ( + + Filter + + } + outlined + onClick={() => onGlobalChange()} + > + {defaultRoomsFilterName} + + {allowGlobal && ( + } + outlined + onClick={() => onGlobalChange(true)} + > + Global + + )} + + {selectedRooms?.map((roomId) => { + const room = mx.getRoom(roomId); + if (!room) return null; + + return ( + onSelectedRoomsChange(selectedRooms.filter((rId) => rId !== roomId))} + radii="Pill" + before={ + + } + after={} + > + {room.name} + + ); + })} + + + + + + ); +} diff --git a/src/app/features/message-search/SearchInput.tsx b/src/app/features/message-search/SearchInput.tsx new file mode 100644 index 000000000..db646c263 --- /dev/null +++ b/src/app/features/message-search/SearchInput.tsx @@ -0,0 +1,66 @@ +import React, { FormEventHandler, RefObject } from 'react'; +import { Box, Text, Input, Icon, Icons, Spinner, Chip, config } from 'folds'; + +type SearchProps = { + active?: boolean; + loading?: boolean; + searchInputRef: RefObject; + onSearch: (term: string) => void; + onReset: () => void; +}; +export function SearchInput({ active, loading, searchInputRef, onSearch, onReset }: SearchProps) { + const handleSearchSubmit: FormEventHandler = (evt) => { + evt.preventDefault(); + const { searchInput } = evt.target as HTMLFormElement & { + searchInput: HTMLInputElement; + }; + + const searchTerm = searchInput.value.trim() || undefined; + if (searchTerm) { + onSearch(searchTerm); + } + }; + + return ( + + + Search + + ) : ( + + ) + } + after={ + active ? ( + } + onClick={onReset} + > + Clear + + ) : ( + + Enter + + ) + } + /> + + ); +} diff --git a/src/app/features/message-search/SearchResultGroup.tsx b/src/app/features/message-search/SearchResultGroup.tsx new file mode 100644 index 000000000..6f84f6210 --- /dev/null +++ b/src/app/features/message-search/SearchResultGroup.tsx @@ -0,0 +1,262 @@ +/* eslint-disable react/destructuring-assignment */ +import React, { MouseEventHandler, useMemo } from 'react'; +import { IEventWithRoomId, JoinRule, RelationType, Room } from 'matrix-js-sdk'; +import { HTMLReactParserOptions } from 'html-react-parser'; +import { Avatar, Box, Chip, Header, Icon, Icons, Text, config } from 'folds'; +import { useMatrixClient } from '../../hooks/useMatrixClient'; +import { + getReactCustomHtmlParser, + makeHighlightRegex, +} from '../../plugins/react-custom-html-parser'; +import { getMxIdLocalPart, isRoomId, isUserId } from '../../utils/matrix'; +import { openJoinAlias, openProfileViewer } from '../../../client/action/navigation'; +import { useMatrixEventRenderer } from '../../hooks/useMatrixEventRenderer'; +import { GetContentCallback, MessageEvent, StateEvent } from '../../../types/matrix/room'; +import { + AvatarBase, + ImageContent, + MSticker, + ModernLayout, + RedactedContent, + Reply, + Time, + Username, +} from '../../components/message'; +import { RenderMessageContent } from '../../components/RenderMessageContent'; +import { Image } from '../../components/media'; +import { ImageViewer } from '../../components/image-viewer'; +import * as customHtmlCss from '../../styles/CustomHtml.css'; +import { RoomAvatar, RoomIcon } from '../../components/room-avatar'; +import { getMemberAvatarMxc, getMemberDisplayName, getRoomAvatarUrl } from '../../utils/room'; +import colorMXID from '../../../util/colorMXID'; +import { ResultItem } from './useMessageSearch'; +import { SequenceCard } from '../../components/sequence-card'; +import { useRoomNavigate } from '../../hooks/useRoomNavigate'; +import { UserAvatar } from '../../components/user-avatar'; + +type SearchResultGroupProps = { + room: Room; + highlights: string[]; + items: ResultItem[]; + mediaAutoLoad?: boolean; + urlPreview?: boolean; + onOpen: (roomId: string, eventId: string) => void; +}; +export function SearchResultGroup({ + room, + highlights, + items, + mediaAutoLoad, + urlPreview, + onOpen, +}: SearchResultGroupProps) { + const mx = useMatrixClient(); + const { navigateRoom, navigateSpace } = useRoomNavigate(); + const highlightRegex = useMemo(() => makeHighlightRegex(highlights), [highlights]); + + const htmlReactParserOptions = useMemo( + () => + getReactCustomHtmlParser(mx, room, { + highlightRegex, + handleSpoilerClick: (evt) => { + const target = evt.currentTarget; + if (target.getAttribute('aria-pressed') === 'true') { + evt.stopPropagation(); + target.setAttribute('aria-pressed', 'false'); + target.style.cursor = 'initial'; + } + }, + handleMentionClick: (evt) => { + const target = evt.currentTarget; + const mentionId = target.getAttribute('data-mention-id'); + if (typeof mentionId !== 'string') return; + if (isUserId(mentionId)) { + openProfileViewer(mentionId, room.roomId); + return; + } + if (isRoomId(mentionId) && mx.getRoom(mentionId)) { + if (mx.getRoom(mentionId)?.isSpaceRoom()) navigateSpace(mentionId); + else navigateRoom(mentionId); + return; + } + openJoinAlias(mentionId); + }, + }), + [mx, room, highlightRegex, navigateRoom, navigateSpace] + ); + + const renderMatrixEvent = useMatrixEventRenderer<[IEventWithRoomId, string, GetContentCallback]>( + { + [MessageEvent.RoomMessage]: (event, displayName, getContent) => { + if (event.unsigned?.redacted_because) { + return ; + } + + return ( + + ); + }, + [MessageEvent.Reaction]: (event, displayName, getContent) => { + if (event.unsigned?.redacted_because) { + return ; + } + return ( + ( + } + renderViewer={(p) => } + /> + )} + /> + ); + }, + [StateEvent.RoomTombstone]: (event) => { + const { content } = event; + return ( + + + Room Tombstone. {content.body} + + + ); + }, + }, + undefined, + (event) => { + if (event.unsigned?.redacted_because) { + return ; + } + return ( + + + {event.type} + {' event'} + + + ); + } + ); + + const handleOpenClick: MouseEventHandler = (evt) => { + const eventId = evt.currentTarget.getAttribute('data-event-id'); + if (!eventId) return; + onOpen(room.roomId, eventId); + }; + + return ( + +
          + + + ( + + )} + /> + + + {room.name} + + +
          + + {items.map((item) => { + const { event } = item; + + const displayName = + getMemberDisplayName(room, event.sender) ?? + getMxIdLocalPart(event.sender) ?? + event.sender; + const senderAvatarMxc = getMemberAvatarMxc(room, event.sender); + + const mainEventId = + event.content['m.relates_to']?.rel_type === RelationType.Replace + ? event.content['m.relates_to'].event_id + : event.event_id; + + const getContent = (() => + event.content['m.new_content'] ?? event.content) as GetContentCallback; + + const replyEventId = event.content['m.relates_to']?.['m.in_reply_to']?.event_id; + + return ( + + + + } + /> + + + } + > + + + + + {displayName} + + + + + + Open + + + + {replyEventId && ( + + )} + {renderMatrixEvent(event.type, false, event, displayName, getContent)} + + + ); + })} + +
          + ); +} diff --git a/src/app/features/message-search/index.ts b/src/app/features/message-search/index.ts new file mode 100644 index 000000000..5160d12fd --- /dev/null +++ b/src/app/features/message-search/index.ts @@ -0,0 +1 @@ +export * from './MessageSearch'; diff --git a/src/app/features/message-search/useMessageSearch.ts b/src/app/features/message-search/useMessageSearch.ts new file mode 100644 index 000000000..ded6d4b74 --- /dev/null +++ b/src/app/features/message-search/useMessageSearch.ts @@ -0,0 +1,115 @@ +import { + IEventWithRoomId, + IResultContext, + ISearchRequestBody, + ISearchResponse, + ISearchResult, + SearchOrderBy, +} from 'matrix-js-sdk'; +import { useCallback } from 'react'; +import { useMatrixClient } from '../../hooks/useMatrixClient'; + +export type ResultItem = { + rank: number; + event: IEventWithRoomId; + context: IResultContext; +}; + +export type ResultGroup = { + roomId: string; + items: ResultItem[]; +}; + +export type SearchResult = { + nextToken?: string; + highlights: string[]; + groups: ResultGroup[]; +}; + +const groupSearchResult = (results: ISearchResult[]): ResultGroup[] => { + const groups: ResultGroup[] = []; + + results.forEach((item) => { + const roomId = item.result.room_id; + const resultItem: ResultItem = { + rank: item.rank, + event: item.result, + context: item.context, + }; + + const lastAddedGroup: ResultGroup | undefined = groups[groups.length - 1]; + if (lastAddedGroup && roomId === lastAddedGroup.roomId) { + lastAddedGroup.items.push(resultItem); + return; + } + groups.push({ + roomId, + items: [resultItem], + }); + }); + + return groups; +}; + +const parseSearchResult = (result: ISearchResponse): SearchResult => { + const roomEvents = result.search_categories.room_events; + + const searchResult: SearchResult = { + nextToken: roomEvents?.next_batch, + highlights: roomEvents?.highlights ?? [], + groups: groupSearchResult(roomEvents?.results ?? []), + }; + + return searchResult; +}; + +export type MessageSearchParams = { + term?: string; + order?: string; + rooms?: string[]; + senders?: string[]; +}; +export const useMessageSearch = (params: MessageSearchParams) => { + const mx = useMatrixClient(); + const { term, order, rooms, senders } = params; + + const searchMessages = useCallback( + async (nextBatch?: string) => { + if (!term) + return { + highlights: [], + groups: [], + }; + const limit = 20; + + const requestBody: ISearchRequestBody = { + search_categories: { + room_events: { + event_context: { + before_limit: 0, + after_limit: 0, + include_profile: false, + }, + filter: { + limit, + rooms, + senders, + }, + include_state: false, + order_by: order as SearchOrderBy.Recent, + search_term: term, + }, + }, + }; + + const r = await mx.search({ + body: requestBody, + next_batch: nextBatch === '' ? undefined : nextBatch, + }); + return parseSearchResult(r); + }, + [mx, term, order, rooms, senders] + ); + + return searchMessages; +}; diff --git a/src/app/features/room-nav/RoomNavCategoryButton.tsx b/src/app/features/room-nav/RoomNavCategoryButton.tsx new file mode 100644 index 000000000..7acbbe28d --- /dev/null +++ b/src/app/features/room-nav/RoomNavCategoryButton.tsx @@ -0,0 +1,27 @@ +import React from 'react'; +import { as, Chip, Icon, Icons, Text } from 'folds'; +import classNames from 'classnames'; +import * as css from './styles.css'; + +export const RoomNavCategoryButton = as<'button', { closed?: boolean }>( + ({ className, closed, children, ...props }, ref) => ( + + } + {...props} + ref={ref} + > + + {children} + + + ) +); diff --git a/src/app/features/room-nav/RoomNavItem.tsx b/src/app/features/room-nav/RoomNavItem.tsx new file mode 100644 index 000000000..fce623750 --- /dev/null +++ b/src/app/features/room-nav/RoomNavItem.tsx @@ -0,0 +1,297 @@ +import React, { MouseEventHandler, forwardRef, useState } from 'react'; +import { Room } from 'matrix-js-sdk'; +import { + Avatar, + Box, + Icon, + IconButton, + Icons, + Text, + Menu, + MenuItem, + config, + PopOut, + toRem, + Line, + RectCords, + Badge, +} from 'folds'; +import { useFocusWithin, useHover } from 'react-aria'; +import FocusTrap from 'focus-trap-react'; +import { NavItem, NavItemContent, NavItemOptions, NavLink } from '../../components/nav'; +import { UnreadBadge, UnreadBadgeCenter } from '../../components/unread-badge'; +import { RoomAvatar, RoomIcon } from '../../components/room-avatar'; +import { getDirectRoomAvatarUrl, getRoomAvatarUrl } from '../../utils/room'; +import { nameInitials } from '../../utils/common'; +import { useMatrixClient } from '../../hooks/useMatrixClient'; +import { useRoomUnread } from '../../state/hooks/unread'; +import { roomToUnreadAtom } from '../../state/room/roomToUnread'; +import { usePowerLevels, usePowerLevelsAPI } from '../../hooks/usePowerLevels'; +import { copyToClipboard } from '../../utils/dom'; +import { getOriginBaseUrl, withOriginBaseUrl } from '../../pages/pathUtils'; +import { markAsRead } from '../../../client/action/notifications'; +import { openInviteUser, toggleRoomSettings } from '../../../client/action/navigation'; +import { UseStateProvider } from '../../components/UseStateProvider'; +import { LeaveRoomPrompt } from '../../components/leave-room-prompt'; +import { useClientConfig } from '../../hooks/useClientConfig'; +import { useRoomTypingMember } from '../../hooks/useRoomTypingMembers'; +import { TypingIndicator } from '../../components/typing-indicator'; + +type RoomNavItemMenuProps = { + room: Room; + linkPath: string; + requestClose: () => void; +}; +const RoomNavItemMenu = forwardRef( + ({ room, linkPath, requestClose }, ref) => { + const mx = useMatrixClient(); + const { hashRouter } = useClientConfig(); + const unread = useRoomUnread(room.roomId, roomToUnreadAtom); + const powerLevels = usePowerLevels(room); + const { getPowerLevel, canDoAction } = usePowerLevelsAPI(powerLevels); + const canInvite = canDoAction('invite', getPowerLevel(mx.getUserId() ?? '')); + + const handleMarkAsRead = () => { + markAsRead(room.roomId); + requestClose(); + }; + + const handleInvite = () => { + openInviteUser(room.roomId); + requestClose(); + }; + + const handleCopyLink = () => { + copyToClipboard(withOriginBaseUrl(getOriginBaseUrl(hashRouter), linkPath)); + requestClose(); + }; + + const handleRoomSettings = () => { + toggleRoomSettings(room.roomId); + requestClose(); + }; + + return ( + + + } + radii="300" + disabled={!unread} + > + + Mark as Read + + + + + + } + radii="300" + disabled={!canInvite} + > + + Invite + + + } + radii="300" + > + + Copy Link + + + } + radii="300" + > + + Room Settings + + + + + + + {(promptLeave, setPromptLeave) => ( + <> + setPromptLeave(true)} + variant="Critical" + fill="None" + size="300" + after={} + radii="300" + aria-pressed={promptLeave} + > + + Leave Room + + + {promptLeave && ( + setPromptLeave(false)} + /> + )} + + )} + + + + ); + } +); + +type RoomNavItemProps = { + room: Room; + selected: boolean; + linkPath: string; + muted?: boolean; + showAvatar?: boolean; + direct?: boolean; +}; +export function RoomNavItem({ + room, + selected, + showAvatar, + direct, + muted, + linkPath, +}: RoomNavItemProps) { + const mx = useMatrixClient(); + const [hover, setHover] = useState(false); + const { hoverProps } = useHover({ onHoverChange: setHover }); + const { focusWithinProps } = useFocusWithin({ onFocusWithinChange: setHover }); + const [menuAnchor, setMenuAnchor] = useState(); + const unread = useRoomUnread(room.roomId, roomToUnreadAtom); + const typingMember = useRoomTypingMember(room.roomId); + + const handleContextMenu: MouseEventHandler = (evt) => { + evt.preventDefault(); + setMenuAnchor({ + x: evt.clientX, + y: evt.clientY, + width: 0, + height: 0, + }); + }; + + const handleOpenMenu: MouseEventHandler = (evt) => { + setMenuAnchor(evt.currentTarget.getBoundingClientRect()); + }; + + const optionsVisible = hover || !!menuAnchor; + + return ( + + + + + + {showAvatar ? ( + ( + + {nameInitials(room.name)} + + )} + /> + ) : ( + + )} + + + + {room.name} + + + {!optionsVisible && !unread && !selected && typingMember.length > 0 && ( + + + + )} + {!optionsVisible && unread && ( + + 0} count={unread.total} /> + + )} + {muted && !optionsVisible && } + + + + {optionsVisible && ( + + setMenuAnchor(undefined), + clickOutsideDeactivates: true, + isKeyForward: (evt: KeyboardEvent) => evt.key === 'ArrowDown', + isKeyBackward: (evt: KeyboardEvent) => evt.key === 'ArrowUp', + }} + > + setMenuAnchor(undefined)} + /> + + } + > + + + + + + )} + + ); +} diff --git a/src/app/features/room-nav/index.ts b/src/app/features/room-nav/index.ts new file mode 100644 index 000000000..d1ea3ec7b --- /dev/null +++ b/src/app/features/room-nav/index.ts @@ -0,0 +1,2 @@ +export * from './RoomNavItem'; +export * from './RoomNavCategoryButton'; diff --git a/src/app/features/room-nav/styles.css.ts b/src/app/features/room-nav/styles.css.ts new file mode 100644 index 000000000..b5701a6f6 --- /dev/null +++ b/src/app/features/room-nav/styles.css.ts @@ -0,0 +1,9 @@ +import { style } from '@vanilla-extract/css'; +import { config } from 'folds'; + +export const CategoryButton = style({ + flexGrow: 1, +}); +export const CategoryButtonIcon = style({ + opacity: config.opacity.P400, +}); diff --git a/src/app/organisms/room/CommandAutocomplete.tsx b/src/app/features/room/CommandAutocomplete.tsx similarity index 100% rename from src/app/organisms/room/CommandAutocomplete.tsx rename to src/app/features/room/CommandAutocomplete.tsx diff --git a/src/app/organisms/room/MembersDrawer.css.ts b/src/app/features/room/MembersDrawer.css.ts similarity index 100% rename from src/app/organisms/room/MembersDrawer.css.ts rename to src/app/features/room/MembersDrawer.css.ts diff --git a/src/app/organisms/room/MembersDrawer.tsx b/src/app/features/room/MembersDrawer.tsx similarity index 79% rename from src/app/organisms/room/MembersDrawer.tsx rename to src/app/features/room/MembersDrawer.tsx index b4ba6b799..8a96b84af 100644 --- a/src/app/organisms/room/MembersDrawer.tsx +++ b/src/app/features/room/MembersDrawer.tsx @@ -8,8 +8,6 @@ import React, { } from 'react'; import { Avatar, - AvatarFallback, - AvatarImage, Badge, Box, Chip, @@ -22,6 +20,7 @@ import { Menu, MenuItem, PopOut, + RectCords, Scroll, Spinner, Text, @@ -32,18 +31,12 @@ import { import { Room, RoomMember } from 'matrix-js-sdk'; import { useVirtualizer } from '@tanstack/react-virtual'; import FocusTrap from 'focus-trap-react'; -import millify from 'millify'; import classNames from 'classnames'; -import { useAtomValue } from 'jotai'; -import { openInviteUser, openProfileViewer } from '../../../client/action/navigation'; +import { openProfileViewer } from '../../../client/action/navigation'; import * as css from './MembersDrawer.css'; import { useRoomMembers } from '../../hooks/useRoomMembers'; import { useMatrixClient } from '../../hooks/useMatrixClient'; -import { - getIntersectionObserverEntry, - useIntersectionObserver, -} from '../../hooks/useIntersectionObserver'; import { Membership } from '../../../types/matrix/room'; import { UseStateProvider } from '../../components/UseStateProvider'; import { @@ -52,14 +45,16 @@ import { useAsyncSearch, } from '../../hooks/useAsyncSearch'; import { useDebounce } from '../../hooks/useDebounce'; -import colorMXID from '../../../util/colorMXID'; import { usePowerLevelTags, PowerLevelTag } from '../../hooks/usePowerLevelTags'; -import { roomIdToTypingMembersAtom, selectRoomTypingMembersAtom } from '../../state/typingMembers'; import { TypingIndicator } from '../../components/typing-indicator'; import { getMemberDisplayName, getMemberSearchStr } from '../../utils/room'; import { getMxIdLocalPart } from '../../utils/matrix'; -import { useSetting } from '../../state/hooks/settings'; +import { useSetSetting, useSetting } from '../../state/hooks/settings'; import { settingsAtom } from '../../state/settings'; +import { millify } from '../../plugins/millify'; +import { ScrollTopContainer } from '../../components/scroll-top-container'; +import { UserAvatar } from '../../components/user-avatar'; +import { useRoomTypingMember } from '../../hooks/useRoomTypingMembers'; export const MembershipFilters = { filterJoined: (m: RoomMember) => m.membership === Membership.Join, @@ -181,6 +176,7 @@ export function MembersDrawer({ room }: MembersDrawerProps) { const members = useRoomMembers(mx, room.roomId); const getPowerLevelTag = usePowerLevelTags(); const fetchingMembers = members.length < room.getJoinedMemberCount(); + const setPeopleDrawer = useSetSetting(settingsAtom, 'isPeopleDrawer'); const membershipFilterMenu = useMembershipFilterMenu(); const sortFilterMenu = useSortFilterMenu(); @@ -190,11 +186,7 @@ export function MembersDrawer({ room }: MembersDrawerProps) { const membershipFilter = membershipFilterMenu[membershipFilterIndex] ?? membershipFilterMenu[0]; const sortFilter = sortFilterMenu[sortFilterIndex] ?? sortFilterMenu[0]; - const [onTop, setOnTop] = useState(true); - - const typingMembers = useAtomValue( - useMemo(() => selectRoomTypingMembersAtom(room.roomId, roomIdToTypingMembersAtom), [room]) - ); + const typingMembers = useRoomTypingMember(room.roomId); const filteredMembers = useMemo( () => @@ -235,16 +227,6 @@ export function MembersDrawer({ room }: MembersDrawerProps) { overscan: 10, }); - useIntersectionObserver( - useCallback((intersectionEntries) => { - if (!scrollTopAnchorRef.current) return; - const entry = getIntersectionObserverEntry(scrollTopAnchorRef.current, intersectionEntries); - if (entry) setOnTop(entry.isIntersecting); - }, []), - useCallback(() => ({ root: scrollRef.current }), []), - useCallback(() => scrollTopAnchorRef.current, []) - ); - const handleSearchChange: ChangeEventHandler = useDebounce( useCallback( (evt) => { @@ -266,12 +248,12 @@ export function MembersDrawer({ room }: MembersDrawerProps) { }; return ( - +
          - - {`${millify(room.getJoinedMemberCount(), { precision: 1, locales: [] })} Members`} + + {`${millify(room.getJoinedMemberCount())} Members`} @@ -281,7 +263,7 @@ export function MembersDrawer({ room }: MembersDrawerProps) { offset={4} tooltip={ - Invite Member + Close } > @@ -289,9 +271,9 @@ export function MembersDrawer({ room }: MembersDrawerProps) { openInviteUser(room.roomId)} + onClick={() => setPeopleDrawer(false)} > - + )} @@ -299,14 +281,14 @@ export function MembersDrawer({ room }: MembersDrawerProps) {
          - + - - {(open, setOpen) => ( + + {(anchor: RectCords | undefined, setAnchor) => ( setOpen(false), + onDeactivate: () => setAnchor(undefined), clickOutsideDeactivates: true, isKeyForward: (evt: KeyboardEvent) => evt.key === 'ArrowDown', isKeyBackward: (evt: KeyboardEvent) => evt.key === 'ArrowUp', @@ -330,38 +312,41 @@ export function MembersDrawer({ room }: MembersDrawerProps) { : 'Surface' } aria-pressed={menuItem.name === membershipFilter.name} + size="300" radii="300" onClick={() => { setMembershipFilterIndex(index); - setOpen(false); + setAnchor(undefined); }} > - {menuItem.name} + {menuItem.name} ))}
    • } > - {(anchorRef) => ( - setOpen(!open)} - variant={membershipFilter.color} - size="400" - radii="300" - before={} - > - {membershipFilter.name} - - )} + + setAnchor( + evt.currentTarget.getBoundingClientRect() + )) as MouseEventHandler + } + variant={membershipFilter.color} + size="400" + radii="300" + before={} + > + {membershipFilter.name} + )} - - {(open, setOpen) => ( + + {(anchor: RectCords | undefined, setAnchor) => ( setOpen(false), + onDeactivate: () => setAnchor(undefined), clickOutsideDeactivates: true, isKeyForward: (evt: KeyboardEvent) => evt.key === 'ArrowDown', isKeyBackward: (evt: KeyboardEvent) => evt.key === 'ArrowUp', @@ -381,31 +366,34 @@ export function MembersDrawer({ room }: MembersDrawerProps) { key={menuItem.name} variant="Surface" aria-pressed={menuItem.name === sortFilter.name} + size="300" radii="300" onClick={() => { setSortFilterIndex(index); - setOpen(false); + setAnchor(undefined); }} > - {menuItem.name} + {menuItem.name} ))} } > - {(anchorRef) => ( - setOpen(!open)} - variant="Background" - size="400" - radii="300" - after={} - > - {sortFilter.name} - - )} + + setAnchor( + evt.currentTarget.getBoundingClientRect() + )) as MouseEventHandler + } + variant="Background" + size="400" + radii="300" + after={} + > + {sortFilter.name} + )} @@ -446,20 +434,18 @@ export function MembersDrawer({ room }: MembersDrawerProps) { - {!onTop && ( - - virtualizer.scrollToOffset(0)} - variant="Surface" - radii="Pill" - outlined - size="300" - aria-label="Scroll to Top" - > - - - - )} + + virtualizer.scrollToOffset(0)} + variant="Surface" + radii="Pill" + outlined + size="300" + aria-label="Scroll to Top" + > + + + {!fetchingMembers && !result && processMembers.length === 0 && ( @@ -520,22 +506,16 @@ export function MembersDrawer({ room }: MembersDrawerProps) { onClick={handleMemberClick} before={ - {avatarUrl ? ( - - ) : ( - - {name[0]} - - )} + } + /> } after={ - typingMembers.find((tm) => tm.userId === member.userId) && ( + typingMembers.find((receipt) => receipt.userId === member.userId) && ( diff --git a/src/app/features/room/Room.tsx b/src/app/features/room/Room.tsx new file mode 100644 index 000000000..764e9686f --- /dev/null +++ b/src/app/features/room/Room.tsx @@ -0,0 +1,33 @@ +import React from 'react'; +import { Box, Line } from 'folds'; +import { useParams } from 'react-router-dom'; +import { RoomView } from './RoomView'; +import { MembersDrawer } from './MembersDrawer'; +import { ScreenSize, useScreenSizeContext } from '../../hooks/useScreenSize'; +import { useSetting } from '../../state/hooks/settings'; +import { settingsAtom } from '../../state/settings'; +import { PowerLevelsContextProvider, usePowerLevels } from '../../hooks/usePowerLevels'; +import { useRoom } from '../../hooks/useRoom'; + +export function Room() { + const { eventId } = useParams(); + const room = useRoom(); + + const [isDrawer] = useSetting(settingsAtom, 'isPeopleDrawer'); + const screenSize = useScreenSizeContext(); + const powerLevels = usePowerLevels(room); + + return ( + + + + {screenSize === ScreenSize.Desktop && isDrawer && ( + <> + + + + )} + + + ); +} diff --git a/src/app/organisms/room/RoomInput.tsx b/src/app/features/room/RoomInput.tsx similarity index 85% rename from src/app/organisms/room/RoomInput.tsx rename to src/app/features/room/RoomInput.tsx index e6c4fb73c..6f9a2495b 100644 --- a/src/app/organisms/room/RoomInput.tsx +++ b/src/app/features/room/RoomInput.tsx @@ -57,7 +57,7 @@ import { import { EmojiBoard, EmojiBoardTab } from '../../components/emoji-board'; import { UseStateProvider } from '../../components/UseStateProvider'; import initMatrix from '../../../client/initMatrix'; -import { TUploadContent, encryptFile, getImageInfo } from '../../utils/matrix'; +import { TUploadContent, encryptFile, getImageInfo, getMxIdLocalPart } from '../../utils/matrix'; import { useTypingStatusUpdater } from '../../hooks/useTypingStatusUpdater'; import { useFilePicker } from '../../hooks/useFilePicker'; import { useFilePasteHandler } from '../../hooks/useFilePasteHandler'; @@ -68,7 +68,7 @@ import { roomIdToReplyDraftAtomFamily, roomIdToUploadItemsAtomFamily, roomUploadAtomFamily, -} from '../../state/roomInputDrafts'; +} from '../../state/room/roomInputDrafts'; import { UploadCardRenderer } from '../../components/upload-card'; import { UploadBoard, @@ -93,32 +93,34 @@ import { getImageMsgContent, getVideoMsgContent, } from './msgContent'; -import { MessageReply } from '../../molecules/message/Message'; import colorMXID from '../../../util/colorMXID'; import { + getMemberDisplayName, parseReplyBody, parseReplyFormattedBody, trimReplyFromBody, trimReplyFromFormattedBody, } from '../../utils/room'; import { sanitizeText } from '../../utils/sanitize'; -import { useScreenSize } from '../../hooks/useScreenSize'; import { CommandAutocomplete } from './CommandAutocomplete'; import { Command, SHRUG, useCommands } from '../../hooks/useCommands'; import { mobileOrTablet } from '../../utils/user-agent'; +import { useElementSizeObserver } from '../../hooks/useElementSizeObserver'; +import { ReplyLayout } from '../../components/message'; interface RoomInputProps { editor: Editor; - roomViewRef: RefObject; + fileDropContainerRef: RefObject; roomId: string; room: Room; } export const RoomInput = forwardRef( - ({ editor, roomViewRef, roomId, room }, ref) => { + ({ editor, fileDropContainerRef, roomId, room }, ref) => { const mx = useMatrixClient(); const [enterForNewline] = useSetting(settingsAtom, 'enterForNewline'); const [isMarkdown] = useSetting(settingsAtom, 'isMarkdown'); const commands = useCommands(mx, room); + const emojiBtnRef = useRef(null); const [msgDraft, setMsgDraft] = useAtom(roomIdToMsgDraftAtomFamily(roomId)); const [replyDraft, setReplyDraft] = useAtom(roomIdToReplyDraftAtomFamily(roomId)); @@ -170,10 +172,13 @@ export const RoomInput = forwardRef( ); const pickFile = useFilePicker(handleFiles, true); const handlePaste = useFilePasteHandler(handleFiles); - const dropZoneVisible = useFileDropZone(roomViewRef, handleFiles); + const dropZoneVisible = useFileDropZone(fileDropContainerRef, handleFiles); + const [hideStickerBtn, setHideStickerBtn] = useState(document.body.clientWidth < 500); - const [, screenWidth] = useScreenSize(); - const hideStickerBtn = screenWidth < 500; + useElementSizeObserver( + useCallback(() => document.body, []), + useCallback((width) => setHideStickerBtn(width < 500), []) + ); useEffect(() => { Transforms.insertFragment(editor, msgDraft); @@ -307,7 +312,7 @@ export const RoomInput = forwardRef( mx.sendMessage(roomId, content); resetEditor(editor); resetEditorHistory(editor); - setReplyDraft(); + setReplyDraft(undefined); sendTypingStatus(false); }, [mx, roomId, editor, replyDraft, sendTypingStatus, setReplyDraft, isMarkdown, commands]); @@ -319,7 +324,7 @@ export const RoomInput = forwardRef( } if (isKeyHotkey('escape', evt)) { evt.preventDefault(); - setReplyDraft(); + setReplyDraft(undefined); } }, [submit, setReplyDraft, enterForNewline] @@ -475,18 +480,29 @@ export const RoomInput = forwardRef( style={{ padding: `${config.space.S200} ${config.space.S300} 0` }} > setReplyDraft()} + onClick={() => setReplyDraft(undefined)} variant="SurfaceVariant" size="300" radii="300" > - + + + {getMemberDisplayName(room, replyDraft.userId) ?? + getMxIdLocalPart(replyDraft.userId) ?? + replyDraft.userId} + + + } + > + + {trimReplyFromBody(replyDraft.body)} + +
      ) @@ -518,7 +534,11 @@ export const RoomInput = forwardRef( alignOffset={-44} position="Top" align="End" - open={!!emojiBoardTab} + anchor={ + emojiBoardTab === undefined + ? undefined + : emojiBtnRef.current?.getBoundingClientRect() ?? undefined + } content={ ( /> } > - {(anchorRef) => ( - <> - {!hideStickerBtn && ( - setEmojiBoardTab(EmojiBoardTab.Sticker)} - variant="SurfaceVariant" - size="300" - radii="300" - > - - - )} - setEmojiBoardTab(EmojiBoardTab.Emoji)} - variant="SurfaceVariant" - size="300" - radii="300" - > - - - + {!hideStickerBtn && ( + setEmojiBoardTab(EmojiBoardTab.Sticker)} + variant="SurfaceVariant" + size="300" + radii="300" + > + + )} + setEmojiBoardTab(EmojiBoardTab.Emoji)} + variant="SurfaceVariant" + size="300" + radii="300" + > + + )} diff --git a/src/app/organisms/room/RoomInputPlaceholder.css.ts b/src/app/features/room/RoomInputPlaceholder.css.ts similarity index 100% rename from src/app/organisms/room/RoomInputPlaceholder.css.ts rename to src/app/features/room/RoomInputPlaceholder.css.ts diff --git a/src/app/organisms/room/RoomInputPlaceholder.tsx b/src/app/features/room/RoomInputPlaceholder.tsx similarity index 100% rename from src/app/organisms/room/RoomInputPlaceholder.tsx rename to src/app/features/room/RoomInputPlaceholder.tsx diff --git a/src/app/organisms/room/RoomTimeline.css.ts b/src/app/features/room/RoomTimeline.css.ts similarity index 100% rename from src/app/organisms/room/RoomTimeline.css.ts rename to src/app/features/room/RoomTimeline.css.ts diff --git a/src/app/organisms/room/RoomTimeline.tsx b/src/app/features/room/RoomTimeline.tsx similarity index 62% rename from src/app/organisms/room/RoomTimeline.tsx rename to src/app/features/room/RoomTimeline.tsx index 0c74de520..29b874fca 100644 --- a/src/app/organisms/room/RoomTimeline.tsx +++ b/src/app/features/room/RoomTimeline.tsx @@ -1,3 +1,4 @@ +/* eslint-disable react/destructuring-assignment */ import React, { Dispatch, MouseEventHandler, @@ -22,7 +23,7 @@ import { RoomEvent, RoomEventHandlerMap, } from 'matrix-js-sdk'; -import parse, { HTMLReactParserOptions } from 'html-react-parser'; +import { HTMLReactParserOptions } from 'html-react-parser'; import classNames from 'classnames'; import { ReactEditor } from 'slate-react'; import { Editor } from 'slate'; @@ -52,7 +53,6 @@ import { isRoomId, isUserId, } from '../../utils/matrix'; -import { sanitizeCustomHtml } from '../../utils/sanitize'; import { useMatrixClient } from '../../hooks/useMatrixClient'; import { useVirtualPaginator, ItemRange } from '../../hooks/useVirtualPaginator'; import { useAlive } from '../../hooks/useAlive'; @@ -62,24 +62,15 @@ import { CompactPlaceholder, Reply, MessageBase, - MessageDeletedContent, - MessageBrokenContent, MessageUnsupportedContent, - MessageEditedContent, - MessageEmptyContent, - AttachmentBox, - Attachment, - AttachmentContent, - AttachmentHeader, Time, - MessageBadEncryptedContent, MessageNotDecryptedContent, - MessageTextBody, + RedactedContent, + MSticker, + ImageContent, + EventContent, } from '../../components/message'; -import { - emojifyAndLinkify, - getReactCustomHtmlParser, -} from '../../plugins/react-custom-html-parser'; +import { getReactCustomHtmlParser } from '../../plugins/react-custom-html-parser'; import { canEditEvent, decryptAllTimelineEvent, @@ -90,35 +81,12 @@ import { getReactionContent, isMembershipChanged, reactionOrEditEvent, - trimReplyFromBody, } from '../../utils/room'; import { useSetting } from '../../state/hooks/settings'; import { settingsAtom } from '../../state/settings'; -import { - openJoinAlias, - openProfileViewer, - selectRoom, - selectTab, -} from '../../../client/action/navigation'; -import { useForceUpdate } from '../../hooks/useForceUpdate'; -import { parseGeoUri, scaleYDimension } from '../../utils/common'; +import { openJoinAlias, openProfileViewer } from '../../../client/action/navigation'; import { useMatrixEventRenderer } from '../../hooks/useMatrixEventRenderer'; -import { useRoomMsgContentRenderer } from '../../hooks/useRoomMsgContentRenderer'; -import { IAudioContent, IImageContent, IVideoContent } from '../../../types/matrix/common'; -import { getBlobSafeMimeType } from '../../utils/mimeTypes'; -import { - ImageContent, - VideoContent, - FileHeader, - fileRenderer, - AudioContent, - Reactions, - EventContent, - Message, - Event, - EncryptedContent, - StickerContent, -} from './message'; +import { Reactions, Message, Event, EncryptedContent } from './message'; import { useMemberEventParser } from '../../hooks/useMemberEventParser'; import * as customHtmlCss from '../../styles/CustomHtml.css'; import { RoomIntro } from '../../components/room-intro'; @@ -132,22 +100,17 @@ import { getResizeObserverEntry, useResizeObserver } from '../../hooks/useResize import * as css from './RoomTimeline.css'; import { inSameDay, minuteDifference, timeDayMonthYear, today, yesterday } from '../../utils/time'; import { createMentionElement, isEmptyEditor, moveCursor } from '../../components/editor'; -import { roomIdToReplyDraftAtomFamily } from '../../state/roomInputDrafts'; -import { usePowerLevelsAPI } from '../../hooks/usePowerLevels'; -import { MessageEvent } from '../../../types/matrix/room'; +import { roomIdToReplyDraftAtomFamily } from '../../state/room/roomInputDrafts'; +import { usePowerLevelsAPI, usePowerLevelsContext } from '../../hooks/usePowerLevels'; +import { GetContentCallback, MessageEvent, StateEvent } from '../../../types/matrix/room'; import initMatrix from '../../../client/initMatrix'; import { useKeyDown } from '../../hooks/useKeyDown'; import cons from '../../../client/state/cons'; import { useDocumentFocusChange } from '../../hooks/useDocumentFocusChange'; -import { EMOJI_PATTERN, HTTP_URL_PATTERN, VARIATION_SELECTOR_PATTERN } from '../../utils/regex'; -import { UrlPreviewCard, UrlPreviewHolder } from './message/UrlPreviewCard'; - -// Thumbs up emoji found to have Variation Selector 16 at the end -// so included variation selector pattern in regex -const JUMBO_EMOJI_REG = new RegExp( - `^(((${EMOJI_PATTERN})|(:.+?:))(${VARIATION_SELECTOR_PATTERN}|\\s)*){1,10}$` -); -const URL_REG = new RegExp(HTTP_URL_PATTERN, 'g'); +import { RenderMessageContent } from '../../components/RenderMessageContent'; +import { Image } from '../../components/media'; +import { ImageViewer } from '../../components/image-viewer'; +import { useRoomNavigate } from '../../hooks/useRoomNavigate'; const TimelineFloat = as<'div', css.TimelineFloatVariants>( ({ position, className, ...props }, ref) => ( @@ -474,11 +437,13 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli const showUrlPreview = encryptedRoom ? encUrlPreview : urlPreview; const [showHiddenEvents] = useSetting(settingsAtom, 'showHiddenEvents'); const setReplyDraft = useSetAtom(roomIdToReplyDraftAtomFamily(room.roomId)); - const { canDoAction, canSendEvent, getPowerLevel } = usePowerLevelsAPI(); + const powerLevels = usePowerLevelsContext(); + const { canDoAction, canSendEvent, getPowerLevel } = usePowerLevelsAPI(powerLevels); const myPowerLevel = getPowerLevel(mx.getUserId() ?? ''); const canRedact = canDoAction('redact', myPowerLevel); const canSendReaction = canSendEvent(MessageEvent.Reaction, myPowerLevel); const [editId, setEditId] = useState(); + const { navigateRoom, navigateSpace } = useRoomNavigate(); const imagePackRooms: Room[] = useMemo(() => { const allParentSpaces = [ @@ -509,13 +474,15 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli smooth: true, }); - const focusItem = useRef<{ - index: number; - scrollTo: boolean; - highlight: boolean; - }>(); + const [focusItem, setFocusItem] = useState< + | { + index: number; + scrollTo: boolean; + highlight: boolean; + } + | undefined + >(); const alive = useAlive(); - const [, forceUpdate] = useForceUpdate(); const htmlReactParserOptions = useMemo( () => @@ -537,14 +504,14 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli return; } if (isRoomId(mentionId) && mx.getRoom(mentionId)) { - if (mx.getRoom(mentionId)?.isSpaceRoom()) selectTab(mentionId); - else selectRoom(mentionId); + if (mx.getRoom(mentionId)?.isSpaceRoom()) navigateSpace(mentionId); + else navigateRoom(mentionId); return; } openJoinAlias(mentionId); }, }), - [mx, room] + [mx, room, navigateRoom, navigateSpace] ); const parseMemberEvent = useMemberEventParser(); @@ -594,11 +561,11 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli if (!alive()) return; const evLength = getTimelinesEventsCount(lTimelines); - focusItem.current = { + setFocusItem({ index: evtAbsIndex, scrollTo: true, highlight: evtId !== readUptoEventIdRef.current, - }; + }); setTimeline({ linkedTimelines: lTimelines, range: { @@ -797,18 +764,23 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli }, [room, unreadInfo, scrollToItem]); // scroll to focused message - const focusItm = focusItem.current; useLayoutEffect(() => { - if (focusItm && focusItm.scrollTo) { - scrollToItem(focusItm.index, { + if (focusItem && focusItem.scrollTo) { + scrollToItem(focusItem.index, { behavior: 'instant', align: 'center', stopInView: true, }); } - focusItem.current = undefined; - }, [focusItm, scrollToItem]); + setTimeout(() => { + if (!alive()) return; + setFocusItem((currentItem) => { + if (currentItem === focusItem) return undefined; + return currentItem; + }); + }, 2000); + }, [alive, focusItem, scrollToItem]); // scroll to bottom of timeline const scrollToBottomCount = scrollToBottomRef.current.count; @@ -879,18 +851,17 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli align: 'center', stopInView: true, }); - focusItem.current = { + setFocusItem({ index: absoluteIndex, scrollTo: false, highlight: true, - }; - forceUpdate(); + }); } else { setTimeline(getEmptyTimeline()); loadEventTimeline(replyId); } }, - [room, timeline, scrollToItem, loadEventTimeline, forceUpdate] + [room, timeline, scrollToItem, loadEventTimeline] ); const handleUserClick: MouseEventHandler = useCallback( @@ -989,590 +960,398 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli [editor] ); - const renderBody = (body: string, customBody?: string) => { - if (body === '') ; - if (customBody) { - if (customBody === '') ; - return parse(sanitizeCustomHtml(customBody), htmlReactParserOptions); - } - return emojifyAndLinkify(body, true); - }; + const renderMatrixEvent = useMatrixEventRenderer< + [string, MatrixEvent, number, EventTimelineSet, boolean] + >( + { + [MessageEvent.RoomMessage]: (mEventId, mEvent, item, timelineSet, collapse) => { + const reactionRelations = getEventReactions(timelineSet, mEventId); + const reactions = reactionRelations && reactionRelations.getSortedAnnotationsByKey(); + const hasReactions = reactions && reactions.length > 0; + const { replyEventId } = mEvent; + const highlighted = focusItem?.index === item && focusItem.highlight; - const renderRoomMsgContent = useRoomMsgContentRenderer<[EventTimelineSet]>({ - renderText: (mEventId, mEvent, timelineSet) => { - const editedEvent = getEditedEvent(mEventId, mEvent, timelineSet); - const { body, formatted_body: customBody }: Record = - editedEvent?.getContent()['m.new_content'] ?? mEvent.getContent(); + const editedEvent = getEditedEvent(mEventId, mEvent, timelineSet); + const getContent = (() => + editedEvent?.getContent()['m.new_content'] ?? mEvent.getContent()) as GetContentCallback; - if (typeof body !== 'string') return null; - const trimmedBody = trimReplyFromBody(body); - const urlsMatch = showUrlPreview && trimmedBody.match(URL_REG); - const urls = urlsMatch ? [...new Set(urlsMatch)] : undefined; - - return ( - <> - - {renderBody(trimmedBody, typeof customBody === 'string' ? customBody : undefined)} - {!!editedEvent && } - - {urls && urls.length > 0 && ( - - {urls.map((url) => ( - - ))} - - )} - - ); - }, - renderEmote: (mEventId, mEvent, timelineSet) => { - const editedEvent = getEditedEvent(mEventId, mEvent, timelineSet); - const { body, formatted_body: customBody } = - editedEvent?.getContent()['m.new_content'] ?? mEvent.getContent(); - const senderId = mEvent.getSender() ?? ''; - - const senderDisplayName = - getMemberDisplayName(room, senderId) ?? getMxIdLocalPart(senderId) ?? senderId; - - if (typeof body !== 'string') return null; - const trimmedBody = trimReplyFromBody(body); - const urlsMatch = showUrlPreview && trimmedBody.match(URL_REG); - const urls = urlsMatch ? [...new Set(urlsMatch)] : undefined; - - return ( - <> - - {`${senderDisplayName} `} - {renderBody(trimmedBody, typeof customBody === 'string' ? customBody : undefined)} - {!!editedEvent && } - - {urls && urls.length > 0 && ( - - {urls.map((url) => ( - - ))} - - )} - - ); - }, - renderNotice: (mEventId, mEvent, timelineSet) => { - const editedEvent = getEditedEvent(mEventId, mEvent, timelineSet); - const { body, formatted_body: customBody }: Record = - editedEvent?.getContent()['m.new_content'] ?? mEvent.getContent(); - - if (typeof body !== 'string') return null; - const trimmedBody = trimReplyFromBody(body); - const urlsMatch = showUrlPreview && trimmedBody.match(URL_REG); - const urls = urlsMatch ? [...new Set(urlsMatch)] : undefined; - - return ( - <> - - {renderBody(trimmedBody, typeof customBody === 'string' ? customBody : undefined)} - {!!editedEvent && } - - {urls && urls.length > 0 && ( - - {urls.map((url) => ( - - ))} - - )} - - ); - }, - renderImage: (mEventId, mEvent) => { - const content = mEvent.getContent(); - const imgInfo = content?.info; - const mxcUrl = content.file?.url ?? content.url; - if (typeof mxcUrl !== 'string') { - return null; - } - const height = scaleYDimension(imgInfo?.w || 400, 400, imgInfo?.h || 400); - - return ( - - - - - - ); - }, - renderVideo: (mEventId, mEvent) => { - const content = mEvent.getContent(); - - const videoInfo = content?.info; - const mxcUrl = content.file?.url ?? content.url; - const safeMimeType = getBlobSafeMimeType(videoInfo?.mimetype ?? ''); - - if (!videoInfo || !safeMimeType.startsWith('video') || typeof mxcUrl !== 'string') { - if (mxcUrl) { - return fileRenderer(mEventId, mEvent); - } - return null; - } - - const height = scaleYDimension(videoInfo.w || 400, 400, videoInfo.h || 400); - - return ( - - - - - - ); - }, - renderAudio: (mEventId, mEvent) => { - const content = mEvent.getContent(); - - const audioInfo = content?.info; - const mxcUrl = content.file?.url ?? content.url; - const safeMimeType = getBlobSafeMimeType(audioInfo?.mimetype ?? ''); - - if (!audioInfo || !safeMimeType.startsWith('audio') || typeof mxcUrl !== 'string') { - if (mxcUrl) { - return fileRenderer(mEventId, mEvent); - } - return null; - } - - return ( - - - - - - - - - - - ); - }, - renderLocation: (mEventId, mEvent) => { - const content = mEvent.getContent(); - const geoUri = content.geo_uri; - if (typeof geoUri !== 'string') return null; - const location = parseGeoUri(geoUri); - return ( - - {geoUri} - } - > - Open Location - - - ); - }, - renderFile: fileRenderer, - renderBadEncrypted: () => ( - - - - ), - renderUnsupported: (mEventId, mEvent) => { - if (mEvent.isRedacted()) { - const redactedEvt = mEvent.getRedactionEvent(); - const reason = - redactedEvt && 'content' in redactedEvt ? redactedEvt.content.reason : undefined; + const senderId = mEvent.getSender() ?? ''; + const senderDisplayName = + getMemberDisplayName(room, senderId) ?? getMxIdLocalPart(senderId) ?? senderId; return ( - - - + + ) + } + reactions={ + reactionRelations && ( + + ) + } + > + {mEvent.isRedacted() ? ( + + ) : ( + + )} + ); - } - return ( - - - - ); - }, - renderBrokenFallback: (mEventId, mEvent) => { - if (mEvent.isRedacted()) { - const redactedEvt = mEvent.getRedactionEvent(); - const reason = - redactedEvt && 'content' in redactedEvt ? redactedEvt.content.reason : undefined; + }, + [MessageEvent.RoomMessageEncrypted]: (mEventId, mEvent, item, timelineSet, collapse) => { + const reactionRelations = getEventReactions(timelineSet, mEventId); + const reactions = reactionRelations && reactionRelations.getSortedAnnotationsByKey(); + const hasReactions = reactions && reactions.length > 0; + const { replyEventId } = mEvent; + const highlighted = focusItem?.index === item && focusItem.highlight; + return ( - - - - ); - } - return ( - - - - ); - }, - }); + + ) + } + reactions={ + reactionRelations && ( + + ) + } + > + + {() => { + if (mEvent.isRedacted()) return ; + if (mEvent.getType() === MessageEvent.Sticker) + return ( + ( + } + renderViewer={(p) => } + /> + )} + /> + ); + if (mEvent.getType() === MessageEvent.RoomMessage) { + const editedEvent = getEditedEvent(mEventId, mEvent, timelineSet); + const getContent = (() => + editedEvent?.getContent()['m.new_content'] ?? + mEvent.getContent()) as GetContentCallback; - const renderMatrixEvent = useMatrixEventRenderer<[number, EventTimelineSet, boolean]>({ - renderRoomMessage: (mEventId, mEvent, item, timelineSet, collapse) => { - const reactionRelations = getEventReactions(timelineSet, mEventId); - const reactions = reactionRelations && reactionRelations.getSortedAnnotationsByKey(); - const hasReactions = reactions && reactions.length > 0; - const { replyEventId } = mEvent; - const highlighted = focusItem.current?.index === item && focusItem.current.highlight; - - return ( - - ) - } - reactions={ - reactionRelations && ( - - ) - } - > - {renderRoomMsgContent(mEventId, mEvent, timelineSet)} - - ); - }, - renderRoomEncrypted: (mEventId, mEvent, item, timelineSet, collapse) => { - const reactionRelations = getEventReactions(timelineSet, mEventId); - const reactions = reactionRelations && reactionRelations.getSortedAnnotationsByKey(); - const hasReactions = reactions && reactions.length > 0; - const { replyEventId } = mEvent; - const highlighted = focusItem.current?.index === item && focusItem.current.highlight; - - return ( - - ) - } - reactions={ - reactionRelations && ( - - ) - } - > - - {() => { - if (mEvent.isRedacted()) return ; - if (mEvent.getType() === MessageEvent.Sticker) - return ; - if (mEvent.getType() === MessageEvent.RoomMessage) - return renderRoomMsgContent(mEventId, mEvent, timelineSet); - if (mEvent.getType() === MessageEvent.RoomMessageEncrypted) + const senderId = mEvent.getSender() ?? ''; + const senderDisplayName = + getMemberDisplayName(room, senderId) ?? getMxIdLocalPart(senderId) ?? senderId; + return ( + + ); + } + if (mEvent.getType() === MessageEvent.RoomMessageEncrypted) + return ( + + + + ); return ( - + ); - return ( - - - - ); - }} - - - ); - }, - renderSticker: (mEventId, mEvent, item, timelineSet, collapse) => { - const reactionRelations = getEventReactions(timelineSet, mEventId); - const reactions = reactionRelations && reactionRelations.getSortedAnnotationsByKey(); - const hasReactions = reactions && reactions.length > 0; - const highlighted = focusItem.current?.index === item && focusItem.current.highlight; + }} + + + ); + }, + [MessageEvent.Sticker]: (mEventId, mEvent, item, timelineSet, collapse) => { + const reactionRelations = getEventReactions(timelineSet, mEventId); + const reactions = reactionRelations && reactionRelations.getSortedAnnotationsByKey(); + const hasReactions = reactions && reactions.length > 0; + const highlighted = focusItem?.index === item && focusItem.highlight; - return ( - + ) + } + > + {mEvent.isRedacted() ? ( + + ) : ( + ( + } + renderViewer={(p) => } + /> + )} /> - ) - } - > - - - ); + )} + + ); + }, + [StateEvent.RoomMember]: (mEventId, mEvent, item) => { + const membershipChanged = isMembershipChanged(mEvent); + if (membershipChanged && hideMembershipEvents) return null; + if (!membershipChanged && hideNickAvatarEvents) return null; + + const highlighted = focusItem?.index === item && focusItem.highlight; + const parsed = parseMemberEvent(mEvent); + + const timeJSX =
      + } + /> + + ); + }, + [StateEvent.RoomName]: (mEventId, mEvent, item) => { + const highlighted = focusItem?.index === item && focusItem.highlight; + const senderId = mEvent.getSender() ?? ''; + const senderName = getMemberDisplayName(room, senderId) || getMxIdLocalPart(senderId); + + const timeJSX =
      ); @@ -706,11 +758,36 @@ export const Message = as<'div', MessageProps>( const tag = (evt.target as any).tagName; if (typeof tag === 'string' && tag.toLowerCase() === 'a') return; evt.preventDefault(); - setMenu(true); + setMenuAnchor({ + x: evt.clientX, + y: evt.clientY, + width: 0, + height: 0, + }); + }; + + const handleOpenMenu: MouseEventHandler = (evt) => { + const target = evt.currentTarget.parentElement?.parentElement ?? evt.currentTarget; + setMenuAnchor(target.getBoundingClientRect()); }; const closeMenu = () => { - setMenu(false); + setMenuAnchor(undefined); + }; + + const handleOpenEmojiBoard: MouseEventHandler = (evt) => { + const target = evt.currentTarget.parentElement?.parentElement ?? evt.currentTarget; + setEmojiBoardAnchor(target.getBoundingClientRect()); + }; + const handleAddReactions: MouseEventHandler = () => { + const rect = menuAnchor; + closeMenu(); + // open it with timeout because closeMenu + // FocusTrap will return focus from emojiBoard + + setTimeout(() => { + setEmojiBoardAnchor(rect); + }, 100); }; return ( @@ -720,22 +797,22 @@ export const Message = as<'div', MessageProps>( space={messageSpacing} collapse={collapse} highlight={highlight} - selected={menu || emojiBoard} + selected={!!menuAnchor || !!emojiBoardAnchor} {...props} {...hoverProps} {...focusWithinProps} ref={ref} > - {!edit && (hover || menu || emojiBoard) && ( + {!edit && (hover || !!menuAnchor || !!emojiBoardAnchor) && (
      {canSendReaction && ( ( allowTextCustomEmoji onEmojiSelect={(key) => { onReactionToggle(mEvent.getId()!, key); - setEmojiBoard(false); + setEmojiBoardAnchor(undefined); }} onCustomEmojiSelect={(mxc, shortcode) => { onReactionToggle(mEvent.getId()!, mxc, shortcode); - setEmojiBoard(false); + setEmojiBoardAnchor(undefined); }} requestClose={() => { - setEmojiBoard(false); + setEmojiBoardAnchor(undefined); }} /> } > - {(anchorRef) => ( - setEmojiBoard(true)} - variant="SurfaceVariant" - size="300" - radii="300" - aria-pressed={emojiBoard} - > - - - )} + + + )} ( )} setMenu(false), + onDeactivate: () => setMenuAnchor(undefined), clickOutsideDeactivates: true, isKeyForward: (evt: KeyboardEvent) => evt.key === 'ArrowDown', isKeyBackward: (evt: KeyboardEvent) => evt.key === 'ArrowUp', }} > - + {canSendReaction && ( { @@ -818,12 +892,7 @@ export const Message = as<'div', MessageProps>( size="300" after={} radii="300" - onClick={() => { - closeMenu(); - // open it with timeout because closeMenu - // FocusTrap will return focus from emojiBoard - setTimeout(() => setEmojiBoard(true), 100); - }} + onClick={handleAddReactions} > ( onClose={closeMenu} /> + {((!mEvent.isRedacted() && canDelete) || mEvent.getSender() !== mx.getUserId()) && ( @@ -915,18 +985,15 @@ export const Message = as<'div', MessageProps>( } > - {(targetRef) => ( - setMenu((v) => !v)} - aria-pressed={menu} - > - - - )} + + + @@ -967,7 +1034,7 @@ export const Event = as<'div', EventProps>( const [hover, setHover] = useState(false); const { hoverProps } = useHover({ onHoverChange: setHover }); const { focusWithinProps } = useFocusWithin({ onFocusWithinChange: setHover }); - const [menu, setMenu] = useState(false); + const [menuAnchor, setMenuAnchor] = useState(); const stateEvent = typeof mEvent.getStateKey() === 'string'; const handleContextMenu: MouseEventHandler = (evt) => { @@ -975,11 +1042,21 @@ export const Event = as<'div', EventProps>( const tag = (evt.target as any).tagName; if (typeof tag === 'string' && tag.toLowerCase() === 'a') return; evt.preventDefault(); - setMenu(true); + setMenuAnchor({ + x: evt.clientX, + y: evt.clientY, + width: 0, + height: 0, + }); + }; + + const handleOpenMenu: MouseEventHandler = (evt) => { + const target = evt.currentTarget.parentElement?.parentElement ?? evt.currentTarget; + setMenuAnchor(target.getBoundingClientRect()); }; const closeMenu = () => { - setMenu(false); + setMenuAnchor(undefined); }; return ( @@ -989,26 +1066,26 @@ export const Event = as<'div', EventProps>( space={messageSpacing} autoCollapse highlight={highlight} - selected={menu} + selected={!!menuAnchor} {...props} {...hoverProps} {...focusWithinProps} ref={ref} > - {(hover || menu) && ( + {(hover || !!menuAnchor) && (
      setMenu(false), + onDeactivate: () => setMenuAnchor(undefined), clickOutsideDeactivates: true, isKeyForward: (evt: KeyboardEvent) => evt.key === 'ArrowDown', isKeyBackward: (evt: KeyboardEvent) => evt.key === 'ArrowUp', @@ -1022,6 +1099,7 @@ export const Event = as<'div', EventProps>( onClose={closeMenu} /> + {((!mEvent.isRedacted() && canDelete && !stateEvent) || (mEvent.getSender() !== mx.getUserId() && !stateEvent)) && ( @@ -1049,18 +1127,15 @@ export const Event = as<'div', EventProps>( } > - {(targetRef) => ( - setMenu((v) => !v)} - aria-pressed={menu} - > - - - )} + + + diff --git a/src/app/organisms/room/message/MessageEditor.tsx b/src/app/features/room/message/MessageEditor.tsx similarity index 89% rename from src/app/organisms/room/message/MessageEditor.tsx rename to src/app/features/room/message/MessageEditor.tsx index 006b46a88..0c9950308 100644 --- a/src/app/organisms/room/message/MessageEditor.tsx +++ b/src/app/features/room/message/MessageEditor.tsx @@ -1,5 +1,24 @@ -import React, { KeyboardEventHandler, useCallback, useEffect, useState } from 'react'; -import { Box, Chip, Icon, IconButton, Icons, Line, PopOut, Spinner, Text, as, config } from 'folds'; +import React, { + KeyboardEventHandler, + MouseEventHandler, + useCallback, + useEffect, + useState, +} from 'react'; +import { + Box, + Chip, + Icon, + IconButton, + Icons, + Line, + PopOut, + RectCords, + Spinner, + Text, + as, + config, +} from 'folds'; import { Editor, Transforms } from 'slate'; import { ReactEditor } from 'slate-react'; import { IContent, MatrixEvent, RelationType, Room } from 'matrix-js-sdk'; @@ -258,13 +277,13 @@ export const MessageEditor = as<'div', MessageEditorProps>( > - - {(emojiBoard: boolean, setEmojiBoard) => ( + + {(anchor: RectCords | undefined, setAnchor) => ( ( onEmojiSelect={handleEmoticonSelect} onCustomEmojiSelect={handleEmoticonSelect} requestClose={() => { - setEmojiBoard(false); + setAnchor(undefined); if (!mobileOrTablet()) ReactEditor.focus(editor); }} /> } > - {(anchorRef) => ( - setEmojiBoard(true)} - variant="SurfaceVariant" - size="300" - radii="300" - > - - - )} + + setAnchor( + evt.currentTarget.getBoundingClientRect() + )) as MouseEventHandler + } + variant="SurfaceVariant" + size="300" + radii="300" + > + + )} diff --git a/src/app/organisms/room/message/Reactions.tsx b/src/app/features/room/message/Reactions.tsx similarity index 100% rename from src/app/organisms/room/message/Reactions.tsx rename to src/app/features/room/message/Reactions.tsx diff --git a/src/app/features/room/message/index.ts b/src/app/features/room/message/index.ts new file mode 100644 index 000000000..d79e2aabc --- /dev/null +++ b/src/app/features/room/message/index.ts @@ -0,0 +1,3 @@ +export * from './Reactions'; +export * from './Message'; +export * from './EncryptedContent'; diff --git a/src/app/features/room/message/styles.css.ts b/src/app/features/room/message/styles.css.ts new file mode 100644 index 000000000..b87cb5054 --- /dev/null +++ b/src/app/features/room/message/styles.css.ts @@ -0,0 +1,50 @@ +import { style } from '@vanilla-extract/css'; +import { DefaultReset, config, toRem } from 'folds'; + +export const MessageBase = style({ + position: 'relative', +}); + +export const MessageOptionsBase = style([ + DefaultReset, + { + position: 'absolute', + top: toRem(-30), + right: 0, + zIndex: 1, + }, +]); +export const MessageOptionsBar = style([ + DefaultReset, + { + padding: config.space.S100, + }, +]); + +export const MessageAvatar = style({ + cursor: 'pointer', +}); + +export const MessageQuickReaction = style({ + minWidth: toRem(32), +}); + +export const MessageMenuGroup = style({ + padding: config.space.S100, +}); + +export const MessageMenuItemText = style({ + flexGrow: 1, +}); + +export const ReactionsContainer = style({ + selectors: { + '&:empty': { + display: 'none', + }, + }, +}); + +export const ReactionsTooltipText = style({ + wordBreak: 'break-word', +}); diff --git a/src/app/organisms/room/msgContent.ts b/src/app/features/room/msgContent.ts similarity index 98% rename from src/app/organisms/room/msgContent.ts rename to src/app/features/room/msgContent.ts index 0760ec9e9..103e8dcdf 100644 --- a/src/app/organisms/room/msgContent.ts +++ b/src/app/features/room/msgContent.ts @@ -10,7 +10,7 @@ import { loadVideoElement, } from '../../utils/dom'; import { encryptFile, getImageInfo, getThumbnailContent, getVideoInfo } from '../../utils/matrix'; -import { TUploadItem } from '../../state/roomInputDrafts'; +import { TUploadItem } from '../../state/room/roomInputDrafts'; import { encodeBlurHash } from '../../utils/blurHash'; import { scaleYDimension } from '../../utils/common'; diff --git a/src/app/organisms/room/reaction-viewer/ReactionViewer.css.ts b/src/app/features/room/reaction-viewer/ReactionViewer.css.ts similarity index 100% rename from src/app/organisms/room/reaction-viewer/ReactionViewer.css.ts rename to src/app/features/room/reaction-viewer/ReactionViewer.css.ts diff --git a/src/app/organisms/room/reaction-viewer/ReactionViewer.tsx b/src/app/features/room/reaction-viewer/ReactionViewer.tsx similarity index 89% rename from src/app/organisms/room/reaction-viewer/ReactionViewer.tsx rename to src/app/features/room/reaction-viewer/ReactionViewer.tsx index 7bcc0ccf8..1c1b79a78 100644 --- a/src/app/organisms/room/reaction-viewer/ReactionViewer.tsx +++ b/src/app/features/room/reaction-viewer/ReactionViewer.tsx @@ -2,8 +2,6 @@ import React, { useCallback, useState } from 'react'; import classNames from 'classnames'; import { Avatar, - AvatarFallback, - AvatarImage, Box, Header, Icon, @@ -22,11 +20,11 @@ import { getMemberDisplayName } from '../../../utils/room'; import { eventWithShortcode, getMxIdLocalPart } from '../../../utils/matrix'; import * as css from './ReactionViewer.css'; import { useMatrixClient } from '../../../hooks/useMatrixClient'; -import colorMXID from '../../../../util/colorMXID'; import { openProfileViewer } from '../../../../client/action/navigation'; import { useRelations } from '../../../hooks/useRelations'; import { Reaction } from '../../../components/message'; import { getHexcodeForEmoji, getShortcodeFor } from '../../../plugins/emoji'; +import { UserAvatar } from '../../../components/user-avatar'; export type ReactionViewerProps = { room: Room; @@ -129,18 +127,12 @@ export const ReactionViewer = as<'div', ReactionViewerProps>( }} before={ - {avatarUrl ? ( - - ) : ( - - {name[0]} - - )} + } + /> } > diff --git a/src/app/organisms/room/reaction-viewer/index.ts b/src/app/features/room/reaction-viewer/index.ts similarity index 100% rename from src/app/organisms/room/reaction-viewer/index.ts rename to src/app/features/room/reaction-viewer/index.ts diff --git a/src/app/hooks/router/useDirectSelected.ts b/src/app/hooks/router/useDirectSelected.ts new file mode 100644 index 000000000..adb2851ed --- /dev/null +++ b/src/app/hooks/router/useDirectSelected.ts @@ -0,0 +1,22 @@ +import { useMatch } from 'react-router-dom'; +import { getDirectCreatePath, getDirectPath } from '../../pages/pathUtils'; + +export const useDirectSelected = (): boolean => { + const directMatch = useMatch({ + path: getDirectPath(), + caseSensitive: true, + end: false, + }); + + return !!directMatch; +}; + +export const useDirectCreateSelected = (): boolean => { + const match = useMatch({ + path: getDirectCreatePath(), + caseSensitive: true, + end: false, + }); + + return !!match; +}; diff --git a/src/app/hooks/router/useExploreSelected.ts b/src/app/hooks/router/useExploreSelected.ts new file mode 100644 index 000000000..f0ffdc86a --- /dev/null +++ b/src/app/hooks/router/useExploreSelected.ts @@ -0,0 +1,28 @@ +import { useMatch, useParams } from 'react-router-dom'; +import { getExploreFeaturedPath, getExplorePath } from '../../pages/pathUtils'; + +export const useExploreSelected = (): boolean => { + const match = useMatch({ + path: getExplorePath(), + caseSensitive: true, + end: false, + }); + + return !!match; +}; + +export const useExploreFeaturedSelected = (): boolean => { + const match = useMatch({ + path: getExploreFeaturedPath(), + caseSensitive: true, + end: false, + }); + + return !!match; +}; + +export const useExploreServer = (): string | undefined => { + const { server } = useParams(); + + return server; +}; diff --git a/src/app/hooks/router/useHomeSelected.ts b/src/app/hooks/router/useHomeSelected.ts new file mode 100644 index 000000000..75802601e --- /dev/null +++ b/src/app/hooks/router/useHomeSelected.ts @@ -0,0 +1,47 @@ +import { useMatch } from 'react-router-dom'; +import { + getHomeCreatePath, + getHomeJoinPath, + getHomePath, + getHomeSearchPath, +} from '../../pages/pathUtils'; + +export const useHomeSelected = (): boolean => { + const homeMatch = useMatch({ + path: getHomePath(), + caseSensitive: true, + end: false, + }); + + return !!homeMatch; +}; + +export const useHomeCreateSelected = (): boolean => { + const match = useMatch({ + path: getHomeCreatePath(), + caseSensitive: true, + end: false, + }); + + return !!match; +}; + +export const useHomeJoinSelected = (): boolean => { + const match = useMatch({ + path: getHomeJoinPath(), + caseSensitive: true, + end: false, + }); + + return !!match; +}; + +export const useHomeSearchSelected = (): boolean => { + const match = useMatch({ + path: getHomeSearchPath(), + caseSensitive: true, + end: false, + }); + + return !!match; +}; diff --git a/src/app/hooks/router/useInbox.ts b/src/app/hooks/router/useInbox.ts new file mode 100644 index 000000000..de8d3d69f --- /dev/null +++ b/src/app/hooks/router/useInbox.ts @@ -0,0 +1,36 @@ +import { useMatch } from 'react-router-dom'; +import { + getInboxInvitesPath, + getInboxNotificationsPath, + getInboxPath, +} from '../../pages/pathUtils'; + +export const useInboxSelected = (): boolean => { + const match = useMatch({ + path: getInboxPath(), + caseSensitive: true, + end: false, + }); + + return !!match; +}; + +export const useInboxNotificationsSelected = (): boolean => { + const match = useMatch({ + path: getInboxNotificationsPath(), + caseSensitive: true, + end: false, + }); + + return !!match; +}; + +export const useInboxInvitesSelected = (): boolean => { + const match = useMatch({ + path: getInboxInvitesPath(), + caseSensitive: true, + end: false, + }); + + return !!match; +}; diff --git a/src/app/hooks/router/useSelectedRoom.ts b/src/app/hooks/router/useSelectedRoom.ts new file mode 100644 index 000000000..6d0ee4f19 --- /dev/null +++ b/src/app/hooks/router/useSelectedRoom.ts @@ -0,0 +1,15 @@ +import { useParams } from 'react-router-dom'; +import { getCanonicalAliasRoomId, isRoomAlias } from '../../utils/matrix'; +import { useMatrixClient } from '../useMatrixClient'; + +export const useSelectedRoom = (): string | undefined => { + const mx = useMatrixClient(); + + const { roomIdOrAlias } = useParams(); + const roomId = + roomIdOrAlias && isRoomAlias(roomIdOrAlias) + ? getCanonicalAliasRoomId(mx, roomIdOrAlias) + : roomIdOrAlias; + + return roomId; +}; diff --git a/src/app/hooks/router/useSelectedSpace.ts b/src/app/hooks/router/useSelectedSpace.ts new file mode 100644 index 000000000..2e8e73a0c --- /dev/null +++ b/src/app/hooks/router/useSelectedSpace.ts @@ -0,0 +1,37 @@ +import { useMatch, useParams } from 'react-router-dom'; +import { getCanonicalAliasRoomId, isRoomAlias } from '../../utils/matrix'; +import { useMatrixClient } from '../useMatrixClient'; +import { getSpaceLobbyPath, getSpaceSearchPath } from '../../pages/pathUtils'; + +export const useSelectedSpace = (): string | undefined => { + const mx = useMatrixClient(); + + const { spaceIdOrAlias } = useParams(); + + const spaceId = + spaceIdOrAlias && isRoomAlias(spaceIdOrAlias) + ? getCanonicalAliasRoomId(mx, spaceIdOrAlias) + : spaceIdOrAlias; + + return spaceId; +}; + +export const useSpaceLobbySelected = (spaceIdOrAlias: string): boolean => { + const match = useMatch({ + path: getSpaceLobbyPath(spaceIdOrAlias), + caseSensitive: true, + end: false, + }); + + return !!match; +}; + +export const useSpaceSearchSelected = (spaceIdOrAlias: string): boolean => { + const match = useMatch({ + path: getSpaceSearchPath(spaceIdOrAlias), + caseSensitive: true, + end: false, + }); + + return !!match; +}; diff --git a/src/app/hooks/useAccountDataCallback.ts b/src/app/hooks/useAccountDataCallback.ts new file mode 100644 index 000000000..e12f1c4d2 --- /dev/null +++ b/src/app/hooks/useAccountDataCallback.ts @@ -0,0 +1,14 @@ +import { ClientEvent, ClientEventHandlerMap, MatrixClient } from 'matrix-js-sdk'; +import { useEffect } from 'react'; + +export const useAccountDataCallback = ( + mx: MatrixClient, + onAccountData: ClientEventHandlerMap[ClientEvent.AccountData] +) => { + useEffect(() => { + mx.on(ClientEvent.AccountData, onAccountData); + return () => { + mx.removeListener(ClientEvent.AccountData, onAccountData); + }; + }, [mx, onAccountData]); +}; diff --git a/src/app/hooks/useAsyncCallback.ts b/src/app/hooks/useAsyncCallback.ts index fc7dca63f..431f0b32f 100644 --- a/src/app/hooks/useAsyncCallback.ts +++ b/src/app/hooks/useAsyncCallback.ts @@ -68,9 +68,11 @@ export const useAsyncCallback = ( throw new Error('AsyncCallbackHook: Request replaced!'); } if (alive()) { - setState({ - status: AsyncStatus.Success, - data, + queueMicrotask(() => { + setState({ + status: AsyncStatus.Success, + data, + }); }); } return data; @@ -78,10 +80,13 @@ export const useAsyncCallback = ( if (currentReqNumber !== reqNumberRef.current) { throw new Error('AsyncCallbackHook: Request replaced!'); } + if (alive()) { - setState({ - status: AsyncStatus.Error, - error: e as TError, + queueMicrotask(() => { + setState({ + status: AsyncStatus.Error, + error: e as TError, + }); }); } throw e; diff --git a/src/app/hooks/useCapabilities.ts b/src/app/hooks/useCapabilities.ts new file mode 100644 index 000000000..b2fbd640c --- /dev/null +++ b/src/app/hooks/useCapabilities.ts @@ -0,0 +1,12 @@ +import { Capabilities } from 'matrix-js-sdk'; +import { createContext, useContext } from 'react'; + +const CapabilitiesContext = createContext(null); + +export const CapabilitiesProvider = CapabilitiesContext.Provider; + +export function useCapabilities(): Capabilities { + const capabilities = useContext(CapabilitiesContext); + if (!capabilities) throw new Error('Capabilities are not provided!'); + return capabilities; +} diff --git a/src/app/hooks/useCategoryHandler.ts b/src/app/hooks/useCategoryHandler.ts new file mode 100644 index 000000000..086902d63 --- /dev/null +++ b/src/app/hooks/useCategoryHandler.ts @@ -0,0 +1,27 @@ +import { MouseEventHandler } from 'react'; + +type CategoryAction = + | { + type: 'PUT'; + categoryId: string; + } + | { + type: 'DELETE'; + categoryId: string; + }; +export const useCategoryHandler = ( + setAtom: (action: CategoryAction) => void, + closed: (categoryId: string) => boolean +) => { + const handleCategoryClick: MouseEventHandler = (evt) => { + const categoryId = evt.currentTarget.getAttribute('data-category-id'); + if (!categoryId) return; + if (closed(categoryId)) { + setAtom({ type: 'DELETE', categoryId }); + return; + } + setAtom({ type: 'PUT', categoryId }); + }; + + return handleCategoryClick; +}; diff --git a/src/app/hooks/useClientConfig.ts b/src/app/hooks/useClientConfig.ts index 8406668de..e5fc6cc61 100644 --- a/src/app/hooks/useClientConfig.ts +++ b/src/app/hooks/useClientConfig.ts @@ -1,14 +1,23 @@ import { createContext, useContext } from 'react'; +export type HashRouterConfig = { + enabled?: boolean; + basename?: string; +}; + export type ClientConfig = { defaultHomeserver?: number; homeserverList?: string[]; allowCustomHomeservers?: boolean; - hashRouter?: { - enabled?: boolean; - basename?: string; + featuredCommunities?: { + openAsDefault?: boolean; + spaces?: string[]; + rooms?: string[]; + servers?: string[]; }; + + hashRouter?: HashRouterConfig; }; const ClientConfigContext = createContext(null); diff --git a/src/app/hooks/useCommands.ts b/src/app/hooks/useCommands.ts index ad464c63d..aadbf5348 100644 --- a/src/app/hooks/useCommands.ts +++ b/src/app/hooks/useCommands.ts @@ -1,9 +1,9 @@ import { MatrixClient, Room } from 'matrix-js-sdk'; import { useMemo } from 'react'; -import { hasDMWith, isRoomAlias, isRoomId, isUserId } from '../utils/matrix'; -import { selectRoom } from '../../client/action/navigation'; +import { getDMRoomFor, isRoomAlias, isRoomId, isUserId } from '../utils/matrix'; import { hasDevices } from '../../util/matrixUtil'; import * as roomActions from '../../client/action/room'; +import { useRoomNavigate } from './useRoomNavigate'; export const SHRUG = '¯\\_(ツ)_/¯'; @@ -59,6 +59,8 @@ export type CommandContent = { export type CommandRecord = Record; export const useCommands = (mx: MatrixClient, room: Room): CommandRecord => { + const { navigateRoom } = useRoomNavigate(); + const commands: CommandRecord = useMemo( () => ({ [Command.Me]: { @@ -84,16 +86,16 @@ export const useCommands = (mx: MatrixClient, room: Room): CommandRecord => { const userIds = rawIds.filter((id) => isUserId(id) && id !== mx.getUserId()); if (userIds.length === 0) return; if (userIds.length === 1) { - const dmRoomId = hasDMWith(mx, userIds[0]); + const dmRoomId = getDMRoomFor(mx, userIds[0])?.roomId; if (dmRoomId) { - selectRoom(dmRoomId); + navigateRoom(dmRoomId); return; } } const devices = await Promise.all(userIds.map(hasDevices)); const isEncrypt = devices.every((hasDevice) => hasDevice); const result = await roomActions.createDM(userIds, isEncrypt); - selectRoom(result.room_id); + navigateRoom(result.room_id); }, }, [Command.Join]: { @@ -212,7 +214,7 @@ export const useCommands = (mx: MatrixClient, room: Room): CommandRecord => { }, }, }), - [mx, room] + [mx, room, navigateRoom] ); return commands; diff --git a/src/app/hooks/useElementSizeObserver.ts b/src/app/hooks/useElementSizeObserver.ts new file mode 100644 index 000000000..da563c102 --- /dev/null +++ b/src/app/hooks/useElementSizeObserver.ts @@ -0,0 +1,23 @@ +import { useCallback } from 'react'; +import { getResizeObserverEntry, useResizeObserver } from './useResizeObserver'; + +export const useElementSizeObserver = ( + element: () => T | null, + onResize: (width: number, height: number, element: T) => void +) => { + useResizeObserver( + useCallback( + (entries) => { + const target = element(); + if (!target) return; + const targetEntry = getResizeObserverEntry(target, entries); + if (targetEntry) { + const { clientWidth, clientHeight } = targetEntry.target; + onResize(clientWidth, clientHeight, target); + } + }, + [element, onResize] + ), + element + ); +}; diff --git a/src/app/hooks/useInterval.ts b/src/app/hooks/useInterval.ts new file mode 100644 index 000000000..161af3942 --- /dev/null +++ b/src/app/hooks/useInterval.ts @@ -0,0 +1,24 @@ +import { useEffect, useMemo } from 'react'; + +export type IntervalCallback = () => void; + +/** + * @param callback interval callback. + * @param ms interval time in milliseconds. negative value will stop the interval. + * @returns interval id or undefined if not running. + */ +export const useInterval = (callback: IntervalCallback, ms: number): number | undefined => { + const id = useMemo(() => { + if (ms < 0) return undefined; + return window.setInterval(callback, ms); + }, [callback, ms]); + + useEffect( + () => () => { + window.clearInterval(id); + }, + [id] + ); + + return id; +}; diff --git a/src/app/hooks/useJoinedRoomId.ts b/src/app/hooks/useJoinedRoomId.ts new file mode 100644 index 000000000..857defa83 --- /dev/null +++ b/src/app/hooks/useJoinedRoomId.ts @@ -0,0 +1,19 @@ +import { useMemo } from 'react'; +import { useMatrixClient } from './useMatrixClient'; + +import { getCanonicalAliasRoomId, isRoomAlias } from '../utils/matrix'; + +export const useJoinedRoomId = (allRooms: string[], roomIdOrAlias: string): string | undefined => { + const mx = useMatrixClient(); + + const joinedRoomId = useMemo(() => { + const roomId = isRoomAlias(roomIdOrAlias) + ? getCanonicalAliasRoomId(mx, roomIdOrAlias) + : roomIdOrAlias; + + if (roomId && allRooms.includes(roomId)) return roomId; + return undefined; + }, [mx, allRooms, roomIdOrAlias]); + + return joinedRoomId; +}; diff --git a/src/app/hooks/useLocalRoomSummary.ts b/src/app/hooks/useLocalRoomSummary.ts new file mode 100644 index 000000000..46f815698 --- /dev/null +++ b/src/app/hooks/useLocalRoomSummary.ts @@ -0,0 +1,44 @@ +import { GuestAccess, HistoryVisibility, JoinRule, Room } from 'matrix-js-sdk'; +import { getStateEvent } from '../utils/room'; +import { StateEvent } from '../../types/matrix/room'; + +export type LocalRoomSummary = { + roomId: string; + name: string; + topic?: string; + avatarUrl?: string; + canonicalAlias?: string; + worldReadable?: boolean; + guestCanJoin?: boolean; + memberCount?: number; + roomType?: string; + joinRule?: JoinRule; +}; +export const useLocalRoomSummary = (room: Room): LocalRoomSummary => { + const topicEvent = getStateEvent(room, StateEvent.RoomTopic); + const topicContent = topicEvent?.getContent(); + const topic = + topicContent && typeof topicContent.topic === 'string' ? topicContent.topic : undefined; + + const historyEvent = getStateEvent(room, StateEvent.RoomHistoryVisibility); + const historyContent = historyEvent?.getContent(); + const worldReadable = + historyContent && typeof historyContent.history_visibility === 'string' + ? historyContent.history_visibility === HistoryVisibility.WorldReadable + : undefined; + + const guestCanJoin = room.getGuestAccess() === GuestAccess.CanJoin; + + return { + roomId: room.roomId, + name: room.name, + topic, + avatarUrl: room.getMxcAvatarUrl() ?? undefined, + canonicalAlias: room.getCanonicalAlias() ?? undefined, + worldReadable, + guestCanJoin, + memberCount: room.getJoinedMemberCount(), + roomType: room.getType(), + joinRule: room.getJoinRule(), + }; +}; diff --git a/src/app/hooks/useMatrixEventRenderer.ts b/src/app/hooks/useMatrixEventRenderer.ts index 9ace6b66a..57d56cc1c 100644 --- a/src/app/hooks/useMatrixEventRenderer.ts +++ b/src/app/hooks/useMatrixEventRenderer.ts @@ -1,80 +1,31 @@ import { ReactNode } from 'react'; -import { MatrixEvent } from 'matrix-js-sdk'; -import { MessageEvent, StateEvent } from '../../types/matrix/room'; -export type EventRenderer = ( - eventId: string, - mEvent: MatrixEvent, - ...args: T -) => ReactNode; +export type EventRenderer = (...args: T) => ReactNode; -export type EventRendererOpts = { - renderRoomMessage?: EventRenderer; - renderRoomEncrypted?: EventRenderer; - renderSticker?: EventRenderer; - renderRoomMember?: EventRenderer; - renderRoomName?: EventRenderer; - renderRoomTopic?: EventRenderer; - renderRoomAvatar?: EventRenderer; - renderStateEvent?: EventRenderer; - renderEvent?: EventRenderer; -}; +export type EventRendererOpts = Record>; export type RenderMatrixEvent = ( - eventId: string, - mEvent: MatrixEvent, + eventType: string, + isStateEvent: boolean, ...args: T ) => ReactNode; export const useMatrixEventRenderer = - ({ - renderRoomMessage, - renderRoomEncrypted, - renderSticker, - renderRoomMember, - renderRoomName, - renderRoomTopic, - renderRoomAvatar, - renderStateEvent, - renderEvent, - }: EventRendererOpts): RenderMatrixEvent => - (eventId, mEvent, ...args) => { - const eventType = mEvent.getWireType(); + ( + typeToRenderer: EventRendererOpts, + renderStateEvent?: EventRenderer, + renderEvent?: EventRenderer + ): RenderMatrixEvent => + (eventType, isStateEvent, ...args) => { + const renderer = typeToRenderer[eventType]; + if (typeToRenderer[eventType]) return renderer(...args); - if (eventType === MessageEvent.RoomMessage && renderRoomMessage) { - return renderRoomMessage(eventId, mEvent, ...args); + if (isStateEvent && renderStateEvent) { + return renderStateEvent(...args); } - if (eventType === MessageEvent.RoomMessageEncrypted && renderRoomEncrypted) { - return renderRoomEncrypted(eventId, mEvent, ...args); - } - - if (eventType === MessageEvent.Sticker && renderSticker) { - return renderSticker(eventId, mEvent, ...args); - } - - if (eventType === StateEvent.RoomMember && renderRoomMember) { - return renderRoomMember(eventId, mEvent, ...args); - } - - if (eventType === StateEvent.RoomName && renderRoomName) { - return renderRoomName(eventId, mEvent, ...args); - } - - if (eventType === StateEvent.RoomTopic && renderRoomTopic) { - return renderRoomTopic(eventId, mEvent, ...args); - } - - if (eventType === StateEvent.RoomAvatar && renderRoomAvatar) { - return renderRoomAvatar(eventId, mEvent, ...args); - } - - if (typeof mEvent.getStateKey() === 'string' && renderStateEvent) { - return renderStateEvent(eventId, mEvent, ...args); - } - - if (typeof mEvent.getStateKey() !== 'string' && renderEvent) { - return renderEvent(eventId, mEvent, ...args); + if (!isStateEvent && renderEvent) { + return renderEvent(...args); } return null; }; diff --git a/src/app/hooks/useMediaConfig.ts b/src/app/hooks/useMediaConfig.ts new file mode 100644 index 000000000..929ebd004 --- /dev/null +++ b/src/app/hooks/useMediaConfig.ts @@ -0,0 +1,16 @@ +import { createContext, useContext } from 'react'; + +export interface MediaConfig { + [key: string]: unknown; + 'm.upload.size'?: number; +} + +const MediaConfigContext = createContext(null); + +export const MediaConfigProvider = MediaConfigContext.Provider; + +export function useMediaConfig(): MediaConfig { + const mediaConfig = useContext(MediaConfigContext); + if (!mediaConfig) throw new Error('Media configs are not provided!'); + return mediaConfig; +} diff --git a/src/app/hooks/useNavToActivePathMapper.ts b/src/app/hooks/useNavToActivePathMapper.ts new file mode 100644 index 000000000..d3cec08ef --- /dev/null +++ b/src/app/hooks/useNavToActivePathMapper.ts @@ -0,0 +1,18 @@ +import { useEffect } from 'react'; +import { useSetAtom } from 'jotai'; +import { useLocation } from 'react-router-dom'; +import { useNavToActivePathAtom } from '../state/hooks/navToActivePath'; + +export const useNavToActivePathMapper = (navId: string) => { + const location = useLocation(); + const setNavToActivePath = useSetAtom(useNavToActivePathAtom()); + + useEffect(() => { + const { pathname, search, hash } = location; + setNavToActivePath({ + type: 'PUT', + navId, + path: { pathname, search, hash }, + }); + }, [location, setNavToActivePath, navId]); +}; diff --git a/src/app/hooks/usePowerLevels.ts b/src/app/hooks/usePowerLevels.ts index 98e3701ed..0fcbbd330 100644 --- a/src/app/hooks/usePowerLevels.ts +++ b/src/app/hooks/usePowerLevels.ts @@ -1,7 +1,11 @@ import { Room } from 'matrix-js-sdk'; -import { createContext, useCallback, useContext } from 'react'; +import { createContext, useCallback, useContext, useMemo } from 'react'; import { useStateEvent } from './useStateEvent'; import { StateEvent } from '../../types/matrix/room'; +import { useForceUpdate } from './useForceUpdate'; +import { useStateEventCallback } from './useStateEventCallback'; +import { useMatrixClient } from './useMatrixClient'; +import { getStateEvent } from '../utils/room'; export type PowerLevelActions = 'invite' | 'redact' | 'kick' | 'ban' | 'historical'; @@ -16,7 +20,7 @@ enum DefaultPowerLevels { historical = 0, } -interface IPowerLevels { +export interface IPowerLevels { users_default?: number; state_default?: number; events_default?: number; @@ -31,9 +35,75 @@ interface IPowerLevels { notifications?: Record; } -export type GetPowerLevel = (userId: string) => number; -export type CanSend = (eventType: string | undefined, powerLevel: number) => boolean; -export type CanDoAction = (action: PowerLevelActions, powerLevel: number) => boolean; +export function usePowerLevels(room: Room): IPowerLevels { + const powerLevelsEvent = useStateEvent(room, StateEvent.RoomPowerLevels); + const powerLevels: IPowerLevels = + powerLevelsEvent?.getContent() ?? DefaultPowerLevels; + + return powerLevels; +} + +export const PowerLevelsContext = createContext(null); + +export const PowerLevelsContextProvider = PowerLevelsContext.Provider; + +export const usePowerLevelsContext = (): IPowerLevels => { + const pl = useContext(PowerLevelsContext); + if (!pl) throw new Error('PowerLevelContext is not initialized!'); + return pl; +}; + +export const useRoomsPowerLevels = (rooms: Room[]): Map => { + const mx = useMatrixClient(); + const [updateCount, forceUpdate] = useForceUpdate(); + + useStateEventCallback( + mx, + useCallback( + (event) => { + const roomId = event.getRoomId(); + if ( + roomId && + event.getType() === StateEvent.RoomPowerLevels && + event.getStateKey() === '' && + rooms.find((r) => r.roomId === roomId) + ) { + forceUpdate(); + } + }, + [rooms, forceUpdate] + ) + ); + + const roomToPowerLevels = useMemo( + () => { + const rToPl = new Map(); + + rooms.forEach((room) => { + const pl = getStateEvent(room, StateEvent.RoomPowerLevels, '')?.getContent(); + if (pl) rToPl.set(room.roomId, pl); + }); + + return rToPl; + }, + // eslint-disable-next-line react-hooks/exhaustive-deps + [rooms, updateCount] + ); + + return roomToPowerLevels; +}; + +export type GetPowerLevel = (powerLevels: IPowerLevels, userId: string | undefined) => number; +export type CanSend = ( + powerLevels: IPowerLevels, + eventType: string | undefined, + powerLevel: number +) => boolean; +export type CanDoAction = ( + powerLevels: IPowerLevels, + action: PowerLevelActions, + powerLevel: number +) => boolean; export type PowerLevelsAPI = { getPowerLevel: GetPowerLevel; @@ -42,51 +112,58 @@ export type PowerLevelsAPI = { canDoAction: CanDoAction; }; -export function usePowerLevels(room: Room): PowerLevelsAPI { - const powerLevelsEvent = useStateEvent(room, StateEvent.RoomPowerLevels); - const powerLevels: IPowerLevels = powerLevelsEvent?.getContent() ?? DefaultPowerLevels; +export const powerLevelAPI: PowerLevelsAPI = { + getPowerLevel: (powerLevels, userId) => { + const { users_default: usersDefault, users } = powerLevels; + if (userId && users && typeof users[userId] === 'number') { + return users[userId]; + } + return usersDefault ?? DefaultPowerLevels.usersDefault; + }, + canSendEvent: (powerLevels, eventType, powerLevel) => { + const { events, events_default: eventsDefault } = powerLevels; + if (events && eventType && typeof events[eventType] === 'number') { + return powerLevel >= events[eventType]; + } + return powerLevel >= (eventsDefault ?? DefaultPowerLevels.eventsDefault); + }, + canSendStateEvent: (powerLevels, eventType, powerLevel) => { + const { events, state_default: stateDefault } = powerLevels; + if (events && eventType && typeof events[eventType] === 'number') { + return powerLevel >= events[eventType]; + } + return powerLevel >= (stateDefault ?? DefaultPowerLevels.stateDefault); + }, + canDoAction: (powerLevels, action, powerLevel) => { + const requiredPL = powerLevels[action]; + if (typeof requiredPL === 'number') { + return powerLevel >= requiredPL; + } + return powerLevel >= DefaultPowerLevels[action]; + }, +}; - const getPowerLevel: GetPowerLevel = useCallback( - (userId) => { - const { users_default: usersDefault, users } = powerLevels; - if (users && typeof users[userId] === 'number') { - return users[userId]; - } - return usersDefault ?? DefaultPowerLevels.usersDefault; - }, +export const usePowerLevelsAPI = (powerLevels: IPowerLevels) => { + const getPowerLevel = useCallback( + (userId: string | undefined) => powerLevelAPI.getPowerLevel(powerLevels, userId), [powerLevels] ); - const canSendEvent: CanSend = useCallback( - (eventType, powerLevel) => { - const { events, events_default: eventsDefault } = powerLevels; - if (events && eventType && typeof events[eventType] === 'number') { - return powerLevel >= events[eventType]; - } - return powerLevel >= (eventsDefault ?? DefaultPowerLevels.eventsDefault); - }, + const canSendEvent = useCallback( + (eventType: string | undefined, powerLevel: number) => + powerLevelAPI.canSendEvent(powerLevels, eventType, powerLevel), [powerLevels] ); - const canSendStateEvent: CanSend = useCallback( - (eventType, powerLevel) => { - const { events, state_default: stateDefault } = powerLevels; - if (events && eventType && typeof events[eventType] === 'number') { - return powerLevel >= events[eventType]; - } - return powerLevel >= (stateDefault ?? DefaultPowerLevels.stateDefault); - }, + const canSendStateEvent = useCallback( + (eventType: string | undefined, powerLevel: number) => + powerLevelAPI.canSendStateEvent(powerLevels, eventType, powerLevel), [powerLevels] ); - const canDoAction: CanDoAction = useCallback( - (action, powerLevel) => { - const requiredPL = powerLevels[action]; - if (typeof requiredPL === 'number') { - return powerLevel >= requiredPL; - } - return powerLevel >= DefaultPowerLevels[action]; - }, + const canDoAction = useCallback( + (action: PowerLevelActions, powerLevel: number) => + powerLevelAPI.canDoAction(powerLevels, action, powerLevel), [powerLevels] ); @@ -96,14 +173,4 @@ export function usePowerLevels(room: Room): PowerLevelsAPI { canSendStateEvent, canDoAction, }; -} - -export const PowerLevelsContext = createContext(null); - -export const PowerLevelsContextProvider = PowerLevelsContext.Provider; - -export const usePowerLevelsAPI = (): PowerLevelsAPI => { - const api = useContext(PowerLevelsContext); - if (!api) throw new Error('PowerLevelContext is not initialized!'); - return api; }; diff --git a/src/app/hooks/useRoom.ts b/src/app/hooks/useRoom.ts new file mode 100644 index 000000000..3f802d432 --- /dev/null +++ b/src/app/hooks/useRoom.ts @@ -0,0 +1,12 @@ +import { Room } from 'matrix-js-sdk'; +import { createContext, useContext } from 'react'; + +const RoomContext = createContext(null); + +export const RoomProvider = RoomContext.Provider; + +export function useRoom(): Room { + const room = useContext(RoomContext); + if (!room) throw new Error('Room not provided!'); + return room; +} diff --git a/src/app/hooks/useRoomMeta.ts b/src/app/hooks/useRoomMeta.ts new file mode 100644 index 000000000..51248831e --- /dev/null +++ b/src/app/hooks/useRoomMeta.ts @@ -0,0 +1,41 @@ +import { useEffect, useState } from 'react'; +import { Room, RoomEvent, RoomEventHandlerMap } from 'matrix-js-sdk'; +import { StateEvent } from '../../types/matrix/room'; +import { useStateEvent } from './useStateEvent'; + +export const useRoomAvatar = (room: Room, dm?: boolean): string | undefined => { + const avatarEvent = useStateEvent(room, StateEvent.RoomAvatar); + + if (dm) { + return room.getAvatarFallbackMember()?.getMxcAvatarUrl(); + } + const content = avatarEvent?.getContent(); + const avatarMxc = content && typeof content.url === 'string' ? content.url : undefined; + + return avatarMxc; +}; + +export const useRoomName = (room: Room): string => { + const [name, setName] = useState(room.name); + + useEffect(() => { + const handleRoomNameChange: RoomEventHandlerMap[RoomEvent.Name] = () => { + setName(room.name); + }; + room.on(RoomEvent.Name, handleRoomNameChange); + return () => { + room.removeListener(RoomEvent.Name, handleRoomNameChange); + }; + }, [room]); + + return name; +}; + +export const useRoomTopic = (room: Room): string | undefined => { + const topicEvent = useStateEvent(room, StateEvent.RoomTopic); + + const content = topicEvent?.getContent(); + const topic = content && typeof content.topic === 'string' ? content.topic : undefined; + + return topic; +}; diff --git a/src/app/hooks/useRoomMsgContentRenderer.ts b/src/app/hooks/useRoomMsgContentRenderer.ts deleted file mode 100644 index b014249a2..000000000 --- a/src/app/hooks/useRoomMsgContentRenderer.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { ReactNode } from 'react'; -import { MatrixEvent, MsgType } from 'matrix-js-sdk'; - -export type MsgContentRenderer = ( - eventId: string, - mEvent: MatrixEvent, - ...args: T -) => ReactNode; - -export type RoomMsgContentRendererOpts = { - renderText?: MsgContentRenderer; - renderEmote?: MsgContentRenderer; - renderNotice?: MsgContentRenderer; - renderImage?: MsgContentRenderer; - renderVideo?: MsgContentRenderer; - renderAudio?: MsgContentRenderer; - renderFile?: MsgContentRenderer; - renderLocation?: MsgContentRenderer; - renderBadEncrypted?: MsgContentRenderer; - renderUnsupported?: MsgContentRenderer; - renderBrokenFallback?: MsgContentRenderer; -}; - -export type RenderRoomMsgContent = ( - eventId: string, - mEvent: MatrixEvent, - ...args: T -) => ReactNode; - -export const useRoomMsgContentRenderer = - ({ - renderText, - renderEmote, - renderNotice, - renderImage, - renderVideo, - renderAudio, - renderFile, - renderLocation, - renderBadEncrypted, - renderUnsupported, - renderBrokenFallback, - }: RoomMsgContentRendererOpts): RenderRoomMsgContent => - (eventId, mEvent, ...args) => { - const msgType = mEvent.getContent().msgtype; - - let node: ReactNode = null; - - if (msgType === MsgType.Text && renderText) node = renderText(eventId, mEvent, ...args); - else if (msgType === MsgType.Emote && renderEmote) node = renderEmote(eventId, mEvent, ...args); - else if (msgType === MsgType.Notice && renderNotice) - node = renderNotice(eventId, mEvent, ...args); - else if (msgType === MsgType.Image && renderImage) node = renderImage(eventId, mEvent, ...args); - else if (msgType === MsgType.Video && renderVideo) node = renderVideo(eventId, mEvent, ...args); - else if (msgType === MsgType.Audio && renderAudio) node = renderAudio(eventId, mEvent, ...args); - else if (msgType === MsgType.File && renderFile) node = renderFile(eventId, mEvent, ...args); - else if (msgType === MsgType.Location && renderLocation) - node = renderLocation(eventId, mEvent, ...args); - else if (msgType === 'm.bad.encrypted' && renderBadEncrypted) - node = renderBadEncrypted(eventId, mEvent, ...args); - else if (renderUnsupported) { - node = renderUnsupported(eventId, mEvent, ...args); - } - - if (!node && renderBrokenFallback) node = renderBrokenFallback(eventId, mEvent, ...args); - - return node; - }; diff --git a/src/app/hooks/useRoomNavigate.ts b/src/app/hooks/useRoomNavigate.ts new file mode 100644 index 000000000..55528e7ee --- /dev/null +++ b/src/app/hooks/useRoomNavigate.ts @@ -0,0 +1,55 @@ +import { useCallback } from 'react'; +import { useNavigate } from 'react-router-dom'; +import { useAtomValue } from 'jotai'; +import { getCanonicalAliasOrRoomId } from '../utils/matrix'; +import { + getDirectRoomPath, + getHomeRoomPath, + getSpacePath, + getSpaceRoomPath, +} from '../pages/pathUtils'; +import { useMatrixClient } from './useMatrixClient'; +import { getOrphanParents } from '../utils/room'; +import { roomToParentsAtom } from '../state/room/roomToParents'; +import { mDirectAtom } from '../state/mDirectList'; + +export const useRoomNavigate = () => { + const navigate = useNavigate(); + const mx = useMatrixClient(); + const roomToParents = useAtomValue(roomToParentsAtom); + const mDirects = useAtomValue(mDirectAtom); + + const navigateSpace = useCallback( + (roomId: string) => { + const roomIdOrAlias = getCanonicalAliasOrRoomId(mx, roomId); + navigate(getSpacePath(roomIdOrAlias)); + }, + [mx, navigate] + ); + + const navigateRoom = useCallback( + (roomId: string, eventId?: string) => { + const roomIdOrAlias = getCanonicalAliasOrRoomId(mx, roomId); + + const orphanParents = getOrphanParents(roomToParents, roomId); + if (orphanParents.length > 0) { + const pSpaceIdOrAlias = getCanonicalAliasOrRoomId(mx, orphanParents[0]); + navigate(getSpaceRoomPath(pSpaceIdOrAlias, roomIdOrAlias, eventId)); + return; + } + + if (mDirects.has(roomId)) { + navigate(getDirectRoomPath(roomIdOrAlias, eventId)); + return; + } + + navigate(getHomeRoomPath(roomIdOrAlias, eventId)); + }, + [mx, navigate, roomToParents, mDirects] + ); + + return { + navigateSpace, + navigateRoom, + }; +}; diff --git a/src/app/hooks/useRoomTypingMembers.ts b/src/app/hooks/useRoomTypingMembers.ts new file mode 100644 index 000000000..5f24fb5df --- /dev/null +++ b/src/app/hooks/useRoomTypingMembers.ts @@ -0,0 +1,10 @@ +import { useAtomValue } from 'jotai'; +import { useMemo } from 'react'; +import { roomIdToTypingMembersAtom, selectRoomTypingMembersAtom } from '../state/typingMembers'; + +export const useRoomTypingMember = (roomId: string) => { + const typing = useAtomValue( + useMemo(() => selectRoomTypingMembersAtom(roomId, roomIdToTypingMembersAtom), [roomId]) + ); + return typing; +}; diff --git a/src/app/hooks/useScreenSize.ts b/src/app/hooks/useScreenSize.ts index 4afe90832..3e64528d6 100644 --- a/src/app/hooks/useScreenSize.ts +++ b/src/app/hooks/useScreenSize.ts @@ -1,5 +1,5 @@ -import { useCallback, useState } from 'react'; -import { getResizeObserverEntry, useResizeObserver } from './useResizeObserver'; +import { createContext, useCallback, useContext, useState } from 'react'; +import { useElementSizeObserver } from './useElementSizeObserver'; export const TABLET_BREAKPOINT = 1124; export const MOBILE_BREAKPOINT = 750; @@ -16,21 +16,24 @@ export const getScreenSize = (width: number): ScreenSize => { return ScreenSize.Mobile; }; -export const useScreenSize = (): [ScreenSize, number] => { - const [size, setSize] = useState<[ScreenSize, number]>([ - getScreenSize(document.body.clientWidth), - document.body.clientWidth, - ]); - useResizeObserver( - useCallback((entries) => { - const bodyEntry = getResizeObserverEntry(document.body, entries); - if (bodyEntry) { - const bWidth = bodyEntry.contentRect.width; - setSize([getScreenSize(bWidth), bWidth]); - } - }, []), - document.body +export const useScreenSize = (): ScreenSize => { + const [size, setSize] = useState(getScreenSize(document.body.clientWidth)); + + useElementSizeObserver( + useCallback(() => document.body, []), + useCallback((width) => setSize(getScreenSize(width)), []) ); return size; }; + +const ScreenSizeContext = createContext(null); +export const ScreenSizeProvider = ScreenSizeContext.Provider; + +export const useScreenSizeContext = (): ScreenSize => { + const screenSize = useContext(ScreenSizeContext); + if (screenSize === null) { + throw new Error('Screen size not provided!'); + } + return screenSize; +}; diff --git a/src/app/hooks/useSidebarItems.ts b/src/app/hooks/useSidebarItems.ts new file mode 100644 index 000000000..16aba225a --- /dev/null +++ b/src/app/hooks/useSidebarItems.ts @@ -0,0 +1,138 @@ +import { Dispatch, SetStateAction, useCallback, useEffect, useState } from 'react'; +import { MatrixClient } from 'matrix-js-sdk'; +import { AccountDataEvent } from '../../types/matrix/accountData'; +import { useMatrixClient } from './useMatrixClient'; +import { getAccountData, isSpace } from '../utils/room'; +import { Membership } from '../../types/matrix/room'; +import { useAccountDataCallback } from './useAccountDataCallback'; + +export type ISidebarFolder = { + name?: string; + id: string; + content: string[]; +}; +export type TSidebarItem = string | ISidebarFolder; +export type SidebarItems = Array; + +export type InCinnySpacesContent = { + shortcut?: string[]; + sidebar?: SidebarItems; +}; + +export const parseSidebar = ( + mx: MatrixClient, + orphanSpaces: string[], + content?: InCinnySpacesContent +) => { + const sidebar = content?.sidebar ?? content?.shortcut ?? []; + const orphans = new Set(orphanSpaces); + + const items: SidebarItems = []; + + const safeToAdd = (spaceId: string): boolean => { + if (typeof spaceId !== 'string') return false; + const space = mx.getRoom(spaceId); + if (space?.getMyMembership() !== Membership.Join) return false; + return isSpace(space); + }; + + sidebar.forEach((item) => { + if (typeof item === 'string') { + if (safeToAdd(item) && !items.includes(item)) { + orphans.delete(item); + items.push(item); + } + return; + } + if ( + typeof item === 'object' && + typeof item.id === 'string' && + Array.isArray(item.content) && + !items.find((i) => (typeof i === 'string' ? false : i.id === item.id)) + ) { + const safeContent = item.content.filter(safeToAdd); + safeContent.forEach((i) => orphans.delete(i)); + items.push({ + ...item, + content: Array.from(new Set(safeContent)), + }); + } + }); + + orphans.forEach((spaceId) => items.push(spaceId)); + return items; +}; + +export const useSidebarItems = ( + orphanSpaces: string[] +): [SidebarItems, Dispatch>] => { + const mx = useMatrixClient(); + + const [sidebarItems, setSidebarItems] = useState(() => { + const inCinnySpacesContent = getAccountData( + mx, + AccountDataEvent.CinnySpaces + )?.getContent(); + return parseSidebar(mx, orphanSpaces, inCinnySpacesContent); + }); + + useEffect(() => { + const inCinnySpacesContent = getAccountData( + mx, + AccountDataEvent.CinnySpaces + )?.getContent(); + setSidebarItems(parseSidebar(mx, orphanSpaces, inCinnySpacesContent)); + }, [mx, orphanSpaces]); + + useAccountDataCallback( + mx, + useCallback( + (mEvent) => { + if (mEvent.getType() === AccountDataEvent.CinnySpaces) { + const newContent = mEvent.getContent(); + setSidebarItems(parseSidebar(mx, orphanSpaces, newContent)); + } + }, + [mx, orphanSpaces] + ) + ); + + return [sidebarItems, setSidebarItems]; +}; + +export const sidebarItemWithout = (items: SidebarItems, roomId: string) => { + const newItems: SidebarItems = items + .map((item) => { + if (typeof item === 'string') { + if (item === roomId) return null; + return item; + } + if (item.content.includes(roomId)) { + const newContent = item.content.filter((id) => id !== roomId); + if (newContent.length === 0) return null; + return { + ...item, + content: newContent, + }; + } + return item; + }) + .filter((item) => item !== null) as SidebarItems; + + return newItems; +}; + +export const makeCinnySpacesContent = ( + mx: MatrixClient, + items: SidebarItems +): InCinnySpacesContent => { + const currentInSpaces = + getAccountData(mx, AccountDataEvent.CinnySpaces)?.getContent() ?? {}; + + const newSpacesContent: InCinnySpacesContent = { + ...currentInSpaces, + sidebar: items, + }; + + return newSpacesContent; +}; diff --git a/src/app/hooks/useSpace.ts b/src/app/hooks/useSpace.ts new file mode 100644 index 000000000..8bec49e4c --- /dev/null +++ b/src/app/hooks/useSpace.ts @@ -0,0 +1,17 @@ +import { Room } from 'matrix-js-sdk'; +import { createContext, useContext } from 'react'; + +const SpaceContext = createContext(null); + +export const SpaceProvider = SpaceContext.Provider; + +export function useSpace(): Room { + const space = useContext(SpaceContext); + if (!space) throw new Error('Space not provided!'); + return space; +} + +export function useSpaceOptionally(): Room | null { + const space = useContext(SpaceContext); + return space; +} diff --git a/src/app/hooks/useSpaceHierarchy.ts b/src/app/hooks/useSpaceHierarchy.ts new file mode 100644 index 000000000..c109cc212 --- /dev/null +++ b/src/app/hooks/useSpaceHierarchy.ts @@ -0,0 +1,253 @@ +import { atom, useAtom, useAtomValue } from 'jotai'; +import { useCallback, useEffect, useState } from 'react'; +import { Room } from 'matrix-js-sdk'; +import { useMatrixClient } from './useMatrixClient'; +import { roomToParentsAtom } from '../state/room/roomToParents'; +import { MSpaceChildContent, StateEvent } from '../../types/matrix/room'; +import { getAllParents, getStateEvents, isValidChild } from '../utils/room'; +import { isRoomId } from '../utils/matrix'; +import { SortFunc, byOrderKey, byTsOldToNew, factoryRoomIdByActivity } from '../utils/sort'; +import { useStateEventCallback } from './useStateEventCallback'; + +export type HierarchyItem = + | { + roomId: string; + content: MSpaceChildContent; + ts: number; + space: true; + parentId?: string; + } + | { + roomId: string; + content: MSpaceChildContent; + ts: number; + space?: false; + parentId: string; + }; + +type GetRoomCallback = (roomId: string) => Room | undefined; + +const hierarchyItemTs: SortFunc = (a, b) => byTsOldToNew(a.ts, b.ts); +const hierarchyItemByOrder: SortFunc = (a, b) => + byOrderKey(a.content.order, b.content.order); + +const getHierarchySpaces = ( + rootSpaceId: string, + getRoom: GetRoomCallback, + spaceRooms: Set +): HierarchyItem[] => { + const rootSpaceItem: HierarchyItem = { + roomId: rootSpaceId, + content: { via: [] }, + ts: 0, + space: true, + }; + let spaceItems: HierarchyItem[] = []; + + const findAndCollectHierarchySpaces = (spaceItem: HierarchyItem) => { + if (spaceItems.find((item) => item.roomId === spaceItem.roomId)) return; + const space = getRoom(spaceItem.roomId); + spaceItems.push(spaceItem); + + if (!space) return; + const childEvents = getStateEvents(space, StateEvent.SpaceChild); + + childEvents.forEach((childEvent) => { + if (!isValidChild(childEvent)) return; + const childId = childEvent.getStateKey(); + if (!childId || !isRoomId(childId)) return; + + // because we can not find if a childId is space without joining + // or requesting room summary, we will look it into spaceRooms local + // cache which we maintain as we load summary in UI. + if (getRoom(childId)?.isSpaceRoom() || spaceRooms.has(childId)) { + const childItem: HierarchyItem = { + roomId: childId, + content: childEvent.getContent(), + ts: childEvent.getTs(), + space: true, + parentId: spaceItem.roomId, + }; + findAndCollectHierarchySpaces(childItem); + } + }); + }; + findAndCollectHierarchySpaces(rootSpaceItem); + + spaceItems = [ + rootSpaceItem, + ...spaceItems + .filter((item) => item.roomId !== rootSpaceId) + .sort(hierarchyItemTs) + .sort(hierarchyItemByOrder), + ]; + + return spaceItems; +}; + +const getSpaceHierarchy = ( + rootSpaceId: string, + spaceRooms: Set, + getRoom: (roomId: string) => Room | undefined, + closedCategory: (spaceId: string) => boolean +): HierarchyItem[] => { + const spaceItems: HierarchyItem[] = getHierarchySpaces(rootSpaceId, getRoom, spaceRooms); + + const hierarchy: HierarchyItem[] = spaceItems.flatMap((spaceItem) => { + const space = getRoom(spaceItem.roomId); + if (!space || closedCategory(spaceItem.roomId)) { + return [spaceItem]; + } + const childEvents = getStateEvents(space, StateEvent.SpaceChild); + const childItems: HierarchyItem[] = []; + childEvents.forEach((childEvent) => { + if (!isValidChild(childEvent)) return; + const childId = childEvent.getStateKey(); + if (!childId || !isRoomId(childId)) return; + if (getRoom(childId)?.isSpaceRoom() || spaceRooms.has(childId)) return; + + const childItem: HierarchyItem = { + roomId: childId, + content: childEvent.getContent(), + ts: childEvent.getTs(), + parentId: spaceItem.roomId, + }; + childItems.push(childItem); + }); + return [spaceItem, ...childItems.sort(hierarchyItemTs).sort(hierarchyItemByOrder)]; + }); + + return hierarchy; +}; + +export const useSpaceHierarchy = ( + spaceId: string, + spaceRooms: Set, + getRoom: (roomId: string) => Room | undefined, + closedCategory: (spaceId: string) => boolean +): HierarchyItem[] => { + const mx = useMatrixClient(); + const roomToParents = useAtomValue(roomToParentsAtom); + + const [hierarchyAtom] = useState(() => + atom(getSpaceHierarchy(spaceId, spaceRooms, getRoom, closedCategory)) + ); + const [hierarchy, setHierarchy] = useAtom(hierarchyAtom); + + useEffect(() => { + setHierarchy(getSpaceHierarchy(spaceId, spaceRooms, getRoom, closedCategory)); + }, [mx, spaceId, spaceRooms, setHierarchy, getRoom, closedCategory]); + + useStateEventCallback( + mx, + useCallback( + (mEvent) => { + if (mEvent.getType() !== StateEvent.SpaceChild) return; + const eventRoomId = mEvent.getRoomId(); + if (!eventRoomId) return; + + if (spaceId === eventRoomId || getAllParents(roomToParents, eventRoomId).has(spaceId)) { + setHierarchy(getSpaceHierarchy(spaceId, spaceRooms, getRoom, closedCategory)); + } + }, + [spaceId, roomToParents, setHierarchy, spaceRooms, getRoom, closedCategory] + ) + ); + + return hierarchy; +}; + +const getSpaceJoinedHierarchy = ( + rootSpaceId: string, + getRoom: GetRoomCallback, + excludeRoom: (parentId: string, roomId: string) => boolean, + sortRoomItems: (parentId: string, items: HierarchyItem[]) => HierarchyItem[] +): HierarchyItem[] => { + const spaceItems: HierarchyItem[] = getHierarchySpaces(rootSpaceId, getRoom, new Set()); + + const hierarchy: HierarchyItem[] = spaceItems.flatMap((spaceItem) => { + const space = getRoom(spaceItem.roomId); + if (!space) { + return []; + } + const joinedRoomEvents = getStateEvents(space, StateEvent.SpaceChild).filter((childEvent) => { + if (!isValidChild(childEvent)) return false; + const childId = childEvent.getStateKey(); + if (!childId || !isRoomId(childId)) return false; + const room = getRoom(childId); + if (!room || room.isSpaceRoom()) return false; + + return true; + }); + + if (joinedRoomEvents.length === 0) return []; + + const childItems: HierarchyItem[] = []; + joinedRoomEvents.forEach((childEvent) => { + const childId = childEvent.getStateKey(); + if (!childId) return; + + if (excludeRoom(space.roomId, childId)) return; + + const childItem: HierarchyItem = { + roomId: childId, + content: childEvent.getContent(), + ts: childEvent.getTs(), + parentId: spaceItem.roomId, + }; + childItems.push(childItem); + }); + return [spaceItem, ...sortRoomItems(spaceItem.roomId, childItems)]; + }); + + return hierarchy; +}; + +export const useSpaceJoinedHierarchy = ( + spaceId: string, + getRoom: GetRoomCallback, + excludeRoom: (parentId: string, roomId: string) => boolean, + sortByActivity: (spaceId: string) => boolean +): HierarchyItem[] => { + const mx = useMatrixClient(); + const roomToParents = useAtomValue(roomToParentsAtom); + + const sortRoomItems = useCallback( + (sId: string, items: HierarchyItem[]) => { + if (sortByActivity(sId)) { + items.sort((a, b) => factoryRoomIdByActivity(mx)(a.roomId, b.roomId)); + return items; + } + items.sort(hierarchyItemTs).sort(hierarchyItemByOrder); + return items; + }, + [mx, sortByActivity] + ); + + const [hierarchyAtom] = useState(() => + atom(getSpaceJoinedHierarchy(spaceId, getRoom, excludeRoom, sortRoomItems)) + ); + const [hierarchy, setHierarchy] = useAtom(hierarchyAtom); + + useEffect(() => { + setHierarchy(getSpaceJoinedHierarchy(spaceId, getRoom, excludeRoom, sortRoomItems)); + }, [mx, spaceId, setHierarchy, getRoom, excludeRoom, sortRoomItems]); + + useStateEventCallback( + mx, + useCallback( + (mEvent) => { + if (mEvent.getType() !== StateEvent.SpaceChild) return; + const eventRoomId = mEvent.getRoomId(); + if (!eventRoomId) return; + + if (spaceId === eventRoomId || getAllParents(roomToParents, eventRoomId).has(spaceId)) { + setHierarchy(getSpaceJoinedHierarchy(spaceId, getRoom, excludeRoom, sortRoomItems)); + } + }, + [spaceId, roomToParents, setHierarchy, getRoom, excludeRoom, sortRoomItems] + ) + ); + + return hierarchy; +}; diff --git a/src/app/hooks/useSyncState.ts b/src/app/hooks/useSyncState.ts new file mode 100644 index 000000000..4b2f41632 --- /dev/null +++ b/src/app/hooks/useSyncState.ts @@ -0,0 +1,14 @@ +import { ClientEvent, ClientEventHandlerMap, MatrixClient } from 'matrix-js-sdk'; +import { useEffect } from 'react'; + +export const useSyncState = ( + mx: MatrixClient, + onChange: ClientEventHandlerMap[ClientEvent.Sync] +): void => { + useEffect(() => { + mx.on(ClientEvent.Sync, onChange); + return () => { + mx.removeListener(ClientEvent.Sync, onChange); + }; + }, [mx, onChange]); +}; diff --git a/src/app/hooks/useTypingStatusUpdater.ts b/src/app/hooks/useTypingStatusUpdater.ts index af76eae7e..db8ceff1e 100644 --- a/src/app/hooks/useTypingStatusUpdater.ts +++ b/src/app/hooks/useTypingStatusUpdater.ts @@ -1,10 +1,9 @@ import { MatrixClient } from 'matrix-js-sdk'; import { useMemo, useRef } from 'react'; +import { TYPING_TIMEOUT_MS } from '../state/typingMembers'; type TypingStatusUpdater = (typing: boolean) => void; -const TYPING_TIMEOUT_MS = 5000; // 5 seconds - export const useTypingStatusUpdater = (mx: MatrixClient, roomId: string): TypingStatusUpdater => { const statusSentTsRef = useRef(0); diff --git a/src/app/molecules/space-add-existing/SpaceAddExisting.jsx b/src/app/molecules/space-add-existing/SpaceAddExisting.jsx index a9de7bdb9..547c0af5b 100644 --- a/src/app/molecules/space-add-existing/SpaceAddExisting.jsx +++ b/src/app/molecules/space-add-existing/SpaceAddExisting.jsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect } from 'react'; +import React, { useState, useEffect, useCallback } from 'react'; import PropTypes from 'prop-types'; import './SpaceAddExisting.scss'; @@ -25,7 +25,7 @@ import SearchIC from '../../../../public/res/ic/outlined/search.svg'; import { useStore } from '../../hooks/useStore'; -function SpaceAddExistingContent({ roomId }) { +function SpaceAddExistingContent({ roomId, spaces: onlySpaces }) { const mountStore = useStore(roomId); const [debounce] = useState(new Debounce()); const [process, setProcess] = useState(null); @@ -33,16 +33,15 @@ function SpaceAddExistingContent({ roomId }) { const [selected, setSelected] = useState([]); const [searchIds, setSearchIds] = useState(null); const mx = initMatrix.matrixClient; - const { - spaces, rooms, directs, roomIdToParents, - } = initMatrix.roomList; + const { spaces, rooms, directs, roomIdToParents } = initMatrix.roomList; useEffect(() => { - const allIds = [...spaces, ...rooms, ...directs].filter((rId) => ( - rId !== roomId && !roomIdToParents.get(rId)?.has(roomId) - )); + const roomIds = onlySpaces ? [...spaces] : [...rooms, ...directs]; + const allIds = roomIds.filter( + (rId) => rId !== roomId && !roomIdToParents.get(rId)?.has(roomId) + ); setAllRoomIds(allIds); - }, [roomId]); + }, [roomId, onlySpaces]); const toggleSelection = (rId) => { if (process !== null) return; @@ -68,20 +67,26 @@ function SpaceAddExistingContent({ roomId }) { via.push(getIdServer(rId)); } - return mx.sendStateEvent(roomId, 'm.space.child', { - auto_join: false, - suggested: false, - via, - }, rId); + return mx.sendStateEvent( + roomId, + 'm.space.child', + { + auto_join: false, + suggested: false, + via, + }, + rId + ); }); mountStore.setItem(true); await Promise.allSettled(promises); if (mountStore.getItem() !== true) return; - const allIds = [...spaces, ...rooms, ...directs].filter((rId) => ( - rId !== roomId && !roomIdToParents.get(rId)?.has(roomId) && !selected.includes(rId) - )); + const roomIds = onlySpaces ? [...spaces] : [...rooms, ...directs]; + const allIds = roomIds.filter( + (rId) => rId !== roomId && !roomIdToParents.get(rId)?.has(roomId) && !selected.includes(rId) + ); setAllRoomIds(allIds); setProcess(null); setSelected([]); @@ -98,9 +103,7 @@ function SpaceAddExistingContent({ roomId }) { const searchedIds = allRoomIds.filter((rId) => { let name = mx.getRoom(rId)?.name; if (!name) return false; - name = name.normalize('NFKC') - .toLocaleLowerCase() - .replace(/\s/g, ''); + name = name.normalize('NFKC').toLocaleLowerCase().replace(/\s/g, ''); return name.includes(term); }); setSearchIds(searchedIds); @@ -114,66 +117,64 @@ function SpaceAddExistingContent({ roomId }) { return ( <> -
      { ev.preventDefault(); }}> + { + ev.preventDefault(); + }} + > - + {searchIds?.length === 0 && No results found} - { - (searchIds || allRoomIds).map((rId) => { - const room = mx.getRoom(rId); - let imageSrc = room.getAvatarFallbackMember()?.getAvatarUrl(mx.baseUrl, 24, 24, 'crop') || null; - if (imageSrc === null) imageSrc = room.getAvatarUrl(mx.baseUrl, 24, 24, 'crop') || null; + {(searchIds || allRoomIds).map((rId) => { + const room = mx.getRoom(rId); + let imageSrc = + room.getAvatarFallbackMember()?.getAvatarUrl(mx.baseUrl, 24, 24, 'crop') || null; + if (imageSrc === null) imageSrc = room.getAvatarUrl(mx.baseUrl, 24, 24, 'crop') || null; - const parentSet = roomIdToParents.get(rId); - const parentNames = parentSet - ? [...parentSet].map((parentId) => mx.getRoom(parentId).name) - : undefined; - const parents = parentNames ? parentNames.join(', ') : null; + const parentSet = roomIdToParents.get(rId); + const parentNames = parentSet + ? [...parentSet].map((parentId) => mx.getRoom(parentId).name) + : undefined; + const parents = parentNames ? parentNames.join(', ') : null; - const handleSelect = () => toggleSelection(rId); + const handleSelect = () => toggleSelection(rId); - return ( - - )} - /> - ); - }) - } + return ( + + } + /> + ); + })} {selected.length !== 0 && (
      {process && } {process || `${selected.length} item selected`} - { !process && ( - + {!process && ( + )}
      )} @@ -182,47 +183,51 @@ function SpaceAddExistingContent({ roomId }) { } SpaceAddExistingContent.propTypes = { roomId: PropTypes.string.isRequired, + spaces: PropTypes.bool.isRequired, }; function useVisibilityToggle() { - const [roomId, setRoomId] = useState(null); + const [data, setData] = useState(null); useEffect(() => { - const handleOpen = (rId) => setRoomId(rId); + const handleOpen = (roomId, spaces) => + setData({ + roomId, + spaces, + }); navigation.on(cons.events.navigation.SPACE_ADDEXISTING_OPENED, handleOpen); return () => { navigation.removeListener(cons.events.navigation.SPACE_ADDEXISTING_OPENED, handleOpen); }; }, []); - const requestClose = () => setRoomId(null); + const requestClose = () => setData(null); - return [roomId, requestClose]; + return [data, requestClose]; } function SpaceAddExisting() { - const [roomId, requestClose] = useVisibilityToggle(); + const [data, requestClose] = useVisibilityToggle(); const mx = initMatrix.matrixClient; - const room = mx.getRoom(roomId); + const room = mx.getRoom(data?.roomId); return ( - {roomId && twemojify(room.name)} - — add existing rooms + {room && twemojify(room.name)} + + {' '} + — add existing {data?.spaces ? 'spaces' : 'rooms'} + - )} + } contentOptions={} onRequestClose={requestClose} > - { - roomId - ? - :
      - } + {room ? :
      }
      ); } diff --git a/src/app/organisms/navigation/Drawer.jsx b/src/app/organisms/navigation/Drawer.jsx index fb75ee5b1..0795e4692 100644 --- a/src/app/organisms/navigation/Drawer.jsx +++ b/src/app/organisms/navigation/Drawer.jsx @@ -72,16 +72,16 @@ function Drawer() {
      - { - selectedTab !== cons.tabs.DIRECTS - ? - : - } + {selectedTab !== cons.tabs.DIRECTS ? ( + + ) : ( + + )}
      - { systemState !== null && ( + {systemState !== null && (
      {systemState.status}
      diff --git a/src/app/organisms/navigation/Sidebar1.tsx b/src/app/organisms/navigation/Sidebar1.tsx deleted file mode 100644 index d9ee4662b..000000000 --- a/src/app/organisms/navigation/Sidebar1.tsx +++ /dev/null @@ -1,125 +0,0 @@ -import React from 'react'; -import { Icon, Icons, Badge, AvatarFallback, Text } from 'folds'; -import { useAtom } from 'jotai'; - -import { - Sidebar, - SidebarContent, - SidebarStackSeparator, - SidebarStack, - SidebarAvatar, -} from '../../components/sidebar'; -import { selectedTabAtom, SidebarTab } from '../../state/selectedTab'; - -export function Sidebar1() { - const [selectedTab, setSelectedTab] = useAtom(selectedTabAtom); - - return ( - - - - } - onClick={() => setSelectedTab(SidebarTab.Home)} - /> - } - onClick={() => setSelectedTab(SidebarTab.People)} - /> - - - - ( - - )} - avatarChildren={ - - B - - } - /> - ( - - 64 - - )} - avatarChildren={ - - C - - } - /> - - - - } - /> - } - /> - - - } - sticky={ - <> - - - } - /> - - A - - } - /> - - - } - /> - - ); -} diff --git a/src/app/organisms/pw/Windows.jsx b/src/app/organisms/pw/Windows.jsx index ba80f132d..835b70334 100644 --- a/src/app/organisms/pw/Windows.jsx +++ b/src/app/organisms/pw/Windows.jsx @@ -9,14 +9,18 @@ import InviteUser from '../invite-user/InviteUser'; import Settings from '../settings/Settings'; import SpaceSettings from '../space-settings/SpaceSettings'; import SpaceManage from '../space-manage/SpaceManage'; +import RoomSettings from '../room/RoomSettings'; function Windows() { const [isInviteList, changeInviteList] = useState(false); const [publicRooms, changePublicRooms] = useState({ - isOpen: false, searchTerm: undefined, + isOpen: false, + searchTerm: undefined, }); const [inviteUser, changeInviteUser] = useState({ - isOpen: false, roomId: undefined, term: undefined, + isOpen: false, + roomId: undefined, + term: undefined, }); function openInviteList() { @@ -49,10 +53,7 @@ function Windows() { return ( <> - changeInviteList(false)} - /> + changeInviteList(false)} /> + ); diff --git a/src/app/organisms/room/Room.scss b/src/app/organisms/room/Room.scss index 11a00074d..69f8f9dd3 100644 --- a/src/app/organisms/room/Room.scss +++ b/src/app/organisms/room/Room.scss @@ -4,6 +4,7 @@ .room { @extend .cp-fx__row; height: 100%; + flex-grow: 1; &__content { @extend .cp-fx__item-one; diff --git a/src/app/organisms/room/Room.tsx b/src/app/organisms/room/Room.tsx deleted file mode 100644 index 6158547c3..000000000 --- a/src/app/organisms/room/Room.tsx +++ /dev/null @@ -1,46 +0,0 @@ -import React from 'react'; -import './Room.scss'; -import { Room } from 'matrix-js-sdk'; -import { Line } from 'folds'; - -import RoomView from './RoomView'; -import RoomSettings from './RoomSettings'; -import { MembersDrawer } from './MembersDrawer'; -import { ScreenSize, useScreenSize } from '../../hooks/useScreenSize'; -import { useSetting } from '../../state/hooks/settings'; -import { settingsAtom } from '../../state/settings'; -import { PowerLevelsContextProvider, usePowerLevels } from '../../hooks/usePowerLevels'; -import { - roomIdToTypingMembersAtom, - useBindRoomIdToTypingMembersAtom, -} from '../../state/typingMembers'; - -export type RoomBaseViewProps = { - room: Room; - eventId?: string; -}; -export function RoomBaseView({ room, eventId }: RoomBaseViewProps) { - useBindRoomIdToTypingMembersAtom(room.client, roomIdToTypingMembersAtom); - - const [isDrawer] = useSetting(settingsAtom, 'isPeopleDrawer'); - const [screenSize] = useScreenSize(); - const powerLevelAPI = usePowerLevels(room); - - return ( - -
      -
      - - -
      - - {screenSize === ScreenSize.Desktop && isDrawer && ( - <> - - - - )} -
      -
      - ); -} diff --git a/src/app/organisms/room/RoomSettings.jsx b/src/app/organisms/room/RoomSettings.jsx index 632773471..1e617ae7e 100644 --- a/src/app/organisms/room/RoomSettings.jsx +++ b/src/app/organisms/room/RoomSettings.jsx @@ -2,22 +2,15 @@ import React, { useState, useEffect } from 'react'; import PropTypes from 'prop-types'; import './RoomSettings.scss'; -import { blurOnBubbling } from '../../atoms/button/script'; - import initMatrix from '../../../client/initMatrix'; import cons from '../../../client/state/cons'; import navigation from '../../../client/state/navigation'; -import { openInviteUser, toggleRoomSettings } from '../../../client/action/navigation'; import * as roomActions from '../../../client/action/room'; import Text from '../../atoms/text/Text'; -import RawIcon from '../../atoms/system-icons/RawIcon'; -import Header, { TitleWrapper } from '../../atoms/header/Header'; -import ScrollView from '../../atoms/scroll/ScrollView'; import Tabs from '../../atoms/tabs/Tabs'; import { MenuHeader, MenuItem } from '../../atoms/context-menu/ContextMenu'; import RoomProfile from '../../molecules/room-profile/RoomProfile'; -import RoomSearch from '../../molecules/room-search/RoomSearch'; import RoomNotification from '../../molecules/room-notification/RoomNotification'; import RoomVisibility from '../../molecules/room-visibility/RoomVisibility'; import RoomAliases from '../../molecules/room-aliases/RoomAliases'; @@ -30,67 +23,59 @@ import RoomEmojis from '../../molecules/room-emojis/RoomEmojis'; import UserIC from '../../../../public/res/ic/outlined/user.svg'; import SettingsIC from '../../../../public/res/ic/outlined/settings.svg'; import EmojiIC from '../../../../public/res/ic/outlined/emoji.svg'; -import SearchIC from '../../../../public/res/ic/outlined/search.svg'; import ShieldUserIC from '../../../../public/res/ic/outlined/shield-user.svg'; import LockIC from '../../../../public/res/ic/outlined/lock.svg'; -import AddUserIC from '../../../../public/res/ic/outlined/add-user.svg'; import LeaveArrowIC from '../../../../public/res/ic/outlined/leave-arrow.svg'; -import ChevronTopIC from '../../../../public/res/ic/outlined/chevron-top.svg'; +import CrossIC from '../../../../public/res/ic/outlined/cross.svg'; -import { useForceUpdate } from '../../hooks/useForceUpdate'; import { confirmDialog } from '../../molecules/confirm-dialog/ConfirmDialog'; +import PopupWindow from '../../molecules/popup-window/PopupWindow'; +import IconButton from '../../atoms/button/IconButton'; const tabText = { GENERAL: 'General', - SEARCH: 'Search', MEMBERS: 'Members', EMOJIS: 'Emojis', PERMISSIONS: 'Permissions', SECURITY: 'Security', }; -const tabItems = [{ - iconSrc: SettingsIC, - text: tabText.GENERAL, - disabled: false, -}, { - iconSrc: SearchIC, - text: tabText.SEARCH, - disabled: false, -}, { - iconSrc: UserIC, - text: tabText.MEMBERS, - disabled: false, -}, { - iconSrc: EmojiIC, - text: tabText.EMOJIS, - disabled: false, -}, { - iconSrc: ShieldUserIC, - text: tabText.PERMISSIONS, - disabled: false, -}, { - iconSrc: LockIC, - text: tabText.SECURITY, - disabled: false, -}]; +const tabItems = [ + { + iconSrc: SettingsIC, + text: tabText.GENERAL, + disabled: false, + }, + { + iconSrc: UserIC, + text: tabText.MEMBERS, + disabled: false, + }, + { + iconSrc: EmojiIC, + text: tabText.EMOJIS, + disabled: false, + }, + { + iconSrc: ShieldUserIC, + text: tabText.PERMISSIONS, + disabled: false, + }, + { + iconSrc: LockIC, + text: tabText.SECURITY, + disabled: false, + }, +]; function GeneralSettings({ roomId }) { const mx = initMatrix.matrixClient; const room = mx.getRoom(roomId); - const canInvite = room.canInvite(mx.getUserId()); return ( <>
      Options - openInviteUser(roomId)} - iconSrc={AddUserIC} - > - Invite - { @@ -98,7 +83,7 @@ function GeneralSettings({ roomId }) { 'Leave room', `Are you sure that you want to leave "${room.name}" room?`, 'Leave', - 'danger', + 'danger' ); if (!isConfirmed) return; roomActions.leave(roomId); @@ -146,54 +131,52 @@ SecuritySettings.propTypes = { roomId: PropTypes.string.isRequired, }; -function RoomSettings({ roomId }) { - const [, forceUpdate] = useForceUpdate(); +function useWindowToggle(setSelectedTab) { + const [window, setWindow] = useState(null); + + useEffect(() => { + const openRoomSettings = (roomId, tab) => { + setWindow({ roomId, tabText }); + const tabItem = tabItems.find((item) => item.text === tab); + if (tabItem) setSelectedTab(tabItem); + }; + navigation.on(cons.events.navigation.ROOM_SETTINGS_TOGGLED, openRoomSettings); + return () => { + navigation.removeListener(cons.events.navigation.ROOM_SETTINGS_TOGGLED, openRoomSettings); + }; + }, [setSelectedTab]); + + const requestClose = () => setWindow(null); + + return [window, requestClose]; +} + +function RoomSettings() { const [selectedTab, setSelectedTab] = useState(tabItems[0]); + const [window, requestClose] = useWindowToggle(setSelectedTab); + const isOpen = window !== null; + const roomId = window?.roomId; const room = initMatrix.matrixClient.getRoom(roomId); const handleTabChange = (tabItem) => { setSelectedTab(tabItem); }; - useEffect(() => { - let mounted = true; - const settingsToggle = (isVisible, tab) => { - if (!mounted) return; - if (isVisible) { - const tabItem = tabItems.find((item) => item.text === tab); - if (tabItem) setSelectedTab(tabItem); - forceUpdate(); - } else setTimeout(() => forceUpdate(), 200); - }; - navigation.on(cons.events.navigation.ROOM_SETTINGS_TOGGLED, settingsToggle); - return () => { - mounted = false; - navigation.removeListener(cons.events.navigation.ROOM_SETTINGS_TOGGLED, settingsToggle); - }; - }, []); - - if (!navigation.isRoomSettings) return null; - return ( -
      - + + {isOpen && room.name} + — room settings + + } + contentOptions={} + onRequestClose={requestClose} + > + {isOpen && (
      -
      - -
      {selectedTab.text === tabText.GENERAL && } - {selectedTab.text === tabText.SEARCH && } {selectedTab.text === tabText.MEMBERS && } {selectedTab.text === tabText.EMOJIS && } {selectedTab.text === tabText.PERMISSIONS && } {selectedTab.text === tabText.SECURITY && }
      -
      -
      + )} + ); } -RoomSettings.propTypes = { - roomId: PropTypes.string.isRequired, -}; - export default RoomSettings; export { tabText }; diff --git a/src/app/organisms/room/RoomSettings.scss b/src/app/organisms/room/RoomSettings.scss index ab7fca5c8..fd3af501c 100644 --- a/src/app/organisms/room/RoomSettings.scss +++ b/src/app/organisms/room/RoomSettings.scss @@ -2,59 +2,18 @@ @use '../../partials/flex'; .room-settings { - height: 100%; - & .scrollbar { - position: relative; - } - - & .header { - padding: 0 var(--sp-extra-tight); - } - - &__header-btn { - min-width: 0; - @extend .cp-fx__row--s-c; - @include dir.side(margin, 0, auto); - padding: var(--sp-ultra-tight) var(--sp-extra-tight); - border-radius: calc(var(--bo-radius) / 2); - cursor: pointer; - - @media (hover:hover) { - &:hover { - background-color: var(--bg-surface-hover); - box-shadow: var(--bs-surface-outline); - } - } - &:focus, - &:active { - background-color: var(--bg-surface-active); - box-shadow: var(--bs-surface-outline); - outline: none; - } - } - - &__content { - padding-bottom: calc(2 * var(--sp-extra-loose)); - - & .room-profile { - margin: var(--sp-extra-loose); - } - } - - & .tabs { - position: sticky; - top: 0; - z-index: 999; - width: 100%; + & .pw { background-color: var(--bg-surface-low); - box-shadow: 0 -4px 0 var(--bg-surface-low), - inset 0 -1px 0 var(--bg-surface-border); - - &__content { - padding: 0 var(--sp-normal); - } } - + + & .room-profile { + padding: var(--sp-loose) var(--sp-extra-loose); + } + + & .tabs__content { + padding: 0 var(--sp-normal); + } + &__cards-wrapper { padding: 0 var(--sp-normal); @include dir.side(padding, var(--sp-normal), var(--sp-extra-tight)); @@ -75,7 +34,7 @@ .room-settings .room-permissions__card, .room-settings .room-search__form, -.room-settings .room-search__result-item , +.room-settings .room-search__result-item, .room-settings .room-members { @extend .room-settings__card; -} \ No newline at end of file +} diff --git a/src/app/organisms/room/RoomView.jsx b/src/app/organisms/room/RoomView.jsx deleted file mode 100644 index 9d97cb605..000000000 --- a/src/app/organisms/room/RoomView.jsx +++ /dev/null @@ -1,118 +0,0 @@ -import React, { useEffect, useRef } from 'react'; -import PropTypes from 'prop-types'; -import './RoomView.scss'; -import { Text, config } from 'folds'; -import { EventType } from 'matrix-js-sdk'; - -import cons from '../../../client/state/cons'; -import navigation from '../../../client/state/navigation'; - -import RoomViewHeader from './RoomViewHeader'; -import { RoomInput } from './RoomInput'; -import { useStateEvent } from '../../hooks/useStateEvent'; -import { StateEvent } from '../../../types/matrix/room'; -import { RoomTombstone } from './RoomTombstone'; -import { usePowerLevelsAPI } from '../../hooks/usePowerLevels'; -import { useMatrixClient } from '../../hooks/useMatrixClient'; -import { RoomInputPlaceholder } from './RoomInputPlaceholder'; -import { RoomTimeline } from './RoomTimeline'; -import { RoomViewTyping } from './RoomViewTyping'; -import { RoomViewFollowing } from './RoomViewFollowing'; -import { useEditor } from '../../components/editor'; - -function RoomView({ room, eventId }) { - const roomInputRef = useRef(null); - const roomViewRef = useRef(null); - - // eslint-disable-next-line react/prop-types - const { roomId } = room; - const editor = useEditor(); - - const mx = useMatrixClient(); - const tombstoneEvent = useStateEvent(room, StateEvent.RoomTombstone); - const { getPowerLevel, canSendEvent } = usePowerLevelsAPI(); - const myUserId = mx.getUserId(); - const canMessage = myUserId - ? canSendEvent(EventType.RoomMessage, getPowerLevel(myUserId)) - : false; - - useEffect(() => { - const settingsToggle = (isVisible) => { - const roomView = roomViewRef.current; - roomView.classList.toggle('room-view--dropped'); - - const roomViewContent = roomView.children[1]; - if (isVisible) { - setTimeout(() => { - if (!navigation.isRoomSettings) return; - roomViewContent.style.visibility = 'hidden'; - }, 200); - } else roomViewContent.style.visibility = 'visible'; - }; - navigation.on(cons.events.navigation.ROOM_SETTINGS_TOGGLED, settingsToggle); - return () => { - navigation.removeListener(cons.events.navigation.ROOM_SETTINGS_TOGGLED, settingsToggle); - }; - }, []); - - return ( -
      - -
      -
      - - -
      -
      -
      - {tombstoneEvent ? ( - - ) : ( - <> - {canMessage && ( - - )} - {!canMessage && ( - - You do not have permission to post in this room - - )} - - )} -
      - -
      -
      -
      - ); -} - -RoomView.defaultProps = { - eventId: null, -}; -RoomView.propTypes = { - room: PropTypes.shape({}).isRequired, - eventId: PropTypes.string, -}; - -export default RoomView; diff --git a/src/app/organisms/room/RoomViewTyping.tsx b/src/app/organisms/room/RoomViewTyping.tsx deleted file mode 100644 index c393f3aee..000000000 --- a/src/app/organisms/room/RoomViewTyping.tsx +++ /dev/null @@ -1,118 +0,0 @@ -import React, { useMemo } from 'react'; -import { Box, Icon, IconButton, Icons, Text, as } from 'folds'; -import { Room } from 'matrix-js-sdk'; -import classNames from 'classnames'; -import { useAtomValue, useSetAtom } from 'jotai'; -import { roomIdToTypingMembersAtom, selectRoomTypingMembersAtom } from '../../state/typingMembers'; -import { TypingIndicator } from '../../components/typing-indicator'; -import { getMemberDisplayName } from '../../utils/room'; -import { getMxIdLocalPart } from '../../utils/matrix'; -import * as css from './RoomViewTyping.css'; -import { useMatrixClient } from '../../hooks/useMatrixClient'; - -export type RoomViewTypingProps = { - room: Room; -}; -export const RoomViewTyping = as<'div', RoomViewTypingProps>( - ({ className, room, ...props }, ref) => { - const setTypingMembers = useSetAtom(roomIdToTypingMembersAtom); - const mx = useMatrixClient(); - const typingMembers = useAtomValue( - useMemo(() => selectRoomTypingMembersAtom(room.roomId, roomIdToTypingMembersAtom), [room]) - ); - - const typingNames = typingMembers - .filter((member) => member.userId !== mx.getUserId()) - .map((member) => getMemberDisplayName(room, member.userId) ?? getMxIdLocalPart(member.userId)) - .reverse(); - - if (typingNames.length === 0) { - return null; - } - - const handleDropAll = () => { - // some homeserver does not timeout typing status - // we have given option so user can drop their typing status - typingMembers.forEach((member) => - setTypingMembers({ - type: 'DELETE', - roomId: room.roomId, - member, - }) - ); - }; - - return ( - - - - {typingNames.length === 1 && ( - <> - {typingNames[0]} - - {' is typing...'} - - - )} - {typingNames.length === 2 && ( - <> - {typingNames[0]} - - {' and '} - - {typingNames[1]} - - {' are typing...'} - - - )} - {typingNames.length === 3 && ( - <> - {typingNames[0]} - - {', '} - - {typingNames[1]} - - {' and '} - - {typingNames[2]} - - {' are typing...'} - - - )} - {typingNames.length > 3 && ( - <> - {typingNames[0]} - - {', '} - - {typingNames[1]} - - {', '} - - {typingNames[2]} - - {' and '} - - {typingNames.length - 3} others - - {' are typing...'} - - - )} - - - - - - ); - } -); diff --git a/src/app/organisms/room/message/AudioContent.tsx b/src/app/organisms/room/message/AudioContent.tsx deleted file mode 100644 index 83e5dc010..000000000 --- a/src/app/organisms/room/message/AudioContent.tsx +++ /dev/null @@ -1,194 +0,0 @@ -/* eslint-disable jsx-a11y/media-has-caption */ -import { Badge, Chip, Icon, IconButton, Icons, ProgressBar, Spinner, Text, as, toRem } from 'folds'; -import React, { useCallback, useRef, useState } from 'react'; -import { EncryptedAttachmentInfo } from 'browser-encrypt-attachment'; -import { Range } from 'react-range'; -import { useMatrixClient } from '../../../hooks/useMatrixClient'; -import { AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback'; -import { getFileSrcUrl } from './util'; -import { IAudioInfo } from '../../../../types/matrix/common'; -import { MediaControl } from '../../../components/media'; -import { - PlayTimeCallback, - useMediaLoading, - useMediaPlay, - useMediaPlayTimeCallback, - useMediaSeek, - useMediaVolume, -} from '../../../hooks/media'; -import { useThrottle } from '../../../hooks/useThrottle'; -import { secondsToMinutesAndSeconds } from '../../../utils/common'; - -const PLAY_TIME_THROTTLE_OPS = { - wait: 500, - immediate: true, -}; - -export type AudioContentProps = { - mimeType: string; - url: string; - info: IAudioInfo; - encInfo?: EncryptedAttachmentInfo; -}; -export const AudioContent = as<'div', AudioContentProps>( - ({ mimeType, url, info, encInfo, ...props }, ref) => { - const mx = useMatrixClient(); - - const [srcState, loadSrc] = useAsyncCallback( - useCallback( - () => getFileSrcUrl(mx.mxcUrlToHttp(url) ?? '', mimeType, encInfo), - [mx, url, mimeType, encInfo] - ) - ); - - const audioRef = useRef(null); - - const [currentTime, setCurrentTime] = useState(0); - // duration in seconds. (NOTE: info.duration is in milliseconds) - const infoDuration = info.duration ?? 0; - const [duration, setDuration] = useState((infoDuration >= 0 ? infoDuration : 0) / 1000); - - const getAudioRef = useCallback(() => audioRef.current, []); - const { loading } = useMediaLoading(getAudioRef); - const { playing, setPlaying } = useMediaPlay(getAudioRef); - const { seek } = useMediaSeek(getAudioRef); - const { volume, mute, setMute, setVolume } = useMediaVolume(getAudioRef); - const handlePlayTimeCallback: PlayTimeCallback = useCallback((d, ct) => { - setDuration(d); - setCurrentTime(ct); - }, []); - useMediaPlayTimeCallback( - getAudioRef, - useThrottle(handlePlayTimeCallback, PLAY_TIME_THROTTLE_OPS) - ); - - const handlePlay = () => { - if (srcState.status === AsyncStatus.Success) { - setPlaying(!playing); - } else if (srcState.status !== AsyncStatus.Loading) { - loadSrc(); - } - }; - - return ( - seek(values[0])} - renderTrack={(params) => ( -
      - {params.children} - -
      - )} - renderThumb={(params) => ( - - )} - /> - } - leftControl={ - <> - - ) : ( - - ) - } - > - {playing ? 'Pause' : 'Play'} - - - {`${secondsToMinutesAndSeconds( - currentTime - )} / ${secondsToMinutesAndSeconds(duration)}`} - - } - rightControl={ - <> - setMute(!mute)} - aria-pressed={mute} - > - - - setVolume(values[0])} - renderTrack={(params) => ( -
      - {params.children} - -
      - )} - renderThumb={(params) => ( - - )} - /> - - } - {...props} - ref={ref} - > - -
      - ); - } -); diff --git a/src/app/organisms/room/message/StickerContent.tsx b/src/app/organisms/room/message/StickerContent.tsx deleted file mode 100644 index 49b8b8d1c..000000000 --- a/src/app/organisms/room/message/StickerContent.tsx +++ /dev/null @@ -1,48 +0,0 @@ -import React from 'react'; -import { as, toRem } from 'folds'; -import { MatrixEvent } from 'matrix-js-sdk'; -import { - AttachmentBox, - MessageBrokenContent, - MessageDeletedContent, -} from '../../../components/message'; -import { ImageContent } from './ImageContent'; -import { scaleYDimension } from '../../../utils/common'; -import { IImageContent } from '../../../../types/matrix/common'; - -type StickerContentProps = { - mEvent: MatrixEvent; - autoPlay: boolean; -}; -export const StickerContent = as<'div', StickerContentProps>( - ({ mEvent, autoPlay, ...props }, ref) => { - if (mEvent.isRedacted()) return ; - const content = mEvent.getContent(); - const imgInfo = content?.info; - const mxcUrl = content.file?.url ?? content.url; - if (typeof mxcUrl !== 'string') { - return ; - } - const height = scaleYDimension(imgInfo?.w || 152, 152, imgInfo?.h || 152); - - return ( - - - - ); - } -); diff --git a/src/app/organisms/room/message/fileRenderer.tsx b/src/app/organisms/room/message/fileRenderer.tsx deleted file mode 100644 index 5ff70b330..000000000 --- a/src/app/organisms/room/message/fileRenderer.tsx +++ /dev/null @@ -1,45 +0,0 @@ -import React from 'react'; -import { MatrixEvent } from 'matrix-js-sdk'; -import { IFileContent } from '../../../../types/matrix/common'; -import { - Attachment, - AttachmentBox, - AttachmentContent, - AttachmentHeader, -} from '../../../components/message'; -import { FileHeader } from './FileHeader'; -import { FileContent } from './FileContent'; -import { FALLBACK_MIMETYPE } from '../../../utils/mimeTypes'; - -export const fileRenderer = (mEventId: string, mEvent: MatrixEvent) => { - const content = mEvent.getContent(); - - const fileInfo = content?.info; - const mxcUrl = content.file?.url ?? content.url; - - if (typeof mxcUrl !== 'string') { - return null; - } - - return ( - - - - - - - - - - - ); -}; diff --git a/src/app/organisms/room/message/index.ts b/src/app/organisms/room/message/index.ts deleted file mode 100644 index d89086164..000000000 --- a/src/app/organisms/room/message/index.ts +++ /dev/null @@ -1,10 +0,0 @@ -export * from './ImageContent'; -export * from './VideoContent'; -export * from './FileHeader'; -export * from './fileRenderer'; -export * from './AudioContent'; -export * from './Reactions'; -export * from './EventContent'; -export * from './Message'; -export * from './EncryptedContent'; -export * from './StickerContent'; diff --git a/src/app/organisms/room/message/styles.css.ts b/src/app/organisms/room/message/styles.css.ts deleted file mode 100644 index d42cf05bf..000000000 --- a/src/app/organisms/room/message/styles.css.ts +++ /dev/null @@ -1,131 +0,0 @@ -import { style } from '@vanilla-extract/css'; -import { recipe } from '@vanilla-extract/recipes'; -import { DefaultReset, color, config, toRem } from 'folds'; - -export const RelativeBase = style([ - DefaultReset, - { - position: 'relative', - width: '100%', - height: '100%', - }, -]); - -export const AbsoluteContainer = style([ - DefaultReset, - { - position: 'absolute', - top: 0, - left: 0, - width: '100%', - height: '100%', - }, -]); - -export const AbsoluteFooter = style([ - DefaultReset, - { - position: 'absolute', - bottom: config.space.S100, - left: config.space.S100, - right: config.space.S100, - }, -]); - -export const ModalWide = style({ - minWidth: '85vw', - minHeight: '90vh', -}); - -export const MessageBase = style({ - position: 'relative', -}); - -export const MessageOptionsBase = style([ - DefaultReset, - { - position: 'absolute', - top: toRem(-30), - right: 0, - zIndex: 1, - }, -]); -export const MessageOptionsBar = style([ - DefaultReset, - { - padding: config.space.S100, - }, -]); - -export const MessageAvatar = style({ - cursor: 'pointer', -}); - -export const MessageQuickReaction = style({ - minWidth: toRem(32), -}); - -export const MessageMenuGroup = style({ - padding: config.space.S100, -}); - -export const MessageMenuItemText = style({ - flexGrow: 1, -}); - -export const ReactionsContainer = style({ - selectors: { - '&:empty': { - display: 'none', - }, - }, -}); - -export const ReactionsTooltipText = style({ - wordBreak: 'break-word', -}); - -export const UrlPreviewHolderGradient = recipe({ - base: [ - DefaultReset, - { - position: 'absolute', - height: '100%', - width: toRem(10), - zIndex: 1, - }, - ], - variants: { - position: { - Left: { - left: 0, - background: `linear-gradient(to right,${color.Surface.Container} , rgba(116,116,116,0))`, - }, - Right: { - right: 0, - background: `linear-gradient(to left,${color.Surface.Container} , rgba(116,116,116,0))`, - }, - }, - }, -}); -export const UrlPreviewHolderBtn = recipe({ - base: [ - DefaultReset, - { - position: 'absolute', - zIndex: 1, - }, - ], - variants: { - position: { - Left: { - left: 0, - transform: 'translateX(-25%)', - }, - Right: { - right: 0, - transform: 'translateX(25%)', - }, - }, - }, -}); diff --git a/src/app/organisms/search/Search.jsx b/src/app/organisms/search/Search.jsx index 64c898bfd..66b685114 100644 --- a/src/app/organisms/search/Search.jsx +++ b/src/app/organisms/search/Search.jsx @@ -5,7 +5,6 @@ import initMatrix from '../../../client/initMatrix'; import cons from '../../../client/state/cons'; import navigation from '../../../client/state/navigation'; import AsyncSearch from '../../../util/AsyncSearch'; -import { selectRoom, selectTab } from '../../../client/action/navigation'; import { joinRuleToIconSrc } from '../../../util/matrixUtil'; import { roomIdByActivity } from '../../../util/sort'; @@ -19,6 +18,7 @@ import RoomSelector from '../../molecules/room-selector/RoomSelector'; import SearchIC from '../../../../public/res/ic/outlined/search.svg'; import CrossIC from '../../../../public/res/ic/outlined/cross.svg'; +import { useRoomNavigate } from '../../hooks/useRoomNavigate'; function useVisiblityToggle(setResult) { const [isOpen, setIsOpen] = useState(false); @@ -64,13 +64,13 @@ function mapRoomIds(roomIds) { if (room.isSpaceRoom()) type = 'space'; else if (directs.has(roomId)) type = 'direct'; - return ({ + return { type, name: room.name, parents, roomId, room, - }); + }; }); } @@ -80,6 +80,7 @@ function Search() { const [isOpen, requestClose] = useVisiblityToggle(setResult); const searchRef = useRef(null); const mx = initMatrix.matrixClient; + const { navigateRoom, navigateSpace } = useRoomNavigate(); const handleSearchResults = (chunk, term) => { setResult({ @@ -155,8 +156,8 @@ function Search() { }; const openItem = (roomId, type) => { - if (type === 'space') selectTab(roomId); - else selectRoom(roomId); + if (type === 'space') navigateSpace(roomId); + else navigateRoom(roomId); requestClose(); }; @@ -173,7 +174,8 @@ function Search() { let imageSrc = null; let iconSrc = null; if (item.type === 'direct') { - imageSrc = item.room.getAvatarFallbackMember()?.getAvatarUrl(mx.baseUrl, 24, 24, 'crop') || null; + imageSrc = + item.room.getAvatarFallbackMember()?.getAvatarUrl(mx.baseUrl, 24, 24, 'crop') || null; } else { iconSrc = joinRuleToIconSrc(item.room.getJoinRule(), item.type === 'space'); } @@ -204,19 +206,21 @@ function Search() { size="small" >
      -
      { e.preventDefault(); openFirstResult(); }}> + { + e.preventDefault(); + openFirstResult(); + }} + > - +
      - { Array.isArray(result?.chunk) && result.chunk.map(renderRoomSelector) } + {Array.isArray(result?.chunk) && result.chunk.map(renderRoomSelector)}
      diff --git a/src/app/organisms/space-settings/SpaceSettings.jsx b/src/app/organisms/space-settings/SpaceSettings.jsx index 2c9d6d461..46fe7b3f7 100644 --- a/src/app/organisms/space-settings/SpaceSettings.jsx +++ b/src/app/organisms/space-settings/SpaceSettings.jsx @@ -8,12 +8,6 @@ import initMatrix from '../../../client/initMatrix'; import cons from '../../../client/state/cons'; import navigation from '../../../client/state/navigation'; import { leave } from '../../../client/action/room'; -import { - createSpaceShortcut, - deleteSpaceShortcut, - categorizeSpace, - unCategorizeSpace, -} from '../../../client/action/accountData'; import Text from '../../atoms/text/Text'; import IconButton from '../../atoms/button/IconButton'; @@ -32,14 +26,9 @@ import CrossIC from '../../../../public/res/ic/outlined/cross.svg'; import SettingsIC from '../../../../public/res/ic/outlined/settings.svg'; import ShieldUserIC from '../../../../public/res/ic/outlined/shield-user.svg'; import LeaveArrowIC from '../../../../public/res/ic/outlined/leave-arrow.svg'; -import PinIC from '../../../../public/res/ic/outlined/pin.svg'; -import PinFilledIC from '../../../../public/res/ic/filled/pin.svg'; -import CategoryIC from '../../../../public/res/ic/outlined/category.svg'; -import CategoryFilledIC from '../../../../public/res/ic/filled/category.svg'; import EmojiIC from '../../../../public/res/ic/outlined/emoji.svg'; import { confirmDialog } from '../../molecules/confirm-dialog/ConfirmDialog'; -import { useForceUpdate } from '../../hooks/useForceUpdate'; const tabText = { GENERAL: 'General', @@ -48,54 +37,36 @@ const tabText = { PERMISSIONS: 'Permissions', }; -const tabItems = [{ - iconSrc: SettingsIC, - text: tabText.GENERAL, - disabled: false, -}, { - iconSrc: UserIC, - text: tabText.MEMBERS, - disabled: false, -}, { - iconSrc: EmojiIC, - text: tabText.EMOJIS, - disabled: false, -}, { - iconSrc: ShieldUserIC, - text: tabText.PERMISSIONS, - disabled: false, -}]; +const tabItems = [ + { + iconSrc: SettingsIC, + text: tabText.GENERAL, + disabled: false, + }, + { + iconSrc: UserIC, + text: tabText.MEMBERS, + disabled: false, + }, + { + iconSrc: EmojiIC, + text: tabText.EMOJIS, + disabled: false, + }, + { + iconSrc: ShieldUserIC, + text: tabText.PERMISSIONS, + disabled: false, + }, +]; function GeneralSettings({ roomId }) { - const isPinned = initMatrix.accountData.spaceShortcut.has(roomId); - const isCategorized = initMatrix.accountData.categorizedSpaces.has(roomId); const roomName = initMatrix.matrixClient.getRoom(roomId)?.name; - const [, forceUpdate] = useForceUpdate(); return ( <>
      Options - { - if (isCategorized) unCategorizeSpace(roomId); - else categorizeSpace(roomId); - forceUpdate(); - }} - iconSrc={isCategorized ? CategoryFilledIC : CategoryIC} - > - {isCategorized ? 'Uncategorize subspaces' : 'Categorize subspaces'} - - { - if (isPinned) deleteSpaceShortcut(roomId); - else createSpaceShortcut(roomId); - forceUpdate(); - }} - iconSrc={isPinned ? PinFilledIC : PinIC} - > - {isPinned ? 'Unpin from sidebar' : 'Pin to sidebar'} - { @@ -103,7 +74,7 @@ function GeneralSettings({ roomId }) { 'Leave space', `Are you sure that you want to leave "${roomName}" space?`, 'Leave', - 'danger', + 'danger' ); if (isConfirmed) leave(roomId); }} @@ -165,12 +136,12 @@ function SpaceSettings() { {isOpen && twemojify(room.name)} — space settings - )} + } contentOptions={} onRequestClose={requestClose} > diff --git a/src/app/pages/App.tsx b/src/app/pages/App.tsx index 62c173f91..b16462dff 100644 --- a/src/app/pages/App.tsx +++ b/src/app/pages/App.tsx @@ -1,84 +1,43 @@ import React from 'react'; import { Provider as JotaiProvider } from 'jotai'; -import { - Route, - RouterProvider, - createBrowserRouter, - createHashRouter, - createRoutesFromElements, - redirect, -} from 'react-router-dom'; +import { RouterProvider } from 'react-router-dom'; +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; +import { ReactQueryDevtools } from '@tanstack/react-query-devtools'; import { ClientConfigLoader } from '../components/ClientConfigLoader'; -import { ClientConfig, ClientConfigProvider } from '../hooks/useClientConfig'; -import { AuthLayout, Login, Register, ResetPassword, authLayoutLoader } from './auth'; -import { LOGIN_PATH, REGISTER_PATH, RESET_PASSWORD_PATH, ROOT_PATH } from './paths'; -import { isAuthenticated } from '../../client/state/auth'; -import Client from '../templates/client/Client'; -import { getLoginPath } from './pathUtils'; +import { ClientConfigProvider } from '../hooks/useClientConfig'; import { ConfigConfigError, ConfigConfigLoading } from './ConfigConfig'; import { FeatureCheck } from './FeatureCheck'; +import { createRouter } from './Router'; +import { ScreenSizeProvider, useScreenSize } from '../hooks/useScreenSize'; -const createRouter = (clientConfig: ClientConfig) => { - const { hashRouter } = clientConfig; +const queryClient = new QueryClient(); - const routes = createRoutesFromElements( - - { - if (isAuthenticated()) return redirect('/home'); - return redirect(getLoginPath()); - }} - /> - }> - } /> - } /> - } /> - - - { - if (!isAuthenticated()) return redirect(getLoginPath()); - return null; - }} - > - } /> - direct

      } /> - :spaceIdOrAlias

      } /> - explore

      } /> -
      - Page not found

      } /> -
      - ); - - if (hashRouter?.enabled) { - return createHashRouter(routes, { basename: hashRouter.basename }); - } - return createBrowserRouter(routes, { - basename: import.meta.env.BASE_URL, - }); -}; - -// TODO: app crash boundary function App() { + const screenSize = useScreenSize(); + return ( - - } - error={(err, retry, ignore) => ( - - )} - > - {(clientConfig) => ( - - - - - - )} - - + + + } + error={(err, retry, ignore) => ( + + )} + > + {(clientConfig) => ( + + + + + + + + + )} + + + ); } diff --git a/src/app/pages/MobileFriendly.tsx b/src/app/pages/MobileFriendly.tsx new file mode 100644 index 000000000..ca947ac61 --- /dev/null +++ b/src/app/pages/MobileFriendly.tsx @@ -0,0 +1,44 @@ +import { ReactNode } from 'react'; +import { useMatch } from 'react-router-dom'; +import { ScreenSize, useScreenSizeContext } from '../hooks/useScreenSize'; +import { DIRECT_PATH, EXPLORE_PATH, HOME_PATH, INBOX_PATH, SPACE_PATH } from './paths'; + +type MobileFriendlyClientNavProps = { + children: ReactNode; +}; +export function MobileFriendlyClientNav({ children }: MobileFriendlyClientNavProps) { + const screenSize = useScreenSizeContext(); + const homeMatch = useMatch({ path: HOME_PATH, caseSensitive: true, end: true }); + const directMatch = useMatch({ path: DIRECT_PATH, caseSensitive: true, end: true }); + const spaceMatch = useMatch({ path: SPACE_PATH, caseSensitive: true, end: true }); + const exploreMatch = useMatch({ path: EXPLORE_PATH, caseSensitive: true, end: true }); + const inboxMatch = useMatch({ path: INBOX_PATH, caseSensitive: true, end: true }); + + if ( + screenSize === ScreenSize.Mobile && + !(homeMatch || directMatch || spaceMatch || exploreMatch || inboxMatch) + ) { + return null; + } + + return children; +} + +type MobileFriendlyPageNavProps = { + path: string; + children: ReactNode; +}; +export function MobileFriendlyPageNav({ path, children }: MobileFriendlyPageNavProps) { + const screenSize = useScreenSizeContext(); + const exactPath = useMatch({ + path, + caseSensitive: true, + end: true, + }); + + if (screenSize === ScreenSize.Mobile && !exactPath) { + return null; + } + + return children; +} diff --git a/src/app/pages/Router.tsx b/src/app/pages/Router.tsx new file mode 100644 index 000000000..ffa20d4ed --- /dev/null +++ b/src/app/pages/Router.tsx @@ -0,0 +1,269 @@ +import React from 'react'; +import { + Outlet, + Route, + createBrowserRouter, + createHashRouter, + createRoutesFromElements, + redirect, +} from 'react-router-dom'; + +import { ClientConfig } from '../hooks/useClientConfig'; +import { AuthLayout, Login, Register, ResetPassword } from './auth'; +import { + DIRECT_PATH, + EXPLORE_PATH, + HOME_PATH, + LOGIN_PATH, + INBOX_PATH, + REGISTER_PATH, + RESET_PASSWORD_PATH, + SPACE_PATH, + _CREATE_PATH, + _FEATURED_PATH, + _INVITES_PATH, + _JOIN_PATH, + _LOBBY_PATH, + _NOTIFICATIONS_PATH, + _ROOM_PATH, + _SEARCH_PATH, + _SERVER_PATH, +} from './paths'; +import { isAuthenticated } from '../../client/state/auth'; +import { + getAppPathFromHref, + getExploreFeaturedPath, + getHomePath, + getInboxNotificationsPath, + getLoginPath, + getOriginBaseUrl, + getSpaceLobbyPath, +} from './pathUtils'; +import { ClientBindAtoms, ClientLayout, ClientRoot } from './client'; +import { Home, HomeRouteRoomProvider, HomeSearch } from './client/home'; +import { Direct, DirectRouteRoomProvider } from './client/direct'; +import { RouteSpaceProvider, Space, SpaceRouteRoomProvider, SpaceSearch } from './client/space'; +import { Explore, FeaturedRooms, PublicRooms } from './client/explore'; +import { Notifications, Inbox, Invites } from './client/inbox'; +import { setAfterLoginRedirectPath } from './afterLoginRedirectPath'; +import { Room } from '../features/room'; +import { Lobby } from '../features/lobby'; +import { WelcomePage } from './client/WelcomePage'; +import { SidebarNav } from './client/SidebarNav'; +import { PageRoot } from '../components/page'; +import { ScreenSize } from '../hooks/useScreenSize'; +import { MobileFriendlyPageNav, MobileFriendlyClientNav } from './MobileFriendly'; +import { ClientInitStorageAtom } from './client/ClientInitStorageAtom'; + +export const createRouter = (clientConfig: ClientConfig, screenSize: ScreenSize) => { + const { hashRouter } = clientConfig; + const mobile = screenSize === ScreenSize.Mobile; + + const routes = createRoutesFromElements( + + { + if (isAuthenticated()) return redirect(getHomePath()); + const afterLoginPath = getAppPathFromHref(getOriginBaseUrl(), window.location.href); + if (afterLoginPath) setAfterLoginRedirectPath(afterLoginPath); + return redirect(getLoginPath()); + }} + /> + { + if (isAuthenticated()) { + return redirect(getHomePath()); + } + + return null; + }} + element={} + > + } /> + } /> + } /> + + + { + if (!isAuthenticated()) { + const afterLoginPath = getAppPathFromHref( + getOriginBaseUrl(hashRouter), + window.location.href + ); + if (afterLoginPath) setAfterLoginRedirectPath(afterLoginPath); + return redirect(getLoginPath()); + } + return null; + }} + element={ + + + + + + + } + > + + + + + + } + > + + + + } + > + + + } + > + {mobile ? null : } />} + create

      } /> + join

      } /> + } /> + + + + } + /> + + + + + } + > + + + } + > + {mobile ? null : } />} + create

      } /> + + + + } + /> + + + + + + } + > + + + + } + > + {mobile ? null : ( + { + const { spaceIdOrAlias } = params; + if (spaceIdOrAlias) { + return redirect(getSpaceLobbyPath(spaceIdOrAlias)); + } + return null; + }} + element={} + /> + )} + } /> + } /> + + + + } + /> + + + + + } + > + + + } + > + {mobile ? null : ( + redirect(getExploreFeaturedPath())} + element={} + /> + )} + } /> + } /> + + + + + } + > + + + } + > + {mobile ? null : ( + redirect(getInboxNotificationsPath())} + element={} + /> + )} + } /> + } /> + + + Page not found

      } /> +
      + ); + + if (hashRouter?.enabled) { + return createHashRouter(routes, { basename: hashRouter.basename }); + } + return createBrowserRouter(routes, { + basename: import.meta.env.BASE_URL, + }); +}; diff --git a/src/app/pages/afterLoginRedirectPath.ts b/src/app/pages/afterLoginRedirectPath.ts new file mode 100644 index 000000000..60e09da33 --- /dev/null +++ b/src/app/pages/afterLoginRedirectPath.ts @@ -0,0 +1,12 @@ +const AFTER_LOGIN_REDIRECT_PATH_KEY = 'after_login_redirect_url'; + +export const setAfterLoginRedirectPath = (url: string): void => { + localStorage.setItem(AFTER_LOGIN_REDIRECT_PATH_KEY, url); +}; +export const getAfterLoginRedirectPath = (): string | undefined => { + const url = localStorage.getItem(AFTER_LOGIN_REDIRECT_PATH_KEY); + return url ?? undefined; +}; +export const deleteAfterLoginRedirectPath = (): void => { + localStorage.removeItem(AFTER_LOGIN_REDIRECT_PATH_KEY); +}; diff --git a/src/app/pages/auth/AuthLayout.tsx b/src/app/pages/auth/AuthLayout.tsx index c58ecdd5f..2ea941420 100644 --- a/src/app/pages/auth/AuthLayout.tsx +++ b/src/app/pages/auth/AuthLayout.tsx @@ -1,11 +1,9 @@ import React, { useCallback, useEffect } from 'react'; import { Box, Header, Scroll, Spinner, Text, color } from 'folds'; import { - LoaderFunction, Outlet, generatePath, matchPath, - redirect, useLocation, useNavigate, useParams, @@ -15,14 +13,13 @@ import classNames from 'classnames'; import { AuthFooter } from './AuthFooter'; import * as css from './styles.css'; import * as PatternsCss from '../../styles/Patterns.css'; -import { isAuthenticated } from '../../../client/state/auth'; import { clientAllowedServer, clientDefaultServer, useClientConfig, } from '../../hooks/useClientConfig'; import { AsyncStatus, useAsyncCallback } from '../../hooks/useAsyncCallback'; -import { LOGIN_PATH, REGISTER_PATH } from '../paths'; +import { LOGIN_PATH, REGISTER_PATH, RESET_PASSWORD_PATH } from '../paths'; import CinnySVG from '../../../../public/res/svg/cinny.svg'; import { ServerPicker } from './ServerPicker'; import { AutoDiscoveryAction, autoDiscovery } from '../../cs-api'; @@ -33,18 +30,13 @@ import { AuthFlowsLoader } from '../../components/AuthFlowsLoader'; import { AuthFlowsProvider } from '../../hooks/useAuthFlows'; import { AuthServerProvider } from '../../hooks/useAuthServer'; -export const authLayoutLoader: LoaderFunction = () => { - if (isAuthenticated()) { - return redirect('/'); - } - - return null; -}; - const currentAuthPath = (pathname: string): string => { if (matchPath(LOGIN_PATH, pathname)) { return LOGIN_PATH; } + if (matchPath(RESET_PASSWORD_PATH, pathname)) { + return RESET_PASSWORD_PATH; + } if (matchPath(REGISTER_PATH, pathname)) { return REGISTER_PATH; } @@ -175,6 +167,7 @@ export function AuthLayout() { ( mx.getSsoLoginUrl(redirectUrl, 'sso', ssoId); + const anyAsBtn = providers.find( + (provider) => !provider.icon || !mx.mxcUrlToHttp(provider.icon, 96, 96, 'crop', false) + ); + return ( {providers.map((provider) => { @@ -23,7 +27,7 @@ export function SSOLogin({ providers, redirectUrl, asIcons }: SSOLoginProps) { const buttonTitle = `Continue with ${name}`; - if (iconUrl && asIcons) { + if (!anyAsBtn && iconUrl && asIcons) { return ( void; }) { - const [serverMenu, setServerMenu] = useState(false); + const [serverMenuAnchor, setServerMenuAnchor] = useState(); const serverInputRef = useRef(null); useEffect(() => { @@ -53,7 +54,7 @@ export function ServerPicker({ const handleKeyDown: KeyboardEventHandler = (evt) => { if (evt.key === 'ArrowDown') { evt.preventDefault(); - setServerMenu(true); + setServerMenuAnchor(undefined); } if (evt.key === 'Enter') { evt.preventDefault(); @@ -67,7 +68,12 @@ export function ServerPicker({ if (selectedServer) { onServerChange(selectedServer); } - setServerMenu(false); + setServerMenuAnchor(undefined); + }; + + const handleOpenServerMenu: MouseEventHandler = (evt) => { + const target = evt.currentTarget.parentElement ?? evt.currentTarget; + setServerMenuAnchor(target.getBoundingClientRect()); }; return ( @@ -81,11 +87,11 @@ export function ServerPicker({ onKeyDown={handleKeyDown} size="500" readOnly={!allowCustomServer} - onClick={allowCustomServer ? undefined : () => setServerMenu(true)} + onClick={allowCustomServer ? undefined : handleOpenServerMenu} after={ serverList.length === 0 || (serverList.length === 1 && !allowCustomServer) ? undefined : ( setServerMenu(false), + onDeactivate: () => setServerMenuAnchor(undefined), clickOutsideDeactivates: true, isKeyForward: (evt: KeyboardEvent) => evt.key === 'ArrowDown', isKeyBackward: (evt: KeyboardEvent) => evt.key === 'ArrowUp', @@ -120,18 +126,15 @@ export function ServerPicker({ } > - {(anchorRef) => ( - setServerMenu(true)} - variant={allowCustomServer ? 'Background' : 'Surface'} - size="300" - aria-pressed={serverMenu} - radii="300" - > - - - )} + + + ) } diff --git a/src/app/pages/auth/login/Login.tsx b/src/app/pages/auth/login/Login.tsx index 901b19cbe..e1689d1e4 100644 --- a/src/app/pages/auth/login/Login.tsx +++ b/src/app/pages/auth/login/Login.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useMemo } from 'react'; import { Box, Text, color } from 'folds'; import { Link, useSearchParams } from 'react-router-dom'; import { useAuthFlows } from '../../../hooks/useAuthFlows'; @@ -23,18 +23,22 @@ const getLoginTokenSearchParam = () => { return loginToken ?? undefined; }; -const getLoginSearchParams = (searchParams: URLSearchParams): LoginPathSearchParams => ({ - username: searchParams.get('username') ?? undefined, - email: searchParams.get('email') ?? undefined, - loginToken: searchParams.get('loginToken') ?? undefined, -}); +const useLoginSearchParams = (searchParams: URLSearchParams): LoginPathSearchParams => + useMemo( + () => ({ + username: searchParams.get('username') ?? undefined, + email: searchParams.get('email') ?? undefined, + loginToken: searchParams.get('loginToken') ?? undefined, + }), + [searchParams] + ); export function Login() { const server = useAuthServer(); const { hashRouter } = useClientConfig(); const { loginFlows } = useAuthFlows(); const [searchParams] = useSearchParams(); - const loginSearchParams = getLoginSearchParams(searchParams); + const loginSearchParams = useLoginSearchParams(searchParams); const ssoRedirectUrl = usePathWithOrigin(getLoginPath(server)); const loginTokenForHashRouter = getLoginTokenSearchParam(); const absoluteLoginPath = usePathWithOrigin(getLoginPath(server)); diff --git a/src/app/pages/auth/login/PasswordLoginForm.tsx b/src/app/pages/auth/login/PasswordLoginForm.tsx index ea52aad8c..b9dd14b7a 100644 --- a/src/app/pages/auth/login/PasswordLoginForm.tsx +++ b/src/app/pages/auth/login/PasswordLoginForm.tsx @@ -1,4 +1,4 @@ -import React, { FormEventHandler, useCallback, useState } from 'react'; +import React, { FormEventHandler, MouseEventHandler, useCallback, useState } from 'react'; import { Box, Button, @@ -12,6 +12,7 @@ import { OverlayBackdrop, OverlayCenter, PopOut, + RectCords, Spinner, Text, config, @@ -37,17 +38,21 @@ import { FieldError } from '../FiledError'; import { getResetPasswordPath } from '../../pathUtils'; function UsernameHint({ server }: { server: string }) { - const [open, setOpen] = useState(false); + const [anchor, setAnchor] = useState(); + + const handleOpenMenu: MouseEventHandler = (evt) => { + setAnchor(evt.currentTarget.getBoundingClientRect()); + }; return ( setOpen(false), + onDeactivate: () => setAnchor(undefined), clickOutsideDeactivates: true, }} > @@ -84,20 +89,17 @@ function UsernameHint({ server }: { server: string }) { } > - {(targetRef) => ( - setOpen(true)} - ref={targetRef} - type="button" - variant="Background" - size="300" - radii="300" - aria-pressed={open} - > - - - )} + + + ); } diff --git a/src/app/pages/auth/login/loginUtil.ts b/src/app/pages/auth/login/loginUtil.ts index b2fd38709..1e2248d90 100644 --- a/src/app/pages/auth/login/loginUtil.ts +++ b/src/app/pages/auth/login/loginUtil.ts @@ -5,8 +5,12 @@ import { useNavigate } from 'react-router-dom'; import { ClientConfig, clientAllowedServer } from '../../../hooks/useClientConfig'; import { autoDiscovery, specVersions } from '../../../cs-api'; import { updateLocalStore } from '../../../../client/action/auth'; -import { ROOT_PATH } from '../../paths'; import { ErrorCode } from '../../../cs-errorcode'; +import { + deleteAfterLoginRedirectPath, + getAfterLoginRedirectPath, +} from '../../afterLoginRedirectPath'; +import { getHomePath } from '../../pathUtils'; export enum GetBaseUrlError { NotAllow = 'NotAllow', @@ -111,8 +115,9 @@ export const useLoginComplete = (data?: CustomLoginResponse) => { if (data) { const { response: loginRes, baseUrl: loginBaseUrl } = data; updateLocalStore(loginRes.access_token, loginRes.device_id, loginRes.user_id, loginBaseUrl); - // TODO: add after login redirect url - navigate(ROOT_PATH, { replace: true }); + const afterLoginRedirectUrl = getAfterLoginRedirectPath(); + deleteAfterLoginRedirectPath(); + navigate(afterLoginRedirectUrl ?? getHomePath(), { replace: true }); } }, [data, navigate]); }; diff --git a/src/app/pages/auth/register/Register.tsx b/src/app/pages/auth/register/Register.tsx index 756b13b30..c859d0e54 100644 --- a/src/app/pages/auth/register/Register.tsx +++ b/src/app/pages/auth/register/Register.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useMemo } from 'react'; import { Box, Text, color } from 'folds'; import { Link, useSearchParams } from 'react-router-dom'; import { useAuthServer } from '../../../hooks/useAuthServer'; @@ -12,17 +12,21 @@ import { getLoginPath } from '../../pathUtils'; import { usePathWithOrigin } from '../../../hooks/usePathWithOrigin'; import { RegisterPathSearchParams } from '../../paths'; -const getRegisterSearchParams = (searchParams: URLSearchParams): RegisterPathSearchParams => ({ - username: searchParams.get('username') ?? undefined, - email: searchParams.get('email') ?? undefined, - token: searchParams.get('token') ?? undefined, -}); +const useRegisterSearchParams = (searchParams: URLSearchParams): RegisterPathSearchParams => + useMemo( + () => ({ + username: searchParams.get('username') ?? undefined, + email: searchParams.get('email') ?? undefined, + token: searchParams.get('token') ?? undefined, + }), + [searchParams] + ); export function Register() { const server = useAuthServer(); const { loginFlows, registerFlows } = useAuthFlows(); const [searchParams] = useSearchParams(); - const registerSearchParams = getRegisterSearchParams(searchParams); + const registerSearchParams = useRegisterSearchParams(searchParams); const { sso } = useParsedLoginFlows(loginFlows.flows); // redirect to /login because only that path handle m.login.token diff --git a/src/app/pages/auth/register/registerUtil.ts b/src/app/pages/auth/register/registerUtil.ts index 23c3d6a1d..e8145780a 100644 --- a/src/app/pages/auth/register/registerUtil.ts +++ b/src/app/pages/auth/register/registerUtil.ts @@ -9,8 +9,14 @@ import { import { useEffect } from 'react'; import { useNavigate } from 'react-router-dom'; import { updateLocalStore } from '../../../../client/action/auth'; -import { ROOT_PATH } from '../../paths'; +import { LoginPathSearchParams } from '../../paths'; import { ErrorCode } from '../../../cs-errorcode'; +import { + deleteAfterLoginRedirectPath, + getAfterLoginRedirectPath, +} from '../../afterLoginRedirectPath'; +import { getHomePath, getLoginPath, withSearchParam } from '../../pathUtils'; +import { getMxIdLocalPart, getMxIdServer } from '../../../utils/matrix'; export enum RegisterError { UserTaken = 'UserTaken', @@ -114,11 +120,18 @@ export const useRegisterComplete = (data?: CustomRegisterResponse) => { if (accessToken && deviceId) { updateLocalStore(accessToken, deviceId, userId, baseUrl); - // TODO: add after register redirect url - navigate(ROOT_PATH, { replace: true }); + const afterLoginRedirectPath = getAfterLoginRedirectPath(); + deleteAfterLoginRedirectPath(); + navigate(afterLoginRedirectPath ?? getHomePath(), { replace: true }); } else { - // TODO: navigate to login with userId - navigate(ROOT_PATH, { replace: true }); + const username = getMxIdLocalPart(userId); + const userServer = getMxIdServer(userId); + navigate( + withSearchParam(getLoginPath(userServer), { + username, + }), + { replace: true } + ); } } }, [data, navigate]); diff --git a/src/app/pages/auth/reset-password/ResetPassword.tsx b/src/app/pages/auth/reset-password/ResetPassword.tsx index 1ada9afd7..c5e1d2ad3 100644 --- a/src/app/pages/auth/reset-password/ResetPassword.tsx +++ b/src/app/pages/auth/reset-password/ResetPassword.tsx @@ -1,24 +1,25 @@ import { Box, Text } from 'folds'; -import React from 'react'; +import React, { useMemo } from 'react'; import { Link, useSearchParams } from 'react-router-dom'; import { getLoginPath } from '../../pathUtils'; import { useAuthServer } from '../../../hooks/useAuthServer'; import { PasswordResetForm } from './PasswordResetForm'; +import { ResetPasswordPathSearchParams } from '../../paths'; -export type ResetPasswordSearchParams = { - email?: string; -}; - -const getResetPasswordSearchParams = ( +const useResetPasswordSearchParams = ( searchParams: URLSearchParams -): ResetPasswordSearchParams => ({ - email: searchParams.get('email') ?? undefined, -}); +): ResetPasswordPathSearchParams => + useMemo( + () => ({ + email: searchParams.get('email') ?? undefined, + }), + [searchParams] + ); export function ResetPassword() { const server = useAuthServer(); const [searchParams] = useSearchParams(); - const resetPasswordSearchParams = getResetPasswordSearchParams(searchParams); + const resetPasswordSearchParams = useResetPasswordSearchParams(searchParams); return ( diff --git a/src/app/pages/client/ClientBindAtoms.ts b/src/app/pages/client/ClientBindAtoms.ts new file mode 100644 index 000000000..5d57321ec --- /dev/null +++ b/src/app/pages/client/ClientBindAtoms.ts @@ -0,0 +1,14 @@ +import { ReactNode } from 'react'; + +import { useMatrixClient } from '../../hooks/useMatrixClient'; +import { useBindAtoms } from '../../state/hooks/useBindAtoms'; + +type ClientBindAtomsProps = { + children: ReactNode; +}; +export function ClientBindAtoms({ children }: ClientBindAtomsProps) { + const mx = useMatrixClient(); + useBindAtoms(mx); + + return children; +} diff --git a/src/app/pages/client/ClientInitStorageAtom.tsx b/src/app/pages/client/ClientInitStorageAtom.tsx new file mode 100644 index 000000000..1abee707a --- /dev/null +++ b/src/app/pages/client/ClientInitStorageAtom.tsx @@ -0,0 +1,38 @@ +import React, { ReactNode, useMemo } from 'react'; +import { useMatrixClient } from '../../hooks/useMatrixClient'; +import { makeClosedNavCategoriesAtom } from '../../state/closedNavCategories'; +import { ClosedNavCategoriesProvider } from '../../state/hooks/closedNavCategories'; +import { makeClosedLobbyCategoriesAtom } from '../../state/closedLobbyCategories'; +import { ClosedLobbyCategoriesProvider } from '../../state/hooks/closedLobbyCategories'; +import { makeNavToActivePathAtom } from '../../state/navToActivePath'; +import { NavToActivePathProvider } from '../../state/hooks/navToActivePath'; +import { makeOpenedSidebarFolderAtom } from '../../state/openedSidebarFolder'; +import { OpenedSidebarFolderProvider } from '../../state/hooks/openedSidebarFolder'; + +type ClientInitStorageAtomProps = { + children: ReactNode; +}; +export function ClientInitStorageAtom({ children }: ClientInitStorageAtomProps) { + const mx = useMatrixClient(); + const userId = mx.getUserId()!; + + const closedNavCategoriesAtom = useMemo(() => makeClosedNavCategoriesAtom(userId), [userId]); + + const closedLobbyCategoriesAtom = useMemo(() => makeClosedLobbyCategoriesAtom(userId), [userId]); + + const navToActivePathAtom = useMemo(() => makeNavToActivePathAtom(userId), [userId]); + + const openedSidebarFolderAtom = useMemo(() => makeOpenedSidebarFolderAtom(userId), [userId]); + + return ( + + + + + {children} + + + + + ); +} diff --git a/src/app/pages/client/ClientLayout.tsx b/src/app/pages/client/ClientLayout.tsx new file mode 100644 index 000000000..208d12e48 --- /dev/null +++ b/src/app/pages/client/ClientLayout.tsx @@ -0,0 +1,15 @@ +import React, { ReactNode } from 'react'; +import { Box } from 'folds'; + +type ClientLayoutProps = { + nav: ReactNode; + children: ReactNode; +}; +export function ClientLayout({ nav, children }: ClientLayoutProps) { + return ( + + {nav} + {children} + + ); +} diff --git a/src/app/pages/client/ClientRoot.tsx b/src/app/pages/client/ClientRoot.tsx new file mode 100644 index 000000000..1bb7855b6 --- /dev/null +++ b/src/app/pages/client/ClientRoot.tsx @@ -0,0 +1,87 @@ +import { Box, Spinner, Text } from 'folds'; +import React, { ReactNode, useEffect, useState } from 'react'; +import initMatrix from '../../../client/initMatrix'; +import { initHotkeys } from '../../../client/event/hotkeys'; +import { initRoomListListener } from '../../../client/event/roomList'; +import { getSecret } from '../../../client/state/auth'; +import { SplashScreen } from '../../components/splash-screen'; +import { CapabilitiesAndMediaConfigLoader } from '../../components/CapabilitiesAndMediaConfigLoader'; +import { CapabilitiesProvider } from '../../hooks/useCapabilities'; +import { MediaConfigProvider } from '../../hooks/useMediaConfig'; +import { MatrixClientProvider } from '../../hooks/useMatrixClient'; +import { SpecVersions } from './SpecVersions'; +import Windows from '../../organisms/pw/Windows'; +import Dialogs from '../../organisms/pw/Dialogs'; +import ReusableContextMenu from '../../atoms/context-menu/ReusableContextMenu'; +import { useSetting } from '../../state/hooks/settings'; +import { settingsAtom } from '../../state/settings'; + +function SystemEmojiFeature() { + const [twitterEmoji] = useSetting(settingsAtom, 'twitterEmoji'); + + if (twitterEmoji) { + document.documentElement.style.setProperty('--font-emoji', 'Twemoji'); + } else { + document.documentElement.style.setProperty('--font-emoji', 'Twemoji_DISABLED'); + } + + return null; +} + +function ClientRootLoading() { + return ( + + + + Heating up + + + ); +} + +type ClientRootProps = { + children: ReactNode; +}; +export function ClientRoot({ children }: ClientRootProps) { + const [loading, setLoading] = useState(true); + const { baseUrl } = getSecret(); + + useEffect(() => { + const handleStart = () => { + initHotkeys(); + initRoomListListener(initMatrix.roomList); + setLoading(false); + }; + initMatrix.once('init_loading_finished', handleStart); + if (!initMatrix.matrixClient) initMatrix.init(); + return () => { + initMatrix.removeListener('init_loading_finished', handleStart); + }; + }, []); + + return ( + + {loading ? ( + + ) : ( + + + {(capabilities, mediaConfig) => ( + + + {children} + + {/* TODO: remove these components after navigation refactor */} + + + + + + + )} + + + )} + + ); +} diff --git a/src/app/pages/client/SidebarNav.tsx b/src/app/pages/client/SidebarNav.tsx new file mode 100644 index 000000000..fb6bd7422 --- /dev/null +++ b/src/app/pages/client/SidebarNav.tsx @@ -0,0 +1,76 @@ +import React, { useRef } from 'react'; +import { Icon, Icons, Scroll } from 'folds'; + +import { + Sidebar, + SidebarContent, + SidebarStackSeparator, + SidebarStack, + SidebarAvatar, + SidebarItemTooltip, + SidebarItem, +} from '../../components/sidebar'; +import { DirectTab, HomeTab, SpaceTabs, InboxTab, ExploreTab, UserTab } from './sidebar'; +import { openCreateRoom, openSearch } from '../../../client/action/navigation'; + +export function SidebarNav() { + const scrollRef = useRef(null); + + return ( + + + + + + + + + + + + + {(triggerRef) => ( + openCreateRoom(true)} + > + + + )} + + + + + } + sticky={ + <> + + + + + {(triggerRef) => ( + openSearch()} + > + + + )} + + + + + + + + } + /> + + ); +} diff --git a/src/app/pages/client/SpecVersions.tsx b/src/app/pages/client/SpecVersions.tsx new file mode 100644 index 000000000..952885cdb --- /dev/null +++ b/src/app/pages/client/SpecVersions.tsx @@ -0,0 +1,46 @@ +import React, { ReactNode } from 'react'; +import { Box, Dialog, config, Text, Button, Spinner } from 'folds'; +import { SpecVersionsLoader } from '../../components/SpecVersionsLoader'; +import { SpecVersionsProvider } from '../../hooks/useSpecVersions'; +import { SplashScreen } from '../../components/splash-screen'; + +export function SpecVersions({ baseUrl, children }: { baseUrl: string; children: ReactNode }) { + return ( + ( + + + + Connecting to server + + + )} + error={(err, retry, ignore) => ( + + + + + + Failed to connect to homeserver. Either homeserver is down or your internet. + + + + + + + + )} + > + {(versions) => {children}} + + ); +} diff --git a/src/app/pages/client/WelcomePage.tsx b/src/app/pages/client/WelcomePage.tsx new file mode 100644 index 000000000..2486625f6 --- /dev/null +++ b/src/app/pages/client/WelcomePage.tsx @@ -0,0 +1,64 @@ +import React from 'react'; +import { Box, Button, Icon, Icons, Text, config, toRem } from 'folds'; +import { Page, PageHero, PageHeroSection } from '../../components/page'; +import CinnySVG from '../../../../public/res/svg/cinny.svg'; + +export function WelcomePage() { + return ( + + + + } + title="Welcome to Cinny" + subTitle={ + + Yet anothor matrix client.{' '} + + v3.2.0 + + + } + > + + + + + + + + + + + ); +} diff --git a/src/app/pages/client/direct/Direct.tsx b/src/app/pages/client/direct/Direct.tsx new file mode 100644 index 000000000..673a5d9f1 --- /dev/null +++ b/src/app/pages/client/direct/Direct.tsx @@ -0,0 +1,263 @@ +import React, { MouseEventHandler, forwardRef, useMemo, useRef, useState } from 'react'; +import { useAtom, useAtomValue } from 'jotai'; +import { + Avatar, + Box, + Button, + Icon, + IconButton, + Icons, + Menu, + MenuItem, + PopOut, + RectCords, + Text, + config, + toRem, +} from 'folds'; +import { useVirtualizer } from '@tanstack/react-virtual'; +import FocusTrap from 'focus-trap-react'; +import { useMatrixClient } from '../../../hooks/useMatrixClient'; +import { factoryRoomIdByActivity } from '../../../utils/sort'; +import { + NavButton, + NavCategory, + NavCategoryHeader, + NavEmptyCenter, + NavEmptyLayout, + NavItem, + NavItemContent, +} from '../../../components/nav'; +import { getDirectRoomPath } from '../../pathUtils'; +import { getCanonicalAliasOrRoomId } from '../../../utils/matrix'; +import { useSelectedRoom } from '../../../hooks/router/useSelectedRoom'; +import { VirtualTile } from '../../../components/virtualizer'; +import { RoomNavCategoryButton, RoomNavItem } from '../../../features/room-nav'; +import { muteChangesAtom } from '../../../state/room-list/mutedRoomList'; +import { makeNavCategoryId } from '../../../state/closedNavCategories'; +import { roomToUnreadAtom } from '../../../state/room/roomToUnread'; +import { useCategoryHandler } from '../../../hooks/useCategoryHandler'; +import { useNavToActivePathMapper } from '../../../hooks/useNavToActivePathMapper'; +import { useDirectRooms } from './useDirectRooms'; +import { openInviteUser } from '../../../../client/action/navigation'; +import { PageNav, PageNavContent, PageNavHeader } from '../../../components/page'; +import { useClosedNavCategoriesAtom } from '../../../state/hooks/closedNavCategories'; +import { useRoomsUnread } from '../../../state/hooks/unread'; +import { markAsRead } from '../../../../client/action/notifications'; + +type DirectMenuProps = { + requestClose: () => void; +}; +const DirectMenu = forwardRef(({ requestClose }, ref) => { + const orphanRooms = useDirectRooms(); + const unread = useRoomsUnread(orphanRooms, roomToUnreadAtom); + + const handleMarkAsRead = () => { + if (!unread) return; + orphanRooms.forEach((rId) => markAsRead(rId)); + requestClose(); + }; + + return ( + + + } + radii="300" + aria-disabled={!unread} + > + + Mark as Read + + + + + ); +}); + +function DirectHeader() { + const [menuAnchor, setMenuAnchor] = useState(); + + const handleOpenMenu: MouseEventHandler = (evt) => { + const cords = evt.currentTarget.getBoundingClientRect(); + setMenuAnchor((currentState) => { + if (currentState) return undefined; + return cords; + }); + }; + + return ( + <> + + + + + Direct Messages + + + + + + + + + + setMenuAnchor(undefined), + clickOutsideDeactivates: true, + isKeyForward: (evt: KeyboardEvent) => evt.key === 'ArrowDown', + isKeyBackward: (evt: KeyboardEvent) => evt.key === 'ArrowUp', + }} + > + setMenuAnchor(undefined)} /> + + } + /> + + ); +} + +function DirectEmpty() { + return ( + + } + title={ + + No Direct Messages + + } + content={ + + You do not have any direct messages yet. + + } + options={ + + } + /> + + ); +} + +const DEFAULT_CATEGORY_ID = makeNavCategoryId('direct', 'direct'); +export function Direct() { + const mx = useMatrixClient(); + useNavToActivePathMapper('direct'); + const scrollRef = useRef(null); + const directs = useDirectRooms(); + const muteChanges = useAtomValue(muteChangesAtom); + const mutedRooms = muteChanges.added; + const roomToUnread = useAtomValue(roomToUnreadAtom); + + const selectedRoomId = useSelectedRoom(); + const noRoomToDisplay = directs.length === 0; + const [closedCategories, setClosedCategories] = useAtom(useClosedNavCategoriesAtom()); + + const sortedDirects = useMemo(() => { + const items = Array.from(directs).sort(factoryRoomIdByActivity(mx)); + if (closedCategories.has(DEFAULT_CATEGORY_ID)) { + return items.filter((rId) => roomToUnread.has(rId) || rId === selectedRoomId); + } + return items; + }, [mx, directs, closedCategories, roomToUnread, selectedRoomId]); + + const virtualizer = useVirtualizer({ + count: sortedDirects.length, + getScrollElement: () => scrollRef.current, + estimateSize: () => 38, + overscan: 10, + }); + + const handleCategoryClick = useCategoryHandler(setClosedCategories, (categoryId) => + closedCategories.has(categoryId) + ); + + return ( + + + {noRoomToDisplay ? ( + + ) : ( + + + + + openInviteUser()}> + + + + + + + + Create Chat + + + + + + + + + + + Chats + + +
      + {virtualizer.getVirtualItems().map((vItem) => { + const roomId = sortedDirects[vItem.index]; + const room = mx.getRoom(roomId); + if (!room) return null; + const selected = selectedRoomId === roomId; + + return ( + + + + ); + })} +
      +
      +
      +
      + )} +
      + ); +} diff --git a/src/app/pages/client/direct/RoomProvider.tsx b/src/app/pages/client/direct/RoomProvider.tsx new file mode 100644 index 000000000..c78a8f44e --- /dev/null +++ b/src/app/pages/client/direct/RoomProvider.tsx @@ -0,0 +1,26 @@ +import React, { ReactNode } from 'react'; +import { useParams } from 'react-router-dom'; +import { useSelectedRoom } from '../../../hooks/router/useSelectedRoom'; +import { RoomProvider } from '../../../hooks/useRoom'; +import { useMatrixClient } from '../../../hooks/useMatrixClient'; +import { JoinBeforeNavigate } from '../../../features/join-before-navigate'; +import { useDirectRooms } from './useDirectRooms'; + +export function DirectRouteRoomProvider({ children }: { children: ReactNode }) { + const mx = useMatrixClient(); + const rooms = useDirectRooms(); + + const { roomIdOrAlias } = useParams(); + const roomId = useSelectedRoom(); + const room = mx.getRoom(roomId); + + if (!room || !rooms.includes(room.roomId)) { + return ; + } + + return ( + + {children} + + ); +} diff --git a/src/app/pages/client/direct/index.ts b/src/app/pages/client/direct/index.ts new file mode 100644 index 000000000..36f44d63e --- /dev/null +++ b/src/app/pages/client/direct/index.ts @@ -0,0 +1,2 @@ +export * from './Direct'; +export * from './RoomProvider'; diff --git a/src/app/pages/client/direct/useDirectRooms.ts b/src/app/pages/client/direct/useDirectRooms.ts new file mode 100644 index 000000000..00009927b --- /dev/null +++ b/src/app/pages/client/direct/useDirectRooms.ts @@ -0,0 +1,12 @@ +import { useAtomValue } from 'jotai'; +import { useMatrixClient } from '../../../hooks/useMatrixClient'; +import { mDirectAtom } from '../../../state/mDirectList'; +import { allRoomsAtom } from '../../../state/room-list/roomList'; +import { useDirects } from '../../../state/hooks/roomList'; + +export const useDirectRooms = () => { + const mx = useMatrixClient(); + const mDirects = useAtomValue(mDirectAtom); + const directs = useDirects(mx, allRoomsAtom, mDirects); + return directs; +}; diff --git a/src/app/pages/client/explore/Explore.tsx b/src/app/pages/client/explore/Explore.tsx new file mode 100644 index 000000000..67f8dc3f1 --- /dev/null +++ b/src/app/pages/client/explore/Explore.tsx @@ -0,0 +1,269 @@ +import React, { FormEventHandler, useCallback, useRef, useState } from 'react'; +import { useNavigate } from 'react-router-dom'; +import FocusTrap from 'focus-trap-react'; +import { + Avatar, + Box, + Button, + Dialog, + Header, + Icon, + IconButton, + Icons, + Input, + Overlay, + OverlayBackdrop, + OverlayCenter, + Text, + color, + config, +} from 'folds'; +import { + NavCategory, + NavCategoryHeader, + NavItem, + NavItemContent, + NavLink, +} from '../../../components/nav'; +import { getExploreFeaturedPath, getExploreServerPath } from '../../pathUtils'; +import { useClientConfig } from '../../../hooks/useClientConfig'; +import { + useExploreFeaturedSelected, + useExploreServer, +} from '../../../hooks/router/useExploreSelected'; +import { useMatrixClient } from '../../../hooks/useMatrixClient'; +import { getMxIdServer } from '../../../utils/matrix'; +import { AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback'; +import { useNavToActivePathMapper } from '../../../hooks/useNavToActivePathMapper'; +import { PageNav, PageNavContent, PageNavHeader } from '../../../components/page'; + +export function AddServer() { + const mx = useMatrixClient(); + const navigate = useNavigate(); + const [dialog, setDialog] = useState(false); + const serverInputRef = useRef(null); + + const [exploreState] = useAsyncCallback( + useCallback((server: string) => mx.publicRooms({ server, limit: 1 }), [mx]) + ); + + const getInputServer = (): string | undefined => { + const serverInput = serverInputRef.current; + if (!serverInput) return undefined; + const server = serverInput.value.trim(); + return server || undefined; + }; + + const handleSubmit: FormEventHandler = (evt) => { + evt.preventDefault(); + const server = getInputServer(); + if (!server) return; + // explore(server); + + navigate(getExploreServerPath(server)); + setDialog(false); + }; + + const handleView = () => { + const server = getInputServer(); + if (!server) return; + navigate(getExploreServerPath(server)); + setDialog(false); + }; + + return ( + <> + }> + + setDialog(false), + }} + > + +
      + + Add Server + + setDialog(false)} radii="300"> + + +
      + + Add server name to explore public communities. + + Server Name + + {exploreState.status === AsyncStatus.Error && ( + + Failed to load public rooms. Please try again. + + )} + + + {/* */} + + + + +
      +
      +
      +
      + + + ); +} + +export function Explore() { + const mx = useMatrixClient(); + useNavToActivePathMapper('explore'); + const userId = mx.getUserId(); + const clientConfig = useClientConfig(); + const userServer = userId ? getMxIdServer(userId) : undefined; + const servers = + clientConfig.featuredCommunities?.servers?.filter((server) => server !== userServer) ?? []; + + const featuredSelected = useExploreFeaturedSelected(); + const selectedServer = useExploreServer(); + + return ( + + + + + + Explore Community + + + + + + + + + + + + + + + + + + Featured + + + + + + + {userServer && ( + + + + + + + + + + {userServer} + + + + + + + )} + + {servers.length > 0 && ( + + + + Servers + + + {servers.map((server) => ( + + + + + + + + + + {server} + + + + + + + ))} + + )} + + + + + + + ); +} diff --git a/src/app/pages/client/explore/Featured.tsx b/src/app/pages/client/explore/Featured.tsx new file mode 100644 index 000000000..4838127f5 --- /dev/null +++ b/src/app/pages/client/explore/Featured.tsx @@ -0,0 +1,121 @@ +import React from 'react'; +import { Box, Icon, Icons, Scroll, Text } from 'folds'; +import { useAtomValue } from 'jotai'; +import { useClientConfig } from '../../../hooks/useClientConfig'; +import { RoomCard, RoomCardGrid } from '../../../components/room-card'; +import { allRoomsAtom } from '../../../state/room-list/roomList'; +import { RoomSummaryLoader } from '../../../components/RoomSummaryLoader'; +import { + Page, + PageContent, + PageContentCenter, + PageHero, + PageHeroSection, +} from '../../../components/page'; +import { RoomTopicViewer } from '../../../components/room-topic-viewer'; +import * as css from './style.css'; +import { useRoomNavigate } from '../../../hooks/useRoomNavigate'; + +export function FeaturedRooms() { + const { featuredCommunities } = useClientConfig(); + const { rooms, spaces } = featuredCommunities ?? {}; + const allRooms = useAtomValue(allRoomsAtom); + const { navigateSpace, navigateRoom } = useRoomNavigate(); + + return ( + + + + + + + + } + title="Featured by Client" + subTitle="Find and explore public rooms and spaces featured by client provider." + /> + + + {spaces && spaces.length > 0 && ( + + Featured Spaces + + {spaces.map((roomIdOrAlias) => ( + + {(roomSummary) => ( + ( + + )} + /> + )} + + ))} + + + )} + {rooms && rooms.length > 0 && ( + + Featured Rooms + + {rooms.map((roomIdOrAlias) => ( + + {(roomSummary) => ( + ( + + )} + /> + )} + + ))} + + + )} + {((spaces && spaces.length === 0 && rooms && rooms.length === 0) || + (!spaces && !rooms)) && ( + + + + No rooms or spaces featured by client provider. + + + )} + + + + + + + + ); +} diff --git a/src/app/pages/client/explore/Server.tsx b/src/app/pages/client/explore/Server.tsx new file mode 100644 index 000000000..9fe4e78eb --- /dev/null +++ b/src/app/pages/client/explore/Server.tsx @@ -0,0 +1,645 @@ +import React, { + FormEventHandler, + MouseEventHandler, + RefObject, + useCallback, + useEffect, + useMemo, + useRef, + useState, +} from 'react'; +import { + Box, + Button, + Chip, + Icon, + Icons, + Input, + Line, + Menu, + MenuItem, + PopOut, + RectCords, + Scroll, + Spinner, + Text, + config, + toRem, +} from 'folds'; +import { useNavigate, useParams, useSearchParams } from 'react-router-dom'; +import FocusTrap from 'focus-trap-react'; +import { useAtomValue } from 'jotai'; +import { useQuery } from '@tanstack/react-query'; +import { MatrixClient, Method, RoomType } from 'matrix-js-sdk'; +import { Page, PageContent, PageContentCenter, PageHeader } from '../../../components/page'; +import { useMatrixClient } from '../../../hooks/useMatrixClient'; +import { RoomTopicViewer } from '../../../components/room-topic-viewer'; +import { RoomCard, RoomCardBase, RoomCardGrid } from '../../../components/room-card'; +import { ExploreServerPathSearchParams } from '../../paths'; +import { getExploreServerPath, withSearchParam } from '../../pathUtils'; +import * as css from './style.css'; +import { allRoomsAtom } from '../../../state/room-list/roomList'; +import { useRoomNavigate } from '../../../hooks/useRoomNavigate'; +import { getMxIdServer } from '../../../utils/matrix'; + +const useServerSearchParams = (searchParams: URLSearchParams): ExploreServerPathSearchParams => + useMemo( + () => ({ + limit: searchParams.get('limit') ?? undefined, + since: searchParams.get('since') ?? undefined, + term: searchParams.get('term') ?? undefined, + type: searchParams.get('type') ?? undefined, + instance: searchParams.get('instance') ?? undefined, + }), + [searchParams] + ); + +type RoomTypeFilter = { + title: string; + value: string | undefined; +}; +const useRoomTypeFilters = (): RoomTypeFilter[] => + useMemo( + () => [ + { + title: 'All', + value: undefined, + }, + { + title: 'Spaces', + value: RoomType.Space, + }, + { + title: 'Rooms', + value: 'null', + }, + ], + [] + ); + +const FALLBACK_ROOMS_LIMIT = 24; + +type SearchProps = { + active?: boolean; + loading?: boolean; + searchInputRef: RefObject; + onSearch: (term: string) => void; + onReset: () => void; +}; +function Search({ active, loading, searchInputRef, onSearch, onReset }: SearchProps) { + const handleSearchSubmit: FormEventHandler = (evt) => { + evt.preventDefault(); + const { searchInput } = evt.target as HTMLFormElement & { + searchInput: HTMLInputElement; + }; + + const searchTerm = searchInput.value.trim() || undefined; + if (searchTerm) { + onSearch(searchTerm); + } + }; + + return ( + + + Search + + ) : ( + + ) + } + after={ + active ? ( + } + onClick={onReset} + > + Clear + + ) : ( + + Enter + + ) + } + /> + + ); +} + +const DEFAULT_INSTANCE_NAME = 'Matrix'; +function ThirdPartyProtocolsSelector({ + instanceId, + onChange, +}: { + instanceId?: string; + onChange: (instanceId?: string) => void; +}) { + const mx = useMatrixClient(); + const [menuAnchor, setMenuAnchor] = useState(); + + const { data } = useQuery({ + queryKey: ['thirdparty', 'protocols'], + queryFn: () => mx.getThirdpartyProtocols(), + }); + + const handleInstanceSelect: MouseEventHandler = (evt): void => { + const insId = evt.currentTarget.getAttribute('data-instance-id') ?? undefined; + onChange(insId); + setMenuAnchor(undefined); + }; + + const handleOpenMenu: MouseEventHandler = (evt) => { + setMenuAnchor(evt.currentTarget.getBoundingClientRect()); + }; + + const instances = data && Object.keys(data).flatMap((protocol) => data[protocol].instances); + if (!instances || instances.length === 0) return null; + const selectedInstance = instances.find((instance) => instanceId === instance.instance_id); + + return ( + setMenuAnchor(undefined), + clickOutsideDeactivates: true, + }} + > + + + + Protocols + + + + + {DEFAULT_INSTANCE_NAME} + + + {instances.map((instance) => ( + + + {instance.desc} + + + ))} + + + + + } + > + } + > + + {selectedInstance?.desc ?? DEFAULT_INSTANCE_NAME} + + + + ); +} + +type LimitButtonProps = { + limit: number; + onLimitChange: (limit: string) => void; +}; +function LimitButton({ limit, onLimitChange }: LimitButtonProps) { + const [menuAnchor, setMenuAnchor] = useState(); + + const handleLimitSubmit: FormEventHandler = (evt) => { + evt.preventDefault(); + const limitInput = evt.currentTarget.limitInput as HTMLInputElement; + if (!limitInput) return; + const newLimit = limitInput.value.trim(); + if (!newLimit) return; + onLimitChange(newLimit); + }; + + const setLimit = (l: string) => { + setMenuAnchor(undefined); + onLimitChange(l); + }; + const handleOpenMenu: MouseEventHandler = (evt) => { + setMenuAnchor(evt.currentTarget.getBoundingClientRect()); + }; + + return ( + setMenuAnchor(undefined), + clickOutsideDeactivates: true, + }} + > + + + + Presets + + setLimit('24')} radii="Pill"> + 24 + + setLimit('48')} radii="Pill"> + 48 + + setLimit('96')} radii="Pill"> + 96 + + + + + + Custom Limit + + + + + + + + } + > + } + > + {`Page Limit: ${limit}`} + + + ); +} + +export function PublicRooms() { + const { server } = useParams(); + const mx = useMatrixClient(); + const userId = mx.getUserId(); + const userServer = userId && getMxIdServer(userId); + const allRooms = useAtomValue(allRoomsAtom); + const { navigateSpace, navigateRoom } = useRoomNavigate(); + + const [searchParams] = useSearchParams(); + const serverSearchParams = useServerSearchParams(searchParams); + const isSearch = !!serverSearchParams.term; + const scrollRef = useRef(null); + const searchInputRef = useRef(null); + const navigate = useNavigate(); + const roomTypeFilters = useRoomTypeFilters(); + + const currentLimit: number = useMemo(() => { + const limitParam = serverSearchParams.limit; + if (!limitParam) return FALLBACK_ROOMS_LIMIT; + return parseInt(limitParam, 10) || FALLBACK_ROOMS_LIMIT; + }, [serverSearchParams.limit]); + + const resetScroll = useCallback(() => { + const scroll = scrollRef.current; + if (scroll) scroll.scrollTop = 0; + }, []); + + const fetchPublicRooms = useCallback(() => { + const limit = + typeof serverSearchParams.limit === 'string' + ? parseInt(serverSearchParams.limit, 10) + : FALLBACK_ROOMS_LIMIT; + const roomType: string | null | undefined = + serverSearchParams.type === 'null' ? null : serverSearchParams.type; + + return mx.http.authedRequest>>( + Method.Post, + '/publicRooms', + { + server, + }, + { + limit, + since: serverSearchParams.since, + filter: { + generic_search_term: serverSearchParams.term, + room_types: roomType !== undefined ? [roomType] : undefined, + }, + third_party_instance_id: serverSearchParams.instance, + } + ); + }, [mx, server, serverSearchParams]); + + const { data, isLoading, error } = useQuery({ + queryKey: [ + server, + 'publicRooms', + serverSearchParams.limit, + serverSearchParams.since, + serverSearchParams.term, + serverSearchParams.type, + serverSearchParams.instance, + ], + queryFn: fetchPublicRooms, + }); + + useEffect(() => { + if (isLoading) resetScroll(); + }, [isLoading, resetScroll]); + + const explore = (newSearchParams: ExploreServerPathSearchParams) => { + if (!server) return; + + const sParams: Record = { + ...serverSearchParams, + ...newSearchParams, + }; + Object.keys(sParams).forEach((key) => { + if (sParams[key] === undefined) delete sParams[key]; + }); + const path = withSearchParam(getExploreServerPath(server), sParams); + navigate(path); + }; + + const paginateBack = () => { + const token = data?.prev_batch; + explore({ since: token }); + }; + + const paginateFront = () => { + const token = data?.next_batch; + explore({ since: token }); + }; + + const handleSearch = (term: string) => { + explore({ + term, + since: undefined, + }); + }; + + const handleSearchClear = () => { + if (searchInputRef.current) { + searchInputRef.current.value = ''; + } + explore({ + term: undefined, + since: undefined, + }); + }; + + const handleRoomFilterClick: MouseEventHandler = (evt) => { + const filter = evt.currentTarget.getAttribute('data-room-filter'); + explore({ + type: filter ?? undefined, + since: undefined, + }); + }; + + const handleLimitChange = (limit: string) => { + explore({ limit }); + }; + + const handleInstanceIdChange = (instanceId?: string) => { + explore({ instance: instanceId, since: undefined }); + }; + + return ( + + + {isSearch ? ( + <> + + } + onClick={handleSearchClear} + > + {server} + + + + + + + Search + + + + + ) : ( + + + + {server} + + + )} + + + + + + + + + + {isSearch ? ( + {`Results for "${serverSearchParams.term}"`} + ) : ( + Popular Communities + )} + + {roomTypeFilters.map((filter) => ( + + ) + } + outlined + > + {filter.title} + + ))} + {userServer === server && ( + <> + + + + )} + + + + + {isLoading && ( + + {[...Array(currentLimit).keys()].map((item) => ( + + ))} + + )} + {error && ( + + {error.name} + {error.message} + + )} + {data && + (data.chunk.length > 0 ? ( + <> + + {data?.chunk.map((chunkRoom) => ( + ( + + )} + /> + ))} + + + {(data.prev_batch || data.next_batch) && ( + + + + + + )} + + ) : ( + + + + No communities found! + + + ))} + + + + + + + + ); +} diff --git a/src/app/pages/client/explore/index.ts b/src/app/pages/client/explore/index.ts new file mode 100644 index 000000000..1149a10d4 --- /dev/null +++ b/src/app/pages/client/explore/index.ts @@ -0,0 +1,3 @@ +export * from './Explore'; +export * from './Server'; +export * from './Featured'; diff --git a/src/app/pages/client/explore/style.css.ts b/src/app/pages/client/explore/style.css.ts new file mode 100644 index 000000000..9186cb222 --- /dev/null +++ b/src/app/pages/client/explore/style.css.ts @@ -0,0 +1,19 @@ +import { style } from '@vanilla-extract/css'; +import { config } from 'folds'; +import { ContainerColor } from '../../../styles/ContainerColor.css'; + +export const RoomsInfoCard = style([ + ContainerColor({ variant: 'SurfaceVariant' }), + { + padding: `${config.space.S700} ${config.space.S300}`, + borderRadius: config.radii.R400, + }, +]); + +export const PublicRoomsError = style([ + ContainerColor({ variant: 'Critical' }), + { + padding: config.space.S300, + borderRadius: config.radii.R400, + }, +]); diff --git a/src/app/pages/client/home/Home.tsx b/src/app/pages/client/home/Home.tsx new file mode 100644 index 000000000..33714191c --- /dev/null +++ b/src/app/pages/client/home/Home.tsx @@ -0,0 +1,315 @@ +import React, { MouseEventHandler, forwardRef, useMemo, useRef, useState } from 'react'; +import { useNavigate } from 'react-router-dom'; +import { + Avatar, + Box, + Button, + Icon, + IconButton, + Icons, + Menu, + MenuItem, + PopOut, + RectCords, + Text, + config, + toRem, +} from 'folds'; +import { useVirtualizer } from '@tanstack/react-virtual'; +import { useAtom, useAtomValue } from 'jotai'; +import FocusTrap from 'focus-trap-react'; +import { factoryRoomIdByActivity, factoryRoomIdByAtoZ } from '../../../utils/sort'; +import { + NavButton, + NavCategory, + NavCategoryHeader, + NavEmptyCenter, + NavEmptyLayout, + NavItem, + NavItemContent, + NavLink, +} from '../../../components/nav'; +import { getExplorePath, getHomeRoomPath, getHomeSearchPath } from '../../pathUtils'; +import { getCanonicalAliasOrRoomId } from '../../../utils/matrix'; +import { useSelectedRoom } from '../../../hooks/router/useSelectedRoom'; +import { useHomeSearchSelected } from '../../../hooks/router/useHomeSelected'; +import { useHomeRooms } from './useHomeRooms'; +import { useMatrixClient } from '../../../hooks/useMatrixClient'; +import { VirtualTile } from '../../../components/virtualizer'; +import { RoomNavCategoryButton, RoomNavItem } from '../../../features/room-nav'; +import { muteChangesAtom } from '../../../state/room-list/mutedRoomList'; +import { makeNavCategoryId } from '../../../state/closedNavCategories'; +import { roomToUnreadAtom } from '../../../state/room/roomToUnread'; +import { useCategoryHandler } from '../../../hooks/useCategoryHandler'; +import { useNavToActivePathMapper } from '../../../hooks/useNavToActivePathMapper'; +import { openCreateRoom, openJoinAlias } from '../../../../client/action/navigation'; +import { PageNav, PageNavHeader, PageNavContent } from '../../../components/page'; +import { useRoomsUnread } from '../../../state/hooks/unread'; +import { markAsRead } from '../../../../client/action/notifications'; +import { useClosedNavCategoriesAtom } from '../../../state/hooks/closedNavCategories'; + +type HomeMenuProps = { + requestClose: () => void; +}; +const HomeMenu = forwardRef(({ requestClose }, ref) => { + const orphanRooms = useHomeRooms(); + const unread = useRoomsUnread(orphanRooms, roomToUnreadAtom); + + const handleMarkAsRead = () => { + if (!unread) return; + orphanRooms.forEach((rId) => markAsRead(rId)); + requestClose(); + }; + + return ( + + + } + radii="300" + aria-disabled={!unread} + > + + Mark as Read + + + + + ); +}); + +function HomeHeader() { + const [menuAnchor, setMenuAnchor] = useState(); + + const handleOpenMenu: MouseEventHandler = (evt) => { + const cords = evt.currentTarget.getBoundingClientRect(); + setMenuAnchor((currentState) => { + if (currentState) return undefined; + return cords; + }); + }; + + return ( + <> + + + + + Home + + + + + + + + + + setMenuAnchor(undefined), + clickOutsideDeactivates: true, + isKeyForward: (evt: KeyboardEvent) => evt.key === 'ArrowDown', + isKeyBackward: (evt: KeyboardEvent) => evt.key === 'ArrowUp', + }} + > + setMenuAnchor(undefined)} /> + + } + /> + + ); +} + +function HomeEmpty() { + const navigate = useNavigate(); + + return ( + + } + title={ + + No Rooms + + } + content={ + + You do not have any rooms yet. + + } + options={ + <> + + + + } + /> + + ); +} + +const DEFAULT_CATEGORY_ID = makeNavCategoryId('home', 'room'); +export function Home() { + const mx = useMatrixClient(); + useNavToActivePathMapper('home'); + const scrollRef = useRef(null); + const rooms = useHomeRooms(); + const muteChanges = useAtomValue(muteChangesAtom); + const mutedRooms = muteChanges.added; + const roomToUnread = useAtomValue(roomToUnreadAtom); + + const selectedRoomId = useSelectedRoom(); + const searchSelected = useHomeSearchSelected(); + const noRoomToDisplay = rooms.length === 0; + const [closedCategories, setClosedCategories] = useAtom(useClosedNavCategoriesAtom()); + + const sortedRooms = useMemo(() => { + const items = Array.from(rooms).sort( + closedCategories.has(DEFAULT_CATEGORY_ID) + ? factoryRoomIdByActivity(mx) + : factoryRoomIdByAtoZ(mx) + ); + if (closedCategories.has(DEFAULT_CATEGORY_ID)) { + return items.filter((rId) => roomToUnread.has(rId) || rId === selectedRoomId); + } + return items; + }, [mx, rooms, closedCategories, roomToUnread, selectedRoomId]); + + const virtualizer = useVirtualizer({ + count: sortedRooms.length, + getScrollElement: () => scrollRef.current, + estimateSize: () => 38, + overscan: 10, + }); + + const handleCategoryClick = useCategoryHandler(setClosedCategories, (categoryId) => + closedCategories.has(categoryId) + ); + + return ( + + + {noRoomToDisplay ? ( + + ) : ( + + + + + openCreateRoom()}> + + + + + + + + Create Room + + + + + + + + openJoinAlias()}> + + + + + + + + Join with Address + + + + + + + + + + + + + + + + Message Search + + + + + + + + + + + Rooms + + +
      + {virtualizer.getVirtualItems().map((vItem) => { + const roomId = sortedRooms[vItem.index]; + const room = mx.getRoom(roomId); + if (!room) return null; + const selected = selectedRoomId === roomId; + + return ( + + + + ); + })} +
      +
      +
      +
      + )} +
      + ); +} diff --git a/src/app/pages/client/home/RoomProvider.tsx b/src/app/pages/client/home/RoomProvider.tsx new file mode 100644 index 000000000..282cee7dd --- /dev/null +++ b/src/app/pages/client/home/RoomProvider.tsx @@ -0,0 +1,26 @@ +import React, { ReactNode } from 'react'; +import { useParams } from 'react-router-dom'; +import { useSelectedRoom } from '../../../hooks/router/useSelectedRoom'; +import { RoomProvider } from '../../../hooks/useRoom'; +import { useMatrixClient } from '../../../hooks/useMatrixClient'; +import { JoinBeforeNavigate } from '../../../features/join-before-navigate'; +import { useHomeRooms } from './useHomeRooms'; + +export function HomeRouteRoomProvider({ children }: { children: ReactNode }) { + const mx = useMatrixClient(); + const rooms = useHomeRooms(); + + const { roomIdOrAlias } = useParams(); + const roomId = useSelectedRoom(); + const room = mx.getRoom(roomId); + + if (!room || !rooms.includes(room.roomId)) { + return ; + } + + return ( + + {children} + + ); +} diff --git a/src/app/pages/client/home/Search.tsx b/src/app/pages/client/home/Search.tsx new file mode 100644 index 000000000..af7b1eb9a --- /dev/null +++ b/src/app/pages/client/home/Search.tsx @@ -0,0 +1,37 @@ +import React, { useRef } from 'react'; +import { Box, Icon, Icons, Text, Scroll } from 'folds'; +import { Page, PageContent, PageContentCenter, PageHeader } from '../../../components/page'; +import { MessageSearch } from '../../../features/message-search'; +import { useHomeRooms } from './useHomeRooms'; + +export function HomeSearch() { + const scrollRef = useRef(null); + const rooms = useHomeRooms(); + + return ( + + + + + + Message Search + + + + + + + + + + + + + + ); +} diff --git a/src/app/pages/client/home/index.ts b/src/app/pages/client/home/index.ts new file mode 100644 index 000000000..807644818 --- /dev/null +++ b/src/app/pages/client/home/index.ts @@ -0,0 +1,3 @@ +export * from './Home'; +export * from './Search'; +export * from './RoomProvider'; diff --git a/src/app/pages/client/home/useHomeRooms.ts b/src/app/pages/client/home/useHomeRooms.ts new file mode 100644 index 000000000..b0181b08a --- /dev/null +++ b/src/app/pages/client/home/useHomeRooms.ts @@ -0,0 +1,14 @@ +import { useAtomValue } from 'jotai'; +import { useMatrixClient } from '../../../hooks/useMatrixClient'; +import { mDirectAtom } from '../../../state/mDirectList'; +import { roomToParentsAtom } from '../../../state/room/roomToParents'; +import { allRoomsAtom } from '../../../state/room-list/roomList'; +import { useOrphanRooms } from '../../../state/hooks/roomList'; + +export const useHomeRooms = () => { + const mx = useMatrixClient(); + const mDirects = useAtomValue(mDirectAtom); + const roomToParents = useAtomValue(roomToParentsAtom); + const rooms = useOrphanRooms(mx, allRoomsAtom, mDirects, roomToParents); + return rooms; +}; diff --git a/src/app/pages/client/inbox/Inbox.tsx b/src/app/pages/client/inbox/Inbox.tsx new file mode 100644 index 000000000..686296b76 --- /dev/null +++ b/src/app/pages/client/inbox/Inbox.tsx @@ -0,0 +1,87 @@ +import React from 'react'; +import { Avatar, Box, Icon, Icons, Text } from 'folds'; +import { useAtomValue } from 'jotai'; +import { NavCategory, NavItem, NavItemContent, NavLink } from '../../../components/nav'; +import { getInboxInvitesPath, getInboxNotificationsPath } from '../../pathUtils'; +import { + useInboxInvitesSelected, + useInboxNotificationsSelected, +} from '../../../hooks/router/useInbox'; +import { UnreadBadge } from '../../../components/unread-badge'; +import { allInvitesAtom } from '../../../state/room-list/inviteList'; +import { useNavToActivePathMapper } from '../../../hooks/useNavToActivePathMapper'; +import { PageNav, PageNavContent, PageNavHeader } from '../../../components/page'; + +function InvitesNavItem() { + const invitesSelected = useInboxInvitesSelected(); + const allInvites = useAtomValue(allInvitesAtom); + const inviteCount = allInvites.length; + + return ( + 0} + aria-selected={invitesSelected} + > + + + + + + + + + Invitations + + + {inviteCount > 0 && } + + + + + ); +} + +export function Inbox() { + useNavToActivePathMapper('inbox'); + const notificationsSelected = useInboxNotificationsSelected(); + + return ( + + + + + + Inbox + + + + + + + + + + + + + + + + + + Notifications + + + + + + + + + + + + ); +} diff --git a/src/app/pages/client/inbox/Invites.tsx b/src/app/pages/client/inbox/Invites.tsx new file mode 100644 index 000000000..91dc02910 --- /dev/null +++ b/src/app/pages/client/inbox/Invites.tsx @@ -0,0 +1,288 @@ +import React, { useCallback, useRef, useState } from 'react'; +import { + Avatar, + Box, + Button, + Icon, + Icons, + Overlay, + OverlayBackdrop, + OverlayCenter, + Scroll, + Spinner, + Text, + color, + config, +} from 'folds'; +import { useAtomValue } from 'jotai'; +import FocusTrap from 'focus-trap-react'; +import { MatrixError, Room } from 'matrix-js-sdk'; +import { Page, PageContent, PageContentCenter, PageHeader } from '../../../components/page'; +import { useDirectInvites, useRoomInvites, useSpaceInvites } from '../../../state/hooks/inviteList'; +import { useMatrixClient } from '../../../hooks/useMatrixClient'; +import { allInvitesAtom } from '../../../state/room-list/inviteList'; +import { mDirectAtom } from '../../../state/mDirectList'; +import { SequenceCard } from '../../../components/sequence-card'; +import { + getDirectRoomAvatarUrl, + getMemberDisplayName, + getRoomAvatarUrl, + isDirectInvite, +} from '../../../utils/room'; +import { nameInitials } from '../../../utils/common'; +import { RoomAvatar } from '../../../components/room-avatar'; +import { addRoomIdToMDirect, getMxIdLocalPart, guessDmRoomUserId } from '../../../utils/matrix'; +import { Time } from '../../../components/message'; +import { useElementSizeObserver } from '../../../hooks/useElementSizeObserver'; +import { onEnterOrSpace } from '../../../utils/keyboard'; +import { RoomTopicViewer } from '../../../components/room-topic-viewer'; +import { AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback'; +import { useRoomNavigate } from '../../../hooks/useRoomNavigate'; +import { useRoomTopic } from '../../../hooks/useRoomMeta'; + +const COMPACT_CARD_WIDTH = 548; + +type InviteCardProps = { + room: Room; + userId: string; + direct?: boolean; + compact?: boolean; + onNavigate: (roomId: string) => void; +}; +function InviteCard({ room, userId, direct, compact, onNavigate }: InviteCardProps) { + const mx = useMatrixClient(); + const roomName = room.name || room.getCanonicalAlias() || room.roomId; + const member = room.getMember(userId); + const memberEvent = member?.events.member; + const memberTs = memberEvent?.getTs() ?? 0; + const senderId = memberEvent?.getSender(); + const senderName = senderId + ? getMemberDisplayName(room, senderId) ?? getMxIdLocalPart(senderId) ?? senderId + : undefined; + + const topic = useRoomTopic(room); + + const [viewTopic, setViewTopic] = useState(false); + const closeTopic = () => setViewTopic(false); + const openTopic = () => setViewTopic(true); + + const [joinState, join] = useAsyncCallback( + useCallback(async () => { + const dmUserId = isDirectInvite(room, userId) ? guessDmRoomUserId(room, userId) : undefined; + + await mx.joinRoom(room.roomId); + if (dmUserId) { + await addRoomIdToMDirect(mx, room.roomId, dmUserId); + } + onNavigate(room.roomId); + }, [mx, room, userId, onNavigate]) + ); + const [leaveState, leave] = useAsyncCallback, MatrixError, []>( + useCallback(() => mx.leave(room.roomId), [mx, room]) + ); + + const joining = + joinState.status === AsyncStatus.Loading || joinState.status === AsyncStatus.Success; + const leaving = + leaveState.status === AsyncStatus.Loading || leaveState.status === AsyncStatus.Success; + + return ( + + + + + Invited by {senderName} + + + + + + + + ( + + {nameInitials(roomName)} + + )} + /> + + + + + + {roomName} + + {topic && ( + + {topic} + + )} + }> + + + + + + + + {joinState.status === AsyncStatus.Error && ( + + {joinState.error.message} + + )} + {leaveState.status === AsyncStatus.Error && ( + + {leaveState.error.message} + + )} + + + + + + + + + ); +} + +export function Invites() { + const mx = useMatrixClient(); + const userId = mx.getUserId()!; + const mDirects = useAtomValue(mDirectAtom); + const directInvites = useDirectInvites(mx, allInvitesAtom, mDirects); + const spaceInvites = useSpaceInvites(mx, allInvitesAtom); + const roomInvites = useRoomInvites(mx, allInvitesAtom, mDirects); + const containerRef = useRef(null); + const [compact, setCompact] = useState(document.body.clientWidth <= COMPACT_CARD_WIDTH); + useElementSizeObserver( + useCallback(() => containerRef.current, []), + useCallback((width) => setCompact(width <= COMPACT_CARD_WIDTH), []) + ); + + const { navigateRoom, navigateSpace } = useRoomNavigate(); + + const renderInvite = (roomId: string, direct: boolean, handleNavigate: (rId: string) => void) => { + const room = mx.getRoom(roomId); + if (!room) return null; + return ( + + ); + }; + + return ( + + + + + + Invitations + + + + + + + + + {directInvites.length > 0 && ( + + Direct Messages + + {directInvites.map((roomId) => renderInvite(roomId, true, navigateRoom))} + + + )} + {spaceInvites.length > 0 && ( + + Spaces + + {spaceInvites.map((roomId) => renderInvite(roomId, false, navigateSpace))} + + + )} + {roomInvites.length > 0 && ( + + Rooms + + {roomInvites.map((roomId) => renderInvite(roomId, false, navigateRoom))} + + + )} + {directInvites.length === 0 && + spaceInvites.length === 0 && + roomInvites.length === 0 && ( +
      + + No Pending Invitations + + You don't have any new pending invitations to display yet. + + +
      + )} +
      +
      +
      +
      +
      +
      + ); +} diff --git a/src/app/pages/client/inbox/Notifications.tsx b/src/app/pages/client/inbox/Notifications.tsx new file mode 100644 index 000000000..1ab08f01c --- /dev/null +++ b/src/app/pages/client/inbox/Notifications.tsx @@ -0,0 +1,609 @@ +/* eslint-disable react/destructuring-assignment */ +import React, { MouseEventHandler, useCallback, useEffect, useMemo, useRef, useState } from 'react'; +import { + Avatar, + Box, + Chip, + Header, + Icon, + IconButton, + Icons, + Scroll, + Text, + config, + toRem, +} from 'folds'; +import { useSearchParams } from 'react-router-dom'; +import { + INotification, + INotificationsResponse, + IRoomEvent, + JoinRule, + Method, + Room, +} from 'matrix-js-sdk'; +import { useVirtualizer } from '@tanstack/react-virtual'; +import { HTMLReactParserOptions } from 'html-react-parser'; +import { Page, PageContent, PageContentCenter, PageHeader } from '../../../components/page'; +import { useMatrixClient } from '../../../hooks/useMatrixClient'; +import { getMxIdLocalPart, isRoomId, isUserId } from '../../../utils/matrix'; +import { InboxNotificationsPathSearchParams } from '../../paths'; +import { AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback'; +import { SequenceCard } from '../../../components/sequence-card'; +import { RoomAvatar, RoomIcon } from '../../../components/room-avatar'; +import { getMemberAvatarMxc, getMemberDisplayName, getRoomAvatarUrl } from '../../../utils/room'; +import { ScrollTopContainer } from '../../../components/scroll-top-container'; +import { useInterval } from '../../../hooks/useInterval'; +import { + AvatarBase, + ImageContent, + MSticker, + ModernLayout, + RedactedContent, + Reply, + Time, + Username, +} from '../../../components/message'; +import colorMXID from '../../../../util/colorMXID'; +import { getReactCustomHtmlParser } from '../../../plugins/react-custom-html-parser'; +import { openJoinAlias, openProfileViewer } from '../../../../client/action/navigation'; +import { RenderMessageContent } from '../../../components/RenderMessageContent'; +import { useSetting } from '../../../state/hooks/settings'; +import { settingsAtom } from '../../../state/settings'; +import { Image } from '../../../components/media'; +import { ImageViewer } from '../../../components/image-viewer'; +import { GetContentCallback, MessageEvent, StateEvent } from '../../../../types/matrix/room'; +import { useMatrixEventRenderer } from '../../../hooks/useMatrixEventRenderer'; +import * as customHtmlCss from '../../../styles/CustomHtml.css'; +import { useRoomNavigate } from '../../../hooks/useRoomNavigate'; +import { useRoomUnread } from '../../../state/hooks/unread'; +import { roomToUnreadAtom } from '../../../state/room/roomToUnread'; +import { markAsRead } from '../../../../client/action/notifications'; +import { ContainerColor } from '../../../styles/ContainerColor.css'; +import { VirtualTile } from '../../../components/virtualizer'; +import { UserAvatar } from '../../../components/user-avatar'; + +type RoomNotificationsGroup = { + roomId: string; + notifications: INotification[]; +}; +type NotificationTimeline = { + nextToken?: string; + groups: RoomNotificationsGroup[]; +}; +type LoadTimeline = (from?: string) => Promise; +type SilentReloadTimeline = () => Promise; + +const groupNotifications = (notifications: INotification[]): RoomNotificationsGroup[] => { + const groups: RoomNotificationsGroup[] = []; + notifications.forEach((notification) => { + const groupIndex = groups.length - 1; + const lastAddedGroup: RoomNotificationsGroup | undefined = groups[groupIndex]; + if (lastAddedGroup && notification.room_id === lastAddedGroup.roomId) { + lastAddedGroup.notifications.push(notification); + return; + } + groups.push({ + roomId: notification.room_id, + notifications: [notification], + }); + }); + return groups; +}; + +const useNotificationTimeline = ( + paginationLimit: number, + onlyHighlight?: boolean +): [NotificationTimeline, LoadTimeline, SilentReloadTimeline] => { + const mx = useMatrixClient(); + const [notificationTimeline, setNotificationTimeline] = useState({ + groups: [], + }); + + const fetchNotifications = useCallback( + (from?: string, limit?: number, only?: 'highlight') => { + const queryParams = { from, limit, only }; + return mx.http.authedRequest( + Method.Get, + '/notifications', + queryParams + ); + }, + [mx] + ); + + const loadTimeline: LoadTimeline = useCallback( + async (from) => { + if (!from) { + setNotificationTimeline({ groups: [] }); + } + const data = await fetchNotifications( + from, + paginationLimit, + onlyHighlight ? 'highlight' : undefined + ); + const groups = groupNotifications(data.notifications); + + setNotificationTimeline((currentTimeline) => { + if (currentTimeline.nextToken === from) { + return { + nextToken: data.next_token, + groups: from ? currentTimeline.groups.concat(groups) : groups, + }; + } + return currentTimeline; + }); + }, + [paginationLimit, onlyHighlight, fetchNotifications] + ); + + /** + * Reload timeline silently i.e without setting to default + * before fetching notifications from start + */ + const silentReloadTimeline: SilentReloadTimeline = useCallback(async () => { + const data = await fetchNotifications( + undefined, + paginationLimit, + onlyHighlight ? 'highlight' : undefined + ); + const groups = groupNotifications(data.notifications); + setNotificationTimeline({ + nextToken: data.next_token, + groups, + }); + }, [paginationLimit, onlyHighlight, fetchNotifications]); + + return [notificationTimeline, loadTimeline, silentReloadTimeline]; +}; + +type RoomNotificationsGroupProps = { + room: Room; + notifications: INotification[]; + mediaAutoLoad?: boolean; + urlPreview?: boolean; + onOpen: (roomId: string, eventId: string) => void; +}; +function RoomNotificationsGroupComp({ + room, + notifications, + mediaAutoLoad, + urlPreview, + onOpen, +}: RoomNotificationsGroupProps) { + const mx = useMatrixClient(); + const unread = useRoomUnread(room.roomId, roomToUnreadAtom); + const { navigateRoom, navigateSpace } = useRoomNavigate(); + + const htmlReactParserOptions = useMemo( + () => + getReactCustomHtmlParser(mx, room, { + handleSpoilerClick: (evt) => { + const target = evt.currentTarget; + if (target.getAttribute('aria-pressed') === 'true') { + evt.stopPropagation(); + target.setAttribute('aria-pressed', 'false'); + target.style.cursor = 'initial'; + } + }, + handleMentionClick: (evt) => { + const target = evt.currentTarget; + const mentionId = target.getAttribute('data-mention-id'); + if (typeof mentionId !== 'string') return; + if (isUserId(mentionId)) { + openProfileViewer(mentionId, room.roomId); + return; + } + if (isRoomId(mentionId) && mx.getRoom(mentionId)) { + if (mx.getRoom(mentionId)?.isSpaceRoom()) navigateSpace(mentionId); + else navigateRoom(mentionId); + return; + } + openJoinAlias(mentionId); + }, + }), + [mx, room, navigateRoom, navigateSpace] + ); + + const renderMatrixEvent = useMatrixEventRenderer<[IRoomEvent, string, GetContentCallback]>( + { + [MessageEvent.RoomMessage]: (event, displayName, getContent) => { + if (event.unsigned?.redacted_because) { + return ; + } + + return ( + + ); + }, + [MessageEvent.Sticker]: (event, displayName, getContent) => { + if (event.unsigned?.redacted_because) { + return ; + } + return ( + ( + } + renderViewer={(p) => } + /> + )} + /> + ); + }, + [StateEvent.RoomTombstone]: (event) => { + const { content } = event; + return ( + + + Room Tombstone. {content.body} + + + ); + }, + }, + undefined, + (event) => { + if (event.unsigned?.redacted_because) { + return ; + } + return ( + + + {event.type} + {' event'} + + + ); + } + ); + + const handleOpenClick: MouseEventHandler = (evt) => { + const eventId = evt.currentTarget.getAttribute('data-event-id'); + if (!eventId) return; + onOpen(room.roomId, eventId); + }; + const handleMarkAsRead = () => { + markAsRead(room.roomId); + }; + + return ( + +
      + + + ( + + )} + /> + + + {room.name} + + + + {unread && ( + } + > + Mark as Read + + )} + +
      + + {notifications.map((notification) => { + const { event } = notification; + + const displayName = + getMemberDisplayName(room, event.sender) ?? + getMxIdLocalPart(event.sender) ?? + event.sender; + const senderAvatarMxc = getMemberAvatarMxc(room, event.sender); + const getContent = (() => event.content) as GetContentCallback; + + const replyEventId = event.content['m.relates_to']?.['m.in_reply_to']?.event_id; + + return ( + + + + } + /> + + + } + > + + + + + {displayName} + + + + + + Open + + + + {replyEventId && ( + + )} + {renderMatrixEvent(event.type, false, event, displayName, getContent)} + + + ); + })} + +
      + ); +} + +const useNotificationsSearchParams = ( + searchParams: URLSearchParams +): InboxNotificationsPathSearchParams => + useMemo( + () => ({ + only: searchParams.get('only') ?? undefined, + }), + [searchParams] + ); + +const DEFAULT_REFRESH_MS = 10000; + +export function Notifications() { + const mx = useMatrixClient(); + const [mediaAutoLoad] = useSetting(settingsAtom, 'mediaAutoLoad'); + const [urlPreview] = useSetting(settingsAtom, 'urlPreview'); + + const { navigateRoom } = useRoomNavigate(); + const [searchParams, setSearchParams] = useSearchParams(); + const notificationsSearchParams = useNotificationsSearchParams(searchParams); + const scrollRef = useRef(null); + const scrollTopAnchorRef = useRef(null); + const [refreshIntervalTime, setRefreshIntervalTime] = useState(DEFAULT_REFRESH_MS); + + const onlyHighlight = notificationsSearchParams.only === 'highlight'; + const setOnlyHighlighted = (highlight: boolean) => { + if (highlight) { + setSearchParams( + new URLSearchParams({ + only: 'highlight', + }) + ); + return; + } + setSearchParams(); + }; + + const [notificationTimeline, _loadTimeline, silentReloadTimeline] = useNotificationTimeline( + 24, + onlyHighlight + ); + const [timelineState, loadTimeline] = useAsyncCallback(_loadTimeline); + + const virtualizer = useVirtualizer({ + count: notificationTimeline.groups.length, + getScrollElement: () => scrollRef.current, + estimateSize: () => 40, + overscan: 4, + }); + const vItems = virtualizer.getVirtualItems(); + + useInterval( + useCallback(() => { + if (document.hasFocus()) { + silentReloadTimeline(); + } + }, [silentReloadTimeline]), + refreshIntervalTime + ); + + const handleScrollTopVisibility = useCallback( + (onTop: boolean) => setRefreshIntervalTime(onTop ? DEFAULT_REFRESH_MS : -1), + [] + ); + + useEffect(() => { + loadTimeline(); + }, [loadTimeline]); + + const lastVItem = vItems[vItems.length - 1]; + const lastVItemIndex: number | undefined = lastVItem?.index; + useEffect(() => { + if ( + timelineState.status === AsyncStatus.Success && + notificationTimeline.groups.length - 1 === lastVItemIndex && + notificationTimeline.nextToken + ) { + loadTimeline(notificationTimeline.nextToken); + } + }, [timelineState, notificationTimeline, lastVItemIndex, loadTimeline]); + + return ( + + + + + + Notification Messages + + + + + + + + + + + + Filter + + setOnlyHighlighted(false)} + variant={!onlyHighlight ? 'Success' : 'Surface'} + aria-pressed={!onlyHighlight} + before={!onlyHighlight && } + outlined + > + All Notifications + + setOnlyHighlighted(true)} + variant={onlyHighlight ? 'Success' : 'Surface'} + aria-pressed={onlyHighlight} + before={onlyHighlight && } + outlined + > + Highlighted + + + + + virtualizer.scrollToOffset(0)} + variant="SurfaceVariant" + radii="Pill" + outlined + size="300" + aria-label="Scroll to Top" + > + + + +
      + {vItems.map((vItem) => { + const group = notificationTimeline.groups[vItem.index]; + if (!group) return null; + const groupRoom = mx.getRoom(group.roomId); + if (!groupRoom) return null; + + return ( + + + + ); + })} +
      + + {timelineState.status === AsyncStatus.Success && + notificationTimeline.groups.length === 0 && ( + + No Notifications + + You don't have any new notifications to display yet. + + + )} + + {timelineState.status === AsyncStatus.Loading && ( + + {[...Array(8).keys()].map((key) => ( + + ))} + + )} + {timelineState.status === AsyncStatus.Error && ( + + {(timelineState.error as Error).name} + {(timelineState.error as Error).message} + + )} +
      +
      +
      +
      +
      +
      + ); +} diff --git a/src/app/pages/client/inbox/index.ts b/src/app/pages/client/inbox/index.ts new file mode 100644 index 000000000..c8036b471 --- /dev/null +++ b/src/app/pages/client/inbox/index.ts @@ -0,0 +1,3 @@ +export * from './Inbox'; +export * from './Notifications'; +export * from './Invites'; diff --git a/src/app/pages/client/index.ts b/src/app/pages/client/index.ts new file mode 100644 index 000000000..5668e81de --- /dev/null +++ b/src/app/pages/client/index.ts @@ -0,0 +1,3 @@ +export * from './ClientRoot'; +export * from './ClientBindAtoms'; +export * from './ClientLayout'; diff --git a/src/app/pages/client/sidebar/DirectTab.tsx b/src/app/pages/client/sidebar/DirectTab.tsx new file mode 100644 index 000000000..f25d7bdc7 --- /dev/null +++ b/src/app/pages/client/sidebar/DirectTab.tsx @@ -0,0 +1,132 @@ +import React, { MouseEventHandler, forwardRef, useState } from 'react'; +import { useNavigate } from 'react-router-dom'; +import { Box, Icon, Icons, Menu, MenuItem, PopOut, RectCords, Text, config, toRem } from 'folds'; +import FocusTrap from 'focus-trap-react'; +import { useAtomValue } from 'jotai'; +import { useDirects } from '../../../state/hooks/roomList'; +import { useMatrixClient } from '../../../hooks/useMatrixClient'; +import { mDirectAtom } from '../../../state/mDirectList'; +import { allRoomsAtom } from '../../../state/room-list/roomList'; +import { roomToUnreadAtom } from '../../../state/room/roomToUnread'; +import { getDirectPath, joinPathComponent } from '../../pathUtils'; +import { useRoomsUnread } from '../../../state/hooks/unread'; +import { + SidebarAvatar, + SidebarItem, + SidebarItemBadge, + SidebarItemTooltip, +} from '../../../components/sidebar'; +import { useDirectSelected } from '../../../hooks/router/useDirectSelected'; +import { UnreadBadge } from '../../../components/unread-badge'; +import { ScreenSize, useScreenSizeContext } from '../../../hooks/useScreenSize'; +import { useNavToActivePathAtom } from '../../../state/hooks/navToActivePath'; +import { useDirectRooms } from '../direct/useDirectRooms'; +import { markAsRead } from '../../../../client/action/notifications'; + +type DirectMenuProps = { + requestClose: () => void; +}; +const DirectMenu = forwardRef(({ requestClose }, ref) => { + const orphanRooms = useDirectRooms(); + const unread = useRoomsUnread(orphanRooms, roomToUnreadAtom); + + const handleMarkAsRead = () => { + if (!unread) return; + orphanRooms.forEach((rId) => markAsRead(rId)); + requestClose(); + }; + + return ( + + + } + radii="300" + aria-disabled={!unread} + > + + Mark as Read + + + + + ); +}); + +export function DirectTab() { + const navigate = useNavigate(); + const mx = useMatrixClient(); + const screenSize = useScreenSizeContext(); + const navToActivePath = useAtomValue(useNavToActivePathAtom()); + + const mDirects = useAtomValue(mDirectAtom); + const directs = useDirects(mx, allRoomsAtom, mDirects); + const directUnread = useRoomsUnread(directs, roomToUnreadAtom); + const [menuAnchor, setMenuAnchor] = useState(); + + const directSelected = useDirectSelected(); + + const handleDirectClick = () => { + const activePath = navToActivePath.get('direct'); + if (activePath && screenSize !== ScreenSize.Mobile) { + navigate(joinPathComponent(activePath)); + return; + } + + navigate(getDirectPath()); + }; + + const handleContextMenu: MouseEventHandler = (evt) => { + evt.preventDefault(); + const cords = evt.currentTarget.getBoundingClientRect(); + setMenuAnchor((currentState) => { + if (currentState) return undefined; + return cords; + }); + }; + return ( + + + {(triggerRef) => ( + + + + )} + + {directUnread && ( + 0}> + 0} count={directUnread.total} /> + + )} + {menuAnchor && ( + setMenuAnchor(undefined), + clickOutsideDeactivates: true, + isKeyForward: (evt: KeyboardEvent) => evt.key === 'ArrowDown', + isKeyBackward: (evt: KeyboardEvent) => evt.key === 'ArrowUp', + }} + > + setMenuAnchor(undefined)} /> + + } + /> + )} + + ); +} diff --git a/src/app/pages/client/sidebar/ExploreTab.tsx b/src/app/pages/client/sidebar/ExploreTab.tsx new file mode 100644 index 000000000..a45b58309 --- /dev/null +++ b/src/app/pages/client/sidebar/ExploreTab.tsx @@ -0,0 +1,64 @@ +import React from 'react'; +import { Icon, Icons } from 'folds'; +import { useNavigate } from 'react-router-dom'; +import { useAtomValue } from 'jotai'; +import { SidebarAvatar, SidebarItem, SidebarItemTooltip } from '../../../components/sidebar'; +import { useExploreSelected } from '../../../hooks/router/useExploreSelected'; +import { + getExploreFeaturedPath, + getExplorePath, + getExploreServerPath, + joinPathComponent, +} from '../../pathUtils'; +import { useClientConfig } from '../../../hooks/useClientConfig'; +import { useMatrixClient } from '../../../hooks/useMatrixClient'; +import { getMxIdServer } from '../../../utils/matrix'; +import { ScreenSize, useScreenSizeContext } from '../../../hooks/useScreenSize'; +import { useNavToActivePathAtom } from '../../../state/hooks/navToActivePath'; + +export function ExploreTab() { + const mx = useMatrixClient(); + const screenSize = useScreenSizeContext(); + const clientConfig = useClientConfig(); + const navigate = useNavigate(); + const navToActivePath = useAtomValue(useNavToActivePathAtom()); + + const exploreSelected = useExploreSelected(); + + const handleExploreClick = () => { + if (screenSize === ScreenSize.Mobile) { + navigate(getExplorePath()); + return; + } + + const activePath = navToActivePath.get('explore'); + if (activePath) { + navigate(joinPathComponent(activePath)); + return; + } + + if (clientConfig.featuredCommunities?.openAsDefault) { + navigate(getExploreFeaturedPath()); + return; + } + const userId = mx.getUserId(); + const userServer = userId ? getMxIdServer(userId) : undefined; + if (userServer) { + navigate(getExploreServerPath(userServer)); + return; + } + navigate(getExplorePath()); + }; + + return ( + + + {(triggerRef) => ( + + + + )} + + + ); +} diff --git a/src/app/pages/client/sidebar/HomeTab.tsx b/src/app/pages/client/sidebar/HomeTab.tsx new file mode 100644 index 000000000..0b5135cae --- /dev/null +++ b/src/app/pages/client/sidebar/HomeTab.tsx @@ -0,0 +1,134 @@ +import React, { MouseEventHandler, forwardRef, useState } from 'react'; +import { useNavigate } from 'react-router-dom'; +import { Box, Icon, Icons, Menu, MenuItem, PopOut, RectCords, Text, config, toRem } from 'folds'; +import { useAtomValue } from 'jotai'; +import FocusTrap from 'focus-trap-react'; +import { useOrphanRooms } from '../../../state/hooks/roomList'; +import { useMatrixClient } from '../../../hooks/useMatrixClient'; +import { mDirectAtom } from '../../../state/mDirectList'; +import { roomToParentsAtom } from '../../../state/room/roomToParents'; +import { allRoomsAtom } from '../../../state/room-list/roomList'; +import { roomToUnreadAtom } from '../../../state/room/roomToUnread'; +import { getHomePath, joinPathComponent } from '../../pathUtils'; +import { useRoomsUnread } from '../../../state/hooks/unread'; +import { + SidebarAvatar, + SidebarItem, + SidebarItemBadge, + SidebarItemTooltip, +} from '../../../components/sidebar'; +import { useHomeSelected } from '../../../hooks/router/useHomeSelected'; +import { UnreadBadge } from '../../../components/unread-badge'; +import { ScreenSize, useScreenSizeContext } from '../../../hooks/useScreenSize'; +import { useNavToActivePathAtom } from '../../../state/hooks/navToActivePath'; +import { useHomeRooms } from '../home/useHomeRooms'; +import { markAsRead } from '../../../../client/action/notifications'; + +type HomeMenuProps = { + requestClose: () => void; +}; +const HomeMenu = forwardRef(({ requestClose }, ref) => { + const orphanRooms = useHomeRooms(); + const unread = useRoomsUnread(orphanRooms, roomToUnreadAtom); + + const handleMarkAsRead = () => { + if (!unread) return; + orphanRooms.forEach((rId) => markAsRead(rId)); + requestClose(); + }; + + return ( + + + } + radii="300" + aria-disabled={!unread} + > + + Mark as Read + + + + + ); +}); + +export function HomeTab() { + const navigate = useNavigate(); + const mx = useMatrixClient(); + const screenSize = useScreenSizeContext(); + const navToActivePath = useAtomValue(useNavToActivePathAtom()); + + const mDirects = useAtomValue(mDirectAtom); + const roomToParents = useAtomValue(roomToParentsAtom); + const orphanRooms = useOrphanRooms(mx, allRoomsAtom, mDirects, roomToParents); + const homeUnread = useRoomsUnread(orphanRooms, roomToUnreadAtom); + const homeSelected = useHomeSelected(); + const [menuAnchor, setMenuAnchor] = useState(); + + const handleHomeClick = () => { + const activePath = navToActivePath.get('home'); + if (activePath && screenSize !== ScreenSize.Mobile) { + navigate(joinPathComponent(activePath)); + return; + } + + navigate(getHomePath()); + }; + + const handleContextMenu: MouseEventHandler = (evt) => { + evt.preventDefault(); + const cords = evt.currentTarget.getBoundingClientRect(); + setMenuAnchor((currentState) => { + if (currentState) return undefined; + return cords; + }); + }; + + return ( + + + {(triggerRef) => ( + + + + )} + + {homeUnread && ( + 0}> + 0} count={homeUnread.total} /> + + )} + {menuAnchor && ( + setMenuAnchor(undefined), + clickOutsideDeactivates: true, + isKeyForward: (evt: KeyboardEvent) => evt.key === 'ArrowDown', + isKeyBackward: (evt: KeyboardEvent) => evt.key === 'ArrowUp', + }} + > + setMenuAnchor(undefined)} /> + + } + /> + )} + + ); +} diff --git a/src/app/pages/client/sidebar/InboxTab.tsx b/src/app/pages/client/sidebar/InboxTab.tsx new file mode 100644 index 000000000..5d13a9ab6 --- /dev/null +++ b/src/app/pages/client/sidebar/InboxTab.tsx @@ -0,0 +1,62 @@ +import React from 'react'; +import { useNavigate } from 'react-router-dom'; +import { Icon, Icons } from 'folds'; +import { useAtomValue } from 'jotai'; +import { + SidebarAvatar, + SidebarItem, + SidebarItemBadge, + SidebarItemTooltip, +} from '../../../components/sidebar'; +import { allInvitesAtom } from '../../../state/room-list/inviteList'; +import { + getInboxInvitesPath, + getInboxNotificationsPath, + getInboxPath, + joinPathComponent, +} from '../../pathUtils'; +import { useInboxSelected } from '../../../hooks/router/useInbox'; +import { UnreadBadge } from '../../../components/unread-badge'; +import { ScreenSize, useScreenSizeContext } from '../../../hooks/useScreenSize'; +import { useNavToActivePathAtom } from '../../../state/hooks/navToActivePath'; + +export function InboxTab() { + const screenSize = useScreenSizeContext(); + const navigate = useNavigate(); + const navToActivePath = useAtomValue(useNavToActivePathAtom()); + const inboxSelected = useInboxSelected(); + const allInvites = useAtomValue(allInvitesAtom); + const inviteCount = allInvites.length; + + const handleInboxClick = () => { + if (screenSize === ScreenSize.Mobile) { + navigate(getInboxPath()); + return; + } + const activePath = navToActivePath.get('inbox'); + if (activePath) { + navigate(joinPathComponent(activePath)); + return; + } + + const path = inviteCount > 0 ? getInboxInvitesPath() : getInboxNotificationsPath(); + navigate(path); + }; + + return ( + + + {(triggerRef) => ( + + + + )} + + {inviteCount > 0 && ( + + + + )} + + ); +} diff --git a/src/app/pages/client/sidebar/SpaceTabs.tsx b/src/app/pages/client/sidebar/SpaceTabs.tsx new file mode 100644 index 000000000..99c04965f --- /dev/null +++ b/src/app/pages/client/sidebar/SpaceTabs.tsx @@ -0,0 +1,844 @@ +import React, { + MouseEventHandler, + ReactNode, + RefObject, + forwardRef, + useCallback, + useEffect, + useMemo, + useRef, + useState, +} from 'react'; +import { useNavigate } from 'react-router-dom'; +import { + Box, + Icon, + IconButton, + Icons, + Line, + Menu, + MenuItem, + PopOut, + RectCords, + Text, + config, + toRem, +} from 'folds'; +import { useAtom, useAtomValue } from 'jotai'; +import { Room } from 'matrix-js-sdk'; +import { + draggable, + dropTargetForElements, + monitorForElements, +} from '@atlaskit/pragmatic-drag-and-drop/element/adapter'; +import { + attachInstruction, + extractInstruction, + Instruction, +} from '@atlaskit/pragmatic-drag-and-drop-hitbox/tree-item'; +import { autoScrollForElements } from '@atlaskit/pragmatic-drag-and-drop-auto-scroll/element'; +import { combine } from '@atlaskit/pragmatic-drag-and-drop/combine'; +import FocusTrap from 'focus-trap-react'; +import { + useOrphanSpaces, + useRecursiveChildScopeFactory, + useSpaceChildren, +} from '../../../state/hooks/roomList'; +import { useMatrixClient } from '../../../hooks/useMatrixClient'; +import { roomToParentsAtom } from '../../../state/room/roomToParents'; +import { allRoomsAtom } from '../../../state/room-list/roomList'; +import { + getOriginBaseUrl, + getSpaceLobbyPath, + getSpacePath, + joinPathComponent, + withOriginBaseUrl, +} from '../../pathUtils'; +import { + SidebarAvatar, + SidebarItem, + SidebarItemBadge, + SidebarItemTooltip, + SidebarStack, + SidebarStackSeparator, + SidebarFolder, + SidebarFolderDropTarget, +} from '../../../components/sidebar'; +import { RoomUnreadProvider, RoomsUnreadProvider } from '../../../components/RoomUnreadProvider'; +import { useSelectedSpace } from '../../../hooks/router/useSelectedSpace'; +import { UnreadBadge } from '../../../components/unread-badge'; +import { getCanonicalAliasOrRoomId } from '../../../utils/matrix'; +import { RoomAvatar } from '../../../components/room-avatar'; +import { nameInitials, randomStr } from '../../../utils/common'; +import { + ISidebarFolder, + SidebarItems, + TSidebarItem, + makeCinnySpacesContent, + parseSidebar, + sidebarItemWithout, + useSidebarItems, +} from '../../../hooks/useSidebarItems'; +import { AccountDataEvent } from '../../../../types/matrix/accountData'; +import { ScreenSize, useScreenSizeContext } from '../../../hooks/useScreenSize'; +import { useNavToActivePathAtom } from '../../../state/hooks/navToActivePath'; +import { useOpenedSidebarFolderAtom } from '../../../state/hooks/openedSidebarFolder'; +import { useClientConfig } from '../../../hooks/useClientConfig'; +import { usePowerLevels, usePowerLevelsAPI } from '../../../hooks/usePowerLevels'; +import { useRoomsUnread } from '../../../state/hooks/unread'; +import { roomToUnreadAtom } from '../../../state/room/roomToUnread'; +import { markAsRead } from '../../../../client/action/notifications'; +import { copyToClipboard } from '../../../utils/dom'; +import { openInviteUser, openSpaceSettings } from '../../../../client/action/navigation'; + +type SpaceMenuProps = { + room: Room; + requestClose: () => void; + onUnpin?: (roomId: string) => void; +}; +const SpaceMenu = forwardRef( + ({ room, requestClose, onUnpin }, ref) => { + const mx = useMatrixClient(); + const { hashRouter } = useClientConfig(); + const roomToParents = useAtomValue(roomToParentsAtom); + const powerLevels = usePowerLevels(room); + const { getPowerLevel, canDoAction } = usePowerLevelsAPI(powerLevels); + const canInvite = canDoAction('invite', getPowerLevel(mx.getUserId() ?? '')); + + const allChild = useSpaceChildren( + allRoomsAtom, + room.roomId, + useRecursiveChildScopeFactory(mx, roomToParents) + ); + const unread = useRoomsUnread(allChild, roomToUnreadAtom); + + const handleMarkAsRead = () => { + allChild.forEach((childRoomId) => markAsRead(childRoomId)); + requestClose(); + }; + + const handleUnpin = () => { + onUnpin?.(room.roomId); + requestClose(); + }; + + const handleCopyLink = () => { + const spacePath = getSpacePath(getCanonicalAliasOrRoomId(mx, room.roomId)); + copyToClipboard(withOriginBaseUrl(getOriginBaseUrl(hashRouter), spacePath)); + requestClose(); + }; + + const handleInvite = () => { + openInviteUser(room.roomId); + requestClose(); + }; + + const handleRoomSettings = () => { + openSpaceSettings(room.roomId); + requestClose(); + }; + + return ( + + + } + radii="300" + disabled={!unread} + > + + Mark as Read + + + {onUnpin && ( + } + > + + Unpin + + + )} + + + + } + radii="300" + disabled={!canInvite} + > + + Invite + + + } + radii="300" + > + + Copy Link + + + } + radii="300" + > + + Space Settings + + + + + ); + } +); + +type InstructionType = Instruction['type']; +type FolderDraggable = { + folder: ISidebarFolder; + spaceId?: string; + open?: boolean; +}; +type SidebarDraggable = string | FolderDraggable; + +const useDraggableItem = ( + item: SidebarDraggable, + targetRef: RefObject, + onDragging: (item?: SidebarDraggable) => void, + dragHandleRef?: RefObject +): boolean => { + const [dragging, setDragging] = useState(false); + + useEffect(() => { + const target = targetRef.current; + const dragHandle = dragHandleRef?.current ?? undefined; + + return !target + ? undefined + : draggable({ + element: target, + dragHandle, + getInitialData: () => ({ item }), + onDragStart: () => { + setDragging(true); + onDragging?.(item); + }, + onDrop: () => { + setDragging(false); + onDragging?.(undefined); + }, + }); + }, [targetRef, dragHandleRef, item, onDragging]); + + return dragging; +}; + +const useDropTarget = ( + item: SidebarDraggable, + targetRef: RefObject +): Instruction | undefined => { + const [dropState, setDropState] = useState(); + + useEffect(() => { + const target = targetRef.current; + if (!target) return undefined; + + return dropTargetForElements({ + element: target, + canDrop: ({ source }) => { + const dragItem = source.data.item as SidebarDraggable; + return dragItem !== item; + }, + getData: ({ input, element }) => { + const block: Instruction['type'][] = ['reparent']; + if (typeof item === 'object' && item.spaceId) block.push('make-child'); + + const insData = attachInstruction( + {}, + { + input, + element, + currentLevel: 0, + indentPerLevel: 0, + mode: 'standard', + block, + } + ); + + const instruction: Instruction | null = extractInstruction(insData); + setDropState(instruction ?? undefined); + + return { + item, + instructionType: instruction ? instruction.type : undefined, + }; + }, + onDragLeave: () => setDropState(undefined), + onDrop: () => setDropState(undefined), + }); + }, [item, targetRef]); + + return dropState; +}; + +function useDropTargetInstruction( + item: SidebarDraggable, + targetRef: RefObject, + instructionType: T +): T | undefined { + const [dropState, setDropState] = useState(); + + useEffect(() => { + const target = targetRef.current; + if (!target) return undefined; + + return dropTargetForElements({ + element: target, + canDrop: ({ source }) => { + const dragItem = source.data.item as SidebarDraggable; + return dragItem !== item; + }, + getData: () => { + setDropState(instructionType); + + return { + item, + instructionType, + }; + }, + onDragLeave: () => setDropState(undefined), + onDrop: () => setDropState(undefined), + }); + }, [item, targetRef, instructionType]); + + return dropState; +} + +const useDnDMonitor = ( + scrollRef: RefObject, + onDragging: (dragItem?: SidebarDraggable) => void, + onReorder: ( + draggable: SidebarDraggable, + container: SidebarDraggable, + instruction: InstructionType + ) => void +) => { + useEffect(() => { + const scrollElement = scrollRef.current; + if (!scrollElement) { + throw Error('Scroll element ref not configured'); + } + + return combine( + monitorForElements({ + onDrop: ({ source, location }) => { + onDragging(undefined); + const { dropTargets } = location.current; + if (dropTargets.length === 0) return; + const item = source.data.item as SidebarDraggable; + const containerItem = dropTargets[0].data.item as SidebarDraggable; + const instructionType = dropTargets[0].data.instructionType as + | InstructionType + | undefined; + if (!instructionType) return; + onReorder(item, containerItem, instructionType); + }, + }), + autoScrollForElements({ + element: scrollElement, + }) + ); + }, [scrollRef, onDragging, onReorder]); +}; + +type SpaceTabProps = { + space: Room; + selected: boolean; + onClick: MouseEventHandler; + folder?: ISidebarFolder; + onDragging: (dragItem?: SidebarDraggable) => void; + disabled?: boolean; + onUnpin?: (roomId: string) => void; +}; +function SpaceTab({ + space, + selected, + onClick, + folder, + onDragging, + disabled, + onUnpin, +}: SpaceTabProps) { + const mx = useMatrixClient(); + const targetRef = useRef(null); + + const spaceDraggable: SidebarDraggable = useMemo( + () => + folder + ? { + folder, + spaceId: space.roomId, + } + : space.roomId, + [folder, space] + ); + + useDraggableItem(spaceDraggable, targetRef, onDragging); + const dropState = useDropTarget(spaceDraggable, targetRef); + const dropType = dropState?.type; + + const [menuAnchor, setMenuAnchor] = useState(); + + const handleContextMenu: MouseEventHandler = (evt) => { + evt.preventDefault(); + const cords = evt.currentTarget.getBoundingClientRect(); + setMenuAnchor((currentState) => { + if (currentState) return undefined; + return cords; + }); + }; + + return ( + + {(unread) => ( + + + {(triggerRef) => ( + + ( + {nameInitials(space.name, 2)} + )} + /> + + )} + + {unread && ( + 0}> + 0} count={unread.total} /> + + )} + {menuAnchor && ( + setMenuAnchor(undefined), + clickOutsideDeactivates: true, + isKeyForward: (evt: KeyboardEvent) => evt.key === 'ArrowDown', + isKeyBackward: (evt: KeyboardEvent) => evt.key === 'ArrowUp', + }} + > + setMenuAnchor(undefined)} + onUnpin={onUnpin} + /> + + } + /> + )} + + )} + + ); +} + +type OpenedSpaceFolderProps = { + folder: ISidebarFolder; + onClose: MouseEventHandler; + children?: ReactNode; +}; +function OpenedSpaceFolder({ folder, onClose, children }: OpenedSpaceFolderProps) { + const aboveTargetRef = useRef(null); + const belowTargetRef = useRef(null); + + const spaceDraggable: SidebarDraggable = useMemo(() => ({ folder, open: true }), [folder]); + + const orderAbove = useDropTargetInstruction(spaceDraggable, aboveTargetRef, 'reorder-above'); + const orderBelow = useDropTargetInstruction(spaceDraggable, belowTargetRef, 'reorder-below'); + + return ( + + + + + + + + {children} + + + ); +} + +type ClosedSpaceFolderProps = { + folder: ISidebarFolder; + selected: boolean; + onOpen: MouseEventHandler; + onDragging: (dragItem?: SidebarDraggable) => void; + disabled?: boolean; +}; +function ClosedSpaceFolder({ + folder, + selected, + onOpen, + onDragging, + disabled, +}: ClosedSpaceFolderProps) { + const mx = useMatrixClient(); + const handlerRef = useRef(null); + + const spaceDraggable: FolderDraggable = useMemo(() => ({ folder }), [folder]); + useDraggableItem(spaceDraggable, handlerRef, onDragging); + const dropState = useDropTarget(spaceDraggable, handlerRef); + const dropType = dropState?.type; + + const tooltipName = + folder.name ?? folder.content.map((i) => mx.getRoom(i)?.name ?? '').join(', ') ?? 'Unnamed'; + + return ( + + {(unread) => ( + + + {(tooltipRef) => ( + + {folder.content.map((sId) => { + const space = mx.getRoom(sId); + if (!space) return null; + + return ( + + ( + + {nameInitials(space.name, 2)} + + )} + /> + + ); + })} + + )} + + {unread && ( + 0}> + 0} count={unread.total} /> + + )} + + )} + + ); +} + +type SpaceTabsProps = { + scrollRef: RefObject; +}; +export function SpaceTabs({ scrollRef }: SpaceTabsProps) { + const navigate = useNavigate(); + const mx = useMatrixClient(); + const screenSize = useScreenSizeContext(); + const roomToParents = useAtomValue(roomToParentsAtom); + const orphanSpaces = useOrphanSpaces(mx, allRoomsAtom, roomToParents); + const [sidebarItems, localEchoSidebarItem] = useSidebarItems(orphanSpaces); + const navToActivePath = useAtomValue(useNavToActivePathAtom()); + const [openedFolder, setOpenedFolder] = useAtom(useOpenedSidebarFolderAtom()); + const [draggingItem, setDraggingItem] = useState(); + + useDnDMonitor( + scrollRef, + setDraggingItem, + useCallback( + (item, containerItem, instructionType) => { + const newItems: SidebarItems = []; + + const matchDest = (sI: TSidebarItem, dI: SidebarDraggable): boolean => { + if (typeof sI === 'string' && typeof dI === 'string') { + return sI === dI; + } + if (typeof sI === 'object' && typeof dI === 'object') { + return sI.id === dI.folder.id; + } + return false; + }; + const itemAsFolderContent = (i: SidebarDraggable): string[] => { + if (typeof i === 'string') { + return [i]; + } + if (i.spaceId) { + return [i.spaceId]; + } + return [...i.folder.content]; + }; + + sidebarItems.forEach((i) => { + const sameFolders = + typeof item === 'object' && + typeof containerItem === 'object' && + item.folder.id === containerItem.folder.id; + + // remove draggable space from current position or folder + if (!sameFolders && matchDest(i, item)) { + if (typeof item === 'object' && item.spaceId) { + const folderContent = item.folder.content.filter((s) => s !== item.spaceId); + if (folderContent.length === 0) { + // remove open state from local storage + setOpenedFolder({ type: 'DELETE', id: item.folder.id }); + return; + } + newItems.push({ + ...item.folder, + content: folderContent, + }); + } + return; + } + if (matchDest(i, containerItem)) { + // we can make child only if + // container item is space or closed folder + if (instructionType === 'make-child') { + const child: string[] = itemAsFolderContent(item); + if (typeof containerItem === 'string') { + const folder: ISidebarFolder = { + id: randomStr(), + content: [containerItem].concat(child), + }; + newItems.push(folder); + return; + } + newItems.push({ + ...containerItem.folder, + content: containerItem.folder.content.concat(child), + }); + return; + } + + // drop inside opened folder + // or reordering inside same folder + if (typeof containerItem === 'object' && containerItem.spaceId) { + const child = itemAsFolderContent(item); + const newContent: string[] = []; + containerItem.folder.content + .filter((sId) => !child.includes(sId)) + .forEach((sId) => { + if (sId === containerItem.spaceId) { + if (instructionType === 'reorder-below') { + newContent.push(sId, ...child); + } + if (instructionType === 'reorder-above') { + newContent.push(...child, sId); + } + return; + } + newContent.push(sId); + }); + const folder = { + ...containerItem.folder, + content: newContent, + }; + + newItems.push(folder); + return; + } + + // drop above or below space or closed/opened folder + if (typeof item === 'string') { + if (instructionType === 'reorder-below') newItems.push(i); + newItems.push(item); + if (instructionType === 'reorder-above') newItems.push(i); + } else if (item.spaceId) { + if (instructionType === 'reorder-above') { + newItems.push(item.spaceId); + } + if (sameFolders && typeof i === 'object') { + // remove from folder if placing around itself + const newI = { ...i, content: i.content.filter((sId) => sId !== item.spaceId) }; + if (newI.content.length > 0) newItems.push(newI); + } else { + newItems.push(i); + } + if (instructionType === 'reorder-below') { + newItems.push(item.spaceId); + } + } else { + if (instructionType === 'reorder-below') newItems.push(i); + newItems.push(item.folder); + if (instructionType === 'reorder-above') newItems.push(i); + } + return; + } + newItems.push(i); + }); + + const newSpacesContent = makeCinnySpacesContent(mx, newItems); + localEchoSidebarItem(parseSidebar(mx, orphanSpaces, newSpacesContent)); + mx.setAccountData(AccountDataEvent.CinnySpaces, newSpacesContent); + }, + [mx, sidebarItems, setOpenedFolder, localEchoSidebarItem, orphanSpaces] + ) + ); + + const selectedSpaceId = useSelectedSpace(); + + const handleSpaceClick: MouseEventHandler = (evt) => { + const target = evt.currentTarget; + const targetSpaceId = target.getAttribute('data-id'); + if (!targetSpaceId) return; + + if (screenSize === ScreenSize.Mobile) { + navigate(getSpacePath(getCanonicalAliasOrRoomId(mx, targetSpaceId))); + return; + } + + const activePath = navToActivePath.get(targetSpaceId); + if (activePath) { + navigate(joinPathComponent(activePath)); + return; + } + + navigate(getSpaceLobbyPath(getCanonicalAliasOrRoomId(mx, targetSpaceId))); + }; + + const handleFolderToggle: MouseEventHandler = (evt) => { + const target = evt.currentTarget; + const targetFolderId = target.getAttribute('data-id'); + if (!targetFolderId) return; + + setOpenedFolder({ + type: openedFolder.has(targetFolderId) ? 'DELETE' : 'PUT', + id: targetFolderId, + }); + }; + + const handleUnpin = useCallback( + (roomId: string) => { + if (orphanSpaces.includes(roomId)) return; + const newItems = sidebarItemWithout(sidebarItems, roomId); + + const newSpacesContent = makeCinnySpacesContent(mx, newItems); + localEchoSidebarItem(parseSidebar(mx, orphanSpaces, newSpacesContent)); + mx.setAccountData(AccountDataEvent.CinnySpaces, newSpacesContent); + }, + [mx, sidebarItems, orphanSpaces, localEchoSidebarItem] + ); + + if (sidebarItems.length === 0) return null; + return ( + <> + + + {sidebarItems.map((item) => { + if (typeof item === 'object') { + if (openedFolder.has(item.id)) { + return ( + + {item.content.map((sId) => { + const space = mx.getRoom(sId); + if (!space) return null; + return ( + + ); + })} + + ); + } + + return ( + + ); + } + + const space = mx.getRoom(item); + if (!space) return null; + + return ( + + ); + })} + + + ); +} diff --git a/src/app/pages/client/sidebar/UserTab.tsx b/src/app/pages/client/sidebar/UserTab.tsx new file mode 100644 index 000000000..89c035bba --- /dev/null +++ b/src/app/pages/client/sidebar/UserTab.tsx @@ -0,0 +1,63 @@ +import React, { useEffect, useState } from 'react'; +import { Text } from 'folds'; +import { UserEvent, UserEventHandlerMap } from 'matrix-js-sdk'; +import { SidebarItem, SidebarItemTooltip, SidebarAvatar } from '../../../components/sidebar'; +import { openSettings } from '../../../../client/action/navigation'; +import { UserAvatar } from '../../../components/user-avatar'; +import { useMatrixClient } from '../../../hooks/useMatrixClient'; +import { getMxIdLocalPart } from '../../../utils/matrix'; +import { nameInitials } from '../../../utils/common'; + +type UserProfile = { + avatar_url?: string; + displayname?: string; +}; +export function UserTab() { + const mx = useMatrixClient(); + const userId = mx.getUserId()!; + + const [profile, setProfile] = useState({}); + const displayName = profile.displayname ?? getMxIdLocalPart(userId) ?? userId; + const avatarUrl = profile.avatar_url + ? mx.mxcUrlToHttp(profile.avatar_url, 96, 96, 'crop') ?? undefined + : undefined; + + useEffect(() => { + const user = mx.getUser(userId); + const onAvatarChange: UserEventHandlerMap[UserEvent.AvatarUrl] = (event, myUser) => { + setProfile((cp) => ({ + ...cp, + avatar_url: myUser.avatarUrl, + })); + }; + const onDisplayNameChange: UserEventHandlerMap[UserEvent.DisplayName] = (event, myUser) => { + setProfile((cp) => ({ + ...cp, + avatar_url: myUser.displayName, + })); + }; + mx.getProfileInfo(userId).then((info) => setProfile(() => ({ ...info }))); + user?.on(UserEvent.AvatarUrl, onAvatarChange); + user?.on(UserEvent.DisplayName, onDisplayNameChange); + return () => { + user?.removeListener(UserEvent.AvatarUrl, onAvatarChange); + user?.removeListener(UserEvent.DisplayName, onDisplayNameChange); + }; + }, [mx, userId]); + + return ( + + + {(triggerRef) => ( + openSettings()}> + {nameInitials(displayName)}} + /> + + )} + + + ); +} diff --git a/src/app/pages/client/sidebar/index.ts b/src/app/pages/client/sidebar/index.ts new file mode 100644 index 000000000..63c5d4bb6 --- /dev/null +++ b/src/app/pages/client/sidebar/index.ts @@ -0,0 +1,6 @@ +export * from './HomeTab'; +export * from './DirectTab'; +export * from './SpaceTabs'; +export * from './InboxTab'; +export * from './ExploreTab'; +export * from './UserTab'; diff --git a/src/app/pages/client/space/RoomProvider.tsx b/src/app/pages/client/space/RoomProvider.tsx new file mode 100644 index 000000000..1105e220a --- /dev/null +++ b/src/app/pages/client/space/RoomProvider.tsx @@ -0,0 +1,37 @@ +import React, { ReactNode } from 'react'; +import { useParams } from 'react-router-dom'; +import { useAtomValue } from 'jotai'; +import { useSelectedRoom } from '../../../hooks/router/useSelectedRoom'; +import { RoomProvider } from '../../../hooks/useRoom'; +import { useMatrixClient } from '../../../hooks/useMatrixClient'; +import { JoinBeforeNavigate } from '../../../features/join-before-navigate'; +import { useSpace } from '../../../hooks/useSpace'; +import { getAllParents } from '../../../utils/room'; +import { roomToParentsAtom } from '../../../state/room/roomToParents'; +import { allRoomsAtom } from '../../../state/room-list/roomList'; + +export function SpaceRouteRoomProvider({ children }: { children: ReactNode }) { + const mx = useMatrixClient(); + const space = useSpace(); + const roomToParents = useAtomValue(roomToParentsAtom); + const allRooms = useAtomValue(allRoomsAtom); + + const { roomIdOrAlias } = useParams(); + const roomId = useSelectedRoom(); + const room = mx.getRoom(roomId); + + if ( + !room || + room.isSpaceRoom() || + !allRooms.includes(room.roomId) || + !getAllParents(roomToParents, room.roomId).has(space.roomId) + ) { + return ; + } + + return ( + + {children} + + ); +} diff --git a/src/app/pages/client/space/Search.tsx b/src/app/pages/client/space/Search.tsx new file mode 100644 index 000000000..6e7ac57d4 --- /dev/null +++ b/src/app/pages/client/space/Search.tsx @@ -0,0 +1,52 @@ +import React, { useRef } from 'react'; +import { Box, Icon, Icons, Text, Scroll } from 'folds'; +import { useAtomValue } from 'jotai'; +import { Page, PageContent, PageContentCenter, PageHeader } from '../../../components/page'; +import { MessageSearch } from '../../../features/message-search'; +import { useSpace } from '../../../hooks/useSpace'; +import { useRecursiveChildRoomScopeFactory, useSpaceChildren } from '../../../state/hooks/roomList'; +import { allRoomsAtom } from '../../../state/room-list/roomList'; +import { mDirectAtom } from '../../../state/mDirectList'; +import { roomToParentsAtom } from '../../../state/room/roomToParents'; +import { useMatrixClient } from '../../../hooks/useMatrixClient'; + +export function SpaceSearch() { + const mx = useMatrixClient(); + const scrollRef = useRef(null); + const space = useSpace(); + + const mDirects = useAtomValue(mDirectAtom); + const roomToParents = useAtomValue(roomToParentsAtom); + const rooms = useSpaceChildren( + allRoomsAtom, + space.roomId, + useRecursiveChildRoomScopeFactory(mx, mDirects, roomToParents) + ); + + return ( + + + + + + Message Search + + + + + + + + + + + + + + ); +} diff --git a/src/app/pages/client/space/Space.tsx b/src/app/pages/client/space/Space.tsx new file mode 100644 index 000000000..8eab6b495 --- /dev/null +++ b/src/app/pages/client/space/Space.tsx @@ -0,0 +1,417 @@ +import React, { + MouseEventHandler, + forwardRef, + useCallback, + useMemo, + useRef, + useState, +} from 'react'; +import { useAtom, useAtomValue } from 'jotai'; +import { + Avatar, + Box, + Icon, + IconButton, + Icons, + Line, + Menu, + MenuItem, + PopOut, + RectCords, + Text, + config, + toRem, +} from 'folds'; +import { useVirtualizer } from '@tanstack/react-virtual'; +import { IJoinRuleEventContent, JoinRule, Room } from 'matrix-js-sdk'; +import FocusTrap from 'focus-trap-react'; +import { useMatrixClient } from '../../../hooks/useMatrixClient'; +import { mDirectAtom } from '../../../state/mDirectList'; +import { + NavCategory, + NavCategoryHeader, + NavItem, + NavItemContent, + NavLink, +} from '../../../components/nav'; +import { + getOriginBaseUrl, + getSpaceLobbyPath, + getSpacePath, + getSpaceRoomPath, + getSpaceSearchPath, + withOriginBaseUrl, +} from '../../pathUtils'; +import { getCanonicalAliasOrRoomId } from '../../../utils/matrix'; +import { useSelectedRoom } from '../../../hooks/router/useSelectedRoom'; +import { + useSpaceLobbySelected, + useSpaceSearchSelected, +} from '../../../hooks/router/useSelectedSpace'; +import { useSpace } from '../../../hooks/useSpace'; +import { VirtualTile } from '../../../components/virtualizer'; +import { RoomNavCategoryButton, RoomNavItem } from '../../../features/room-nav'; +import { muteChangesAtom } from '../../../state/room-list/mutedRoomList'; +import { makeNavCategoryId } from '../../../state/closedNavCategories'; +import { roomToUnreadAtom } from '../../../state/room/roomToUnread'; +import { useCategoryHandler } from '../../../hooks/useCategoryHandler'; +import { useNavToActivePathMapper } from '../../../hooks/useNavToActivePathMapper'; +import { useRoomName } from '../../../hooks/useRoomMeta'; +import { useSpaceJoinedHierarchy } from '../../../hooks/useSpaceHierarchy'; +import { allRoomsAtom } from '../../../state/room-list/roomList'; +import { PageNav, PageNavContent, PageNavHeader } from '../../../components/page'; +import { usePowerLevels, usePowerLevelsAPI } from '../../../hooks/usePowerLevels'; +import { openInviteUser, openSpaceSettings } from '../../../../client/action/navigation'; +import { useRecursiveChildScopeFactory, useSpaceChildren } from '../../../state/hooks/roomList'; +import { roomToParentsAtom } from '../../../state/room/roomToParents'; +import { markAsRead } from '../../../../client/action/notifications'; +import { useRoomsUnread } from '../../../state/hooks/unread'; +import { UseStateProvider } from '../../../components/UseStateProvider'; +import { LeaveSpacePrompt } from '../../../components/leave-space-prompt'; +import { copyToClipboard } from '../../../utils/dom'; +import { useClientConfig } from '../../../hooks/useClientConfig'; +import { useClosedNavCategoriesAtom } from '../../../state/hooks/closedNavCategories'; +import { useStateEvent } from '../../../hooks/useStateEvent'; +import { StateEvent } from '../../../../types/matrix/room'; + +type SpaceMenuProps = { + room: Room; + requestClose: () => void; +}; +const SpaceMenu = forwardRef(({ room, requestClose }, ref) => { + const mx = useMatrixClient(); + const { hashRouter } = useClientConfig(); + const roomToParents = useAtomValue(roomToParentsAtom); + const powerLevels = usePowerLevels(room); + const { getPowerLevel, canDoAction } = usePowerLevelsAPI(powerLevels); + const canInvite = canDoAction('invite', getPowerLevel(mx.getUserId() ?? '')); + + const allChild = useSpaceChildren( + allRoomsAtom, + room.roomId, + useRecursiveChildScopeFactory(mx, roomToParents) + ); + const unread = useRoomsUnread(allChild, roomToUnreadAtom); + + const handleMarkAsRead = () => { + allChild.forEach((childRoomId) => markAsRead(childRoomId)); + requestClose(); + }; + + const handleCopyLink = () => { + const spacePath = getSpacePath(getCanonicalAliasOrRoomId(mx, room.roomId)); + copyToClipboard(withOriginBaseUrl(getOriginBaseUrl(hashRouter), spacePath)); + requestClose(); + }; + + const handleInvite = () => { + openInviteUser(room.roomId); + requestClose(); + }; + + const handleRoomSettings = () => { + openSpaceSettings(room.roomId); + requestClose(); + }; + + return ( + + + } + radii="300" + disabled={!unread} + > + + Mark as Read + + + + + + } + radii="300" + disabled={!canInvite} + > + + Invite + + + } + radii="300" + > + + Copy Link + + + } + radii="300" + > + + Space Settings + + + + + + + {(promptLeave, setPromptLeave) => ( + <> + setPromptLeave(true)} + variant="Critical" + fill="None" + size="300" + after={} + radii="300" + aria-pressed={promptLeave} + > + + Leave Space + + + {promptLeave && ( + setPromptLeave(false)} + /> + )} + + )} + + + + ); +}); + +function SpaceHeader() { + const space = useSpace(); + const spaceName = useRoomName(space); + const [menuAnchor, setMenuAnchor] = useState(); + + const joinRules = useStateEvent( + space, + StateEvent.RoomJoinRules + )?.getContent(); + + const handleOpenMenu: MouseEventHandler = (evt) => { + const cords = evt.currentTarget.getBoundingClientRect(); + setMenuAnchor((currentState) => { + if (currentState) return undefined; + return cords; + }); + }; + + return ( + <> + + + + + {spaceName} + + {joinRules?.join_rule !== JoinRule.Public && } + + + + + + + + + {menuAnchor && ( + setMenuAnchor(undefined), + clickOutsideDeactivates: true, + isKeyForward: (evt: KeyboardEvent) => evt.key === 'ArrowDown', + isKeyBackward: (evt: KeyboardEvent) => evt.key === 'ArrowUp', + }} + > + setMenuAnchor(undefined)} /> + + } + /> + )} + + ); +} + +export function Space() { + const mx = useMatrixClient(); + const space = useSpace(); + useNavToActivePathMapper(space.roomId); + const spaceIdOrAlias = getCanonicalAliasOrRoomId(mx, space.roomId); + const scrollRef = useRef(null); + const mDirects = useAtomValue(mDirectAtom); + const roomToUnread = useAtomValue(roomToUnreadAtom); + const allRooms = useAtomValue(allRoomsAtom); + const allJoinedRooms = useMemo(() => new Set(allRooms), [allRooms]); + const muteChanges = useAtomValue(muteChangesAtom); + const mutedRooms = muteChanges.added; + + const selectedRoomId = useSelectedRoom(); + const lobbySelected = useSpaceLobbySelected(spaceIdOrAlias); + const searchSelected = useSpaceSearchSelected(spaceIdOrAlias); + + const [closedCategories, setClosedCategories] = useAtom(useClosedNavCategoriesAtom()); + + const getRoom = useCallback( + (rId: string) => { + if (allJoinedRooms.has(rId)) { + return mx.getRoom(rId) ?? undefined; + } + return undefined; + }, + [mx, allJoinedRooms] + ); + + const hierarchy = useSpaceJoinedHierarchy( + space.roomId, + getRoom, + useCallback( + (parentId, roomId) => { + if (!closedCategories.has(makeNavCategoryId(space.roomId, parentId))) { + return false; + } + const showRoom = roomToUnread.has(roomId) || roomId === selectedRoomId; + if (showRoom) return false; + return true; + }, + [space.roomId, closedCategories, roomToUnread, selectedRoomId] + ), + useCallback( + (sId) => closedCategories.has(makeNavCategoryId(space.roomId, sId)), + [closedCategories, space.roomId] + ) + ); + + const virtualizer = useVirtualizer({ + count: hierarchy.length, + getScrollElement: () => scrollRef.current, + estimateSize: () => 0, + overscan: 10, + }); + + const handleCategoryClick = useCategoryHandler(setClosedCategories, (categoryId) => + closedCategories.has(categoryId) + ); + + const getToLink = (roomId: string) => + getSpaceRoomPath(spaceIdOrAlias, getCanonicalAliasOrRoomId(mx, roomId)); + + return ( + + + + + + + + + + + + + + + Lobby + + + + + + + + + + + + + + + + Message Search + + + + + + + + + {virtualizer.getVirtualItems().map((vItem) => { + const { roomId } = hierarchy[vItem.index] ?? {}; + const room = mx.getRoom(roomId); + if (!room) return null; + + if (room.isSpaceRoom()) { + const categoryId = makeNavCategoryId(space.roomId, roomId); + + return ( + +
      + + + {roomId === space.roomId ? 'Rooms' : room?.name} + + +
      +
      + ); + } + + return ( + + + + ); + })} +
      +
      +
      +
      + ); +} diff --git a/src/app/pages/client/space/SpaceProvider.tsx b/src/app/pages/client/space/SpaceProvider.tsx new file mode 100644 index 000000000..530fc3cca --- /dev/null +++ b/src/app/pages/client/space/SpaceProvider.tsx @@ -0,0 +1,30 @@ +import React, { ReactNode } from 'react'; +import { useParams } from 'react-router-dom'; +import { useMatrixClient } from '../../../hooks/useMatrixClient'; +import { useSpaces } from '../../../state/hooks/roomList'; +import { allRoomsAtom } from '../../../state/room-list/roomList'; +import { useSelectedSpace } from '../../../hooks/router/useSelectedSpace'; +import { SpaceProvider } from '../../../hooks/useSpace'; +import { JoinBeforeNavigate } from '../../../features/join-before-navigate'; + +type RouteSpaceProviderProps = { + children: ReactNode; +}; +export function RouteSpaceProvider({ children }: RouteSpaceProviderProps) { + const mx = useMatrixClient(); + const joinedSpaces = useSpaces(mx, allRoomsAtom); + const { spaceIdOrAlias } = useParams(); + + const selectedSpaceId = useSelectedSpace(); + const space = mx.getRoom(selectedSpaceId); + + if (!space || !joinedSpaces.includes(space.roomId)) { + return ; + } + + return ( + + {children} + + ); +} diff --git a/src/app/pages/client/space/index.ts b/src/app/pages/client/space/index.ts new file mode 100644 index 000000000..0e32d93b3 --- /dev/null +++ b/src/app/pages/client/space/index.ts @@ -0,0 +1,4 @@ +export * from './SpaceProvider'; +export * from './Space'; +export * from './Search'; +export * from './RoomProvider'; diff --git a/src/app/pages/pathUtils.ts b/src/app/pages/pathUtils.ts index db39ce391..cbd453ae3 100644 --- a/src/app/pages/pathUtils.ts +++ b/src/app/pages/pathUtils.ts @@ -1,5 +1,32 @@ -import { generatePath } from 'react-router-dom'; -import { LOGIN_PATH, REGISTER_PATH, RESET_PASSWORD_PATH, ROOT_PATH } from './paths'; +import { generatePath, Path } from 'react-router-dom'; +import { + DIRECT_CREATE_PATH, + DIRECT_PATH, + DIRECT_ROOM_PATH, + EXPLORE_FEATURED_PATH, + EXPLORE_PATH, + EXPLORE_SERVER_PATH, + HOME_CREATE_PATH, + HOME_JOIN_PATH, + HOME_PATH, + HOME_ROOM_PATH, + HOME_SEARCH_PATH, + LOGIN_PATH, + INBOX_INVITES_PATH, + INBOX_NOTIFICATIONS_PATH, + INBOX_PATH, + REGISTER_PATH, + RESET_PASSWORD_PATH, + ROOT_PATH, + SPACE_LOBBY_PATH, + SPACE_PATH, + SPACE_ROOM_PATH, + SPACE_SEARCH_PATH, +} from './paths'; +import { trimLeadingSlash, trimTrailingSlash } from '../utils/common'; +import { HashRouterConfig } from '../hooks/useClientConfig'; + +export const joinPathComponent = (path: Path): string => path.pathname + path.search + path.hash; export const withSearchParam = >( path: string, @@ -9,6 +36,38 @@ export const withSearchParam = >( return `${path}?${params}`; }; +export const encodeSearchParamValueArray = (ids: string[]): string => ids.join(','); +export const decodeSearchParamValueArray = (idsParam: string): string[] => idsParam.split(','); + +export const getOriginBaseUrl = (hashRouterConfig?: HashRouterConfig): string => { + const baseUrl = `${trimTrailingSlash(window.location.origin)}${import.meta.env.BASE_URL}`; + + if (hashRouterConfig?.enabled) { + return `${trimTrailingSlash(baseUrl)}/#${hashRouterConfig.basename}`; + } + + return baseUrl; +}; + +export const withOriginBaseUrl = (baseUrl: string, path: string): string => + `${trimTrailingSlash(baseUrl)}${path}`; + +export const getAppPathFromHref = (baseUrl: string, href: string): string => { + // if hash is in baseUrl means we are using hashRouter + const baseHashIndex = baseUrl.indexOf('#'); + if (baseHashIndex > -1) { + const hrefHashIndex = href.indexOf('#'); + // href may/not have "/" around "#" + // we need to take care of this when extracting app path + const trimmedBaseUrl = trimLeadingSlash(baseUrl.slice(baseHashIndex + 1)); + const trimmedHref = trimLeadingSlash(href.slice(hrefHashIndex + 1)); + + const appPath = trimmedHref.slice(trimmedBaseUrl.length); + return `/${trimLeadingSlash(appPath)}`; + } + + return href.slice(trimTrailingSlash(baseUrl).length); +}; export const getRootPath = (): string => ROOT_PATH; @@ -26,3 +85,73 @@ export const getResetPasswordPath = (server?: string): string => { const params = server ? { server: encodeURIComponent(server) } : undefined; return generatePath(RESET_PASSWORD_PATH, params); }; + +export const getHomePath = (): string => HOME_PATH; +export const getHomeCreatePath = (): string => HOME_CREATE_PATH; +export const getHomeJoinPath = (): string => HOME_JOIN_PATH; +export const getHomeSearchPath = (): string => HOME_SEARCH_PATH; +export const getHomeRoomPath = (roomIdOrAlias: string, eventId?: string): string => { + const params = { + roomIdOrAlias: encodeURIComponent(roomIdOrAlias), + eventId: eventId ? encodeURIComponent(eventId) : null, + }; + + return generatePath(HOME_ROOM_PATH, params); +}; + +export const getDirectPath = (): string => DIRECT_PATH; +export const getDirectCreatePath = (): string => DIRECT_CREATE_PATH; +export const getDirectRoomPath = (roomIdOrAlias: string, eventId?: string): string => { + const params = { + roomIdOrAlias: encodeURIComponent(roomIdOrAlias), + eventId: eventId ? encodeURIComponent(eventId) : null, + }; + + return generatePath(DIRECT_ROOM_PATH, params); +}; + +export const getSpacePath = (spaceIdOrAlias: string): string => { + const params = { + spaceIdOrAlias: encodeURIComponent(spaceIdOrAlias), + }; + + return generatePath(SPACE_PATH, params); +}; +export const getSpaceLobbyPath = (spaceIdOrAlias: string): string => { + const params = { + spaceIdOrAlias: encodeURIComponent(spaceIdOrAlias), + }; + return generatePath(SPACE_LOBBY_PATH, params); +}; +export const getSpaceSearchPath = (spaceIdOrAlias: string): string => { + const params = { + spaceIdOrAlias: encodeURIComponent(spaceIdOrAlias), + }; + return generatePath(SPACE_SEARCH_PATH, params); +}; +export const getSpaceRoomPath = ( + spaceIdOrAlias: string, + roomIdOrAlias: string, + eventId?: string +): string => { + const params = { + spaceIdOrAlias: encodeURIComponent(spaceIdOrAlias), + roomIdOrAlias: encodeURIComponent(roomIdOrAlias), + eventId: eventId ? encodeURIComponent(eventId) : null, + }; + + return generatePath(SPACE_ROOM_PATH, params); +}; + +export const getExplorePath = (): string => EXPLORE_PATH; +export const getExploreFeaturedPath = (): string => EXPLORE_FEATURED_PATH; +export const getExploreServerPath = (server: string): string => { + const params = { + server: encodeURIComponent(server), + }; + return generatePath(EXPLORE_SERVER_PATH, params); +}; + +export const getInboxPath = (): string => INBOX_PATH; +export const getInboxNotificationsPath = (): string => INBOX_NOTIFICATIONS_PATH; +export const getInboxInvitesPath = (): string => INBOX_INVITES_PATH; diff --git a/src/app/pages/paths.ts b/src/app/pages/paths.ts index cd6226414..fd3266e93 100644 --- a/src/app/pages/paths.ts +++ b/src/app/pages/paths.ts @@ -14,4 +14,69 @@ export type RegisterPathSearchParams = { }; export const REGISTER_PATH = '/register/:server?/'; +export type ResetPasswordPathSearchParams = { + email?: string; +}; export const RESET_PASSWORD_PATH = '/reset-password/:server?/'; + +export const _CREATE_PATH = 'create/'; +export const _JOIN_PATH = 'join/'; +export const _LOBBY_PATH = 'lobby/'; +/** + * array of rooms and senders mxId assigned + * to search param as string should be "," separated + * Like: url?rooms=!one:server,!two:server + */ +export type _SearchPathSearchParams = { + global?: string; + term?: string; + order?: string; + rooms?: string; + senders?: string; +}; +export const _SEARCH_PATH = 'search/'; +export const _ROOM_PATH = ':roomIdOrAlias/:eventId?/'; + +export const HOME_PATH = '/home/'; +export const HOME_CREATE_PATH = `/home/${_CREATE_PATH}`; +export const HOME_JOIN_PATH = `/home/${_JOIN_PATH}`; +export const HOME_SEARCH_PATH = `/home/${_SEARCH_PATH}`; +export const HOME_ROOM_PATH = `/home/${_ROOM_PATH}`; + +export const DIRECT_PATH = '/direct/'; +export const DIRECT_CREATE_PATH = `/direct/${_CREATE_PATH}`; +export const DIRECT_ROOM_PATH = `/direct/${_ROOM_PATH}`; + +export const SPACE_PATH = '/:spaceIdOrAlias/'; +export const SPACE_LOBBY_PATH = `/:spaceIdOrAlias/${_LOBBY_PATH}`; +export const SPACE_SEARCH_PATH = `/:spaceIdOrAlias/${_SEARCH_PATH}`; +export const SPACE_ROOM_PATH = `/:spaceIdOrAlias/${_ROOM_PATH}`; + +export const _FEATURED_PATH = 'featured/'; +export const _SERVER_PATH = ':server/'; +export const EXPLORE_PATH = '/explore/'; +export const EXPLORE_FEATURED_PATH = `/explore/${_FEATURED_PATH}`; + +export type ExploreServerPathSearchParams = { + limit?: string; + since?: string; + term?: string; + type?: string; + instance?: string; +}; +export const EXPLORE_SERVER_PATH = `/explore/${_SERVER_PATH}`; + +export const _NOTIFICATIONS_PATH = 'notifications/'; +export const _INVITES_PATH = 'invites/'; +export const INBOX_PATH = '/inbox/'; +export type InboxNotificationsPathSearchParams = { + only?: string; +}; +export const INBOX_NOTIFICATIONS_PATH = `/inbox/${_NOTIFICATIONS_PATH}`; +export const INBOX_INVITES_PATH = `/inbox/${_INVITES_PATH}`; + +export const USER_SETTINGS_PATH = '/user-settings/'; + +export const SPACE_SETTINGS_PATH = '/space-settings/'; + +export const ROOM_SETTINGS_PATH = '/room-settings/'; diff --git a/src/app/plugins/millify.ts b/src/app/plugins/millify.ts new file mode 100644 index 000000000..d8608deee --- /dev/null +++ b/src/app/plugins/millify.ts @@ -0,0 +1,9 @@ +import millifyPlugin from 'millify'; +import { MillifyOptions } from 'millify/dist/options'; + +export const millify = (count: number, options?: Partial): string => + millifyPlugin(count, { + precision: 1, + locales: [], + ...options, + }); diff --git a/src/app/plugins/pdfjs-dist.ts b/src/app/plugins/pdfjs-dist.ts index 5412ea458..1b2991f4c 100644 --- a/src/app/plugins/pdfjs-dist.ts +++ b/src/app/plugins/pdfjs-dist.ts @@ -2,12 +2,15 @@ import { useCallback } from 'react'; import type * as PdfJsDist from 'pdfjs-dist'; import type { GetViewportParameters } from 'pdfjs-dist/types/src/display/api'; import { useAsyncCallback } from '../hooks/useAsyncCallback'; +import { trimTrailingSlash } from '../utils/common'; export const usePdfJSLoader = () => useAsyncCallback( useCallback(async () => { const pdf = await import('pdfjs-dist'); - pdf.GlobalWorkerOptions.workerSrc = 'pdf.worker.min.js'; + pdf.GlobalWorkerOptions.workerSrc = `${trimTrailingSlash( + import.meta.env.BASE_URL + )}/pdf.worker.min.js`; return pdf; }, []) ); diff --git a/src/app/plugins/react-custom-html-parser.tsx b/src/app/plugins/react-custom-html-parser.tsx index ee41687de..a8086687a 100644 --- a/src/app/plugins/react-custom-html-parser.tsx +++ b/src/app/plugins/react-custom-html-parser.tsx @@ -14,7 +14,7 @@ import { Opts as LinkifyOpts } from 'linkifyjs'; import Linkify from 'linkify-react'; import { ErrorBoundary } from 'react-error-boundary'; import * as css from '../styles/CustomHtml.css'; -import { getMxIdLocalPart, getRoomWithCanonicalAlias } from '../utils/matrix'; +import { getMxIdLocalPart, getCanonicalAliasRoomId } from '../utils/matrix'; import { getMemberDisplayName } from '../utils/room'; import { EMOJI_PATTERN, URL_NEG_LB } from '../utils/regex'; import { getHexcodeForEmoji, getShortcodeFor } from './emoji'; @@ -35,12 +35,12 @@ export const LINKIFY_OPTS: LinkifyOpts = { ignoreTags: ['span'], }; -const textToEmojifyJSX = (text: string): (string | JSX.Element)[] => +export const scaleSystemEmoji = (text: string): (string | JSX.Element)[] => findAndReplace( text, EMOJI_REG_G, (match, pushIndex) => ( - + {match[0]} @@ -49,19 +49,36 @@ const textToEmojifyJSX = (text: string): (string | JSX.Element)[] => (txt) => txt ); -export const emojifyAndLinkify = (text: string, linkify?: boolean) => { - const emojifyJSX = textToEmojifyJSX(text); - - if (linkify) { - return {emojifyJSX}; - } - return emojifyJSX; +export const makeHighlightRegex = (highlights: string[]): RegExp | undefined => { + const pattern = highlights.join('|'); + if (!pattern) return undefined; + return new RegExp(pattern, 'gi'); }; +export const highlightText = ( + regex: RegExp, + data: (string | JSX.Element)[] +): (string | JSX.Element)[] => + data.flatMap((text) => { + if (typeof text !== 'string') return text; + + return findAndReplace( + text, + regex, + (match, pushIndex) => ( + + {match[0]} + + ), + (txt) => txt + ); + }); + export const getReactCustomHtmlParser = ( mx: MatrixClient, room: Room, params: { + highlightRegex?: RegExp; handleSpoilerClick?: ReactEventHandler; handleMentionClick?: ReactEventHandler; } @@ -207,10 +224,9 @@ export const getReactCustomHtmlParser = ( const mentionId = mention[1]; const mentionPrefix = mention[2]; if (mentionPrefix === '#' || mentionPrefix === '!') { - const mentionRoom = - mentionPrefix === '#' - ? getRoomWithCanonicalAlias(mx, mentionId) - : mx.getRoom(mentionId); + const mentionRoom = mx.getRoom( + mentionPrefix === '#' ? getCanonicalAliasRoomId(mx, mentionId) : mentionId + ); return ( {jsx}; + } + return jsx; } return undefined; }, diff --git a/src/app/state/closedLobbyCategories.ts b/src/app/state/closedLobbyCategories.ts new file mode 100644 index 000000000..40ecd1632 --- /dev/null +++ b/src/app/state/closedLobbyCategories.ts @@ -0,0 +1,68 @@ +import { WritableAtom, atom } from 'jotai'; +import produce from 'immer'; +import { + atomWithLocalStorage, + getLocalStorageItem, + setLocalStorageItem, +} from './utils/atomWithLocalStorage'; + +const CLOSED_LOBBY_CATEGORY = 'closedLobbyCategories'; + +type ClosedLobbyCategoriesAction = + | { + type: 'PUT'; + categoryId: string; + } + | { + type: 'DELETE'; + categoryId: string; + }; + +export type ClosedLobbyCategoriesAtom = WritableAtom< + Set, + [ClosedLobbyCategoriesAction], + undefined +>; + +export const makeClosedLobbyCategoriesAtom = (userId: string): ClosedLobbyCategoriesAtom => { + const storeKey = `${CLOSED_LOBBY_CATEGORY}${userId}`; + + const baseClosedLobbyCategoriesAtom = atomWithLocalStorage>( + storeKey, + (key) => { + const arrayValue = getLocalStorageItem(key, []); + return new Set(arrayValue); + }, + (key, value) => { + const arrayValue = Array.from(value); + setLocalStorageItem(key, arrayValue); + } + ); + + const closedLobbyCategoriesAtom = atom, [ClosedLobbyCategoriesAction], undefined>( + (get) => get(baseClosedLobbyCategoriesAtom), + (get, set, action) => { + if (action.type === 'DELETE') { + set( + baseClosedLobbyCategoriesAtom, + produce(get(baseClosedLobbyCategoriesAtom), (draft) => { + draft.delete(action.categoryId); + }) + ); + return; + } + if (action.type === 'PUT') { + set( + baseClosedLobbyCategoriesAtom, + produce(get(baseClosedLobbyCategoriesAtom), (draft) => { + draft.add(action.categoryId); + }) + ); + } + } + ); + + return closedLobbyCategoriesAtom; +}; + +export const makeLobbyCategoryId = (...args: string[]): string => args.join('|'); diff --git a/src/app/state/closedNavCategories.ts b/src/app/state/closedNavCategories.ts new file mode 100644 index 000000000..ea61cb2e9 --- /dev/null +++ b/src/app/state/closedNavCategories.ts @@ -0,0 +1,68 @@ +import { WritableAtom, atom } from 'jotai'; +import produce from 'immer'; +import { + atomWithLocalStorage, + getLocalStorageItem, + setLocalStorageItem, +} from './utils/atomWithLocalStorage'; + +const CLOSED_NAV_CATEGORY = 'closedNavCategories'; + +type ClosedNavCategoriesAction = + | { + type: 'PUT'; + categoryId: string; + } + | { + type: 'DELETE'; + categoryId: string; + }; + +export type ClosedNavCategoriesAtom = WritableAtom< + Set, + [ClosedNavCategoriesAction], + undefined +>; + +export const makeClosedNavCategoriesAtom = (userId: string): ClosedNavCategoriesAtom => { + const storeKey = `${CLOSED_NAV_CATEGORY}${userId}`; + + const baseClosedNavCategoriesAtom = atomWithLocalStorage>( + storeKey, + (key) => { + const arrayValue = getLocalStorageItem(key, []); + return new Set(arrayValue); + }, + (key, value) => { + const arrayValue = Array.from(value); + setLocalStorageItem(key, arrayValue); + } + ); + + const closedNavCategoriesAtom = atom, [ClosedNavCategoriesAction], undefined>( + (get) => get(baseClosedNavCategoriesAtom), + (get, set, action) => { + if (action.type === 'DELETE') { + set( + baseClosedNavCategoriesAtom, + produce(get(baseClosedNavCategoriesAtom), (draft) => { + draft.delete(action.categoryId); + }) + ); + return; + } + if (action.type === 'PUT') { + set( + baseClosedNavCategoriesAtom, + produce(get(baseClosedNavCategoriesAtom), (draft) => { + draft.add(action.categoryId); + }) + ); + } + } + ); + + return closedNavCategoriesAtom; +}; + +export const makeNavCategoryId = (...args: string[]): string => args.join('|'); diff --git a/src/app/state/hooks/closedLobbyCategories.ts b/src/app/state/hooks/closedLobbyCategories.ts new file mode 100644 index 000000000..1545254f8 --- /dev/null +++ b/src/app/state/hooks/closedLobbyCategories.ts @@ -0,0 +1,15 @@ +import { createContext, useContext } from 'react'; +import { ClosedLobbyCategoriesAtom } from '../closedLobbyCategories'; + +const ClosedLobbyCategoriesAtomContext = createContext(null); +export const ClosedLobbyCategoriesProvider = ClosedLobbyCategoriesAtomContext.Provider; + +export const useClosedLobbyCategoriesAtom = (): ClosedLobbyCategoriesAtom => { + const anAtom = useContext(ClosedLobbyCategoriesAtomContext); + + if (!anAtom) { + throw new Error('ClosedLobbyCategoriesAtom is not provided!'); + } + + return anAtom; +}; diff --git a/src/app/state/hooks/closedNavCategories.ts b/src/app/state/hooks/closedNavCategories.ts new file mode 100644 index 000000000..ed34c1e62 --- /dev/null +++ b/src/app/state/hooks/closedNavCategories.ts @@ -0,0 +1,15 @@ +import { createContext, useContext } from 'react'; +import { ClosedNavCategoriesAtom } from '../closedNavCategories'; + +const ClosedNavCategoriesAtomContext = createContext(null); +export const ClosedNavCategoriesProvider = ClosedNavCategoriesAtomContext.Provider; + +export const useClosedNavCategoriesAtom = (): ClosedNavCategoriesAtom => { + const anAtom = useContext(ClosedNavCategoriesAtomContext); + + if (!anAtom) { + throw new Error('ClosedNavCategoriesAtom is not provided!'); + } + + return anAtom; +}; diff --git a/src/app/state/hooks/inviteList.ts b/src/app/state/hooks/inviteList.ts index ffe44445d..5e003fb19 100644 --- a/src/app/state/hooks/inviteList.ts +++ b/src/app/state/hooks/inviteList.ts @@ -3,9 +3,8 @@ import { selectAtom } from 'jotai/utils'; import { MatrixClient } from 'matrix-js-sdk'; import { useCallback } from 'react'; import { isDirectInvite, isRoom, isSpace, isUnsupportedRoom } from '../../utils/room'; -import { compareRoomsEqual } from '../utils'; -import { mDirectAtom } from '../mDirectList'; -import { allInvitesAtom } from '../inviteList'; +import { compareRoomsEqual } from '../room-list/utils'; +import { allInvitesAtom } from '../room-list/inviteList'; export const useSpaceInvites = (mx: MatrixClient, invitesAtom: typeof allInvitesAtom) => { const selector = useCallback( @@ -18,9 +17,8 @@ export const useSpaceInvites = (mx: MatrixClient, invitesAtom: typeof allInvites export const useRoomInvites = ( mx: MatrixClient, invitesAtom: typeof allInvitesAtom, - directAtom: typeof mDirectAtom + mDirects: Set ) => { - const mDirects = useAtomValue(directAtom); const selector = useCallback( (rooms: string[]) => rooms.filter( @@ -36,9 +34,8 @@ export const useRoomInvites = ( export const useDirectInvites = ( mx: MatrixClient, invitesAtom: typeof allInvitesAtom, - directAtom: typeof mDirectAtom + mDirects: Set ) => { - const mDirects = useAtomValue(directAtom); const selector = useCallback( (rooms: string[]) => rooms.filter( diff --git a/src/app/state/hooks/navToActivePath.ts b/src/app/state/hooks/navToActivePath.ts new file mode 100644 index 000000000..5f8798f2d --- /dev/null +++ b/src/app/state/hooks/navToActivePath.ts @@ -0,0 +1,15 @@ +import { createContext, useContext } from 'react'; +import { NavToActivePathAtom } from '../navToActivePath'; + +const NavToActivePathAtomContext = createContext(null); +export const NavToActivePathProvider = NavToActivePathAtomContext.Provider; + +export const useNavToActivePathAtom = (): NavToActivePathAtom => { + const anAtom = useContext(NavToActivePathAtomContext); + + if (!anAtom) { + throw new Error('NavToActivePathAtom is not provided!'); + } + + return anAtom; +}; diff --git a/src/app/state/hooks/openedSidebarFolder.ts b/src/app/state/hooks/openedSidebarFolder.ts new file mode 100644 index 000000000..3a165334a --- /dev/null +++ b/src/app/state/hooks/openedSidebarFolder.ts @@ -0,0 +1,15 @@ +import { createContext, useContext } from 'react'; +import { OpenedSidebarFolderAtom } from '../openedSidebarFolder'; + +const OpenedSidebarFolderAtomContext = createContext(null); +export const OpenedSidebarFolderProvider = OpenedSidebarFolderAtomContext.Provider; + +export const useOpenedSidebarFolderAtom = (): OpenedSidebarFolderAtom => { + const anAtom = useContext(OpenedSidebarFolderAtomContext); + + if (!anAtom) { + throw new Error('OpenedSidebarFolderAtom is not provided!'); + } + + return anAtom; +}; diff --git a/src/app/state/hooks/roomList.ts b/src/app/state/hooks/roomList.ts index c0a7bfb88..d64ecd5b1 100644 --- a/src/app/state/hooks/roomList.ts +++ b/src/app/state/hooks/roomList.ts @@ -1,52 +1,177 @@ -import { useAtomValue } from 'jotai'; +import { Atom, useAtomValue } from 'jotai'; import { selectAtom } from 'jotai/utils'; import { MatrixClient } from 'matrix-js-sdk'; -import { useCallback } from 'react'; -import { isRoom, isSpace, isUnsupportedRoom } from '../../utils/room'; -import { compareRoomsEqual } from '../utils'; -import { mDirectAtom } from '../mDirectList'; -import { allRoomsAtom } from '../roomList'; +import { useCallback, useMemo } from 'react'; +import { getAllParents, isRoom, isSpace, isUnsupportedRoom } from '../../utils/room'; +import { compareRoomsEqual } from '../room-list/utils'; +import { RoomToParents } from '../../../types/matrix/room'; -export const useSpaces = (mx: MatrixClient, roomsAtom: typeof allRoomsAtom) => { - const selector = useCallback( - (rooms: string[]) => rooms.filter((roomId) => isSpace(mx.getRoom(roomId))), - [mx] - ); - return useAtomValue(selectAtom(roomsAtom, selector, compareRoomsEqual)); +export type RoomsAtom = Atom; +export type RoomSelector = (roomId: string) => boolean | undefined; + +export const selectedRoomsAtom = ( + roomsAtom: RoomsAtom, + selector: (roomId: string) => boolean | undefined +) => selectAtom(roomsAtom, (rooms) => rooms.filter(selector), compareRoomsEqual); + +export const useSelectedRooms = (roomsAtom: RoomsAtom, selector: RoomSelector) => { + const anAtom = useMemo(() => selectedRoomsAtom(roomsAtom, selector), [roomsAtom, selector]); + + return useAtomValue(anAtom); }; -export const useRooms = ( +export type SpaceChildSelectorFactory = (parentId: string) => RoomSelector; + +export const useRecursiveChildScopeFactory = ( mx: MatrixClient, - roomsAtom: typeof allRoomsAtom, - directAtom: typeof mDirectAtom + roomToParents: RoomToParents +): SpaceChildSelectorFactory => + useCallback( + (parentId: string) => (roomId) => + isRoom(mx.getRoom(roomId)) && + roomToParents.has(roomId) && + getAllParents(roomToParents, roomId).has(parentId), + [mx, roomToParents] + ); + +export const useChildSpaceScopeFactory = ( + mx: MatrixClient, + roomToParents: RoomToParents +): SpaceChildSelectorFactory => + useCallback( + (parentId: string) => (roomId) => + isSpace(mx.getRoom(roomId)) && roomToParents.get(roomId)?.has(parentId), + [mx, roomToParents] + ); + +export const useRecursiveChildSpaceScopeFactory = ( + mx: MatrixClient, + roomToParents: RoomToParents +): SpaceChildSelectorFactory => + useCallback( + (parentId: string) => (roomId) => + isSpace(mx.getRoom(roomId)) && + roomToParents.has(roomId) && + getAllParents(roomToParents, roomId).has(parentId), + [mx, roomToParents] + ); + +export const useChildRoomScopeFactory = ( + mx: MatrixClient, + mDirects: Set, + roomToParents: RoomToParents +): SpaceChildSelectorFactory => + useCallback( + (parentId: string) => (roomId) => + isRoom(mx.getRoom(roomId)) && + !mDirects.has(roomId) && + roomToParents.get(roomId)?.has(parentId), + [mx, mDirects, roomToParents] + ); + +export const useRecursiveChildRoomScopeFactory = ( + mx: MatrixClient, + mDirects: Set, + roomToParents: RoomToParents +): SpaceChildSelectorFactory => + useCallback( + (parentId: string) => (roomId) => + isRoom(mx.getRoom(roomId)) && + !mDirects.has(roomId) && + roomToParents.has(roomId) && + getAllParents(roomToParents, roomId).has(parentId), + [mx, mDirects, roomToParents] + ); + +export const useChildDirectScopeFactory = ( + mx: MatrixClient, + mDirects: Set, + roomToParents: RoomToParents +): SpaceChildSelectorFactory => + useCallback( + (parentId: string) => (roomId) => + isRoom(mx.getRoom(roomId)) && + mDirects.has(roomId) && + roomToParents.get(roomId)?.has(parentId), + [mx, mDirects, roomToParents] + ); + +export const useRecursiveChildDirectScopeFactory = ( + mx: MatrixClient, + mDirects: Set, + roomToParents: RoomToParents +): SpaceChildSelectorFactory => + useCallback( + (parentId: string) => (roomId) => + isRoom(mx.getRoom(roomId)) && + mDirects.has(roomId) && + roomToParents.has(roomId) && + getAllParents(roomToParents, roomId).has(parentId), + [mx, mDirects, roomToParents] + ); + +export const useSpaceChildren = ( + roomsAtom: RoomsAtom, + spaceId: string, + selectorFactory: SpaceChildSelectorFactory ) => { - const mDirects = useAtomValue(directAtom); - const selector = useCallback( - (rooms: string[]) => - rooms.filter((roomId) => isRoom(mx.getRoom(roomId)) && !mDirects.has(roomId)), + const recursiveChildRoomSelector = useMemo( + () => selectorFactory(spaceId), + [selectorFactory, spaceId] + ); + return useSelectedRooms(roomsAtom, recursiveChildRoomSelector); +}; + +export const useSpaces = (mx: MatrixClient, roomsAtom: RoomsAtom) => { + const selector: RoomSelector = useCallback((roomId) => isSpace(mx.getRoom(roomId)), [mx]); + return useSelectedRooms(roomsAtom, selector); +}; + +export const useOrphanSpaces = ( + mx: MatrixClient, + roomsAtom: RoomsAtom, + roomToParents: RoomToParents +) => { + const selector: RoomSelector = useCallback( + (roomId) => isSpace(mx.getRoom(roomId)) && !roomToParents.has(roomId), + [mx, roomToParents] + ); + return useSelectedRooms(roomsAtom, selector); +}; + +export const useRooms = (mx: MatrixClient, roomsAtom: RoomsAtom, mDirects: Set) => { + const selector: RoomSelector = useCallback( + (roomId: string) => isRoom(mx.getRoom(roomId)) && !mDirects.has(roomId), [mx, mDirects] ); - return useAtomValue(selectAtom(roomsAtom, selector, compareRoomsEqual)); + return useSelectedRooms(roomsAtom, selector); }; -export const useDirects = ( +export const useOrphanRooms = ( mx: MatrixClient, - roomsAtom: typeof allRoomsAtom, - directAtom: typeof mDirectAtom + roomsAtom: RoomsAtom, + mDirects: Set, + roomToParents: RoomToParents ) => { - const mDirects = useAtomValue(directAtom); - const selector = useCallback( - (rooms: string[]) => - rooms.filter((roomId) => isRoom(mx.getRoom(roomId)) && mDirects.has(roomId)), + const selector: RoomSelector = useCallback( + (roomId) => isRoom(mx.getRoom(roomId)) && !mDirects.has(roomId) && !roomToParents.has(roomId), + [mx, mDirects, roomToParents] + ); + return useSelectedRooms(roomsAtom, selector); +}; + +export const useDirects = (mx: MatrixClient, roomsAtom: RoomsAtom, mDirects: Set) => { + const selector: RoomSelector = useCallback( + (roomId) => isRoom(mx.getRoom(roomId)) && mDirects.has(roomId), [mx, mDirects] ); - return useAtomValue(selectAtom(roomsAtom, selector, compareRoomsEqual)); + return useSelectedRooms(roomsAtom, selector); }; -export const useUnsupportedRooms = (mx: MatrixClient, roomsAtom: typeof allRoomsAtom) => { - const selector = useCallback( - (rooms: string[]) => rooms.filter((roomId) => isUnsupportedRoom(mx.getRoom(roomId))), +export const useUnsupportedRooms = (mx: MatrixClient, roomsAtom: RoomsAtom) => { + const selector: RoomSelector = useCallback( + (roomId) => isUnsupportedRoom(mx.getRoom(roomId)), [mx] ); - return useAtomValue(selectAtom(roomsAtom, selector, compareRoomsEqual)); + return useSelectedRooms(roomsAtom, selector); }; diff --git a/src/app/state/hooks/unread.ts b/src/app/state/hooks/unread.ts new file mode 100644 index 000000000..62386d02f --- /dev/null +++ b/src/app/state/hooks/unread.ts @@ -0,0 +1,46 @@ +import { useCallback } from 'react'; +import { useAtomValue } from 'jotai'; +import { selectAtom } from 'jotai/utils'; +import { RoomToUnread, Unread } from '../../../types/matrix/room'; +import { roomToUnreadAtom, unreadEqual } from '../room/roomToUnread'; + +const compareUnreadEqual = (u1?: Unread, u2?: Unread): boolean => { + if (!u1 || !u2) return false; + return unreadEqual(u1, u2); +}; + +const getRoomsUnread = (rooms: string[], roomToUnread: RoomToUnread): Unread | undefined => { + const unread = rooms.reduce((u, roomId) => { + const roomUnread = roomToUnread.get(roomId); + if (!roomUnread) return u; + const newUnread: Unread = u ?? { + total: 0, + highlight: 0, + from: new Set(), + }; + newUnread.total += roomUnread.total; + newUnread.highlight += roomUnread.highlight; + newUnread.from?.add(roomId); + return newUnread; + }, undefined); + return unread; +}; + +export const useRoomsUnread = ( + rooms: string[], + roomToUnreadAtm: typeof roomToUnreadAtom +): Unread | undefined => { + const selector = useCallback( + (roomToUnread: RoomToUnread) => getRoomsUnread(rooms, roomToUnread), + [rooms] + ); + return useAtomValue(selectAtom(roomToUnreadAtm, selector, compareUnreadEqual)); +}; + +export const useRoomUnread = ( + roomId: string, + roomToUnreadAtm: typeof roomToUnreadAtom +): Unread | undefined => { + const selector = useCallback((roomToUnread: RoomToUnread) => roomToUnread.get(roomId), [roomId]); + return useAtomValue(selectAtom(roomToUnreadAtm, selector, compareUnreadEqual)); +}; diff --git a/src/app/state/hooks/useBindAtoms.ts b/src/app/state/hooks/useBindAtoms.ts index 6dc2a3de9..136c833f0 100644 --- a/src/app/state/hooks/useBindAtoms.ts +++ b/src/app/state/hooks/useBindAtoms.ts @@ -1,10 +1,11 @@ import { MatrixClient } from 'matrix-js-sdk'; -import { allInvitesAtom, useBindAllInvitesAtom } from '../inviteList'; -import { allRoomsAtom, useBindAllRoomsAtom } from '../roomList'; +import { allInvitesAtom, useBindAllInvitesAtom } from '../room-list/inviteList'; +import { allRoomsAtom, useBindAllRoomsAtom } from '../room-list/roomList'; import { mDirectAtom, useBindMDirectAtom } from '../mDirectList'; -import { muteChangesAtom, mutedRoomsAtom, useBindMutedRoomsAtom } from '../mutedRoomList'; -import { roomToUnreadAtom, useBindRoomToUnreadAtom } from '../roomToUnread'; -import { roomToParentsAtom, useBindRoomToParentsAtom } from '../roomToParents'; +import { muteChangesAtom, mutedRoomsAtom, useBindMutedRoomsAtom } from '../room-list/mutedRoomList'; +import { roomToUnreadAtom, useBindRoomToUnreadAtom } from '../room/roomToUnread'; +import { roomToParentsAtom, useBindRoomToParentsAtom } from '../room/roomToParents'; +import { roomIdToTypingMembersAtom, useBindRoomIdToTypingMembersAtom } from '../typingMembers'; export const useBindAtoms = (mx: MatrixClient) => { useBindMDirectAtom(mx, mDirectAtom); @@ -13,4 +14,6 @@ export const useBindAtoms = (mx: MatrixClient) => { useBindRoomToParentsAtom(mx, roomToParentsAtom); useBindMutedRoomsAtom(mx, mutedRoomsAtom); useBindRoomToUnreadAtom(mx, roomToUnreadAtom, muteChangesAtom); + + useBindRoomIdToTypingMembersAtom(mx, roomIdToTypingMembersAtom); }; diff --git a/src/app/state/mDirectList.ts b/src/app/state/mDirectList.ts index 1fa8311f4..95165255f 100644 --- a/src/app/state/mDirectList.ts +++ b/src/app/state/mDirectList.ts @@ -30,10 +30,12 @@ export const useBindMDirectAtom = (mx: MatrixClient, mDirect: typeof mDirectAtom } const handleAccountData = (event: MatrixEvent) => { - setMDirect({ - type: 'UPDATE', - rooms: getMDirects(event), - }); + if (event.getType() === AccountDataEvent.Direct) { + setMDirect({ + type: 'UPDATE', + rooms: getMDirects(event), + }); + } }; mx.on(ClientEvent.AccountData, handleAccountData); diff --git a/src/app/state/navToActivePath.ts b/src/app/state/navToActivePath.ts new file mode 100644 index 000000000..80869146a --- /dev/null +++ b/src/app/state/navToActivePath.ts @@ -0,0 +1,66 @@ +import { WritableAtom, atom } from 'jotai'; +import produce from 'immer'; +import { Path } from 'react-router-dom'; +import { + atomWithLocalStorage, + getLocalStorageItem, + setLocalStorageItem, +} from './utils/atomWithLocalStorage'; + +const NAV_TO_ACTIVE_PATH = 'navToActivePath'; + +type NavToActivePath = Map; + +type NavToActivePathAction = + | { + type: 'PUT'; + navId: string; + path: Path; + } + | { + type: 'DELETE'; + navId: string; + }; + +export type NavToActivePathAtom = WritableAtom; + +export const makeNavToActivePathAtom = (userId: string): NavToActivePathAtom => { + const storeKey = `${NAV_TO_ACTIVE_PATH}${userId}`; + + const baseNavToActivePathAtom = atomWithLocalStorage( + storeKey, + (key) => { + const obj: Record = getLocalStorageItem(key, {}); + return new Map(Object.entries(obj)); + }, + (key, value) => { + const obj: Record = Object.fromEntries(value); + setLocalStorageItem(key, obj); + } + ); + + const navToActivePathAtom = atom( + (get) => get(baseNavToActivePathAtom), + (get, set, action) => { + if (action.type === 'DELETE') { + set( + baseNavToActivePathAtom, + produce(get(baseNavToActivePathAtom), (draft) => { + draft.delete(action.navId); + }) + ); + return; + } + if (action.type === 'PUT') { + set( + baseNavToActivePathAtom, + produce(get(baseNavToActivePathAtom), (draft) => { + draft.set(action.navId, action.path); + }) + ); + } + } + ); + + return navToActivePathAtom; +}; diff --git a/src/app/state/openedSidebarFolder.ts b/src/app/state/openedSidebarFolder.ts new file mode 100644 index 000000000..70373b3b2 --- /dev/null +++ b/src/app/state/openedSidebarFolder.ts @@ -0,0 +1,66 @@ +import { WritableAtom, atom } from 'jotai'; +import produce from 'immer'; +import { + atomWithLocalStorage, + getLocalStorageItem, + setLocalStorageItem, +} from './utils/atomWithLocalStorage'; + +const OPENED_SIDEBAR_FOLDER = 'openedSidebarFolder'; + +type OpenedSidebarFolderAction = + | { + type: 'PUT'; + id: string; + } + | { + type: 'DELETE'; + id: string; + }; + +export type OpenedSidebarFolderAtom = WritableAtom< + Set, + [OpenedSidebarFolderAction], + undefined +>; + +export const makeOpenedSidebarFolderAtom = (userId: string): OpenedSidebarFolderAtom => { + const storeKey = `${OPENED_SIDEBAR_FOLDER}${userId}`; + + const baseOpenedSidebarFolderAtom = atomWithLocalStorage>( + storeKey, + (key) => { + const arrayValue = getLocalStorageItem(key, []); + return new Set(arrayValue); + }, + (key, value) => { + const arrayValue = Array.from(value); + setLocalStorageItem(key, arrayValue); + } + ); + + const openedSidebarFolderAtom = atom, [OpenedSidebarFolderAction], undefined>( + (get) => get(baseOpenedSidebarFolderAtom), + (get, set, action) => { + if (action.type === 'DELETE') { + set( + baseOpenedSidebarFolderAtom, + produce(get(baseOpenedSidebarFolderAtom), (draft) => { + draft.delete(action.id); + }) + ); + return; + } + if (action.type === 'PUT') { + set( + baseOpenedSidebarFolderAtom, + produce(get(baseOpenedSidebarFolderAtom), (draft) => { + draft.add(action.id); + }) + ); + } + } + ); + + return openedSidebarFolderAtom; +}; diff --git a/src/app/state/inviteList.ts b/src/app/state/room-list/inviteList.ts similarity index 94% rename from src/app/state/inviteList.ts rename to src/app/state/room-list/inviteList.ts index a6dc79668..4fa97be45 100644 --- a/src/app/state/inviteList.ts +++ b/src/app/state/room-list/inviteList.ts @@ -1,7 +1,7 @@ import { atom, WritableAtom } from 'jotai'; import { MatrixClient } from 'matrix-js-sdk'; import { useMemo } from 'react'; -import { Membership } from '../../types/matrix/room'; +import { Membership } from '../../../types/matrix/room'; import { RoomsAction, useBindRoomsWithMembershipsAtom } from './utils'; const baseRoomsAtom = atom([]); diff --git a/src/app/state/mutedRoomList.ts b/src/app/state/room-list/mutedRoomList.ts similarity index 96% rename from src/app/state/mutedRoomList.ts rename to src/app/state/room-list/mutedRoomList.ts index f818450bb..cb56ec0f9 100644 --- a/src/app/state/mutedRoomList.ts +++ b/src/app/state/room-list/mutedRoomList.ts @@ -1,8 +1,8 @@ import { atom, useSetAtom } from 'jotai'; import { ClientEvent, IPushRule, IPushRules, MatrixClient, MatrixEvent } from 'matrix-js-sdk'; import { useEffect } from 'react'; -import { MuteChanges } from '../../types/matrix/room'; -import { findMutedRule, isMutedRule } from '../utils/room'; +import { MuteChanges } from '../../../types/matrix/room'; +import { findMutedRule, isMutedRule } from '../../utils/room'; export type MutedRoomsUpdate = | { diff --git a/src/app/state/roomList.ts b/src/app/state/room-list/roomList.ts similarity index 93% rename from src/app/state/roomList.ts rename to src/app/state/room-list/roomList.ts index e0fa170fb..736a0bc2a 100644 --- a/src/app/state/roomList.ts +++ b/src/app/state/room-list/roomList.ts @@ -1,7 +1,7 @@ import { atom } from 'jotai'; import { MatrixClient } from 'matrix-js-sdk'; import { useMemo } from 'react'; -import { Membership } from '../../types/matrix/room'; +import { Membership } from '../../../types/matrix/room'; import { RoomsAction, useBindRoomsWithMembershipsAtom } from './utils'; const baseRoomsAtom = atom([]); diff --git a/src/app/state/utils.ts b/src/app/state/room-list/utils.ts similarity index 91% rename from src/app/state/utils.ts rename to src/app/state/room-list/utils.ts index 4c4caa5ca..1ca7e7de1 100644 --- a/src/app/state/utils.ts +++ b/src/app/state/room-list/utils.ts @@ -1,7 +1,7 @@ import { useSetAtom, WritableAtom } from 'jotai'; import { ClientEvent, MatrixClient, Room, RoomEvent } from 'matrix-js-sdk'; import { useEffect } from 'react'; -import { Membership } from '../../types/matrix/room'; +import { Membership } from '../../../types/matrix/room'; export type RoomsAction = | { @@ -38,7 +38,9 @@ export const useBindRoomsWithMembershipsAtom = ( }; const handleMembershipChange = (room: Room) => { - if (!satisfyMembership(room)) { + if (satisfyMembership(room)) { + setRoomsAtom({ type: 'PUT', roomId: room.roomId }); + } else { setRoomsAtom({ type: 'DELETE', roomId: room.roomId }); } }; diff --git a/src/app/state/roomInputDrafts.ts b/src/app/state/room/roomInputDrafts.ts similarity index 88% rename from src/app/state/roomInputDrafts.ts rename to src/app/state/room/roomInputDrafts.ts index 2708b8bdf..60b42fdb7 100644 --- a/src/app/state/roomInputDrafts.ts +++ b/src/app/state/room/roomInputDrafts.ts @@ -2,9 +2,9 @@ import { atom } from 'jotai'; import { atomFamily } from 'jotai/utils'; import { Descendant } from 'slate'; import { EncryptedAttachmentInfo } from 'browser-encrypt-attachment'; -import { TListAtom, createListAtom } from './list'; -import { createUploadAtomFamily } from './upload'; -import { TUploadContent } from '../utils/matrix'; +import { TListAtom, createListAtom } from '../list'; +import { createUploadAtomFamily } from '../upload'; +import { TUploadContent } from '../../utils/matrix'; export const roomUploadAtomFamily = createUploadAtomFamily(); diff --git a/src/app/state/roomToParents.ts b/src/app/state/room/roomToParents.ts similarity index 93% rename from src/app/state/roomToParents.ts rename to src/app/state/room/roomToParents.ts index 1e2ef18c4..b58190cdb 100644 --- a/src/app/state/roomToParents.ts +++ b/src/app/state/room/roomToParents.ts @@ -9,14 +9,14 @@ import { RoomStateEvent, } from 'matrix-js-sdk'; import { useEffect } from 'react'; -import { Membership, RoomToParents, StateEvent } from '../../types/matrix/room'; +import { Membership, RoomToParents, StateEvent } from '../../../types/matrix/room'; import { getRoomToParents, getSpaceChildren, isSpace, isValidChild, mapParentWithChildren, -} from '../utils/room'; +} from '../../utils/room'; export type RoomToParentsAction = | { @@ -83,6 +83,10 @@ export const useBindRoomToParentsAtom = ( }; const handleMembershipChange = (room: Room, membership: string) => { + if (room.getMyMembership() === Membership.Leave) { + setRoomToParents({ type: 'DELETE', roomId: room.roomId }); + return; + } if (isSpace(room) && membership === Membership.Join) { setRoomToParents({ type: 'PUT', parent: room.roomId, children: getSpaceChildren(room) }); } diff --git a/src/app/state/roomToUnread.ts b/src/app/state/room/roomToUnread.ts similarity index 74% rename from src/app/state/roomToUnread.ts rename to src/app/state/room/roomToUnread.ts index ad388763e..4ac391fe9 100644 --- a/src/app/state/roomToUnread.ts +++ b/src/app/state/room/roomToUnread.ts @@ -1,15 +1,24 @@ import produce from 'immer'; import { atom, useSetAtom, PrimitiveAtom, useAtomValue } from 'jotai'; -import { IRoomTimelineData, MatrixClient, MatrixEvent, Room, RoomEvent } from 'matrix-js-sdk'; +import { + IRoomTimelineData, + MatrixClient, + MatrixEvent, + Room, + RoomEvent, + SyncState, +} from 'matrix-js-sdk'; import { ReceiptContent, ReceiptType } from 'matrix-js-sdk/lib/@types/read_receipts'; -import { useEffect } from 'react'; +import { useCallback, useEffect } from 'react'; import { MuteChanges, Membership, NotificationType, RoomToUnread, UnreadInfo, -} from '../../types/matrix/room'; + Unread, + StateEvent, +} from '../../../types/matrix/room'; import { getAllParents, getNotificationType, @@ -17,8 +26,10 @@ import { getUnreadInfos, isNotificationEvent, roomHaveUnread, -} from '../utils/room'; +} from '../../utils/room'; import { roomToParentsAtom } from './roomToParents'; +import { useStateEventCallback } from '../../hooks/useStateEventCallback'; +import { useSyncState } from '../../hooks/useSyncState'; export type RoomToUnreadAction = | { @@ -34,17 +45,19 @@ export type RoomToUnreadAction = roomId: string; }; +const unreadInfoToUnread = (unreadInfo: UnreadInfo): Unread => ({ + highlight: unreadInfo.highlight, + total: unreadInfo.total, + from: null, +}); + const putUnreadInfo = ( roomToUnread: RoomToUnread, allParents: Set, unreadInfo: UnreadInfo ) => { const oldUnread = roomToUnread.get(unreadInfo.roomId) ?? { highlight: 0, total: 0, from: null }; - roomToUnread.set(unreadInfo.roomId, { - highlight: unreadInfo.highlight, - total: unreadInfo.total, - from: null, - }); + roomToUnread.set(unreadInfo.roomId, unreadInfoToUnread(unreadInfo)); const newH = unreadInfo.highlight - oldUnread.highlight; const newT = unreadInfo.total - oldUnread.total; @@ -81,6 +94,28 @@ const deleteUnreadInfo = (roomToUnread: RoomToUnread, allParents: Set, r }); }; +export const unreadEqual = (u1: Unread, u2: Unread): boolean => { + const countEqual = u1.highlight === u2.highlight && u1.total === u2.total; + + if (!countEqual) return false; + + const f1 = u1.from; + const f2 = u2.from; + if (f1 === null && f2 === null) return true; + if (f1 === null || f2 === null) return false; + + if (f1.size !== f2.size) return false; + + let fromEqual = true; + f1?.forEach((item) => { + if (!f2?.has(item)) { + fromEqual = false; + } + }); + + return fromEqual; +}; + const baseRoomToUnread = atom(new Map()); export const roomToUnreadAtom = atom( (get) => get(baseRoomToUnread), @@ -98,13 +133,20 @@ export const roomToUnreadAtom = atom putUnreadInfo( draftRoomToUnread, - getAllParents(get(roomToParentsAtom), action.unreadInfo.roomId), - action.unreadInfo + getAllParents(get(roomToParentsAtom), unreadInfo.roomId), + unreadInfo ) ) ); @@ -140,6 +182,21 @@ export const useBindRoomToUnreadAtom = ( }); }, [mx, setUnreadAtom]); + useSyncState( + mx, + useCallback( + (state) => { + if (state === SyncState.Prepared) { + setUnreadAtom({ + type: 'RESET', + unreadInfos: getUnreadInfos(mx), + }); + } + }, + [mx, setUnreadAtom] + ) + ); + useEffect(() => { const handleTimelineEvent = ( mEvent: MatrixEvent, @@ -216,4 +273,19 @@ export const useBindRoomToUnreadAtom = ( mx.removeListener(RoomEvent.MyMembership, handleMembershipChange); }; }, [mx, setUnreadAtom]); + + useStateEventCallback( + mx, + useCallback( + (mEvent) => { + if (mEvent.getType() === StateEvent.SpaceChild) { + setUnreadAtom({ + type: 'RESET', + unreadInfos: getUnreadInfos(mx), + }); + } + }, + [mx, setUnreadAtom] + ) + ); }; diff --git a/src/app/state/selectedRoom.ts b/src/app/state/selectedRoom.ts deleted file mode 100644 index 1ef04de35..000000000 --- a/src/app/state/selectedRoom.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { atom } from 'jotai'; - -export const selectedRoomAtom = atom(undefined); diff --git a/src/app/state/selectedTab.ts b/src/app/state/selectedTab.ts deleted file mode 100644 index e680ae606..000000000 --- a/src/app/state/selectedTab.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { atom } from 'jotai'; - -export enum SidebarTab { - Home = 'Home', - People = 'People', -} - -export const selectedTabAtom = atom(SidebarTab.Home); diff --git a/src/app/state/spaceRooms.ts b/src/app/state/spaceRooms.ts new file mode 100644 index 000000000..8480498d4 --- /dev/null +++ b/src/app/state/spaceRooms.ts @@ -0,0 +1,54 @@ +import { atom } from 'jotai'; +import produce from 'immer'; +import { + atomWithLocalStorage, + getLocalStorageItem, + setLocalStorageItem, +} from './utils/atomWithLocalStorage'; + +const SPACE_ROOMS = 'spaceRooms'; + +const baseSpaceRoomsAtom = atomWithLocalStorage>( + SPACE_ROOMS, + (key) => { + const arrayValue = getLocalStorageItem(key, []); + return new Set(arrayValue); + }, + (key, value) => { + const arrayValue = Array.from(value); + setLocalStorageItem(key, arrayValue); + } +); + +type SpaceRoomsAction = + | { + type: 'PUT'; + roomId: string; + } + | { + type: 'DELETE'; + roomId: string; + }; + +export const spaceRoomsAtom = atom, [SpaceRoomsAction], undefined>( + (get) => get(baseSpaceRoomsAtom), + (get, set, action) => { + if (action.type === 'DELETE') { + set( + baseSpaceRoomsAtom, + produce(get(baseSpaceRoomsAtom), (draft) => { + draft.delete(action.roomId); + }) + ); + return; + } + if (action.type === 'PUT') { + set( + baseSpaceRoomsAtom, + produce(get(baseSpaceRoomsAtom), (draft) => { + draft.add(action.roomId); + }) + ); + } + } +); diff --git a/src/app/state/tabToRoom.ts b/src/app/state/tabToRoom.ts deleted file mode 100644 index b9472d9f9..000000000 --- a/src/app/state/tabToRoom.ts +++ /dev/null @@ -1,34 +0,0 @@ -import produce from 'immer'; -import { atom } from 'jotai'; -import { MatrixClient } from 'matrix-js-sdk'; - -type RoomInfo = { - roomId: string; - timestamp: number; -}; -type TabToRoom = Map; - -type TabToRoomAction = { - type: 'PUT'; - tabInfo: { tabId: string; roomInfo: RoomInfo }; -}; - -const baseTabToRoom = atom(new Map()); -export const tabToRoomAtom = atom( - (get) => get(baseTabToRoom), - (get, set, action) => { - if (action.type === 'PUT') { - set( - baseTabToRoom, - produce(get(baseTabToRoom), (draft) => { - draft.set(action.tabInfo.tabId, action.tabInfo.roomInfo); - }) - ); - } - } -); - -export const useBindTabToRoomAtom = (mx: MatrixClient) => { - console.log(mx); - // TODO: -}; diff --git a/src/app/state/typingMembers.ts b/src/app/state/typingMembers.ts index c77c91be6..88d4687cd 100644 --- a/src/app/state/typingMembers.ts +++ b/src/app/state/typingMembers.ts @@ -1,28 +1,76 @@ +import produce from 'immer'; import { atom, useSetAtom } from 'jotai'; import { selectAtom } from 'jotai/utils'; -import { - MatrixClient, - RoomMember, - RoomMemberEvent, - RoomMemberEventHandlerMap, -} from 'matrix-js-sdk'; +import { MatrixClient, RoomMemberEvent, RoomMemberEventHandlerMap } from 'matrix-js-sdk'; import { useEffect } from 'react'; -export type IRoomIdToTypingMembers = Map; +export const TYPING_TIMEOUT_MS = 5000; // 5 seconds -export type IRoomIdToTypingMembersAction = - | { - type: 'PUT'; - roomId: string; - member: RoomMember; - } - | { - type: 'DELETE'; - roomId: string; - member: RoomMember; - }; +export type TypingReceipt = { + userId: string; + ts: number; +}; +export type IRoomIdToTypingMembers = Map; + +type TypingMemberPutAction = { + type: 'PUT'; + roomId: string; + userId: string; + ts: number; +}; +type TypingMemberDeleteAction = { + type: 'DELETE'; + roomId: string; + userId: string; +}; +export type IRoomIdToTypingMembersAction = TypingMemberPutAction | TypingMemberDeleteAction; const baseRoomIdToTypingMembersAtom = atom(new Map()); + +const putTypingMember = ( + roomToMembers: IRoomIdToTypingMembers, + action: TypingMemberPutAction +): IRoomIdToTypingMembers => { + let typingMembers = roomToMembers.get(action.roomId) ?? []; + + typingMembers = typingMembers.filter((receipt) => receipt.userId !== action.userId); + typingMembers.push({ + userId: action.userId, + ts: action.ts, + }); + roomToMembers.set(action.roomId, typingMembers); + return roomToMembers; +}; + +const deleteTypingMember = ( + roomToMembers: IRoomIdToTypingMembers, + action: TypingMemberDeleteAction +): IRoomIdToTypingMembers => { + let typingMembers = roomToMembers.get(action.roomId) ?? []; + + typingMembers = typingMembers.filter((receipt) => receipt.userId !== action.userId); + if (typingMembers.length === 0) { + roomToMembers.delete(action.roomId); + } else { + roomToMembers.set(action.roomId, typingMembers); + } + return roomToMembers; +}; + +const timeoutReceipt = ( + roomToMembers: IRoomIdToTypingMembers, + roomId: string, + userId: string, + timeout: number +): boolean | undefined => { + const typingMembers = roomToMembers.get(roomId) ?? []; + + const target = typingMembers.find((receipt) => receipt.userId === userId); + if (!target) return undefined; + + return Date.now() - target.ts >= timeout; +}; + export const roomIdToTypingMembersAtom = atom< IRoomIdToTypingMembers, [IRoomIdToTypingMembersAction], @@ -30,16 +78,48 @@ export const roomIdToTypingMembersAtom = atom< >( (get) => get(baseRoomIdToTypingMembersAtom), (get, set, action) => { - const roomIdToTypingMembers = get(baseRoomIdToTypingMembersAtom); - let typingMembers = roomIdToTypingMembers.get(action.roomId) ?? []; - - typingMembers = typingMembers.filter((member) => member.userId !== action.member.userId); + const rToTyping = get(baseRoomIdToTypingMembersAtom); if (action.type === 'PUT') { - typingMembers = [...typingMembers, action.member]; + set( + baseRoomIdToTypingMembersAtom, + produce(rToTyping, (draft) => putTypingMember(draft, action)) + ); + + // remove typing receipt after some timeout + // to prevent stuck typing members + setTimeout(() => { + const { roomId, userId } = action; + const timeout = timeoutReceipt( + get(baseRoomIdToTypingMembersAtom), + roomId, + userId, + TYPING_TIMEOUT_MS + ); + if (timeout) { + set( + baseRoomIdToTypingMembersAtom, + produce(get(baseRoomIdToTypingMembersAtom), (draft) => + deleteTypingMember(draft, { + type: 'DELETE', + roomId, + userId, + }) + ) + ); + } + }, TYPING_TIMEOUT_MS); + } + + if ( + action.type === 'DELETE' && + rToTyping.get(action.roomId)?.find((receipt) => receipt.userId === action.userId) + ) { + set( + baseRoomIdToTypingMembersAtom, + produce(rToTyping, (draft) => deleteTypingMember(draft, action)) + ); } - roomIdToTypingMembers.set(action.roomId, typingMembers); - set(baseRoomIdToTypingMembersAtom, new Map([...roomIdToTypingMembers])); } ); @@ -57,7 +137,8 @@ export const useBindRoomIdToTypingMembersAtom = ( setTypingMembers({ type: member.typing ? 'PUT' : 'DELETE', roomId: member.roomId, - member, + userId: member.userId, + ts: Date.now(), }); }; diff --git a/src/app/styles/ContainerColor.css.ts b/src/app/styles/ContainerColor.css.ts new file mode 100644 index 000000000..cb1f933da --- /dev/null +++ b/src/app/styles/ContainerColor.css.ts @@ -0,0 +1,33 @@ +import { ComplexStyleRule } from '@vanilla-extract/css'; +import { RecipeVariants, recipe } from '@vanilla-extract/recipes'; +import { ContainerColor as TContainerColor, DefaultReset, color } from 'folds'; + +const getVariant = (variant: TContainerColor): ComplexStyleRule => ({ + vars: { + backgroundColor: color[variant].Container, + borderColor: color[variant].ContainerLine, + outlineColor: color[variant].ContainerLine, + color: color[variant].OnContainer, + }, +}); + +export const ContainerColor = recipe({ + base: [DefaultReset], + variants: { + variant: { + Background: getVariant('Background'), + Surface: getVariant('Surface'), + SurfaceVariant: getVariant('SurfaceVariant'), + Primary: getVariant('Primary'), + Secondary: getVariant('Secondary'), + Success: getVariant('Success'), + Warning: getVariant('Warning'), + Critical: getVariant('Critical'), + }, + }, + defaultVariants: { + variant: 'Surface', + }, +}); + +export type ContainerColorVariants = RecipeVariants; diff --git a/src/app/styles/CustomHtml.css.ts b/src/app/styles/CustomHtml.css.ts index 076bbb61b..d86a32366 100644 --- a/src/app/styles/CustomHtml.css.ts +++ b/src/app/styles/CustomHtml.css.ts @@ -211,3 +211,11 @@ export const EmoticonImg = style([ cursor: 'default', }, ]); + +export const highlightText = style([ + DefaultReset, + { + backgroundColor: 'yellow', + color: 'black', + }, +]); diff --git a/src/app/templates/client/Client.jsx b/src/app/templates/client/Client.jsx index e9be6b16e..f6ef2b9e1 100644 --- a/src/app/templates/client/Client.jsx +++ b/src/app/templates/client/Client.jsx @@ -1,24 +1,13 @@ -import React, { useState, useEffect, useRef } from 'react'; +import React, { useEffect, useRef } from 'react'; import './Client.scss'; -import { initHotkeys } from '../../../client/event/hotkeys'; -import { initRoomListListener } from '../../../client/event/roomList'; - -import Text from '../../atoms/text/Text'; -import Spinner from '../../atoms/spinner/Spinner'; -import Navigation from '../../organisms/navigation/Navigation'; -import ContextMenu, { MenuItem } from '../../atoms/context-menu/ContextMenu'; -import IconButton from '../../atoms/button/IconButton'; import ReusableContextMenu from '../../atoms/context-menu/ReusableContextMenu'; import Windows from '../../organisms/pw/Windows'; import Dialogs from '../../organisms/pw/Dialogs'; -import initMatrix from '../../../client/initMatrix'; import navigation from '../../../client/state/navigation'; import cons from '../../../client/state/cons'; -import VerticalMenuIC from '../../../../public/res/ic/outlined/vertical-menu.svg'; -import { MatrixClientProvider } from '../../hooks/useMatrixClient'; import { ClientContent } from './ClientContent'; import { useSetting } from '../../state/hooks/settings'; import { settingsAtom } from '../../state/settings'; @@ -36,8 +25,6 @@ function SystemEmojiFeature() { } function Client() { - const [isLoading, changeLoading] = useState(true); - const [loadingMsg, setLoadingMsg] = useState('Heating up'); const classNameHidden = 'client__item-hidden'; const navWrapperRef = useRef(null); @@ -62,76 +49,19 @@ function Client() { }; }, []); - useEffect(() => { - changeLoading(true); - let counter = 0; - const iId = setInterval(() => { - const msgList = ['Almost there...', 'Looks like you have a lot of stuff to heat up!']; - if (counter === msgList.length - 1) { - setLoadingMsg(msgList[msgList.length - 1]); - clearInterval(iId); - return; - } - setLoadingMsg(msgList[counter]); - counter += 1; - }, 15000); - initMatrix.once('init_loading_finished', () => { - clearInterval(iId); - initHotkeys(); - initRoomListListener(initMatrix.roomList); - changeLoading(false); - }); - initMatrix.init(); - }, []); - - if (isLoading) { - return ( -
      -
      - - initMatrix.clearCacheAndReload()}> - Clear cache & reload - - initMatrix.logout()}>Logout - - } - render={(toggle) => ( - - )} - /> -
      - - - {loadingMsg} - - -
      - - Cinny - -
      -
      - ); - } - return ( - -
      -
      - -
      -
      - -
      - - - - +
      + {/*
      + +
      */} +
      +
      - + + + + +
      ); } diff --git a/src/app/templates/client/Client.scss b/src/app/templates/client/Client.scss index cdb8fcc94..bad5fc93b 100644 --- a/src/app/templates/client/Client.scss +++ b/src/app/templates/client/Client.scss @@ -3,11 +3,12 @@ .client-container { display: flex; height: 100%; + flex-grow: 1; } .navigation__wrapper { width: var(--navigation-width); - + @include screen.smallerThan(mobileBreakpoint) { width: 100%; } diff --git a/src/app/templates/client/ClientContent.jsx b/src/app/templates/client/ClientContent.jsx index ada7008e5..cebe012c2 100644 --- a/src/app/templates/client/ClientContent.jsx +++ b/src/app/templates/client/ClientContent.jsx @@ -6,7 +6,7 @@ import navigation from '../../../client/state/navigation'; import { openNavigation } from '../../../client/action/navigation'; import Welcome from '../../organisms/welcome/Welcome'; -import { RoomBaseView } from '../../organisms/room/Room'; +import { RoomBaseView } from '../../features/room/Room'; export function ClientContent() { const [roomInfo, setRoomInfo] = useState({ diff --git a/src/app/utils/ASCIILexicalTable.ts b/src/app/utils/ASCIILexicalTable.ts new file mode 100644 index 000000000..61b2481a6 --- /dev/null +++ b/src/app/utils/ASCIILexicalTable.ts @@ -0,0 +1,393 @@ +export class ASCIILexicalTable { + readonly startCode: number; + + readonly endCode: number; + + readonly maxStrWidth: number; + + private readonly widthToSize: number[]; + + private readonly rangeCount: (i: number, j: number) => number; + + constructor(startCode: number, endCode: number, maxStrWidth: number) { + if (startCode > endCode) { + throw new Error('Invalid ASCII code! startCode is greater than endCode.'); + } + if (startCode < 0 || endCode > 128) { + throw new Error('Invalid ASCII code range!'); + } + + if (maxStrWidth <= 0) { + throw new Error('Invalid max string width!'); + } + + this.maxStrWidth = maxStrWidth; + this.startCode = startCode; + this.endCode = endCode; + + /** + * @param i smaller - inclusive + * @param j larger - inclusive + * @returns number + */ + this.rangeCount = (i: number, j: number): number => j - i + 1; + + this.widthToSize = []; + this.populateWidthToSize(); + + if (this.size() > Number.MAX_SAFE_INTEGER) { + console.warn( + `[!] Warning: ASCIILexicalTable size is larger than the Number.MAX_SAFE_INTEGER: ${this.size()} > ${ + Number.MAX_SAFE_INTEGER + }` + ); + } + } + + private populateWidthToSize() { + const chars = this.rangeCount(this.startCode, this.endCode); + for (let i = 0, count = 0; i < this.maxStrWidth; i += 1) { + count = count * chars + chars; + this.widthToSize[i] = count; + } + } + + private getWidthToSize(width: number): number { + return this.widthToSize[width - 1]; + } + + first(): string { + return String.fromCharCode(this.startCode); + } + + last(): string { + let str = ''; + for (let i = 0; i < this.maxStrWidth; i += 1) { + str += String.fromCharCode(this.endCode); + } + return str; + } + + hasIndex(index: number): boolean { + return index >= 0 && index < this.size(); + } + + has(str: string): boolean { + if (str.length === 0 || str.length > this.maxStrWidth) { + return false; + } + + let charCode: number; + for (let i = 0; i < str.length; i += 1) { + charCode = str.charCodeAt(i); + if (charCode < this.startCode || charCode > this.endCode) { + return false; + } + } + return true; + } + + size(): number { + return this.getWidthToSize(this.maxStrWidth); + } + + index(str: string): number { + if (!this.has(str)) { + return -1; + } + + let index = 0; + const chars = this.rangeCount(this.startCode, this.endCode); + + for (let i = 0; i < this.maxStrWidth; i += 1) { + const code = str.charCodeAt(i); + + if (Number.isNaN(code)) { + return index; + } + + const opStrWidth = this.maxStrWidth - i; + const opStrTableSize = this.getWidthToSize(opStrWidth); + + const segmentSize = opStrTableSize / chars; + + const codeIndex = code - this.startCode; + const emptyCount = i === 0 ? 0 : 1; + + index += segmentSize * codeIndex + emptyCount; + } + + return index; + } + + get(index: number): string | undefined { + if (!this.hasIndex(index)) { + return undefined; + } + + let str = ''; + const chars = this.rangeCount(this.startCode, this.endCode); + + for (let toIndex = index, i = 0; i < this.maxStrWidth; i += 1) { + const opStrWidth = this.maxStrWidth - i; + const opStrTableSize = this.getWidthToSize(opStrWidth); + + const segmentSize = opStrTableSize / chars; + + const segmentIndex = Math.floor(toIndex / segmentSize); + str += String.fromCharCode(this.startCode + segmentIndex); + + toIndex -= segmentIndex * segmentSize; + if (toIndex === 0) { + break; + } + toIndex -= 1; + } + + return str; + } + + previous(str: string): string | undefined { + if (!this.has(str)) return undefined; + let prev = str; + const lastCode = prev.charCodeAt(prev.length - 1); + prev = prev.slice(0, prev.length - 1); + + if (lastCode === this.startCode) { + if (prev.length === 0) return undefined; + return prev; + } + + prev += String.fromCharCode(lastCode - 1); + while (prev.length < this.maxStrWidth) { + prev += String.fromCharCode(this.endCode); + } + return prev; + } + + next(str: string): string | undefined { + if (!this.has(str)) return undefined; + let next = str; + + if (next.length < this.maxStrWidth) { + next += String.fromCharCode(this.startCode); + return next; + } + + for (let i = next.length - 1; i >= 0; i -= 1) { + const lastCode = next.charCodeAt(i); + if (lastCode !== this.endCode) { + next = next.slice(0, i) + String.fromCharCode(lastCode + 1); + return next; + } + next = next.slice(0, i); + } + return undefined; + } + + between(a: string, b: string): string | undefined { + if (!this.has(a) || !this.has(b)) { + return undefined; + } + + const centerIndex = Math.floor((this.index(a) + this.index(b)) / 2); + + const str = this.get(centerIndex); + if (str === a || str === b) return undefined; + return str; + } + + nBetween(n: number, a: string, b: string): string[] | undefined { + if (n <= 0 || !this.has(a) || !this.has(b)) { + return undefined; + } + + const indexA = this.index(a); + const indexB = this.index(b); + + const nBetween = Math.max(indexA, indexB) - Math.min(indexA, indexB); + if (nBetween < n) { + return undefined; + } + const segmentSize = Math.floor(nBetween / (n + 1)); + if (segmentSize === 0) return undefined; + + const items: string[] = []; + + for ( + let segmentIndex = indexA + segmentSize; + segmentIndex < indexB; + segmentIndex += segmentSize + ) { + if (items.length === n) break; + + const str = this.get(segmentIndex); + + if (!str) break; + items.push(str); + } + + if (items.length < n) { + return undefined; + } + + return items; + } +} + +// const printLex = (lex: ASCIILexicalTable) => { +// const padRight = (s: string, maxWidth: number, padding: string): string => { +// let ns = s; +// for (let i = s.length; i < maxWidth; i += 1) { +// ns += padding; +// } +// return ns; +// }; + +// const formattedLine = (n: number, item: string): string => +// `|${padRight(n.toString(), lex.size().toString().length, ' ')}|${item}|`; + +// const hr = `|${padRight('-', lex.size().toString().length, '-')}|${padRight( +// '-', +// lex.maxStrWidth, +// '-' +// )}|`; + +// console.log(`All lexicographic string combination in order.`); +// console.log(`Start ASCII code: "${lex.startCode}"`); +// console.log(`End ASCII code: "${lex.endCode}"`); +// console.log(`Max string width: ${lex.maxStrWidth}`); +// console.log(`Total String Combination Count: ${lex.size()}\n`); +// console.log('Table:'); +// console.log(hr); +// for (let i = 0; i < lex.size(); i += 1) { +// const str = lex.get(i); +// if (str) { +// console.log(formattedLine(i, padRight(str, lex.maxStrWidth, '_'))); +// } +// } +// console.log(hr); +// }; + +// console.log('\n'); + +// const lex = new ASCIILexicalTable('a'.charCodeAt(0), 'c'.charCodeAt(0), 3); +// printLex(lex); +// console.log(lex.size()); +// console.log(lex.nBetween(8, ' ', '~~~~~')); +// console.log(lex.between('a', 'ccc')); +// console.log(lex.get(11)); +// console.log(lex.get(11) === 'aaac'); + +// const lex4 = new ASCIILexicalTable(' '.charCodeAt(0), '~'.charCodeAt(0), 5); +// console.log('Size: ', lex4.size()); +// console.log('Between: ', lex4.between('7g7g5', 'caccc')); +// printLex(lex4); + +// console.log('\n'); + +// const perf = () => { +// const loopLength = 99999; +// const lexT = new ASCIILexicalTable('a'.charCodeAt(0), 'z'.charCodeAt(0), 9); +// console.log(lexT.size()); +// const str = 'bcbba'; +// const strI = lexT.index(str); +// console.log('================'); +// console.time('index'); +// console.log(lexT.index(str)); +// for (let i = 0; i < loopLength; i += 1) { +// lexT.index(str); +// } +// console.timeEnd('index'); +// console.log('================'); +// console.time('get'); +// console.log(lexT.get(strI)); +// for (let i = 0; i < loopLength; i += 1) { +// lexT.get(strI); +// } +// console.timeEnd('get'); +// console.log('================'); +// console.time('previous'); +// console.log(lexT.previous(str)); +// for (let i = 0; i < loopLength; i += 1) { +// lexT.previous(str); +// } +// console.timeEnd('previous'); +// console.log('================'); +// console.time('next'); +// console.log(lexT.next(str)); +// for (let i = 0; i < loopLength; i += 1) { +// lexT.next(str); +// } +// console.timeEnd('next'); +// console.log('================'); +// console.time('between'); +// console.log(lexT.between(str, 'cbbca')); +// for (let i = 0; i < loopLength; i += 1) { +// lexT.between(str, 'cbbca'); +// } +// console.timeEnd('between'); +// }; + +// perf(); + +const findNextFilledKey = ( + fromIndex: number, + keys: Array +): [number, string] | [-1, undefined] => { + for (let j = fromIndex; j < keys.length; j += 1) { + const key = keys[j]; + if (typeof key === 'string') { + return [j, key]; + } + } + + return [-1, undefined]; +}; + +export const orderKeys = ( + lex: ASCIILexicalTable, + keys: Array +): Array | undefined => { + const newKeys: string[] = []; + + for (let i = 0; i < keys.length; ) { + const key = keys[i]; + const collectedKeys: string[] = []; + const [nextKeyIndex, nextKey] = findNextFilledKey(i + 1, keys); + const isKey = typeof key === 'string'; + + if (isKey) { + collectedKeys.push(key); + } + + const keyToGenerateCount = + (nextKeyIndex === -1 ? keys.length : nextKeyIndex) - (key ? i + 1 : i + 0); + + if (keyToGenerateCount > 0) { + const generatedKeys = lex.nBetween( + keyToGenerateCount, + key ?? lex.first(), + nextKey ?? lex.last() + ); + if (generatedKeys) { + collectedKeys.push(...generatedKeys); + } else { + return lex.nBetween(keys?.length, lex.first(), lex.last()); + } + } + + newKeys.push(...collectedKeys); + i += collectedKeys.length; + } + + if (newKeys.length !== keys.length) { + return undefined; + } + + return newKeys; +}; + +// const lex = new ASCIILexicalTable('a'.charCodeAt(0), 'b'.charCodeAt(0), 2); +// const keys = [undefined, undefined]; +// console.log(orderKeys(lex, keys)); diff --git a/src/app/utils/common.ts b/src/app/utils/common.ts index 5cbe3806b..6d7b69c13 100644 --- a/src/app/utils/common.ts +++ b/src/app/utils/common.ts @@ -95,3 +95,20 @@ export const trimLeadingSlash = (str: string): string => str.replace(START_SLASH export const trimTrailingSlash = (str: string): string => str.replace(END_SLASHES_REG, ''); export const trimSlash = (str: string): string => trimLeadingSlash(trimTrailingSlash(str)); + +export const nameInitials = (str: string | undefined | null, len = 1): string => { + if (!str) return '�'; + return [...str].slice(0, len).join('') || '�'; +}; + +export const randomStr = (len = 12): string => { + let str = ''; + const minCode = 'A'.charCodeAt(0); + const maxCode = 'Z'.charCodeAt(0); + + for (let i = 0; i < len; i += 1) { + const code = Math.floor(Math.random() * (maxCode - minCode + 1) + minCode); + str += String.fromCharCode(code); + } + return str; +}; diff --git a/src/app/utils/keyboard.ts b/src/app/utils/keyboard.ts index 78aa25218..8ec435d3d 100644 --- a/src/app/utils/keyboard.ts +++ b/src/app/utils/keyboard.ts @@ -23,3 +23,10 @@ export const preventScrollWithArrowKey: KeyboardEventHandler = (evt) => { evt.preventDefault(); } }; + +export const onEnterOrSpace = (callback: () => void) => (evt: KeyboardEventLike) => { + if (isKeyHotkey('enter', evt) || isKeyHotkey('space', evt)) { + evt.preventDefault(); + callback(); + } +}; diff --git a/src/app/utils/matrix.ts b/src/app/utils/matrix.ts index 9303c9ac0..55e16a95d 100644 --- a/src/app/utils/matrix.ts +++ b/src/app/utils/matrix.ts @@ -8,10 +8,12 @@ import { MatrixError, MatrixEvent, Room, + RoomMember, UploadProgress, UploadResponse, } from 'matrix-js-sdk'; import { IImageInfo, IThumbnailContent, IVideoInfo } from '../../types/matrix/common'; +import { AccountDataEvent } from '../../types/matrix/accountData'; export const matchMxId = (id: string): RegExpMatchArray | null => id.match(/^([@!$+#])(\S+):(\S+)$/); @@ -37,8 +39,11 @@ export const parseMatrixToUrl = (url: string): [string | undefined, string | und return [g1AsMxId, g3AsVia]; }; -export const getRoomWithCanonicalAlias = (mx: MatrixClient, alias: string): Room | undefined => - mx.getRooms()?.find((room) => room.getCanonicalAlias() === alias); +export const getCanonicalAliasRoomId = (mx: MatrixClient, alias: string): string | undefined => + mx.getRooms()?.find((room) => room.getCanonicalAlias() === alias)?.roomId; + +export const getCanonicalAliasOrRoomId = (mx: MatrixClient, roomId: string): string => + mx.getRoom(roomId)?.getCanonicalAlias() || roomId; export const getImageInfo = (img: HTMLImageElement, fileOrBlob: File | Blob): IImageInfo => { const info: IImageInfo = {}; @@ -162,10 +167,86 @@ export const factoryEventSentBy = (senderId: string) => (ev: MatrixEvent) => export const eventWithShortcode = (ev: MatrixEvent) => typeof ev.getContent().shortcode === 'string'; -export function hasDMWith(mx: MatrixClient, userId: string) { +export const getDMRoomFor = (mx: MatrixClient, userId: string): Room | undefined => { const dmLikeRooms = mx .getRooms() .filter((room) => mx.isRoomEncrypted(room.roomId) && room.getMembers().length <= 2); return dmLikeRooms.find((room) => room.getMember(userId)); -} +}; + +export const guessDmRoomUserId = (room: Room, myUserId: string): string => { + const getOldestMember = (members: RoomMember[]): RoomMember | undefined => { + let oldestMemberTs: number | undefined; + let oldestMember: RoomMember | undefined; + + const pickOldestMember = (member: RoomMember) => { + if (member.userId === myUserId) return; + + if ( + oldestMemberTs === undefined || + (member.events.member && member.events.member.getTs() < oldestMemberTs) + ) { + oldestMember = member; + oldestMemberTs = member.events.member?.getTs(); + } + }; + + members.forEach(pickOldestMember); + + return oldestMember; + }; + + // Pick the joined user who's been here longest (and isn't us), + const member = getOldestMember(room.getJoinedMembers()); + if (member) return member.userId; + + // if there are no joined members other than us, use the oldest member + const member1 = getOldestMember(room.currentState.getMembers()); + return member1?.userId ?? myUserId; +}; + +export const addRoomIdToMDirect = async ( + mx: MatrixClient, + roomId: string, + userId: string +): Promise => { + const mDirectsEvent = mx.getAccountData(AccountDataEvent.Direct); + const userIdToRoomIds: Record = mDirectsEvent?.getContent() ?? {}; + + // remove it from the lists of any others users + // (it can only be a DM room for one person) + Object.keys(userIdToRoomIds).forEach((targetUserId) => { + const roomIds = userIdToRoomIds[targetUserId]; + + if (targetUserId !== userId) { + const indexOfRoomId = roomIds.indexOf(roomId); + if (indexOfRoomId > -1) { + roomIds.splice(indexOfRoomId, 1); + } + } + }); + + const roomIds = userIdToRoomIds[userId] || []; + if (roomIds.indexOf(roomId) === -1) { + roomIds.push(roomId); + } + userIdToRoomIds[userId] = roomIds; + + await mx.setAccountData(AccountDataEvent.Direct, userIdToRoomIds); +}; + +export const removeRoomIdFromMDirect = async (mx: MatrixClient, roomId: string): Promise => { + const mDirectsEvent = mx.getAccountData(AccountDataEvent.Direct); + const userIdToRoomIds: Record = mDirectsEvent?.getContent() ?? {}; + + Object.keys(userIdToRoomIds).forEach((targetUserId) => { + const roomIds = userIdToRoomIds[targetUserId]; + const indexOfRoomId = roomIds.indexOf(roomId); + if (indexOfRoomId > -1) { + roomIds.splice(indexOfRoomId, 1); + } + }); + + await mx.setAccountData(AccountDataEvent.Direct, userIdToRoomIds); +}; diff --git a/src/app/utils/regex.ts b/src/app/utils/regex.ts index 281f12006..d7169062d 100644 --- a/src/app/utils/regex.ts +++ b/src/app/utils/regex.ts @@ -1,5 +1,7 @@ export const HTTP_URL_PATTERN = `https?:\\/\\/(?:www\\.)?(?:[^\\s)]*)(?()[\]\\.,;:\s@\\"]+(\.[^<>()[\]\\.,;:\s@\\"]+)*)|(\\".+\\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; @@ -10,3 +12,9 @@ export const VARIATION_SELECTOR_PATTERN = '[\uFE00-\uFE0F]'; // https://github.com/mathiasbynens/emoji-regex export const EMOJI_PATTERN = `[#*0-9]\uFE0F?\u20E3|[\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23ED-\u23EF\u23F1\u23F2\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB\u25FC\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692\u2694-\u2697\u2699\u269B\u269C\u26A0\u26A7\u26AA\u26B0\u26B1\u26BD\u26BE\u26C4\u26C8\u26CF\u26D1\u26E9\u26F0-\u26F5\u26F7\u26F8\u26FA\u2702\u2708\u2709\u270F\u2712\u2714\u2716\u271D\u2721\u2733\u2734\u2744\u2747\u2757\u2763\u27A1\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B55\u3030\u303D\u3297\u3299]\uFE0F?|[\u261D\u270C\u270D](?:\uFE0F|\uD83C[\uDFFB-\uDFFF])?|[\u270A\u270B](?:\uD83C[\uDFFB-\uDFFF])?|[\u23E9-\u23EC\u23F0\u23F3\u25FD\u2693\u26A1\u26AB\u26C5\u26CE\u26D4\u26EA\u26FD\u2705\u2728\u274C\u274E\u2753-\u2755\u2795-\u2797\u27B0\u27BF\u2B50]|\u26D3\uFE0F?(?:\u200D\uD83D\uDCA5)?|\u26F9(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|\u2764\uFE0F?(?:\u200D(?:\uD83D\uDD25|\uD83E\uDE79))?|\uD83C(?:[\uDC04\uDD70\uDD71\uDD7E\uDD7F\uDE02\uDE37\uDF21\uDF24-\uDF2C\uDF36\uDF7D\uDF96\uDF97\uDF99-\uDF9B\uDF9E\uDF9F\uDFCD\uDFCE\uDFD4-\uDFDF\uDFF5\uDFF7]\uFE0F?|[\uDF85\uDFC2\uDFC7](?:\uD83C[\uDFFB-\uDFFF])?|[\uDFC4\uDFCA](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDFCB\uDFCC](?:\uFE0F|\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDCCF\uDD8E\uDD91-\uDD9A\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF43\uDF45-\uDF4A\uDF4C-\uDF7C\uDF7E-\uDF84\uDF86-\uDF93\uDFA0-\uDFC1\uDFC5\uDFC6\uDFC8\uDFC9\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF8-\uDFFF]|\uDDE6\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF]|\uDDE7\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF]|\uDDE8\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF5\uDDF7\uDDFA-\uDDFF]|\uDDE9\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF]|\uDDEA\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA]|\uDDEB\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7]|\uDDEC\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE]|\uDDED\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA]|\uDDEE\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9]|\uDDEF\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5]|\uDDF0\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF]|\uDDF1\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE]|\uDDF2\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF]|\uDDF3\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF]|\uDDF4\uD83C\uDDF2|\uDDF5\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE]|\uDDF6\uD83C\uDDE6|\uDDF7\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC]|\uDDF8\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF]|\uDDF9\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF]|\uDDFA\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF]|\uDDFB\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA]|\uDDFC\uD83C[\uDDEB\uDDF8]|\uDDFD\uD83C\uDDF0|\uDDFE\uD83C[\uDDEA\uDDF9]|\uDDFF\uD83C[\uDDE6\uDDF2\uDDFC]|\uDF44(?:\u200D\uD83D\uDFEB)?|\uDF4B(?:\u200D\uD83D\uDFE9)?|\uDFC3(?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D(?:[\u2640\u2642]\uFE0F?(?:\u200D\u27A1\uFE0F?)?|\u27A1\uFE0F?))?|\uDFF3\uFE0F?(?:\u200D(?:\u26A7\uFE0F?|\uD83C\uDF08))?|\uDFF4(?:\u200D\u2620\uFE0F?|\uDB40\uDC67\uDB40\uDC62\uDB40(?:\uDC65\uDB40\uDC6E\uDB40\uDC67|\uDC73\uDB40\uDC63\uDB40\uDC74|\uDC77\uDB40\uDC6C\uDB40\uDC73)\uDB40\uDC7F)?)|\uD83D(?:[\uDC3F\uDCFD\uDD49\uDD4A\uDD6F\uDD70\uDD73\uDD76-\uDD79\uDD87\uDD8A-\uDD8D\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA\uDECB\uDECD-\uDECF\uDEE0-\uDEE5\uDEE9\uDEF0\uDEF3]\uFE0F?|[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC](?:\uD83C[\uDFFB-\uDFFF])?|[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4\uDEB5](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDD74\uDD90](?:\uFE0F|\uD83C[\uDFFB-\uDFFF])?|[\uDC00-\uDC07\uDC09-\uDC14\uDC16-\uDC25\uDC27-\uDC3A\uDC3C-\uDC3E\uDC40\uDC44\uDC45\uDC51-\uDC65\uDC6A\uDC79-\uDC7B\uDC7D-\uDC80\uDC84\uDC88-\uDC8E\uDC90\uDC92-\uDCA9\uDCAB-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDDA4\uDDFB-\uDE2D\uDE2F-\uDE34\uDE37-\uDE41\uDE43\uDE44\uDE48-\uDE4A\uDE80-\uDEA2\uDEA4-\uDEB3\uDEB7-\uDEBF\uDEC1-\uDEC5\uDED0-\uDED2\uDED5-\uDED7\uDEDC-\uDEDF\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB\uDFF0]|\uDC08(?:\u200D\u2B1B)?|\uDC15(?:\u200D\uD83E\uDDBA)?|\uDC26(?:\u200D(?:\u2B1B|\uD83D\uDD25))?|\uDC3B(?:\u200D\u2744\uFE0F?)?|\uDC41\uFE0F?(?:\u200D\uD83D\uDDE8\uFE0F?)?|\uDC68(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDC68\uDC69]\u200D\uD83D(?:\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?)|[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?)|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]))|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFC-\uDFFF])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFD-\uDFFF])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFD\uDFFF])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFE])))?))?|\uDC69(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?[\uDC68\uDC69]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?|\uDC69\u200D\uD83D(?:\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?))|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]))|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFC-\uDFFF])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB\uDFFD-\uDFFF])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFD\uDFFF])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFE])))?))?|\uDC6F(?:\u200D[\u2640\u2642]\uFE0F?)?|\uDD75(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|\uDE2E(?:\u200D\uD83D\uDCA8)?|\uDE35(?:\u200D\uD83D\uDCAB)?|\uDE36(?:\u200D\uD83C\uDF2B\uFE0F?)?|\uDE42(?:\u200D[\u2194\u2195]\uFE0F?)?|\uDEB6(?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D(?:[\u2640\u2642]\uFE0F?(?:\u200D\u27A1\uFE0F?)?|\u27A1\uFE0F?))?)|\uD83E(?:[\uDD0C\uDD0F\uDD18-\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5\uDEC3-\uDEC5\uDEF0\uDEF2-\uDEF8](?:\uD83C[\uDFFB-\uDFFF])?|[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD\uDDCF\uDDD4\uDDD6-\uDDDD](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDDDE\uDDDF](?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDD0D\uDD0E\uDD10-\uDD17\uDD20-\uDD25\uDD27-\uDD2F\uDD3A\uDD3F-\uDD45\uDD47-\uDD76\uDD78-\uDDB4\uDDB7\uDDBA\uDDBC-\uDDCC\uDDD0\uDDE0-\uDDFF\uDE70-\uDE7C\uDE80-\uDE88\uDE90-\uDEBD\uDEBF-\uDEC2\uDECE-\uDEDB\uDEE0-\uDEE8]|\uDD3C(?:\u200D[\u2640\u2642]\uFE0F?|\uD83C[\uDFFB-\uDFFF])?|\uDDCE(?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D(?:[\u2640\u2642]\uFE0F?(?:\u200D\u27A1\uFE0F?)?|\u27A1\uFE0F?))?|\uDDD1(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83E\uDDD1|\uDDD1\u200D\uD83E\uDDD2(?:\u200D\uD83E\uDDD2)?|\uDDD2(?:\u200D\uD83E\uDDD2)?))|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFC-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB\uDFFD-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB-\uDFFD\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB-\uDFFE]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF])))?))?|\uDEF1(?:\uD83C(?:\uDFFB(?:\u200D\uD83E\uDEF2\uD83C[\uDFFC-\uDFFF])?|\uDFFC(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB\uDFFD-\uDFFF])?|\uDFFD(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])?|\uDFFE(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB-\uDFFD\uDFFF])?|\uDFFF(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB-\uDFFE])?))?)`; + +// Thumbs up emoji found to have Variation Selector 16 at the end +// so included variation selector pattern in regex +export const JUMBO_EMOJI_REG = new RegExp( + `^(((${EMOJI_PATTERN})|(:.+?:))(${VARIATION_SELECTOR_PATTERN}|\\s)*){1,10}$` +); diff --git a/src/app/utils/room.ts b/src/app/utils/room.ts index a2cb3a9f1..750dd6ca7 100644 --- a/src/app/utils/room.ts +++ b/src/app/utils/room.ts @@ -76,8 +76,8 @@ export const isSpace = (room: Room | null): boolean => { export const isRoom = (room: Room | null): boolean => { if (!room) return false; const event = getStateEvent(room, StateEvent.RoomCreate); - if (!event) return false; - return event.getContent().type === undefined; + if (!event) return true; + return event.getContent().type !== RoomType.Space; }; export const isUnsupportedRoom = (room: Room | null): boolean => { @@ -88,7 +88,10 @@ export const isUnsupportedRoom = (room: Room | null): boolean => { }; export function isValidChild(mEvent: MatrixEvent): boolean { - return mEvent.getType() === StateEvent.SpaceChild && Object.keys(mEvent.getContent()).length > 0; + return ( + mEvent.getType() === StateEvent.SpaceChild && + Array.isArray(mEvent.getContent<{ via: string[] }>().via) + ); } export const getAllParents = (roomToParents: RoomToParents, roomId: string): Set => { @@ -141,6 +144,15 @@ export const getRoomToParents = (mx: MatrixClient): RoomToParents => { return map; }; +export const getOrphanParents = (roomToParents: RoomToParents, roomId: string): string[] => { + const parents = getAllParents(roomToParents, roomId); + const orphanParents = Array.from(parents).filter( + (parentRoomId) => !roomToParents.has(parentRoomId) + ); + + return orphanParents; +}; + export const isMutedRule = (rule: IPushRule) => rule.actions[0] === 'dont_notify' && rule.conditions?.[0]?.kind === 'event_match'; @@ -167,14 +179,18 @@ export const getNotificationType = (mx: MatrixClient, roomId: string): Notificat return NotificationType.MentionsAndKeywords; }; +const NOTIFICATION_EVENT_TYPES = [ + 'm.room.create', + 'm.room.message', + 'm.room.encrypted', + 'm.room.member', + 'm.sticker', +]; export const isNotificationEvent = (mEvent: MatrixEvent) => { const eType = mEvent.getType(); - if ( - ['m.room.create', 'm.room.message', 'm.room.encrypted', 'm.room.member', 'm.sticker'].find( - (type) => type === eType - ) - ) + if (!NOTIFICATION_EVENT_TYPES.includes(eType)) { return false; + } if (eType === 'm.room.member') return false; if (mEvent.isRedacted()) return false; @@ -183,6 +199,13 @@ export const isNotificationEvent = (mEvent: MatrixEvent) => { return true; }; +export const roomHaveNotification = (room: Room): boolean => { + const total = room.getUnreadNotificationCount(NotificationCountType.Total); + const highlight = room.getUnreadNotificationCount(NotificationCountType.Highlight); + + return total > 0 || highlight > 0; +}; + export const roomHaveUnread = (mx: MatrixClient, room: Room) => { const userId = mx.getUserId(); if (!userId) return false; @@ -218,7 +241,7 @@ export const getUnreadInfos = (mx: MatrixClient): UnreadInfo[] => { if (room.getMyMembership() !== 'join') return unread; if (getNotificationType(mx, room.roomId) === NotificationType.Mute) return unread; - if (roomHaveUnread(mx, room)) { + if (roomHaveNotification(room) || roomHaveUnread(mx, room)) { unread.push(getUnreadInfo(room)); } @@ -247,13 +270,19 @@ export const joinRuleToIconSrc = ( return undefined; }; -export const getRoomAvatarUrl = (mx: MatrixClient, room: Room): string | undefined => { - const url = - room.getAvatarFallbackMember()?.getAvatarUrl(mx.baseUrl, 32, 32, 'crop', undefined, false) ?? - undefined; - if (url) return url; - return room.getAvatarUrl(mx.baseUrl, 32, 32, 'crop') ?? undefined; -}; +export const getRoomAvatarUrl = ( + mx: MatrixClient, + room: Room, + size: 32 | 96 = 32 +): string | undefined => room.getAvatarUrl(mx.baseUrl, size, size, 'crop') ?? undefined; + +export const getDirectRoomAvatarUrl = ( + mx: MatrixClient, + room: Room, + size: 32 | 96 = 32 +): string | undefined => + room.getAvatarFallbackMember()?.getAvatarUrl(mx.baseUrl, size, size, 'crop', undefined, false) ?? + undefined; export const trimReplyFromBody = (body: string): string => { const match = body.match(/^> <.+?> .+\n(>.*\n)*?\n/m); diff --git a/src/app/utils/sort.ts b/src/app/utils/sort.ts new file mode 100644 index 000000000..512c19989 --- /dev/null +++ b/src/app/utils/sort.ts @@ -0,0 +1,59 @@ +import { MatrixClient } from 'matrix-js-sdk'; + +export type SortFunc = (a: T, b: T) => number; + +export const factoryRoomIdByActivity = + (mx: MatrixClient): SortFunc => + (a, b) => { + const room1 = mx.getRoom(a); + const room2 = mx.getRoom(b); + + return ( + (room2?.getLastActiveTimestamp() ?? Number.MIN_SAFE_INTEGER) - + (room1?.getLastActiveTimestamp() ?? Number.MIN_SAFE_INTEGER) + ); + }; + +export const factoryRoomIdByAtoZ = + (mx: MatrixClient): SortFunc => + (a, b) => { + let aName = mx.getRoom(a)?.name ?? ''; + let bName = mx.getRoom(b)?.name ?? ''; + + // remove "#" from the room name + // To ignore it in sorting + aName = aName.replace(/#/g, ''); + bName = bName.replace(/#/g, ''); + + if (aName.toLowerCase() < bName.toLowerCase()) { + return -1; + } + if (aName.toLowerCase() > bName.toLowerCase()) { + return 1; + } + return 0; + }; + +export const factoryRoomIdByUnreadCount = + (getUnreadCount: (roomId: string) => number): SortFunc => + (a, b) => { + const aT = getUnreadCount(a) ?? 0; + const bT = getUnreadCount(b) ?? 0; + return bT - aT; + }; + +export const byTsOldToNew: SortFunc = (a, b) => a - b; + +export const byOrderKey: SortFunc = (a, b) => { + if (!a && !b) { + return 0; + } + + if (!b) return -1; + if (!a) return 1; + + if (a < b) { + return -1; + } + return 1; +}; diff --git a/src/client/action/navigation.js b/src/client/action/navigation.js index 4ee78a638..e48e839b3 100644 --- a/src/client/action/navigation.js +++ b/src/client/action/navigation.js @@ -45,17 +45,19 @@ export function openSpaceManage(roomId) { }); } -export function openSpaceAddExisting(roomId) { +export function openSpaceAddExisting(roomId, spaces = false) { appDispatcher.dispatch({ type: cons.actions.navigation.OPEN_SPACE_ADDEXISTING, roomId, + spaces, }); } -export function toggleRoomSettings(tabText) { +export function toggleRoomSettings(roomId, tabText) { appDispatcher.dispatch({ type: cons.actions.navigation.TOGGLE_ROOM_SETTINGS, - tabText, + roomId, + tabText }); } diff --git a/src/client/event/hotkeys.js b/src/client/event/hotkeys.js index e59ce3d75..076d37941 100644 --- a/src/client/event/hotkeys.js +++ b/src/client/event/hotkeys.js @@ -1,4 +1,4 @@ -import { openSearch, toggleRoomSettings } from '../action/navigation'; +import { openSearch } from '../action/navigation'; import navigation from '../state/navigation'; import { markAsRead } from '../action/notifications'; @@ -53,10 +53,6 @@ function listenKeyboard(event) { if (navigation.isRawModalVisible) return; if (event.key === 'Escape') { - if (navigation.isRoomSettings) { - toggleRoomSettings(); - return; - } if (navigation.selectedRoomId) { markAsRead(navigation.selectedRoomId); return; diff --git a/src/client/initMatrix.js b/src/client/initMatrix.js index 211cf1142..835982f81 100644 --- a/src/client/initMatrix.js +++ b/src/client/initMatrix.js @@ -1,7 +1,7 @@ import EventEmitter from 'events'; import * as sdk from 'matrix-js-sdk'; import Olm from '@matrix-org/olm'; -// import { logger } from 'matrix-js-sdk/lib/logger'; +import { logger } from 'matrix-js-sdk/lib/logger'; import { getSecret } from './state/auth'; import RoomList from './state/RoomList'; @@ -13,7 +13,9 @@ import navigation from './state/navigation'; global.Olm = Olm; -// logger.disableAll(); +if (import.meta.env.PROD) { + logger.disableAll(); +} class InitMatrix extends EventEmitter { constructor() { @@ -23,14 +25,20 @@ class InitMatrix extends EventEmitter { } async init() { - if (this.matrixClient) { + if (this.matrixClient || this.initializing) { console.warn('Client is already initialized!') return; } + this.initializing = true; - await this.startClient(); - this.setupSync(); - this.listenEvents(); + try { + await this.startClient(); + this.setupSync(); + this.listenEvents(); + this.initializing = false; + } catch { + this.initializing = false; + } } async startClient() { @@ -62,6 +70,7 @@ class InitMatrix extends EventEmitter { lazyLoadMembers: true, }); this.matrixClient.setGlobalErrorOnUnknownDevices(false); + this.matrixClient.setMaxListeners(50); } setupSync() { diff --git a/src/client/state/navigation.js b/src/client/state/navigation.js index 07231cd4b..ddac4dda8 100644 --- a/src/client/state/navigation.js +++ b/src/client/state/navigation.js @@ -13,7 +13,6 @@ class Navigation extends EventEmitter { this.selectedSpacePath = [cons.tabs.HOME]; this.selectedRoomId = null; - this.isRoomSettings = false; this.recentRooms = []; this.spaceToRoom = new Map(); @@ -85,10 +84,6 @@ class Navigation extends EventEmitter { this.removeRecentRoom(prevSelectedRoomId); this.addRecentRoom(prevSelectedRoomId); this.removeRecentRoom(this.selectedRoomId); - if (this.isRoomSettings && typeof this.selectedRoomId === 'string') { - this.isRoomSettings = !this.isRoomSettings; - this.emit(cons.events.navigation.ROOM_SETTINGS_TOGGLED, this.isRoomSettings); - } this.emit( cons.events.navigation.ROOM_SELECTED, this.selectedRoomId, @@ -305,14 +300,13 @@ class Navigation extends EventEmitter { this.emit(cons.events.navigation.SPACE_MANAGE_OPENED, action.roomId); }, [cons.actions.navigation.OPEN_SPACE_ADDEXISTING]: () => { - this.emit(cons.events.navigation.SPACE_ADDEXISTING_OPENED, action.roomId); + this.emit(cons.events.navigation.SPACE_ADDEXISTING_OPENED, action.roomId, action.spaces); }, [cons.actions.navigation.TOGGLE_ROOM_SETTINGS]: () => { - this.isRoomSettings = !this.isRoomSettings; this.emit( cons.events.navigation.ROOM_SETTINGS_TOGGLED, - this.isRoomSettings, - action.tabText, + action.roomId, + action.tabText ); }, [cons.actions.navigation.OPEN_SHORTCUT_SPACES]: () => { diff --git a/src/index.scss b/src/index.scss index 9dc5b4c30..5290035bd 100644 --- a/src/index.scss +++ b/src/index.scss @@ -68,7 +68,7 @@ --tc-danger-low: rgba(240, 71, 71, 60%); --tc-code: #e62498; - --tc-link: hsl(213deg 76% 56%); + --tc-link: hsl(213deg 100% 45%); --tc-tooltip: white; --tc-badge: white; @@ -86,14 +86,14 @@ --ic-danger-normal: rgba(240, 71, 71, 0.7); /* user mxid colors */ - --mx-uc-1: hsl(208, 66%, 53%); - --mx-uc-2: hsl(302, 49%, 45%); - --mx-uc-3: hsl(163, 97%, 36%); - --mx-uc-4: hsl(343, 75%, 61%); - --mx-uc-5: hsl(24, 100%, 59%); - --mx-uc-6: hsl(181, 63%, 47%); - --mx-uc-7: hsl(242, 89%, 65%); - --mx-uc-8: hsl(94, 65%, 50%); + --mx-uc-1: hsl(208, 100%, 45%); + --mx-uc-2: hsl(302, 100%, 30%); + --mx-uc-3: hsl(163, 100%, 30%); + --mx-uc-4: hsl(343, 100%, 45%); + --mx-uc-5: hsl(24, 100%, 45%); + --mx-uc-6: hsl(181, 100%, 30%); + --mx-uc-7: hsl(242, 100%, 45%); + --mx-uc-8: hsl(94, 100%, 35%); /* system icon size | -ic-[size]: value */ --ic-large: 38px; @@ -242,7 +242,7 @@ --tc-primary-low: rgba(255, 255, 255, 0.4); --tc-code: #e565b1; - --tc-link: hsl(213deg 94% 73%); + --tc-link: hsl(213deg 100% 80%); --tc-badge: black; /* system icons | --ic-[background type]-[priority]: value */ @@ -251,17 +251,14 @@ --ic-surface-low: rgba(255, 255, 255, 64%); --ic-primary-normal: #ffffff; - & .text { - /* override user mxid colors for texts */ - --mx-uc-1: hsl(208, 100%, 58%); - --mx-uc-2: hsl(301, 80%, 70%); - --mx-uc-3: hsl(163, 93%, 41%); - --mx-uc-4: hsl(343, 91%, 66%); - --mx-uc-5: hsl(24, 90%, 67%); - --mx-uc-6: hsl(181, 90%, 50%); - --mx-uc-7: hsl(243, 100%, 74%); - --mx-uc-8: hsl(94, 66%, 50%); - } + --mx-uc-1: hsl(208, 100%, 75%); + --mx-uc-2: hsl(301, 100%, 80%); + --mx-uc-3: hsl(163, 100%, 70%); + --mx-uc-4: hsl(343, 100%, 75%); + --mx-uc-5: hsl(24, 100%, 70%); + --mx-uc-6: hsl(181, 100%, 60%); + --mx-uc-7: hsl(243, 100%, 80%); + --mx-uc-8: hsl(94, 100%, 80%); /* shadow and overlay */ --bg-overlay: rgba(0, 0, 0, 60%); @@ -402,6 +399,7 @@ textarea { margin: 0; padding: 0; background-color: transparent; + color: inherit; font-family: inherit; font-size: inherit; font-weight: inherit; diff --git a/src/types/matrix/room.ts b/src/types/matrix/room.ts index 33419ce5d..c468309d6 100644 --- a/src/types/matrix/room.ts +++ b/src/types/matrix/room.ts @@ -49,6 +49,12 @@ export enum RoomType { Space = 'm.space', } +export type MSpaceChildContent = { + via: string[]; + suggested?: boolean; + order?: string; +}; + export enum NotificationType { Default = 'default', AllMessages = 'all_messages', @@ -67,15 +73,15 @@ export type IRoomCreateContent = { }; }; +export type GetContentCallback = () => T; + export type RoomToParents = Map>; -export type RoomToUnread = Map< - string, - { - total: number; - highlight: number; - from: Set | null; - } ->; +export type Unread = { + total: number; + highlight: number; + from: Set | null; +}; +export type RoomToUnread = Map; export type UnreadInfo = { roomId: string; total: number; diff --git a/vite.config.js b/vite.config.js index 97f405007..1255f81c4 100644 --- a/vite.config.js +++ b/vite.config.js @@ -45,6 +45,12 @@ export default defineConfig({ server: { port: 8080, host: true, + proxy: { + "^\\/.*?\\/olm\\.wasm$": { + target: 'http://localhost:8080', + rewrite: () => '/olm.wasm' + } + } }, plugins: [ topLevelAwait({ From 6987332ba8142f6b9d25a5017fd7b3c3f0b55af4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 4 Jun 2024 14:25:07 +1000 Subject: [PATCH 1144/1531] Bump nginx from 1.26.0-alpine to 1.27.0-alpine (#1759) Bumps nginx from 1.26.0-alpine to 1.27.0-alpine. --- updated-dependencies: - dependency-name: nginx dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index f843fbf19..d6fffeedb 100644 --- a/Dockerfile +++ b/Dockerfile @@ -11,7 +11,7 @@ RUN npm run build ## App -FROM nginx:1.26.0-alpine +FROM nginx:1.27.0-alpine COPY --from=builder /src/dist /app From 9db4b3a9c2f05138612172b7c8a1d5536f67b15e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 4 Jun 2024 14:26:21 +1000 Subject: [PATCH 1145/1531] Bump docker/login-action from 3.1.0 to 3.2.0 (#1758) Bumps [docker/login-action](https://github.com/docker/login-action) from 3.1.0 to 3.2.0. - [Release notes](https://github.com/docker/login-action/releases) - [Commits](https://github.com/docker/login-action/compare/v3.1.0...v3.2.0) --- updated-dependencies: - dependency-name: docker/login-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/prod-deploy.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/prod-deploy.yml b/.github/workflows/prod-deploy.yml index a203ea34c..76ccb7e9f 100644 --- a/.github/workflows/prod-deploy.yml +++ b/.github/workflows/prod-deploy.yml @@ -72,12 +72,12 @@ jobs: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3.3.0 - name: Login to Docker Hub - uses: docker/login-action@v3.1.0 + uses: docker/login-action@v3.2.0 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} - name: Login to the Container registry - uses: docker/login-action@v3.1.0 + uses: docker/login-action@v3.2.0 with: registry: ghcr.io username: ${{ github.actor }} From 09a0a2d7daa12d1e68f04042fbdeb2c5aa279f25 Mon Sep 17 00:00:00 2001 From: Kimiblock Moe Date: Wed, 5 Jun 2024 20:43:19 +0800 Subject: [PATCH 1146/1531] Prevent Safari iOS from auto zooming (#1756) Thanks @pixlxip:beeper.com --- index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.html b/index.html index 48f8e69eb..af2952d38 100644 --- a/index.html +++ b/index.html @@ -3,7 +3,7 @@ - + Cinny From b6157707dbb5064f114bb41e6373cdb1c21189e6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 15 Jun 2024 23:28:03 +1000 Subject: [PATCH 1147/1531] Bump docker/build-push-action from 5.3.0 to 5.4.0 (#1766) Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 5.3.0 to 5.4.0. - [Release notes](https://github.com/docker/build-push-action/releases) - [Commits](https://github.com/docker/build-push-action/compare/v5.3.0...v5.4.0) --- updated-dependencies: - dependency-name: docker/build-push-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/docker-pr.yml | 2 +- .github/workflows/prod-deploy.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docker-pr.yml b/.github/workflows/docker-pr.yml index de29ff35d..aa5d1a2b9 100644 --- a/.github/workflows/docker-pr.yml +++ b/.github/workflows/docker-pr.yml @@ -13,7 +13,7 @@ jobs: - name: Checkout repository uses: actions/checkout@v4.1.6 - name: Build Docker image - uses: docker/build-push-action@v5.3.0 + uses: docker/build-push-action@v5.4.0 with: context: . push: false diff --git a/.github/workflows/prod-deploy.yml b/.github/workflows/prod-deploy.yml index 76ccb7e9f..5afac9427 100644 --- a/.github/workflows/prod-deploy.yml +++ b/.github/workflows/prod-deploy.yml @@ -90,7 +90,7 @@ jobs: ${{ secrets.DOCKER_USERNAME }}/cinny ghcr.io/${{ github.repository }} - name: Build and push Docker image - uses: docker/build-push-action@v5.3.0 + uses: docker/build-push-action@v5.4.0 with: context: . platforms: linux/amd64,linux/arm64 From c4615bd2560e247947a977c14b05e59502d0fe55 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 19 Jun 2024 13:55:34 +1000 Subject: [PATCH 1148/1531] Bump dawidd6/action-download-artifact from 3.1.4 to 6 (#1776) Bumps [dawidd6/action-download-artifact](https://github.com/dawidd6/action-download-artifact) from 3.1.4 to 6. - [Release notes](https://github.com/dawidd6/action-download-artifact/releases) - [Commits](https://github.com/dawidd6/action-download-artifact/compare/09f2f74827fd3a8607589e5ad7f9398816f540fe...bf251b5aa9c2f7eeb574a96ee720e24f801b7c11) --- updated-dependencies: - dependency-name: dawidd6/action-download-artifact dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/deploy-pull-request.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/deploy-pull-request.yml b/.github/workflows/deploy-pull-request.yml index 66e648b07..72ffed87a 100644 --- a/.github/workflows/deploy-pull-request.yml +++ b/.github/workflows/deploy-pull-request.yml @@ -15,7 +15,7 @@ jobs: if: ${{ github.event.workflow_run.conclusion == 'success' }} steps: - name: Download pr number - uses: dawidd6/action-download-artifact@09f2f74827fd3a8607589e5ad7f9398816f540fe + uses: dawidd6/action-download-artifact@bf251b5aa9c2f7eeb574a96ee720e24f801b7c11 with: workflow: ${{ github.event.workflow.id }} run_id: ${{ github.event.workflow_run.id }} @@ -24,7 +24,7 @@ jobs: id: pr run: echo "id=$(> $GITHUB_OUTPUT - name: Download artifact - uses: dawidd6/action-download-artifact@09f2f74827fd3a8607589e5ad7f9398816f540fe + uses: dawidd6/action-download-artifact@bf251b5aa9c2f7eeb574a96ee720e24f801b7c11 with: workflow: ${{ github.event.workflow.id }} run_id: ${{ github.event.workflow_run.id }} From 7a3e8dba924d122b5fbd4c375bf4ba1d039dbb95 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 19 Jun 2024 14:00:11 +1000 Subject: [PATCH 1149/1531] Bump docker/build-push-action from 5.4.0 to 6.0.0 (#1777) Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 5.4.0 to 6.0.0. - [Release notes](https://github.com/docker/build-push-action/releases) - [Commits](https://github.com/docker/build-push-action/compare/v5.4.0...v6.0.0) --- updated-dependencies: - dependency-name: docker/build-push-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/docker-pr.yml | 2 +- .github/workflows/prod-deploy.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docker-pr.yml b/.github/workflows/docker-pr.yml index aa5d1a2b9..3dda9f7bb 100644 --- a/.github/workflows/docker-pr.yml +++ b/.github/workflows/docker-pr.yml @@ -13,7 +13,7 @@ jobs: - name: Checkout repository uses: actions/checkout@v4.1.6 - name: Build Docker image - uses: docker/build-push-action@v5.4.0 + uses: docker/build-push-action@v6.0.0 with: context: . push: false diff --git a/.github/workflows/prod-deploy.yml b/.github/workflows/prod-deploy.yml index 5afac9427..61451f79f 100644 --- a/.github/workflows/prod-deploy.yml +++ b/.github/workflows/prod-deploy.yml @@ -90,7 +90,7 @@ jobs: ${{ secrets.DOCKER_USERNAME }}/cinny ghcr.io/${{ github.repository }} - name: Build and push Docker image - uses: docker/build-push-action@v5.4.0 + uses: docker/build-push-action@v6.0.0 with: context: . platforms: linux/amd64,linux/arm64 From 60e022035f3bbfc09b2b5aee52f83e2aadf054e7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 19 Jun 2024 14:02:12 +1000 Subject: [PATCH 1150/1531] Bump actions/checkout from 4.1.6 to 4.1.7 (#1775) Bumps [actions/checkout](https://github.com/actions/checkout) from 4.1.6 to 4.1.7. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v4.1.6...v4.1.7) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build-pull-request.yml | 2 +- .github/workflows/docker-pr.yml | 2 +- .github/workflows/lockfile.yml | 2 +- .github/workflows/netlify-dev.yml | 2 +- .github/workflows/prod-deploy.yml | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build-pull-request.yml b/.github/workflows/build-pull-request.yml index 133729f70..95a9e8ef5 100644 --- a/.github/workflows/build-pull-request.yml +++ b/.github/workflows/build-pull-request.yml @@ -12,7 +12,7 @@ jobs: PR_NUMBER: ${{github.event.number}} steps: - name: Checkout repository - uses: actions/checkout@v4.1.6 + uses: actions/checkout@v4.1.7 - name: Setup node uses: actions/setup-node@v4.0.2 with: diff --git a/.github/workflows/docker-pr.yml b/.github/workflows/docker-pr.yml index 3dda9f7bb..a45917ba5 100644 --- a/.github/workflows/docker-pr.yml +++ b/.github/workflows/docker-pr.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v4.1.6 + uses: actions/checkout@v4.1.7 - name: Build Docker image uses: docker/build-push-action@v6.0.0 with: diff --git a/.github/workflows/lockfile.yml b/.github/workflows/lockfile.yml index af91698ea..410d2f59a 100644 --- a/.github/workflows/lockfile.yml +++ b/.github/workflows/lockfile.yml @@ -14,7 +14,7 @@ jobs: pull-requests: write steps: - name: Checkout - uses: actions/checkout@v4.1.6 + uses: actions/checkout@v4.1.7 - name: NPM Lockfile Changes uses: codepunkt/npm-lockfile-changes@b40543471c36394409466fdb277a73a0856d7891 with: diff --git a/.github/workflows/netlify-dev.yml b/.github/workflows/netlify-dev.yml index 9252e3e4d..5a0ecbcab 100644 --- a/.github/workflows/netlify-dev.yml +++ b/.github/workflows/netlify-dev.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v4.1.6 + uses: actions/checkout@v4.1.7 - name: Setup node uses: actions/setup-node@v4.0.2 with: diff --git a/.github/workflows/prod-deploy.yml b/.github/workflows/prod-deploy.yml index 61451f79f..227b96c7b 100644 --- a/.github/workflows/prod-deploy.yml +++ b/.github/workflows/prod-deploy.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v4.1.6 + uses: actions/checkout@v4.1.7 - name: Setup node uses: actions/setup-node@v4.0.2 with: @@ -66,7 +66,7 @@ jobs: packages: write steps: - name: Checkout repository - uses: actions/checkout@v4.1.6 + uses: actions/checkout@v4.1.7 - name: Set up QEMU uses: docker/setup-qemu-action@v3.0.0 - name: Set up Docker Buildx From 4f09e6bbb5a633715937a3b89307dd685229606c Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Mon, 8 Jul 2024 16:57:10 +0530 Subject: [PATCH 1151/1531] (chore) remove outdated code (#1765) * optimize room typing members hook * remove unused code - WIP * remove old code from initMatrix * remove twemojify function * remove old sanitize util * delete old markdown util * delete Math atom component * uninstall unused dependencies * remove old notification system * decrypt message in inbox notification center and fix refresh in background * improve notification --------- Co-authored-by: Krishan <33421343+kfiven@users.noreply.github.com> --- index.html | 6 - package-lock.json | 188 +--- package.json | 6 - src/app/atoms/avatar/Avatar.jsx | 62 +- src/app/atoms/math/Math.jsx | 33 - src/app/atoms/math/Math.scss | 3 - src/app/features/room/RoomInput.tsx | 10 +- src/app/features/room/RoomTimeline.tsx | 30 +- src/app/hooks/useCategorizedSpaces.js | 25 - src/app/hooks/useCommands.ts | 4 +- src/app/hooks/usePreviousValue.ts | 11 + src/app/hooks/useRoomTypingMembers.ts | 24 +- src/app/hooks/useSelectedSpace.js | 21 - src/app/hooks/useSelectedTab.js | 21 - src/app/hooks/useSpaceShortcut.js | 25 - src/app/molecules/dialog/Dialog.jsx | 29 +- .../following-members/FollowingMembers.jsx | 61 -- .../following-members/FollowingMembers.scss | 31 - .../image-lightbox/ImageLightbox.jsx | 47 - .../image-lightbox/ImageLightbox.scss | 50 - src/app/molecules/media/Media.jsx | 366 -------- src/app/molecules/media/Media.scss | 90 -- src/app/molecules/message/Message.jsx | 853 ------------------ src/app/molecules/message/Message.scss | 479 ---------- src/app/molecules/message/TimelineChange.jsx | 78 -- src/app/molecules/message/TimelineChange.scss | 37 - .../people-selector/PeopleSelector.jsx | 16 +- .../molecules/popup-window/PopupWindow.jsx | 66 +- .../room-notification/RoomNotification.jsx | 146 +-- .../molecules/room-options/RoomOptions.jsx | 73 -- .../molecules/room-profile/RoomProfile.jsx | 93 +- src/app/molecules/room-search/RoomSearch.jsx | 201 ----- src/app/molecules/room-search/RoomSearch.scss | 62 -- .../molecules/room-selector/RoomSelector.jsx | 41 +- src/app/molecules/room-tile/RoomTile.jsx | 48 +- .../sidebar-avatar/SidebarAvatar.jsx | 55 -- .../sidebar-avatar/SidebarAvatar.scss | 64 -- .../space-add-existing/SpaceAddExisting.jsx | 15 +- .../molecules/space-options/SpaceOptions.jsx | 128 --- src/app/molecules/sso-buttons/SSOButtons.jsx | 41 - src/app/molecules/sso-buttons/SSOButtons.scss | 25 - src/app/organisms/create-room/CreateRoom.jsx | 154 ++-- src/app/organisms/emoji-board/EmojiBoard.jsx | 356 -------- src/app/organisms/emoji-board/EmojiBoard.scss | 137 --- .../emoji-board/EmojiBoardOpener.jsx | 78 -- src/app/organisms/emoji-board/custom-emoji.js | 127 +-- src/app/organisms/emoji-board/emoji.js | 69 -- src/app/organisms/emoji-board/recent.js | 36 - .../emoji-verification/EmojiVerification.jsx | 48 +- src/app/organisms/invite-list/InviteList.jsx | 145 --- src/app/organisms/invite-list/InviteList.scss | 26 - src/app/organisms/invite-user/InviteUser.jsx | 128 +-- src/app/organisms/join-alias/JoinAlias.jsx | 69 +- src/app/organisms/navigation/Directs.jsx | 71 -- src/app/organisms/navigation/Drawer.jsx | 93 -- src/app/organisms/navigation/Drawer.scss | 56 -- .../organisms/navigation/DrawerBreadcrumb.jsx | 142 --- .../navigation/DrawerBreadcrumb.scss | 66 -- src/app/organisms/navigation/DrawerHeader.jsx | 159 ---- .../organisms/navigation/DrawerHeader.scss | 28 - src/app/organisms/navigation/Home.jsx | 112 --- src/app/organisms/navigation/Navigation.jsx | 16 - src/app/organisms/navigation/Navigation.scss | 7 - .../organisms/navigation/RoomsCategory.jsx | 92 -- .../organisms/navigation/RoomsCategory.scss | 54 -- src/app/organisms/navigation/Selector.jsx | 93 -- src/app/organisms/navigation/SideBar.jsx | 390 -------- src/app/organisms/navigation/SideBar.scss | 75 -- .../profile-editor/ProfileEditor.jsx | 24 +- .../profile-viewer/ProfileViewer.jsx | 165 ++-- .../organisms/public-rooms/PublicRooms.jsx | 295 ------ .../organisms/public-rooms/PublicRooms.scss | 85 -- src/app/organisms/pw/Dialogs.jsx | 6 - src/app/organisms/pw/Windows.jsx | 28 - .../organisms/read-receipts/ReadReceipts.jsx | 76 -- src/app/organisms/room/EventLimit.js | 35 - src/app/organisms/room/PeopleDrawer.jsx | 215 ----- src/app/organisms/room/PeopleDrawer.scss | 93 -- src/app/organisms/room/Room.scss | 20 - src/app/organisms/room/RoomSettings.jsx | 3 +- src/app/organisms/room/RoomView.scss | 46 - src/app/organisms/room/RoomViewCmdBar.jsx | 297 ------ src/app/organisms/room/RoomViewCmdBar.scss | 57 -- src/app/organisms/room/RoomViewContent.jsx | 644 ------------- src/app/organisms/room/RoomViewContent.scss | 30 - src/app/organisms/room/RoomViewFloating.jsx | 125 --- src/app/organisms/room/RoomViewFloating.scss | 125 --- src/app/organisms/room/RoomViewHeader.jsx | 132 --- src/app/organisms/room/RoomViewHeader.scss | 47 - src/app/organisms/room/RoomViewInput.jsx | 491 ---------- src/app/organisms/room/RoomViewInput.scss | 108 --- src/app/organisms/room/TimelineScroll.js | 136 --- src/app/organisms/room/commands.jsx | 220 ----- src/app/organisms/room/commands.scss | 10 - src/app/organisms/room/common.jsx | 222 ----- src/app/organisms/search/Search.jsx | 31 +- src/app/organisms/settings/CrossSigning.jsx | 109 ++- src/app/organisms/settings/KeyBackup.jsx | 93 +- .../shortcut-spaces/ShortcutSpaces.jsx | 169 ---- .../shortcut-spaces/ShortcutSpaces.scss | 52 -- .../organisms/space-manage/SpaceManage.jsx | 433 --------- .../organisms/space-manage/SpaceManage.scss | 168 ---- .../space-settings/SpaceSettings.jsx | 9 +- .../organisms/sticker-board/StickerBoard.jsx | 115 --- .../organisms/sticker-board/StickerBoard.scss | 74 -- src/app/organisms/view-source/ViewSource.jsx | 73 -- src/app/organisms/view-source/ViewSource.scss | 19 - src/app/organisms/welcome/Welcome.jsx | 20 - src/app/organisms/welcome/Welcome.scss | 23 - src/app/pages/Router.tsx | 21 +- src/app/pages/client/ClientNonUIFeatures.tsx | 231 +++++ src/app/pages/client/ClientRoot.tsx | 2 - src/app/pages/client/inbox/Notifications.tsx | 88 +- src/app/state/room/roomToUnread.ts | 2 +- src/app/state/typingMembers.ts | 6 - src/app/templates/auth/Auth.jsx | 684 -------------- src/app/templates/auth/Auth.scss | 173 ---- src/app/templates/client/Client.jsx | 68 -- src/app/templates/client/Client.scss | 57 -- src/app/templates/client/ClientContent.jsx | 49 - src/app/utils/disposable.ts | 20 +- src/app/utils/dom.ts | 6 + src/client/action/accountData.js | 41 - src/client/action/auth.js | 104 --- src/client/action/auth.ts | 13 + src/client/action/navigation.js | 87 -- src/client/action/notifications.js | 1 - src/client/action/room.js | 32 +- src/client/action/roomTimeline.js | 34 - src/client/event/hotkeys.js | 59 -- src/client/event/roomList.js | 38 - src/client/initMatrix.js | 19 - src/client/state/AccountData.js | 144 --- src/client/state/Notifications.js | 412 --------- src/client/state/RoomList.js | 383 -------- src/client/state/RoomTimeline.js | 407 --------- src/client/state/RoomsHierarchy.js | 49 - src/client/state/RoomsInput.js | 423 --------- src/client/state/cons.js | 71 -- src/client/state/navigation.js | 318 ------- src/util/Postie.js | 97 -- src/util/colorMXID.js | 2 +- src/util/markdown.js | 515 ----------- src/util/matrixUtil.js | 14 - src/util/mimetypes.js | 39 - src/util/sanitize.js | 140 --- src/util/twemojify.jsx | 31 - 147 files changed, 1164 insertions(+), 15330 deletions(-) delete mode 100644 src/app/atoms/math/Math.jsx delete mode 100644 src/app/atoms/math/Math.scss delete mode 100644 src/app/hooks/useCategorizedSpaces.js create mode 100644 src/app/hooks/usePreviousValue.ts delete mode 100644 src/app/hooks/useSelectedSpace.js delete mode 100644 src/app/hooks/useSelectedTab.js delete mode 100644 src/app/hooks/useSpaceShortcut.js delete mode 100644 src/app/molecules/following-members/FollowingMembers.jsx delete mode 100644 src/app/molecules/following-members/FollowingMembers.scss delete mode 100644 src/app/molecules/image-lightbox/ImageLightbox.jsx delete mode 100644 src/app/molecules/image-lightbox/ImageLightbox.scss delete mode 100644 src/app/molecules/media/Media.jsx delete mode 100644 src/app/molecules/media/Media.scss delete mode 100644 src/app/molecules/message/Message.jsx delete mode 100644 src/app/molecules/message/Message.scss delete mode 100644 src/app/molecules/message/TimelineChange.jsx delete mode 100644 src/app/molecules/message/TimelineChange.scss delete mode 100644 src/app/molecules/room-options/RoomOptions.jsx delete mode 100644 src/app/molecules/room-search/RoomSearch.jsx delete mode 100644 src/app/molecules/room-search/RoomSearch.scss delete mode 100644 src/app/molecules/sidebar-avatar/SidebarAvatar.jsx delete mode 100644 src/app/molecules/sidebar-avatar/SidebarAvatar.scss delete mode 100644 src/app/molecules/space-options/SpaceOptions.jsx delete mode 100644 src/app/molecules/sso-buttons/SSOButtons.jsx delete mode 100644 src/app/molecules/sso-buttons/SSOButtons.scss delete mode 100644 src/app/organisms/emoji-board/EmojiBoard.jsx delete mode 100644 src/app/organisms/emoji-board/EmojiBoard.scss delete mode 100644 src/app/organisms/emoji-board/EmojiBoardOpener.jsx delete mode 100644 src/app/organisms/emoji-board/emoji.js delete mode 100644 src/app/organisms/emoji-board/recent.js delete mode 100644 src/app/organisms/invite-list/InviteList.jsx delete mode 100644 src/app/organisms/invite-list/InviteList.scss delete mode 100644 src/app/organisms/navigation/Directs.jsx delete mode 100644 src/app/organisms/navigation/Drawer.jsx delete mode 100644 src/app/organisms/navigation/Drawer.scss delete mode 100644 src/app/organisms/navigation/DrawerBreadcrumb.jsx delete mode 100644 src/app/organisms/navigation/DrawerBreadcrumb.scss delete mode 100644 src/app/organisms/navigation/DrawerHeader.jsx delete mode 100644 src/app/organisms/navigation/DrawerHeader.scss delete mode 100644 src/app/organisms/navigation/Home.jsx delete mode 100644 src/app/organisms/navigation/Navigation.jsx delete mode 100644 src/app/organisms/navigation/Navigation.scss delete mode 100644 src/app/organisms/navigation/RoomsCategory.jsx delete mode 100644 src/app/organisms/navigation/RoomsCategory.scss delete mode 100644 src/app/organisms/navigation/Selector.jsx delete mode 100644 src/app/organisms/navigation/SideBar.jsx delete mode 100644 src/app/organisms/navigation/SideBar.scss delete mode 100644 src/app/organisms/public-rooms/PublicRooms.jsx delete mode 100644 src/app/organisms/public-rooms/PublicRooms.scss delete mode 100644 src/app/organisms/read-receipts/ReadReceipts.jsx delete mode 100644 src/app/organisms/room/EventLimit.js delete mode 100644 src/app/organisms/room/PeopleDrawer.jsx delete mode 100644 src/app/organisms/room/PeopleDrawer.scss delete mode 100644 src/app/organisms/room/Room.scss delete mode 100644 src/app/organisms/room/RoomView.scss delete mode 100644 src/app/organisms/room/RoomViewCmdBar.jsx delete mode 100644 src/app/organisms/room/RoomViewCmdBar.scss delete mode 100644 src/app/organisms/room/RoomViewContent.jsx delete mode 100644 src/app/organisms/room/RoomViewContent.scss delete mode 100644 src/app/organisms/room/RoomViewFloating.jsx delete mode 100644 src/app/organisms/room/RoomViewFloating.scss delete mode 100644 src/app/organisms/room/RoomViewHeader.jsx delete mode 100644 src/app/organisms/room/RoomViewHeader.scss delete mode 100644 src/app/organisms/room/RoomViewInput.jsx delete mode 100644 src/app/organisms/room/RoomViewInput.scss delete mode 100644 src/app/organisms/room/TimelineScroll.js delete mode 100644 src/app/organisms/room/commands.jsx delete mode 100644 src/app/organisms/room/commands.scss delete mode 100644 src/app/organisms/room/common.jsx delete mode 100644 src/app/organisms/shortcut-spaces/ShortcutSpaces.jsx delete mode 100644 src/app/organisms/shortcut-spaces/ShortcutSpaces.scss delete mode 100644 src/app/organisms/space-manage/SpaceManage.jsx delete mode 100644 src/app/organisms/space-manage/SpaceManage.scss delete mode 100644 src/app/organisms/sticker-board/StickerBoard.jsx delete mode 100644 src/app/organisms/sticker-board/StickerBoard.scss delete mode 100644 src/app/organisms/view-source/ViewSource.jsx delete mode 100644 src/app/organisms/view-source/ViewSource.scss delete mode 100644 src/app/organisms/welcome/Welcome.jsx delete mode 100644 src/app/organisms/welcome/Welcome.scss create mode 100644 src/app/pages/client/ClientNonUIFeatures.tsx delete mode 100644 src/app/templates/auth/Auth.jsx delete mode 100644 src/app/templates/auth/Auth.scss delete mode 100644 src/app/templates/client/Client.jsx delete mode 100644 src/app/templates/client/Client.scss delete mode 100644 src/app/templates/client/ClientContent.jsx delete mode 100644 src/client/action/accountData.js delete mode 100644 src/client/action/auth.js create mode 100644 src/client/action/auth.ts delete mode 100644 src/client/action/roomTimeline.js delete mode 100644 src/client/event/roomList.js delete mode 100644 src/client/state/AccountData.js delete mode 100644 src/client/state/Notifications.js delete mode 100644 src/client/state/RoomList.js delete mode 100644 src/client/state/RoomTimeline.js delete mode 100644 src/client/state/RoomsHierarchy.js delete mode 100644 src/client/state/RoomsInput.js delete mode 100644 src/util/Postie.js delete mode 100644 src/util/markdown.js delete mode 100644 src/util/mimetypes.js delete mode 100644 src/util/sanitize.js delete mode 100644 src/util/twemojify.jsx diff --git a/index.html b/index.html index af2952d38..9196cf3dc 100644 --- a/index.html +++ b/index.html @@ -90,12 +90,6 @@ window.global ||= window;
      - - diff --git a/package-lock.json b/package-lock.json index 17e4dd509..ab70f0fbb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,7 +13,6 @@ "@atlaskit/pragmatic-drag-and-drop-auto-scroll": "1.3.0", "@atlaskit/pragmatic-drag-and-drop-hitbox": "1.0.3", "@fontsource/inter": "4.5.14", - "@khanacademy/simple-markdown": "0.8.6", "@matrix-org/olm": "3.2.14", "@tanstack/react-query": "5.24.1", "@tanstack/react-query-devtools": "5.24.1", @@ -41,8 +40,6 @@ "immer": "9.0.16", "is-hotkey": "0.2.0", "jotai": "2.6.0", - "katex": "0.16.10", - "linkify-html": "4.0.2", "linkify-react": "4.1.1", "linkifyjs": "4.0.2", "matrix-js-sdk": "29.1.0", @@ -54,8 +51,6 @@ "react-aria": "3.29.1", "react-autosize-textarea": "7.1.0", "react-blurhash": "0.2.0", - "react-dnd": "16.0.1", - "react-dnd-html5-backend": "16.0.1", "react-dom": "18.2.0", "react-error-boundary": "4.0.10", "react-google-recaptcha": "2.1.0", @@ -67,7 +62,6 @@ "slate-history": "0.93.0", "slate-react": "0.98.4", "tippy.js": "6.3.7", - "twemoji": "14.0.2", "ua-parser-js": "1.0.35" }, "devDependencies": { @@ -1109,18 +1103,6 @@ "resolved": "https://registry.npmjs.org/@juggle/resize-observer/-/resize-observer-3.4.0.tgz", "integrity": "sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA==" }, - "node_modules/@khanacademy/simple-markdown": { - "version": "0.8.6", - "resolved": "https://registry.npmjs.org/@khanacademy/simple-markdown/-/simple-markdown-0.8.6.tgz", - "integrity": "sha512-mAUlR9lchzfqunR89pFvNI51jQKsMpJeWYsYWw0DQcUXczn/T/V6510utgvm7X0N3zN87j1SvuKk8cMbl9IAFw==", - "dependencies": { - "@types/react": ">=16.0.0" - }, - "peerDependencies": { - "react": "16.14.0", - "react-dom": "16.14.0" - } - }, "node_modules/@mapbox/node-pre-gyp": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz", @@ -1942,21 +1924,6 @@ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" } }, - "node_modules/@react-dnd/asap": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@react-dnd/asap/-/asap-5.0.2.tgz", - "integrity": "sha512-WLyfoHvxhs0V9U+GTsGilGgf2QsPl6ZZ44fnv0/b8T3nQyvzxidxsg/ZltbWssbsRDlYW8UKSQMTGotuTotZ6A==" - }, - "node_modules/@react-dnd/invariant": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@react-dnd/invariant/-/invariant-4.0.2.tgz", - "integrity": "sha512-xKCTqAK/FFauOM9Ta2pswIyT3D8AQlfrYdOi/toTPEhqCuAs1v5tcJ3Y08Izh1cJ5Jchwy9SeAXmMg6zrKs2iw==" - }, - "node_modules/@react-dnd/shallowequal": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@react-dnd/shallowequal/-/shallowequal-4.0.2.tgz", - "integrity": "sha512-/RVXdLvJxLg4QKvMoM5WlwNR9ViO9z8B/qPcc+C0Sa/teJY7QG7kJ441DwzOjMYEY7GmU4dj5EcGHIkKZiQZCA==" - }, "node_modules/@react-stately/calendar": { "version": "3.4.1", "resolved": "https://registry.npmjs.org/@react-stately/calendar/-/calendar-3.4.1.tgz", @@ -3307,12 +3274,14 @@ "node_modules/@types/prop-types": { "version": "15.7.5", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", - "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==" + "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==", + "dev": true }, "node_modules/@types/react": { "version": "18.2.39", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.39.tgz", "integrity": "sha512-Oiw+ppED6IremMInLV4HXGbfbG6GyziY3kqAwJYOR0PNbkYDmLWQA3a95EhdSmamsvbkJN96ZNN+YD+fGjzSBA==", + "dev": true, "dependencies": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -3354,7 +3323,8 @@ "node_modules/@types/scheduler": { "version": "0.16.2", "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", - "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==" + "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==", + "dev": true }, "node_modules/@types/semver": { "version": "7.3.13", @@ -4419,14 +4389,6 @@ "color-support": "bin.js" } }, - "node_modules/commander": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", - "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", - "engines": { - "node": ">= 12" - } - }, "node_modules/compute-scroll-into-view": { "version": "1.0.20", "resolved": "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-1.0.20.tgz", @@ -4723,16 +4685,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/dnd-core": { - "version": "16.0.1", - "resolved": "https://registry.npmjs.org/dnd-core/-/dnd-core-16.0.1.tgz", - "integrity": "sha512-HK294sl7tbw6F6IeuK16YSBUoorvHpY8RHO+9yFfaJyCDVb6n7PRcezrOEOa2SBCqiYpemh5Jx20ZcjKdFAVng==", - "dependencies": { - "@react-dnd/asap": "^5.0.1", - "@react-dnd/invariant": "^4.0.1", - "redux": "^4.2.0" - } - }, "node_modules/doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -5559,7 +5511,8 @@ "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true }, "node_modules/fast-glob": { "version": "3.2.12", @@ -5796,27 +5749,6 @@ "react": ">=16.8.0" } }, - "node_modules/fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, - "node_modules/fs-extra/node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, "node_modules/fs-minipass": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", @@ -6060,7 +5992,8 @@ "node_modules/graceful-fs": { "version": "4.2.10", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", + "dev": true }, "node_modules/grapheme-splitter": { "version": "1.0.4", @@ -6749,17 +6682,6 @@ "node": ">=6" } }, - "node_modules/jsonfile": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-5.0.0.tgz", - "integrity": "sha512-NQRZ5CRo74MhMMC3/3r5g2k4fjodJ/wh8MxjFbCViWKFjxrnudWSY5vomh+23ZaXzAS7J3fBZIR2dV6WbmfM0w==", - "dependencies": { - "universalify": "^0.1.2" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, "node_modules/jsx-ast-utils": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.3.tgz", @@ -6778,21 +6700,6 @@ "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-3.1.2.tgz", "integrity": "sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A==" }, - "node_modules/katex": { - "version": "0.16.10", - "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.10.tgz", - "integrity": "sha512-ZiqaC04tp2O5utMsl2TEZTXxa6WSC4yo0fv5ML++D3QZv/vx2Mct0mTlRx3O+uUkjfuAgOkzsCmq5MiUEsDDdA==", - "funding": [ - "https://opencollective.com/katex", - "https://github.com/sponsors/katex" - ], - "dependencies": { - "commander": "^8.3.0" - }, - "bin": { - "katex": "cli.js" - } - }, "node_modules/language-subtag-registry": { "version": "0.3.22", "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz", @@ -6854,14 +6761,6 @@ "node": ">= 4.0.0" } }, - "node_modules/linkify-html": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/linkify-html/-/linkify-html-4.0.2.tgz", - "integrity": "sha512-YcN3tsyutK2Y/uSuoG0zne8FQdoqzrAgNU5ko0DWE7M2oQ3ms4z/202f2W4TvRm9uxKdrsWAullfynANLaVMqw==", - "peerDependencies": { - "linkifyjs": "^4.0.0" - } - }, "node_modules/linkify-react": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/linkify-react/-/linkify-react-4.1.1.tgz", @@ -7766,43 +7665,6 @@ "react": ">=15" } }, - "node_modules/react-dnd": { - "version": "16.0.1", - "resolved": "https://registry.npmjs.org/react-dnd/-/react-dnd-16.0.1.tgz", - "integrity": "sha512-QeoM/i73HHu2XF9aKksIUuamHPDvRglEwdHL4jsp784BgUuWcg6mzfxT0QDdQz8Wj0qyRKx2eMg8iZtWvU4E2Q==", - "dependencies": { - "@react-dnd/invariant": "^4.0.1", - "@react-dnd/shallowequal": "^4.0.1", - "dnd-core": "^16.0.1", - "fast-deep-equal": "^3.1.3", - "hoist-non-react-statics": "^3.3.2" - }, - "peerDependencies": { - "@types/hoist-non-react-statics": ">= 3.3.1", - "@types/node": ">= 12", - "@types/react": ">= 16", - "react": ">= 16.14" - }, - "peerDependenciesMeta": { - "@types/hoist-non-react-statics": { - "optional": true - }, - "@types/node": { - "optional": true - }, - "@types/react": { - "optional": true - } - } - }, - "node_modules/react-dnd-html5-backend": { - "version": "16.0.1", - "resolved": "https://registry.npmjs.org/react-dnd-html5-backend/-/react-dnd-html5-backend-16.0.1.tgz", - "integrity": "sha512-Wu3dw5aDJmOGw8WjH1I1/yTH+vlXEL4vmjk5p+MHxP8HuHJS1lAGeIdG/hze1AvNeXWo/JgULV87LyQOr+r5jw==", - "dependencies": { - "dnd-core": "^16.0.1" - } - }, "node_modules/react-dom": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", @@ -7950,14 +7812,6 @@ "node": ">=8.10.0" } }, - "node_modules/redux": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz", - "integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==", - "dependencies": { - "@babel/runtime": "^7.9.2" - } - }, "node_modules/regexp.prototype.flags": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", @@ -8711,22 +8565,6 @@ "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" } }, - "node_modules/twemoji": { - "version": "14.0.2", - "resolved": "https://registry.npmjs.org/twemoji/-/twemoji-14.0.2.tgz", - "integrity": "sha512-BzOoXIe1QVdmsUmZ54xbEH+8AgtOKUiG53zO5vVP2iUu6h5u9lN15NcuS6te4OY96qx0H7JK9vjjl9WQbkTRuA==", - "dependencies": { - "fs-extra": "^8.0.1", - "jsonfile": "^5.0.0", - "twemoji-parser": "14.0.0", - "universalify": "^0.1.2" - } - }, - "node_modules/twemoji-parser": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/twemoji-parser/-/twemoji-parser-14.0.0.tgz", - "integrity": "sha512-9DUOTGLOWs0pFWnh1p6NF+C3CkQ96PWmEFwhOVmT3WbecRC+68AIqpsnJXygfkFcp4aXbOp8Dwbhh/HQgvoRxA==" - }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -8875,14 +8713,6 @@ "resolved": "https://registry.npmjs.org/unhomoglyph/-/unhomoglyph-1.0.6.tgz", "integrity": "sha512-7uvcWI3hWshSADBu4JpnyYbTVc7YlhF5GDW/oPD5AxIxl34k4wXR3WDkPnzLxkN32LiTCTKMQLtKVZiwki3zGg==" }, - "node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "engines": { - "node": ">= 4.0.0" - } - }, "node_modules/update-browserslist-db": { "version": "1.0.13", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", diff --git a/package.json b/package.json index e626e8373..a4bf6f34b 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,6 @@ "@atlaskit/pragmatic-drag-and-drop-auto-scroll": "1.3.0", "@atlaskit/pragmatic-drag-and-drop-hitbox": "1.0.3", "@fontsource/inter": "4.5.14", - "@khanacademy/simple-markdown": "0.8.6", "@matrix-org/olm": "3.2.14", "@tanstack/react-query": "5.24.1", "@tanstack/react-query-devtools": "5.24.1", @@ -52,8 +51,6 @@ "immer": "9.0.16", "is-hotkey": "0.2.0", "jotai": "2.6.0", - "katex": "0.16.10", - "linkify-html": "4.0.2", "linkify-react": "4.1.1", "linkifyjs": "4.0.2", "matrix-js-sdk": "29.1.0", @@ -65,8 +62,6 @@ "react-aria": "3.29.1", "react-autosize-textarea": "7.1.0", "react-blurhash": "0.2.0", - "react-dnd": "16.0.1", - "react-dnd-html5-backend": "16.0.1", "react-dom": "18.2.0", "react-error-boundary": "4.0.10", "react-google-recaptcha": "2.1.0", @@ -78,7 +73,6 @@ "slate-history": "0.93.0", "slate-react": "0.98.4", "tippy.js": "6.3.7", - "twemoji": "14.0.2", "ua-parser-js": "1.0.35" }, "devDependencies": { diff --git a/src/app/atoms/avatar/Avatar.jsx b/src/app/atoms/avatar/Avatar.jsx index fc46c2504..27bf7c906 100644 --- a/src/app/atoms/avatar/Avatar.jsx +++ b/src/app/atoms/avatar/Avatar.jsx @@ -2,17 +2,13 @@ import React from 'react'; import PropTypes from 'prop-types'; import './Avatar.scss'; -import { twemojify } from '../../../util/twemojify'; - import Text from '../text/Text'; import RawIcon from '../system-icons/RawIcon'; import ImageBrokenSVG from '../../../../public/res/svg/image-broken.svg'; import { avatarInitials } from '../../../util/common'; -const Avatar = React.forwardRef(({ - text, bgColor, iconSrc, iconColor, imageSrc, size, -}, ref) => { +const Avatar = React.forwardRef(({ text, bgColor, iconSrc, iconColor, imageSrc, size }, ref) => { let textSize = 's1'; if (size === 'large') textSize = 'h1'; if (size === 'small') textSize = 'b1'; @@ -20,34 +16,34 @@ const Avatar = React.forwardRef(({ return (
      - { - imageSrc !== null - ? ( - { e.target.style.backgroundColor = 'transparent'; }} - onError={(e) => { e.target.src = ImageBrokenSVG; }} - alt="" - /> - ) - : ( - - { - iconSrc !== null - ? - : text !== null && ( - - {twemojify(avatarInitials(text))} - - ) - } - - ) - } + {imageSrc !== null ? ( + { + e.target.style.backgroundColor = 'transparent'; + }} + onError={(e) => { + e.target.src = ImageBrokenSVG; + }} + alt="" + /> + ) : ( + + {iconSrc !== null ? ( + + ) : ( + text !== null && ( + + {avatarInitials(text)} + + ) + )} + + )}
      ); }); diff --git a/src/app/atoms/math/Math.jsx b/src/app/atoms/math/Math.jsx deleted file mode 100644 index ab52a4784..000000000 --- a/src/app/atoms/math/Math.jsx +++ /dev/null @@ -1,33 +0,0 @@ -import React, { useEffect, useRef } from 'react'; -import PropTypes from 'prop-types'; -import './Math.scss'; - -import katex from 'katex'; -import 'katex/dist/katex.min.css'; - -import 'katex/dist/contrib/copy-tex'; - -const Math = React.memo(({ - content, throwOnError, errorColor, displayMode, -}) => { - const ref = useRef(null); - - useEffect(() => { - katex.render(content, ref.current, { throwOnError, errorColor, displayMode }); - }, [content, throwOnError, errorColor, displayMode]); - - return ; -}); -Math.defaultProps = { - throwOnError: null, - errorColor: null, - displayMode: null, -}; -Math.propTypes = { - content: PropTypes.string.isRequired, - throwOnError: PropTypes.bool, - errorColor: PropTypes.string, - displayMode: PropTypes.bool, -}; - -export default Math; diff --git a/src/app/atoms/math/Math.scss b/src/app/atoms/math/Math.scss deleted file mode 100644 index 306b147cf..000000000 --- a/src/app/atoms/math/Math.scss +++ /dev/null @@ -1,3 +0,0 @@ -.katex-display { - margin: 0 !important; -} diff --git a/src/app/features/room/RoomInput.tsx b/src/app/features/room/RoomInput.tsx index 6f9a2495b..2728a54c8 100644 --- a/src/app/features/room/RoomInput.tsx +++ b/src/app/features/room/RoomInput.tsx @@ -8,7 +8,7 @@ import React, { useRef, useState, } from 'react'; -import { useAtom } from 'jotai'; +import { useAtom, useAtomValue } from 'jotai'; import { isKeyHotkey } from 'is-hotkey'; import { EventType, IContent, MsgType, Room } from 'matrix-js-sdk'; import { ReactEditor } from 'slate-react'; @@ -56,7 +56,6 @@ import { } from '../../components/editor'; import { EmojiBoard, EmojiBoardTab } from '../../components/emoji-board'; import { UseStateProvider } from '../../components/UseStateProvider'; -import initMatrix from '../../../client/initMatrix'; import { TUploadContent, encryptFile, getImageInfo, getMxIdLocalPart } from '../../utils/matrix'; import { useTypingStatusUpdater } from '../../hooks/useTypingStatusUpdater'; import { useFilePicker } from '../../hooks/useFilePicker'; @@ -95,6 +94,7 @@ import { } from './msgContent'; import colorMXID from '../../../util/colorMXID'; import { + getAllParents, getMemberDisplayName, parseReplyBody, parseReplyFormattedBody, @@ -107,6 +107,7 @@ import { Command, SHRUG, useCommands } from '../../hooks/useCommands'; import { mobileOrTablet } from '../../utils/user-agent'; import { useElementSizeObserver } from '../../hooks/useElementSizeObserver'; import { ReplyLayout } from '../../components/message'; +import { roomToParentsAtom } from '../../state/room/roomToParents'; interface RoomInputProps { editor: Editor; @@ -121,6 +122,7 @@ export const RoomInput = forwardRef( const [isMarkdown] = useSetting(settingsAtom, 'isMarkdown'); const commands = useCommands(mx, room); const emojiBtnRef = useRef(null); + const roomToParents = useAtomValue(roomToParentsAtom); const [msgDraft, setMsgDraft] = useAtom(roomIdToMsgDraftAtomFamily(roomId)); const [replyDraft, setReplyDraft] = useAtom(roomIdToReplyDraftAtomFamily(roomId)); @@ -133,13 +135,13 @@ export const RoomInput = forwardRef( const uploadBoardHandlers = useRef(); const imagePackRooms: Room[] = useMemo(() => { - const allParentSpaces = [roomId, ...(initMatrix.roomList?.getAllParentSpaces(roomId) ?? [])]; + const allParentSpaces = [roomId].concat(Array.from(getAllParents(roomToParents, roomId))); return allParentSpaces.reduce((list, rId) => { const r = mx.getRoom(rId); if (r) list.push(r); return list; }, []); - }, [mx, roomId]); + }, [mx, roomId, roomToParents]); const [toolbar, setToolbar] = useSetting(settingsAtom, 'editorToolbar'); const [autocompleteQuery, setAutocompleteQuery] = diff --git a/src/app/features/room/RoomTimeline.tsx b/src/app/features/room/RoomTimeline.tsx index 29b874fca..14cdb56e8 100644 --- a/src/app/features/room/RoomTimeline.tsx +++ b/src/app/features/room/RoomTimeline.tsx @@ -28,7 +28,7 @@ import classNames from 'classnames'; import { ReactEditor } from 'slate-react'; import { Editor } from 'slate'; import to from 'await-to-js'; -import { useSetAtom } from 'jotai'; +import { useAtomValue, useSetAtom } from 'jotai'; import { Badge, Box, @@ -74,6 +74,7 @@ import { getReactCustomHtmlParser } from '../../plugins/react-custom-html-parser import { canEditEvent, decryptAllTimelineEvent, + getAllParents, getEditedEvent, getEventReactions, getLatestEditableEvt, @@ -103,14 +104,15 @@ import { createMentionElement, isEmptyEditor, moveCursor } from '../../component import { roomIdToReplyDraftAtomFamily } from '../../state/room/roomInputDrafts'; import { usePowerLevelsAPI, usePowerLevelsContext } from '../../hooks/usePowerLevels'; import { GetContentCallback, MessageEvent, StateEvent } from '../../../types/matrix/room'; -import initMatrix from '../../../client/initMatrix'; import { useKeyDown } from '../../hooks/useKeyDown'; -import cons from '../../../client/state/cons'; import { useDocumentFocusChange } from '../../hooks/useDocumentFocusChange'; import { RenderMessageContent } from '../../components/RenderMessageContent'; import { Image } from '../../components/media'; import { ImageViewer } from '../../components/image-viewer'; import { useRoomNavigate } from '../../hooks/useRoomNavigate'; +import { roomToParentsAtom } from '../../state/room/roomToParents'; +import { useRoomUnread } from '../../state/hooks/unread'; +import { roomToUnreadAtom } from '../../state/room/roomToUnread'; const TimelineFloat = as<'div', css.TimelineFloatVariants>( ({ position, className, ...props }, ref) => ( @@ -444,18 +446,19 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli const canSendReaction = canSendEvent(MessageEvent.Reaction, myPowerLevel); const [editId, setEditId] = useState(); const { navigateRoom, navigateSpace } = useRoomNavigate(); + const roomToParents = useAtomValue(roomToParentsAtom); + const unread = useRoomUnread(room.roomId, roomToUnreadAtom); const imagePackRooms: Room[] = useMemo(() => { - const allParentSpaces = [ - room.roomId, - ...(initMatrix.roomList?.getAllParentSpaces(room.roomId) ?? []), - ]; + const allParentSpaces = [room.roomId].concat( + Array.from(getAllParents(roomToParents, room.roomId)) + ); return allParentSpaces.reduce((list, rId) => { const r = mx.getRoom(rId); if (r) list.push(r); return list; }, []); - }, [mx, room]); + }, [mx, room, roomToParents]); const [unreadInfo, setUnreadInfo] = useState(() => getRoomUnreadInfo(room, true)); const readUptoEventIdRef = useRef(); @@ -794,15 +797,10 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli // Remove unreadInfo on mark as read useEffect(() => { - const handleFullRead = (rId: string) => { - if (rId !== room.roomId) return; + if (!unread) { setUnreadInfo(undefined); - }; - initMatrix.notifications?.on(cons.events.notifications.FULL_READ, handleFullRead); - return () => { - initMatrix.notifications?.removeListener(cons.events.notifications.FULL_READ, handleFullRead); - }; - }, [room]); + } + }, [unread]); // scroll out of view msg editor in view. useEffect(() => { diff --git a/src/app/hooks/useCategorizedSpaces.js b/src/app/hooks/useCategorizedSpaces.js deleted file mode 100644 index 6d3c02afd..000000000 --- a/src/app/hooks/useCategorizedSpaces.js +++ /dev/null @@ -1,25 +0,0 @@ -/* eslint-disable import/prefer-default-export */ -import { useState, useEffect } from 'react'; - -import initMatrix from '../../client/initMatrix'; -import cons from '../../client/state/cons'; - -export function useCategorizedSpaces() { - const { accountData } = initMatrix; - const [categorizedSpaces, setCategorizedSpaces] = useState([...accountData.categorizedSpaces]); - - useEffect(() => { - const handleCategorizedSpaces = () => { - setCategorizedSpaces([...accountData.categorizedSpaces]); - }; - accountData.on(cons.events.accountData.CATEGORIZE_SPACE_UPDATED, handleCategorizedSpaces); - return () => { - accountData.removeListener( - cons.events.accountData.CATEGORIZE_SPACE_UPDATED, - handleCategorizedSpaces, - ); - }; - }, []); - - return [categorizedSpaces]; -} diff --git a/src/app/hooks/useCommands.ts b/src/app/hooks/useCommands.ts index aadbf5348..3c8295149 100644 --- a/src/app/hooks/useCommands.ts +++ b/src/app/hooks/useCommands.ts @@ -114,12 +114,12 @@ export const useCommands = (mx: MatrixClient, room: Room): CommandRecord => { description: 'Leave current room.', exe: async (payload) => { if (payload.trim() === '') { - roomActions.leave(room.roomId); + mx.leave(room.roomId); return; } const rawIds = payload.split(' '); const roomIds = rawIds.filter((id) => isRoomId(id)); - roomIds.map((id) => roomActions.leave(id)); + roomIds.map((id) => mx.leave(id)); }, }, [Command.Invite]: { diff --git a/src/app/hooks/usePreviousValue.ts b/src/app/hooks/usePreviousValue.ts new file mode 100644 index 000000000..01b4850da --- /dev/null +++ b/src/app/hooks/usePreviousValue.ts @@ -0,0 +1,11 @@ +import { useEffect, useRef } from 'react'; + +export const usePreviousValue = (currentValue: T, initialValue: T) => { + const valueRef = useRef(initialValue); + + useEffect(() => { + valueRef.current = currentValue; + }, [currentValue]); + + return valueRef.current; +}; diff --git a/src/app/hooks/useRoomTypingMembers.ts b/src/app/hooks/useRoomTypingMembers.ts index 5f24fb5df..f526cbf16 100644 --- a/src/app/hooks/useRoomTypingMembers.ts +++ b/src/app/hooks/useRoomTypingMembers.ts @@ -1,10 +1,26 @@ import { useAtomValue } from 'jotai'; -import { useMemo } from 'react'; -import { roomIdToTypingMembersAtom, selectRoomTypingMembersAtom } from '../state/typingMembers'; +import { selectAtom } from 'jotai/utils'; +import { useCallback } from 'react'; +import { + IRoomIdToTypingMembers, + TypingReceipt, + roomIdToTypingMembersAtom, +} from '../state/typingMembers'; + +const typingReceiptEqual = (a: TypingReceipt, b: TypingReceipt): boolean => + a.userId === b.userId && a.ts === b.ts; + +const equalTypingMembers = (x: TypingReceipt[], y: TypingReceipt[]): boolean => { + if (x.length !== y.length) return false; + return x.every((a, i) => typingReceiptEqual(a, y[i])); +}; export const useRoomTypingMember = (roomId: string) => { - const typing = useAtomValue( - useMemo(() => selectRoomTypingMembersAtom(roomId, roomIdToTypingMembersAtom), [roomId]) + const selector = useCallback( + (roomToTyping: IRoomIdToTypingMembers) => roomToTyping.get(roomId) ?? [], + [roomId] ); + + const typing = useAtomValue(selectAtom(roomIdToTypingMembersAtom, selector, equalTypingMembers)); return typing; }; diff --git a/src/app/hooks/useSelectedSpace.js b/src/app/hooks/useSelectedSpace.js deleted file mode 100644 index 535c5dcda..000000000 --- a/src/app/hooks/useSelectedSpace.js +++ /dev/null @@ -1,21 +0,0 @@ -/* eslint-disable import/prefer-default-export */ -import { useState, useEffect } from 'react'; - -import cons from '../../client/state/cons'; -import navigation from '../../client/state/navigation'; - -export function useSelectedSpace() { - const [spaceId, setSpaceId] = useState(navigation.selectedSpaceId); - - useEffect(() => { - const onSpaceSelected = (roomId) => { - setSpaceId(roomId); - }; - navigation.on(cons.events.navigation.SPACE_SELECTED, onSpaceSelected); - return () => { - navigation.removeListener(cons.events.navigation.SPACE_SELECTED, onSpaceSelected); - }; - }, []); - - return [spaceId]; -} diff --git a/src/app/hooks/useSelectedTab.js b/src/app/hooks/useSelectedTab.js deleted file mode 100644 index 33b76a81b..000000000 --- a/src/app/hooks/useSelectedTab.js +++ /dev/null @@ -1,21 +0,0 @@ -/* eslint-disable import/prefer-default-export */ -import { useState, useEffect } from 'react'; - -import cons from '../../client/state/cons'; -import navigation from '../../client/state/navigation'; - -export function useSelectedTab() { - const [selectedTab, setSelectedTab] = useState(navigation.selectedTab); - - useEffect(() => { - const onTabSelected = (tabId) => { - setSelectedTab(tabId); - }; - navigation.on(cons.events.navigation.TAB_SELECTED, onTabSelected); - return () => { - navigation.removeListener(cons.events.navigation.TAB_SELECTED, onTabSelected); - }; - }, []); - - return [selectedTab]; -} diff --git a/src/app/hooks/useSpaceShortcut.js b/src/app/hooks/useSpaceShortcut.js deleted file mode 100644 index a1710c603..000000000 --- a/src/app/hooks/useSpaceShortcut.js +++ /dev/null @@ -1,25 +0,0 @@ -/* eslint-disable import/prefer-default-export */ -import { useState, useEffect } from 'react'; - -import initMatrix from '../../client/initMatrix'; -import cons from '../../client/state/cons'; - -export function useSpaceShortcut() { - const { accountData } = initMatrix; - const [spaceShortcut, setSpaceShortcut] = useState([...accountData.spaceShortcut]); - - useEffect(() => { - const onSpaceShortcutUpdated = () => { - setSpaceShortcut([...accountData.spaceShortcut]); - }; - accountData.on(cons.events.accountData.SPACE_SHORTCUT_UPDATED, onSpaceShortcutUpdated); - return () => { - accountData.removeListener( - cons.events.accountData.SPACE_SHORTCUT_UPDATED, - onSpaceShortcutUpdated, - ); - }; - }, []); - - return [spaceShortcut]; -} diff --git a/src/app/molecules/dialog/Dialog.jsx b/src/app/molecules/dialog/Dialog.jsx index 2f29971d5..478a08558 100644 --- a/src/app/molecules/dialog/Dialog.jsx +++ b/src/app/molecules/dialog/Dialog.jsx @@ -2,16 +2,21 @@ import React from 'react'; import PropTypes from 'prop-types'; import './Dialog.scss'; -import { twemojify } from '../../../util/twemojify'; - import Text from '../../atoms/text/Text'; import Header, { TitleWrapper } from '../../atoms/header/Header'; import ScrollView from '../../atoms/scroll/ScrollView'; import RawModal from '../../atoms/modal/RawModal'; function Dialog({ - className, isOpen, title, onAfterOpen, onAfterClose, - contentOptions, onRequestClose, closeFromOutside, children, + className, + isOpen, + title, + onAfterOpen, + onAfterClose, + contentOptions, + onRequestClose, + closeFromOutside, + children, invisibleScroll, }) { return ( @@ -28,19 +33,19 @@ function Dialog({
      - { - typeof title === 'string' - ? {twemojify(title)} - : title - } + {typeof title === 'string' ? ( + + {title} + + ) : ( + title + )} {contentOptions}
      -
      - {children} -
      +
      {children}
      diff --git a/src/app/molecules/following-members/FollowingMembers.jsx b/src/app/molecules/following-members/FollowingMembers.jsx deleted file mode 100644 index 949dac76a..000000000 --- a/src/app/molecules/following-members/FollowingMembers.jsx +++ /dev/null @@ -1,61 +0,0 @@ -/* eslint-disable react/prop-types */ -import React, { useState, useEffect } from 'react'; -import PropTypes from 'prop-types'; -import './FollowingMembers.scss'; - -import initMatrix from '../../../client/initMatrix'; -import cons from '../../../client/state/cons'; -import { openReadReceipts } from '../../../client/action/navigation'; - -import Text from '../../atoms/text/Text'; -import RawIcon from '../../atoms/system-icons/RawIcon'; -import TickMarkIC from '../../../../public/res/ic/outlined/tick-mark.svg'; - -import { getUsersActionJsx } from '../../organisms/room/common'; - -function FollowingMembers({ roomTimeline }) { - const [followingMembers, setFollowingMembers] = useState([]); - const { roomId } = roomTimeline; - const mx = initMatrix.matrixClient; - const myUserId = mx.getUserId(); - - useEffect(() => { - const updateFollowingMembers = () => { - setFollowingMembers(roomTimeline.getLiveReaders()); - }; - const updateOnEvent = (event, room) => { - if (room.roomId !== roomId) return; - setFollowingMembers(roomTimeline.getLiveReaders()); - }; - updateFollowingMembers(); - roomTimeline.on(cons.events.roomTimeline.LIVE_RECEIPT, updateFollowingMembers); - mx.on('Room.timeline', updateOnEvent); - return () => { - roomTimeline.removeListener(cons.events.roomTimeline.LIVE_RECEIPT, updateFollowingMembers); - mx.removeListener('Room.timeline', updateOnEvent); - }; - }, [roomTimeline, roomId]); - - const filteredM = followingMembers.filter((userId) => userId !== myUserId); - - return ( - filteredM.length !== 0 && ( - - ) - ); -} - -FollowingMembers.propTypes = { - roomTimeline: PropTypes.shape({}).isRequired, -}; - -export default FollowingMembers; diff --git a/src/app/molecules/following-members/FollowingMembers.scss b/src/app/molecules/following-members/FollowingMembers.scss deleted file mode 100644 index a0daf5ad5..000000000 --- a/src/app/molecules/following-members/FollowingMembers.scss +++ /dev/null @@ -1,31 +0,0 @@ -@use '../../partials/text'; - -.following-members { - width: 100%; - padding: 0 var(--sp-normal); - display: flex; - justify-content: flex-end; - align-items: center; - cursor: pointer; - - & .ic-raw { - min-width: var(--ic-extra-small); - opacity: 0.4; - margin: 0 var(--sp-extra-tight); - } - & .text { - @extend .cp-txt__ellipsis; - color: var(--tc-surface-low); - b { - color: var(--tc-surface-normal); - } - } - - &:hover, - &:focus { - background-color: var(--bg-surface-hover); - } - &:active { - background-color: var(--bg-surface-active); - } -} \ No newline at end of file diff --git a/src/app/molecules/image-lightbox/ImageLightbox.jsx b/src/app/molecules/image-lightbox/ImageLightbox.jsx deleted file mode 100644 index c1c45db87..000000000 --- a/src/app/molecules/image-lightbox/ImageLightbox.jsx +++ /dev/null @@ -1,47 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import './ImageLightbox.scss'; -import FileSaver from 'file-saver'; - -import Text from '../../atoms/text/Text'; -import RawModal from '../../atoms/modal/RawModal'; -import IconButton from '../../atoms/button/IconButton'; - -import DownloadSVG from '../../../../public/res/ic/outlined/download.svg'; -import ExternalSVG from '../../../../public/res/ic/outlined/external.svg'; - -function ImageLightbox({ - url, alt, isOpen, onRequestClose, -}) { - const handleDownload = () => { - FileSaver.saveAs(url, alt); - }; - - return ( - -
      - {alt} - window.open(url)} size="small" src={ExternalSVG} /> - -
      -
      - {alt} -
      -
      - ); -} - -ImageLightbox.propTypes = { - url: PropTypes.string.isRequired, - alt: PropTypes.string.isRequired, - isOpen: PropTypes.bool.isRequired, - onRequestClose: PropTypes.func.isRequired, -}; - -export default ImageLightbox; diff --git a/src/app/molecules/image-lightbox/ImageLightbox.scss b/src/app/molecules/image-lightbox/ImageLightbox.scss deleted file mode 100644 index 201fc91c9..000000000 --- a/src/app/molecules/image-lightbox/ImageLightbox.scss +++ /dev/null @@ -1,50 +0,0 @@ -@use '../../partials/flex'; -@use '../../partials/text'; - -.image-lightbox__modal { - box-shadow: none; - width: unset; - gap: var(--sp-normal); - - border-radius: 0; - pointer-events: none; - - & .text { - color: white; - } - & .ic-raw { - background-color: white; - } -} - -.image-lightbox__overlay { - background-color: var(--bg-overlay-low); -} - - -.image-lightbox__header > *, -.image-lightbox__content > * { - pointer-events: all; -} -.image-lightbox__header { - display: flex; - align-items: center; - - & > .text { - @extend .cp-fx__item-one; - @extend .cp-txt__ellipsis; - } -} -.image-lightbox__content { - display: flex; - justify-content: center; - max-height: 80vh; - - & img { - background-color: var(--bg-surface-low); - object-fit: contain; - max-width: 100%; - max-height: 100%; - border-radius: var(--bo-radius); - } -} \ No newline at end of file diff --git a/src/app/molecules/media/Media.jsx b/src/app/molecules/media/Media.jsx deleted file mode 100644 index e2b61775c..000000000 --- a/src/app/molecules/media/Media.jsx +++ /dev/null @@ -1,366 +0,0 @@ -import React, { useState, useEffect } from 'react'; -import PropTypes from 'prop-types'; -import './Media.scss'; - -import encrypt from 'browser-encrypt-attachment'; - -import { BlurhashCanvas } from 'react-blurhash'; -import Text from '../../atoms/text/Text'; -import IconButton from '../../atoms/button/IconButton'; -import Spinner from '../../atoms/spinner/Spinner'; -import ImageLightbox from '../image-lightbox/ImageLightbox'; - -import DownloadSVG from '../../../../public/res/ic/outlined/download.svg'; -import ExternalSVG from '../../../../public/res/ic/outlined/external.svg'; -import PlaySVG from '../../../../public/res/ic/outlined/play.svg'; - -import { getBlobSafeMimeType } from '../../../util/mimetypes'; - -async function getDecryptedBlob(response, type, decryptData) { - const arrayBuffer = await response.arrayBuffer(); - const dataArray = await encrypt.decryptAttachment(arrayBuffer, decryptData); - const blob = new Blob([dataArray], { type: getBlobSafeMimeType(type) }); - return blob; -} - -async function getUrl(link, type, decryptData) { - try { - const response = await fetch(link, { method: 'GET' }); - if (decryptData !== null) { - return URL.createObjectURL(await getDecryptedBlob(response, type, decryptData)); - } - const blob = await response.blob(); - return URL.createObjectURL(blob); - } catch (e) { - return link; - } -} - -function getNativeHeight(width, height, maxWidth = 296) { - const scale = maxWidth / width; - return scale * height; -} - -function FileHeader({ - name, link, external, - file, type, -}) { - const [url, setUrl] = useState(null); - - async function getFile() { - const myUrl = await getUrl(link, type, file); - setUrl(myUrl); - } - - async function handleDownload(e) { - if (file !== null && url === null) { - e.preventDefault(); - await getFile(); - e.target.click(); - } - } - return ( -
      - {name} - { link !== null && ( - <> - { - external && ( - window.open(url || link)} - /> - ) - } - - - - - )} -
      - ); -} -FileHeader.defaultProps = { - external: false, - file: null, - link: null, -}; -FileHeader.propTypes = { - name: PropTypes.string.isRequired, - link: PropTypes.string, - external: PropTypes.bool, - file: PropTypes.shape({}), - type: PropTypes.string.isRequired, -}; - -function File({ - name, link, file, type, -}) { - return ( -
      - -
      - ); -} -File.defaultProps = { - file: null, - type: '', -}; -File.propTypes = { - name: PropTypes.string.isRequired, - link: PropTypes.string.isRequired, - type: PropTypes.string, - file: PropTypes.shape({}), -}; - -function Image({ - name, width, height, link, file, type, blurhash, -}) { - const [url, setUrl] = useState(null); - const [blur, setBlur] = useState(true); - const [lightbox, setLightbox] = useState(false); - - useEffect(() => { - let unmounted = false; - async function fetchUrl() { - const myUrl = await getUrl(link, type, file); - if (unmounted) return; - setUrl(myUrl); - } - fetchUrl(); - return () => { - unmounted = true; - }; - }, []); - - const toggleLightbox = () => { - if (!url) return; - setLightbox(!lightbox); - }; - - return ( - <> -
      -
      - { blurhash && blur && } - { url !== null && ( - setBlur(false)} - src={url || link} - alt={name} - /> - )} -
      -
      - {url && ( - - )} - - ); -} -Image.defaultProps = { - file: null, - width: null, - height: null, - type: '', - blurhash: '', -}; -Image.propTypes = { - name: PropTypes.string.isRequired, - width: PropTypes.number, - height: PropTypes.number, - link: PropTypes.string.isRequired, - file: PropTypes.shape({}), - type: PropTypes.string, - blurhash: PropTypes.string, -}; - -function Sticker({ - name, height, width, link, file, type, -}) { - const [url, setUrl] = useState(null); - - useEffect(() => { - let unmounted = false; - async function fetchUrl() { - const myUrl = await getUrl(link, type, file); - if (unmounted) return; - setUrl(myUrl); - } - fetchUrl(); - return () => { - unmounted = true; - }; - }, []); - - return ( -
      - { url !== null && {name}} -
      - ); -} -Sticker.defaultProps = { - file: null, - type: '', - width: null, - height: null, -}; -Sticker.propTypes = { - name: PropTypes.string.isRequired, - width: PropTypes.number, - height: PropTypes.number, - link: PropTypes.string.isRequired, - file: PropTypes.shape({}), - type: PropTypes.string, -}; - -function Audio({ - name, link, type, file, -}) { - const [isLoading, setIsLoading] = useState(false); - const [url, setUrl] = useState(null); - - async function loadAudio() { - const myUrl = await getUrl(link, type, file); - setUrl(myUrl); - setIsLoading(false); - } - function handlePlayAudio() { - setIsLoading(true); - loadAudio(); - } - - return ( -
      - -
      - { url === null && isLoading && } - { url === null && !isLoading && } - { url !== null && ( - /* eslint-disable-next-line jsx-a11y/media-has-caption */ - - )} -
      -
      - ); -} -Audio.defaultProps = { - file: null, - type: '', -}; -Audio.propTypes = { - name: PropTypes.string.isRequired, - link: PropTypes.string.isRequired, - type: PropTypes.string, - file: PropTypes.shape({}), -}; - -function Video({ - name, link, thumbnail, thumbnailFile, thumbnailType, - width, height, file, type, blurhash, -}) { - const [isLoading, setIsLoading] = useState(false); - const [url, setUrl] = useState(null); - const [thumbUrl, setThumbUrl] = useState(null); - const [blur, setBlur] = useState(true); - - useEffect(() => { - let unmounted = false; - async function fetchUrl() { - const myThumbUrl = await getUrl(thumbnail, thumbnailType, thumbnailFile); - if (unmounted) return; - setThumbUrl(myThumbUrl); - } - if (thumbnail !== null) fetchUrl(); - return () => { - unmounted = true; - }; - }, []); - - const loadVideo = async () => { - const myUrl = await getUrl(link, type, file); - setUrl(myUrl); - setIsLoading(false); - }; - - const handlePlayVideo = () => { - setIsLoading(true); - loadVideo(); - }; - - return ( -
      - -
      - { url === null ? ( - <> - { blurhash && blur && } - { thumbUrl !== null && ( - setBlur(false)} alt={name} /> - )} - {isLoading && } - {!isLoading && } - - ) : ( - /* eslint-disable-next-line jsx-a11y/media-has-caption */ - - )} -
      -
      - ); -} -Video.defaultProps = { - width: null, - height: null, - file: null, - thumbnail: null, - thumbnailType: null, - thumbnailFile: null, - type: '', - blurhash: null, -}; -Video.propTypes = { - name: PropTypes.string.isRequired, - link: PropTypes.string.isRequired, - thumbnail: PropTypes.string, - thumbnailFile: PropTypes.shape({}), - thumbnailType: PropTypes.string, - width: PropTypes.number, - height: PropTypes.number, - file: PropTypes.shape({}), - type: PropTypes.string, - blurhash: PropTypes.string, -}; - -export { - File, Image, Sticker, Audio, Video, -}; diff --git a/src/app/molecules/media/Media.scss b/src/app/molecules/media/Media.scss deleted file mode 100644 index 8d98c428e..000000000 --- a/src/app/molecules/media/Media.scss +++ /dev/null @@ -1,90 +0,0 @@ -@use '../../partials/text'; - -.file-header { - display: flex; - align-items: center; - padding: var(--sp-ultra-tight) var(--sp-tight); - min-height: 42px; - - & .file-name { - @extend .cp-txt__ellipsis; - flex: 1; - color: var(--tc-surface-low); - } - - & a { - line-height: 0; - } -} - -.file-container { - --media-max-width: 296px; - - background-color: var(--bg-surface-hover); - border-radius: calc(var(--bo-radius) / 2); - overflow: hidden; - max-width: var(--media-max-width); - white-space: initial; -} - -.sticker-container { - display: inline-flex; - max-width: 128px; - width: 100%; - & img { - width: 100% !important; - } -} - -.image-container, -.video-container, -.audio-container { - font-size: 0; - line-height: 0; - - display: flex; - justify-content: center; - align-items: center; - - background-position: center; - background-repeat: no-repeat; - background-size: cover; -} - -.image-container, -.video-container { - & img, - & canvas { - max-width: unset !important; - width: 100% !important; - height: 100%; - border-radius: 0 !important; - margin: 0 !important; - } -} -.image-container { - max-height: 460px; - img { - cursor: pointer; - object-fit: cover; - } -} - -.video-container { - position: relative; - & .ic-btn-surface { - background-color: var(--bg-surface-low); - } - & .ic-btn-surface, - & .donut-spinner { - position: absolute; - } - video { - width: 100%; - } -} -.audio-container { - audio { - width: 100%; - } -} diff --git a/src/app/molecules/message/Message.jsx b/src/app/molecules/message/Message.jsx deleted file mode 100644 index 26a5b29da..000000000 --- a/src/app/molecules/message/Message.jsx +++ /dev/null @@ -1,853 +0,0 @@ -/* eslint-disable react/prop-types */ -import React, { - useState, useEffect, useCallback, useRef, -} from 'react'; -import PropTypes from 'prop-types'; -import './Message.scss'; - -import { twemojify } from '../../../util/twemojify'; - -import initMatrix from '../../../client/initMatrix'; -import { - getUsername, getUsernameOfRoomMember, parseReply, trimHTMLReply, -} from '../../../util/matrixUtil'; -import colorMXID from '../../../util/colorMXID'; -import { getEventCords } from '../../../util/common'; -import { redactEvent, sendReaction } from '../../../client/action/roomTimeline'; -import { - openEmojiBoard, openProfileViewer, openReadReceipts, openViewSource, replyTo, -} from '../../../client/action/navigation'; -import { sanitizeCustomHtml } from '../../../util/sanitize'; - -import Text from '../../atoms/text/Text'; -import RawIcon from '../../atoms/system-icons/RawIcon'; -import Button from '../../atoms/button/Button'; -import Tooltip from '../../atoms/tooltip/Tooltip'; -import Input from '../../atoms/input/Input'; -import Avatar from '../../atoms/avatar/Avatar'; -import IconButton from '../../atoms/button/IconButton'; -import Time from '../../atoms/time/Time'; -import ContextMenu, { MenuHeader, MenuItem, MenuBorder } from '../../atoms/context-menu/ContextMenu'; -import * as Media from '../media/Media'; - -import ReplyArrowIC from '../../../../public/res/ic/outlined/reply-arrow.svg'; -import EmojiAddIC from '../../../../public/res/ic/outlined/emoji-add.svg'; -import VerticalMenuIC from '../../../../public/res/ic/outlined/vertical-menu.svg'; -import PencilIC from '../../../../public/res/ic/outlined/pencil.svg'; -import TickMarkIC from '../../../../public/res/ic/outlined/tick-mark.svg'; -import CmdIC from '../../../../public/res/ic/outlined/cmd.svg'; -import BinIC from '../../../../public/res/ic/outlined/bin.svg'; - -import { confirmDialog } from '../confirm-dialog/ConfirmDialog'; -import { getBlobSafeMimeType } from '../../../util/mimetypes'; -import { html, plain } from '../../../util/markdown'; - -function PlaceholderMessage() { - return ( -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      - ); -} - -const MessageAvatar = React.memo(({ - roomId, avatarSrc, userId, username, -}) => ( -
      - -
      -)); - -const MessageHeader = React.memo(({ - userId, username, timestamp, fullTime, -}) => ( -
      - - {twemojify(username)} - {twemojify(userId)} - -
      - - -
      -
      -)); -MessageHeader.defaultProps = { - fullTime: false, -}; -MessageHeader.propTypes = { - userId: PropTypes.string.isRequired, - username: PropTypes.string.isRequired, - timestamp: PropTypes.number.isRequired, - fullTime: PropTypes.bool, -}; - -function MessageReply({ name, color, body }) { - return ( -
      - - - {twemojify(name)} - {' '} - {twemojify(body)} - -
      - ); -} - -MessageReply.propTypes = { - name: PropTypes.string.isRequired, - color: PropTypes.string.isRequired, - body: PropTypes.string.isRequired, -}; - -const MessageReplyWrapper = React.memo(({ roomTimeline, eventId }) => { - const [reply, setReply] = useState(null); - const isMountedRef = useRef(true); - - useEffect(() => { - const mx = initMatrix.matrixClient; - const timelineSet = roomTimeline.getUnfilteredTimelineSet(); - const loadReply = async () => { - try { - const eTimeline = await mx.getEventTimeline(timelineSet, eventId); - await roomTimeline.decryptAllEventsOfTimeline(eTimeline); - - let mEvent = eTimeline.getTimelineSet().findEventById(eventId); - const editedList = roomTimeline.editedTimeline.get(mEvent.getId()); - if (editedList) { - mEvent = editedList[editedList.length - 1]; - } - - const rawBody = mEvent.getContent().body; - const username = getUsernameOfRoomMember(mEvent.sender); - - if (isMountedRef.current === false) return; - const fallbackBody = mEvent.isRedacted() ? '*** This message has been deleted ***' : '*** Unable to load reply ***'; - let parsedBody = parseReply(rawBody)?.body ?? rawBody ?? fallbackBody; - if (editedList && parsedBody.startsWith(' * ')) { - parsedBody = parsedBody.slice(3); - } - - setReply({ - to: username, - color: colorMXID(mEvent.getSender()), - body: parsedBody, - event: mEvent, - }); - } catch { - setReply({ - to: '** Unknown user **', - color: 'var(--tc-danger-normal)', - body: '*** Unable to load reply ***', - event: null, - }); - } - }; - loadReply(); - - return () => { - isMountedRef.current = false; - }; - }, []); - - const focusReply = (ev) => { - if (!ev.key || ev.key === ' ' || ev.key === 'Enter') { - if (ev.key) ev.preventDefault(); - if (reply?.event === null) return; - if (reply?.event.isRedacted()) return; - roomTimeline.loadEventTimeline(eventId); - } - }; - - return ( -
      - {reply !== null && } -
      - ); -}); -MessageReplyWrapper.propTypes = { - roomTimeline: PropTypes.shape({}).isRequired, - eventId: PropTypes.string.isRequired, -}; - -const MessageBody = React.memo(({ - senderName, - body, - isCustomHTML, - isEdited, - msgType, -}) => { - // if body is not string it is a React element. - if (typeof body !== 'string') return
      {body}
      ; - - let content = null; - if (isCustomHTML) { - try { - content = twemojify( - sanitizeCustomHtml(initMatrix.matrixClient, body), - undefined, - true, - false, - true, - ); - } catch { - console.error('Malformed custom html: ', body); - content = twemojify(body, undefined); - } - } else { - content = twemojify(body, undefined, true); - } - - // Determine if this message should render with large emojis - // Criteria: - // - Contains only emoji - // - Contains no more than 10 emoji - let emojiOnly = false; - if (content.type === 'img') { - // If this messages contains only a single (inline) image - emojiOnly = true; - } else if (content.constructor.name === 'Array') { - // Otherwise, it might be an array of images / texb - - // Count the number of emojis - const nEmojis = content.filter((e) => e.type === 'img').length; - - // Make sure there's no text besides whitespace and variation selector U+FE0F - if (nEmojis <= 10 && content.every((element) => ( - (typeof element === 'object' && element.type === 'img') - || (typeof element === 'string' && /^[\s\ufe0f]*$/g.test(element)) - ))) { - emojiOnly = true; - } - } - - if (!isCustomHTML) { - // If this is a plaintext message, wrap it in a

      element (automatically applying - // white-space: pre-wrap) in order to preserve newlines - content = (

      {content}

      ); - } - - return ( -
      -
      - { msgType === 'm.emote' && ( - <> - {'* '} - {twemojify(senderName)} - {' '} - - )} - { content } -
      - { isEdited && (edited)} -
      - ); -}); -MessageBody.defaultProps = { - isCustomHTML: false, - isEdited: false, - msgType: null, -}; -MessageBody.propTypes = { - senderName: PropTypes.string.isRequired, - body: PropTypes.node.isRequired, - isCustomHTML: PropTypes.bool, - isEdited: PropTypes.bool, - msgType: PropTypes.string, -}; - -function MessageEdit({ body, onSave, onCancel }) { - const editInputRef = useRef(null); - - useEffect(() => { - // makes the cursor end up at the end of the line instead of the beginning - editInputRef.current.value = ''; - editInputRef.current.value = body; - }, []); - - const handleKeyDown = (e) => { - if (e.key === 'Escape') { - e.preventDefault(); - onCancel(); - } - - if (e.key === 'Enter' && e.shiftKey === false) { - e.preventDefault(); - onSave(editInputRef.current.value, body); - } - }; - - return ( -
      { e.preventDefault(); onSave(editInputRef.current.value, body); }}> - -
      - - -
      -
      - ); -} -MessageEdit.propTypes = { - body: PropTypes.string.isRequired, - onSave: PropTypes.func.isRequired, - onCancel: PropTypes.func.isRequired, -}; - -function getMyEmojiEvent(emojiKey, eventId, roomTimeline) { - const mx = initMatrix.matrixClient; - const rEvents = roomTimeline.reactionTimeline.get(eventId); - let rEvent = null; - rEvents?.find((rE) => { - if (rE.getRelation() === null) return false; - if (rE.getRelation().key === emojiKey && rE.getSender() === mx.getUserId()) { - rEvent = rE; - return true; - } - return false; - }); - return rEvent; -} - -function toggleEmoji(roomId, eventId, emojiKey, shortcode, roomTimeline) { - const myAlreadyReactEvent = getMyEmojiEvent(emojiKey, eventId, roomTimeline); - if (myAlreadyReactEvent) { - const rId = myAlreadyReactEvent.getId(); - if (rId.startsWith('~')) return; - redactEvent(roomId, rId); - return; - } - sendReaction(roomId, eventId, emojiKey, shortcode); -} - -function pickEmoji(e, roomId, eventId, roomTimeline) { - openEmojiBoard(getEventCords(e), (emoji) => { - toggleEmoji(roomId, eventId, emoji.mxc ?? emoji.unicode, emoji.shortcodes[0], roomTimeline); - e.target.click(); - }); -} - -function genReactionMsg(userIds, reaction, shortcode) { - return ( - <> - {userIds.map((userId, index) => ( - - {twemojify(getUsername(userId))} - {index < userIds.length - 1 && ( - - {index === userIds.length - 2 ? ' and ' : ', '} - - )} - - ))} - {' reacted with '} - {twemojify(shortcode ? `:${shortcode}:` : reaction, { className: 'react-emoji' })} - - ); -} - -function MessageReaction({ - reaction, shortcode, count, users, isActive, onClick, -}) { - let customEmojiUrl = null; - if (reaction.match(/^mxc:\/\/\S+$/)) { - customEmojiUrl = initMatrix.matrixClient.mxcUrlToHttp(reaction); - } - return ( - {users.length > 0 ? genReactionMsg(users, reaction, shortcode) : 'Unable to load who has reacted'}} - > - - - ); -} -MessageReaction.defaultProps = { - shortcode: undefined, -}; -MessageReaction.propTypes = { - reaction: PropTypes.node.isRequired, - shortcode: PropTypes.string, - count: PropTypes.number.isRequired, - users: PropTypes.arrayOf(PropTypes.string).isRequired, - isActive: PropTypes.bool.isRequired, - onClick: PropTypes.func.isRequired, -}; - -function MessageReactionGroup({ roomTimeline, mEvent }) { - const { roomId, room, reactionTimeline } = roomTimeline; - const mx = initMatrix.matrixClient; - const reactions = {}; - const canSendReaction = room.currentState.maySendEvent('m.reaction', mx.getUserId()); - - const eventReactions = reactionTimeline.get(mEvent.getId()); - const addReaction = (key, shortcode, count, senderId, isActive) => { - let reaction = reactions[key]; - if (reaction === undefined) { - reaction = { - count: 0, - users: [], - isActive: false, - }; - } - if (shortcode) reaction.shortcode = shortcode; - if (count) { - reaction.count = count; - } else { - reaction.users.push(senderId); - reaction.count = reaction.users.length; - if (isActive) reaction.isActive = isActive; - } - - reactions[key] = reaction; - }; - if (eventReactions) { - eventReactions.forEach((rEvent) => { - if (rEvent.getRelation() === null) return; - const reaction = rEvent.getRelation(); - const senderId = rEvent.getSender(); - const { shortcode } = rEvent.getContent(); - const isActive = senderId === mx.getUserId(); - - addReaction(reaction.key, shortcode, undefined, senderId, isActive); - }); - } else { - // Use aggregated reactions - const aggregatedReaction = mEvent.getServerAggregatedRelation('m.annotation')?.chunk; - if (!aggregatedReaction) return null; - aggregatedReaction.forEach((reaction) => { - if (reaction.type !== 'm.reaction') return; - addReaction(reaction.key, undefined, reaction.count, undefined, false); - }); - } - - return ( -
      - { - Object.keys(reactions).map((key) => ( - { - toggleEmoji(roomId, mEvent.getId(), key, reactions[key].shortcode, roomTimeline); - }} - /> - )) - } - {canSendReaction && ( - { - pickEmoji(e, roomId, mEvent.getId(), roomTimeline); - }} - src={EmojiAddIC} - size="extra-small" - tooltip="Add reaction" - /> - )} -
      - ); -} -MessageReactionGroup.propTypes = { - roomTimeline: PropTypes.shape({}).isRequired, - mEvent: PropTypes.shape({}).isRequired, -}; - -function isMedia(mE) { - return ( - mE.getContent()?.msgtype === 'm.file' - || mE.getContent()?.msgtype === 'm.image' - || mE.getContent()?.msgtype === 'm.audio' - || mE.getContent()?.msgtype === 'm.video' - || mE.getType() === 'm.sticker' - ); -} - -// if editedTimeline has mEventId then pass editedMEvent else pass mEvent to openViewSource -function handleOpenViewSource(mEvent, roomTimeline) { - const eventId = mEvent.getId(); - const { editedTimeline } = roomTimeline ?? {}; - let editedMEvent; - if (editedTimeline?.has(eventId)) { - const editedList = editedTimeline.get(eventId); - editedMEvent = editedList[editedList.length - 1]; - } - openViewSource(editedMEvent !== undefined ? editedMEvent : mEvent); -} - -const MessageOptions = React.memo(({ - roomTimeline, mEvent, edit, reply, -}) => { - const { roomId, room } = roomTimeline; - const mx = initMatrix.matrixClient; - const senderId = mEvent.getSender(); - - const myPowerlevel = room.getMember(mx.getUserId())?.powerLevel; - const canIRedact = room.currentState.hasSufficientPowerLevelFor('redact', myPowerlevel); - const canSendReaction = room.currentState.maySendEvent('m.reaction', mx.getUserId()); - - return ( -
      - {canSendReaction && ( - pickEmoji(e, roomId, mEvent.getId(), roomTimeline)} - src={EmojiAddIC} - size="extra-small" - tooltip="Add reaction" - /> - )} - reply()} - src={ReplyArrowIC} - size="extra-small" - tooltip="Reply" - /> - {(senderId === mx.getUserId() && !isMedia(mEvent)) && ( - edit(true)} - src={PencilIC} - size="extra-small" - tooltip="Edit" - /> - )} - ( - <> - Options - openReadReceipts(roomId, roomTimeline.getEventReaders(mEvent))} - > - Read receipts - - handleOpenViewSource(mEvent, roomTimeline)} - > - View source - - {(canIRedact || senderId === mx.getUserId()) && ( - <> - - { - const isConfirmed = await confirmDialog( - 'Delete message', - 'Are you sure that you want to delete this message?', - 'Delete', - 'danger', - ); - if (!isConfirmed) return; - redactEvent(roomId, mEvent.getId()); - }} - > - Delete - - - )} - - )} - render={(toggleMenu) => ( - - )} - /> -
      - ); -}); -MessageOptions.propTypes = { - roomTimeline: PropTypes.shape({}).isRequired, - mEvent: PropTypes.shape({}).isRequired, - edit: PropTypes.func.isRequired, - reply: PropTypes.func.isRequired, -}; - -function genMediaContent(mE) { - const mx = initMatrix.matrixClient; - const mContent = mE.getContent(); - if (!mContent || !mContent.body) return Malformed event; - - let mediaMXC = mContent?.url; - const isEncryptedFile = typeof mediaMXC === 'undefined'; - if (isEncryptedFile) mediaMXC = mContent?.file?.url; - - let thumbnailMXC = mContent?.info?.thumbnail_url; - - if (typeof mediaMXC === 'undefined' || mediaMXC === '') return Malformed event; - - let msgType = mE.getContent()?.msgtype; - const safeMimetype = getBlobSafeMimeType(mContent.info?.mimetype); - if (mE.getType() === 'm.sticker') { - msgType = 'm.sticker'; - } else if (safeMimetype === 'application/octet-stream') { - msgType = 'm.file'; - } - - const blurhash = mContent?.info?.['xyz.amorgan.blurhash']; - - switch (msgType) { - case 'm.file': - return ( - - ); - case 'm.image': - return ( - - ); - case 'm.sticker': - return ( - - ); - case 'm.audio': - return ( - - ); - case 'm.video': - if (typeof thumbnailMXC === 'undefined') { - thumbnailMXC = mContent.info?.thumbnail_file?.url || null; - } - return ( - - ); - default: - return Malformed event; - } -} - -function getEditedBody(editedMEvent) { - const newContent = editedMEvent.getContent()['m.new_content']; - if (typeof newContent === 'undefined') return [null, false, null]; - - const isCustomHTML = newContent.format === 'org.matrix.custom.html'; - const parsedContent = parseReply(newContent.body); - if (parsedContent === null) { - return [newContent.body, isCustomHTML, newContent.formatted_body ?? null]; - } - return [parsedContent.body, isCustomHTML, newContent.formatted_body ?? null]; -} - -function Message({ - mEvent, isBodyOnly, roomTimeline, - focus, fullTime, isEdit, setEdit, cancelEdit, -}) { - const roomId = mEvent.getRoomId(); - const { editedTimeline, reactionTimeline } = roomTimeline ?? {}; - - const className = ['message', (isBodyOnly ? 'message--body-only' : 'message--full')]; - if (focus) className.push('message--focus'); - const content = mEvent.getContent(); - const eventId = mEvent.getId(); - const msgType = content?.msgtype; - const senderId = mEvent.getSender(); - let { body } = content; - const username = mEvent.sender ? getUsernameOfRoomMember(mEvent.sender) : getUsername(senderId); - const avatarSrc = mEvent.sender?.getAvatarUrl(initMatrix.matrixClient.baseUrl, 36, 36, 'crop') ?? null; - let isCustomHTML = content.format === 'org.matrix.custom.html'; - let customHTML = isCustomHTML ? content.formatted_body : null; - - const edit = useCallback(() => { - setEdit(eventId); - }, []); - const reply = useCallback(() => { - replyTo(senderId, mEvent.getId(), body, customHTML); - }, [body, customHTML]); - - if (msgType === 'm.emote') className.push('message--type-emote'); - - const isEdited = roomTimeline ? editedTimeline.has(eventId) : false; - const haveReactions = roomTimeline - ? reactionTimeline.has(eventId) || !!mEvent.getServerAggregatedRelation('m.annotation') - : false; - const isReply = !!mEvent.replyEventId; - - if (isEdited) { - const editedList = editedTimeline.get(eventId); - const editedMEvent = editedList[editedList.length - 1]; - [body, isCustomHTML, customHTML] = getEditedBody(editedMEvent); - } - - if (isReply) { - body = parseReply(body)?.body ?? body; - customHTML = trimHTMLReply(customHTML); - } - - if (typeof body !== 'string') body = ''; - - return ( -
      - { - isBodyOnly - ?
      - : ( - - ) - } -
      - {!isBodyOnly && ( - - )} - {roomTimeline && isReply && ( - - )} - {!isEdit && ( - - )} - {isEdit && ( - { - if (newBody !== oldBody) { - initMatrix.roomsInput.sendEditedMessage(roomId, mEvent, newBody); - } - cancelEdit(); - }} - onCancel={cancelEdit} - /> - )} - {haveReactions && ( - - )} - {roomTimeline && !isEdit && ( - - )} -
      -
      - ); -} -Message.defaultProps = { - isBodyOnly: false, - focus: false, - roomTimeline: null, - fullTime: false, - isEdit: false, - setEdit: null, - cancelEdit: null, -}; -Message.propTypes = { - mEvent: PropTypes.shape({}).isRequired, - isBodyOnly: PropTypes.bool, - roomTimeline: PropTypes.shape({}), - focus: PropTypes.bool, - fullTime: PropTypes.bool, - isEdit: PropTypes.bool, - setEdit: PropTypes.func, - cancelEdit: PropTypes.func, -}; - -export { Message, MessageReply, PlaceholderMessage }; diff --git a/src/app/molecules/message/Message.scss b/src/app/molecules/message/Message.scss deleted file mode 100644 index 5dda9c98d..000000000 --- a/src/app/molecules/message/Message.scss +++ /dev/null @@ -1,479 +0,0 @@ -@use '../../atoms/scroll/scrollbar'; -@use '../../partials/text'; -@use '../../partials/dir'; -@use '../../partials/screen'; - -.message, -.ph-msg { - padding: var(--sp-ultra-tight); - @include dir.side(padding, var(--sp-normal), var(--sp-extra-tight)); - display: flex; - - &:hover { - background-color: var(--bg-surface-hover); - & .message__options { - display: flex; - } - } - - &__avatar-container { - padding-top: 6px; - @include dir.side(margin, 0, var(--sp-tight)); - - & .avatar-container { - transition: transform 200ms var(--fluid-push); - &:hover { - transform: translateY(-4px); - } - } - - & button { - cursor: pointer; - display: flex; - } - } - - &__main-container { - flex: 1; - min-width: 0; - - position: relative; - } -} - -.message { - &--full + &--full, - &--body-only + &--full, - & + .timeline-change, - .timeline-change + & { - margin-top: var(--sp-normal); - } - &__avatar-container { - width: var(--av-small); - } - &--focus { - --ltr: inset 2px 0 0 var(--bg-caution); - --rtl: inset -2px 0 0 var(--bg-caution); - @include dir.prop(box-shadow, var(--ltr), var(--rtl)); - background-color: var(--bg-caution-hover); - } -} - -.ph-msg { - &__avatar { - width: var(--av-small); - height: var(--av-small); - background-color: var(--bg-surface-hover); - border-radius: var(--bo-radius); - } - - &__header, - &__body > div { - margin: var(--sp-ultra-tight); - @include dir.side(margin, 0, var(--sp-extra-tight)); - height: var(--fs-b1); - width: 100%; - max-width: 100px; - background-color: var(--bg-surface-hover); - border-radius: calc(var(--bo-radius) / 2); - } - &__body { - display: flex; - flex-wrap: wrap; - } - &__body > div:nth-child(1n) { - max-width: 10%; - } - &__body > div:nth-child(2n) { - max-width: 50%; - } -} - -.message__reply, -.message__body, -.message__body__wrapper, -.message__edit, -.message__reactions { - max-width: calc(100% - 88px); - min-width: 0; - @include screen.smallerThan(tabletBreakpoint) { - max-width: 100%; - } -} - -.message__header { - display: flex; - align-items: baseline; - - & .message__profile { - min-width: 0; - color: var(--tc-surface-high); - @include dir.side(margin, 0, var(--sp-tight)); - - & > span { - @extend .cp-txt__ellipsis; - color: inherit; - } - & > span:last-child { - display: none; - } - &:hover { - & > span:first-child { - display: none; - } - & > span:last-child { - display: block; - } - } - } - - & .message__time { - flex: 1; - display: flex; - justify-content: flex-end; - & > .text { - white-space: nowrap; - color: var(--tc-surface-low); - } - } -} -.message__reply { - &-wrapper { - min-height: 20px; - cursor: pointer; - &:empty { - border-radius: calc(var(--bo-radius) / 2); - background-color: var(--bg-surface-hover); - max-width: 200px; - cursor: auto; - } - &:hover .text { - color: var(--tc-surface-high); - } - } - .text { - @extend .cp-txt__ellipsis; - color: var(--tc-surface-low); - } - .ic-raw { - width: 16px; - height: 14px; - } -} -.message__body { - word-break: break-word; - - & > .text > .message__body-plain { - white-space: pre-wrap; - } - - & a { - word-break: break-word; - } - & > .text > a { - white-space: initial !important; - } - - & > .text > p + p { - margin-top: var(--sp-normal); - } - - & span[data-mx-pill] { - background-color: hsla(0, 0%, 64%, 0.15); - padding: 0 2px; - border-radius: 4px; - cursor: pointer; - font-weight: var(--fw-medium); - &:hover { - background-color: hsla(0, 0%, 64%, 0.3); - color: var(--tc-surface-high); - } - - &[data-mx-ping] { - background-color: var(--bg-ping); - &:hover { - background-color: var(--bg-ping-hover); - } - } - } - - & span[data-mx-spoiler] { - border-radius: 4px; - background-color: rgba(124, 124, 124, 0.5); - color: transparent; - cursor: pointer; - -webkit-touch-callout: none; - -webkit-user-select: none; - -khtml-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - & > * { - opacity: 0; - } - } - - .data-mx-spoiler--visible { - background-color: var(--bg-surface-active) !important; - color: inherit !important; - user-select: initial !important; - & > * { - opacity: inherit !important; - } - } - &-edited { - color: var(--tc-surface-low); - } -} -.message__edit { - padding: var(--sp-extra-tight) 0; - &-btns button { - margin: var(--sp-tight) 0 0 0; - padding: var(--sp-ultra-tight) var(--sp-tight); - min-width: 0; - @include dir.side(margin, 0, var(--sp-tight)); - } -} -.message__reactions { - display: flex; - flex-wrap: wrap; - - & .ic-btn-surface { - display: none; - padding: var(--sp-ultra-tight); - margin-top: var(--sp-extra-tight); - } - &:hover .ic-btn-surface { - display: block; - } -} -.msg__reaction { - margin: var(--sp-extra-tight) 0 0 0; - @include dir.side(margin, 0, var(--sp-extra-tight)); - padding: 0 var(--sp-ultra-tight); - min-height: 26px; - display: inline-flex; - align-items: center; - color: var(--tc-surface-normal); - background-color: var(--bg-surface-low); - border: 1px solid var(--bg-surface-border); - border-radius: 4px; - cursor: pointer; - - & .react-emoji { - height: 16px; - margin: 2px; - } - &-count { - margin: 0 var(--sp-ultra-tight); - color: var(--tc-surface-normal); - } - &-tooltip .react-emoji { - width: 16px; - height: 16px; - margin: 0 var(--sp-ultra-tight); - margin-bottom: -2px; - } - - @media (hover: hover) { - &:hover { - background-color: var(--bg-surface-hover); - } - } - &:active { - background-color: var(--bg-surface-active); - } - - &--active { - background-color: var(--bg-caution-active); - - @media (hover: hover) { - &:hover { - background-color: var(--bg-caution-hover); - } - } - &:active { - background-color: var(--bg-caution-active); - } - } -} -.message__options { - position: absolute; - top: 0; - @include dir.prop(right, 60px, unset); - @include dir.prop(left, unset, 60px); - - z-index: 99; - transform: translateY(-100%); - - border-radius: var(--bo-radius); - box-shadow: var(--bs-surface-border); - background-color: var(--bg-surface-low); - display: none; -} - -// markdown formating -.message__body { - & h1, - h2, - h3, - h4, - h5, - h6 { - margin: 0; - margin-bottom: var(--sp-ultra-tight); - font-weight: var(--fw-medium); - &:first-child { - margin-top: 0; - } - &:last-child { - margin-bottom: 0; - } - } - & h1, - & h2 { - color: var(--tc-surface-high); - margin-top: var(--sp-normal); - font-size: var(--fs-h2); - line-height: var(--lh-h2); - letter-spacing: var(--ls-h2); - } - & h3, - & h4 { - color: var(--tc-surface-high); - margin-top: var(--sp-tight); - font-size: var(--fs-s1); - line-height: var(--lh-s1); - letter-spacing: var(--ls-s1); - } - & h5, - & h6 { - color: var(--tc-surface-high); - margin-top: var(--sp-extra-tight); - font-size: var(--fs-b1); - line-height: var(--lh-b1); - letter-spacing: var(--ls-b1); - } - & hr { - border-color: var(--bg-divider); - } - - .text img { - margin: var(--sp-ultra-tight) 0; - max-width: 296px; - border-radius: calc(var(--bo-radius) / 2); - } - - & p, - & pre, - & blockquote { - margin: 0; - padding: 0; - } - & pre, - & blockquote { - margin: var(--sp-ultra-tight) 0; - padding: var(--sp-extra-tight); - background-color: var(--bg-surface-hover) !important; - border-radius: calc(var(--bo-radius) / 2); - } - & pre { - div { - background: none !important; - margin: 0 !important; - } - span { - background: none !important; - } - .linenumber { - min-width: 2.25em !important; - } - } - & code { - padding: 0 !important; - color: var(--tc-code) !important; - white-space: pre-wrap; - @include scrollbar.scroll; - @include scrollbar.scroll__h; - @include scrollbar.scroll--auto-hide; - } - & pre { - width: fit-content; - max-width: 100%; - @include scrollbar.scroll; - @include scrollbar.scroll__h; - @include scrollbar.scroll--auto-hide; - & code { - color: var(--tc-surface-normal) !important; - white-space: pre; - } - } - & blockquote { - width: fit-content; - max-width: 100%; - @include dir.side(border, 4px solid var(--bg-surface-active), 0); - white-space: initial !important; - - & > * { - white-space: pre-wrap; - } - } - & ul, - & ol { - margin: var(--sp-ultra-tight) 0; - @include dir.side(padding, 24px, 0); - white-space: initial !important; - } - & ul.contains-task-list { - padding: 0; - list-style: none; - } - & table { - display: inline-block; - max-width: 100%; - white-space: normal !important; - background-color: var(--bg-surface-hover); - border-radius: calc(var(--bo-radius) / 2); - border-spacing: 0; - border: 1px solid var(--bg-surface-border); - @include scrollbar.scroll; - @include scrollbar.scroll__h; - @include scrollbar.scroll--auto-hide; - - & td, - & th { - padding: var(--sp-extra-tight); - border: 1px solid var(--bg-surface-border); - border-width: 0 1px 1px 0; - white-space: pre; - &:last-child { - border-width: 0; - border-bottom-width: 1px; - [dir='rtl'] & { - border-width: 0 1px 1px 0; - } - } - [dir='rtl'] &:first-child { - border-width: 0; - border-bottom-width: 1px; - } - } - & tbody tr:nth-child(2n + 1) { - background-color: var(--bg-surface-hover); - } - & tr:last-child td { - border-bottom-width: 0px !important; - } - } -} - -.message.message--type-emote { - .message__body { - font-style: italic; - - // Remove blockness of first `

      ` so that markdown emotes stay on one line. - p:first-of-type { - display: inline; - } - } -} diff --git a/src/app/molecules/message/TimelineChange.jsx b/src/app/molecules/message/TimelineChange.jsx deleted file mode 100644 index bc6e913f3..000000000 --- a/src/app/molecules/message/TimelineChange.jsx +++ /dev/null @@ -1,78 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import './TimelineChange.scss'; - -import Text from '../../atoms/text/Text'; -import RawIcon from '../../atoms/system-icons/RawIcon'; -import Time from '../../atoms/time/Time'; - -import JoinArraowIC from '../../../../public/res/ic/outlined/join-arrow.svg'; -import LeaveArraowIC from '../../../../public/res/ic/outlined/leave-arrow.svg'; -import InviteArraowIC from '../../../../public/res/ic/outlined/invite-arrow.svg'; -import InviteCancelArraowIC from '../../../../public/res/ic/outlined/invite-cancel-arrow.svg'; -import UserIC from '../../../../public/res/ic/outlined/user.svg'; - -function TimelineChange({ - variant, content, timestamp, onClick, -}) { - let iconSrc; - - switch (variant) { - case 'join': - iconSrc = JoinArraowIC; - break; - case 'leave': - iconSrc = LeaveArraowIC; - break; - case 'invite': - iconSrc = InviteArraowIC; - break; - case 'invite-cancel': - iconSrc = InviteCancelArraowIC; - break; - case 'avatar': - iconSrc = UserIC; - break; - default: - iconSrc = JoinArraowIC; - break; - } - - return ( - - ); -} - -TimelineChange.defaultProps = { - variant: 'other', - onClick: null, -}; - -TimelineChange.propTypes = { - variant: PropTypes.oneOf([ - 'join', 'leave', 'invite', - 'invite-cancel', 'avatar', 'other', - ]), - content: PropTypes.oneOfType([ - PropTypes.string, - PropTypes.node, - ]).isRequired, - timestamp: PropTypes.number.isRequired, - onClick: PropTypes.func, -}; - -export default TimelineChange; diff --git a/src/app/molecules/message/TimelineChange.scss b/src/app/molecules/message/TimelineChange.scss deleted file mode 100644 index c066a9ae5..000000000 --- a/src/app/molecules/message/TimelineChange.scss +++ /dev/null @@ -1,37 +0,0 @@ -@use '../../partials/dir'; - -.timeline-change { - padding: var(--sp-ultra-tight); - @include dir.side(padding, var(--sp-normal), var(--sp-extra-tight)); - - display: flex; - align-items: center; - width: 100%; - - &:hover { - background-color: var(--bg-surface-hover); - } - - &__avatar-container { - width: var(--av-small); - display: inline-flex; - justify-content: center; - align-items: center; - opacity: 0.38; - .ic-raw { - background-color: var(--tc-surface-low); - } - } - - & .text { - color: var(--tc-surface-low); - } - - &__content { - flex: 1; - min-width: 0; - - margin: 0 var(--sp-tight); - word-break: break-word; - } -} \ No newline at end of file diff --git a/src/app/molecules/people-selector/PeopleSelector.jsx b/src/app/molecules/people-selector/PeopleSelector.jsx index 8ea0587f5..7025aa7c4 100644 --- a/src/app/molecules/people-selector/PeopleSelector.jsx +++ b/src/app/molecules/people-selector/PeopleSelector.jsx @@ -2,16 +2,12 @@ import React from 'react'; import PropTypes from 'prop-types'; import './PeopleSelector.scss'; -import { twemojify } from '../../../util/twemojify'; - import { blurOnBubbling } from '../../atoms/button/script'; import Text from '../../atoms/text/Text'; import Avatar from '../../atoms/avatar/Avatar'; -function PeopleSelector({ - avatarSrc, name, color, peopleRole, onClick, -}) { +function PeopleSelector({ avatarSrc, name, color, peopleRole, onClick }) { return (

      ); diff --git a/src/app/molecules/popup-window/PopupWindow.jsx b/src/app/molecules/popup-window/PopupWindow.jsx index 4179f49a8..55872d6ae 100644 --- a/src/app/molecules/popup-window/PopupWindow.jsx +++ b/src/app/molecules/popup-window/PopupWindow.jsx @@ -2,8 +2,6 @@ import React from 'react'; import PropTypes from 'prop-types'; import './PopupWindow.scss'; -import { twemojify } from '../../../util/twemojify'; - import Text from '../../atoms/text/Text'; import IconButton from '../../atoms/button/IconButton'; import { MenuItem } from '../../atoms/context-menu/ContextMenu'; @@ -13,19 +11,11 @@ import RawModal from '../../atoms/modal/RawModal'; import ChevronLeftIC from '../../../../public/res/ic/outlined/chevron-left.svg'; -function PWContentSelector({ - selected, variant, iconSrc, - type, onClick, children, -}) { +function PWContentSelector({ selected, variant, iconSrc, type, onClick, children }) { const pwcsClass = selected ? ' pw-content-selector--selected' : ''; return (
      - + {children}
      @@ -49,9 +39,16 @@ PWContentSelector.propTypes = { }; function PopupWindow({ - className, isOpen, title, contentTitle, - drawer, drawerOptions, contentOptions, - onAfterClose, onRequestClose, children, + className, + isOpen, + title, + contentTitle, + drawer, + drawerOptions, + contentOptions, + onAfterClose, + onRequestClose, + children, }) { const haveDrawer = drawer !== null; const cTitle = contentTitle !== null ? contentTitle : title; @@ -69,21 +66,26 @@ function PopupWindow({ {haveDrawer && (
      - + - { - typeof title === 'string' - ? {twemojify(title)} - : title - } + {typeof title === 'string' ? ( + + {title} + + ) : ( + title + )} {drawerOptions}
      -
      - {drawer} -
      +
      {drawer}
      @@ -91,19 +93,19 @@ function PopupWindow({
      - { - typeof cTitle === 'string' - ? {twemojify(cTitle)} - : cTitle - } + {typeof cTitle === 'string' ? ( + + {cTitle} + + ) : ( + cTitle + )} {contentOptions}
      -
      - {children} -
      +
      {children}
      diff --git a/src/app/molecules/room-notification/RoomNotification.jsx b/src/app/molecules/room-notification/RoomNotification.jsx index 4adb1169e..821ea5084 100644 --- a/src/app/molecules/room-notification/RoomNotification.jsx +++ b/src/app/molecules/room-notification/RoomNotification.jsx @@ -13,28 +13,33 @@ import BellIC from '../../../../public/res/ic/outlined/bell.svg'; import BellRingIC from '../../../../public/res/ic/outlined/bell-ring.svg'; import BellPingIC from '../../../../public/res/ic/outlined/bell-ping.svg'; import BellOffIC from '../../../../public/res/ic/outlined/bell-off.svg'; +import { getNotificationType } from '../../utils/room'; -const items = [{ - iconSrc: BellIC, - text: 'Global', - type: cons.notifs.DEFAULT, -}, { - iconSrc: BellRingIC, - text: 'All messages', - type: cons.notifs.ALL_MESSAGES, -}, { - iconSrc: BellPingIC, - text: 'Mentions & Keywords', - type: cons.notifs.MENTIONS_AND_KEYWORDS, -}, { - iconSrc: BellOffIC, - text: 'Mute', - type: cons.notifs.MUTE, -}]; +const items = [ + { + iconSrc: BellIC, + text: 'Global', + type: cons.notifs.DEFAULT, + }, + { + iconSrc: BellRingIC, + text: 'All messages', + type: cons.notifs.ALL_MESSAGES, + }, + { + iconSrc: BellPingIC, + text: 'Mentions & Keywords', + type: cons.notifs.MENTIONS_AND_KEYWORDS, + }, + { + iconSrc: BellOffIC, + text: 'Mute', + type: cons.notifs.MUTE, + }, +]; function setRoomNotifType(roomId, newType) { const mx = initMatrix.matrixClient; - const { notifications } = initMatrix; let roomPushRule; try { roomPushRule = mx.getRoomPushRule('global', roomId); @@ -47,22 +52,22 @@ function setRoomNotifType(roomId, newType) { if (roomPushRule) { promises.push(mx.deletePushRule('global', 'room', roomPushRule.rule_id)); } - promises.push(mx.addPushRule('global', 'override', roomId, { - conditions: [ - { - kind: 'event_match', - key: 'room_id', - pattern: roomId, - }, - ], - actions: [ - 'dont_notify', - ], - })); + promises.push( + mx.addPushRule('global', 'override', roomId, { + conditions: [ + { + kind: 'event_match', + key: 'room_id', + pattern: roomId, + }, + ], + actions: ['dont_notify'], + }) + ); return promises; } - const oldState = notifications.getNotiType(roomId); + const oldState = getNotificationType(mx, roomId); if (oldState === cons.notifs.MUTE) { promises.push(mx.deletePushRule('global', 'override', roomId)); } @@ -75,25 +80,27 @@ function setRoomNotifType(roomId, newType) { } if (newType === cons.notifs.MENTIONS_AND_KEYWORDS) { - promises.push(mx.addPushRule('global', 'room', roomId, { - actions: [ - 'dont_notify', - ], - })); + promises.push( + mx.addPushRule('global', 'room', roomId, { + actions: ['dont_notify'], + }) + ); promises.push(mx.setPushRuleEnabled('global', 'room', roomId, true)); return Promise.all(promises); } // cons.notifs.ALL_MESSAGES - promises.push(mx.addPushRule('global', 'room', roomId, { - actions: [ - 'notify', - { - set_tweak: 'sound', - value: 'default', - }, - ], - })); + promises.push( + mx.addPushRule('global', 'room', roomId, { + actions: [ + 'notify', + { + set_tweak: 'sound', + value: 'default', + }, + ], + }) + ); promises.push(mx.setPushRuleEnabled('global', 'room', roomId, true)); @@ -101,17 +108,20 @@ function setRoomNotifType(roomId, newType) { } function useNotifications(roomId) { - const { notifications } = initMatrix; - const [activeType, setActiveType] = useState(notifications.getNotiType(roomId)); + const mx = initMatrix.matrixClient; + const [activeType, setActiveType] = useState(getNotificationType(mx, roomId)); useEffect(() => { - setActiveType(notifications.getNotiType(roomId)); - }, [roomId]); + setActiveType(getNotificationType(mx, roomId)); + }, [mx, roomId]); - const setNotification = useCallback((item) => { - if (item.type === activeType.type) return; - setActiveType(item.type); - setRoomNotifType(roomId, item.type); - }, [activeType, roomId]); + const setNotification = useCallback( + (item) => { + if (item.type === activeType.type) return; + setActiveType(item.type); + setRoomNotifType(roomId, item.type); + }, + [activeType, roomId] + ); return [activeType, setNotification]; } @@ -120,21 +130,19 @@ function RoomNotification({ roomId }) { return (
      - { - items.map((item) => ( - setNotification(item)} - > - - {item.text} - - - - )) - } + {items.map((item) => ( + setNotification(item)} + > + + {item.text} + + + + ))}
      ); } diff --git a/src/app/molecules/room-options/RoomOptions.jsx b/src/app/molecules/room-options/RoomOptions.jsx deleted file mode 100644 index af18d7120..000000000 --- a/src/app/molecules/room-options/RoomOptions.jsx +++ /dev/null @@ -1,73 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; - -import { twemojify } from '../../../util/twemojify'; - -import initMatrix from '../../../client/initMatrix'; -import { openInviteUser } from '../../../client/action/navigation'; -import * as roomActions from '../../../client/action/room'; -import { markAsRead } from '../../../client/action/notifications'; - -import { MenuHeader, MenuItem } from '../../atoms/context-menu/ContextMenu'; -import RoomNotification from '../room-notification/RoomNotification'; - -import TickMarkIC from '../../../../public/res/ic/outlined/tick-mark.svg'; -import AddUserIC from '../../../../public/res/ic/outlined/add-user.svg'; -import LeaveArrowIC from '../../../../public/res/ic/outlined/leave-arrow.svg'; - -import { confirmDialog } from '../confirm-dialog/ConfirmDialog'; - -function RoomOptions({ roomId, afterOptionSelect }) { - const mx = initMatrix.matrixClient; - const room = mx.getRoom(roomId); - const canInvite = room?.canInvite(mx.getUserId()); - - const handleMarkAsRead = () => { - markAsRead(roomId); - afterOptionSelect(); - }; - - const handleInviteClick = () => { - openInviteUser(roomId); - afterOptionSelect(); - }; - const handleLeaveClick = async () => { - afterOptionSelect(); - const isConfirmed = await confirmDialog( - 'Leave room', - `Are you sure that you want to leave "${room.name}" room?`, - 'Leave', - 'danger', - ); - if (!isConfirmed) return; - roomActions.leave(roomId); - }; - - return ( -
      - {twemojify(`Options for ${initMatrix.matrixClient.getRoom(roomId)?.name}`)} - Mark as read - - Invite - - Leave - Notification - -
      - ); -} - -RoomOptions.defaultProps = { - afterOptionSelect: null, -}; - -RoomOptions.propTypes = { - roomId: PropTypes.string.isRequired, - afterOptionSelect: PropTypes.func, -}; - -export default RoomOptions; diff --git a/src/app/molecules/room-profile/RoomProfile.jsx b/src/app/molecules/room-profile/RoomProfile.jsx index 218119845..15273ebfd 100644 --- a/src/app/molecules/room-profile/RoomProfile.jsx +++ b/src/app/molecules/room-profile/RoomProfile.jsx @@ -1,9 +1,9 @@ import React, { useState, useEffect } from 'react'; import PropTypes from 'prop-types'; +import { useAtomValue } from 'jotai'; +import Linkify from 'linkify-react'; import './RoomProfile.scss'; -import { twemojify } from '../../../util/twemojify'; - import initMatrix from '../../../client/initMatrix'; import cons from '../../../client/state/cons'; import colorMXID from '../../../util/colorMXID'; @@ -20,6 +20,8 @@ import PencilIC from '../../../../public/res/ic/outlined/pencil.svg'; import { useStore } from '../../hooks/useStore'; import { useForceUpdate } from '../../hooks/useForceUpdate'; import { confirmDialog } from '../confirm-dialog/ConfirmDialog'; +import { mDirectAtom } from '../../state/mDirectList'; +import { LINKIFY_OPTS } from '../../plugins/react-custom-html-parser'; function RoomProfile({ roomId }) { const isMountStore = useStore(); @@ -31,9 +33,12 @@ function RoomProfile({ roomId }) { }); const mx = initMatrix.matrixClient; - const isDM = initMatrix.roomList.directs.has(roomId); + const mDirects = useAtomValue(mDirectAtom); + const isDM = mDirects.has(roomId); let avatarSrc = mx.getRoom(roomId).getAvatarUrl(mx.baseUrl, 36, 36, 'crop'); - avatarSrc = isDM ? mx.getRoom(roomId).getAvatarFallbackMember()?.getAvatarUrl(mx.baseUrl, 36, 36, 'crop') : avatarSrc; + avatarSrc = isDM + ? mx.getRoom(roomId).getAvatarFallbackMember()?.getAvatarUrl(mx.baseUrl, 36, 36, 'crop') + : avatarSrc; const room = mx.getRoom(roomId); const { currentState } = room; const roomName = room.name; @@ -47,15 +52,14 @@ function RoomProfile({ roomId }) { useEffect(() => { isMountStore.setItem(true); - const { roomList } = initMatrix; - const handleProfileUpdate = (rId) => { - if (roomId !== rId) return; + const handleStateEvent = (mEvent) => { + if (mEvent.event.room_id !== roomId) return; forceUpdate(); }; - roomList.on(cons.events.roomList.ROOM_PROFILE_UPDATED, handleProfileUpdate); + mx.on('RoomState.events', handleStateEvent); return () => { - roomList.removeListener(cons.events.roomList.ROOM_PROFILE_UPDATED, handleProfileUpdate); + mx.removeListener('RoomState.events', handleStateEvent); isMountStore.setItem(false); setStatus({ msg: null, @@ -122,7 +126,7 @@ function RoomProfile({ roomId }) { 'Remove avatar', 'Are you sure that you want to remove room avatar?', 'Remove', - 'caution', + 'caution' ); if (isConfirmed) { await mx.sendStateEvent(roomId, 'm.room.avatar', { url }, ''); @@ -132,15 +136,45 @@ function RoomProfile({ roomId }) { const renderEditNameAndTopic = () => (
      - {canChangeName && } - {canChangeTopic && } - {(!canChangeName || !canChangeTopic) && {`You have permission to change ${room.isSpaceRoom() ? 'space' : 'room'} ${canChangeName ? 'name' : 'topic'} only.`}} - { status.type === cons.status.IN_FLIGHT && {status.msg}} - { status.type === cons.status.SUCCESS && {status.msg}} - { status.type === cons.status.ERROR && {status.msg}} - { status.type !== cons.status.IN_FLIGHT && ( + {canChangeName && ( + + )} + {canChangeTopic && ( + + )} + {(!canChangeName || !canChangeTopic) && ( + {`You have permission to change ${ + room.isSpaceRoom() ? 'space' : 'room' + } ${canChangeName ? 'name' : 'topic'} only.`} + )} + {status.type === cons.status.IN_FLIGHT && {status.msg}} + {status.type === cons.status.SUCCESS && ( + + {status.msg} + + )} + {status.type === cons.status.ERROR && ( + + {status.msg} + + )} + {status.type !== cons.status.IN_FLIGHT && (
      - +
      )} @@ -148,10 +182,15 @@ function RoomProfile({ roomId }) { ); const renderNameAndTopic = () => ( -
      +
      - {twemojify(roomName)} - { (canChangeName || canChangeTopic) && ( + + {roomName} + + {(canChangeName || canChangeTopic) && ( {room.getCanonicalAlias() || room.roomId} - {roomTopic && {twemojify(roomTopic, undefined, true)}} + {roomTopic && ( + + {roomTopic} + + )}
      ); return (
      - { !canChangeAvatar && } - { canChangeAvatar && ( + {!canChangeAvatar && ( + + )} + {canChangeAvatar && ( { - mountStore.setItem(true) - }, [roomId]); - - useEffect(() => { - if (searchData?.results?.length > 0) { - roomIdToBackup.set(roomId, searchData); - } else { - roomIdToBackup.delete(roomId); - } - }, [searchData]); - - const search = async (term) => { - setSearchData(null); - if (term === '') { - setStatus({ type: cons.status.PRE_FLIGHT, term: null }); - return; - } - setStatus({ type: cons.status.IN_FLIGHT, term }); - const body = { - search_categories: { - room_events: { - search_term: term, - filter: { - limit: 10, - rooms: [roomId], - }, - order_by: 'recent', - event_context: { - before_limit: 0, - after_limit: 0, - include_profile: true, - }, - }, - }, - }; - try { - const res = await mx.search({ body }); - const data = mx.processRoomEventsSearch({ - _query: body, - results: [], - highlights: [], - }, res); - if (!mountStore.getItem()) return; - setStatus({ type: cons.status.SUCCESS, term }); - setSearchData(data); - if (!mountStore.getItem()) return; - } catch (error) { - setSearchData(null); - setStatus({ type: cons.status.ERROR, term }); - } - }; - - const paginate = async () => { - if (searchData === null) return; - const term = searchData._query.search_categories.room_events.search_term; - - setStatus({ type: cons.status.IN_FLIGHT, term }); - try { - const data = await mx.backPaginateRoomEventsSearch(searchData); - if (!mountStore.getItem()) return; - setStatus({ type: cons.status.SUCCESS, term }); - setSearchData(data); - } catch (error) { - if (!mountStore.getItem()) return; - setSearchData(null); - setStatus({ type: cons.status.ERROR, term }); - } - }; - - return [searchData, search, paginate, status]; -} - -function RoomSearch({ roomId }) { - const [searchData, search, paginate, status] = useRoomSearch(roomId); - const mx = initMatrix.matrixClient; - const isRoomEncrypted = mx.isRoomEncrypted(roomId); - const searchTerm = searchData?._query.search_categories.room_events.search_term ?? ''; - - const handleSearch = (e) => { - e.preventDefault(); - if (isRoomEncrypted) return; - const searchTermInput = e.target.elements['room-search-input']; - const term = searchTermInput.value.trim(); - - search(term); - }; - - const renderTimeline = (timeline) => ( -
      - { timeline.map((mEvent) => { - const id = mEvent.getId(); - return ( - - - - - ); - })} -
      - ); - - return ( -
      - - Room search -
      - - -
      - {searchData?.results.length > 0 && ( - {`${searchData.count} results for "${searchTerm}"`} - )} - {!isRoomEncrypted && searchData === null && ( -
      - {status.type === cons.status.IN_FLIGHT && } - {status.type === cons.status.IN_FLIGHT && Searching room messages...} - {status.type === cons.status.PRE_FLIGHT && } - {status.type === cons.status.PRE_FLIGHT && Search room messages} - {status.type === cons.status.ERROR && Failed to search messages} -
      - )} - - {!isRoomEncrypted && searchData?.results.length === 0 && ( -
      - No results found -
      - )} - {isRoomEncrypted && ( -
      - Search does not work in encrypted room -
      - )} - - {searchData?.results.length > 0 && ( - <> -
      - {searchData.results.map((searchResult) => { - const { timeline } = searchResult.context; - return renderTimeline(timeline); - })} -
      - {searchData?.next_batch && ( -
      - {status.type !== cons.status.IN_FLIGHT && ( - - )} - {status.type === cons.status.IN_FLIGHT && } -
      - )} - - )} -
      - ); -} - -RoomSearch.propTypes = { - roomId: PropTypes.string.isRequired, -}; - -export default RoomSearch; diff --git a/src/app/molecules/room-search/RoomSearch.scss b/src/app/molecules/room-search/RoomSearch.scss deleted file mode 100644 index a40945ef4..000000000 --- a/src/app/molecules/room-search/RoomSearch.scss +++ /dev/null @@ -1,62 +0,0 @@ -@use '../../partials/flex'; -@use '../../partials/dir'; - -.room-search { - &__form { - & div:nth-child(2) { - display: flex; - align-items: flex-end; - padding: var(--sp-normal);; - - & .input-container { - @extend .cp-fx__item-one; - @include dir.side(margin, 0, var(--sp-normal)); - } - & button { - height: 46px; - } - } - & .context-menu__header { - margin-bottom: 0; - } - & > .text { - padding: 0 var(--sp-normal) var(--sp-tight); - } - } - - &__help { - height: 248px; - @extend .cp-fx__column--c-c; - - & .ic-raw { - opacity: .5; - } - .text { - margin-top: var(--sp-normal); - } - } - &__more { - margin-bottom: var(--sp-normal); - @extend .cp-fx__row--c-c; - button { - width: 100%; - } - } - &__result-item { - padding: var(--sp-tight) var(--sp-normal); - display: flex; - align-items: flex-start; - - .message { - @include dir.side(margin, 0, var(--sp-normal)); - @extend .cp-fx__item-one; - padding: 0; - &:hover { - background-color: transparent; - } - & .message__time { - flex: 0; - } - } - } -} \ No newline at end of file diff --git a/src/app/molecules/room-selector/RoomSelector.jsx b/src/app/molecules/room-selector/RoomSelector.jsx index fa6daa9e9..f865c95d0 100644 --- a/src/app/molecules/room-selector/RoomSelector.jsx +++ b/src/app/molecules/room-selector/RoomSelector.jsx @@ -2,7 +2,6 @@ import React from 'react'; import PropTypes from 'prop-types'; import './RoomSelector.scss'; -import { twemojify } from '../../../util/twemojify'; import colorMXID from '../../../util/colorMXID'; import Text from '../../atoms/text/Text'; @@ -11,8 +10,13 @@ import NotificationBadge from '../../atoms/badge/NotificationBadge'; import { blurOnBubbling } from '../../atoms/button/script'; function RoomSelectorWrapper({ - isSelected, isMuted, isUnread, onClick, - content, options, onContextMenu, + isSelected, + isMuted, + isUnread, + onClick, + content, + options, + onContextMenu, }) { const classes = ['room-selector']; if (isMuted) classes.push('room-selector--muted'); @@ -50,16 +54,26 @@ RoomSelectorWrapper.propTypes = { }; function RoomSelector({ - name, parentName, roomId, imageSrc, iconSrc, - isSelected, isMuted, isUnread, notificationCount, isAlert, - options, onClick, onContextMenu, + name, + parentName, + roomId, + imageSrc, + iconSrc, + isSelected, + isMuted, + isUnread, + notificationCount, + isAlert, + options, + onClick, + onContextMenu, }) { return ( - {twemojify(name)} + {name} {parentName && ( {' — '} - {twemojify(parentName)} + {parentName} )} - { isUnread && ( + {isUnread && ( )} - )} + } options={options} onClick={onClick} onContextMenu={onContextMenu} @@ -110,10 +124,7 @@ RoomSelector.propTypes = { isSelected: PropTypes.bool, isMuted: PropTypes.bool, isUnread: PropTypes.bool.isRequired, - notificationCount: PropTypes.oneOfType([ - PropTypes.string, - PropTypes.number, - ]).isRequired, + notificationCount: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired, isAlert: PropTypes.bool.isRequired, options: PropTypes.node, onClick: PropTypes.func.isRequired, diff --git a/src/app/molecules/room-tile/RoomTile.jsx b/src/app/molecules/room-tile/RoomTile.jsx index 95481ecec..2e0a63f60 100644 --- a/src/app/molecules/room-tile/RoomTile.jsx +++ b/src/app/molecules/room-tile/RoomTile.jsx @@ -2,46 +2,35 @@ import React from 'react'; import PropTypes from 'prop-types'; import './RoomTile.scss'; -import { twemojify } from '../../../util/twemojify'; - import colorMXID from '../../../util/colorMXID'; import Text from '../../atoms/text/Text'; import Avatar from '../../atoms/avatar/Avatar'; -function RoomTile({ - avatarSrc, name, id, - inviterName, memberCount, desc, options, -}) { +function RoomTile({ avatarSrc, name, id, inviterName, memberCount, desc, options }) { return (
      - +
      - {twemojify(name)} + {name} - { - inviterName !== null - ? `Invited by ${inviterName} to ${id}${memberCount === null ? '' : ` • ${memberCount} members`}` - : id + (memberCount === null ? '' : ` • ${memberCount} members`) - } + {inviterName !== null + ? `Invited by ${inviterName} to ${id}${ + memberCount === null ? '' : ` • ${memberCount} members` + }` + : id + (memberCount === null ? '' : ` • ${memberCount} members`)} - { - desc !== null && (typeof desc === 'string') - ? {twemojify(desc, undefined, true)} - : desc - } + {desc !== null && typeof desc === 'string' ? ( + + {desc} + + ) : ( + desc + )}
      - { options !== null && ( -
      - {options} -
      - )} + {options !== null &&
      {options}
      }
      ); } @@ -58,10 +47,7 @@ RoomTile.propTypes = { name: PropTypes.string.isRequired, id: PropTypes.string.isRequired, inviterName: PropTypes.string, - memberCount: PropTypes.oneOfType([ - PropTypes.string, - PropTypes.number, - ]), + memberCount: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), desc: PropTypes.node, options: PropTypes.node, }; diff --git a/src/app/molecules/sidebar-avatar/SidebarAvatar.jsx b/src/app/molecules/sidebar-avatar/SidebarAvatar.jsx deleted file mode 100644 index bc8b7c8f2..000000000 --- a/src/app/molecules/sidebar-avatar/SidebarAvatar.jsx +++ /dev/null @@ -1,55 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import './SidebarAvatar.scss'; - -import { twemojify } from '../../../util/twemojify'; - -import Text from '../../atoms/text/Text'; -import Tooltip from '../../atoms/tooltip/Tooltip'; -import { blurOnBubbling } from '../../atoms/button/script'; - -const SidebarAvatar = React.forwardRef(({ - className, tooltip, active, onClick, - onContextMenu, avatar, notificationBadge, -}, ref) => { - const classes = ['sidebar-avatar']; - if (active) classes.push('sidebar-avatar--active'); - if (className) classes.push(className); - return ( - {twemojify(tooltip)}} - placement="right" - > - - - ); -}); -SidebarAvatar.defaultProps = { - className: null, - active: false, - onClick: null, - onContextMenu: null, - notificationBadge: null, -}; - -SidebarAvatar.propTypes = { - className: PropTypes.string, - tooltip: PropTypes.string.isRequired, - active: PropTypes.bool, - onClick: PropTypes.func, - onContextMenu: PropTypes.func, - avatar: PropTypes.node.isRequired, - notificationBadge: PropTypes.node, -}; - -export default SidebarAvatar; diff --git a/src/app/molecules/sidebar-avatar/SidebarAvatar.scss b/src/app/molecules/sidebar-avatar/SidebarAvatar.scss deleted file mode 100644 index d76dbc86d..000000000 --- a/src/app/molecules/sidebar-avatar/SidebarAvatar.scss +++ /dev/null @@ -1,64 +0,0 @@ -@use '../../partials/dir'; - -.sidebar-avatar { - position: relative; - display: flex; - justify-content: center; - align-items: center; - cursor: pointer; - - & .notification-badge { - position: absolute; - @include dir.prop(left, unset, 0); - @include dir.prop(right, 0, unset); - top: 0; - box-shadow: 0 0 0 2px var(--bg-surface-low); - @include dir.prop(transform, translate(20%, -20%), translate(-20%, -20%)); - - margin: 0 !important; - } - & .avatar-container, - & .notification-badge { - transition: transform 200ms var(--fluid-push); - } - &:hover .avatar-container { - @include dir.prop(transform, translateX(4px), translateX(-4px)); - } - &:hover .notification-badge { - --ltr: translate(calc(20% + 4px), -20%); - --rtl: translate(calc(-20% - 4px), -20%); - @include dir.prop(transform, var(--ltr), var(--rtl)); - } - &:focus { - outline: none; - } - &:active .avatar-container { - box-shadow: var(--bs-surface-outline); - } - - &:hover::before, - &:focus::before, - &--active::before { - content: ""; - display: block; - position: absolute; - @include dir.prop(left, -11px, unset); - @include dir.prop(right, unset, -11px); - top: 50%; - transform: translateY(-50%); - - width: 3px; - height: 12px; - background-color: var(--tc-surface-high); - @include dir.prop(border-radius, 0 4px 4px 0, 4px 0 0 4px); - transition: height 200ms linear; - } - &--active:hover::before, - &--active:focus::before, - &--active::before { - height: 28px; - } - &--active .avatar-container { - background-color: var(--bg-surface); - } -} \ No newline at end of file diff --git a/src/app/molecules/space-add-existing/SpaceAddExisting.jsx b/src/app/molecules/space-add-existing/SpaceAddExisting.jsx index 547c0af5b..3895ac756 100644 --- a/src/app/molecules/space-add-existing/SpaceAddExisting.jsx +++ b/src/app/molecules/space-add-existing/SpaceAddExisting.jsx @@ -1,9 +1,8 @@ -import React, { useState, useEffect, useCallback } from 'react'; +import React, { useState, useEffect } from 'react'; import PropTypes from 'prop-types'; +import { useAtomValue } from 'jotai'; import './SpaceAddExisting.scss'; -import { twemojify } from '../../../util/twemojify'; - import initMatrix from '../../../client/initMatrix'; import cons from '../../../client/state/cons'; import navigation from '../../../client/state/navigation'; @@ -24,6 +23,9 @@ import CrossIC from '../../../../public/res/ic/outlined/cross.svg'; import SearchIC from '../../../../public/res/ic/outlined/search.svg'; import { useStore } from '../../hooks/useStore'; +import { roomToParentsAtom } from '../../state/room/roomToParents'; +import { useDirects, useRooms, useSpaces } from '../../state/hooks/roomList'; +import { allRoomsAtom } from '../../state/room-list/roomList'; function SpaceAddExistingContent({ roomId, spaces: onlySpaces }) { const mountStore = useStore(roomId); @@ -33,7 +35,10 @@ function SpaceAddExistingContent({ roomId, spaces: onlySpaces }) { const [selected, setSelected] = useState([]); const [searchIds, setSearchIds] = useState(null); const mx = initMatrix.matrixClient; - const { spaces, rooms, directs, roomIdToParents } = initMatrix.roomList; + const roomIdToParents = useAtomValue(roomToParentsAtom); + const spaces = useSpaces(mx, allRoomsAtom); + const rooms = useRooms(mx, allRoomsAtom); + const directs = useDirects(mx, allRoomsAtom); useEffect(() => { const roomIds = onlySpaces ? [...spaces] : [...rooms, ...directs]; @@ -217,7 +222,7 @@ function SpaceAddExisting() { className="space-add-existing" title={ - {room && twemojify(room.name)} + {room && room.name} {' '} — add existing {data?.spaces ? 'spaces' : 'rooms'} diff --git a/src/app/molecules/space-options/SpaceOptions.jsx b/src/app/molecules/space-options/SpaceOptions.jsx deleted file mode 100644 index 0c166c6a9..000000000 --- a/src/app/molecules/space-options/SpaceOptions.jsx +++ /dev/null @@ -1,128 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; - -import { twemojify } from '../../../util/twemojify'; - -import initMatrix from '../../../client/initMatrix'; -import { openSpaceSettings, openSpaceManage, openInviteUser } from '../../../client/action/navigation'; -import { markAsRead } from '../../../client/action/notifications'; -import { leave } from '../../../client/action/room'; -import { - createSpaceShortcut, - deleteSpaceShortcut, - categorizeSpace, - unCategorizeSpace, -} from '../../../client/action/accountData'; - -import { MenuHeader, MenuItem } from '../../atoms/context-menu/ContextMenu'; - -import CategoryIC from '../../../../public/res/ic/outlined/category.svg'; -import CategoryFilledIC from '../../../../public/res/ic/filled/category.svg'; -import TickMarkIC from '../../../../public/res/ic/outlined/tick-mark.svg'; -import AddUserIC from '../../../../public/res/ic/outlined/add-user.svg'; -import SettingsIC from '../../../../public/res/ic/outlined/settings.svg'; -import HashSearchIC from '../../../../public/res/ic/outlined/hash-search.svg'; -import LeaveArrowIC from '../../../../public/res/ic/outlined/leave-arrow.svg'; -import PinIC from '../../../../public/res/ic/outlined/pin.svg'; -import PinFilledIC from '../../../../public/res/ic/filled/pin.svg'; - -import { confirmDialog } from '../confirm-dialog/ConfirmDialog'; - -function SpaceOptions({ roomId, afterOptionSelect }) { - const mx = initMatrix.matrixClient; - const { roomList } = initMatrix; - const room = mx.getRoom(roomId); - const canInvite = room?.canInvite(mx.getUserId()); - const isPinned = initMatrix.accountData.spaceShortcut.has(roomId); - const isCategorized = initMatrix.accountData.categorizedSpaces.has(roomId); - - const handleMarkAsRead = () => { - const spaceChildren = roomList.getCategorizedSpaces([roomId]); - spaceChildren?.forEach((childIds) => { - childIds?.forEach((childId) => { - markAsRead(childId); - }); - }); - afterOptionSelect(); - }; - const handleInviteClick = () => { - openInviteUser(roomId); - afterOptionSelect(); - }; - const handlePinClick = () => { - if (isPinned) deleteSpaceShortcut(roomId); - else createSpaceShortcut(roomId); - afterOptionSelect(); - }; - const handleCategorizeClick = () => { - if (isCategorized) unCategorizeSpace(roomId); - else categorizeSpace(roomId); - afterOptionSelect(); - }; - const handleSettingsClick = () => { - openSpaceSettings(roomId); - afterOptionSelect(); - }; - const handleManageRoom = () => { - openSpaceManage(roomId); - afterOptionSelect(); - }; - - const handleLeaveClick = async () => { - afterOptionSelect(); - const isConfirmed = await confirmDialog( - 'Leave space', - `Are you sure that you want to leave "${room.name}" space?`, - 'Leave', - 'danger', - ); - if (!isConfirmed) return; - leave(roomId); - }; - - return ( -
      - {twemojify(`Options for ${initMatrix.matrixClient.getRoom(roomId)?.name}`)} - Mark as read - - {isCategorized ? 'Uncategorize subspaces' : 'Categorize subspaces'} - - - {isPinned ? 'Unpin from sidebar' : 'Pin to sidebar'} - - - Invite - - Manage rooms - Settings - - Leave - -
      - ); -} - -SpaceOptions.defaultProps = { - afterOptionSelect: null, -}; - -SpaceOptions.propTypes = { - roomId: PropTypes.string.isRequired, - afterOptionSelect: PropTypes.func, -}; - -export default SpaceOptions; diff --git a/src/app/molecules/sso-buttons/SSOButtons.jsx b/src/app/molecules/sso-buttons/SSOButtons.jsx deleted file mode 100644 index 0a653be91..000000000 --- a/src/app/molecules/sso-buttons/SSOButtons.jsx +++ /dev/null @@ -1,41 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import './SSOButtons.scss'; - -import { createTemporaryClient, startSsoLogin } from '../../../client/action/auth'; - -import Button from '../../atoms/button/Button'; - -function SSOButtons({ type, identityProviders, baseUrl }) { - const tempClient = createTemporaryClient(baseUrl); - function handleClick(id) { - startSsoLogin(baseUrl, type, id); - } - return ( -
      - {identityProviders - .sort((idp, idp2) => { - if (typeof idp.icon !== 'string') return -1; - return idp.name.toLowerCase() > idp2.name.toLowerCase() ? 1 : -1; - }) - .map((idp) => ( - idp.icon - ? ( - - ) : - ))} -
      - ); -} - -SSOButtons.propTypes = { - identityProviders: PropTypes.arrayOf( - PropTypes.shape({}), - ).isRequired, - baseUrl: PropTypes.string.isRequired, - type: PropTypes.oneOf(['sso', 'cas']).isRequired, -}; - -export default SSOButtons; diff --git a/src/app/molecules/sso-buttons/SSOButtons.scss b/src/app/molecules/sso-buttons/SSOButtons.scss deleted file mode 100644 index 065067042..000000000 --- a/src/app/molecules/sso-buttons/SSOButtons.scss +++ /dev/null @@ -1,25 +0,0 @@ -.sso-buttons { - display: flex; - justify-content: center; - flex-wrap: wrap; -} - -.sso-btn { - margin: var(--sp-tight); - display: inline-flex; - justify-content: center; - - cursor: pointer; - - &__img { - height: var(--av-small); - width: var(--av-small); - } - &__text-only { - margin-top: var(--sp-normal); - flex-basis: 100%; - & .text { - color: var(--tc-link); - } - } -} \ No newline at end of file diff --git a/src/app/organisms/create-room/CreateRoom.jsx b/src/app/organisms/create-room/CreateRoom.jsx index 15be02d29..ff00cca19 100644 --- a/src/app/organisms/create-room/CreateRoom.jsx +++ b/src/app/organisms/create-room/CreateRoom.jsx @@ -2,11 +2,10 @@ import React, { useState, useEffect, useRef } from 'react'; import PropTypes from 'prop-types'; import './CreateRoom.scss'; -import { twemojify } from '../../../util/twemojify'; import initMatrix from '../../../client/initMatrix'; import cons from '../../../client/state/cons'; import navigation from '../../../client/state/navigation'; -import { selectRoom, openReusableContextMenu } from '../../../client/action/navigation'; +import { openReusableContextMenu } from '../../../client/action/navigation'; import * as roomActions from '../../../client/action/room'; import { isRoomAliasAvailable, getIdServer } from '../../../util/matrixUtil'; import { getEventCords } from '../../../util/common'; @@ -32,12 +31,14 @@ import SpaceLockIC from '../../../../public/res/ic/outlined/space-lock.svg'; import SpaceGlobeIC from '../../../../public/res/ic/outlined/space-globe.svg'; import ChevronBottomIC from '../../../../public/res/ic/outlined/chevron-bottom.svg'; import CrossIC from '../../../../public/res/ic/outlined/cross.svg'; +import { useRoomNavigate } from '../../hooks/useRoomNavigate'; function CreateRoomContent({ isSpace, parentId, onRequestClose }) { const [joinRule, setJoinRule] = useState(parentId ? 'restricted' : 'invite'); const [isEncrypted, setIsEncrypted] = useState(true); const [isCreatingRoom, setIsCreatingRoom] = useState(false); const [creatingError, setCreatingError] = useState(null); + const { navigateRoom, navigateSpace } = useRoomNavigate(); const [isValidAddress, setIsValidAddress] = useState(null); const [addressValue, setAddressValue] = useState(undefined); @@ -48,25 +49,6 @@ function CreateRoomContent({ isSpace, parentId, onRequestClose }) { const mx = initMatrix.matrixClient; const userHs = getIdServer(mx.getUserId()); - useEffect(() => { - const { roomList } = initMatrix; - const onCreated = (roomId) => { - setIsCreatingRoom(false); - setCreatingError(null); - setIsValidAddress(null); - setAddressValue(undefined); - - if (!mx.getRoom(roomId)?.isSpaceRoom()) { - selectRoom(roomId); - } - onRequestClose(); - }; - roomList.on(cons.events.roomList.ROOM_CREATED, onCreated); - return () => { - roomList.removeListener(cons.events.roomList.ROOM_CREATED, onCreated); - }; - }, []); - const handleSubmit = async (evt) => { evt.preventDefault(); const { target } = evt; @@ -87,16 +69,26 @@ function CreateRoomContent({ isSpace, parentId, onRequestClose }) { const powerLevel = roleIndex === 1 ? 101 : undefined; try { - await roomActions.createRoom({ + const data = await roomActions.createRoom({ name, topic, joinRule, alias: roomAlias, - isEncrypted: (isSpace || joinRule === 'public') ? false : isEncrypted, + isEncrypted: isSpace || joinRule === 'public' ? false : isEncrypted, powerLevel, isSpace, parentId, }); + setIsCreatingRoom(false); + setCreatingError(null); + setIsValidAddress(null); + setAddressValue(undefined); + onRequestClose(); + if (isSpace) { + navigateSpace(data.room_id); + } else { + navigateRoom(data.room_id); + } } catch (e) { if (e.message === 'M_UNKNOWN: Invalid characters in room alias') { setCreatingError('ERROR: Invalid characters in address'); @@ -131,36 +123,35 @@ function CreateRoomContent({ isSpace, parentId, onRequestClose }) { const joinRules = ['invite', 'restricted', 'public']; const joinRuleShortText = ['Private', 'Restricted', 'Public']; - const joinRuleText = ['Private (invite only)', 'Restricted (space member can join)', 'Public (anyone can join)']; + const joinRuleText = [ + 'Private (invite only)', + 'Restricted (space member can join)', + 'Public (anyone can join)', + ]; const jrRoomIC = [HashLockIC, HashIC, HashGlobeIC]; const jrSpaceIC = [SpaceLockIC, SpaceIC, SpaceGlobeIC]; const handleJoinRule = (evt) => { - openReusableContextMenu( - 'bottom', - getEventCords(evt, '.btn-surface'), - (closeMenu) => ( - <> - Visibility (who can join) - { - joinRules.map((rule) => ( - { closeMenu(); setJoinRule(rule); }} - disabled={!parentId && rule === 'restricted'} - > - { joinRuleText[joinRules.indexOf(rule)] } - - )) - } - - ), - ); + openReusableContextMenu('bottom', getEventCords(evt, '.btn-surface'), (closeMenu) => ( + <> + Visibility (who can join) + {joinRules.map((rule) => ( + { + closeMenu(); + setJoinRule(rule); + }} + disabled={!parentId && rule === 'restricted'} + > + {joinRuleText[joinRules.indexOf(rule)]} + + ))} + + )); }; return ( @@ -168,50 +159,64 @@ function CreateRoomContent({ isSpace, parentId, onRequestClose }) {
      {joinRuleShortText[joinRules.indexOf(joinRule)]} - )} - content={{`Select who can join this ${isSpace ? 'space' : 'room'}.`}} + } + content={ + {`Select who can join this ${isSpace ? 'space' : 'room'}.`} + } /> {joinRule === 'public' && (
      - {isSpace ? 'Space address' : 'Room address'} + + {isSpace ? 'Space address' : 'Room address'} +
      # {`:${userHs}`}
      - {isValidAddress === false && {`#${addressValue}:${userHs} is already in use`}} + {isValidAddress === false && ( + + {`#${addressValue}:${userHs} is already in use`} + + )}
      )} {!isSpace && joinRule !== 'public' && ( } - content={You can’t disable this later. Bridges & most bots won’t work yet.} + content={ + + You can’t disable this later. Bridges & most bots won’t work yet. + + } /> )} - )} - content={( + } + content={ Selecting Admin sets 100 power level whereas Founder sets 101. - )} + } />
      @@ -231,7 +236,11 @@ function CreateRoomContent({ isSpace, parentId, onRequestClose }) { {`Creating ${isSpace ? 'space' : 'room'}...`}
      )} - {typeof creatingError === 'string' && {creatingError}} + {typeof creatingError === 'string' && ( + + {creatingError} + + )}
      ); @@ -275,27 +284,22 @@ function CreateRoom() { return ( - {parentId ? twemojify(room.name) : 'Home'} + {parentId ? room.name : 'Home'} {` — create ${isSpace ? 'space' : 'room'}`} - )} + } contentOptions={} onRequestClose={onRequestClose} > - { - create - ? ( - - ) :
      - } + {create ? ( + + ) : ( +
      + )}
      ); } diff --git a/src/app/organisms/emoji-board/EmojiBoard.jsx b/src/app/organisms/emoji-board/EmojiBoard.jsx deleted file mode 100644 index 84c413064..000000000 --- a/src/app/organisms/emoji-board/EmojiBoard.jsx +++ /dev/null @@ -1,356 +0,0 @@ -/* eslint-disable jsx-a11y/no-static-element-interactions */ -/* eslint-disable jsx-a11y/click-events-have-key-events */ -import React, { useState, useEffect, useRef } from 'react'; -import PropTypes from 'prop-types'; -import './EmojiBoard.scss'; - -import parse from 'html-react-parser'; -import twemoji from 'twemoji'; -import { emojiGroups, emojis } from './emoji'; -import { getRelevantPacks } from './custom-emoji'; -import initMatrix from '../../../client/initMatrix'; -import cons from '../../../client/state/cons'; -import navigation from '../../../client/state/navigation'; -import AsyncSearch from '../../../util/AsyncSearch'; -import { addRecentEmoji, getRecentEmojis } from './recent'; -import { TWEMOJI_BASE_URL } from '../../../util/twemojify'; - -import Text from '../../atoms/text/Text'; -import RawIcon from '../../atoms/system-icons/RawIcon'; -import IconButton from '../../atoms/button/IconButton'; -import Input from '../../atoms/input/Input'; -import ScrollView from '../../atoms/scroll/ScrollView'; - -import SearchIC from '../../../../public/res/ic/outlined/search.svg'; -import RecentClockIC from '../../../../public/res/ic/outlined/recent-clock.svg'; -import EmojiIC from '../../../../public/res/ic/outlined/emoji.svg'; -import DogIC from '../../../../public/res/ic/outlined/dog.svg'; -import CupIC from '../../../../public/res/ic/outlined/cup.svg'; -import BallIC from '../../../../public/res/ic/outlined/ball.svg'; -import PhotoIC from '../../../../public/res/ic/outlined/photo.svg'; -import BulbIC from '../../../../public/res/ic/outlined/bulb.svg'; -import PeaceIC from '../../../../public/res/ic/outlined/peace.svg'; -import FlagIC from '../../../../public/res/ic/outlined/flag.svg'; - -const ROW_EMOJIS_COUNT = 7; - -const EmojiGroup = React.memo(({ name, groupEmojis }) => { - function getEmojiBoard() { - const emojiBoard = []; - const totalEmojis = groupEmojis.length; - - for (let r = 0; r < totalEmojis; r += ROW_EMOJIS_COUNT) { - const emojiRow = []; - for (let c = r; c < r + ROW_EMOJIS_COUNT; c += 1) { - const emojiIndex = c; - if (emojiIndex >= totalEmojis) break; - const emoji = groupEmojis[emojiIndex]; - emojiRow.push( - - {emoji.hexcode ? ( - // This is a unicode emoji, and should be rendered with twemoji - parse( - twemoji.parse(emoji.unicode, { - attributes: () => ({ - unicode: emoji.unicode, - shortcodes: emoji.shortcodes?.toString(), - hexcode: emoji.hexcode, - loading: 'lazy', - }), - base: TWEMOJI_BASE_URL, - }) - ) - ) : ( - // This is a custom emoji, and should be render as an mxc - {emoji.shortcode} - )} - - ); - } - emojiBoard.push( -
      - {emojiRow} -
      - ); - } - return emojiBoard; - } - - return ( -
      - - {name} - - {groupEmojis.length !== 0 &&
      {getEmojiBoard()}
      } -
      - ); -}); - -EmojiGroup.propTypes = { - name: PropTypes.string.isRequired, - groupEmojis: PropTypes.arrayOf( - PropTypes.shape({ - length: PropTypes.number, - unicode: PropTypes.string, - hexcode: PropTypes.string, - mxc: PropTypes.string, - shortcode: PropTypes.string, - shortcodes: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.string)]), - }) - ).isRequired, -}; - -const asyncSearch = new AsyncSearch(); -asyncSearch.setup(emojis, { keys: ['shortcode'], isContain: true, limit: 40 }); -function SearchedEmoji() { - const [searchedEmojis, setSearchedEmojis] = useState(null); - - function handleSearchEmoji(resultEmojis, term) { - if (term === '' || resultEmojis.length === 0) { - if (term === '') setSearchedEmojis(null); - else setSearchedEmojis({ emojis: [] }); - return; - } - setSearchedEmojis({ emojis: resultEmojis }); - } - - useEffect(() => { - asyncSearch.on(asyncSearch.RESULT_SENT, handleSearchEmoji); - return () => { - asyncSearch.removeListener(asyncSearch.RESULT_SENT, handleSearchEmoji); - }; - }, []); - - if (searchedEmojis === null) return false; - - return ( - - ); -} - -function EmojiBoard({ onSelect, searchRef }) { - const scrollEmojisRef = useRef(null); - const emojiInfo = useRef(null); - - function isTargetNotEmoji(target) { - return target.classList.contains('emoji') === false; - } - function getEmojiDataFromTarget(target) { - const unicode = target.getAttribute('unicode'); - const hexcode = target.getAttribute('hexcode'); - const mxc = target.getAttribute('data-mx-emoticon'); - let shortcodes = target.getAttribute('shortcodes'); - if (typeof shortcodes === 'undefined') shortcodes = undefined; - else shortcodes = shortcodes.split(','); - return { - unicode, - hexcode, - shortcodes, - mxc, - }; - } - - function selectEmoji(e) { - if (isTargetNotEmoji(e.target)) return; - - const emoji = getEmojiDataFromTarget(e.target); - onSelect(emoji); - if (emoji.hexcode) addRecentEmoji(emoji.unicode); - } - - function setEmojiInfo(emoji) { - const infoEmoji = emojiInfo.current.firstElementChild.firstElementChild; - const infoShortcode = emojiInfo.current.lastElementChild; - - infoEmoji.src = emoji.src; - infoEmoji.alt = emoji.unicode; - infoShortcode.textContent = `:${emoji.shortcode}:`; - } - - function hoverEmoji(e) { - if (isTargetNotEmoji(e.target)) return; - - const emoji = e.target; - const { shortcodes, unicode } = getEmojiDataFromTarget(emoji); - const { src } = e.target; - - if (typeof shortcodes === 'undefined') { - searchRef.current.placeholder = 'Search'; - setEmojiInfo({ - unicode: '🙂', - shortcode: 'slight_smile', - src: 'https://twemoji.maxcdn.com/v/13.1.0/72x72/1f642.png', - }); - return; - } - if (searchRef.current.placeholder === shortcodes[0]) return; - searchRef.current.setAttribute('placeholder', shortcodes[0]); - setEmojiInfo({ shortcode: shortcodes[0], src, unicode }); - } - - function handleSearchChange() { - const term = searchRef.current.value; - asyncSearch.search(term); - scrollEmojisRef.current.scrollTop = 0; - } - - const [availableEmojis, setAvailableEmojis] = useState([]); - const [recentEmojis, setRecentEmojis] = useState([]); - - const recentOffset = recentEmojis.length > 0 ? 1 : 0; - - useEffect(() => { - const updateAvailableEmoji = (selectedRoomId) => { - if (!selectedRoomId) { - setAvailableEmojis([]); - return; - } - - const mx = initMatrix.matrixClient; - const room = mx.getRoom(selectedRoomId); - const parentIds = initMatrix.roomList.getAllParentSpaces(room.roomId); - const parentRooms = [...parentIds].map((id) => mx.getRoom(id)); - if (room) { - const packs = getRelevantPacks(room.client, [room, ...parentRooms]).filter( - (pack) => pack.getEmojis().length !== 0 - ); - - // Set an index for each pack so that we know where to jump when the user uses the nav - for (let i = 0; i < packs.length; i += 1) { - packs[i].packIndex = i; - } - setAvailableEmojis(packs); - } - }; - - const onOpen = () => { - searchRef.current.value = ''; - handleSearchChange(); - - // only update when board is getting opened to prevent shifting UI - setRecentEmojis(getRecentEmojis(3 * ROW_EMOJIS_COUNT)); - }; - - navigation.on(cons.events.navigation.ROOM_SELECTED, updateAvailableEmoji); - navigation.on(cons.events.navigation.EMOJIBOARD_OPENED, onOpen); - return () => { - navigation.removeListener(cons.events.navigation.ROOM_SELECTED, updateAvailableEmoji); - navigation.removeListener(cons.events.navigation.EMOJIBOARD_OPENED, onOpen); - }; - }, []); - - function openGroup(groupOrder) { - let tabIndex = groupOrder; - const $emojiContent = scrollEmojisRef.current.firstElementChild; - const groupCount = $emojiContent.childElementCount; - if (groupCount > emojiGroups.length) { - tabIndex += groupCount - emojiGroups.length - availableEmojis.length - recentOffset; - } - $emojiContent.children[tabIndex].scrollIntoView(); - } - - return ( -
      - -
      - {recentEmojis.length > 0 && ( - openGroup(0)} - src={RecentClockIC} - tooltip="Recent" - tooltipPlacement="left" - /> - )} -
      - {availableEmojis.map((pack) => { - const src = initMatrix.matrixClient.mxcUrlToHttp( - pack.avatarUrl ?? pack.getEmojis()[0].mxc - ); - return ( - openGroup(recentOffset + pack.packIndex)} - src={src} - key={pack.packIndex} - tooltip={pack.displayName ?? 'Unknown'} - tooltipPlacement="left" - isImage - /> - ); - })} -
      -
      - {[ - [0, EmojiIC, 'Smilies'], - [1, DogIC, 'Animals'], - [2, CupIC, 'Food'], - [3, BallIC, 'Activities'], - [4, PhotoIC, 'Travel'], - [5, BulbIC, 'Objects'], - [6, PeaceIC, 'Symbols'], - [7, FlagIC, 'Flags'], - ].map(([indx, ico, name]) => ( - openGroup(recentOffset + availableEmojis.length + indx)} - key={indx} - src={ico} - tooltip={name} - tooltipPlacement="left" - /> - ))} -
      -
      -
      -
      -
      - - -
      -
      - -
      - - {recentEmojis.length > 0 && ( - - )} - {availableEmojis.map((pack) => ( - - ))} - {emojiGroups.map((group) => ( - - ))} -
      -
      -
      -
      -
      {parse(twemoji.parse('🙂', { base: TWEMOJI_BASE_URL }))}
      - :slight_smile: -
      -
      -
      - ); -} - -EmojiBoard.propTypes = { - onSelect: PropTypes.func.isRequired, - searchRef: PropTypes.shape({}).isRequired, -}; - -export default EmojiBoard; diff --git a/src/app/organisms/emoji-board/EmojiBoard.scss b/src/app/organisms/emoji-board/EmojiBoard.scss deleted file mode 100644 index 683026f0e..000000000 --- a/src/app/organisms/emoji-board/EmojiBoard.scss +++ /dev/null @@ -1,137 +0,0 @@ -@use '../../partials/flex'; -@use '../../partials/text'; -@use '../../partials/dir'; - -.emoji-board { - --emoji-board-height: 390px; - --emoji-board-width: 286px; - display: flex; - max-width: 90vw; - max-height: 90vh; - - &__content { - @extend .cp-fx__item-one; - @extend .cp-fx__column; - height: var(--emoji-board-height); - width: var(--emoji-board-width); - } - & > .scrollbar { - width: initial; - height: var(--emoji-board-height); - } - &__nav { - @extend .cp-fx__column; - justify-content: center; - - min-height: 100%; - padding: 4px 6px; - @include dir.side(border, none, 1px solid var(--bg-surface-border)); - - position: relative; - - & .ic-btn-surface { - opacity: 0.8; - } - } - &__nav-custom, - &__nav-twemoji { - @extend .cp-fx__column; - } - &__nav-twemoji { - background-color: var(--bg-surface); - position: sticky; - bottom: -70%; - z-index: 999; - } -} - -.emoji-board__content__search { - padding: var(--sp-extra-tight); - position: relative; - - & .ic-raw { - position: absolute; - @include dir.prop(left, var(--sp-normal), unset); - @include dir.prop(right, unset, var(--sp-normal)); - top: var(--sp-normal); - transform: translateY(1px); - } - - & .input-container { - & .input { - min-width: 100%; - width: 0; - padding: var(--sp-extra-tight) 36px; - border-radius: calc(var(--bo-radius) / 2); - } - } -} -.emoji-board__content__emojis { - @extend .cp-fx__item-one; - @extend .cp-fx__column; -} -.emoji-board__content__info { - margin: 0 var(--sp-extra-tight); - padding: var(--sp-tight) var(--sp-extra-tight); - border-top: 1px solid var(--bg-surface-border); - - display: flex; - align-items: center; - - & > div:first-child { - line-height: 0; - .emoji { - width: 32px; - height: 32px; - object-fit: contain; - } - } - & > p:last-child { - @extend .cp-fx__item-one; - @extend .cp-txt__ellipsis; - margin: 0 var(--sp-tight); - } -} - -.emoji-row { - display: flex; -} - -.emoji-group { - --emoji-padding: 6px; - position: relative; - margin-bottom: var(--sp-normal); - - &__header { - position: sticky; - top: 0; - z-index: 99; - background-color: var(--bg-surface); - - @include dir.side(margin, var(--sp-extra-tight), 0); - padding: var(--sp-extra-tight) var(--sp-ultra-tight); - text-transform: uppercase; - box-shadow: 0 -4px 0 0 var(--bg-surface); - border-bottom: 1px solid var(--bg-surface-border); - } - & .emoji-set { - --left-margin: calc(var(--sp-normal) - var(--emoji-padding)); - --right-margin: calc(var(--sp-extra-tight) - var(--emoji-padding)); - margin: var(--sp-extra-tight); - @include dir.side(margin, var(--left-margin), var(--right-margin)); - } - & .emoji { - max-width: 38px; - max-height: 38px; - width: 100%; - height: 100%; - overflow: hidden; - object-fit: contain; - padding: var(--emoji-padding); - cursor: pointer; - &:hover { - background-color: var(--bg-surface-hover); - border-radius: var(--bo-radius); - } - } -} \ No newline at end of file diff --git a/src/app/organisms/emoji-board/EmojiBoardOpener.jsx b/src/app/organisms/emoji-board/EmojiBoardOpener.jsx deleted file mode 100644 index 32b7a8370..000000000 --- a/src/app/organisms/emoji-board/EmojiBoardOpener.jsx +++ /dev/null @@ -1,78 +0,0 @@ -import React, { useEffect, useRef } from 'react'; - -import cons from '../../../client/state/cons'; -import navigation from '../../../client/state/navigation'; -import settings from '../../../client/state/settings'; - -import ContextMenu from '../../atoms/context-menu/ContextMenu'; -import EmojiBoard from './EmojiBoard'; - -let requestCallback = null; -let isEmojiBoardVisible = false; -function EmojiBoardOpener() { - const openerRef = useRef(null); - const searchRef = useRef(null); - - function openEmojiBoard(cords, requestEmojiCallback) { - if (requestCallback !== null || isEmojiBoardVisible) { - requestCallback = null; - if (cords.detail === 0) openerRef.current.click(); - return; - } - - openerRef.current.style.transform = `translate(${cords.x}px, ${cords.y}px)`; - requestCallback = requestEmojiCallback; - openerRef.current.click(); - } - - function afterEmojiBoardToggle(isVisible) { - isEmojiBoardVisible = isVisible; - if (isVisible) { - if (!settings.isTouchScreenDevice) searchRef.current.focus(); - } else { - setTimeout(() => { - if (!isEmojiBoardVisible) requestCallback = null; - }, 500); - } - } - - function addEmoji(emoji) { - requestCallback(emoji); - } - - useEffect(() => { - navigation.on(cons.events.navigation.EMOJIBOARD_OPENED, openEmojiBoard); - return () => { - navigation.removeListener(cons.events.navigation.EMOJIBOARD_OPENED, openEmojiBoard); - }; - }, []); - - return ( - - )} - afterToggle={afterEmojiBoardToggle} - render={(toggleMenu) => ( - - )} - /> - ); -} - -export default EmojiBoardOpener; diff --git a/src/app/organisms/emoji-board/custom-emoji.js b/src/app/organisms/emoji-board/custom-emoji.js index 09b605228..4ca2088f7 100644 --- a/src/app/organisms/emoji-board/custom-emoji.js +++ b/src/app/organisms/emoji-board/custom-emoji.js @@ -1,8 +1,6 @@ -import { emojis } from './emoji'; - // https://github.com/Sorunome/matrix-doc/blob/soru/emotes/proposals/2545-emotes.md -class ImagePack { +export class ImagePack { static parsePack(eventId, packContent) { if (!eventId || typeof packContent?.images !== 'object') { return null; @@ -141,127 +139,4 @@ class ImagePack { } } -function getGlobalImagePacks(mx) { - const globalContent = mx.getAccountData('im.ponies.emote_rooms')?.getContent(); - if (typeof globalContent !== 'object') return []; - const { rooms } = globalContent; - if (typeof rooms !== 'object') return []; - - const roomIds = Object.keys(rooms); - - const packs = roomIds.flatMap((roomId) => { - if (typeof rooms[roomId] !== 'object') return []; - const room = mx.getRoom(roomId); - if (!room) return []; - const stateKeys = Object.keys(rooms[roomId]); - - return stateKeys.map((stateKey) => { - const data = room.currentState.getStateEvents('im.ponies.room_emotes', stateKey); - const pack = ImagePack.parsePack(data?.getId(), data?.getContent()); - if (pack) { - pack.displayName ??= room.name; - pack.avatarUrl ??= room.getMxcAvatarUrl(); - } - return pack; - }).filter((pack) => pack !== null); - }); - - return packs; -} - -function getUserImagePack(mx) { - const accountDataEmoji = mx.getAccountData('im.ponies.user_emotes'); - if (!accountDataEmoji) { - return null; - } - - const userImagePack = ImagePack.parsePack(mx.getUserId(), accountDataEmoji.event.content); - if (userImagePack) userImagePack.displayName ??= 'Personal Emoji'; - return userImagePack; -} - -function getRoomImagePacks(room) { - const dataEvents = room.currentState.getStateEvents('im.ponies.room_emotes'); - - return dataEvents - .map((data) => { - const pack = ImagePack.parsePack(data?.getId(), data?.getContent()); - if (pack) { - pack.displayName ??= room.name; - pack.avatarUrl ??= room.getMxcAvatarUrl(); - } - return pack; - }) - .filter((pack) => pack !== null); -} - -/** - * @param {MatrixClient} mx Provide if you want to include user personal/global pack - * @param {Room[]} rooms Provide rooms if you want to include rooms pack - * @returns {ImagePack[]} packs - */ -function getRelevantPacks(mx, rooms) { - const userPack = mx ? getUserImagePack(mx) : []; - const globalPacks = mx ? getGlobalImagePacks(mx) : []; - const globalPackIds = new Set(globalPacks.map((pack) => pack.id)); - const roomsPack = rooms?.flatMap(getRoomImagePacks) ?? []; - - return [].concat( - userPack ?? [], - globalPacks, - roomsPack.filter((pack) => !globalPackIds.has(pack.id)), - ); -} - -function getShortcodeToEmoji(mx, rooms) { - const allEmoji = new Map(); - - emojis.forEach((emoji) => { - if (Array.isArray(emoji.shortcodes)) { - emoji.shortcodes.forEach((shortcode) => { - allEmoji.set(shortcode, emoji); - }); - } else { - allEmoji.set(emoji.shortcodes, emoji); - } - }); - - getRelevantPacks(mx, rooms) - .flatMap((pack) => pack.getEmojis()) - .forEach((emoji) => { - allEmoji.set(emoji.shortcode, emoji); - }); - - return allEmoji; -} - -function getShortcodeToCustomEmoji(room) { - const allEmoji = new Map(); - - getRelevantPacks(room.client, [room]) - .flatMap((pack) => pack.getEmojis()) - .forEach((emoji) => { - allEmoji.set(emoji.shortcode, emoji); - }); - - return allEmoji; -} - -function getEmojiForCompletion(mx, rooms) { - const allEmoji = new Map(); - getRelevantPacks(mx, rooms) - .flatMap((pack) => pack.getEmojis()) - .forEach((emoji) => { - allEmoji.set(emoji.shortcode, emoji); - }); - - return Array.from(allEmoji.values()).concat(emojis.filter((e) => !allEmoji.has(e.shortcode))); -} - -export { - ImagePack, - getUserImagePack, getGlobalImagePacks, getRoomImagePacks, - getShortcodeToEmoji, getShortcodeToCustomEmoji, - getRelevantPacks, getEmojiForCompletion, -}; diff --git a/src/app/organisms/emoji-board/emoji.js b/src/app/organisms/emoji-board/emoji.js deleted file mode 100644 index 3cbd0b881..000000000 --- a/src/app/organisms/emoji-board/emoji.js +++ /dev/null @@ -1,69 +0,0 @@ -import emojisData from 'emojibase-data/en/compact.json'; -import joypixels from 'emojibase-data/en/shortcodes/joypixels.json'; -import emojibase from 'emojibase-data/en/shortcodes/emojibase.json'; - -const emojiGroups = [{ - name: 'Smileys & people', - order: 0, - emojis: [], -}, { - name: 'Animals & nature', - order: 1, - emojis: [], -}, { - name: 'Food & drinks', - order: 2, - emojis: [], -}, { - name: 'Activity', - order: 3, - emojis: [], -}, { - name: 'Travel & places', - order: 4, - emojis: [], -}, { - name: 'Objects', - order: 5, - emojis: [], -}, { - name: 'Symbols', - order: 6, - emojis: [], -}, { - name: 'Flags', - order: 7, - emojis: [], -}]; -Object.freeze(emojiGroups); - -function addEmoji(emoji, order) { - emojiGroups[order].emojis.push(emoji); -} -function addToGroup(emoji) { - if (emoji.group === 0 || emoji.group === 1) addEmoji(emoji, 0); - else if (emoji.group === 3) addEmoji(emoji, 1); - else if (emoji.group === 4) addEmoji(emoji, 2); - else if (emoji.group === 6) addEmoji(emoji, 3); - else if (emoji.group === 5) addEmoji(emoji, 4); - else if (emoji.group === 7) addEmoji(emoji, 5); - else if (emoji.group === 8 || typeof emoji.group === 'undefined') addEmoji(emoji, 6); - else if (emoji.group === 9) addEmoji(emoji, 7); -} - -const emojis = []; -emojisData.forEach((emoji) => { - const myShortCodes = joypixels[emoji.hexcode] || emojibase[emoji.hexcode]; - if (!myShortCodes) return; - const em = { - ...emoji, - shortcode: Array.isArray(myShortCodes) ? myShortCodes[0] : myShortCodes, - shortcodes: myShortCodes, - }; - addToGroup(em); - emojis.push(em); -}); - -export { - emojis, emojiGroups, -}; diff --git a/src/app/organisms/emoji-board/recent.js b/src/app/organisms/emoji-board/recent.js deleted file mode 100644 index dff67fb0b..000000000 --- a/src/app/organisms/emoji-board/recent.js +++ /dev/null @@ -1,36 +0,0 @@ -import initMatrix from '../../../client/initMatrix'; -import { emojis } from './emoji'; - -const eventType = 'io.element.recent_emoji'; - -function getRecentEmojisRaw() { - return initMatrix.matrixClient.getAccountData(eventType)?.getContent().recent_emoji ?? []; -} - -export function getRecentEmojis(limit) { - const res = []; - getRecentEmojisRaw() - .sort((a, b) => b[1] - a[1]) - .find(([unicode]) => { - const emoji = emojis.find((e) => e.unicode === unicode); - if (emoji) return res.push(emoji) >= limit; - return false; - }); - return res; -} - -export function addRecentEmoji(unicode) { - const recent = getRecentEmojisRaw(); - const i = recent.findIndex(([u]) => u === unicode); - let entry; - if (i < 0) { - entry = [unicode, 1]; - } else { - [entry] = recent.splice(i, 1); - entry[1] += 1; - } - recent.unshift(entry); - initMatrix.matrixClient.setAccountData(eventType, { - recent_emoji: recent.slice(0, 100), - }); -} diff --git a/src/app/organisms/emoji-verification/EmojiVerification.jsx b/src/app/organisms/emoji-verification/EmojiVerification.jsx index 3ae1f2948..1b543c052 100644 --- a/src/app/organisms/emoji-verification/EmojiVerification.jsx +++ b/src/app/organisms/emoji-verification/EmojiVerification.jsx @@ -2,7 +2,6 @@ import React, { useState, useEffect } from 'react'; import PropTypes from 'prop-types'; import './EmojiVerification.scss'; -import { twemojify } from '../../../util/twemojify'; import initMatrix from '../../../client/initMatrix'; import cons from '../../../client/state/cons'; @@ -30,8 +29,9 @@ function EmojiVerificationContent({ data, requestClose }) { const beginVerification = async () => { if ( - isCrossVerified(mx.deviceId) - && (mx.getCrossSigningId() === null || await mx.crypto.crossSigningInfo.isStoredInKeyCache('self_signing') === false) + isCrossVerified(mx.deviceId) && + (mx.getCrossSigningId() === null || + (await mx.crypto.crossSigningInfo.isStoredInKeyCache('self_signing')) === false) ) { if (!hasPrivateKey(getDefaultSSKey())) { const keyData = await accessSecretStorage('Emoji verification'); @@ -106,16 +106,20 @@ function EmojiVerificationContent({ data, requestClose }) { {sas.sas.emoji.map((emoji, i) => ( // eslint-disable-next-line react/no-array-index-key
      - {twemojify(emoji[0])} + {emoji[0]} {emoji[1]}
      ))}
      - {process ? renderWait() : ( + {process ? ( + renderWait() + ) : ( <> - - + + )}
      @@ -127,9 +131,7 @@ function EmojiVerificationContent({ data, requestClose }) { return (
      Please accept the request from other device. -
      - {renderWait()} -
      +
      {renderWait()}
      ); } @@ -138,11 +140,13 @@ function EmojiVerificationContent({ data, requestClose }) {
      Click accept to start the verification process.
      - { - process - ? renderWait() - : - } + {process ? ( + renderWait() + ) : ( + + )}
      ); @@ -180,19 +184,19 @@ function EmojiVerification() { Emoji verification - )} + } contentOptions={} onRequestClose={requestClose} > - { - data !== null - ? - :
      - } + {data !== null ? ( + + ) : ( +
      + )}
      ); } diff --git a/src/app/organisms/invite-list/InviteList.jsx b/src/app/organisms/invite-list/InviteList.jsx deleted file mode 100644 index 231928fee..000000000 --- a/src/app/organisms/invite-list/InviteList.jsx +++ /dev/null @@ -1,145 +0,0 @@ -import React, { useState, useEffect } from 'react'; -import PropTypes from 'prop-types'; -import './InviteList.scss'; - -import initMatrix from '../../../client/initMatrix'; -import cons from '../../../client/state/cons'; -import * as roomActions from '../../../client/action/room'; -import { selectRoom, selectTab } from '../../../client/action/navigation'; - -import Text from '../../atoms/text/Text'; -import Button from '../../atoms/button/Button'; -import IconButton from '../../atoms/button/IconButton'; -import Spinner from '../../atoms/spinner/Spinner'; -import PopupWindow from '../../molecules/popup-window/PopupWindow'; -import RoomTile from '../../molecules/room-tile/RoomTile'; - -import CrossIC from '../../../../public/res/ic/outlined/cross.svg'; - -function InviteList({ isOpen, onRequestClose }) { - const [procInvite, changeProcInvite] = useState(new Set()); - - function acceptInvite(roomId, isDM) { - procInvite.add(roomId); - changeProcInvite(new Set(Array.from(procInvite))); - roomActions.join(roomId, isDM); - } - function rejectInvite(roomId, isDM) { - procInvite.add(roomId); - changeProcInvite(new Set(Array.from(procInvite))); - roomActions.leave(roomId, isDM); - } - function updateInviteList(roomId) { - if (procInvite.has(roomId)) procInvite.delete(roomId); - changeProcInvite(new Set(Array.from(procInvite))); - - const rl = initMatrix.roomList; - const totalInvites = rl.inviteDirects.size + rl.inviteRooms.size + rl.inviteSpaces.size; - const room = initMatrix.matrixClient.getRoom(roomId); - const isRejected = room === null || room?.getMyMembership() !== 'join'; - if (!isRejected) { - if (room.isSpaceRoom()) selectTab(roomId); - else selectRoom(roomId); - onRequestClose(); - } - if (totalInvites === 0) onRequestClose(); - } - - useEffect(() => { - initMatrix.roomList.on(cons.events.roomList.INVITELIST_UPDATED, updateInviteList); - - return () => { - initMatrix.roomList.removeListener(cons.events.roomList.INVITELIST_UPDATED, updateInviteList); - }; - }, [procInvite]); - - function renderRoomTile(roomId) { - const mx = initMatrix.matrixClient; - const myRoom = mx.getRoom(roomId); - if (!myRoom) return null; - const roomName = myRoom.name; - let roomAlias = myRoom.getCanonicalAlias(); - if (!roomAlias) roomAlias = myRoom.roomId; - const inviterName = myRoom.getMember(mx.getUserId())?.events?.member?.getSender?.() ?? ''; - return ( - ) - : ( -
      - - -
      - ) - } - /> - ); - } - - return ( - } - onRequestClose={onRequestClose} - > -
      - { initMatrix.roomList.inviteDirects.size !== 0 && ( -
      - Direct Messages -
      - )} - { - Array.from(initMatrix.roomList.inviteDirects).map((roomId) => { - const myRoom = initMatrix.matrixClient.getRoom(roomId); - if (myRoom === null) return null; - const roomName = myRoom.name; - return ( - ) - : ( -
      - - -
      - ) - } - /> - ); - }) - } - { initMatrix.roomList.inviteSpaces.size !== 0 && ( -
      - Spaces -
      - )} - { Array.from(initMatrix.roomList.inviteSpaces).map(renderRoomTile) } - - { initMatrix.roomList.inviteRooms.size !== 0 && ( -
      - Rooms -
      - )} - { Array.from(initMatrix.roomList.inviteRooms).map(renderRoomTile) } -
      -
      - ); -} - -InviteList.propTypes = { - isOpen: PropTypes.bool.isRequired, - onRequestClose: PropTypes.func.isRequired, -}; - -export default InviteList; diff --git a/src/app/organisms/invite-list/InviteList.scss b/src/app/organisms/invite-list/InviteList.scss deleted file mode 100644 index da1968c30..000000000 --- a/src/app/organisms/invite-list/InviteList.scss +++ /dev/null @@ -1,26 +0,0 @@ -@use '../../partials/dir'; - -.invites-content { - @include dir.side(margin, var(--sp-normal), var(--sp-extra-tight)); - - &__subheading { - margin-top: var(--sp-extra-loose); - - & .text { - text-transform: uppercase; - } - &:first-child { - margin-top: var(--sp-tight); - } - } - - & .room-tile { - margin-top: var(--sp-normal); - &__options { - align-self: flex-end; - } - } - & .invite-btn__container .btn-surface { - @include dir.side(margin, 0, var(--sp-normal)); - } -} \ No newline at end of file diff --git a/src/app/organisms/invite-user/InviteUser.jsx b/src/app/organisms/invite-user/InviteUser.jsx index 751951024..10f55f9f6 100644 --- a/src/app/organisms/invite-user/InviteUser.jsx +++ b/src/app/organisms/invite-user/InviteUser.jsx @@ -3,10 +3,8 @@ import PropTypes from 'prop-types'; import './InviteUser.scss'; import initMatrix from '../../../client/initMatrix'; -import cons from '../../../client/state/cons'; import * as roomActions from '../../../client/action/room'; -import { selectRoom } from '../../../client/action/navigation'; -import { hasDMWith, hasDevices } from '../../../util/matrixUtil'; +import { hasDevices } from '../../../util/matrixUtil'; import Text from '../../atoms/text/Text'; import Button from '../../atoms/button/Button'; @@ -18,10 +16,10 @@ import RoomTile from '../../molecules/room-tile/RoomTile'; import CrossIC from '../../../../public/res/ic/outlined/cross.svg'; import UserIC from '../../../../public/res/ic/outlined/user.svg'; +import { useRoomNavigate } from '../../hooks/useRoomNavigate'; +import { getDMRoomFor } from '../../utils/matrix'; -function InviteUser({ - isOpen, roomId, searchTerm, onRequestClose, -}) { +function InviteUser({ isOpen, roomId, searchTerm, onRequestClose }) { const [isSearching, updateIsSearching] = useState(false); const [searchQuery, updateSearchQuery] = useState({}); const [users, updateUsers] = useState([]); @@ -37,6 +35,7 @@ function InviteUser({ const usernameRef = useRef(null); const mx = initMatrix.matrixClient; + const { navigateRoom } = useRoomNavigate(); function getMapCopy(myMap) { const newMap = new Map(); @@ -76,11 +75,13 @@ function InviteUser({ if (isInputUserId) { try { const result = await mx.getProfileInfo(inputUsername); - updateUsers([{ - user_id: inputUsername, - display_name: result.displayname, - avatar_url: result.avatar_url, - }]); + updateUsers([ + { + user_id: inputUsername, + display_name: result.displayname, + avatar_url: result.avatar_url, + }, + ]); } catch (e) { updateSearchQuery({ error: `${inputUsername} not found!` }); } @@ -105,9 +106,9 @@ function InviteUser({ async function createDM(userId) { if (mx.getUserId() === userId) return; - const dmRoomId = hasDMWith(userId); + const dmRoomId = getDMRoomFor(mx, userId)?.roomId; if (dmRoomId) { - selectRoom(dmRoomId); + navigateRoom(dmRoomId); onRequestClose(); return; } @@ -120,6 +121,7 @@ function InviteUser({ const result = await roomActions.createDM(userId, await hasDevices(userId)); roomIdToUserId.set(result.room_id, userId); updateRoomIdToUserId(getMapCopy(roomIdToUserId)); + onDMCreated(result.room_id); } catch (e) { deleteUserFromProc(userId); if (typeof e.message === 'string') procUserError.set(userId, e.message); @@ -150,7 +152,13 @@ function InviteUser({ function renderUserList() { const renderOptions = (userId) => { - const messageJSX = (message, isPositive) => {message}; + const messageJSX = (message, isPositive) => ( + + + {message} + + + ); if (mx.getUserId() === userId) return null; if (procUsers.has(userId)) { @@ -158,7 +166,16 @@ function InviteUser({ } if (createdDM.has(userId)) { // eslint-disable-next-line max-len - return ; + return ( + + ); } if (invitedUserIds.has(userId)) { return messageJSX('Invited', true); @@ -178,13 +195,23 @@ function InviteUser({ } } } - return (typeof roomId === 'string') - ? - : ; + return typeof roomId === 'string' ? ( + + ) : ( + + ); }; const renderError = (userId) => { if (!procUserError.has(userId)) return null; - return {procUserError.get(userId)}; + return ( + + {procUserError.get(userId)} + + ); }; return users.map((user) => { @@ -193,7 +220,11 @@ function InviteUser({ return ( { - initMatrix.roomList.on(cons.events.roomList.ROOM_CREATED, onDMCreated); - return () => { - initMatrix.roomList.removeListener(cons.events.roomList.ROOM_CREATED, onDMCreated); - }; - }, [isOpen, procUsers, createdDM, roomIdToUserId]); - return ( } onRequestClose={onRequestClose} >
      -
      { e.preventDefault(); searchUser(usernameRef.current.value); }}> + { + e.preventDefault(); + searchUser(usernameRef.current.value); + }} + > - +
      - { - typeof searchQuery.username !== 'undefined' && isSearching && ( -
      - - {`Searching for user "${searchQuery.username}"...`} -
      - ) - } - { - typeof searchQuery.username !== 'undefined' && !isSearching && ( - {`Search result for user "${searchQuery.username}"`} - ) - } - { - searchQuery.error && {searchQuery.error} - } + {typeof searchQuery.username !== 'undefined' && isSearching && ( +
      + + {`Searching for user "${searchQuery.username}"...`} +
      + )} + {typeof searchQuery.username !== 'undefined' && !isSearching && ( + {`Search result for user "${searchQuery.username}"`} + )} + {searchQuery.error && ( + + {searchQuery.error} + + )}
      - { users.length !== 0 && ( -
      - {renderUserList()} -
      - )} + {users.length !== 0 &&
      {renderUserList()}
      }
      ); diff --git a/src/app/organisms/join-alias/JoinAlias.jsx b/src/app/organisms/join-alias/JoinAlias.jsx index bc0a8adb7..9fa5542df 100644 --- a/src/app/organisms/join-alias/JoinAlias.jsx +++ b/src/app/organisms/join-alias/JoinAlias.jsx @@ -6,7 +6,6 @@ import initMatrix from '../../../client/initMatrix'; import cons from '../../../client/state/cons'; import navigation from '../../../client/state/navigation'; import { join } from '../../../client/action/room'; -import { selectRoom, selectTab } from '../../../client/action/navigation'; import Text from '../../atoms/text/Text'; import IconButton from '../../atoms/button/IconButton'; @@ -18,36 +17,24 @@ import Dialog from '../../molecules/dialog/Dialog'; import CrossIC from '../../../../public/res/ic/outlined/cross.svg'; import { useStore } from '../../hooks/useStore'; +import { useRoomNavigate } from '../../hooks/useRoomNavigate'; const ALIAS_OR_ID_REG = /^[#|!].+:.+\..+$/; function JoinAliasContent({ term, requestClose }) { const [process, setProcess] = useState(false); const [error, setError] = useState(undefined); - const [lastJoinId, setLastJoinId] = useState(undefined); const mx = initMatrix.matrixClient; const mountStore = useStore(); + const { navigateRoom } = useRoomNavigate(); + const openRoom = (roomId) => { - const room = mx.getRoom(roomId); - if (!room) return; - if (room.isSpaceRoom()) selectTab(roomId); - else selectRoom(roomId); + navigateRoom(roomId); requestClose(); }; - useEffect(() => { - const handleJoin = (roomId) => { - if (lastJoinId !== roomId) return; - openRoom(roomId); - }; - initMatrix.roomList.on(cons.events.roomList.ROOM_JOINED, handleJoin); - return () => { - initMatrix.roomList.removeListener(cons.events.roomList.ROOM_JOINED, handleJoin); - }; - }, [lastJoinId]); - const handleSubmit = async (e) => { e.preventDefault(); mountStore.setItem(true); @@ -70,13 +57,14 @@ function JoinAliasContent({ term, requestClose }) { } catch (err) { if (!mountStore.getItem()) return; setProcess(false); - setError(`Unable to find room/space with ${alias}. Either room/space is private or doesn't exist.`); + setError( + `Unable to find room/space with ${alias}. Either room/space is private or doesn't exist.` + ); } } try { const roomId = await join(alias, false, via); if (!mountStore.getItem()) return; - setLastJoinId(roomId); openRoom(roomId); } catch { if (!mountStore.getItem()) return; @@ -87,24 +75,23 @@ function JoinAliasContent({ term, requestClose }) { return (
      - - {error && {error}} + + {error && ( + + {error} + + )}
      - { - process - ? ( - <> - - {process} - - ) - : - } + {process ? ( + <> + + {process} + + ) : ( + + )}
      ); @@ -141,13 +128,15 @@ function JoinAlias() { return ( Join with address - )} + title={ + + Join with address + + } contentOptions={} onRequestClose={requestClose} > - { data ? :
      } + {data ? :
      }
      ); } diff --git a/src/app/organisms/navigation/Directs.jsx b/src/app/organisms/navigation/Directs.jsx deleted file mode 100644 index e65c8afcf..000000000 --- a/src/app/organisms/navigation/Directs.jsx +++ /dev/null @@ -1,71 +0,0 @@ -import React, { useState, useEffect } from 'react'; -import PropTypes from 'prop-types'; - -import initMatrix from '../../../client/initMatrix'; -import cons from '../../../client/state/cons'; -import navigation from '../../../client/state/navigation'; -import Postie from '../../../util/Postie'; -import { roomIdByActivity } from '../../../util/sort'; - -import RoomsCategory from './RoomsCategory'; - -const drawerPostie = new Postie(); -function Directs({ size }) { - const mx = initMatrix.matrixClient; - const { roomList, notifications } = initMatrix; - const [directIds, setDirectIds] = useState([]); - - useEffect(() => setDirectIds([...roomList.directs].sort(roomIdByActivity)), [size]); - - useEffect(() => { - const handleTimeline = (event, room, toStartOfTimeline, removed, data) => { - if (!roomList.directs.has(room.roomId)) return; - if (!data.liveEvent) return; - if (directIds[0] === room.roomId) return; - const newDirectIds = [room.roomId]; - directIds.forEach((id) => { - if (id === room.roomId) return; - newDirectIds.push(id); - }); - setDirectIds(newDirectIds); - }; - mx.on('Room.timeline', handleTimeline); - return () => { - mx.removeListener('Room.timeline', handleTimeline); - }; - }, [directIds]); - - useEffect(() => { - const selectorChanged = (selectedRoomId, prevSelectedRoomId) => { - if (!drawerPostie.hasTopic('selector-change')) return; - const addresses = []; - if (drawerPostie.hasSubscriber('selector-change', selectedRoomId)) addresses.push(selectedRoomId); - if (drawerPostie.hasSubscriber('selector-change', prevSelectedRoomId)) addresses.push(prevSelectedRoomId); - if (addresses.length === 0) return; - drawerPostie.post('selector-change', addresses, selectedRoomId); - }; - - const notiChanged = (roomId, total, prevTotal) => { - if (total === prevTotal) return; - if (drawerPostie.hasTopicAndSubscriber('unread-change', roomId)) { - drawerPostie.post('unread-change', roomId); - } - }; - - navigation.on(cons.events.navigation.ROOM_SELECTED, selectorChanged); - notifications.on(cons.events.notifications.NOTI_CHANGED, notiChanged); - notifications.on(cons.events.notifications.MUTE_TOGGLED, notiChanged); - return () => { - navigation.removeListener(cons.events.navigation.ROOM_SELECTED, selectorChanged); - notifications.removeListener(cons.events.notifications.NOTI_CHANGED, notiChanged); - notifications.removeListener(cons.events.notifications.MUTE_TOGGLED, notiChanged); - }; - }, []); - - return ; -} -Directs.propTypes = { - size: PropTypes.number.isRequired, -}; - -export default Directs; diff --git a/src/app/organisms/navigation/Drawer.jsx b/src/app/organisms/navigation/Drawer.jsx deleted file mode 100644 index 0795e4692..000000000 --- a/src/app/organisms/navigation/Drawer.jsx +++ /dev/null @@ -1,93 +0,0 @@ -import React, { useState, useEffect, useRef } from 'react'; -import './Drawer.scss'; - -import initMatrix from '../../../client/initMatrix'; -import cons from '../../../client/state/cons'; -import navigation from '../../../client/state/navigation'; - -import Text from '../../atoms/text/Text'; -import ScrollView from '../../atoms/scroll/ScrollView'; - -import DrawerHeader from './DrawerHeader'; -import DrawerBreadcrumb from './DrawerBreadcrumb'; -import Home from './Home'; -import Directs from './Directs'; - -import { useForceUpdate } from '../../hooks/useForceUpdate'; -import { useSelectedTab } from '../../hooks/useSelectedTab'; -import { useSelectedSpace } from '../../hooks/useSelectedSpace'; - -function useSystemState() { - const [systemState, setSystemState] = useState(null); - - useEffect(() => { - const handleSystemState = (state) => { - if (state === 'ERROR' || state === 'RECONNECTING' || state === 'STOPPED') { - setSystemState({ status: 'Connection lost!' }); - } - if (systemState !== null) setSystemState(null); - }; - initMatrix.matrixClient.on('sync', handleSystemState); - return () => { - initMatrix.matrixClient.removeListener('sync', handleSystemState); - }; - }, [systemState]); - - return [systemState]; -} - -function Drawer() { - const [systemState] = useSystemState(); - const [selectedTab] = useSelectedTab(); - const [spaceId] = useSelectedSpace(); - const [, forceUpdate] = useForceUpdate(); - const scrollRef = useRef(null); - const { roomList } = initMatrix; - - useEffect(() => { - const handleUpdate = () => { - forceUpdate(); - }; - roomList.on(cons.events.roomList.ROOMLIST_UPDATED, handleUpdate); - return () => { - roomList.removeListener(cons.events.roomList.ROOMLIST_UPDATED, handleUpdate); - }; - }, []); - - useEffect(() => { - requestAnimationFrame(() => { - if (scrollRef.current) { - scrollRef.current.scrollTop = 0; - } - }); - }, [selectedTab]); - - return ( -
      - -
      - {navigation.selectedSpacePath.length > 1 && selectedTab !== cons.tabs.DIRECTS && ( - - )} -
      - -
      - {selectedTab !== cons.tabs.DIRECTS ? ( - - ) : ( - - )} -
      -
      -
      -
      - {systemState !== null && ( -
      - {systemState.status} -
      - )} -
      - ); -} - -export default Drawer; diff --git a/src/app/organisms/navigation/Drawer.scss b/src/app/organisms/navigation/Drawer.scss deleted file mode 100644 index 4e54c5fa2..000000000 --- a/src/app/organisms/navigation/Drawer.scss +++ /dev/null @@ -1,56 +0,0 @@ -@use '../../partials/flex'; -@use '../../partials/dir'; - -.drawer { - @extend .cp-fx__column; - @extend .cp-fx__item-one; - min-width: 0; - @include dir.side(border, - none, - 1px solid var(--bg-surface-border), - ); - - & .header { - padding: var(--sp-extra-tight); - & > .header__title-wrapper { - @include dir.side(margin, var(--sp-ultra-tight), 0); - } - } - - &__content-wrapper { - @extend .cp-fx__item-one; - @extend .cp-fx__column; - } - - &__state { - padding: var(--sp-extra-tight); - border-top: 1px solid var(--bg-surface-border); - @extend .cp-fx__row--c-c; - - & .text { - color: var(--tc-danger-high); - } - } -} -.rooms__wrapper { - @extend .cp-fx__item-one; - position: relative; -} - -.rooms-container { - padding-bottom: var(--sp-extra-loose); - - &::before { - position: absolute; - top: 0; - z-index: 99; - content: ''; - display: inline-block; - width: 100%; - height: 8px; - background-image: linear-gradient( - to bottom, - var(--bg-surface-low), - var(--bg-surface-low-transparent)); - } -} diff --git a/src/app/organisms/navigation/DrawerBreadcrumb.jsx b/src/app/organisms/navigation/DrawerBreadcrumb.jsx deleted file mode 100644 index face349d4..000000000 --- a/src/app/organisms/navigation/DrawerBreadcrumb.jsx +++ /dev/null @@ -1,142 +0,0 @@ -import React, { useState, useEffect, useRef } from 'react'; -import PropTypes from 'prop-types'; -import './DrawerBreadcrumb.scss'; - -import { twemojify } from '../../../util/twemojify'; - -import initMatrix from '../../../client/initMatrix'; -import cons from '../../../client/state/cons'; -import { selectTab, selectSpace } from '../../../client/action/navigation'; -import navigation from '../../../client/state/navigation'; -import { abbreviateNumber } from '../../../util/common'; - -import Text from '../../atoms/text/Text'; -import RawIcon from '../../atoms/system-icons/RawIcon'; -import Button from '../../atoms/button/Button'; -import ScrollView from '../../atoms/scroll/ScrollView'; -import NotificationBadge from '../../atoms/badge/NotificationBadge'; - -import ChevronRightIC from '../../../../public/res/ic/outlined/chevron-right.svg'; - -function DrawerBreadcrumb({ spaceId }) { - const [, forceUpdate] = useState({}); - const scrollRef = useRef(null); - const { roomList, notifications, accountData } = initMatrix; - const mx = initMatrix.matrixClient; - const spacePath = navigation.selectedSpacePath; - - function onNotiChanged(roomId, total, prevTotal) { - if (total === prevTotal) return; - if (navigation.selectedSpacePath.includes(roomId)) { - forceUpdate({}); - } - if (navigation.selectedSpacePath[0] === cons.tabs.HOME) { - if (!roomList.isOrphan(roomId)) return; - if (roomList.directs.has(roomId)) return; - forceUpdate({}); - } - } - - useEffect(() => { - requestAnimationFrame(() => { - if (scrollRef?.current === null) return; - scrollRef.current.scrollLeft = scrollRef.current.scrollWidth; - }); - notifications.on(cons.events.notifications.NOTI_CHANGED, onNotiChanged); - return () => { - notifications.removeListener(cons.events.notifications.NOTI_CHANGED, onNotiChanged); - }; - }, [spaceId]); - - function getHomeNotiExcept(childId) { - const orphans = roomList.getOrphans() - .filter((id) => (id !== childId)) - .filter((id) => !accountData.spaceShortcut.has(id)); - - let noti = null; - - orphans.forEach((roomId) => { - if (!notifications.hasNoti(roomId)) return; - if (noti === null) noti = { total: 0, highlight: 0 }; - const childNoti = notifications.getNoti(roomId); - noti.total += childNoti.total; - noti.highlight += childNoti.highlight; - }); - - return noti; - } - - function getNotiExcept(roomId, childId) { - if (!notifications.hasNoti(roomId)) return null; - - const noti = notifications.getNoti(roomId); - if (!notifications.hasNoti(childId)) return noti; - if (noti.from === null) return noti; - - const childNoti = notifications.getNoti(childId); - - let noOther = true; - let total = 0; - let highlight = 0; - noti.from.forEach((fromId) => { - if (childNoti.from.has(fromId)) return; - noOther = false; - const fromNoti = notifications.getNoti(fromId); - total += fromNoti.total; - highlight += fromNoti.highlight; - }); - - if (noOther) return null; - return { total, highlight }; - } - - return ( -
      - -
      - { - spacePath.map((id, index) => { - const noti = (id !== cons.tabs.HOME && index < spacePath.length) - ? getNotiExcept(id, (index === spacePath.length - 1) ? null : spacePath[index + 1]) - : getHomeNotiExcept((index === spacePath.length - 1) ? null : spacePath[index + 1]); - - return ( - - { index !== 0 && } - - - ); - }) - } -
      -
      - -
      - ); -} - -DrawerBreadcrumb.defaultProps = { - spaceId: null, -}; - -DrawerBreadcrumb.propTypes = { - spaceId: PropTypes.string, -}; - -export default DrawerBreadcrumb; diff --git a/src/app/organisms/navigation/DrawerBreadcrumb.scss b/src/app/organisms/navigation/DrawerBreadcrumb.scss deleted file mode 100644 index 0b7bacceb..000000000 --- a/src/app/organisms/navigation/DrawerBreadcrumb.scss +++ /dev/null @@ -1,66 +0,0 @@ -@use '../../partials/text'; -@use '../../partials/dir'; - -.drawer-breadcrumb__wrapper { - height: var(--header-height); - position: relative; -} - -.drawer-breadcrumb { - display: flex; - align-items: center; - height: 100%; - margin: 0 var(--sp-extra-tight); - - &::before, - &::after { - flex-shrink: 0; - position: absolute; - right: 0; - z-index: 99; - - content: ''; - display: inline-block; - min-width: 8px; - width: 8px; - height: 100%; - background-image: linear-gradient( - to right, - var(--bg-surface-low-transparent), - var(--bg-surface-low) - ); - } - &::before { - left: 0; - right: unset; - background-image: linear-gradient( - to left, - var(--bg-surface-low-transparent), - var(--bg-surface-low) - ); - } - - & > * { - flex-shrink: 0; - } - - & > .btn-surface { - min-width: 0; - padding: var(--sp-extra-tight) 10px; - white-space: nowrap; - box-shadow: none; - & p { - @extend .cp-txt__ellipsis; - max-width: 86px; - } - - & .notification-badge { - @include dir.side(margin, var(--sp-extra-tight), 0); - } - } - - &__btn--selected { - box-shadow: var(--bs-surface-border) !important; - background-color: var(--bg-surface); - } -} \ No newline at end of file diff --git a/src/app/organisms/navigation/DrawerHeader.jsx b/src/app/organisms/navigation/DrawerHeader.jsx deleted file mode 100644 index e8782e384..000000000 --- a/src/app/organisms/navigation/DrawerHeader.jsx +++ /dev/null @@ -1,159 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import './DrawerHeader.scss'; - -import { twemojify } from '../../../util/twemojify'; - -import initMatrix from '../../../client/initMatrix'; -import cons from '../../../client/state/cons'; -import { - openPublicRooms, openCreateRoom, openSpaceManage, openJoinAlias, - openSpaceAddExisting, openInviteUser, openReusableContextMenu, -} from '../../../client/action/navigation'; -import { getEventCords } from '../../../util/common'; - -import { blurOnBubbling } from '../../atoms/button/script'; - -import Text from '../../atoms/text/Text'; -import RawIcon from '../../atoms/system-icons/RawIcon'; -import Header, { TitleWrapper } from '../../atoms/header/Header'; -import IconButton from '../../atoms/button/IconButton'; -import { MenuItem, MenuHeader } from '../../atoms/context-menu/ContextMenu'; -import SpaceOptions from '../../molecules/space-options/SpaceOptions'; - -import PlusIC from '../../../../public/res/ic/outlined/plus.svg'; -import HashPlusIC from '../../../../public/res/ic/outlined/hash-plus.svg'; -import HashGlobeIC from '../../../../public/res/ic/outlined/hash-globe.svg'; -import HashSearchIC from '../../../../public/res/ic/outlined/hash-search.svg'; -import SpacePlusIC from '../../../../public/res/ic/outlined/space-plus.svg'; -import ChevronBottomIC from '../../../../public/res/ic/outlined/chevron-bottom.svg'; - -export function HomeSpaceOptions({ spaceId, afterOptionSelect }) { - const mx = initMatrix.matrixClient; - const room = mx.getRoom(spaceId); - const canManage = room - ? room.currentState.maySendStateEvent('m.space.child', mx.getUserId()) - : true; - - return ( - <> - Add rooms or spaces - { afterOptionSelect(); openCreateRoom(true, spaceId); }} - disabled={!canManage} - > - Create new space - - { afterOptionSelect(); openCreateRoom(false, spaceId); }} - disabled={!canManage} - > - Create new room - - { !spaceId && ( - { afterOptionSelect(); openPublicRooms(); }} - > - Explore public rooms - - )} - { !spaceId && ( - { afterOptionSelect(); openJoinAlias(); }} - > - Join with address - - )} - { spaceId && ( - { afterOptionSelect(); openSpaceAddExisting(spaceId); }} - disabled={!canManage} - > - Add existing - - )} - { spaceId && ( - { afterOptionSelect(); openSpaceManage(spaceId); }} - iconSrc={HashSearchIC} - > - Manage rooms - - )} - - ); -} -HomeSpaceOptions.defaultProps = { - spaceId: null, -}; -HomeSpaceOptions.propTypes = { - spaceId: PropTypes.string, - afterOptionSelect: PropTypes.func.isRequired, -}; - -function DrawerHeader({ selectedTab, spaceId }) { - const mx = initMatrix.matrixClient; - const tabName = selectedTab !== cons.tabs.DIRECTS ? 'Home' : 'Direct messages'; - - const isDMTab = selectedTab === cons.tabs.DIRECTS; - const room = mx.getRoom(spaceId); - const spaceName = isDMTab ? null : (room?.name || null); - - const openSpaceOptions = (e) => { - e.preventDefault(); - openReusableContextMenu( - 'bottom', - getEventCords(e, '.header'), - (closeMenu) => , - ); - }; - - const openHomeSpaceOptions = (e) => { - e.preventDefault(); - openReusableContextMenu( - 'right', - getEventCords(e, '.ic-btn'), - (closeMenu) => , - ); - }; - - return ( -
      - {spaceName ? ( - - ) : ( - - {tabName} - - )} - - { isDMTab && openInviteUser()} tooltip="Start DM" src={PlusIC} size="small" /> } - { !isDMTab && } -
      - ); -} - -DrawerHeader.defaultProps = { - spaceId: null, -}; -DrawerHeader.propTypes = { - selectedTab: PropTypes.string.isRequired, - spaceId: PropTypes.string, -}; - -export default DrawerHeader; diff --git a/src/app/organisms/navigation/DrawerHeader.scss b/src/app/organisms/navigation/DrawerHeader.scss deleted file mode 100644 index 9ed17e4bd..000000000 --- a/src/app/organisms/navigation/DrawerHeader.scss +++ /dev/null @@ -1,28 +0,0 @@ -@use '../../partials/flex'; -@use '../../partials/dir'; - -.drawer-header__btn { - min-width: 0; - @extend .cp-fx__row--s-c; - @include dir.side(margin, 0, auto); - padding: var(--sp-ultra-tight); - border-radius: calc(var(--bo-radius) / 2); - cursor: pointer; - - & .header__title-wrapper { - @include dir.side(margin, 0, var(--sp-extra-tight)); - } - - @media (hover:hover) { - &:hover { - background-color: var(--bg-surface-hover); - box-shadow: var(--bs-surface-outline); - } - } - &:focus, - &:active { - background-color: var(--bg-surface-active); - box-shadow: var(--bs-surface-outline); - outline: none; - } -} \ No newline at end of file diff --git a/src/app/organisms/navigation/Home.jsx b/src/app/organisms/navigation/Home.jsx deleted file mode 100644 index 6bfa6c0dd..000000000 --- a/src/app/organisms/navigation/Home.jsx +++ /dev/null @@ -1,112 +0,0 @@ -import React, { useEffect } from 'react'; -import PropTypes from 'prop-types'; - -import initMatrix from '../../../client/initMatrix'; -import cons from '../../../client/state/cons'; -import navigation from '../../../client/state/navigation'; -import Postie from '../../../util/Postie'; -import { roomIdByActivity, roomIdByAtoZ } from '../../../util/sort'; - -import RoomsCategory from './RoomsCategory'; - -import { useCategorizedSpaces } from '../../hooks/useCategorizedSpaces'; - -const drawerPostie = new Postie(); -function Home({ spaceId }) { - const mx = initMatrix.matrixClient; - const { roomList, notifications, accountData } = initMatrix; - const { spaces, rooms, directs } = roomList; - useCategorizedSpaces(); - const isCategorized = accountData.categorizedSpaces.has(spaceId); - - let categories = null; - let spaceIds = []; - let roomIds = []; - let directIds = []; - - if (spaceId) { - const spaceChildIds = roomList.getSpaceChildren(spaceId) ?? []; - spaceIds = spaceChildIds.filter((roomId) => spaces.has(roomId)); - roomIds = spaceChildIds.filter((roomId) => rooms.has(roomId)); - directIds = spaceChildIds.filter((roomId) => directs.has(roomId)); - } else { - spaceIds = roomList.getOrphanSpaces().filter((id) => !accountData.spaceShortcut.has(id)); - roomIds = roomList.getOrphanRooms(); - } - - if (isCategorized) { - categories = roomList.getCategorizedSpaces(spaceIds); - categories.delete(spaceId); - } - - useEffect(() => { - const selectorChanged = (selectedRoomId, prevSelectedRoomId) => { - if (!drawerPostie.hasTopic('selector-change')) return; - const addresses = []; - if (drawerPostie.hasSubscriber('selector-change', selectedRoomId)) addresses.push(selectedRoomId); - if (drawerPostie.hasSubscriber('selector-change', prevSelectedRoomId)) addresses.push(prevSelectedRoomId); - if (addresses.length === 0) return; - drawerPostie.post('selector-change', addresses, selectedRoomId); - }; - - const notiChanged = (roomId, total, prevTotal) => { - if (total === prevTotal) return; - if (drawerPostie.hasTopicAndSubscriber('unread-change', roomId)) { - drawerPostie.post('unread-change', roomId); - } - }; - - navigation.on(cons.events.navigation.ROOM_SELECTED, selectorChanged); - notifications.on(cons.events.notifications.NOTI_CHANGED, notiChanged); - notifications.on(cons.events.notifications.MUTE_TOGGLED, notiChanged); - return () => { - navigation.removeListener(cons.events.navigation.ROOM_SELECTED, selectorChanged); - notifications.removeListener(cons.events.notifications.NOTI_CHANGED, notiChanged); - notifications.removeListener(cons.events.notifications.MUTE_TOGGLED, notiChanged); - }; - }, []); - - return ( - <> - { !isCategorized && spaceIds.length !== 0 && ( - - )} - - { roomIds.length !== 0 && ( - - )} - - { directIds.length !== 0 && ( - - )} - - { isCategorized && [...categories.keys()].sort(roomIdByAtoZ).map((catId) => { - const rms = []; - const dms = []; - categories.get(catId).forEach((id) => { - if (directs.has(id)) dms.push(id); - else rms.push(id); - }); - rms.sort(roomIdByAtoZ); - dms.sort(roomIdByActivity); - return ( - - ); - })} - - ); -} -Home.defaultProps = { - spaceId: null, -}; -Home.propTypes = { - spaceId: PropTypes.string, -}; - -export default Home; diff --git a/src/app/organisms/navigation/Navigation.jsx b/src/app/organisms/navigation/Navigation.jsx deleted file mode 100644 index 24bd1bd2d..000000000 --- a/src/app/organisms/navigation/Navigation.jsx +++ /dev/null @@ -1,16 +0,0 @@ -import React from 'react'; -import './Navigation.scss'; - -import SideBar from './SideBar'; -import Drawer from './Drawer'; - -function Navigation() { - return ( -
      - - -
      - ); -} - -export default Navigation; diff --git a/src/app/organisms/navigation/Navigation.scss b/src/app/organisms/navigation/Navigation.scss deleted file mode 100644 index 4a932c79d..000000000 --- a/src/app/organisms/navigation/Navigation.scss +++ /dev/null @@ -1,7 +0,0 @@ -.navigation { - width: 100%; - height: 100%; - background-color: var(--bg-surface-low); - - display: flex; -} \ No newline at end of file diff --git a/src/app/organisms/navigation/RoomsCategory.jsx b/src/app/organisms/navigation/RoomsCategory.jsx deleted file mode 100644 index b5666512d..000000000 --- a/src/app/organisms/navigation/RoomsCategory.jsx +++ /dev/null @@ -1,92 +0,0 @@ -import React, { useState } from 'react'; -import PropTypes from 'prop-types'; -import './RoomsCategory.scss'; - -import initMatrix from '../../../client/initMatrix'; -import { selectSpace, selectRoom, openReusableContextMenu } from '../../../client/action/navigation'; -import { getEventCords } from '../../../util/common'; - -import Text from '../../atoms/text/Text'; -import RawIcon from '../../atoms/system-icons/RawIcon'; -import IconButton from '../../atoms/button/IconButton'; -import Selector from './Selector'; -import SpaceOptions from '../../molecules/space-options/SpaceOptions'; -import { HomeSpaceOptions } from './DrawerHeader'; - -import PlusIC from '../../../../public/res/ic/outlined/plus.svg'; -import HorizontalMenuIC from '../../../../public/res/ic/outlined/horizontal-menu.svg'; -import ChevronBottomIC from '../../../../public/res/ic/outlined/chevron-bottom.svg'; -import ChevronRightIC from '../../../../public/res/ic/outlined/chevron-right.svg'; - -function RoomsCategory({ - spaceId, name, hideHeader, roomIds, drawerPostie, -}) { - const { spaces, directs } = initMatrix.roomList; - const [isOpen, setIsOpen] = useState(true); - - const openSpaceOptions = (e) => { - e.preventDefault(); - openReusableContextMenu( - 'bottom', - getEventCords(e, '.header'), - (closeMenu) => , - ); - }; - - const openHomeSpaceOptions = (e) => { - e.preventDefault(); - openReusableContextMenu( - 'right', - getEventCords(e, '.ic-btn'), - (closeMenu) => , - ); - }; - - const renderSelector = (roomId) => { - const isSpace = spaces.has(roomId); - const isDM = directs.has(roomId); - - return ( - (isSpace ? selectSpace(roomId) : selectRoom(roomId))} - /> - ); - }; - - return ( -
      - {!hideHeader && ( -
      - - {spaceId && } - {spaceId && } -
      - )} - {(isOpen || hideHeader) && ( -
      - {roomIds.map(renderSelector)} -
      - )} -
      - ); -} -RoomsCategory.defaultProps = { - spaceId: null, - hideHeader: false, -}; -RoomsCategory.propTypes = { - spaceId: PropTypes.string, - name: PropTypes.string.isRequired, - hideHeader: PropTypes.bool, - roomIds: PropTypes.arrayOf(PropTypes.string).isRequired, - drawerPostie: PropTypes.shape({}).isRequired, -}; - -export default RoomsCategory; diff --git a/src/app/organisms/navigation/RoomsCategory.scss b/src/app/organisms/navigation/RoomsCategory.scss deleted file mode 100644 index 841290c5e..000000000 --- a/src/app/organisms/navigation/RoomsCategory.scss +++ /dev/null @@ -1,54 +0,0 @@ -@use '../../partials/flex'; -@use '../../partials/dir'; -@use '../../partials/text'; - -.room-category { - &__header, - &__toggle { - display: flex; - align-items: center; - } - &__header { - margin-top: var(--sp-extra-tight); - - & .ic-btn { - padding: var(--sp-ultra-tight); - border-radius: 4px; - @include dir.side(margin, 0, 5px); - & .ic-raw { - width: 16px; - height: 16px; - background-color: var(--ic-surface-low); - } - } - } - &__toggle { - @extend .cp-fx__item-one; - padding: var(--sp-extra-tight) var(--sp-tight); - cursor: pointer; - - & .ic-raw { - flex-shrink: 0; - width: 12px; - height: 12px; - background-color: var(--ic-surface-low); - @include dir.side(margin, 0, var(--sp-ultra-tight)); - } - & .text { - text-transform: uppercase; - @extend .cp-txt__ellipsis; - } - &:hover .text { - color: var(--tc-surface-normal); - } - } - - &__content:first-child { - margin-top: var(--sp-extra-tight); - } - - & .room-selector { - width: calc(100% - var(--sp-extra-tight)); - @include dir.side(margin, auto, 0); - } -} \ No newline at end of file diff --git a/src/app/organisms/navigation/Selector.jsx b/src/app/organisms/navigation/Selector.jsx deleted file mode 100644 index cb1086eaa..000000000 --- a/src/app/organisms/navigation/Selector.jsx +++ /dev/null @@ -1,93 +0,0 @@ -/* eslint-disable react/prop-types */ -import React, { useEffect } from 'react'; -import PropTypes from 'prop-types'; - -import initMatrix from '../../../client/initMatrix'; -import cons from '../../../client/state/cons'; -import navigation from '../../../client/state/navigation'; -import { openReusableContextMenu } from '../../../client/action/navigation'; -import { getEventCords, abbreviateNumber } from '../../../util/common'; -import { joinRuleToIconSrc } from '../../../util/matrixUtil'; - -import IconButton from '../../atoms/button/IconButton'; -import RoomSelector from '../../molecules/room-selector/RoomSelector'; -import RoomOptions from '../../molecules/room-options/RoomOptions'; -import SpaceOptions from '../../molecules/space-options/SpaceOptions'; - -import VerticalMenuIC from '../../../../public/res/ic/outlined/vertical-menu.svg'; - -import { useForceUpdate } from '../../hooks/useForceUpdate'; - -function Selector({ - roomId, isDM, drawerPostie, onClick, -}) { - const mx = initMatrix.matrixClient; - const noti = initMatrix.notifications; - const room = mx.getRoom(roomId); - - let imageSrc = room.getAvatarFallbackMember()?.getAvatarUrl(mx.baseUrl, 24, 24, 'crop') || null; - if (imageSrc === null) imageSrc = room.getAvatarUrl(mx.baseUrl, 24, 24, 'crop') || null; - - const isMuted = noti.getNotiType(roomId) === cons.notifs.MUTE; - - const [, forceUpdate] = useForceUpdate(); - - useEffect(() => { - const unSub1 = drawerPostie.subscribe('selector-change', roomId, forceUpdate); - const unSub2 = drawerPostie.subscribe('unread-change', roomId, forceUpdate); - return () => { - unSub1(); - unSub2(); - }; - }, []); - - const openOptions = (e) => { - e.preventDefault(); - openReusableContextMenu( - 'right', - getEventCords(e, '.room-selector'), - room.isSpaceRoom() - ? (closeMenu) => - : (closeMenu) => , - ); - }; - - return ( - - )} - /> - ); -} - -Selector.defaultProps = { - isDM: true, -}; - -Selector.propTypes = { - roomId: PropTypes.string.isRequired, - isDM: PropTypes.bool, - drawerPostie: PropTypes.shape({}).isRequired, - onClick: PropTypes.func.isRequired, -}; - -export default Selector; diff --git a/src/app/organisms/navigation/SideBar.jsx b/src/app/organisms/navigation/SideBar.jsx deleted file mode 100644 index 531869656..000000000 --- a/src/app/organisms/navigation/SideBar.jsx +++ /dev/null @@ -1,390 +0,0 @@ -import React, { useState, useEffect, useRef } from 'react'; -import PropTypes from 'prop-types'; -import './SideBar.scss'; - -import { DndProvider, useDrag, useDrop } from 'react-dnd'; -import { HTML5Backend } from 'react-dnd-html5-backend'; - -import initMatrix from '../../../client/initMatrix'; -import cons from '../../../client/state/cons'; -import colorMXID from '../../../util/colorMXID'; -import { - selectTab, openShortcutSpaces, openInviteList, - openSearch, openSettings, openReusableContextMenu, -} from '../../../client/action/navigation'; -import { moveSpaceShortcut } from '../../../client/action/accountData'; -import { abbreviateNumber, getEventCords } from '../../../util/common'; -import { isCrossVerified } from '../../../util/matrixUtil'; - -import Avatar from '../../atoms/avatar/Avatar'; -import NotificationBadge from '../../atoms/badge/NotificationBadge'; -import ScrollView from '../../atoms/scroll/ScrollView'; -import SidebarAvatar from '../../molecules/sidebar-avatar/SidebarAvatar'; -import SpaceOptions from '../../molecules/space-options/SpaceOptions'; - -import HomeIC from '../../../../public/res/ic/outlined/home.svg'; -import UserIC from '../../../../public/res/ic/outlined/user.svg'; -import AddPinIC from '../../../../public/res/ic/outlined/add-pin.svg'; -import SearchIC from '../../../../public/res/ic/outlined/search.svg'; -import InviteIC from '../../../../public/res/ic/outlined/invite.svg'; -import ShieldUserIC from '../../../../public/res/ic/outlined/shield-user.svg'; - -import { useSelectedTab } from '../../hooks/useSelectedTab'; -import { useDeviceList } from '../../hooks/useDeviceList'; - -import { tabText as settingTabText } from '../settings/Settings'; - -function useNotificationUpdate() { - const { notifications } = initMatrix; - const [, forceUpdate] = useState({}); - useEffect(() => { - function onNotificationChanged(roomId, total, prevTotal) { - if (total === prevTotal) return; - forceUpdate({}); - } - notifications.on(cons.events.notifications.NOTI_CHANGED, onNotificationChanged); - return () => { - notifications.removeListener(cons.events.notifications.NOTI_CHANGED, onNotificationChanged); - }; - }, []); -} - -function ProfileAvatarMenu() { - const mx = initMatrix.matrixClient; - const [profile, setProfile] = useState({ - avatarUrl: null, - displayName: mx.getUser(mx.getUserId()).displayName, - }); - - useEffect(() => { - const user = mx.getUser(mx.getUserId()); - const setNewProfile = (avatarUrl, displayName) => setProfile({ - avatarUrl: avatarUrl || null, - displayName: displayName || profile.displayName, - }); - const onAvatarChange = (event, myUser) => { - setNewProfile(myUser.avatarUrl, myUser.displayName); - }; - mx.getProfileInfo(mx.getUserId()).then((info) => { - setNewProfile(info.avatar_url, info.displayname); - }); - user.on('User.avatarUrl', onAvatarChange); - return () => { - user.removeListener('User.avatarUrl', onAvatarChange); - }; - }, []); - - return ( - - )} - /> - ); -} - -function CrossSigninAlert() { - const deviceList = useDeviceList(); - const unverified = deviceList?.filter((device) => isCrossVerified(device.device_id) === false); - - if (!unverified?.length) return null; - - return ( - openSettings(settingTabText.SECURITY)} - avatar={} - /> - ); -} - -function FeaturedTab() { - const { roomList, accountData, notifications } = initMatrix; - const [selectedTab] = useSelectedTab(); - useNotificationUpdate(); - - function getHomeNoti() { - const orphans = roomList.getOrphans(); - let noti = null; - - orphans.forEach((roomId) => { - if (accountData.spaceShortcut.has(roomId)) return; - if (!notifications.hasNoti(roomId)) return; - if (noti === null) noti = { total: 0, highlight: 0 }; - const childNoti = notifications.getNoti(roomId); - noti.total += childNoti.total; - noti.highlight += childNoti.highlight; - }); - - return noti; - } - function getDMsNoti() { - if (roomList.directs.size === 0) return null; - let noti = null; - - [...roomList.directs].forEach((roomId) => { - if (!notifications.hasNoti(roomId)) return; - if (noti === null) noti = { total: 0, highlight: 0 }; - const childNoti = notifications.getNoti(roomId); - noti.total += childNoti.total; - noti.highlight += childNoti.highlight; - }); - - return noti; - } - - const dmsNoti = getDMsNoti(); - const homeNoti = getHomeNoti(); - - return ( - <> - selectTab(cons.tabs.HOME)} - avatar={} - notificationBadge={homeNoti ? ( - 0} - content={abbreviateNumber(homeNoti.total) || null} - /> - ) : null} - /> - selectTab(cons.tabs.DIRECTS)} - avatar={} - notificationBadge={dmsNoti ? ( - 0} - content={abbreviateNumber(dmsNoti.total) || null} - /> - ) : null} - /> - - ); -} - -function DraggableSpaceShortcut({ - isActive, spaceId, index, moveShortcut, onDrop, -}) { - const mx = initMatrix.matrixClient; - const { notifications } = initMatrix; - const room = mx.getRoom(spaceId); - const shortcutRef = useRef(null); - const avatarRef = useRef(null); - - const openSpaceOptions = (e, sId) => { - e.preventDefault(); - openReusableContextMenu( - 'right', - getEventCords(e, '.sidebar-avatar'), - (closeMenu) => , - ); - }; - - const [, drop] = useDrop({ - accept: 'SPACE_SHORTCUT', - collect(monitor) { - return { - handlerId: monitor.getHandlerId(), - }; - }, - drop(item) { - onDrop(item.index, item.spaceId); - }, - hover(item, monitor) { - if (!shortcutRef.current) return; - - const dragIndex = item.index; - const hoverIndex = index; - if (dragIndex === hoverIndex) return; - - const hoverBoundingRect = shortcutRef.current?.getBoundingClientRect(); - const hoverMiddleY = (hoverBoundingRect.bottom - hoverBoundingRect.top) / 2; - const clientOffset = monitor.getClientOffset(); - const hoverClientY = clientOffset.y - hoverBoundingRect.top; - - if (dragIndex < hoverIndex && hoverClientY < hoverMiddleY) { - return; - } - if (dragIndex > hoverIndex && hoverClientY > hoverMiddleY) { - return; - } - moveShortcut(dragIndex, hoverIndex); - // eslint-disable-next-line no-param-reassign - item.index = hoverIndex; - }, - }); - const [{ isDragging }, drag] = useDrag({ - type: 'SPACE_SHORTCUT', - item: () => ({ spaceId, index }), - collect: (monitor) => ({ - isDragging: monitor.isDragging(), - }), - }); - - drag(avatarRef); - drop(shortcutRef); - - if (shortcutRef.current) { - if (isDragging) shortcutRef.current.style.opacity = 0; - else shortcutRef.current.style.opacity = 1; - } - - return ( - selectTab(spaceId)} - onContextMenu={(e) => openSpaceOptions(e, spaceId)} - avatar={( - - )} - notificationBadge={notifications.hasNoti(spaceId) ? ( - 0} - content={abbreviateNumber(notifications.getTotalNoti(spaceId)) || null} - /> - ) : null} - /> - ); -} - -DraggableSpaceShortcut.propTypes = { - spaceId: PropTypes.string.isRequired, - isActive: PropTypes.bool.isRequired, - index: PropTypes.number.isRequired, - moveShortcut: PropTypes.func.isRequired, - onDrop: PropTypes.func.isRequired, -}; - -function SpaceShortcut() { - const { accountData } = initMatrix; - const [selectedTab] = useSelectedTab(); - useNotificationUpdate(); - const [spaceShortcut, setSpaceShortcut] = useState([...accountData.spaceShortcut]); - - useEffect(() => { - const handleShortcut = () => setSpaceShortcut([...accountData.spaceShortcut]); - accountData.on(cons.events.accountData.SPACE_SHORTCUT_UPDATED, handleShortcut); - return () => { - accountData.removeListener(cons.events.accountData.SPACE_SHORTCUT_UPDATED, handleShortcut); - }; - }, []); - - const moveShortcut = (dragIndex, hoverIndex) => { - const dragSpaceId = spaceShortcut[dragIndex]; - const newShortcuts = [...spaceShortcut]; - newShortcuts.splice(dragIndex, 1); - newShortcuts.splice(hoverIndex, 0, dragSpaceId); - setSpaceShortcut(newShortcuts); - }; - - const handleDrop = (dragIndex, dragSpaceId) => { - if ([...accountData.spaceShortcut][dragIndex] === dragSpaceId) return; - moveSpaceShortcut(dragSpaceId, dragIndex); - }; - - return ( - - { - spaceShortcut.map((shortcut, index) => ( - - )) - } - - ); -} - -function useTotalInvites() { - const { roomList } = initMatrix; - const totalInviteCount = () => roomList.inviteRooms.size - + roomList.inviteSpaces.size - + roomList.inviteDirects.size; - const [totalInvites, updateTotalInvites] = useState(totalInviteCount()); - - useEffect(() => { - const onInviteListChange = () => { - updateTotalInvites(totalInviteCount()); - }; - roomList.on(cons.events.roomList.INVITELIST_UPDATED, onInviteListChange); - return () => { - roomList.removeListener(cons.events.roomList.INVITELIST_UPDATED, onInviteListChange); - }; - }, []); - - return [totalInvites]; -} - -function SideBar() { - const [totalInvites] = useTotalInvites(); - - return ( -
      -
      - -
      -
      - -
      -
      -
      - - openShortcutSpaces()} - avatar={} - /> -
      -
      - -
      -
      -
      -
      - openSearch()} - avatar={} - /> - { totalInvites !== 0 && ( - openInviteList()} - avatar={} - notificationBadge={} - /> - )} - - -
      -
      -
      - ); -} - -export default SideBar; diff --git a/src/app/organisms/navigation/SideBar.scss b/src/app/organisms/navigation/SideBar.scss deleted file mode 100644 index 401947a41..000000000 --- a/src/app/organisms/navigation/SideBar.scss +++ /dev/null @@ -1,75 +0,0 @@ -@use '../../partials/flex'; -@use '../../partials/dir'; - -.sidebar { - @extend .cp-fx__column; - - width: var(--navigation-sidebar-width); - height: 100%; - background-color: var(--bg-surface-extra-low); - @include dir.side(border, none, 1px solid var(--bg-surface-border)); - - &__scrollable, - &__sticky { - width: 100%; - } - - &__scrollable { - @extend .cp-fx__item-one; - } -} - -.scrollable-content { - &::after { - content: ''; - display: block; - width: 100%; - height: 8px; - - background: transparent; - background-image: linear-gradient( - to top, - var(--bg-surface-extra-low), - var(--bg-surface-extra-low-transparent) - ); - position: sticky; - bottom: -1px; - left: 0; - } -} - -.featured-container, -.space-container, -.sticky-container { - @extend .cp-fx__column--c-c; - - padding: var(--sp-ultra-tight) 0; - - & > .sidebar-avatar, - & > .avatar-container { - margin: calc(var(--sp-tight) / 2) 0; - } -} -.sidebar-divider { - margin: auto; - width: 24px; - height: 1px; - background-color: var(--bg-surface-border); -} - -.sidebar__cross-signin-alert .avatar-container { - box-shadow: var(--bs-danger-border); - animation-name: pushRight; - animation-duration: 400ms; - animation-iteration-count: 30; - animation-direction: alternate; -} - -@keyframes pushRight { - from { - transform: translateX(4px) scale(1); - } - to { - transform: translateX(0) scale(1); - } -} diff --git a/src/app/organisms/profile-editor/ProfileEditor.jsx b/src/app/organisms/profile-editor/ProfileEditor.jsx index bb7359da3..c21c82fa4 100644 --- a/src/app/organisms/profile-editor/ProfileEditor.jsx +++ b/src/app/organisms/profile-editor/ProfileEditor.jsx @@ -1,6 +1,5 @@ import React, { useState, useEffect, useRef } from 'react'; import PropTypes from 'prop-types'; -import { twemojify } from '../../../util/twemojify'; import initMatrix from '../../../client/initMatrix'; import colorMXID from '../../../util/colorMXID'; @@ -22,7 +21,9 @@ function ProfileEditor({ userId }) { const user = mx.getUser(mx.getUserId()); const displayNameRef = useRef(null); - const [avatarSrc, setAvatarSrc] = useState(user.avatarUrl ? mx.mxcUrlToHttp(user.avatarUrl, 80, 80, 'crop') : null); + const [avatarSrc, setAvatarSrc] = useState( + user.avatarUrl ? mx.mxcUrlToHttp(user.avatarUrl, 80, 80, 'crop') : null + ); const [username, setUsername] = useState(user.displayName); const [disabled, setDisabled] = useState(true); @@ -44,7 +45,7 @@ function ProfileEditor({ userId }) { 'Remove avatar', 'Are you sure that you want to remove avatar?', 'Remove', - 'caution', + 'caution' ); if (isConfirmed) { mx.setAvatarUrl(''); @@ -79,7 +80,10 @@ function ProfileEditor({ userId }) {
      { e.preventDefault(); saveDisplayName(); }} + onSubmit={(e) => { + e.preventDefault(); + saveDisplayName(); + }} > - +
      ); @@ -95,7 +101,9 @@ function ProfileEditor({ userId }) { const renderInfo = () => (
      - {twemojify(username) ?? userId} + + {username ?? userId} + handleAvatarUpload(null)} /> - { - isEditing ? renderForm() : renderInfo() - } + {isEditing ? renderForm() : renderInfo()}
      ); } diff --git a/src/app/organisms/profile-viewer/ProfileViewer.jsx b/src/app/organisms/profile-viewer/ProfileViewer.jsx index b6ce426e0..b19c9c867 100644 --- a/src/app/organisms/profile-viewer/ProfileViewer.jsx +++ b/src/app/organisms/profile-viewer/ProfileViewer.jsx @@ -2,16 +2,17 @@ import React, { useState, useEffect, useRef } from 'react'; import PropTypes from 'prop-types'; import './ProfileViewer.scss'; -import { twemojify } from '../../../util/twemojify'; - import initMatrix from '../../../client/initMatrix'; import cons from '../../../client/state/cons'; import navigation from '../../../client/state/navigation'; -import { selectRoom, openReusableContextMenu } from '../../../client/action/navigation'; +import { openReusableContextMenu } from '../../../client/action/navigation'; import * as roomActions from '../../../client/action/room'; import { - getUsername, getUsernameOfRoomMember, getPowerLabel, hasDMWith, hasDevices, + getUsername, + getUsernameOfRoomMember, + getPowerLabel, + hasDevices, } from '../../../util/matrixUtil'; import { getEventCords } from '../../../util/common'; import colorMXID from '../../../util/colorMXID'; @@ -33,26 +34,24 @@ import CrossIC from '../../../../public/res/ic/outlined/cross.svg'; import { useForceUpdate } from '../../hooks/useForceUpdate'; import { confirmDialog } from '../../molecules/confirm-dialog/ConfirmDialog'; +import { useRoomNavigate } from '../../hooks/useRoomNavigate'; +import { getDMRoomFor } from '../../utils/matrix'; -function ModerationTools({ - roomId, userId, -}) { +function ModerationTools({ roomId, userId }) { const mx = initMatrix.matrixClient; const room = mx.getRoom(roomId); const roomMember = room.getMember(userId); const myPowerLevel = room.getMember(mx.getUserId())?.powerLevel || 0; const powerLevel = roomMember?.powerLevel || 0; - const canIKick = ( - roomMember?.membership === 'join' - && room.currentState.hasSufficientPowerLevelFor('kick', myPowerLevel) - && powerLevel < myPowerLevel - ); - const canIBan = ( - ['join', 'leave'].includes(roomMember?.membership) - && room.currentState.hasSufficientPowerLevelFor('ban', myPowerLevel) - && powerLevel < myPowerLevel - ); + const canIKick = + roomMember?.membership === 'join' && + room.currentState.hasSufficientPowerLevelFor('kick', myPowerLevel) && + powerLevel < myPowerLevel; + const canIBan = + ['join', 'leave'].includes(roomMember?.membership) && + room.currentState.hasSufficientPowerLevelFor('ban', myPowerLevel) && + powerLevel < myPowerLevel; const handleKick = (e) => { e.preventDefault(); @@ -120,13 +119,14 @@ function SessionInfo({ userId }) {
      {devices === null && Loading sessions...} {devices?.length === 0 && No session found.} - {devices !== null && (devices.map((device) => ( - - )))} + {devices !== null && + devices.map((device) => ( + + ))}
      ); } @@ -137,7 +137,11 @@ function SessionInfo({ userId }) { onClick={() => setIsVisible(!isVisible)} iconSrc={isVisible ? ChevronBottomIC : ChevronRightIC} > - {`View ${devices?.length > 0 ? `${devices.length} ${devices.length == 1 ? 'session' : 'sessions'}` : 'sessions'}`} + {`View ${ + devices?.length > 0 + ? `${devices.length} ${devices.length == 1 ? 'session' : 'sessions'}` + : 'sessions' + }`} {renderSessionChips()}
      @@ -155,6 +159,7 @@ function ProfileFooter({ roomId, userId, onRequestClose }) { const isMountedRef = useRef(true); const mx = initMatrix.matrixClient; + const { navigateRoom } = useRoomNavigate(); const room = mx.getRoom(roomId); const member = room.getMember(userId); const isInvitable = member?.membership !== 'join' && member?.membership !== 'ban'; @@ -164,25 +169,18 @@ function ProfileFooter({ roomId, userId, onRequestClose }) { const myPowerlevel = room.getMember(mx.getUserId())?.powerLevel || 0; const userPL = room.getMember(userId)?.powerLevel || 0; - const canIKick = room.currentState.hasSufficientPowerLevelFor('kick', myPowerlevel) && userPL < myPowerlevel; + const canIKick = + room.currentState.hasSufficientPowerLevelFor('kick', myPowerlevel) && userPL < myPowerlevel; const isBanned = member?.membership === 'ban'; const onCreated = (dmRoomId) => { if (isMountedRef.current === false) return; setIsCreatingDM(false); - selectRoom(dmRoomId); + navigateRoom(dmRoomId); onRequestClose(); }; - useEffect(() => { - const { roomList } = initMatrix; - roomList.on(cons.events.roomList.ROOM_CREATED, onCreated); - return () => { - isMountedRef.current = false; - roomList.removeListener(cons.events.roomList.ROOM_CREATED, onCreated); - }; - }, []); useEffect(() => { setIsUserIgnored(initMatrix.matrixClient.isUserIgnored(userId)); setIsIgnoring(false); @@ -191,9 +189,9 @@ function ProfileFooter({ roomId, userId, onRequestClose }) { const openDM = async () => { // Check and open if user already have a DM with userId. - const dmRoomId = hasDMWith(userId); + const dmRoomId = getDMRoomFor(mx, userId)?.roomId; if (dmRoomId) { - selectRoom(dmRoomId); + navigateRoom(dmRoomId); onRequestClose(); return; } @@ -201,7 +199,8 @@ function ProfileFooter({ roomId, userId, onRequestClose }) { // Create new DM try { setIsCreatingDM(true); - await roomActions.createDM(userId, await hasDevices(userId)); + const result = await roomActions.createDM(userId, await hasDevices(userId)); + onCreated(result.room_id); } catch { if (isMountedRef.current === false) return; setIsCreatingDM(false); @@ -246,31 +245,19 @@ function ProfileFooter({ roomId, userId, onRequestClose }) { return (
      - - { isBanned && canIKick && ( - )} - { (isInvited ? canIKick : room.canInvite(mx.getUserId())) && isInvitable && ( - )}
      ); @@ -326,8 +311,8 @@ function useRerenderOnProfileChange(roomId, userId) { useEffect(() => { const handleProfileChange = (mEvent, member) => { if ( - mEvent.getRoomId() === roomId - && (member.userId === userId || member.userId === mx.getUserId()) + mEvent.getRoomId() === roomId && + (member.userId === userId || member.userId === mx.getUserId()) ) { forceUpdate(); } @@ -352,20 +337,22 @@ function ProfileViewer() { const roomMember = room.getMember(userId); const username = roomMember ? getUsernameOfRoomMember(roomMember) : getUsername(userId); const avatarMxc = roomMember?.getMxcAvatarUrl?.() || mx.getUser(userId)?.avatarUrl; - const avatarUrl = (avatarMxc && avatarMxc !== 'null') ? mx.mxcUrlToHttp(avatarMxc, 80, 80, 'crop') : null; + const avatarUrl = + avatarMxc && avatarMxc !== 'null' ? mx.mxcUrlToHttp(avatarMxc, 80, 80, 'crop') : null; const powerLevel = roomMember?.powerLevel || 0; const myPowerLevel = room.getMember(mx.getUserId())?.powerLevel || 0; - const canChangeRole = ( - room.currentState.maySendEvent('m.room.power_levels', mx.getUserId()) - && (powerLevel < myPowerLevel || userId === mx.getUserId()) - ); + const canChangeRole = + room.currentState.maySendEvent('m.room.power_levels', mx.getUserId()) && + (powerLevel < myPowerLevel || userId === mx.getUserId()); const handleChangePowerLevel = async (newPowerLevel) => { if (newPowerLevel === powerLevel) return; - const SHARED_POWER_MSG = 'You will not be able to undo this change as you are promoting the user to have the same power level as yourself. Are you sure?'; - const DEMOTING_MYSELF_MSG = 'You will not be able to undo this change as you are demoting yourself. Are you sure?'; + const SHARED_POWER_MSG = + 'You will not be able to undo this change as you are promoting the user to have the same power level as yourself. Are you sure?'; + const DEMOTING_MYSELF_MSG = + 'You will not be able to undo this change as you are demoting yourself. Are you sure?'; const isSharedPower = newPowerLevel === myPowerLevel; const isDemotingMyself = userId === mx.getUserId(); @@ -374,7 +361,7 @@ function ProfileViewer() { 'Change power level', isSharedPower ? SHARED_POWER_MSG : DEMOTING_MYSELF_MSG, 'Change', - 'caution', + 'caution' ); if (!isConfirmed) return; roomActions.setPowerLevel(roomId, userId, newPowerLevel); @@ -384,20 +371,16 @@ function ProfileViewer() { }; const handlePowerSelector = (e) => { - openReusableContextMenu( - 'bottom', - getEventCords(e, '.btn-surface'), - (closeMenu) => ( - { - closeMenu(); - handleChangePowerLevel(pl); - }} - /> - ), - ); + openReusableContextMenu('bottom', getEventCords(e, '.btn-surface'), (closeMenu) => ( + { + closeMenu(); + handleChangePowerLevel(pl); + }} + /> + )); }; return ( @@ -405,8 +388,10 @@ function ProfileViewer() {
      - {twemojify(username)} - {twemojify(userId)} + + {username} + + {userId}
      Role @@ -420,7 +405,7 @@ function ProfileViewer() {
      - { userId !== mx.getUserId() && ( + {userId !== mx.getUserId() && ( )}
      diff --git a/src/app/organisms/public-rooms/PublicRooms.jsx b/src/app/organisms/public-rooms/PublicRooms.jsx deleted file mode 100644 index d1674c32f..000000000 --- a/src/app/organisms/public-rooms/PublicRooms.jsx +++ /dev/null @@ -1,295 +0,0 @@ -import React, { useState, useEffect, useRef } from 'react'; -import PropTypes from 'prop-types'; -import './PublicRooms.scss'; - -import initMatrix from '../../../client/initMatrix'; -import cons from '../../../client/state/cons'; -import { selectRoom, selectTab } from '../../../client/action/navigation'; -import * as roomActions from '../../../client/action/room'; - -import Text from '../../atoms/text/Text'; -import Button from '../../atoms/button/Button'; -import IconButton from '../../atoms/button/IconButton'; -import Spinner from '../../atoms/spinner/Spinner'; -import Input from '../../atoms/input/Input'; -import PopupWindow from '../../molecules/popup-window/PopupWindow'; -import RoomTile from '../../molecules/room-tile/RoomTile'; - -import CrossIC from '../../../../public/res/ic/outlined/cross.svg'; -import HashSearchIC from '../../../../public/res/ic/outlined/hash-search.svg'; - -const SEARCH_LIMIT = 20; - -function TryJoinWithAlias({ alias, onRequestClose }) { - const [status, setStatus] = useState({ - isJoining: false, - error: null, - roomId: null, - tempRoomId: null, - }); - function handleOnRoomAdded(roomId) { - if (status.tempRoomId !== null && status.tempRoomId !== roomId) return; - setStatus({ - isJoining: false, error: null, roomId, tempRoomId: null, - }); - } - - useEffect(() => { - initMatrix.roomList.on(cons.events.roomList.ROOM_JOINED, handleOnRoomAdded); - return () => { - initMatrix.roomList.removeListener(cons.events.roomList.ROOM_JOINED, handleOnRoomAdded); - }; - }, [status]); - - async function joinWithAlias() { - setStatus({ - isJoining: true, error: null, roomId: null, tempRoomId: null, - }); - try { - const roomId = await roomActions.join(alias, false); - setStatus({ - isJoining: true, error: null, roomId: null, tempRoomId: roomId, - }); - } catch (e) { - setStatus({ - isJoining: false, - error: `Unable to join ${alias}. Either room is private or doesn't exist.`, - roomId: null, - tempRoomId: null, - }); - } - } - - return ( -
      - {status.roomId === null && !status.isJoining && status.error === null && ( - - )} - {status.isJoining && ( - <> - - {`Joining ${alias}...`} - - )} - {status.roomId !== null && ( - - )} - {status.error !== null && {status.error}} -
      - ); -} - -TryJoinWithAlias.propTypes = { - alias: PropTypes.string.isRequired, - onRequestClose: PropTypes.func.isRequired, -}; - -function PublicRooms({ isOpen, searchTerm, onRequestClose }) { - const [isSearching, updateIsSearching] = useState(false); - const [isViewMore, updateIsViewMore] = useState(false); - const [publicRooms, updatePublicRooms] = useState([]); - const [nextBatch, updateNextBatch] = useState(undefined); - const [searchQuery, updateSearchQuery] = useState({}); - const [joiningRooms, updateJoiningRooms] = useState(new Set()); - - const roomNameRef = useRef(null); - const hsRef = useRef(null); - const userId = initMatrix.matrixClient.getUserId(); - - async function searchRooms(viewMore) { - let inputRoomName = roomNameRef?.current?.value || searchTerm; - let isInputAlias = false; - if (typeof inputRoomName === 'string') { - isInputAlias = inputRoomName[0] === '#' && inputRoomName.indexOf(':') > 1; - } - const hsFromAlias = (isInputAlias) ? inputRoomName.slice(inputRoomName.indexOf(':') + 1) : null; - let inputHs = hsFromAlias || hsRef?.current?.value; - - if (typeof inputHs !== 'string') inputHs = userId.slice(userId.indexOf(':') + 1); - if (typeof inputRoomName !== 'string') inputRoomName = ''; - - if (isSearching) return; - if (viewMore !== true - && inputRoomName === searchQuery.name - && inputHs === searchQuery.homeserver - ) return; - - updateSearchQuery({ - name: inputRoomName, - homeserver: inputHs, - }); - if (isViewMore !== viewMore) updateIsViewMore(viewMore); - updateIsSearching(true); - - try { - const result = await initMatrix.matrixClient.publicRooms({ - server: inputHs, - limit: SEARCH_LIMIT, - since: viewMore ? nextBatch : undefined, - include_all_networks: true, - filter: { - generic_search_term: inputRoomName, - }, - }); - - const totalRooms = viewMore ? publicRooms.concat(result.chunk) : result.chunk; - updatePublicRooms(totalRooms); - updateNextBatch(result.next_batch); - updateIsSearching(false); - updateIsViewMore(false); - if (totalRooms.length === 0) { - updateSearchQuery({ - error: inputRoomName === '' - ? `No public rooms on ${inputHs}` - : `No result found for "${inputRoomName}" on ${inputHs}`, - alias: isInputAlias ? inputRoomName : null, - }); - } - } catch (e) { - updatePublicRooms([]); - let err = 'Something went wrong!'; - if (e?.httpStatus >= 400 && e?.httpStatus < 500) { - err = e.message; - } - updateSearchQuery({ - error: err, - alias: isInputAlias ? inputRoomName : null, - }); - updateIsSearching(false); - updateNextBatch(undefined); - updateIsViewMore(false); - } - } - - useEffect(() => { - if (isOpen) searchRooms(); - }, [isOpen]); - - function handleOnRoomAdded(roomId) { - if (joiningRooms.has(roomId)) { - joiningRooms.delete(roomId); - updateJoiningRooms(new Set(Array.from(joiningRooms))); - } - } - useEffect(() => { - initMatrix.roomList.on(cons.events.roomList.ROOM_JOINED, handleOnRoomAdded); - return () => { - initMatrix.roomList.removeListener(cons.events.roomList.ROOM_JOINED, handleOnRoomAdded); - }; - }, [joiningRooms]); - - function handleViewRoom(roomId) { - const room = initMatrix.matrixClient.getRoom(roomId); - if (room.isSpaceRoom()) selectTab(roomId); - else selectRoom(roomId); - onRequestClose(); - } - - function joinRoom(roomIdOrAlias) { - joiningRooms.add(roomIdOrAlias); - updateJoiningRooms(new Set(Array.from(joiningRooms))); - roomActions.join(roomIdOrAlias, false); - } - - function renderRoomList(rooms) { - return rooms.map((room) => { - const alias = typeof room.canonical_alias === 'string' ? room.canonical_alias : room.room_id; - const name = typeof room.name === 'string' ? room.name : alias; - const isJoined = initMatrix.matrixClient.getRoom(room.room_id)?.getMyMembership() === 'join'; - return ( - - {isJoined && } - {!isJoined && (joiningRooms.has(room.room_id) ? : )} - - )} - /> - ); - }); - } - - return ( - } - onRequestClose={onRequestClose} - > -
      -
      { e.preventDefault(); searchRooms(); }}> -
      - - -
      - -
      -
      - { - typeof searchQuery.name !== 'undefined' && isSearching && ( - searchQuery.name === '' - ? ( -
      - - {`Loading public rooms from ${searchQuery.homeserver}...`} -
      - ) - : ( -
      - - {`Searching for "${searchQuery.name}" on ${searchQuery.homeserver}...`} -
      - ) - ) - } - { - typeof searchQuery.name !== 'undefined' && !isSearching && ( - searchQuery.name === '' - ? {`Public rooms on ${searchQuery.homeserver}.`} - : {`Search result for "${searchQuery.name}" on ${searchQuery.homeserver}.`} - ) - } - { searchQuery.error && ( - <> - {searchQuery.error} - {typeof searchQuery.alias === 'string' && ( - - )} - - )} -
      - { publicRooms.length !== 0 && ( -
      - { renderRoomList(publicRooms) } -
      - )} - { publicRooms.length !== 0 && publicRooms.length % SEARCH_LIMIT === 0 && ( -
      - { isViewMore !== true && ( - - )} - { isViewMore && } -
      - )} -
      -
      - ); -} - -PublicRooms.defaultProps = { - searchTerm: undefined, -}; - -PublicRooms.propTypes = { - isOpen: PropTypes.bool.isRequired, - searchTerm: PropTypes.string, - onRequestClose: PropTypes.func.isRequired, -}; - -export default PublicRooms; diff --git a/src/app/organisms/public-rooms/PublicRooms.scss b/src/app/organisms/public-rooms/PublicRooms.scss deleted file mode 100644 index dc55c9473..000000000 --- a/src/app/organisms/public-rooms/PublicRooms.scss +++ /dev/null @@ -1,85 +0,0 @@ -@use '../../partials/dir'; - -.public-rooms { - @include dir.side(margin, var(--sp-normal), var(--sp-extra-tight)); - margin-top: var(--sp-extra-tight); - - &__form { - display: flex; - align-items: flex-end; - - & .btn-primary { - padding: { - top: 11px; - bottom: 11px; - } - } - } - &__input-wrapper { - flex: 1; - min-width: 0; - - display: flex; - @include dir.side(margin, 0, var(--sp-normal)); - - & > div:first-child { - flex: 1; - min-width: 0; - - & .input { - @include dir.prop(border-radius, - var(--bo-radius) 0 0 var(--bo-radius), - 0 var(--bo-radius) var(--bo-radius) 0, - ); - } - } - - & > div:last-child .input { - width: 120px; - @include dir.prop(border-left-width, 0, 1px); - @include dir.prop(border-right-width, 1px, 0); - @include dir.prop(border-radius, - 0 var(--bo-radius) var(--bo-radius) 0, - var(--bo-radius) 0 0 var(--bo-radius), - ); - } - } - - &__search-status { - margin-top: var(--sp-extra-loose); - margin-bottom: var(--sp-tight); - & .donut-spinner { - margin: 0 var(--sp-tight); - } - - .try-join-with-alias { - margin-top: var(--sp-normal); - } - } - &__search-error { - color: var(--bg-danger); - } - &__content { - border-top: 1px solid var(--bg-surface-border); - } - &__view-more { - margin-top: var(--sp-loose); - @include dir.side(margin, calc(var(--av-normal) + var(--sp-normal)), 0); - } - - & .room-tile { - margin-top: var(--sp-normal); - &__options { - align-self: flex-end; - } - } -} - -.try-join-with-alias { - display: flex; - align-items: center; - - & >.text:nth-child(2) { - margin: 0 var(--sp-normal); - } -} \ No newline at end of file diff --git a/src/app/organisms/pw/Dialogs.jsx b/src/app/organisms/pw/Dialogs.jsx index a51d07e14..cc77cf18e 100644 --- a/src/app/organisms/pw/Dialogs.jsx +++ b/src/app/organisms/pw/Dialogs.jsx @@ -1,11 +1,8 @@ import React from 'react'; -import ReadReceipts from '../read-receipts/ReadReceipts'; import ProfileViewer from '../profile-viewer/ProfileViewer'; -import ShortcutSpaces from '../shortcut-spaces/ShortcutSpaces'; import SpaceAddExisting from '../../molecules/space-add-existing/SpaceAddExisting'; import Search from '../search/Search'; -import ViewSource from '../view-source/ViewSource'; import CreateRoom from '../create-room/CreateRoom'; import JoinAlias from '../join-alias/JoinAlias'; import EmojiVerification from '../emoji-verification/EmojiVerification'; @@ -15,10 +12,7 @@ import ReusableDialog from '../../molecules/dialog/ReusableDialog'; function Dialogs() { return ( <> - - - diff --git a/src/app/organisms/pw/Windows.jsx b/src/app/organisms/pw/Windows.jsx index 835b70334..3ee997695 100644 --- a/src/app/organisms/pw/Windows.jsx +++ b/src/app/organisms/pw/Windows.jsx @@ -3,35 +3,18 @@ import React, { useState, useEffect } from 'react'; import cons from '../../../client/state/cons'; import navigation from '../../../client/state/navigation'; -import InviteList from '../invite-list/InviteList'; -import PublicRooms from '../public-rooms/PublicRooms'; import InviteUser from '../invite-user/InviteUser'; import Settings from '../settings/Settings'; import SpaceSettings from '../space-settings/SpaceSettings'; -import SpaceManage from '../space-manage/SpaceManage'; import RoomSettings from '../room/RoomSettings'; function Windows() { - const [isInviteList, changeInviteList] = useState(false); - const [publicRooms, changePublicRooms] = useState({ - isOpen: false, - searchTerm: undefined, - }); const [inviteUser, changeInviteUser] = useState({ isOpen: false, roomId: undefined, term: undefined, }); - function openInviteList() { - changeInviteList(true); - } - function openPublicRooms(searchTerm) { - changePublicRooms({ - isOpen: true, - searchTerm, - }); - } function openInviteUser(roomId, searchTerm) { changeInviteUser({ isOpen: true, @@ -41,24 +24,14 @@ function Windows() { } useEffect(() => { - navigation.on(cons.events.navigation.INVITE_LIST_OPENED, openInviteList); - navigation.on(cons.events.navigation.PUBLIC_ROOMS_OPENED, openPublicRooms); navigation.on(cons.events.navigation.INVITE_USER_OPENED, openInviteUser); return () => { - navigation.removeListener(cons.events.navigation.INVITE_LIST_OPENED, openInviteList); - navigation.removeListener(cons.events.navigation.PUBLIC_ROOMS_OPENED, openPublicRooms); navigation.removeListener(cons.events.navigation.INVITE_USER_OPENED, openInviteUser); }; }, []); return ( <> - changeInviteList(false)} /> - changePublicRooms({ isOpen: false, searchTerm: undefined })} - /> - ); } diff --git a/src/app/organisms/read-receipts/ReadReceipts.jsx b/src/app/organisms/read-receipts/ReadReceipts.jsx deleted file mode 100644 index 1e648e0b6..000000000 --- a/src/app/organisms/read-receipts/ReadReceipts.jsx +++ /dev/null @@ -1,76 +0,0 @@ -import React, { useState, useEffect } from 'react'; - -import initMatrix from '../../../client/initMatrix'; -import cons from '../../../client/state/cons'; -import navigation from '../../../client/state/navigation'; -import { getUsername, getUsernameOfRoomMember } from '../../../util/matrixUtil'; -import colorMXID from '../../../util/colorMXID'; - -import IconButton from '../../atoms/button/IconButton'; -import PeopleSelector from '../../molecules/people-selector/PeopleSelector'; -import Dialog from '../../molecules/dialog/Dialog'; - -import CrossIC from '../../../../public/res/ic/outlined/cross.svg'; -import { openProfileViewer } from '../../../client/action/navigation'; - -function ReadReceipts() { - const [isOpen, setIsOpen] = useState(false); - const [readers, setReaders] = useState([]); - const [roomId, setRoomId] = useState(null); - - useEffect(() => { - const loadReadReceipts = (rId, userIds) => { - setReaders(userIds); - setRoomId(rId); - setIsOpen(true); - }; - navigation.on(cons.events.navigation.READRECEIPTS_OPENED, loadReadReceipts); - return () => { - navigation.removeListener(cons.events.navigation.READRECEIPTS_OPENED, loadReadReceipts); - }; - }, []); - - const handleAfterClose = () => { - setReaders([]); - setRoomId(null); - }; - - function renderPeople(userId) { - const room = initMatrix.matrixClient.getRoom(roomId); - const member = room.getMember(userId); - const getUserDisplayName = () => { - if (room?.getMember(userId)) return getUsernameOfRoomMember(room.getMember(userId)); - return getUsername(userId); - }; - return ( - { - setIsOpen(false); - openProfileViewer(userId, roomId); - }} - avatarSrc={member?.getAvatarUrl(initMatrix.matrixClient.baseUrl, 24, 24, 'crop')} - name={getUserDisplayName(userId)} - color={colorMXID(userId)} - /> - ); - } - - return ( - setIsOpen(false)} - contentOptions={ setIsOpen(false)} tooltip="Close" />} - > -
      - { - readers.map(renderPeople) - } -
      -
      - ); -} - -export default ReadReceipts; diff --git a/src/app/organisms/room/EventLimit.js b/src/app/organisms/room/EventLimit.js deleted file mode 100644 index de87da377..000000000 --- a/src/app/organisms/room/EventLimit.js +++ /dev/null @@ -1,35 +0,0 @@ -class EventLimit { - constructor() { - this._from = 0; - - this.SMALLEST_EVT_HEIGHT = 32; - this.PAGES_COUNT = 4; - } - - get maxEvents() { - return Math.round(document.body.clientHeight / this.SMALLEST_EVT_HEIGHT) * this.PAGES_COUNT; - } - - get from() { - return this._from; - } - - get length() { - return this._from + this.maxEvents; - } - - setFrom(from) { - this._from = from < 0 ? 0 : from; - } - - paginate(backwards, limit, timelineLength) { - this._from = backwards ? this._from - limit : this._from + limit; - - if (!backwards && this.length > timelineLength) { - this._from = timelineLength - this.maxEvents; - } - if (this._from < 0) this._from = 0; - } -} - -export default EventLimit; diff --git a/src/app/organisms/room/PeopleDrawer.jsx b/src/app/organisms/room/PeopleDrawer.jsx deleted file mode 100644 index 8f983247a..000000000 --- a/src/app/organisms/room/PeopleDrawer.jsx +++ /dev/null @@ -1,215 +0,0 @@ -import React, { - useState, useEffect, useCallback, useRef, -} from 'react'; -import PropTypes from 'prop-types'; -import './PeopleDrawer.scss'; - -import initMatrix from '../../../client/initMatrix'; -import { getPowerLabel, getUsernameOfRoomMember } from '../../../util/matrixUtil'; -import colorMXID from '../../../util/colorMXID'; -import { openInviteUser, openProfileViewer } from '../../../client/action/navigation'; -import AsyncSearch from '../../../util/AsyncSearch'; -import { memberByAtoZ, memberByPowerLevel } from '../../../util/sort'; - -import Text from '../../atoms/text/Text'; -import Header, { TitleWrapper } from '../../atoms/header/Header'; -import RawIcon from '../../atoms/system-icons/RawIcon'; -import IconButton from '../../atoms/button/IconButton'; -import Button from '../../atoms/button/Button'; -import ScrollView from '../../atoms/scroll/ScrollView'; -import Input from '../../atoms/input/Input'; -import SegmentedControl from '../../atoms/segmented-controls/SegmentedControls'; -import PeopleSelector from '../../molecules/people-selector/PeopleSelector'; - -import AddUserIC from '../../../../public/res/ic/outlined/add-user.svg'; -import SearchIC from '../../../../public/res/ic/outlined/search.svg'; -import CrossIC from '../../../../public/res/ic/outlined/cross.svg'; - -function simplyfiMembers(members) { - const mx = initMatrix.matrixClient; - return members.map((member) => ({ - userId: member.userId, - name: getUsernameOfRoomMember(member), - username: member.userId.slice(1, member.userId.indexOf(':')), - avatarSrc: member.getAvatarUrl(mx.baseUrl, 24, 24, 'crop'), - peopleRole: getPowerLabel(member.powerLevel), - powerLevel: members.powerLevel, - })); -} - -const asyncSearch = new AsyncSearch(); -function PeopleDrawer({ roomId }) { - const PER_PAGE_MEMBER = 50; - const mx = initMatrix.matrixClient; - const room = mx.getRoom(roomId); - const canInvite = room?.canInvite(mx.getUserId()); - - const [itemCount, setItemCount] = useState(PER_PAGE_MEMBER); - const [membership, setMembership] = useState('join'); - const [memberList, setMemberList] = useState([]); - const [searchedMembers, setSearchedMembers] = useState(null); - const searchRef = useRef(null); - - const getMembersWithMembership = useCallback( - (mship) => room.getMembersWithMembership(mship), - [roomId, membership], - ); - - function loadMorePeople() { - setItemCount(itemCount + PER_PAGE_MEMBER); - } - - function handleSearchData(data) { - // NOTICE: data is passed as object property - // because react sucks at handling state update with array. - setSearchedMembers({ data }); - setItemCount(PER_PAGE_MEMBER); - } - - function handleSearch(e) { - const term = e.target.value; - if (term === '' || term === undefined) { - searchRef.current.value = ''; - searchRef.current.focus(); - setSearchedMembers(null); - setItemCount(PER_PAGE_MEMBER); - } else asyncSearch.search(term); - } - - useEffect(() => { - asyncSearch.setup(memberList, { - keys: ['name', 'username', 'userId'], - limit: PER_PAGE_MEMBER, - }); - }, [memberList]); - - useEffect(() => { - let isLoadingMembers = false; - let isRoomChanged = false; - const updateMemberList = (event) => { - if (isLoadingMembers) return; - if (event && event?.getRoomId() !== roomId) return; - setMemberList( - simplyfiMembers( - getMembersWithMembership(membership) - .sort(memberByAtoZ).sort(memberByPowerLevel), - ), - ); - }; - searchRef.current.value = ''; - updateMemberList(); - isLoadingMembers = true; - room.loadMembersIfNeeded().then(() => { - isLoadingMembers = false; - if (isRoomChanged) return; - updateMemberList(); - }); - - asyncSearch.on(asyncSearch.RESULT_SENT, handleSearchData); - mx.on('RoomMember.membership', updateMemberList); - mx.on('RoomMember.powerLevel', updateMemberList); - return () => { - isRoomChanged = true; - setMemberList([]); - setSearchedMembers(null); - setItemCount(PER_PAGE_MEMBER); - asyncSearch.removeListener(asyncSearch.RESULT_SENT, handleSearchData); - mx.removeListener('RoomMember.membership', updateMemberList); - mx.removeListener('RoomMember.powerLevel', updateMemberList); - }; - }, [roomId, membership]); - - useEffect(() => { - setMembership('join'); - }, [roomId]); - - const mList = searchedMembers !== null ? searchedMembers.data : memberList.slice(0, itemCount); - return ( -
      -
      - - - People - {`${room.getJoinedMemberCount()} members`} - - - openInviteUser(roomId)} tooltip="Invite" src={AddUserIC} disabled={!canInvite} /> -
      -
      -
      - -
      - { - const getSegmentIndex = { - join: 0, - invite: 1, - ban: 2, - }; - return getSegmentIndex[membership]; - })() - } - segments={[{ text: 'Joined' }, { text: 'Invited' }, { text: 'Banned' }]} - onSelect={(index) => { - const selectSegment = [ - () => setMembership('join'), - () => setMembership('invite'), - () => setMembership('ban'), - ]; - selectSegment[index]?.(); - }} - /> - { - mList.map((member) => ( - openProfileViewer(member.userId, roomId)} - avatarSrc={member.avatarSrc} - name={member.name} - color={colorMXID(member.userId)} - peopleRole={member.peopleRole} - /> - )) - } - { - (searchedMembers?.data.length === 0 || memberList.length === 0) - && ( -
      - No results found! -
      - ) - } -
      - { - mList.length !== 0 - && memberList.length > itemCount - && searchedMembers === null - && ( - - ) - } -
      -
      -
      -
      -
      -
      e.preventDefault()} className="people-search"> - - - { - searchedMembers !== null - && - } - -
      -
      -
      - ); -} - -PeopleDrawer.propTypes = { - roomId: PropTypes.string.isRequired, -}; - -export default PeopleDrawer; diff --git a/src/app/organisms/room/PeopleDrawer.scss b/src/app/organisms/room/PeopleDrawer.scss deleted file mode 100644 index cfc5f6c98..000000000 --- a/src/app/organisms/room/PeopleDrawer.scss +++ /dev/null @@ -1,93 +0,0 @@ -@use '../../partials/flex'; -@use '../../partials/dir'; - -.people-drawer { - @extend .cp-fx__column; - width: var(--people-drawer-width); - background-color: var(--bg-surface-low); - @include dir.side(border, 1px solid var(--bg-surface-border), none); - - &__member-count { - color: var(--tc-surface-low); - } - - &__content-wrapper { - @extend .cp-fx__item-one; - @extend .cp-fx__column; - } - - &__scrollable { - @extend .cp-fx__item-one; - } - - &__noresult { - padding: var(--sp-extra-tight) var(--sp-normal); - text-align: center; - } - - &__sticky { - & .people-search { - --search-input-height: 40px; - min-height: var(--search-input-height); - - margin: 0 var(--sp-extra-tight); - - position: relative; - bottom: var(--sp-normal); - display: flex; - align-items: center; - - & > .ic-raw, - & > .ic-btn { - position: absolute; - z-index: 99; - } - & > .ic-raw { - @include dir.prop(left, var(--sp-tight), unset); - @include dir.prop(right, unset, var(--sp-tight)); - } - & > .ic-btn { - @include dir.prop(right, 2px, unset); - @include dir.prop(left, unset, 2px); - } - & .input-container { - flex: 1; - } - & .input { - padding: 0 44px; - height: var(--search-input-height); - } - } - } -} - -.people-drawer__content { - padding-top: var(--sp-extra-tight); - padding-bottom: calc(2 * var(--sp-normal)); - - & .people-selector { - padding: var(--sp-extra-tight); - border-radius: var(--bo-radius); - &__container { - @include dir.side(margin, var(--sp-extra-tight), 0); - } - } - - & .segmented-controls { - display: flex; - margin-bottom: var(--sp-extra-tight); - @include dir.side(margin, var(--sp-extra-tight), 0); - } - & .segment-btn { - flex: 1; - padding: var(--sp-ultra-tight) 0; - } -} -.people-drawer__load-more { - padding: var(--sp-normal) 0 0; - @include dir.side(padding, var(--sp-normal), var(--sp-extra-tight)); - - & .btn-surface { - width: 100%; - } -} \ No newline at end of file diff --git a/src/app/organisms/room/Room.scss b/src/app/organisms/room/Room.scss deleted file mode 100644 index 69f8f9dd3..000000000 --- a/src/app/organisms/room/Room.scss +++ /dev/null @@ -1,20 +0,0 @@ -@use '../../partials/flex'; -@use '../../partials/screen'; - -.room { - @extend .cp-fx__row; - height: 100%; - flex-grow: 1; - - &__content { - @extend .cp-fx__item-one; - position: relative; - overflow: hidden; - } -} - -.room .people-drawer { - @include screen.smallerThan(tabletBreakpoint) { - display: none; - } -} diff --git a/src/app/organisms/room/RoomSettings.jsx b/src/app/organisms/room/RoomSettings.jsx index 1e617ae7e..2b8f28e66 100644 --- a/src/app/organisms/room/RoomSettings.jsx +++ b/src/app/organisms/room/RoomSettings.jsx @@ -5,7 +5,6 @@ import './RoomSettings.scss'; import initMatrix from '../../../client/initMatrix'; import cons from '../../../client/state/cons'; import navigation from '../../../client/state/navigation'; -import * as roomActions from '../../../client/action/room'; import Text from '../../atoms/text/Text'; import Tabs from '../../atoms/tabs/Tabs'; @@ -86,7 +85,7 @@ function GeneralSettings({ roomId }) { 'danger' ); if (!isConfirmed) return; - roomActions.leave(roomId); + mx.leave(roomId); }} iconSrc={LeaveArrowIC} > diff --git a/src/app/organisms/room/RoomView.scss b/src/app/organisms/room/RoomView.scss deleted file mode 100644 index c70c2b092..000000000 --- a/src/app/organisms/room/RoomView.scss +++ /dev/null @@ -1,46 +0,0 @@ -@use '../../partials/flex'; -@use '../../partials/screen'; -@use '../../partials/dir'; - -.room-view { - @extend .cp-fx__column; - background-color: var(--bg-surface); - height: 100%; - width: 100%; - position: absolute; - top: 0; - z-index: 999; - box-shadow: none; - - transition: transform 200ms var(--fluid-slide-down); - - &--dropped { - transform: translateY(calc(100% - var(--header-height))); - border-radius: var(--bo-radius) var(--bo-radius) 0 0; - box-shadow: var(--bs-popup); - } - - & .header { - @include screen.smallerThan(mobileBreakpoint) { - padding: 0 var(--sp-tight); - } - } - - &__content-wrapper { - @extend .cp-fx__item-one; - @extend .cp-fx__column; - } - - &__scrollable { - @extend .cp-fx__item-one; - position: relative; - } - - &__sticky { - position: relative; - background: var(--bg-surface); - } - &__editor { - padding: 0 var(--sp-normal); - } -} diff --git a/src/app/organisms/room/RoomViewCmdBar.jsx b/src/app/organisms/room/RoomViewCmdBar.jsx deleted file mode 100644 index 0d21123bd..000000000 --- a/src/app/organisms/room/RoomViewCmdBar.jsx +++ /dev/null @@ -1,297 +0,0 @@ -/* eslint-disable react/prop-types */ -import React, { useState, useEffect } from 'react'; -import PropTypes from 'prop-types'; -import './RoomViewCmdBar.scss'; -import parse from 'html-react-parser'; -import twemoji from 'twemoji'; - -import { twemojify, TWEMOJI_BASE_URL } from '../../../util/twemojify'; - -import initMatrix from '../../../client/initMatrix'; -import { getEmojiForCompletion } from '../emoji-board/custom-emoji'; -import AsyncSearch from '../../../util/AsyncSearch'; - -import Text from '../../atoms/text/Text'; -import ScrollView from '../../atoms/scroll/ScrollView'; -import FollowingMembers from '../../molecules/following-members/FollowingMembers'; -import { addRecentEmoji, getRecentEmojis } from '../emoji-board/recent'; -import commands from './commands'; - -function CmdItem({ onClick, children }) { - return ( - - ); -} -CmdItem.propTypes = { - onClick: PropTypes.func.isRequired, - children: PropTypes.node.isRequired, -}; - -function renderSuggestions({ prefix, option, suggestions }, fireCmd) { - function renderCmdSuggestions(cmdPrefix, cmds) { - const cmdOptString = typeof option === 'string' ? `/${option}` : '/?'; - return cmds.map((cmd) => ( - { - fireCmd({ - prefix: cmdPrefix, - option, - result: commands[cmd], - }); - }} - > - {`${cmd}${cmd.isOptions ? cmdOptString : ''}`} - - )); - } - - function renderEmojiSuggestion(emPrefix, emos) { - const mx = initMatrix.matrixClient; - - // Renders a small Twemoji - function renderTwemoji(emoji) { - return parse( - twemoji.parse(emoji.unicode, { - attributes: () => ({ - unicode: emoji.unicode, - shortcodes: emoji.shortcodes?.toString(), - }), - base: TWEMOJI_BASE_URL, - }) - ); - } - - // Render a custom emoji - function renderCustomEmoji(emoji) { - return ( - {`:${emoji.shortcode}:`} - ); - } - - // Dynamically render either a custom emoji or twemoji based on what the input is - function renderEmoji(emoji) { - if (emoji.mxc) { - return renderCustomEmoji(emoji); - } - return renderTwemoji(emoji); - } - - return emos.map((emoji) => ( - - fireCmd({ - prefix: emPrefix, - result: emoji, - }) - } - > - {renderEmoji(emoji)} - {`:${emoji.shortcode}:`} - - )); - } - - function renderNameSuggestion(namePrefix, members) { - return members.map((member) => ( - { - fireCmd({ - prefix: namePrefix, - result: member, - }); - }} - > - {twemojify(member.name)} - - )); - } - - const cmd = { - '/': (cmds) => renderCmdSuggestions(prefix, cmds), - ':': (emos) => renderEmojiSuggestion(prefix, emos), - '@': (members) => renderNameSuggestion(prefix, members), - }; - return cmd[prefix]?.(suggestions); -} - -const asyncSearch = new AsyncSearch(); -let cmdPrefix; -let cmdOption; -function RoomViewCmdBar({ roomId, roomTimeline, viewEvent }) { - const [cmd, setCmd] = useState(null); - - function displaySuggestions(suggestions) { - if (suggestions.length === 0) { - setCmd({ prefix: cmd?.prefix || cmdPrefix, error: 'No suggestion found.' }); - viewEvent.emit('cmd_error'); - return; - } - setCmd({ prefix: cmd?.prefix || cmdPrefix, suggestions, option: cmdOption }); - } - - function processCmd(prefix, slug) { - let searchTerm = slug; - cmdOption = undefined; - cmdPrefix = prefix; - if (prefix === '/') { - const cmdSlugParts = slug.split('/'); - [searchTerm, cmdOption] = cmdSlugParts; - } - if (prefix === ':') { - if (searchTerm.length <= 3) { - if (searchTerm.match(/^[-]?(\))$/)) searchTerm = 'smile'; - else if (searchTerm.match(/^[-]?(s|S)$/)) searchTerm = 'confused'; - else if (searchTerm.match(/^[-]?(o|O|0)$/)) searchTerm = 'astonished'; - else if (searchTerm.match(/^[-]?(\|)$/)) searchTerm = 'neutral_face'; - else if (searchTerm.match(/^[-]?(d|D)$/)) searchTerm = 'grin'; - else if (searchTerm.match(/^[-]?(\/)$/)) searchTerm = 'frown'; - else if (searchTerm.match(/^[-]?(p|P)$/)) searchTerm = 'stuck_out_tongue'; - else if (searchTerm.match(/^'[-]?(\()$/)) searchTerm = 'cry'; - else if (searchTerm.match(/^[-]?(x|X)$/)) searchTerm = 'dizzy_face'; - else if (searchTerm.match(/^[-]?(\()$/)) searchTerm = 'pleading_face'; - else if (searchTerm.match(/^[-]?(\$)$/)) searchTerm = 'money'; - else if (searchTerm.match(/^(<3)$/)) searchTerm = 'heart'; - else if (searchTerm.match(/^(c|ca|cat)$/)) searchTerm = '_cat'; - } - } - - asyncSearch.search(searchTerm); - } - function activateCmd(prefix) { - cmdPrefix = prefix; - cmdPrefix = undefined; - - const mx = initMatrix.matrixClient; - const setupSearch = { - '/': () => { - asyncSearch.setup(Object.keys(commands), { isContain: true }); - setCmd({ prefix, suggestions: Object.keys(commands) }); - }, - ':': () => { - const parentIds = initMatrix.roomList.getAllParentSpaces(roomId); - const parentRooms = [...parentIds].map((id) => mx.getRoom(id)); - const emojis = getEmojiForCompletion(mx, [mx.getRoom(roomId), ...parentRooms]); - const recentEmoji = getRecentEmojis(20); - asyncSearch.setup(emojis, { keys: ['shortcode'], isContain: true, limit: 20 }); - setCmd({ - prefix, - suggestions: recentEmoji.length > 0 ? recentEmoji : emojis.slice(26, 46), - }); - }, - '@': () => { - const members = mx - .getRoom(roomId) - .getJoinedMembers() - .map((member) => ({ - name: member.name, - userId: member.userId.slice(1), - })); - asyncSearch.setup(members, { keys: ['name', 'userId'], limit: 20 }); - const endIndex = members.length > 20 ? 20 : members.length; - setCmd({ prefix, suggestions: members.slice(0, endIndex) }); - }, - }; - setupSearch[prefix]?.(); - } - function deactivateCmd() { - setCmd(null); - cmdOption = undefined; - cmdPrefix = undefined; - } - function fireCmd(myCmd) { - if (myCmd.prefix === '/') { - viewEvent.emit('cmd_fired', { - replace: `/${myCmd.result.name}`, - }); - } - if (myCmd.prefix === ':') { - if (!myCmd.result.mxc) addRecentEmoji(myCmd.result.unicode); - viewEvent.emit('cmd_fired', { - replace: myCmd.result.mxc ? `:${myCmd.result.shortcode}: ` : myCmd.result.unicode, - }); - } - if (myCmd.prefix === '@') { - viewEvent.emit('cmd_fired', { - replace: `@${myCmd.result.userId}`, - }); - } - deactivateCmd(); - } - - function listenKeyboard(event) { - const { activeElement } = document; - const lastCmdItem = document.activeElement.parentNode.lastElementChild; - if (event.key === 'Escape') { - if (activeElement.className !== 'cmd-item') return; - viewEvent.emit('focus_msg_input'); - } - if (event.key === 'Tab') { - if (lastCmdItem.className !== 'cmd-item') return; - if (lastCmdItem !== activeElement) return; - if (event.shiftKey) return; - viewEvent.emit('focus_msg_input'); - event.preventDefault(); - } - } - - useEffect(() => { - viewEvent.on('cmd_activate', activateCmd); - viewEvent.on('cmd_deactivate', deactivateCmd); - return () => { - deactivateCmd(); - viewEvent.removeListener('cmd_activate', activateCmd); - viewEvent.removeListener('cmd_deactivate', deactivateCmd); - }; - }, [roomId]); - - useEffect(() => { - if (cmd !== null) document.body.addEventListener('keydown', listenKeyboard); - viewEvent.on('cmd_process', processCmd); - asyncSearch.on(asyncSearch.RESULT_SENT, displaySuggestions); - return () => { - if (cmd !== null) document.body.removeEventListener('keydown', listenKeyboard); - - viewEvent.removeListener('cmd_process', processCmd); - asyncSearch.removeListener(asyncSearch.RESULT_SENT, displaySuggestions); - }; - }, [cmd]); - - const isError = typeof cmd?.error === 'string'; - if (cmd === null || isError) { - return ( -
      - -
      - ); - } - - return ( -
      -
      - TAB -
      -
      - -
      {renderSuggestions(cmd, fireCmd)}
      -
      -
      -
      - ); -} -RoomViewCmdBar.propTypes = { - roomId: PropTypes.string.isRequired, - roomTimeline: PropTypes.shape({}).isRequired, - viewEvent: PropTypes.shape({}).isRequired, -}; - -export default RoomViewCmdBar; diff --git a/src/app/organisms/room/RoomViewCmdBar.scss b/src/app/organisms/room/RoomViewCmdBar.scss deleted file mode 100644 index 3f03fb06a..000000000 --- a/src/app/organisms/room/RoomViewCmdBar.scss +++ /dev/null @@ -1,57 +0,0 @@ -@use '../../partials/flex'; -@use '../../partials/text'; -@use '../../partials/dir'; - -.cmd-bar { - --cmd-bar-height: 28px; - min-height: var(--cmd-bar-height); - display: flex; - - &__info { - display: flex; - width: 40px; - @include dir.side(margin, 14px, 10px); - - & > * { - margin: auto; - } - } - - &__content { - @extend .cp-fx__item-one; - display: flex; - - &-suggestions { - height: 100%; - white-space: nowrap; - display: flex; - align-items: center; - - & > .text { - @extend .cp-txt__ellipsis; - } - } - } -} - -.cmd-item { - --cmd-item-bar: inset 0 -2px 0 0 var(--bg-caution); - height: 100%; - @include dir.side(margin, 0, var(--sp-extra-tight)); - padding: 0 var(--sp-extra-tight); - border-radius: var(--bo-radius) var(--bo-radius) 0 0; - cursor: pointer; - - display: inline-flex; - align-items: center; - - &:hover { - background-color: var(--bg-caution-hover); - } - &:focus { - background-color: var(--bg-caution-active); - box-shadow: var(--cmd-item-bar); - border-bottom: 2px solid transparent; - outline: none; - } -} \ No newline at end of file diff --git a/src/app/organisms/room/RoomViewContent.jsx b/src/app/organisms/room/RoomViewContent.jsx deleted file mode 100644 index 5726fe119..000000000 --- a/src/app/organisms/room/RoomViewContent.jsx +++ /dev/null @@ -1,644 +0,0 @@ -/* eslint-disable jsx-a11y/no-static-element-interactions */ -/* eslint-disable jsx-a11y/click-events-have-key-events */ -/* eslint-disable react/prop-types */ -import React, { - useState, useEffect, useLayoutEffect, useCallback, useRef, -} from 'react'; -import PropTypes from 'prop-types'; -import './RoomViewContent.scss'; - -import dateFormat from 'dateformat'; -import { twemojify } from '../../../util/twemojify'; - -import initMatrix from '../../../client/initMatrix'; -import cons from '../../../client/state/cons'; -import navigation from '../../../client/state/navigation'; -import { openProfileViewer } from '../../../client/action/navigation'; -import { diffMinutes, isInSameDay, Throttle } from '../../../util/common'; -import { markAsRead } from '../../../client/action/notifications'; - -import Divider from '../../atoms/divider/Divider'; -import ScrollView from '../../atoms/scroll/ScrollView'; -import { Message, PlaceholderMessage } from '../../molecules/message/Message'; -import RoomIntro from '../../molecules/room-intro/RoomIntro'; -import TimelineChange from '../../molecules/message/TimelineChange'; - -import { useStore } from '../../hooks/useStore'; -import { useForceUpdate } from '../../hooks/useForceUpdate'; -import { parseTimelineChange } from './common'; -import TimelineScroll from './TimelineScroll'; -import EventLimit from './EventLimit'; -import { getResizeObserverEntry, useResizeObserver } from '../../hooks/useResizeObserver'; - -const PAG_LIMIT = 30; -const MAX_MSG_DIFF_MINUTES = 5; -const PLACEHOLDER_COUNT = 2; -const PLACEHOLDERS_HEIGHT = 96 * PLACEHOLDER_COUNT; -const SCROLL_TRIGGER_POS = PLACEHOLDERS_HEIGHT * 4; - -function loadingMsgPlaceholders(key, count = 2) { - const pl = []; - const genPlaceholders = () => { - for (let i = 0; i < count; i += 1) { - pl.push(); - } - return pl; - }; - - return ( - - {genPlaceholders()} - - ); -} - -function RoomIntroContainer({ event, timeline }) { - const [, nameForceUpdate] = useForceUpdate(); - const mx = initMatrix.matrixClient; - const { roomList } = initMatrix; - const { room } = timeline; - const roomTopic = room.currentState.getStateEvents('m.room.topic')[0]?.getContent().topic; - const isDM = roomList.directs.has(timeline.roomId); - let avatarSrc = room.getAvatarUrl(mx.baseUrl, 80, 80, 'crop'); - avatarSrc = isDM ? room.getAvatarFallbackMember()?.getAvatarUrl(mx.baseUrl, 80, 80, 'crop') : avatarSrc; - - const heading = isDM ? room.name : `Welcome to ${room.name}`; - const topic = twemojify(roomTopic || '', undefined, true); - const nameJsx = twemojify(room.name); - const desc = isDM - ? ( - <> - This is the beginning of your direct message history with @ - {nameJsx} - {'. '} - {topic} - - ) - : ( - <> - {'This is the beginning of the '} - {nameJsx} - {' room. '} - {topic} - - ); - - useEffect(() => { - const handleUpdate = () => nameForceUpdate(); - - roomList.on(cons.events.roomList.ROOM_PROFILE_UPDATED, handleUpdate); - return () => { - roomList.removeListener(cons.events.roomList.ROOM_PROFILE_UPDATED, handleUpdate); - }; - }, []); - - return ( - - ); -} - -function handleOnClickCapture(e) { - const { target, nativeEvent } = e; - - const userId = target.getAttribute('data-mx-pill'); - if (userId) { - const roomId = navigation.selectedRoomId; - openProfileViewer(userId, roomId); - } - - const spoiler = nativeEvent.composedPath().find((el) => el?.hasAttribute?.('data-mx-spoiler')); - if (spoiler) { - if (!spoiler.classList.contains('data-mx-spoiler--visible')) e.preventDefault(); - spoiler.classList.toggle('data-mx-spoiler--visible'); - } -} - -function renderEvent( - roomTimeline, - mEvent, - prevMEvent, - isFocus, - isEdit, - setEdit, - cancelEdit, -) { - const isBodyOnly = (prevMEvent !== null - && prevMEvent.getSender() === mEvent.getSender() - && prevMEvent.getType() !== 'm.room.member' - && prevMEvent.getType() !== 'm.room.create' - && diffMinutes(mEvent.getDate(), prevMEvent.getDate()) <= MAX_MSG_DIFF_MINUTES - ); - const timestamp = mEvent.getTs(); - - if (mEvent.getType() === 'm.room.member') { - const timelineChange = parseTimelineChange(mEvent); - if (timelineChange === null) return
      ; - return ( - - ); - } - return ( - - ); -} - -function useTimeline(roomTimeline, eventId, readUptoEvtStore, eventLimitRef) { - const [timelineInfo, setTimelineInfo] = useState(null); - - const setEventTimeline = async (eId) => { - if (typeof eId === 'string') { - const isLoaded = await roomTimeline.loadEventTimeline(eId); - if (isLoaded) return; - // if eventTimeline failed to load, - // we will load live timeline as fallback. - } - roomTimeline.loadLiveTimeline(); - }; - - useEffect(() => { - const limit = eventLimitRef.current; - const initTimeline = (eId) => { - // NOTICE: eId can be id of readUpto, reply or specific event. - // readUpTo: when user click jump to unread message button. - // reply: when user click reply from timeline. - // specific event when user open a link of event. behave same as ^^^^ - const readUpToId = roomTimeline.getReadUpToEventId(); - let focusEventIndex = -1; - const isSpecificEvent = eId && eId !== readUpToId; - - if (isSpecificEvent) { - focusEventIndex = roomTimeline.getEventIndex(eId); - } - if (!readUptoEvtStore.getItem() && roomTimeline.hasEventInTimeline(readUpToId)) { - // either opening live timeline or jump to unread. - readUptoEvtStore.setItem(roomTimeline.findEventByIdInTimelineSet(readUpToId)); - } - if (readUptoEvtStore.getItem() && !isSpecificEvent) { - focusEventIndex = roomTimeline.getUnreadEventIndex(readUptoEvtStore.getItem().getId()); - } - - if (focusEventIndex > -1) { - limit.setFrom(focusEventIndex - Math.round(limit.maxEvents / 2)); - } else { - limit.setFrom(roomTimeline.timeline.length - limit.maxEvents); - } - setTimelineInfo({ focusEventId: isSpecificEvent ? eId : null }); - }; - - roomTimeline.on(cons.events.roomTimeline.READY, initTimeline); - setEventTimeline(eventId); - return () => { - roomTimeline.removeListener(cons.events.roomTimeline.READY, initTimeline); - limit.setFrom(0); - }; - }, [roomTimeline, eventId]); - - return timelineInfo; -} - -function usePaginate( - roomTimeline, - readUptoEvtStore, - forceUpdateLimit, - timelineScrollRef, - eventLimitRef, -) { - const [info, setInfo] = useState(null); - - useEffect(() => { - const handlePaginatedFromServer = (backwards, loaded) => { - const limit = eventLimitRef.current; - if (loaded === 0) return; - if (!readUptoEvtStore.getItem()) { - const readUpToId = roomTimeline.getReadUpToEventId(); - readUptoEvtStore.setItem(roomTimeline.findEventByIdInTimelineSet(readUpToId)); - } - limit.paginate(backwards, PAG_LIMIT, roomTimeline.timeline.length); - setTimeout(() => setInfo({ - backwards, - loaded, - })); - }; - roomTimeline.on(cons.events.roomTimeline.PAGINATED, handlePaginatedFromServer); - return () => { - roomTimeline.removeListener(cons.events.roomTimeline.PAGINATED, handlePaginatedFromServer); - }; - }, [roomTimeline]); - - const autoPaginate = useCallback(async () => { - const timelineScroll = timelineScrollRef.current; - const limit = eventLimitRef.current; - if (roomTimeline.isOngoingPagination) return; - const tLength = roomTimeline.timeline.length; - - if (timelineScroll.bottom < SCROLL_TRIGGER_POS) { - if (limit.length < tLength) { - // paginate from memory - limit.paginate(false, PAG_LIMIT, tLength); - forceUpdateLimit(); - } else if (roomTimeline.canPaginateForward()) { - // paginate from server. - await roomTimeline.paginateTimeline(false, PAG_LIMIT); - return; - } - } - if (timelineScroll.top < SCROLL_TRIGGER_POS) { - if (limit.from > 0) { - // paginate from memory - limit.paginate(true, PAG_LIMIT, tLength); - forceUpdateLimit(); - } else if (roomTimeline.canPaginateBackward()) { - // paginate from server. - await roomTimeline.paginateTimeline(true, PAG_LIMIT); - } - } - }, [roomTimeline]); - - return [info, autoPaginate]; -} - -function useHandleScroll( - roomTimeline, - autoPaginate, - readUptoEvtStore, - forceUpdateLimit, - timelineScrollRef, - eventLimitRef, -) { - const handleScroll = useCallback(() => { - const timelineScroll = timelineScrollRef.current; - const limit = eventLimitRef.current; - requestAnimationFrame(() => { - // emit event to toggle scrollToBottom button visibility - const isAtBottom = ( - timelineScroll.bottom < 16 && !roomTimeline.canPaginateForward() - && limit.length >= roomTimeline.timeline.length - ); - roomTimeline.emit(cons.events.roomTimeline.AT_BOTTOM, isAtBottom); - if (isAtBottom && readUptoEvtStore.getItem()) { - requestAnimationFrame(() => markAsRead(roomTimeline.roomId)); - } - }); - autoPaginate(); - }, [roomTimeline]); - - const handleScrollToLive = useCallback(() => { - const timelineScroll = timelineScrollRef.current; - const limit = eventLimitRef.current; - if (readUptoEvtStore.getItem()) { - requestAnimationFrame(() => markAsRead(roomTimeline.roomId)); - } - if (roomTimeline.isServingLiveTimeline()) { - limit.setFrom(roomTimeline.timeline.length - limit.maxEvents); - timelineScroll.scrollToBottom(); - forceUpdateLimit(); - return; - } - roomTimeline.loadLiveTimeline(); - }, [roomTimeline]); - - return [handleScroll, handleScrollToLive]; -} - -function useEventArrive(roomTimeline, readUptoEvtStore, timelineScrollRef, eventLimitRef) { - const myUserId = initMatrix.matrixClient.getUserId(); - const [newEvent, setEvent] = useState(null); - - useEffect(() => { - const timelineScroll = timelineScrollRef.current; - const limit = eventLimitRef.current; - const trySendReadReceipt = (event) => { - if (myUserId === event.getSender()) { - requestAnimationFrame(() => markAsRead(roomTimeline.roomId)); - return; - } - const readUpToEvent = readUptoEvtStore.getItem(); - const readUpToId = roomTimeline.getReadUpToEventId(); - const isUnread = readUpToEvent ? readUpToEvent?.getId() === readUpToId : true; - - if (isUnread === false) { - if (document.visibilityState === 'visible' && timelineScroll.bottom < 16) { - requestAnimationFrame(() => markAsRead(roomTimeline.roomId)); - } else { - readUptoEvtStore.setItem(roomTimeline.findEventByIdInTimelineSet(readUpToId)); - } - return; - } - - const { timeline } = roomTimeline; - const unreadMsgIsLast = timeline[timeline.length - 2].getId() === readUpToId; - if (unreadMsgIsLast) { - requestAnimationFrame(() => markAsRead(roomTimeline.roomId)); - } - }; - - const handleEvent = (event) => { - const tLength = roomTimeline.timeline.length; - const isViewingLive = roomTimeline.isServingLiveTimeline() && limit.length >= tLength - 1; - const isAttached = timelineScroll.bottom < SCROLL_TRIGGER_POS; - - if (isViewingLive && isAttached && document.hasFocus()) { - limit.setFrom(tLength - limit.maxEvents); - trySendReadReceipt(event); - setEvent(event); - return; - } - const isRelates = (event.getType() === 'm.reaction' || event.getRelation()?.rel_type === 'm.replace'); - if (isRelates) { - setEvent(event); - return; - } - - if (isViewingLive) { - // This stateUpdate will help to put the - // loading msg placeholder at bottom - setEvent(event); - } - }; - - const handleEventRedact = (event) => setEvent(event); - - roomTimeline.on(cons.events.roomTimeline.EVENT, handleEvent); - roomTimeline.on(cons.events.roomTimeline.EVENT_REDACTED, handleEventRedact); - return () => { - roomTimeline.removeListener(cons.events.roomTimeline.EVENT, handleEvent); - roomTimeline.removeListener(cons.events.roomTimeline.EVENT_REDACTED, handleEventRedact); - }; - }, [roomTimeline]); - - return newEvent; -} - -let jumpToItemIndex = -1; - -function RoomViewContent({ roomInputRef, eventId, roomTimeline }) { - const [throttle] = useState(new Throttle()); - - const timelineSVRef = useRef(null); - const timelineScrollRef = useRef(null); - const eventLimitRef = useRef(null); - const [editEventId, setEditEventId] = useState(null); - const cancelEdit = () => setEditEventId(null); - - const readUptoEvtStore = useStore(roomTimeline); - const [onLimitUpdate, forceUpdateLimit] = useForceUpdate(); - - const timelineInfo = useTimeline(roomTimeline, eventId, readUptoEvtStore, eventLimitRef); - const [paginateInfo, autoPaginate] = usePaginate( - roomTimeline, - readUptoEvtStore, - forceUpdateLimit, - timelineScrollRef, - eventLimitRef, - ); - const [handleScroll, handleScrollToLive] = useHandleScroll( - roomTimeline, - autoPaginate, - readUptoEvtStore, - forceUpdateLimit, - timelineScrollRef, - eventLimitRef, - ); - const newEvent = useEventArrive(roomTimeline, readUptoEvtStore, timelineScrollRef, eventLimitRef); - - const { timeline } = roomTimeline; - - useLayoutEffect(() => { - if (!roomTimeline.initialized) { - timelineScrollRef.current = new TimelineScroll(timelineSVRef.current); - eventLimitRef.current = new EventLimit(); - } - }); - - // when active timeline changes - useEffect(() => { - if (!roomTimeline.initialized) return undefined; - const timelineScroll = timelineScrollRef.current; - - if (timeline.length > 0) { - if (jumpToItemIndex === -1) { - timelineScroll.scrollToBottom(); - } else { - timelineScroll.scrollToIndex(jumpToItemIndex, 80); - } - if (timelineScroll.bottom < 16 && !roomTimeline.canPaginateForward()) { - const readUpToId = roomTimeline.getReadUpToEventId(); - if (readUptoEvtStore.getItem()?.getId() === readUpToId || readUpToId === null) { - requestAnimationFrame(() => markAsRead(roomTimeline.roomId)); - } - } - jumpToItemIndex = -1; - } - autoPaginate(); - - roomTimeline.on(cons.events.roomTimeline.SCROLL_TO_LIVE, handleScrollToLive); - return () => { - if (timelineSVRef.current === null) return; - roomTimeline.removeListener(cons.events.roomTimeline.SCROLL_TO_LIVE, handleScrollToLive); - }; - }, [timelineInfo]); - - // when paginating from server - useEffect(() => { - if (!roomTimeline.initialized) return; - const timelineScroll = timelineScrollRef.current; - timelineScroll.tryRestoringScroll(); - autoPaginate(); - }, [paginateInfo]); - - // when paginating locally - useEffect(() => { - if (!roomTimeline.initialized) return; - const timelineScroll = timelineScrollRef.current; - timelineScroll.tryRestoringScroll(); - }, [onLimitUpdate]); - - useEffect(() => { - const timelineScroll = timelineScrollRef.current; - if (!roomTimeline.initialized) return; - if (timelineScroll.bottom < 16 && !roomTimeline.canPaginateForward() && document.visibilityState === 'visible') { - timelineScroll.scrollToBottom(); - } else { - timelineScroll.tryRestoringScroll(); - } - }, [newEvent]); - - useResizeObserver( - useCallback((entries) => { - if (!roomInputRef.current) return; - const editorBaseEntry = getResizeObserverEntry(roomInputRef.current, entries); - if (!editorBaseEntry) return; - - const timelineScroll = timelineScrollRef.current; - if (!roomTimeline.initialized) return; - if (timelineScroll.bottom < 40 && !roomTimeline.canPaginateForward() && document.visibilityState === 'visible') { - timelineScroll.scrollToBottom(); - } - }, [roomInputRef]), - useCallback(() => roomInputRef.current, [roomInputRef]), - ); - - const listenKeyboard = useCallback((event) => { - if (event.ctrlKey || event.altKey || event.metaKey) return; - if (event.key !== 'ArrowUp') return; - if (navigation.isRawModalVisible) return; - - if (document.activeElement.id !== 'message-textarea') return; - if (document.activeElement.value !== '') return; - - const { - timeline: tl, activeTimeline, liveTimeline, matrixClient: mx, - } = roomTimeline; - const limit = eventLimitRef.current; - if (activeTimeline !== liveTimeline) return; - if (tl.length > limit.length) return; - - const mTypes = ['m.text']; - for (let i = tl.length - 1; i >= 0; i -= 1) { - const mE = tl[i]; - if ( - mE.getSender() === mx.getUserId() - && mE.getType() === 'm.room.message' - && mTypes.includes(mE.getContent()?.msgtype) - ) { - setEditEventId(mE.getId()); - return; - } - } - }, [roomTimeline]); - - useEffect(() => { - document.body.addEventListener('keydown', listenKeyboard); - return () => { - document.body.removeEventListener('keydown', listenKeyboard); - }; - }, [listenKeyboard]); - - const handleTimelineScroll = (event) => { - const timelineScroll = timelineScrollRef.current; - if (!event.target) return; - - throttle._(() => { - const backwards = timelineScroll?.calcScroll(); - if (typeof backwards !== 'boolean') return; - handleScroll(backwards); - }, 200)(); - }; - - const renderTimeline = () => { - const tl = []; - const limit = eventLimitRef.current; - - let itemCountIndex = 0; - jumpToItemIndex = -1; - const readUptoEvent = readUptoEvtStore.getItem(); - let unreadDivider = false; - - if (roomTimeline.canPaginateBackward() || limit.from > 0) { - tl.push(loadingMsgPlaceholders(1, PLACEHOLDER_COUNT)); - itemCountIndex += PLACEHOLDER_COUNT; - } - for (let i = limit.from; i < limit.length; i += 1) { - if (i >= timeline.length) break; - const mEvent = timeline[i]; - const prevMEvent = timeline[i - 1] ?? null; - - if (i === 0 && !roomTimeline.canPaginateBackward()) { - if (mEvent.getType() === 'm.room.create') { - tl.push( - , - ); - itemCountIndex += 1; - // eslint-disable-next-line no-continue - continue; - } else { - tl.push(); - itemCountIndex += 1; - } - } - - let isNewEvent = false; - if (!unreadDivider) { - unreadDivider = (readUptoEvent - && prevMEvent?.getTs() <= readUptoEvent.getTs() - && readUptoEvent.getTs() < mEvent.getTs()); - if (unreadDivider) { - isNewEvent = true; - tl.push(); - itemCountIndex += 1; - if (jumpToItemIndex === -1) jumpToItemIndex = itemCountIndex; - } - } - const dayDivider = prevMEvent && !isInSameDay(mEvent.getDate(), prevMEvent.getDate()); - if (dayDivider) { - tl.push(); - itemCountIndex += 1; - } - - const focusId = timelineInfo.focusEventId; - const isFocus = focusId === mEvent.getId(); - if (isFocus) jumpToItemIndex = itemCountIndex; - - tl.push(renderEvent( - roomTimeline, - mEvent, - isNewEvent ? null : prevMEvent, - isFocus, - editEventId === mEvent.getId(), - setEditEventId, - cancelEdit, - )); - itemCountIndex += 1; - } - if (roomTimeline.canPaginateForward() || limit.length < timeline.length) { - tl.push(loadingMsgPlaceholders(2, PLACEHOLDER_COUNT)); - } - - return tl; - }; - - return ( - -
      -
      - { roomTimeline.initialized ? renderTimeline() : loadingMsgPlaceholders('loading', 3) } -
      -
      -
      - ); -} - -RoomViewContent.defaultProps = { - eventId: null, -}; -RoomViewContent.propTypes = { - eventId: PropTypes.string, - roomTimeline: PropTypes.shape({}).isRequired, - roomInputRef: PropTypes.shape({ - current: PropTypes.shape({}) - }).isRequired -}; - -export default RoomViewContent; diff --git a/src/app/organisms/room/RoomViewContent.scss b/src/app/organisms/room/RoomViewContent.scss deleted file mode 100644 index 1afd187ef..000000000 --- a/src/app/organisms/room/RoomViewContent.scss +++ /dev/null @@ -1,30 +0,0 @@ -@use '../../partials/dir'; - -.room-view__content { - min-height: 100%; - display: flex; - flex-direction: column; - justify-content: flex-end; - - & .timeline__wrapper { - --typing-noti-height: 28px; - min-height: 0; - min-width: 0; - padding-bottom: var(--typing-noti-height); - - & .message, - & .ph-msg, - & .timeline-change { - @include dir.prop(border-radius, - 0 var(--bo-radius) var(--bo-radius) 0, - var(--bo-radius) 0 0 var(--bo-radius), - ); - } - - & > .divider { - margin: var(--sp-extra-tight); - @include dir.side(margin, var(--sp-normal), var(--sp-extra-tight)); - @include dir.side(padding, calc(var(--av-small) + var(--sp-tight)), 0); - } - } -} \ No newline at end of file diff --git a/src/app/organisms/room/RoomViewFloating.jsx b/src/app/organisms/room/RoomViewFloating.jsx deleted file mode 100644 index d027aff21..000000000 --- a/src/app/organisms/room/RoomViewFloating.jsx +++ /dev/null @@ -1,125 +0,0 @@ -/* eslint-disable react/prop-types */ -import React, { useState, useEffect } from 'react'; -import PropTypes from 'prop-types'; -import './RoomViewFloating.scss'; - -import initMatrix from '../../../client/initMatrix'; -import cons from '../../../client/state/cons'; -import { markAsRead } from '../../../client/action/notifications'; - -import Text from '../../atoms/text/Text'; -import Button from '../../atoms/button/Button'; - -import MessageIC from '../../../../public/res/ic/outlined/message.svg'; -import MessageUnreadIC from '../../../../public/res/ic/outlined/message-unread.svg'; -import TickMarkIC from '../../../../public/res/ic/outlined/tick-mark.svg'; - -import { getUsersActionJsx } from './common'; - -function useJumpToEvent(roomTimeline) { - const [eventId, setEventId] = useState(null); - - const jumpToEvent = () => { - roomTimeline.loadEventTimeline(eventId); - }; - - const cancelJumpToEvent = () => { - markAsRead(roomTimeline.roomId); - setEventId(null); - }; - - useEffect(() => { - const readEventId = roomTimeline.getReadUpToEventId(); - // we only show "Jump to unread" btn only if the event is not in timeline. - // if event is in timeline - // we will automatically open the timeline from that event position - if (!readEventId?.startsWith('~') && !roomTimeline.hasEventInTimeline(readEventId)) { - setEventId(readEventId); - } - - const { notifications } = initMatrix; - const handleMarkAsRead = () => setEventId(null); - notifications.on(cons.events.notifications.FULL_READ, handleMarkAsRead); - - return () => { - notifications.removeListener(cons.events.notifications.FULL_READ, handleMarkAsRead); - setEventId(null); - }; - }, [roomTimeline]); - - return [!!eventId, jumpToEvent, cancelJumpToEvent]; -} - -function useTypingMembers(roomTimeline) { - const [typingMembers, setTypingMembers] = useState(new Set()); - - const updateTyping = (members) => { - const mx = initMatrix.matrixClient; - members.delete(mx.getUserId()); - setTypingMembers(members); - }; - - useEffect(() => { - setTypingMembers(new Set()); - roomTimeline.on(cons.events.roomTimeline.TYPING_MEMBERS_UPDATED, updateTyping); - return () => { - roomTimeline?.removeListener(cons.events.roomTimeline.TYPING_MEMBERS_UPDATED, updateTyping); - }; - }, [roomTimeline]); - - return [typingMembers]; -} - -function useScrollToBottom(roomTimeline) { - const [isAtBottom, setIsAtBottom] = useState(true); - const handleAtBottom = (atBottom) => setIsAtBottom(atBottom); - - useEffect(() => { - setIsAtBottom(true); - roomTimeline.on(cons.events.roomTimeline.AT_BOTTOM, handleAtBottom); - return () => roomTimeline.removeListener(cons.events.roomTimeline.AT_BOTTOM, handleAtBottom); - }, [roomTimeline]); - - return [isAtBottom, setIsAtBottom]; -} - -function RoomViewFloating({ - roomId, roomTimeline, -}) { - const [isJumpToEvent, jumpToEvent, cancelJumpToEvent] = useJumpToEvent(roomTimeline); - const [typingMembers] = useTypingMembers(roomTimeline); - const [isAtBottom, setIsAtBottom] = useScrollToBottom(roomTimeline); - - const handleScrollToBottom = () => { - roomTimeline.emit(cons.events.roomTimeline.SCROLL_TO_LIVE); - setIsAtBottom(true); - }; - - return ( - <> -
      - - -
      -
      0 ? ' room-view__typing--open' : ''}`}> -
      - {getUsersActionJsx(roomId, [...typingMembers], 'typing...')} -
      -
      - -
      - - ); -} -RoomViewFloating.propTypes = { - roomId: PropTypes.string.isRequired, - roomTimeline: PropTypes.shape({}).isRequired, -}; - -export default RoomViewFloating; diff --git a/src/app/organisms/room/RoomViewFloating.scss b/src/app/organisms/room/RoomViewFloating.scss deleted file mode 100644 index 75802175a..000000000 --- a/src/app/organisms/room/RoomViewFloating.scss +++ /dev/null @@ -1,125 +0,0 @@ - @use '../../partials/flex'; -@use '../../partials/text'; -@use '../../partials/dir'; - -.room-view { - &__typing { - display: flex; - padding: var(--sp-ultra-tight) var(--sp-normal); - background: var(--bg-surface); - transition: transform 200ms ease-in-out; - - & b { - color: var(--tc-surface-high); - } - - & .text { - @extend .cp-txt__ellipsis; - @extend .cp-fx__item-one; - - margin: 0 var(--sp-tight); - } - - &--open { - transform: translateY(-99%); - box-shadow: 0 4px 0 0 var(--bg-surface); - & .bouncing-loader { - & > *, - &::after, - &::before { - animation: bouncing-loader 0.6s infinite alternate; - } - } - } - } - - .bouncing-loader { - transform: translateY(2px); - margin: 0 calc(var(--sp-ultra-tight) / 2); - } - .bouncing-loader > div, - .bouncing-loader::before, - .bouncing-loader::after { - display: inline-block; - width: 8px; - height: 8px; - background: var(--tc-surface-high); - border-radius: 50%; - } - - - .bouncing-loader::before, - .bouncing-loader::after { - content: ""; - } - - .bouncing-loader > div { - margin: 0 4px; - } - - .bouncing-loader > div { - animation-delay: 0.2s; - } - - .bouncing-loader::after { - animation-delay: 0.4s; - } - - @keyframes bouncing-loader { - to { - opacity: 0.1; - transform: translate3d(0, -4px, 0); - } - } - - &__STB, - &__unread { - overflow: hidden; - background-color: var(--bg-surface-low); - border-radius: var(--bo-radius); - - & button { - justify-content: flex-start; - border-radius: 0; - box-shadow: none; - padding: 6px var(--sp-tight); - & .ic-raw { - width: 16px; - height: 16px; - } - } - } - - &__STB { - position: absolute; - @include dir.prop(left, 50%, unset); - @include dir.prop(right, unset, 50%); - bottom: 0; - box-shadow: var(--bs-surface-border); - transition: transform 200ms ease-in-out; - transform: translate(-50%, 100%); - - &--open { - transform: translate(-50%, -28px); - } - } - - &__unread { - position: absolute; - top: var(--sp-extra-tight); - @include dir.prop(left, var(--sp-normal), unset); - @include dir.prop(right, unset, var(--sp-normal)); - z-index: 999; - - display: none; - width: calc(100% - var(--sp-extra-loose)); - box-shadow: 0 0 2px 0 rgba(0, 0, 0, 20%); - - &--open { - display: flex; - } - & button:first-child { - @extend .cp-fx__item-one; - } - } -} \ No newline at end of file diff --git a/src/app/organisms/room/RoomViewHeader.jsx b/src/app/organisms/room/RoomViewHeader.jsx deleted file mode 100644 index 6571241eb..000000000 --- a/src/app/organisms/room/RoomViewHeader.jsx +++ /dev/null @@ -1,132 +0,0 @@ -import React, { useEffect, useRef } from 'react'; -import PropTypes from 'prop-types'; -import './RoomViewHeader.scss'; - -import { twemojify } from '../../../util/twemojify'; -import { blurOnBubbling } from '../../atoms/button/script'; - -import initMatrix from '../../../client/initMatrix'; -import cons from '../../../client/state/cons'; -import navigation from '../../../client/state/navigation'; -import { - toggleRoomSettings, - openReusableContextMenu, - openNavigation, -} from '../../../client/action/navigation'; -import colorMXID from '../../../util/colorMXID'; -import { getEventCords } from '../../../util/common'; - -import { tabText } from './RoomSettings'; -import Text from '../../atoms/text/Text'; -import RawIcon from '../../atoms/system-icons/RawIcon'; -import IconButton from '../../atoms/button/IconButton'; -import Header, { TitleWrapper } from '../../atoms/header/Header'; -import Avatar from '../../atoms/avatar/Avatar'; -import RoomOptions from '../../molecules/room-options/RoomOptions'; - -import ChevronBottomIC from '../../../../public/res/ic/outlined/chevron-bottom.svg'; -import SearchIC from '../../../../public/res/ic/outlined/search.svg'; -import UserIC from '../../../../public/res/ic/outlined/user.svg'; -import VerticalMenuIC from '../../../../public/res/ic/outlined/vertical-menu.svg'; -import BackArrowIC from '../../../../public/res/ic/outlined/chevron-left.svg'; - -import { useForceUpdate } from '../../hooks/useForceUpdate'; -import { useSetSetting } from '../../state/hooks/settings'; -import { settingsAtom } from '../../state/settings'; - -function RoomViewHeader({ roomId }) { - const [, forceUpdate] = useForceUpdate(); - const mx = initMatrix.matrixClient; - const isDM = initMatrix.roomList.directs.has(roomId); - const room = mx.getRoom(roomId); - const setPeopleDrawer = useSetSetting(settingsAtom, 'isPeopleDrawer'); - let avatarSrc = room.getAvatarUrl(mx.baseUrl, 36, 36, 'crop'); - avatarSrc = isDM - ? room.getAvatarFallbackMember()?.getAvatarUrl(mx.baseUrl, 36, 36, 'crop') - : avatarSrc; - const roomName = room.name; - - const roomHeaderBtnRef = useRef(null); - useEffect(() => { - const settingsToggle = (isVisibile) => { - const rawIcon = roomHeaderBtnRef.current.lastElementChild; - rawIcon.style.transform = isVisibile ? 'rotateX(180deg)' : 'rotateX(0deg)'; - }; - navigation.on(cons.events.navigation.ROOM_SETTINGS_TOGGLED, settingsToggle); - return () => { - navigation.removeListener(cons.events.navigation.ROOM_SETTINGS_TOGGLED, settingsToggle); - }; - }, []); - - useEffect(() => { - const { roomList } = initMatrix; - const handleProfileUpdate = (rId) => { - if (roomId !== rId) return; - forceUpdate(); - }; - - roomList.on(cons.events.roomList.ROOM_PROFILE_UPDATED, handleProfileUpdate); - return () => { - roomList.removeListener(cons.events.roomList.ROOM_PROFILE_UPDATED, handleProfileUpdate); - }; - }, [roomId]); - - const openRoomOptions = (e) => { - openReusableContextMenu('bottom', getEventCords(e, '.ic-btn'), (closeMenu) => ( - - )); - }; - - return ( -
      - openNavigation()} - /> - - {mx.isRoomEncrypted(roomId) === false && ( - toggleRoomSettings(tabText.SEARCH)} - tooltip="Search" - src={SearchIC} - /> - )} - { - setPeopleDrawer((t) => !t); - }} - tooltip="People" - src={UserIC} - /> - toggleRoomSettings(tabText.MEMBERS)} - tooltip="Members" - src={UserIC} - /> - -
      - ); -} -RoomViewHeader.propTypes = { - roomId: PropTypes.string.isRequired, -}; - -export default RoomViewHeader; diff --git a/src/app/organisms/room/RoomViewHeader.scss b/src/app/organisms/room/RoomViewHeader.scss deleted file mode 100644 index fc19c064c..000000000 --- a/src/app/organisms/room/RoomViewHeader.scss +++ /dev/null @@ -1,47 +0,0 @@ -@use '../../partials/flex'; -@use '../../partials/dir'; -@use '../../partials/screen'; - -.room-header__btn { - min-width: 0; - @extend .cp-fx__row--s-c; - @include dir.side(margin, 0, auto); - border-radius: var(--bo-radius); - cursor: pointer; - - & .ic-raw { - @include dir.side(margin, 0, var(--sp-extra-tight)); - transition: transform 200ms ease-in-out; - } - @media (hover:hover) { - &:hover { - background-color: var(--bg-surface-hover); - box-shadow: var(--bs-surface-outline); - } - } - &:focus, - &:active { - background-color: var(--bg-surface-active); - box-shadow: var(--bs-surface-outline); - outline: none; - } -} - -.room-header__drawer-btn { - @include screen.smallerThan(tabletBreakpoint) { - display: none; - } -} -.room-header__members-btn { - @include screen.biggerThan(tabletBreakpoint) { - display: none; - } -} - -.room-header__back-btn { - @include dir.side(margin, 0, var(--sp-tight)); - - @include screen.biggerThan(mobileBreakpoint) { - display: none; - } -} diff --git a/src/app/organisms/room/RoomViewInput.jsx b/src/app/organisms/room/RoomViewInput.jsx deleted file mode 100644 index 3fb780a4d..000000000 --- a/src/app/organisms/room/RoomViewInput.jsx +++ /dev/null @@ -1,491 +0,0 @@ -/* eslint-disable react/prop-types */ -import React, { useState, useEffect, useRef } from 'react'; -import PropTypes from 'prop-types'; -import './RoomViewInput.scss'; - -import TextareaAutosize from 'react-autosize-textarea'; - -import initMatrix from '../../../client/initMatrix'; -import cons from '../../../client/state/cons'; -import settings from '../../../client/state/settings'; -import { openEmojiBoard, openReusableContextMenu } from '../../../client/action/navigation'; -import navigation from '../../../client/state/navigation'; -import { bytesToSize, getEventCords } from '../../../util/common'; -import { getUsername } from '../../../util/matrixUtil'; -import colorMXID from '../../../util/colorMXID'; - -import Text from '../../atoms/text/Text'; -import RawIcon from '../../atoms/system-icons/RawIcon'; -import IconButton from '../../atoms/button/IconButton'; -import ScrollView from '../../atoms/scroll/ScrollView'; -import { MessageReply } from '../../molecules/message/Message'; - -import StickerBoard from '../sticker-board/StickerBoard'; -import { confirmDialog } from '../../molecules/confirm-dialog/ConfirmDialog'; - -import CirclePlusIC from '../../../../public/res/ic/outlined/circle-plus.svg'; -import EmojiIC from '../../../../public/res/ic/outlined/emoji.svg'; -import SendIC from '../../../../public/res/ic/outlined/send.svg'; -import StickerIC from '../../../../public/res/ic/outlined/sticker.svg'; -import ShieldIC from '../../../../public/res/ic/outlined/shield.svg'; -import VLCIC from '../../../../public/res/ic/outlined/vlc.svg'; -import VolumeFullIC from '../../../../public/res/ic/outlined/volume-full.svg'; -import FileIC from '../../../../public/res/ic/outlined/file.svg'; -import CrossIC from '../../../../public/res/ic/outlined/cross.svg'; - -import commands from './commands'; - -const CMD_REGEX = /(^\/|:|@)(\S*)$/; -let isTyping = false; -let isCmdActivated = false; -let cmdCursorPos = null; -function RoomViewInput({ - roomId, roomTimeline, viewEvent, -}) { - const [attachment, setAttachment] = useState(null); - const [replyTo, setReplyTo] = useState(null); - - const textAreaRef = useRef(null); - const inputBaseRef = useRef(null); - const uploadInputRef = useRef(null); - const uploadProgressRef = useRef(null); - const rightOptionsRef = useRef(null); - - const TYPING_TIMEOUT = 5000; - const mx = initMatrix.matrixClient; - const { roomsInput } = initMatrix; - - function requestFocusInput() { - if (textAreaRef === null) return; - textAreaRef.current.focus(); - } - - useEffect(() => { - roomsInput.on(cons.events.roomsInput.ATTACHMENT_SET, setAttachment); - viewEvent.on('focus_msg_input', requestFocusInput); - return () => { - roomsInput.removeListener(cons.events.roomsInput.ATTACHMENT_SET, setAttachment); - viewEvent.removeListener('focus_msg_input', requestFocusInput); - }; - }, []); - - const sendIsTyping = (isT) => { - mx.sendTyping(roomId, isT, isT ? TYPING_TIMEOUT : undefined); - isTyping = isT; - - if (isT === true) { - setTimeout(() => { - if (isTyping) sendIsTyping(false); - }, TYPING_TIMEOUT); - } - }; - - function uploadingProgress(myRoomId, { loaded, total }) { - if (myRoomId !== roomId) return; - const progressPer = Math.round((loaded * 100) / total); - uploadProgressRef.current.textContent = `Uploading: ${bytesToSize(loaded)}/${bytesToSize(total)} (${progressPer}%)`; - inputBaseRef.current.style.backgroundImage = `linear-gradient(90deg, var(--bg-surface-hover) ${progressPer}%, var(--bg-surface-low) ${progressPer}%)`; - } - function clearAttachment(myRoomId) { - if (roomId !== myRoomId) return; - setAttachment(null); - inputBaseRef.current.style.backgroundImage = 'unset'; - uploadInputRef.current.value = null; - } - - function rightOptionsA11Y(A11Y) { - const rightOptions = rightOptionsRef.current.children; - for (let index = 0; index < rightOptions.length; index += 1) { - rightOptions[index].tabIndex = A11Y ? 0 : -1; - } - } - - function activateCmd(prefix) { - isCmdActivated = true; - rightOptionsA11Y(false); - viewEvent.emit('cmd_activate', prefix); - } - function deactivateCmd() { - isCmdActivated = false; - cmdCursorPos = null; - rightOptionsA11Y(true); - } - function deactivateCmdAndEmit() { - deactivateCmd(); - viewEvent.emit('cmd_deactivate'); - } - function setCursorPosition(pos) { - setTimeout(() => { - textAreaRef.current.focus(); - textAreaRef.current.setSelectionRange(pos, pos); - }, 0); - } - function replaceCmdWith(msg, cursor, replacement) { - if (msg === null) return null; - const targetInput = msg.slice(0, cursor); - const cmdParts = targetInput.match(CMD_REGEX); - const leadingInput = msg.slice(0, cmdParts.index); - if (replacement.length > 0) setCursorPosition(leadingInput.length + replacement.length); - return leadingInput + replacement + msg.slice(cursor); - } - function firedCmd(cmdData) { - const msg = textAreaRef.current.value; - textAreaRef.current.value = replaceCmdWith( - msg, - cmdCursorPos, - typeof cmdData?.replace !== 'undefined' ? cmdData.replace : '', - ); - deactivateCmd(); - } - - function focusInput() { - if (settings.isTouchScreenDevice) return; - textAreaRef.current.focus(); - } - - function setUpReply(userId, eventId, body, formattedBody) { - setReplyTo({ userId, eventId, body }); - roomsInput.setReplyTo(roomId, { - userId, eventId, body, formattedBody, - }); - focusInput(); - } - - useEffect(() => { - roomsInput.on(cons.events.roomsInput.UPLOAD_PROGRESS_CHANGES, uploadingProgress); - roomsInput.on(cons.events.roomsInput.ATTACHMENT_CANCELED, clearAttachment); - roomsInput.on(cons.events.roomsInput.FILE_UPLOADED, clearAttachment); - viewEvent.on('cmd_fired', firedCmd); - navigation.on(cons.events.navigation.REPLY_TO_CLICKED, setUpReply); - if (textAreaRef?.current !== null) { - isTyping = false; - textAreaRef.current.value = roomsInput.getMessage(roomId); - setAttachment(roomsInput.getAttachment(roomId)); - setReplyTo(roomsInput.getReplyTo(roomId)); - } - return () => { - roomsInput.removeListener(cons.events.roomsInput.UPLOAD_PROGRESS_CHANGES, uploadingProgress); - roomsInput.removeListener(cons.events.roomsInput.ATTACHMENT_CANCELED, clearAttachment); - roomsInput.removeListener(cons.events.roomsInput.FILE_UPLOADED, clearAttachment); - viewEvent.removeListener('cmd_fired', firedCmd); - navigation.removeListener(cons.events.navigation.REPLY_TO_CLICKED, setUpReply); - if (isCmdActivated) deactivateCmd(); - if (textAreaRef?.current === null) return; - - const msg = textAreaRef.current.value; - textAreaRef.current.style.height = 'unset'; - inputBaseRef.current.style.backgroundImage = 'unset'; - if (msg.trim() === '') { - roomsInput.setMessage(roomId, ''); - return; - } - roomsInput.setMessage(roomId, msg); - }; - }, [roomId]); - - const sendBody = async (body, options) => { - const opt = options ?? {}; - if (!opt.msgType) opt.msgType = 'm.text'; - if (typeof opt.autoMarkdown !== 'boolean') opt.autoMarkdown = true; - if (roomsInput.isSending(roomId)) return; - sendIsTyping(false); - - roomsInput.setMessage(roomId, body); - if (attachment !== null) { - roomsInput.setAttachment(roomId, attachment); - } - textAreaRef.current.disabled = true; - textAreaRef.current.style.cursor = 'not-allowed'; - await roomsInput.sendInput(roomId, opt); - textAreaRef.current.disabled = false; - textAreaRef.current.style.cursor = 'unset'; - focusInput(); - - textAreaRef.current.value = roomsInput.getMessage(roomId); - textAreaRef.current.style.height = 'unset'; - if (replyTo !== null) setReplyTo(null); - }; - - /** Return true if a command was executed. */ - const processCommand = async (cmdBody) => { - const spaceIndex = cmdBody.indexOf(' '); - const cmdName = cmdBody.slice(1, spaceIndex > -1 ? spaceIndex : undefined); - const cmdData = spaceIndex > -1 ? cmdBody.slice(spaceIndex + 1) : ''; - if (!commands[cmdName]) { - const sendAsMessage = await confirmDialog('Invalid Command', `"${cmdName}" is not a valid command. Did you mean to send this as a message?`, 'Send as message'); - if (sendAsMessage) { - sendBody(cmdBody); - return true; - } - return false; - } - if (['me', 'shrug', 'plain'].includes(cmdName)) { - commands[cmdName].exe(roomId, cmdData, sendBody); - return true; - } - commands[cmdName].exe(roomId, cmdData); - return true; - }; - - const sendMessage = async () => { - requestAnimationFrame(() => deactivateCmdAndEmit()); - const msgBody = textAreaRef.current.value.trim(); - if (msgBody.startsWith('/')) { - const executed = await processCommand(msgBody.trim()); - if (executed) { - textAreaRef.current.value = ''; - textAreaRef.current.style.height = 'unset'; - } - return; - } - if (msgBody === '' && attachment === null) return; - sendBody(msgBody); - }; - - const handleSendSticker = async (data) => { - roomsInput.sendSticker(roomId, data); - }; - - function processTyping(msg) { - const isEmptyMsg = msg === ''; - - if (isEmptyMsg && isTyping) { - sendIsTyping(false); - return; - } - if (!isEmptyMsg && !isTyping) { - sendIsTyping(true); - } - } - - function getCursorPosition() { - return textAreaRef.current.selectionStart; - } - - function recognizeCmd(rawInput) { - const cursor = getCursorPosition(); - const targetInput = rawInput.slice(0, cursor); - - const cmdParts = targetInput.match(CMD_REGEX); - if (cmdParts === null) { - if (isCmdActivated) deactivateCmdAndEmit(); - return; - } - const cmdPrefix = cmdParts[1]; - const cmdSlug = cmdParts[2]; - - if (cmdPrefix === ':') { - // skip emoji autofill command if link is suspected. - const checkForLink = targetInput.slice(0, cmdParts.index); - if (checkForLink.match(/(http|https|mailto|matrix|ircs|irc)$/)) { - deactivateCmdAndEmit(); - return; - } - } - - cmdCursorPos = cursor; - if (cmdSlug === '') { - activateCmd(cmdPrefix); - return; - } - if (!isCmdActivated) activateCmd(cmdPrefix); - viewEvent.emit('cmd_process', cmdPrefix, cmdSlug); - } - - const handleMsgTyping = (e) => { - const msg = e.target.value; - recognizeCmd(e.target.value); - if (!isCmdActivated) processTyping(msg); - }; - - const handleKeyDown = (e) => { - if (e.key === 'Escape') { - e.preventDefault(); - roomsInput.cancelReplyTo(roomId); - setReplyTo(null); - } - if (e.key === 'Enter' && e.shiftKey === false) { - e.preventDefault(); - sendMessage(); - } - }; - - const handlePaste = (e) => { - if (e.clipboardData === false) { - return; - } - - if (e.clipboardData.items === undefined) { - return; - } - - for (let i = 0; i < e.clipboardData.items.length; i += 1) { - const item = e.clipboardData.items[i]; - if (item.type.indexOf('image') !== -1) { - const image = item.getAsFile(); - if (attachment === null) { - setAttachment(image); - if (image !== null) { - roomsInput.setAttachment(roomId, image); - return; - } - } else { - return; - } - } - } - }; - - function addEmoji(emoji) { - textAreaRef.current.value += emoji.unicode; - textAreaRef.current.focus(); - } - - const handleUploadClick = () => { - if (attachment === null) uploadInputRef.current.click(); - else { - roomsInput.cancelAttachment(roomId); - } - }; - function uploadFileChange(e) { - const file = e.target.files.item(0); - setAttachment(file); - if (file !== null) roomsInput.setAttachment(roomId, file); - } - - function renderInputs() { - const canISend = roomTimeline.room.currentState.maySendMessage(mx.getUserId()); - const tombstoneEvent = roomTimeline.room.currentState.getStateEvents('m.room.tombstone')[0]; - if (!canISend || tombstoneEvent) { - return ( - - { - tombstoneEvent - ? tombstoneEvent.getContent()?.body ?? 'This room has been replaced and is no longer active.' - : 'You do not have permission to post to this room' - } - - ); - } - return ( - <> -
      - - -
      -
      - {roomTimeline.isEncrypted() && } - - - - - -
      -
      - { - openReusableContextMenu( - 'top', - (() => { - const cords = getEventCords(e); - cords.y -= 20; - return cords; - })(), - (closeMenu) => ( - { - handleSendSticker(data); - closeMenu(); - }} - /> - ), - ); - }} - tooltip="Sticker" - src={StickerIC} - /> - { - const cords = getEventCords(e); - cords.x += (document.dir === 'rtl' ? -80 : 80); - cords.y -= 250; - openEmojiBoard(cords, addEmoji); - }} - tooltip="Emoji" - src={EmojiIC} - /> - -
      - - ); - } - - function attachFile() { - const fileType = attachment.type.slice(0, attachment.type.indexOf('/')); - return ( -
      -
      - {fileType === 'image' && {attachment.name}} - {fileType === 'video' && } - {fileType === 'audio' && } - {fileType !== 'image' && fileType !== 'video' && fileType !== 'audio' && } -
      -
      - {attachment.name} - {`size: ${bytesToSize(attachment.size)}`} -
      -
      - ); - } - - function attachReply() { - return ( -
      - { - roomsInput.cancelReplyTo(roomId); - setReplyTo(null); - }} - src={CrossIC} - tooltip="Cancel reply" - size="extra-small" - /> - -
      - ); - } - - return ( - <> - { replyTo !== null && attachReply()} - { attachment !== null && attachFile() } -
      { e.preventDefault(); }}> - { - renderInputs() - } -
      - - ); -} -RoomViewInput.propTypes = { - roomId: PropTypes.string.isRequired, - roomTimeline: PropTypes.shape({}).isRequired, - viewEvent: PropTypes.shape({}).isRequired, -}; - -export default RoomViewInput; diff --git a/src/app/organisms/room/RoomViewInput.scss b/src/app/organisms/room/RoomViewInput.scss deleted file mode 100644 index 9fb7c4dea..000000000 --- a/src/app/organisms/room/RoomViewInput.scss +++ /dev/null @@ -1,108 +0,0 @@ -@use '../../partials/dir'; - -.room-input { - padding: var(--sp-extra-tight) calc(var(--sp-normal) - 2px); - display: flex; - min-height: 56px; - - &__alert { - margin: auto; - padding: 0 var(--sp-tight); - text-align: center; - } - - &__input-container { - flex: 1; - min-width: 0; - display: flex; - align-items: center; - - margin: 0 calc(var(--sp-tight) - 2px); - background-color: var(--bg-surface-low); - box-shadow: var(--bs-surface-border); - border-radius: var(--bo-radius); - - & > .ic-raw { - transform: scale(0.8); - margin: 0 var(--sp-extra-tight); - } - - & .scrollbar { - max-height: 50vh; - flex: 1; - - &:first-child { - @include dir.side(margin, var(--sp-tight), 0); - } - } - } - - &__textarea-wrapper { - min-height: 40px; - display: flex; - align-items: center; - - & textarea { - resize: none; - width: 100%; - min-width: 0; - min-height: 100%; - padding: var(--sp-ultra-tight) 0; - - &::placeholder { - color: var(--tc-surface-low); - } - &:focus { - outline: none; - } - } - } -} - -.room-attachment { - --side-spacing: calc(var(--sp-normal) + var(--av-small) + var(--sp-tight)); - display: flex; - align-items: center; - @include dir.side(margin, var(--side-spacing), 0); - margin-top: var(--sp-extra-tight); - line-height: 0; - - &__preview > img { - max-height: 40px; - border-radius: var(--bo-radius); - max-width: 150px; - } - &__icon { - padding: var(--sp-extra-tight); - background-color: var(--bg-surface-low); - box-shadow: var(--bs-surface-border); - border-radius: var(--bo-radius); - } - &__info { - flex: 1; - min-width: 0; - margin: 0 var(--sp-tight); - } - - &__option button { - transition: transform 200ms ease-in-out; - transform: translateY(-48px); - & .ic-raw { - transition: transform 200ms ease-in-out; - transform: rotate(45deg); - background-color: var(--bg-caution); - } - } -} - -.room-reply { - display: flex; - align-items: center; - background-color: var(--bg-surface-low); - border-bottom: 1px solid var(--bg-surface-border); - - & .ic-btn-surface { - @include dir.side(margin, 17px, 13px); - border-radius: 0; - } -} \ No newline at end of file diff --git a/src/app/organisms/room/TimelineScroll.js b/src/app/organisms/room/TimelineScroll.js deleted file mode 100644 index ccdc9a97c..000000000 --- a/src/app/organisms/room/TimelineScroll.js +++ /dev/null @@ -1,136 +0,0 @@ -import { getScrollInfo } from '../../../util/common'; - -class TimelineScroll { - constructor(target) { - if (target === null) { - throw new Error('Can not initialize TimelineScroll, target HTMLElement in null'); - } - this.scroll = target; - - this.backwards = false; - this.inTopHalf = false; - - this.isScrollable = false; - this.top = 0; - this.bottom = 0; - this.height = 0; - this.viewHeight = 0; - - this.topMsg = null; - this.bottomMsg = null; - this.diff = 0; - } - - scrollToBottom() { - const scrollInfo = getScrollInfo(this.scroll); - const maxScrollTop = scrollInfo.height - scrollInfo.viewHeight; - - this._scrollTo(scrollInfo, maxScrollTop); - } - - // use previous calc by this._updateTopBottomMsg() & this._calcDiff. - tryRestoringScroll() { - const scrollInfo = getScrollInfo(this.scroll); - - let scrollTop = 0; - const ot = this.inTopHalf ? this.topMsg?.offsetTop : this.bottomMsg?.offsetTop; - if (!ot) scrollTop = Math.round(this.height - this.viewHeight); - else scrollTop = ot - this.diff; - - this._scrollTo(scrollInfo, scrollTop); - } - - scrollToIndex(index, offset = 0) { - const scrollInfo = getScrollInfo(this.scroll); - const msgs = this.scroll.lastElementChild.lastElementChild.children; - const offsetTop = msgs[index]?.offsetTop; - - if (offsetTop === undefined) return; - // if msg is already in visible are we don't need to scroll to that - if (offsetTop > scrollInfo.top && offsetTop < (scrollInfo.top + scrollInfo.viewHeight)) return; - const to = offsetTop - offset; - - this._scrollTo(scrollInfo, to); - } - - _scrollTo(scrollInfo, scrollTop) { - this.scroll.scrollTop = scrollTop; - - // browser emit 'onscroll' event only if the 'element.scrollTop' value changes. - // so here we flag that the upcoming 'onscroll' event is - // emitted as side effect of assigning 'this.scroll.scrollTop' above - // only if it's changes. - // by doing so we prevent this._updateCalc() from calc again. - if (scrollTop !== this.top) { - this.scrolledByCode = true; - } - const sInfo = { ...scrollInfo }; - - const maxScrollTop = scrollInfo.height - scrollInfo.viewHeight; - - sInfo.top = (scrollTop > maxScrollTop) ? maxScrollTop : scrollTop; - this._updateCalc(sInfo); - } - - // we maintain reference of top and bottom messages - // to restore the scroll position when - // messages gets removed from either end and added to other. - _updateTopBottomMsg() { - const msgs = this.scroll.lastElementChild.lastElementChild.children; - const lMsgIndex = msgs.length - 1; - - // TODO: classname 'ph-msg' prevent this class from being used - const PLACEHOLDER_COUNT = 2; - this.topMsg = msgs[0]?.className === 'ph-msg' - ? msgs[PLACEHOLDER_COUNT] - : msgs[0]; - this.bottomMsg = msgs[lMsgIndex]?.className === 'ph-msg' - ? msgs[lMsgIndex - PLACEHOLDER_COUNT] - : msgs[lMsgIndex]; - } - - // we calculate the difference between first/last message and current scrollTop. - // if we are going above we calc diff between first and scrollTop - // else otherwise. - // NOTE: This will help to restore the scroll when msgs get's removed - // from one end and added to other end - _calcDiff(scrollInfo) { - if (!this.topMsg || !this.bottomMsg) return 0; - if (this.inTopHalf) { - return this.topMsg.offsetTop - scrollInfo.top; - } - return this.bottomMsg.offsetTop - scrollInfo.top; - } - - _updateCalc(scrollInfo) { - const halfViewHeight = Math.round(scrollInfo.viewHeight / 2); - const scrollMiddle = scrollInfo.top + halfViewHeight; - const lastMiddle = this.top + halfViewHeight; - - this.backwards = scrollMiddle < lastMiddle; - this.inTopHalf = scrollMiddle < scrollInfo.height / 2; - - this.isScrollable = scrollInfo.isScrollable; - this.top = scrollInfo.top; - this.bottom = scrollInfo.height - (scrollInfo.top + scrollInfo.viewHeight); - this.height = scrollInfo.height; - this.viewHeight = scrollInfo.viewHeight; - - this._updateTopBottomMsg(); - this.diff = this._calcDiff(scrollInfo); - } - - calcScroll() { - if (this.scrolledByCode) { - this.scrolledByCode = false; - return undefined; - } - - const scrollInfo = getScrollInfo(this.scroll); - this._updateCalc(scrollInfo); - - return this.backwards; - } -} - -export default TimelineScroll; diff --git a/src/app/organisms/room/commands.jsx b/src/app/organisms/room/commands.jsx deleted file mode 100644 index 463f9d945..000000000 --- a/src/app/organisms/room/commands.jsx +++ /dev/null @@ -1,220 +0,0 @@ -import React from 'react'; -import './commands.scss'; - -import initMatrix from '../../../client/initMatrix'; -import * as roomActions from '../../../client/action/room'; -import { hasDMWith, hasDevices } from '../../../util/matrixUtil'; -import { selectRoom, openReusableDialog } from '../../../client/action/navigation'; - -import Text from '../../atoms/text/Text'; -import SettingTile from '../../molecules/setting-tile/SettingTile'; - -const MXID_REG = /^@\S+:\S+$/; -const ROOM_ID_ALIAS_REG = /^(#|!)\S+:\S+$/; -const ROOM_ID_REG = /^!\S+:\S+$/; -const MXC_REG = /^mxc:\/\/\S+$/; - -export function processMxidAndReason(data) { - let reason; - let idData = data; - const reasonMatch = data.match(/\s-r\s/); - if (reasonMatch) { - idData = data.slice(0, reasonMatch.index); - reason = data.slice(reasonMatch.index + reasonMatch[0].length); - if (reason.trim() === '') reason = undefined; - } - const rawIds = idData.split(' '); - const userIds = rawIds.filter((id) => id.match(MXID_REG)); - return { - userIds, - reason, - }; -} - -const commands = { - me: { - name: 'me', - description: 'Display action', - exe: (roomId, data, onSuccess) => { - const body = data.trim(); - if (body === '') return; - onSuccess(body, { msgType: 'm.emote' }); - }, - }, - shrug: { - name: 'shrug', - description: 'Send ¯\\_(ツ)_/¯ as message', - exe: (roomId, data, onSuccess) => onSuccess( - `¯\\_(ツ)_/¯${data.trim() !== '' ? ` ${data}` : ''}`, - { msgType: 'm.text' }, - ), - }, - plain: { - name: 'plain', - description: 'Send plain text message', - exe: (roomId, data, onSuccess) => { - const body = data.trim(); - if (body === '') return; - onSuccess(body, { msgType: 'm.text', autoMarkdown: false }); - }, - }, - help: { - name: 'help', - description: 'View all commands', - // eslint-disable-next-line no-use-before-define - exe: () => openHelpDialog(), - }, - startdm: { - name: 'startdm', - description: 'Start direct message with user. Example: /startdm userId1', - exe: async (roomId, data) => { - const mx = initMatrix.matrixClient; - const rawIds = data.split(' '); - const userIds = rawIds.filter((id) => id.match(MXID_REG) && id !== mx.getUserId()); - if (userIds.length === 0) return; - if (userIds.length === 1) { - const dmRoomId = hasDMWith(userIds[0]); - if (dmRoomId) { - selectRoom(dmRoomId); - return; - } - } - const devices = await Promise.all(userIds.map(hasDevices)); - const isEncrypt = devices.every((hasDevice) => hasDevice); - const result = await roomActions.createDM(userIds, isEncrypt); - selectRoom(result.room_id); - }, - }, - join: { - name: 'join', - description: 'Join room with address. Example: /join address1 address2', - exe: (roomId, data) => { - const rawIds = data.split(' '); - const roomIds = rawIds.filter((id) => id.match(ROOM_ID_ALIAS_REG)); - roomIds.map((id) => roomActions.join(id)); - }, - }, - leave: { - name: 'leave', - description: 'Leave current room.', - exe: (roomId, data) => { - if (data.trim() === '') { - roomActions.leave(roomId); - return; - } - const rawIds = data.split(' '); - const roomIds = rawIds.filter((id) => id.match(ROOM_ID_REG)); - roomIds.map((id) => roomActions.leave(id)); - }, - }, - invite: { - name: 'invite', - description: 'Invite user to room. Example: /invite userId1 userId2 [-r reason]', - exe: (roomId, data) => { - const { userIds, reason } = processMxidAndReason(data); - userIds.map((id) => roomActions.invite(roomId, id, reason)); - }, - }, - disinvite: { - name: 'disinvite', - description: 'Disinvite user to room. Example: /disinvite userId1 userId2 [-r reason]', - exe: (roomId, data) => { - const { userIds, reason } = processMxidAndReason(data); - userIds.map((id) => roomActions.kick(roomId, id, reason)); - }, - }, - kick: { - name: 'kick', - description: 'Kick user from room. Example: /kick userId1 userId2 [-r reason]', - exe: (roomId, data) => { - const { userIds, reason } = processMxidAndReason(data); - userIds.map((id) => roomActions.kick(roomId, id, reason)); - }, - }, - ban: { - name: 'ban', - description: 'Ban user from room. Example: /ban userId1 userId2 [-r reason]', - exe: (roomId, data) => { - const { userIds, reason } = processMxidAndReason(data); - userIds.map((id) => roomActions.ban(roomId, id, reason)); - }, - }, - unban: { - name: 'unban', - description: 'Unban user from room. Example: /unban userId1 userId2', - exe: (roomId, data) => { - const rawIds = data.split(' '); - const userIds = rawIds.filter((id) => id.match(MXID_REG)); - userIds.map((id) => roomActions.unban(roomId, id)); - }, - }, - ignore: { - name: 'ignore', - description: 'Ignore user. Example: /ignore userId1 userId2', - exe: (roomId, data) => { - const rawIds = data.split(' '); - const userIds = rawIds.filter((id) => id.match(MXID_REG)); - if (userIds.length > 0) roomActions.ignore(userIds); - }, - }, - unignore: { - name: 'unignore', - description: 'Unignore user. Example: /unignore userId1 userId2', - exe: (roomId, data) => { - const rawIds = data.split(' '); - const userIds = rawIds.filter((id) => id.match(MXID_REG)); - if (userIds.length > 0) roomActions.unignore(userIds); - }, - }, - myroomnick: { - name: 'myroomnick', - description: 'Change nick in current room.', - exe: (roomId, data) => { - const nick = data.trim(); - if (nick === '') return; - roomActions.setMyRoomNick(roomId, nick); - }, - }, - myroomavatar: { - name: 'myroomavatar', - description: 'Change profile picture in current room. Example /myroomavatar mxc://xyzabc', - exe: (roomId, data) => { - if (data.match(MXC_REG)) { - roomActions.setMyRoomAvatar(roomId, data); - } - }, - }, - converttodm: { - name: 'converttodm', - description: 'Convert room to direct message', - exe: (roomId) => { - roomActions.convertToDm(roomId); - }, - }, - converttoroom: { - name: 'converttoroom', - description: 'Convert direct message to room', - exe: (roomId) => { - roomActions.convertToRoom(roomId); - }, - }, -}; - -function openHelpDialog() { - openReusableDialog( - Commands, - () => ( -
      - {Object.keys(commands).map((cmdName) => ( - {commands[cmdName].description}} - /> - ))} -
      - ), - ); -} - -export default commands; diff --git a/src/app/organisms/room/commands.scss b/src/app/organisms/room/commands.scss deleted file mode 100644 index 628393781..000000000 --- a/src/app/organisms/room/commands.scss +++ /dev/null @@ -1,10 +0,0 @@ -.commands-dialog { - & > * { - padding: var(--sp-tight) var(--sp-normal); - border-bottom: 1px solid var(--bg-surface-border); - &:last-child { - border-bottom: none; - margin-bottom: var(--sp-extra-loose); - } - } -} \ No newline at end of file diff --git a/src/app/organisms/room/common.jsx b/src/app/organisms/room/common.jsx deleted file mode 100644 index 28974a85d..000000000 --- a/src/app/organisms/room/common.jsx +++ /dev/null @@ -1,222 +0,0 @@ -import React from 'react'; - -import { twemojify } from '../../../util/twemojify'; - -import initMatrix from '../../../client/initMatrix'; -import { getUsername, getUsernameOfRoomMember } from '../../../util/matrixUtil'; - -function getTimelineJSXMessages() { - return { - join(user) { - return ( - <> - {twemojify(user)} - {' joined the room'} - - ); - }, - leave(user, reason) { - const reasonMsg = (typeof reason === 'string') ? `: ${reason}` : ''; - return ( - <> - {twemojify(user)} - {' left the room'} - {twemojify(reasonMsg)} - - ); - }, - invite(inviter, user) { - return ( - <> - {twemojify(inviter)} - {' invited '} - {twemojify(user)} - - ); - }, - cancelInvite(inviter, user) { - return ( - <> - {twemojify(inviter)} - {' canceled '} - {twemojify(user)} - {'\'s invite'} - - ); - }, - rejectInvite(user) { - return ( - <> - {twemojify(user)} - {' rejected the invitation'} - - ); - }, - kick(actor, user, reason) { - const reasonMsg = (typeof reason === 'string') ? `: ${reason}` : ''; - return ( - <> - {twemojify(actor)} - {' kicked '} - {twemojify(user)} - {twemojify(reasonMsg)} - - ); - }, - ban(actor, user, reason) { - const reasonMsg = (typeof reason === 'string') ? `: ${reason}` : ''; - return ( - <> - {twemojify(actor)} - {' banned '} - {twemojify(user)} - {twemojify(reasonMsg)} - - ); - }, - unban(actor, user) { - return ( - <> - {twemojify(actor)} - {' unbanned '} - {twemojify(user)} - - ); - }, - avatarSets(user) { - return ( - <> - {twemojify(user)} - {' set a avatar'} - - ); - }, - avatarChanged(user) { - return ( - <> - {twemojify(user)} - {' changed their avatar'} - - ); - }, - avatarRemoved(user) { - return ( - <> - {twemojify(user)} - {' removed their avatar'} - - ); - }, - nameSets(user, newName) { - return ( - <> - {twemojify(user)} - {' set display name to '} - {twemojify(newName)} - - ); - }, - nameChanged(user, newName) { - return ( - <> - {twemojify(user)} - {' changed their display name to '} - {twemojify(newName)} - - ); - }, - nameRemoved(user, lastName) { - return ( - <> - {twemojify(user)} - {' removed their display name '} - {twemojify(lastName)} - - ); - }, - }; -} - -function getUsersActionJsx(roomId, userIds, actionStr) { - const room = initMatrix.matrixClient.getRoom(roomId); - const getUserDisplayName = (userId) => { - if (room?.getMember(userId)) return getUsernameOfRoomMember(room.getMember(userId)); - return getUsername(userId); - }; - const getUserJSX = (userId) => {twemojify(getUserDisplayName(userId))}; - if (!Array.isArray(userIds)) return 'Idle'; - if (userIds.length === 0) return 'Idle'; - const MAX_VISIBLE_COUNT = 3; - - const u1Jsx = getUserJSX(userIds[0]); - // eslint-disable-next-line react/jsx-one-expression-per-line - if (userIds.length === 1) return <>{u1Jsx} is {actionStr}; - - const u2Jsx = getUserJSX(userIds[1]); - // eslint-disable-next-line react/jsx-one-expression-per-line - if (userIds.length === 2) return <>{u1Jsx} and {u2Jsx} are {actionStr}; - - const u3Jsx = getUserJSX(userIds[2]); - if (userIds.length === 3) { - // eslint-disable-next-line react/jsx-one-expression-per-line - return <>{u1Jsx}, {u2Jsx} and {u3Jsx} are {actionStr}; - } - - const othersCount = userIds.length - MAX_VISIBLE_COUNT; - // eslint-disable-next-line react/jsx-one-expression-per-line - return <>{u1Jsx}, {u2Jsx}, {u3Jsx} and {othersCount} others are {actionStr}; -} - -function parseTimelineChange(mEvent) { - const tJSXMsgs = getTimelineJSXMessages(); - const makeReturnObj = (variant, content) => ({ - variant, - content, - }); - const content = mEvent.getContent(); - const prevContent = mEvent.getPrevContent(); - const sender = mEvent.getSender(); - const senderName = getUsername(sender); - const userName = getUsername(mEvent.getStateKey()); - - switch (content.membership) { - case 'invite': return makeReturnObj('invite', tJSXMsgs.invite(senderName, userName)); - case 'ban': return makeReturnObj('leave', tJSXMsgs.ban(senderName, userName, content.reason)); - case 'join': - if (prevContent.membership === 'join') { - if (content.displayname !== prevContent.displayname) { - if (typeof content.displayname === 'undefined') return makeReturnObj('avatar', tJSXMsgs.nameRemoved(sender, prevContent.displayname)); - if (typeof prevContent.displayname === 'undefined') return makeReturnObj('avatar', tJSXMsgs.nameSets(sender, content.displayname)); - return makeReturnObj('avatar', tJSXMsgs.nameChanged(prevContent.displayname, content.displayname)); - } - if (content.avatar_url !== prevContent.avatar_url) { - if (typeof content.avatar_url === 'undefined') return makeReturnObj('avatar', tJSXMsgs.avatarRemoved(content.displayname)); - if (typeof prevContent.avatar_url === 'undefined') return makeReturnObj('avatar', tJSXMsgs.avatarSets(content.displayname)); - return makeReturnObj('avatar', tJSXMsgs.avatarChanged(content.displayname)); - } - return null; - } - return makeReturnObj('join', tJSXMsgs.join(senderName)); - case 'leave': - if (sender === mEvent.getStateKey()) { - switch (prevContent.membership) { - case 'invite': return makeReturnObj('invite-cancel', tJSXMsgs.rejectInvite(senderName)); - default: return makeReturnObj('leave', tJSXMsgs.leave(senderName, content.reason)); - } - } - switch (prevContent.membership) { - case 'invite': return makeReturnObj('invite-cancel', tJSXMsgs.cancelInvite(senderName, userName)); - case 'ban': return makeReturnObj('other', tJSXMsgs.unban(senderName, userName)); - // sender is not target and made the target leave, - // if not from invite/ban then this is a kick - default: return makeReturnObj('leave', tJSXMsgs.kick(senderName, userName, content.reason)); - } - default: return null; - } -} - -export { - getTimelineJSXMessages, - getUsersActionJsx, - parseTimelineChange, -}; diff --git a/src/app/organisms/search/Search.jsx b/src/app/organisms/search/Search.jsx index 66b685114..c9d1d991f 100644 --- a/src/app/organisms/search/Search.jsx +++ b/src/app/organisms/search/Search.jsx @@ -1,4 +1,5 @@ import React, { useState, useEffect, useRef } from 'react'; +import { useAtomValue } from 'jotai'; import './Search.scss'; import initMatrix from '../../../client/initMatrix'; @@ -19,6 +20,11 @@ import RoomSelector from '../../molecules/room-selector/RoomSelector'; import SearchIC from '../../../../public/res/ic/outlined/search.svg'; import CrossIC from '../../../../public/res/ic/outlined/cross.svg'; import { useRoomNavigate } from '../../hooks/useRoomNavigate'; +import { useDirects, useRooms, useSpaces } from '../../state/hooks/roomList'; +import { roomToUnreadAtom } from '../../state/room/roomToUnread'; +import { roomToParentsAtom } from '../../state/room/roomToParents'; +import { allRoomsAtom } from '../../state/room-list/roomList'; +import { mDirectAtom } from '../../state/mDirectList'; function useVisiblityToggle(setResult) { const [isOpen, setIsOpen] = useState(false); @@ -48,9 +54,8 @@ function useVisiblityToggle(setResult) { return [isOpen, requestClose]; } -function mapRoomIds(roomIds) { +function mapRoomIds(roomIds, directs, roomIdToParents) { const mx = initMatrix.matrixClient; - const { directs, roomIdToParents } = initMatrix.roomList; return roomIds.map((roomId) => { const room = mx.getRoom(roomId); @@ -62,7 +67,7 @@ function mapRoomIds(roomIds) { let type = 'room'; if (room.isSpaceRoom()) type = 'space'; - else if (directs.has(roomId)) type = 'direct'; + else if (directs.includes(roomId)) type = 'direct'; return { type, @@ -81,6 +86,12 @@ function Search() { const searchRef = useRef(null); const mx = initMatrix.matrixClient; const { navigateRoom, navigateSpace } = useRoomNavigate(); + const mDirects = useAtomValue(mDirectAtom); + const spaces = useSpaces(mx, allRoomsAtom); + const rooms = useRooms(mx, allRoomsAtom, mDirects); + const directs = useDirects(mx, allRoomsAtom, mDirects); + const roomToUnread = useAtomValue(roomToUnreadAtom); + const roomToParents = useAtomValue(roomToParentsAtom); const handleSearchResults = (chunk, term) => { setResult({ @@ -97,7 +108,6 @@ function Search() { return; } - const { spaces, rooms, directs } = initMatrix.roomList; let ids = null; if (prefix) { @@ -109,15 +119,15 @@ function Search() { } ids.sort(roomIdByActivity); - const mappedIds = mapRoomIds(ids); + const mappedIds = mapRoomIds(ids, directs, roomToParents); asyncSearch.setup(mappedIds, { keys: 'name', isContain: true, limit: 20 }); if (prefix) handleSearchResults(mappedIds, prefix); else asyncSearch.search(term); }; const loadRecentRooms = () => { - const { recentRooms } = navigation; - handleSearchResults(mapRoomIds(recentRooms).reverse()); + const recentRooms = []; + handleSearchResults(mapRoomIds(recentRooms, directs, roomToParents).reverse()); }; const handleAfterOpen = () => { @@ -169,7 +179,6 @@ function Search() { } }; - const noti = initMatrix.notifications; const renderRoomSelector = (item) => { let imageSrc = null; let iconSrc = null; @@ -188,9 +197,9 @@ function Search() { roomId={item.roomId} imageSrc={imageSrc} iconSrc={iconSrc} - isUnread={noti.hasNoti(item.roomId)} - notificationCount={noti.getTotalNoti(item.roomId)} - isAlert={noti.getHighlightNoti(item.roomId) > 0} + isUnread={roomToUnread.has(item.roomId)} + notificationCount={roomToUnread.get(item.roomId)?.total ?? 0} + isAlert={roomToUnread.get(item.roomId)?.highlight > 0} onClick={() => openItem(item.roomId, item.type)} /> ); diff --git a/src/app/organisms/settings/CrossSigning.jsx b/src/app/organisms/settings/CrossSigning.jsx index 563e31522..9d848d5ae 100644 --- a/src/app/organisms/settings/CrossSigning.jsx +++ b/src/app/organisms/settings/CrossSigning.jsx @@ -3,7 +3,6 @@ import React, { useState } from 'react'; import './CrossSigning.scss'; import FileSaver from 'file-saver'; import { Formik } from 'formik'; -import { twemojify } from '../../../util/twemojify'; import initMatrix from '../../../client/initMatrix'; import { openReusableDialog } from '../../../client/action/navigation'; @@ -22,15 +21,17 @@ import { useCrossSigningStatus } from '../../hooks/useCrossSigningStatus'; const failedDialog = () => { const renderFailure = (requestClose) => (
      - {twemojify('❌')} + Failed to setup cross signing. Please try again.
      ); openReusableDialog( - Setup cross signing, - renderFailure, + + Setup cross signing + , + renderFailure ); }; @@ -48,11 +49,11 @@ const securityKeyDialog = (key) => { const renderSecurityKey = () => (
      Please save this security key somewhere safe. - - {key.encodedPrivateKey} - + {key.encodedPrivateKey}
      - +
      @@ -62,8 +63,10 @@ const securityKeyDialog = (key) => { downloadKey(); openReusableDialog( - Security Key, - () => renderSecurityKey(), + + Security Key + , + () => renderSecurityKey() ); }; @@ -112,7 +115,7 @@ function CrossSigningSetup() { errors.phrase = 'Phrase must contain 8-127 characters with no space.'; } if (values.confirmPhrase.length > 0 && values.confirmPhrase !== values.phrase) { - errors.confirmPhrase = 'Phrase don\'t match.'; + errors.confirmPhrase = "Phrase don't match."; } return errors; }; @@ -121,10 +124,14 @@ function CrossSigningSetup() {
      - We will generate a Security Key, - which you can use to manage messages backup and session verification. + We will generate a Security Key, which you can use to manage messages backup and + session verification. - {genWithPhrase !== false && } + {genWithPhrase !== false && ( + + )} {genWithPhrase === false && }
      OR @@ -133,9 +140,7 @@ function CrossSigningSetup() { onSubmit={(values) => setup(values.phrase)} validate={validator} > - {({ - values, errors, handleChange, handleSubmit, - }) => ( + {({ values, errors, handleChange, handleSubmit }) => (
      Alternatively you can also set a Security Phrase - so you don't have to remember long Security Key, - and optionally save the Key as backup. + so you don't have to remember long Security Key, and optionally save the Key as + backup. - {errors.phrase && {errors.phrase}} + {errors.phrase && ( + + {errors.phrase} + + )} - {errors.confirmPhrase && {errors.confirmPhrase}} - {genWithPhrase !== true && } + {errors.confirmPhrase && ( + + {errors.confirmPhrase} + + )} + {genWithPhrase !== true && ( + + )} {genWithPhrase === true && } )} @@ -177,31 +194,36 @@ function CrossSigningSetup() { const setupDialog = () => { openReusableDialog( - Setup cross signing, - () => , + + Setup cross signing + , + () => ); }; function CrossSigningReset() { return (
      - {twemojify('✋🧑‍🚒🤚')} + ✋🧑‍🚒🤚 Resetting cross-signing keys is permanent. - Anyone you have verified with will see security alerts and your message backup will be lost. - You almost certainly do not want to do this, - unless you have lost Security Key or Phrase and - every session you can cross-sign from. + Anyone you have verified with will see security alerts and your message backup will be lost. + You almost certainly do not want to do this, unless you have lost Security Key or{' '} + Phrase and every session you can cross-sign from. - +
      ); } const resetDialog = () => { openReusableDialog( - Reset cross signing, - () => , + + Reset cross signing + , + () => ); }; @@ -210,12 +232,23 @@ function CrossSignin() { return ( Setup to verify and keep track of all your sessions. Also required to backup encrypted message.} - options={( - isCSEnabled - ? - : - )} + content={ + + Setup to verify and keep track of all your sessions. Also required to backup encrypted + message. + + } + options={ + isCSEnabled ? ( + + ) : ( + + ) + } /> ); } diff --git a/src/app/organisms/settings/KeyBackup.jsx b/src/app/organisms/settings/KeyBackup.jsx index 75f032bc3..b4f2125e2 100644 --- a/src/app/organisms/settings/KeyBackup.jsx +++ b/src/app/organisms/settings/KeyBackup.jsx @@ -2,7 +2,6 @@ import React, { useState, useEffect } from 'react'; import PropTypes from 'prop-types'; import './KeyBackup.scss'; -import { twemojify } from '../../../util/twemojify'; import initMatrix from '../../../client/initMatrix'; import { openReusableDialog } from '../../../client/action/navigation'; @@ -34,10 +33,7 @@ function CreateKeyBackupDialog({ keyData }) { let info; try { - info = await mx.prepareKeyBackupVersion( - null, - { secureSecretStorage: true }, - ); + info = await mx.prepareKeyBackupVersion(null, { secureSecretStorage: true }); info = await mx.createKeyBackupVersion(info); await mx.scheduleAllGroupSessionsForBackup(); if (!mountStore.getItem()) return; @@ -65,7 +61,7 @@ function CreateKeyBackupDialog({ keyData }) { )} {done === true && ( <> - {twemojify('✅')} + Successfully created backup )} @@ -104,12 +100,9 @@ function RestoreKeyBackupDialog({ keyData }) { try { const backupInfo = await mx.getKeyBackupVersion(); - const info = await mx.restoreKeyBackupWithSecretStorage( - backupInfo, - undefined, - undefined, - { progressCallback }, - ); + const info = await mx.restoreKeyBackupWithSecretStorage(backupInfo, undefined, undefined, { + progressCallback, + }); if (!mountStore.getItem()) return; setStatus({ done: `Successfully restored backup keys (${info.imported}/${info.total}).` }); } catch (e) { @@ -138,7 +131,7 @@ function RestoreKeyBackupDialog({ keyData }) { )} {status.done && ( <> - {twemojify('✅')} + {status.done} )} @@ -176,14 +169,16 @@ function DeleteKeyBackupDialog({ requestClose }) { return (
      - {twemojify('🗑')} + 🗑 Deleting key backup is permanent. All encrypted messages keys stored on server will be deleted. - { - isDeleting - ? - : - } + {isDeleting ? ( + + ) : ( + + )}
      ); } @@ -224,9 +219,11 @@ function KeyBackup() { if (keyData === null) return; openReusableDialog( - Create Key Backup, + + Create Key Backup + , () => , - () => fetchKeyBackupVersion(), + () => fetchKeyBackupVersion() ); }; @@ -235,29 +232,44 @@ function KeyBackup() { if (keyData === null) return; openReusableDialog( - Restore Key Backup, - () => , + + Restore Key Backup + , + () => ); }; - const openDeleteKeyBackup = () => openReusableDialog( - Delete Key Backup, - (requestClose) => ( - { - if (isDone) setKeyBackup(null); - requestClose(); - }} - /> - ), - ); + const openDeleteKeyBackup = () => + openReusableDialog( + + Delete Key Backup + , + (requestClose) => ( + { + if (isDone) setKeyBackup(null); + requestClose(); + }} + /> + ) + ); const renderOptions = () => { if (keyBackup === undefined) return ; - if (keyBackup === null) return ; + if (keyBackup === null) + return ( + + ); return ( <> - + ); @@ -266,9 +278,12 @@ function KeyBackup() { return ( - Online backup your encrypted messages keys with your account data in case you lose access to your sessions. Your keys will be secured with a unique Security Key. + + Online backup your encrypted messages keys with your account data in case you lose + access to your sessions. Your keys will be secured with a unique Security Key. + {!isCSEnabled && ( )} - )} + } options={isCSEnabled ? renderOptions() : null} /> ); diff --git a/src/app/organisms/shortcut-spaces/ShortcutSpaces.jsx b/src/app/organisms/shortcut-spaces/ShortcutSpaces.jsx deleted file mode 100644 index 62ec76a31..000000000 --- a/src/app/organisms/shortcut-spaces/ShortcutSpaces.jsx +++ /dev/null @@ -1,169 +0,0 @@ -import React, { useState, useEffect } from 'react'; -import './ShortcutSpaces.scss'; - -import initMatrix from '../../../client/initMatrix'; -import cons from '../../../client/state/cons'; -import navigation from '../../../client/state/navigation'; -import { createSpaceShortcut, deleteSpaceShortcut } from '../../../client/action/accountData'; -import { joinRuleToIconSrc } from '../../../util/matrixUtil'; -import { roomIdByAtoZ } from '../../../util/sort'; - -import Text from '../../atoms/text/Text'; -import Button from '../../atoms/button/Button'; -import IconButton from '../../atoms/button/IconButton'; -import Checkbox from '../../atoms/button/Checkbox'; -import Spinner from '../../atoms/spinner/Spinner'; -import RoomSelector from '../../molecules/room-selector/RoomSelector'; -import Dialog from '../../molecules/dialog/Dialog'; - -import PinIC from '../../../../public/res/ic/outlined/pin.svg'; -import PinFilledIC from '../../../../public/res/ic/filled/pin.svg'; -import CrossIC from '../../../../public/res/ic/outlined/cross.svg'; - -import { useSpaceShortcut } from '../../hooks/useSpaceShortcut'; - -function ShortcutSpacesContent() { - const mx = initMatrix.matrixClient; - const { spaces, roomIdToParents } = initMatrix.roomList; - - const [spaceShortcut] = useSpaceShortcut(); - const spaceWithoutShortcut = [...spaces].filter( - (spaceId) => !spaceShortcut.includes(spaceId), - ).sort(roomIdByAtoZ); - - const [process, setProcess] = useState(null); - const [selected, setSelected] = useState([]); - - useEffect(() => { - if (process !== null) { - setProcess(null); - setSelected([]); - } - }, [spaceShortcut]); - - const toggleSelection = (sId) => { - if (process !== null) return; - const newSelected = [...selected]; - const selectedIndex = newSelected.indexOf(sId); - - if (selectedIndex > -1) { - newSelected.splice(selectedIndex, 1); - setSelected(newSelected); - return; - } - newSelected.push(sId); - setSelected(newSelected); - }; - - const handleAdd = () => { - setProcess(`Pinning ${selected.length} spaces...`); - createSpaceShortcut(selected); - }; - - const renderSpace = (spaceId, isShortcut) => { - const room = mx.getRoom(spaceId); - if (!room) return null; - - const parentSet = roomIdToParents.get(spaceId); - const parentNames = parentSet - ? [...parentSet].map((parentId) => mx.getRoom(parentId).name) - : undefined; - const parents = parentNames ? parentNames.join(', ') : null; - - const toggleSelected = () => toggleSelection(spaceId); - const deleteShortcut = () => deleteSpaceShortcut(spaceId); - - return ( - - ) : ( - - )} - /> - ); - }; - - return ( - <> - Pinned spaces - {spaceShortcut.length === 0 && No pinned spaces} - {spaceShortcut.map((spaceId) => renderSpace(spaceId, true))} - Unpinned spaces - {spaceWithoutShortcut.length === 0 && No unpinned spaces} - {spaceWithoutShortcut.map((spaceId) => renderSpace(spaceId, false))} - {selected.length !== 0 && ( -
      - {process && } - {process || `${selected.length} spaces selected`} - { !process && ( - - )} -
      - )} - - ); -} - -function useVisibilityToggle() { - const [isOpen, setIsOpen] = useState(false); - - useEffect(() => { - const handleOpen = () => setIsOpen(true); - navigation.on(cons.events.navigation.SHORTCUT_SPACES_OPENED, handleOpen); - return () => { - navigation.removeListener(cons.events.navigation.SHORTCUT_SPACES_OPENED, handleOpen); - }; - }, []); - - const requestClose = () => setIsOpen(false); - - return [isOpen, requestClose]; -} - -function ShortcutSpaces() { - const [isOpen, requestClose] = useVisibilityToggle(); - - return ( - - Pin spaces - - )} - contentOptions={} - onRequestClose={requestClose} - > - { - isOpen - ? - :
      - } -
      - ); -} - -export default ShortcutSpaces; diff --git a/src/app/organisms/shortcut-spaces/ShortcutSpaces.scss b/src/app/organisms/shortcut-spaces/ShortcutSpaces.scss deleted file mode 100644 index 686c8cc05..000000000 --- a/src/app/organisms/shortcut-spaces/ShortcutSpaces.scss +++ /dev/null @@ -1,52 +0,0 @@ -@use '../../partials/dir'; -@use '../../partials/flex'; - -.shortcut-spaces { - height: 100%; - .dialog__content-container { - padding: 0; - padding-bottom: 80px; - @include dir.side(padding, var(--sp-extra-tight), 0); - - & > .text-b1 { - padding: 0 var(--sp-extra-tight); - } - } - - &__header { - margin-top: var(--sp-extra-tight); - padding: var(--sp-extra-tight); - text-transform: uppercase; - } - - .room-selector { - margin: 0 var(--sp-extra-tight); - } - .room-selector__options { - display: flex; - .checkbox { - margin: 0 6px; - } - } - - &__footer { - position: absolute; - bottom: 0; - left: 0; - width: 100%; - padding: var(--sp-normal); - background-color: var(--bg-surface); - border-top: 1px solid var(--bg-surface-border); - display: flex; - align-items: center; - - & > .text { - @extend .cp-fx__item-one; - padding: 0 var(--sp-tight); - } - - & > button { - @include dir.side(margin, var(--sp-normal), 0); - } - } -} diff --git a/src/app/organisms/space-manage/SpaceManage.jsx b/src/app/organisms/space-manage/SpaceManage.jsx deleted file mode 100644 index 60f00ad31..000000000 --- a/src/app/organisms/space-manage/SpaceManage.jsx +++ /dev/null @@ -1,433 +0,0 @@ -/* eslint-disable react/prop-types */ -import React, { useState, useEffect } from 'react'; -import PropTypes from 'prop-types'; -import './SpaceManage.scss'; - -import { twemojify } from '../../../util/twemojify'; - -import initMatrix from '../../../client/initMatrix'; -import cons from '../../../client/state/cons'; -import navigation from '../../../client/state/navigation'; -import colorMXID from '../../../util/colorMXID'; -import { selectRoom, selectTab } from '../../../client/action/navigation'; -import RoomsHierarchy from '../../../client/state/RoomsHierarchy'; -import { joinRuleToIconSrc } from '../../../util/matrixUtil'; -import { join } from '../../../client/action/room'; -import { Debounce } from '../../../util/common'; - -import Text from '../../atoms/text/Text'; -import RawIcon from '../../atoms/system-icons/RawIcon'; -import Button from '../../atoms/button/Button'; -import IconButton from '../../atoms/button/IconButton'; -import Checkbox from '../../atoms/button/Checkbox'; -import Avatar from '../../atoms/avatar/Avatar'; -import Spinner from '../../atoms/spinner/Spinner'; -import ScrollView from '../../atoms/scroll/ScrollView'; -import PopupWindow from '../../molecules/popup-window/PopupWindow'; - -import CrossIC from '../../../../public/res/ic/outlined/cross.svg'; -import ChevronRightIC from '../../../../public/res/ic/outlined/chevron-right.svg'; -import InfoIC from '../../../../public/res/ic/outlined/info.svg'; - -import { useForceUpdate } from '../../hooks/useForceUpdate'; -import { useStore } from '../../hooks/useStore'; - -function SpaceManageBreadcrumb({ path, onSelect }) { - return ( -
      - -
      - { - path.map((item, index) => ( - - {index > 0 && } - - - )) - } -
      -
      -
      - ); -} -SpaceManageBreadcrumb.propTypes = { - path: PropTypes.arrayOf(PropTypes.exact({ - roomId: PropTypes.string, - name: PropTypes.string, - })).isRequired, - onSelect: PropTypes.func.isRequired, -}; - -function SpaceManageItem({ - parentId, roomInfo, onSpaceClick, requestClose, - isSelected, onSelect, roomHierarchy, -}) { - const [isExpand, setIsExpand] = useState(false); - const [isJoining, setIsJoining] = useState(false); - - const { directs } = initMatrix.roomList; - const mx = initMatrix.matrixClient; - const parentRoom = mx.getRoom(parentId); - const isSpace = roomInfo.room_type === 'm.space'; - const roomId = roomInfo.room_id; - const canManage = parentRoom?.currentState.maySendStateEvent('m.space.child', mx.getUserId()) || false; - const isSuggested = parentRoom?.currentState.getStateEvents('m.space.child', roomId)?.getContent().suggested === true; - - const room = mx.getRoom(roomId); - const isJoined = !!(room?.getMyMembership() === 'join' || null); - const name = room?.name || roomInfo.name || roomInfo.canonical_alias || roomId; - let imageSrc = mx.mxcUrlToHttp(roomInfo.avatar_url, 24, 24, 'crop') || null; - if (!imageSrc && room) { - imageSrc = room.getAvatarFallbackMember()?.getAvatarUrl(mx.baseUrl, 24, 24, 'crop') || null; - if (imageSrc === null) imageSrc = room.getAvatarUrl(mx.baseUrl, 24, 24, 'crop') || null; - } - const isDM = directs.has(roomId); - - const handleOpen = () => { - if (isSpace) selectTab(roomId); - else selectRoom(roomId); - requestClose(); - }; - const handleJoin = () => { - const viaSet = roomHierarchy.viaMap.get(roomId); - const via = viaSet ? [...viaSet] : undefined; - join(roomId, false, via); - setIsJoining(true); - }; - - const roomAvatarJSX = ( - - ); - const roomNameJSX = ( - - {twemojify(name)} - {` • ${roomInfo.num_joined_members} members`} - - ); - - const expandBtnJsx = ( - setIsExpand(!isExpand)} - /> - ); - - return ( -
      -
      - {canManage && onSelect(roomId)} variant="positive" />} - - {roomInfo.topic && expandBtnJsx} - { - isJoined - ? - : - } -
      - {isExpand && roomInfo.topic && {twemojify(roomInfo.topic, undefined, true)}} -
      - ); -} -SpaceManageItem.propTypes = { - parentId: PropTypes.string.isRequired, - roomHierarchy: PropTypes.shape({}).isRequired, - roomInfo: PropTypes.shape({}).isRequired, - onSpaceClick: PropTypes.func.isRequired, - requestClose: PropTypes.func.isRequired, - isSelected: PropTypes.bool.isRequired, - onSelect: PropTypes.func.isRequired, -}; - -function SpaceManageFooter({ parentId, selected }) { - const [process, setProcess] = useState(null); - const mx = initMatrix.matrixClient; - const room = mx.getRoom(parentId); - const { currentState } = room; - - const allSuggested = selected.every((roomId) => { - const sEvent = currentState.getStateEvents('m.space.child', roomId); - return !!sEvent?.getContent()?.suggested; - }); - - const handleRemove = () => { - setProcess(`Removing ${selected.length} items`); - selected.forEach((roomId) => { - mx.sendStateEvent(parentId, 'm.space.child', {}, roomId); - }); - }; - - const handleToggleSuggested = (isMark) => { - if (isMark) setProcess(`Marking as suggested ${selected.length} items`); - else setProcess(`Marking as not suggested ${selected.length} items`); - selected.forEach((roomId) => { - const sEvent = room.currentState.getStateEvents('m.space.child', roomId); - if (!sEvent) return; - const content = { ...sEvent.getContent() }; - if (isMark && content.suggested) return; - if (!isMark && !content.suggested) return; - content.suggested = isMark; - mx.sendStateEvent(parentId, 'm.space.child', content, roomId); - }); - }; - - return ( -
      - {process && } - {process || `${selected.length} item selected`} - { !process && ( - <> - - - - )} -
      - ); -} -SpaceManageFooter.propTypes = { - parentId: PropTypes.string.isRequired, - selected: PropTypes.arrayOf(PropTypes.string).isRequired, -}; - -function useSpacePath(roomId) { - const mx = initMatrix.matrixClient; - const room = mx.getRoom(roomId); - const [spacePath, setSpacePath] = useState([{ roomId, name: room.name }]); - - const addPathItem = (rId, name) => { - const newPath = [...spacePath]; - const itemIndex = newPath.findIndex((item) => item.roomId === rId); - if (itemIndex < 0) { - newPath.push({ roomId: rId, name }); - setSpacePath(newPath); - return; - } - newPath.splice(itemIndex + 1); - setSpacePath(newPath); - }; - - return [spacePath, addPathItem]; -} - -function useUpdateOnJoin(roomId) { - const [, forceUpdate] = useForceUpdate(); - const { roomList } = initMatrix; - - useEffect(() => { - const handleRoomList = () => forceUpdate(); - - roomList.on(cons.events.roomList.ROOM_JOINED, handleRoomList); - roomList.on(cons.events.roomList.ROOM_LEAVED, handleRoomList); - return () => { - roomList.removeListener(cons.events.roomList.ROOM_JOINED, handleRoomList); - roomList.removeListener(cons.events.roomList.ROOM_LEAVED, handleRoomList); - }; - }, [roomId]); -} - -function useChildUpdate(roomId, roomsHierarchy) { - const [, forceUpdate] = useForceUpdate(); - const [debounce] = useState(new Debounce()); - const mx = initMatrix.matrixClient; - - useEffect(() => { - let isMounted = true; - const handleStateEvent = (event) => { - if (event.getRoomId() !== roomId) return; - if (event.getType() !== 'm.space.child') return; - - debounce._(() => { - if (!isMounted) return; - roomsHierarchy.removeHierarchy(roomId); - forceUpdate(); - }, 500)(); - }; - mx.on('RoomState.events', handleStateEvent); - return () => { - isMounted = false; - mx.removeListener('RoomState.events', handleStateEvent); - }; - }, [roomId, roomsHierarchy]); -} - -function SpaceManageContent({ roomId, requestClose }) { - const mx = initMatrix.matrixClient; - useUpdateOnJoin(roomId); - const [, forceUpdate] = useForceUpdate(); - const [roomsHierarchy] = useState(new RoomsHierarchy(mx, 30)); - const [spacePath, addPathItem] = useSpacePath(roomId); - const [isLoading, setIsLoading] = useState(true); - const [selected, setSelected] = useState([]); - const mountStore = useStore(); - const currentPath = spacePath[spacePath.length - 1]; - useChildUpdate(currentPath.roomId, roomsHierarchy); - - const currentHierarchy = roomsHierarchy.getHierarchy(currentPath.roomId); - - useEffect(() => { - mountStore.setItem(true); - return () => { - mountStore.setItem(false); - }; - }, [roomId]); - - useEffect(() => { - setSelected([]); - }, [spacePath]); - - const handleSelected = (selectedRoomId) => { - const newSelected = [...selected]; - const selectedIndex = newSelected.indexOf(selectedRoomId); - - if (selectedIndex > -1) { - newSelected.splice(selectedIndex, 1); - setSelected(newSelected); - return; - } - newSelected.push(selectedRoomId); - setSelected(newSelected); - }; - - const loadRoomHierarchy = async () => { - if (!roomsHierarchy.canLoadMore(currentPath.roomId)) return; - if (!roomsHierarchy.getHierarchy(currentPath.roomId)) setSelected([]); - setIsLoading(true); - try { - await roomsHierarchy.load(currentPath.roomId); - if (!mountStore.getItem()) return; - setIsLoading(false); - forceUpdate(); - } catch { - if (!mountStore.getItem()) return; - setIsLoading(false); - forceUpdate(); - } - }; - - if (!currentHierarchy) loadRoomHierarchy(); - return ( -
      - {spacePath.length > 1 && ( - - )} - Rooms and spaces -
      - {!isLoading && currentHierarchy?.rooms?.length === 1 && ( - - Either the space contains private rooms or you need to join space to view it's rooms. - - )} - {currentHierarchy && (currentHierarchy.rooms?.map((roomInfo) => ( - roomInfo.room_id === currentPath.roomId - ? null - : ( - - ) - )))} - {!currentHierarchy && loading...} -
      - {currentHierarchy?.canLoadMore && !isLoading && ( - - )} - {isLoading && ( -
      - - Loading rooms... -
      - )} - {selected.length > 0 && ( - - )} -
      - ); -} -SpaceManageContent.propTypes = { - roomId: PropTypes.string.isRequired, - requestClose: PropTypes.func.isRequired, -}; - -function useWindowToggle() { - const [roomId, setRoomId] = useState(null); - - useEffect(() => { - const openSpaceManage = (rId) => { - setRoomId(rId); - }; - navigation.on(cons.events.navigation.SPACE_MANAGE_OPENED, openSpaceManage); - return () => { - navigation.removeListener(cons.events.navigation.SPACE_MANAGE_OPENED, openSpaceManage); - }; - }, []); - - const requestClose = () => setRoomId(null); - - return [roomId, requestClose]; -} -function SpaceManage() { - const mx = initMatrix.matrixClient; - const [roomId, requestClose] = useWindowToggle(); - const room = mx.getRoom(roomId); - - return ( - - {roomId && twemojify(room.name)} - — manage rooms - - )} - contentOptions={} - onRequestClose={requestClose} - > - { - roomId - ? - :
      - } - - ); -} - -export default SpaceManage; diff --git a/src/app/organisms/space-manage/SpaceManage.scss b/src/app/organisms/space-manage/SpaceManage.scss deleted file mode 100644 index b72c92d8a..000000000 --- a/src/app/organisms/space-manage/SpaceManage.scss +++ /dev/null @@ -1,168 +0,0 @@ -@use '../../partials/text'; -@use '../../partials/dir'; -@use '../../partials/flex'; - -.space-manage { - & .pw__content-wrapper { - position: relative; - } - & .pw__content-container { - padding-top: 0; - padding-bottom: 73px; - } -} - -.space-manage__content { - margin-bottom: var(--sp-extra-loose); - - & > .text { - margin-top: var(--sp-extra-tight); - padding: var(--sp-extra-tight) var(--sp-normal); - text-transform: uppercase; - } - - &-items { - @include dir.side(padding, var(--sp-extra-tight), 0); - & > .text:first-child { - padding: var(--sp-extra-tight); - } - } - - & > button { - margin: var(--sp-normal); - } - - &-loading { - padding: var(--sp-loose); - display: flex; - justify-content: center; - align-items: center; - & .text { - margin: 0 var(--sp-normal); - } - } -} -.space-manage-breadcrumb { - display: flex; - align-items: center; - height: 100%; - margin: 0 var(--sp-extra-tight); - - &__wrapper { - height: var(--header-height); - position: sticky; - top: 0; - z-index: 99; - background-color: var(--bg-surface); - } - & > * { - flex-shrink: 0; - } - - & > .btn-surface { - min-width: 0; - padding: var(--sp-extra-tight) 10px; - white-space: nowrap; - box-shadow: none; - & p { - @extend .cp-txt__ellipsis; - max-width: 200px; - } - &:last-child { - box-shadow: var(--bs-surface-border) !important; - background-color: var(--bg-surface); - } - } - -} - -.space-manage-item { - margin: var(--sp-ultra-tight) var(--sp-extra-tight); - padding: 0 var(--sp-extra-tight); - border-radius: var(--bo-radius); - - & > div { - min-height: 40px; - display: flex; - align-items: center; - } - - &--space { - @extend .space-manage-item; - & .space-manage-item__btn { - cursor: pointer; - } - } - - &:hover { - background-color: var(--bg-surface-hover); - } - - & .checkbox { - @include dir.side(margin, 0, var(--sp-tight)); - } - - - &__btn { - @extend .cp-fx__item-one; - display: flex; - align-items: center; - - & .avatar__border--active { - box-shadow: none; - } - & > .text-b1 { - @extend .cp-fx__item-one; - @extend .cp-txt__ellipsis; - min-width: 0; - margin: 0 var(--sp-extra-tight); - } - & > .text-b2 { - margin: 0 var(--sp-extra-tight); - padding: 1px var(--sp-ultra-tight); - color: var(--bg-positive); - box-shadow: var(--bs-positive-border); - border-radius: 4px; - } - } - - & .ic-btn { - padding: 7px; - @include dir.side(margin, 0, var(--sp-extra-tight)); - opacity: 0.7; - } - - & .btn-surface, - & .btn-primary { - padding: var(--sp-ultra-tight) var(--sp-extra-tight); - min-width: 60px; - } - - & > .text { - padding: 32px; - padding-top: 0; - padding-bottom: var(--sp-normal); - white-space: pre-wrap; - } -} - -.space-manage__footer { - position: absolute; - bottom: 0; - left: 0; - width: 100%; - padding: var(--sp-normal); - background-color: var(--bg-surface); - border-top: 1px solid var(--bg-surface-border); - display: flex; - align-items: center; - - & > .text { - @extend .cp-fx__item-one; - padding: 0 var(--sp-tight); - } - - & > button { - @include dir.side(margin, var(--sp-normal), 0); - } -} \ No newline at end of file diff --git a/src/app/organisms/space-settings/SpaceSettings.jsx b/src/app/organisms/space-settings/SpaceSettings.jsx index 46fe7b3f7..ff6c18632 100644 --- a/src/app/organisms/space-settings/SpaceSettings.jsx +++ b/src/app/organisms/space-settings/SpaceSettings.jsx @@ -2,12 +2,9 @@ import React, { useState, useEffect } from 'react'; import PropTypes from 'prop-types'; import './SpaceSettings.scss'; -import { twemojify } from '../../../util/twemojify'; - import initMatrix from '../../../client/initMatrix'; import cons from '../../../client/state/cons'; import navigation from '../../../client/state/navigation'; -import { leave } from '../../../client/action/room'; import Text from '../../atoms/text/Text'; import IconButton from '../../atoms/button/IconButton'; @@ -29,6 +26,7 @@ import LeaveArrowIC from '../../../../public/res/ic/outlined/leave-arrow.svg'; import EmojiIC from '../../../../public/res/ic/outlined/emoji.svg'; import { confirmDialog } from '../../molecules/confirm-dialog/ConfirmDialog'; +import { useMatrixClient } from '../../hooks/useMatrixClient'; const tabText = { GENERAL: 'General', @@ -62,6 +60,7 @@ const tabItems = [ function GeneralSettings({ roomId }) { const roomName = initMatrix.matrixClient.getRoom(roomId)?.name; + const mx = useMatrixClient(); return ( <> @@ -76,7 +75,7 @@ function GeneralSettings({ roomId }) { 'Leave', 'danger' ); - if (isConfirmed) leave(roomId); + if (isConfirmed) mx.leave(roomId); }} iconSrc={LeaveArrowIC} > @@ -138,7 +137,7 @@ function SpaceSettings() { className="space-settings" title={ - {isOpen && twemojify(room.name)} + {isOpen && room.name} — space settings } diff --git a/src/app/organisms/sticker-board/StickerBoard.jsx b/src/app/organisms/sticker-board/StickerBoard.jsx deleted file mode 100644 index 91e259186..000000000 --- a/src/app/organisms/sticker-board/StickerBoard.jsx +++ /dev/null @@ -1,115 +0,0 @@ -/* eslint-disable jsx-a11y/click-events-have-key-events */ -/* eslint-disable jsx-a11y/no-static-element-interactions */ -import React, { useRef } from 'react'; -import PropTypes from 'prop-types'; -import './StickerBoard.scss'; - -import initMatrix from '../../../client/initMatrix'; -import { getRelevantPacks } from '../emoji-board/custom-emoji'; - -import Text from '../../atoms/text/Text'; -import ScrollView from '../../atoms/scroll/ScrollView'; -import IconButton from '../../atoms/button/IconButton'; - -function StickerBoard({ roomId, onSelect }) { - const mx = initMatrix.matrixClient; - const room = mx.getRoom(roomId); - const scrollRef = useRef(null); - - const parentIds = initMatrix.roomList.getAllParentSpaces(room.roomId); - const parentRooms = [...parentIds].map((id) => mx.getRoom(id)); - - const packs = getRelevantPacks( - mx, - [room, ...parentRooms], - ).filter((pack) => pack.getStickers().length !== 0); - - function isTargetNotSticker(target) { - return target.classList.contains('sticker-board__sticker') === false; - } - function getStickerData(target) { - const mxc = target.getAttribute('data-mx-sticker'); - const body = target.getAttribute('title'); - const httpUrl = target.getAttribute('src'); - return { mxc, body, httpUrl }; - } - const handleOnSelect = (e) => { - if (isTargetNotSticker(e.target)) return; - - const stickerData = getStickerData(e.target); - onSelect(stickerData); - }; - - const openGroup = (groupIndex) => { - const scrollContent = scrollRef.current.firstElementChild; - scrollContent.children[groupIndex].scrollIntoView(); - }; - - const renderPack = (pack) => ( -
      - {pack.displayName ?? 'Unknown'} -
      - {pack.getStickers().map((sticker) => ( - {sticker.shortcode} - ))} -
      -
      - ); - - return ( -
      - {packs.length > 0 && ( - -
      - {packs.map((pack, index) => { - const src = mx.mxcUrlToHttp(pack.avatarUrl ?? pack.getStickers()[0].mxc); - return ( - openGroup(index)} - src={src} - tooltip={pack.displayName || 'Unknown'} - tooltipPlacement="left" - isImage - /> - ); - })} -
      -
      - )} -
      - -
      - { - packs.length > 0 - ? packs.map(renderPack) - : ( -
      - There is no sticker pack. -
      - ) - } -
      -
      -
      -
      -
      - ); -} -StickerBoard.propTypes = { - roomId: PropTypes.string.isRequired, - onSelect: PropTypes.func.isRequired, -}; - -export default StickerBoard; diff --git a/src/app/organisms/sticker-board/StickerBoard.scss b/src/app/organisms/sticker-board/StickerBoard.scss deleted file mode 100644 index b4e551301..000000000 --- a/src/app/organisms/sticker-board/StickerBoard.scss +++ /dev/null @@ -1,74 +0,0 @@ -@use '../../partials/dir'; - -.sticker-board { - --sticker-board-height: 390px; - --sticker-board-width: 286px; - display: flex; - height: var(--sticker-board-height); - display: flex; - - & > .scrollbar { - width: initial; - height: var(--sticker-board-height); - } - - &__sidebar { - display: flex; - flex-direction: column; - min-height: 100%; - padding: 4px 6px; - @include dir.side(border, none, 1px solid var(--bg-surface-border)); - } - - &__container { - flex-grow: 1; - min-width: 0; - width: var(--sticker-board-width); - display: flex; - } - - &__content { - min-height: 100%; - } - - &__pack { - margin-bottom: var(--sp-normal); - position: relative; - - &-header { - position: sticky; - top: 0; - z-index: 99; - background-color: var(--bg-surface); - - @include dir.side(margin, var(--sp-extra-tight), 0); - padding: var(--sp-extra-tight) var(--sp-ultra-tight); - text-transform: uppercase; - box-shadow: 0 -4px 0 0 var(--bg-surface); - border-bottom: 1px solid var(--bg-surface-border); - } - &-items { - margin: var(--sp-tight); - @include dir.side(margin, var(--sp-normal), var(--sp-extra-tight)); - display: flex; - flex-wrap: wrap; - gap: var(--sp-normal) var(--sp-tight); - - img { - width: 76px; - height: 76px; - object-fit: contain; - cursor: pointer; - } - } - } - - &__empty { - width: 100%; - height: var(--sticker-board-height); - display: flex; - justify-content: center; - align-items: center; - text-align: center; - } -} \ No newline at end of file diff --git a/src/app/organisms/view-source/ViewSource.jsx b/src/app/organisms/view-source/ViewSource.jsx deleted file mode 100644 index 9bd3334f5..000000000 --- a/src/app/organisms/view-source/ViewSource.jsx +++ /dev/null @@ -1,73 +0,0 @@ -import React, { useEffect, useState } from 'react'; -import PropTypes from 'prop-types'; -import './ViewSource.scss'; - -import cons from '../../../client/state/cons'; -import navigation from '../../../client/state/navigation'; - -import IconButton from '../../atoms/button/IconButton'; -import { MenuHeader } from '../../atoms/context-menu/ContextMenu'; -import ScrollView from '../../atoms/scroll/ScrollView'; -import PopupWindow from '../../molecules/popup-window/PopupWindow'; - -import CrossIC from '../../../../public/res/ic/outlined/cross.svg'; - -function ViewSourceBlock({ title, json }) { - return ( -
      - {title} - -
      -          
      -            {JSON.stringify(json, null, 2)}
      -          
      -        
      -
      -
      - ); -} -ViewSourceBlock.propTypes = { - title: PropTypes.string.isRequired, - json: PropTypes.shape({}).isRequired, -}; - -function ViewSource() { - const [isOpen, setIsOpen] = useState(false); - const [event, setEvent] = useState(null); - - useEffect(() => { - const loadViewSource = (e) => { - setEvent(e); - setIsOpen(true); - }; - navigation.on(cons.events.navigation.VIEWSOURCE_OPENED, loadViewSource); - return () => { - navigation.removeListener(cons.events.navigation.VIEWSOURCE_OPENED, loadViewSource); - }; - }, []); - - const handleAfterClose = () => { - setEvent(null); - }; - - const renderViewSource = () => ( -
      - {event.isEncrypted() && } - -
      - ); - - return ( - setIsOpen(false)} - contentOptions={ setIsOpen(false)} tooltip="Close" />} - > - {event ? renderViewSource() :
      } - - ); -} - -export default ViewSource; diff --git a/src/app/organisms/view-source/ViewSource.scss b/src/app/organisms/view-source/ViewSource.scss deleted file mode 100644 index 9ceab8b03..000000000 --- a/src/app/organisms/view-source/ViewSource.scss +++ /dev/null @@ -1,19 +0,0 @@ -@use '../../partials/dir'; - -.view-source { - @include dir.side(margin, var(--sp-normal), var(--sp-extra-tight)); - - & pre { - padding: var(--sp-extra-tight); - white-space: pre-wrap; - word-break: break-all; - } - - &__card { - margin: var(--sp-normal) 0; - background-color: var(--bg-surface-hover); - border-radius: var(--bo-radius); - box-shadow: var(--bs-surface-border); - overflow: hidden; - } -} diff --git a/src/app/organisms/welcome/Welcome.jsx b/src/app/organisms/welcome/Welcome.jsx deleted file mode 100644 index 6d135bee2..000000000 --- a/src/app/organisms/welcome/Welcome.jsx +++ /dev/null @@ -1,20 +0,0 @@ -import React from 'react'; -import './Welcome.scss'; - -import Text from '../../atoms/text/Text'; - -import CinnySvg from '../../../../public/res/svg/cinny.svg'; - -function Welcome() { - return ( -
      -
      - Cinny logo - Welcome to Cinny - Yet another matrix client -
      -
      - ); -} - -export default Welcome; diff --git a/src/app/organisms/welcome/Welcome.scss b/src/app/organisms/welcome/Welcome.scss deleted file mode 100644 index e55bb8edd..000000000 --- a/src/app/organisms/welcome/Welcome.scss +++ /dev/null @@ -1,23 +0,0 @@ -@use '../../partials/flex'; - -.app-welcome { - width: 100%; - height: 100%; - background-color: var(--bg-surface); - - & > div { - @extend .cp-fx__column--c-c; - max-width: 600px; - } - &__logo { - width: 64px; - height: 64px; - } - &__heading { - margin: var(--sp-extra-loose) 0 var(--sp-tight); - color: var(--tc-surface-high); - } - &__subheading { - color: var(--tc-surface-normal); - } -} \ No newline at end of file diff --git a/src/app/pages/Router.tsx b/src/app/pages/Router.tsx index ffa20d4ed..7d0f4fdeb 100644 --- a/src/app/pages/Router.tsx +++ b/src/app/pages/Router.tsx @@ -54,6 +54,7 @@ import { PageRoot } from '../components/page'; import { ScreenSize } from '../hooks/useScreenSize'; import { MobileFriendlyPageNav, MobileFriendlyClientNav } from './MobileFriendly'; import { ClientInitStorageAtom } from './client/ClientInitStorageAtom'; +import { ClientNonUIFeatures } from './client/ClientNonUIFeatures'; export const createRouter = (clientConfig: ClientConfig, screenSize: ScreenSize) => { const { hashRouter } = clientConfig; @@ -101,15 +102,17 @@ export const createRouter = (clientConfig: ClientConfig, screenSize: ScreenSize) - - - - } - > - - + + + + + } + > + + + diff --git a/src/app/pages/client/ClientNonUIFeatures.tsx b/src/app/pages/client/ClientNonUIFeatures.tsx new file mode 100644 index 000000000..27d1ae40d --- /dev/null +++ b/src/app/pages/client/ClientNonUIFeatures.tsx @@ -0,0 +1,231 @@ +import { useAtomValue } from 'jotai'; +import React, { ReactNode, useCallback, useEffect, useRef } from 'react'; +import { useNavigate } from 'react-router-dom'; +import { RoomEvent, RoomEventHandlerMap } from 'matrix-js-sdk'; +import { roomToUnreadAtom, unreadEqual, unreadInfoToUnread } from '../../state/room/roomToUnread'; +import LogoSVG from '../../../../public/res/svg/cinny.svg'; +import LogoUnreadSVG from '../../../../public/res/svg/cinny-unread.svg'; +import LogoHighlightSVG from '../../../../public/res/svg/cinny-highlight.svg'; +import { setFavicon } from '../../utils/dom'; +import { useSetting } from '../../state/hooks/settings'; +import { settingsAtom } from '../../state/settings'; +import { allInvitesAtom } from '../../state/room-list/inviteList'; +import { usePreviousValue } from '../../hooks/usePreviousValue'; +import { useMatrixClient } from '../../hooks/useMatrixClient'; +import { getInboxInvitesPath, getInboxNotificationsPath } from '../pathUtils'; +import { + getMemberDisplayName, + getNotificationType, + getUnreadInfo, + isNotificationEvent, +} from '../../utils/room'; +import { NotificationType, UnreadInfo } from '../../../types/matrix/room'; +import { getMxIdLocalPart } from '../../utils/matrix'; +import { useSelectedRoom } from '../../hooks/router/useSelectedRoom'; +import { useInboxNotificationsSelected } from '../../hooks/router/useInbox'; + +function FaviconUpdater() { + const roomToUnread = useAtomValue(roomToUnreadAtom); + + useEffect(() => { + if (roomToUnread.size === 0) { + setFavicon(LogoSVG); + } else { + const highlight = Array.from(roomToUnread.entries()).find( + ([, unread]) => unread.highlight > 0 + ); + + setFavicon(highlight ? LogoHighlightSVG : LogoUnreadSVG); + } + }, [roomToUnread]); + + return null; +} + +function InviteNotifications() { + const audioRef = useRef(null); + const invites = useAtomValue(allInvitesAtom); + const perviousInviteLen = usePreviousValue(invites.length, 0); + const mx = useMatrixClient(); + + const navigate = useNavigate(); + const [notificationSound] = useSetting(settingsAtom, 'isNotificationSounds'); + + const notify = useCallback( + (count: number) => { + const noti = new window.Notification('Invitation', { + icon: LogoSVG, + badge: LogoSVG, + body: `You have ${count} new invitation request.`, + silent: true, + }); + + noti.onclick = () => { + if (!window.closed) navigate(getInboxInvitesPath()); + noti.close(); + }; + }, + [navigate] + ); + + const playSound = useCallback(() => { + const audioElement = audioRef.current; + audioElement?.play(); + }, []); + + useEffect(() => { + if (invites.length > perviousInviteLen && mx.getSyncState() === 'SYNCING') { + if (Notification.permission === 'granted') { + notify(invites.length - perviousInviteLen); + } + + if (notificationSound) { + playSound(); + } + } + }, [mx, invites, perviousInviteLen, notificationSound, notify, playSound]); + + return ( + // eslint-disable-next-line jsx-a11y/media-has-caption + + ); +} + +function MessageNotifications() { + const audioRef = useRef(null); + const notifRef = useRef(); + const unreadCacheRef = useRef>(new Map()); + const mx = useMatrixClient(); + const [showNotifications] = useSetting(settingsAtom, 'showNotifications'); + const [notificationSound] = useSetting(settingsAtom, 'isNotificationSounds'); + + const navigate = useNavigate(); + const notificationSelected = useInboxNotificationsSelected(); + const selectedRoomId = useSelectedRoom(); + + const notify = useCallback( + ({ + roomName, + roomAvatar, + username, + }: { + roomName: string; + roomAvatar?: string; + username: string; + roomId: string; + eventId: string; + }) => { + const noti = new window.Notification(roomName, { + icon: roomAvatar, + badge: roomAvatar, + body: `New inbox notification from ${username}`, + silent: true, + }); + + noti.onclick = () => { + if (!window.closed) navigate(getInboxNotificationsPath()); + noti.close(); + notifRef.current = undefined; + }; + + notifRef.current?.close(); + notifRef.current = noti; + }, + [navigate] + ); + + const playSound = useCallback(() => { + const audioElement = audioRef.current; + audioElement?.play(); + }, []); + + useEffect(() => { + const handleTimelineEvent: RoomEventHandlerMap[RoomEvent.Timeline] = ( + mEvent, + room, + toStartOfTimeline, + removed, + data + ) => { + if ( + mx.getSyncState() !== 'SYNCING' || + selectedRoomId === room?.roomId || + notificationSelected || + !room || + !data.liveEvent || + room.isSpaceRoom() || + !isNotificationEvent(mEvent) || + getNotificationType(mx, room.roomId) === NotificationType.Mute + ) + return; + + const sender = mEvent.getSender(); + const eventId = mEvent.getId(); + if (!sender || !eventId || mEvent.getSender() === mx.getUserId()) return; + const unreadInfo = getUnreadInfo(room); + const cachedUnreadInfo = unreadCacheRef.current.get(room.roomId); + unreadCacheRef.current.set(room.roomId, unreadInfo); + + if ( + cachedUnreadInfo && + unreadEqual(unreadInfoToUnread(cachedUnreadInfo), unreadInfoToUnread(unreadInfo)) + ) { + return; + } + + if (showNotifications && Notification.permission === 'granted') { + const avatarMxc = + room.getAvatarFallbackMember()?.getMxcAvatarUrl() ?? room.getMxcAvatarUrl(); + notify({ + roomName: room.name ?? 'Unknown', + roomAvatar: avatarMxc + ? mx.mxcUrlToHttp(avatarMxc, 96, 96, 'crop') ?? undefined + : undefined, + username: getMemberDisplayName(room, sender) ?? getMxIdLocalPart(sender) ?? sender, + roomId: room.roomId, + eventId, + }); + } + + if (notificationSound) { + playSound(); + } + }; + mx.on(RoomEvent.Timeline, handleTimelineEvent); + return () => { + mx.removeListener(RoomEvent.Timeline, handleTimelineEvent); + }; + }, [ + mx, + notificationSound, + notificationSelected, + showNotifications, + playSound, + notify, + selectedRoomId, + ]); + + return ( + // eslint-disable-next-line jsx-a11y/media-has-caption + + ); +} + +type ClientNonUIFeaturesProps = { + children: ReactNode; +}; + +export function ClientNonUIFeatures({ children }: ClientNonUIFeaturesProps) { + return ( + <> + + + + {children} + + ); +} diff --git a/src/app/pages/client/ClientRoot.tsx b/src/app/pages/client/ClientRoot.tsx index 1bb7855b6..6a1dbcb16 100644 --- a/src/app/pages/client/ClientRoot.tsx +++ b/src/app/pages/client/ClientRoot.tsx @@ -2,7 +2,6 @@ import { Box, Spinner, Text } from 'folds'; import React, { ReactNode, useEffect, useState } from 'react'; import initMatrix from '../../../client/initMatrix'; import { initHotkeys } from '../../../client/event/hotkeys'; -import { initRoomListListener } from '../../../client/event/roomList'; import { getSecret } from '../../../client/state/auth'; import { SplashScreen } from '../../components/splash-screen'; import { CapabilitiesAndMediaConfigLoader } from '../../components/CapabilitiesAndMediaConfigLoader'; @@ -49,7 +48,6 @@ export function ClientRoot({ children }: ClientRootProps) { useEffect(() => { const handleStart = () => { initHotkeys(); - initRoomListListener(initMatrix.roomList); setLoading(false); }; initMatrix.once('init_loading_finished', handleStart); diff --git a/src/app/pages/client/inbox/Notifications.tsx b/src/app/pages/client/inbox/Notifications.tsx index 1ab08f01c..8b9d1847c 100644 --- a/src/app/pages/client/inbox/Notifications.tsx +++ b/src/app/pages/client/inbox/Notifications.tsx @@ -31,13 +31,20 @@ import { InboxNotificationsPathSearchParams } from '../../paths'; import { AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback'; import { SequenceCard } from '../../../components/sequence-card'; import { RoomAvatar, RoomIcon } from '../../../components/room-avatar'; -import { getMemberAvatarMxc, getMemberDisplayName, getRoomAvatarUrl } from '../../../utils/room'; +import { + getEditedEvent, + getMemberAvatarMxc, + getMemberDisplayName, + getRoomAvatarUrl, +} from '../../../utils/room'; import { ScrollTopContainer } from '../../../components/scroll-top-container'; import { useInterval } from '../../../hooks/useInterval'; import { AvatarBase, ImageContent, MSticker, + MessageNotDecryptedContent, + MessageUnsupportedContent, ModernLayout, RedactedContent, Reply, @@ -62,6 +69,7 @@ import { markAsRead } from '../../../../client/action/notifications'; import { ContainerColor } from '../../../styles/ContainerColor.css'; import { VirtualTile } from '../../../components/virtualizer'; import { UserAvatar } from '../../../components/user-avatar'; +import { EncryptedContent } from '../../../features/room/message'; type RoomNotificationsGroup = { roomId: string; @@ -225,6 +233,78 @@ function RoomNotificationsGroupComp({ /> ); }, + [MessageEvent.RoomMessageEncrypted]: (evt, displayName) => { + const evtTimeline = room.getTimelineForEvent(evt.event_id); + + const mEvent = evtTimeline?.getEvents().find((e) => e.getId() === evt.event_id); + + if (!mEvent || !evtTimeline) { + return ( + + + {evt.type} + {' event'} + + + ); + } + + return ( + + {() => { + if (mEvent.isRedacted()) return ; + if (mEvent.getType() === MessageEvent.Sticker) + return ( + ( + } + renderViewer={(p) => } + /> + )} + /> + ); + if (mEvent.getType() === MessageEvent.RoomMessage) { + const editedEvent = getEditedEvent( + evt.event_id, + mEvent, + evtTimeline.getTimelineSet() + ); + const getContent = (() => + editedEvent?.getContent()['m.new_content'] ?? + mEvent.getContent()) as GetContentCallback; + + return ( + + ); + } + if (mEvent.getType() === MessageEvent.RoomMessageEncrypted) + return ( + + + + ); + return ( + + + + ); + }} + + ); + }, [MessageEvent.Sticker]: (event, displayName, getContent) => { if (event.unsigned?.redacted_because) { return ; @@ -398,7 +478,7 @@ const useNotificationsSearchParams = ( [searchParams] ); -const DEFAULT_REFRESH_MS = 10000; +const DEFAULT_REFRESH_MS = 7000; export function Notifications() { const mx = useMatrixClient(); @@ -441,9 +521,7 @@ export function Notifications() { useInterval( useCallback(() => { - if (document.hasFocus()) { - silentReloadTimeline(); - } + silentReloadTimeline(); }, [silentReloadTimeline]), refreshIntervalTime ); diff --git a/src/app/state/room/roomToUnread.ts b/src/app/state/room/roomToUnread.ts index 4ac391fe9..5a009405e 100644 --- a/src/app/state/room/roomToUnread.ts +++ b/src/app/state/room/roomToUnread.ts @@ -45,7 +45,7 @@ export type RoomToUnreadAction = roomId: string; }; -const unreadInfoToUnread = (unreadInfo: UnreadInfo): Unread => ({ +export const unreadInfoToUnread = (unreadInfo: UnreadInfo): Unread => ({ highlight: unreadInfo.highlight, total: unreadInfo.total, from: null, diff --git a/src/app/state/typingMembers.ts b/src/app/state/typingMembers.ts index 88d4687cd..55bf8f628 100644 --- a/src/app/state/typingMembers.ts +++ b/src/app/state/typingMembers.ts @@ -1,6 +1,5 @@ import produce from 'immer'; import { atom, useSetAtom } from 'jotai'; -import { selectAtom } from 'jotai/utils'; import { MatrixClient, RoomMemberEvent, RoomMemberEventHandlerMap } from 'matrix-js-sdk'; import { useEffect } from 'react'; @@ -148,8 +147,3 @@ export const useBindRoomIdToTypingMembersAtom = ( }; }, [mx, setTypingMembers]); }; - -export const selectRoomTypingMembersAtom = ( - roomId: string, - typingMembersAtom: typeof roomIdToTypingMembersAtom -) => selectAtom(typingMembersAtom, (atoms) => atoms.get(roomId) ?? []); diff --git a/src/app/templates/auth/Auth.jsx b/src/app/templates/auth/Auth.jsx deleted file mode 100644 index 7c2117360..000000000 --- a/src/app/templates/auth/Auth.jsx +++ /dev/null @@ -1,684 +0,0 @@ -/* eslint-disable react/prop-types */ -import React, { useState, useEffect, useRef } from 'react'; -import PropTypes from 'prop-types'; -import './Auth.scss'; -import ReCAPTCHA from 'react-google-recaptcha'; -import { Formik } from 'formik'; - -import * as auth from '../../../client/action/auth'; -import cons from '../../../client/state/cons'; -import { Debounce, getUrlPrams } from '../../../util/common'; -import { getBaseUrl } from '../../../util/matrixUtil'; - -import Text from '../../atoms/text/Text'; -import Button from '../../atoms/button/Button'; -import IconButton from '../../atoms/button/IconButton'; -import Input from '../../atoms/input/Input'; -import Spinner from '../../atoms/spinner/Spinner'; -import ScrollView from '../../atoms/scroll/ScrollView'; -import Header, { TitleWrapper } from '../../atoms/header/Header'; -import Avatar from '../../atoms/avatar/Avatar'; -import ContextMenu, { MenuItem, MenuHeader } from '../../atoms/context-menu/ContextMenu'; - -import ChevronBottomIC from '../../../../public/res/ic/outlined/chevron-bottom.svg'; -import EyeIC from '../../../../public/res/ic/outlined/eye.svg'; -import EyeBlindIC from '../../../../public/res/ic/outlined/eye-blind.svg'; -import CinnySvg from '../../../../public/res/svg/cinny.svg'; -import SSOButtons from '../../molecules/sso-buttons/SSOButtons'; - -const LOCALPART_SIGNUP_REGEX = /^[a-z0-9_\-.=/]+$/; -const BAD_LOCALPART_ERROR = 'Username can only contain characters a-z, 0-9, or \'=_-./\''; -const USER_ID_TOO_LONG_ERROR = 'Your user ID, including the hostname, can\'t be more than 255 characters long.'; - -const PASSWORD_STRENGHT_REGEX = /^(?=.*\d)(?=.*[A-Z])(?=.*[a-z])(?=.*[^\w\d\s:])([^\s]){8,127}$/; -const BAD_PASSWORD_ERROR = 'Password must contain at least 1 lowercase, 1 uppercase, 1 number, 1 non-alphanumeric character, 8-127 characters with no space.'; -const CONFIRM_PASSWORD_ERROR = 'Passwords don\'t match.'; - -const EMAIL_REGEX = /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i; -const BAD_EMAIL_ERROR = 'Invalid email address'; - -function isValidInput(value, regex) { - if (typeof regex === 'string') return regex === value; - return regex.test(value); -} -function normalizeUsername(rawUsername) { - const noLeadingAt = rawUsername.indexOf('@') === 0 ? rawUsername.substr(1) : rawUsername; - return noLeadingAt.trim(); -} - -let searchingHs = null; -function Homeserver({ onChange }) { - const [hs, setHs] = useState(null); - const [debounce] = useState(new Debounce()); - const [process, setProcess] = useState({ isLoading: true, message: 'Loading homeserver list...' }); - const hsRef = useRef(); - - const setupHsConfig = async (servername) => { - setProcess({ isLoading: true, message: 'Looking for homeserver...' }); - let baseUrl = null; - baseUrl = await getBaseUrl(servername); - - if (searchingHs !== servername) return; - setProcess({ isLoading: true, message: `Connecting to ${baseUrl}...` }); - const tempClient = auth.createTemporaryClient(baseUrl); - - Promise.allSettled([tempClient.loginFlows(), tempClient.register()]) - .then((values) => { - const loginFlow = values[0].status === 'fulfilled' ? values[0]?.value : undefined; - const registerFlow = values[1].status === 'rejected' ? values[1]?.reason?.data : undefined; - if (loginFlow === undefined || registerFlow === undefined) throw new Error(); - - if (searchingHs !== servername) return; - onChange({ baseUrl, login: loginFlow, register: registerFlow }); - setProcess({ isLoading: false }); - }).catch(() => { - if (searchingHs !== servername) return; - onChange(null); - setProcess({ isLoading: false, error: 'Unable to connect. Please check your input.' }); - }); - }; - - useEffect(() => { - onChange(null); - if (hs === null || hs?.selected.trim() === '') return; - searchingHs = hs.selected; - setupHsConfig(hs.selected); - }, [hs]); - - useEffect(async () => { - const link = window.location.href; - const configFileUrl = `${link}${link[link.length - 1] === '/' ? '' : '/'}config.json`; - try { - const result = await (await fetch(configFileUrl, { method: 'GET' })).json(); - const selectedHs = result?.defaultHomeserver; - const hsList = result?.homeserverList; - const allowCustom = result?.allowCustomHomeservers ?? true; - if (!hsList?.length > 0 || selectedHs < 0 || selectedHs >= hsList?.length) { - throw new Error(); - } - setHs({ selected: hsList[selectedHs], list: hsList, allowCustom }); - } catch { - setHs({ selected: 'matrix.org', list: ['matrix.org'], allowCustom: true }); - } - }, []); - - const handleHsInput = (e) => { - const { value } = e.target; - setProcess({ isLoading: false }); - debounce._(async () => { - setHs({ ...hs, selected: value.trim() }); - }, 700)(); - }; - - return ( - <> -
      - - ( - <> - Homeserver list - { - hs?.list.map((hsName) => ( - { - hideMenu(); - hsRef.current.value = hsName; - setHs({ ...hs, selected: hsName }); - }} - > - {hsName} - - )) - } - - )} - render={(toggleMenu) => } - /> -
      - {process.error !== undefined && {process.error}} - {process.isLoading && ( -
      - - {process.message} -
      - )} - - ); -} -Homeserver.propTypes = { - onChange: PropTypes.func.isRequired, -}; - -function Login({ loginFlow, baseUrl }) { - const [typeIndex, setTypeIndex] = useState(0); - const [passVisible, setPassVisible] = useState(false); - const loginTypes = ['Username', 'Email']; - const isPassword = loginFlow?.filter((flow) => flow.type === 'm.login.password')[0]; - const ssoProviders = loginFlow?.filter((flow) => flow.type === 'm.login.sso')[0]; - - const initialValues = { - username: '', password: '', email: '', other: '', - }; - - const validator = (values) => { - const errors = {}; - if (typeIndex === 1 && values.email.length > 0 && !isValidInput(values.email, EMAIL_REGEX)) { - errors.email = BAD_EMAIL_ERROR; - } - return errors; - }; - const submitter = async (values, actions) => { - let userBaseUrl = baseUrl; - let { username } = values; - const mxIdMatch = username.match(/^@(.+):(.+\..+)$/); - if (typeIndex === 0 && mxIdMatch) { - [, username, userBaseUrl] = mxIdMatch; - userBaseUrl = await getBaseUrl(userBaseUrl); - } - - return auth.login( - userBaseUrl, - typeIndex === 0 ? normalizeUsername(username) : undefined, - typeIndex === 1 ? values.email : undefined, - values.password, - ).then(() => { - actions.setSubmitting(true); - window.location.reload(); - }).catch((error) => { - let msg = error.message; - if (msg === 'Unknown message') msg = 'Please check your credentials'; - actions.setErrors({ - password: msg === 'Invalid password' ? msg : undefined, - other: msg !== 'Invalid password' ? msg : undefined, - }); - actions.setSubmitting(false); - }); - }; - - return ( - <> -
      - Login - {isPassword && ( - ( - loginTypes.map((type, index) => ( - { - hideMenu(); - setTypeIndex(index); - }} - > - {type} - - )) - )} - render={(toggleMenu) => ( - - )} - /> - )} -
      - {isPassword && ( - - {({ - values, errors, handleChange, handleSubmit, isSubmitting, - }) => ( - <> - {isSubmitting && } -
      - {typeIndex === 0 && } - {errors.username && {errors.username}} - {typeIndex === 1 && } - {errors.email && {errors.email}} -
      - - setPassVisible(!passVisible)} src={passVisible ? EyeIC : EyeBlindIC} size="extra-small" /> -
      - {errors.password && {errors.password}} - {errors.other && {errors.other}} -
      - -
      -
      - - )} -
      - )} - {ssoProviders && isPassword && OR} - {ssoProviders && ( - - )} - - ); -} -Login.propTypes = { - loginFlow: PropTypes.arrayOf( - PropTypes.shape({}), - ).isRequired, - baseUrl: PropTypes.string.isRequired, -}; - -let sid; -let clientSecret; -function Register({ registerInfo, loginFlow, baseUrl }) { - const [process, setProcess] = useState({}); - const [passVisible, setPassVisible] = useState(false); - const [cPassVisible, setCPassVisible] = useState(false); - const formRef = useRef(); - - const ssoProviders = loginFlow?.filter((flow) => flow.type === 'm.login.sso')[0]; - const isDisabled = registerInfo.errcode !== undefined; - const { flows, params, session } = registerInfo; - - let isEmail = false; - let isEmailRequired = true; - let isRecaptcha = false; - let isTerms = false; - let isDummy = false; - - flows?.forEach((flow) => { - if (isEmailRequired && flow.stages.indexOf('m.login.email.identity') === -1) isEmailRequired = false; - if (!isEmail) isEmail = flow.stages.indexOf('m.login.email.identity') > -1; - if (!isRecaptcha) isRecaptcha = flow.stages.indexOf('m.login.recaptcha') > -1; - if (!isTerms) isTerms = flow.stages.indexOf('m.login.terms') > -1; - if (!isDummy) isDummy = flow.stages.indexOf('m.login.dummy') > -1; - }); - - const initialValues = { - username: '', password: '', confirmPassword: '', email: '', other: '', - }; - - const validator = (values) => { - const errors = {}; - if (values.username.list > 255) errors.username = USER_ID_TOO_LONG_ERROR; - if (values.username.length > 0 && !isValidInput(values.username, LOCALPART_SIGNUP_REGEX)) { - errors.username = BAD_LOCALPART_ERROR; - } - if (values.password.length > 0 && !isValidInput(values.password, PASSWORD_STRENGHT_REGEX)) { - errors.password = BAD_PASSWORD_ERROR; - } - if (values.confirmPassword.length > 0 - && !isValidInput(values.confirmPassword, values.password)) { - errors.confirmPassword = CONFIRM_PASSWORD_ERROR; - } - if (values.email.length > 0 && !isValidInput(values.email, EMAIL_REGEX)) { - errors.email = BAD_EMAIL_ERROR; - } - return errors; - }; - const submitter = (values, actions) => { - const tempClient = auth.createTemporaryClient(baseUrl); - clientSecret = tempClient.generateClientSecret(); - return tempClient.isUsernameAvailable(values.username) - .then(async (isAvail) => { - if (!isAvail) { - actions.setErrors({ username: 'Username is already taken' }); - actions.setSubmitting(false); - return; - } - if (isEmail && values.email.length > 0) { - const result = await auth.verifyEmail(baseUrl, values.email, clientSecret, 1); - if (result.errcode) { - if (result.errcode === 'M_THREEPID_IN_USE') actions.setErrors({ email: result.error }); - else actions.setErrors({ others: result.error || result.message }); - actions.setSubmitting(false); - return; - } - sid = result.sid; - } - setProcess({ type: 'processing', message: 'Registration in progress....' }); - actions.setSubmitting(false); - }).catch((err) => { - const msg = err.message || err.error; - if (['M_USER_IN_USE', 'M_INVALID_USERNAME', 'M_EXCLUSIVE'].indexOf(err.errcode) > -1) { - actions.setErrors({ username: err.errcode === 'M_USER_IN_USE' ? 'Username is already taken' : msg }); - } else if (msg) actions.setErrors({ other: msg }); - - actions.setSubmitting(false); - }); - }; - - const refreshWindow = () => window.location.reload(); - - const getInputs = () => { - const f = formRef.current; - return [f.username.value, f.password.value, f?.email?.value]; - }; - - useEffect(() => { - if (process.type !== 'processing') return; - const asyncProcess = async () => { - const [username, password, email] = getInputs(); - const d = await auth.completeRegisterStage(baseUrl, username, password, { session }); - - if (isRecaptcha && !d.completed.includes('m.login.recaptcha')) { - const sitekey = params['m.login.recaptcha'].public_key; - setProcess({ type: 'm.login.recaptcha', sitekey }); - return; - } - if (isTerms && !d.completed.includes('m.login.terms')) { - const pp = params['m.login.terms'].policies.privacy_policy; - const url = pp?.en.url || pp[Object.keys(pp)[0]].url; - setProcess({ type: 'm.login.terms', url }); - return; - } - if (isEmail && email.length > 0) { - setProcess({ type: 'm.login.email.identity', email }); - return; - } - if (isDummy) { - const data = await auth.completeRegisterStage(baseUrl, username, password, { - type: 'm.login.dummy', - session, - }); - if (data.done) refreshWindow(); - } - }; - asyncProcess(); - }, [process]); - - const handleRecaptcha = async (value) => { - if (typeof value !== 'string') return; - const [username, password] = getInputs(); - const d = await auth.completeRegisterStage(baseUrl, username, password, { - type: 'm.login.recaptcha', - response: value, - session, - }); - if (d.done) refreshWindow(); - else setProcess({ type: 'processing', message: 'Registration in progress...' }); - }; - const handleTerms = async () => { - const [username, password] = getInputs(); - const d = await auth.completeRegisterStage(baseUrl, username, password, { - type: 'm.login.terms', - session, - }); - if (d.done) refreshWindow(); - else setProcess({ type: 'processing', message: 'Registration in progress...' }); - }; - const handleEmailVerify = async () => { - const [username, password] = getInputs(); - const d = await auth.completeRegisterStage(baseUrl, username, password, { - type: 'm.login.email.identity', - threepidCreds: { sid, client_secret: clientSecret }, - threepid_creds: { sid, client_secret: clientSecret }, - session, - }); - if (d.done) refreshWindow(); - else setProcess({ type: 'processing', message: 'Registration in progress...' }); - }; - - return ( - <> - {process.type === 'processing' && } - {process.type === 'm.login.recaptcha' && } - {process.type === 'm.login.terms' && } - {process.type === 'm.login.email.identity' && } -
      - {!isDisabled && Register} - {isDisabled && {registerInfo.error}} -
      - {!isDisabled && ( - - {({ - values, errors, handleChange, handleSubmit, isSubmitting, - }) => ( - <> - {process.type === undefined && isSubmitting && } -
      - - {errors.username && {errors.username}} -
      - - setPassVisible(!passVisible)} src={passVisible ? EyeIC : EyeBlindIC} size="extra-small" /> -
      - {errors.password && {errors.password}} -
      - - setCPassVisible(!cPassVisible)} src={cPassVisible ? EyeIC : EyeBlindIC} size="extra-small" /> -
      - {errors.confirmPassword && {errors.confirmPassword}} - {isEmail && } - {errors.email && {errors.email}} - {errors.other && {errors.other}} -
      - -
      -
      - - )} -
      - )} - {isDisabled && ssoProviders && ( - - )} - - ); -} -Register.propTypes = { - registerInfo: PropTypes.shape({}).isRequired, - loginFlow: PropTypes.arrayOf( - PropTypes.shape({}), - ).isRequired, - baseUrl: PropTypes.string.isRequired, -}; - -function AuthCard() { - const [hsConfig, setHsConfig] = useState(null); - const [type, setType] = useState('login'); - - const handleHsChange = (info) => { - console.log(info); - setHsConfig(info); - }; - - return ( - <> - - { hsConfig !== null && ( - type === 'login' - ? - : ( - - ) - )} - { hsConfig !== null && ( - - {`${(type === 'login' ? 'Don\'t have' : 'Already have')} an account?`} - - - )} - - ); -} - -function Auth() { - const [loginToken, setLoginToken] = useState(getUrlPrams('loginToken')); - - useEffect(async () => { - if (!loginToken) return; - if (localStorage.getItem(cons.secretKey.BASE_URL) === undefined) { - setLoginToken(null); - return; - } - const baseUrl = localStorage.getItem(cons.secretKey.BASE_URL); - try { - await auth.loginWithToken(baseUrl, loginToken); - - const { href } = window.location; - window.location.replace(href.slice(0, href.indexOf('?'))); - } catch { - setLoginToken(null); - } - }, []); - - return ( - -
      -
      - {loginToken && } - {!loginToken && ( -
      -
      - - - Cinny - -
      -
      - -
      -
      - )} -
      - - -
      -
      - ); -} - -function LoadingScreen({ message }) { - return ( - - -
      - {message} -
      -
      - ); -} -LoadingScreen.propTypes = { - message: PropTypes.string.isRequired, -}; - -function Recaptcha({ message, sitekey, onChange }) { - return ( - -
      - {message} -
      - -
      - ); -} -Recaptcha.propTypes = { - message: PropTypes.string.isRequired, - sitekey: PropTypes.string.isRequired, - onChange: PropTypes.func.isRequired, -}; - -function Terms({ url, onSubmit }) { - return ( - -
      { e.preventDefault(); onSubmit(); }}> -
      - Agree with terms -
      - In order to complete registration, you need to agree to the terms and conditions. -
      - - - {'I accept '} - Terms and Conditions - -
      - -
      - - - ); -} -Terms.propTypes = { - url: PropTypes.string.isRequired, - onSubmit: PropTypes.func.isRequired, -}; - -function EmailVerify({ email, onContinue }) { - return ( - -
      - Verify email -
      - - {'Please check your email '} - {`(${email})`} - {' and validate before continuing further.'} - -
      - -
      -
      - ); -} -EmailVerify.propTypes = { - email: PropTypes.string.isRequired, -}; - -function ProcessWrapper({ children }) { - return ( -
      - {children} -
      - ); -} -ProcessWrapper.propTypes = { - children: PropTypes.node.isRequired, -}; - -export default Auth; diff --git a/src/app/templates/auth/Auth.scss b/src/app/templates/auth/Auth.scss deleted file mode 100644 index 956a27004..000000000 --- a/src/app/templates/auth/Auth.scss +++ /dev/null @@ -1,173 +0,0 @@ -@use '../../partials/flex'; -@use '../../partials/dir'; - -.auth__base { - --pattern-size: 48px; - min-height: 100%; - background-color: var(--bg-surface-low); - - background-image: radial-gradient(rgba(0, 0, 0, 6%) 2px, rgba(0, 0, 0, 0%) 2px); - background-size: var(--pattern-size) var(--pattern-size); - - display: flex; - flex-direction: column; -} -.auth__wrapper { - flex: 1; - padding: var(--sp-loose); - padding-bottom: 0; - display: flex; - justify-content: center; - align-items: flex-start; -} -.auth-footer { - padding: var(--sp-normal) 0; - display: flex; - justify-content: center; - align-items: center; - - & > *:nth-child(2n) { - margin: 0 var(--sp-loose); - } - & a { - color: var(--tc-surface-normal); - &:hover { text-decoration: underline; } - } -} -.auth-card { - width: 462px; - background-color: var(--bg-surface); - border-radius: var(--bo-radius); - box-shadow: var(--bs-popup); - overflow: hidden; - - &__content { - padding: var(--sp-extra-loose) calc(var(--sp-normal) + var(--sp-extra-loose)); - } - &__switch { - margin-top: var(--sp-loose) !important; - } -} - -.homeserver-form, -.auth-form__heading { - & .context-menu__item .text { - margin: 0 !important; - } -} - -.homeserver-form { - display: flex; - margin-bottom: var(--sp-extra-tight); - align-items: flex-end; - & > .input-container { - flex: 1; - & .input { - background-color: var(--bg-surface); - @include dir.prop(border-right-width, 0, 1px); - @include dir.prop(border-left-width, 1px, 0 ); - @include dir.prop(border-radius, - var(--bo-radius) 0 0 var(--bo-radius), - 0 var(--bo-radius) var(--bo-radius) 0, - ); - } - } - & .ic-btn { - height: 46px; - border: 1px solid var(--bg-surface-border); - @include dir.prop(border-radius, - 0 var(--bo-radius) var(--bo-radius) 0, - var(--bo-radius) 0 0 var(--bo-radius), - ); - } - - &__status { - margin-top: var(--sp-normal); - & .donut-spinner { - min-width: 28px; - } - & .text { - margin: 0 var(--sp-tight); - } - } - &__error { - margin-bottom: var(--sp-normal) !important; - color: var(--tc-danger-normal) !important; - } -} - -.auth-form { - & > .input-container, - &__pass-eye-wrapper { - margin: var(--sp-tight) 0 var(--sp-ultra-tight); - } - - &__heading { - display: flex; - justify-content: space-between; - margin-top: calc(var(--sp-extra-loose) + var(--sp-tight)); - } - - &__pass-eye-wrapper { - position: relative; - & .ic-btn { - position: absolute; - @include dir.prop(right, 6px, unset); - @include dir.prop(left, unset, 6px ); - bottom: 6px; - border-radius: 4px; - } - & input { - @include dir.side(padding, var(--sp-normal), 46px); - } - } - - &__btns { - padding-top: var(--sp-loose); - margin-bottom: var(--sp-extra-loose); - display: flex; - justify-content: flex-end; - } - - &__error { - color: var(--tc-danger-normal) !important; - } -} -.sso__divider { - margin-bottom: var(--sp-tight); - display: flex; - align-items: center; - - &::before, - &::after { - flex: 1; - content: ''; - margin: var(--sp-tight); - border-bottom: 1px solid var(--bg-surface-border); - } -} - -@media (max-width: 462px) { - .auth__wrapper { - padding: var(--sp-tight); - } - .auth-card { - &__content { - padding: var(--sp-loose) var(--sp-normal); - } - } -} - -.process-wrapper { - @extend .cp-fx__column--c-c; - - min-height: 100%; - width: 100%; - background-color: var(--bg-surface-low); - opacity: .96; - - position: fixed; - top: 0; - left: 0; - z-index: 999; -} \ No newline at end of file diff --git a/src/app/templates/client/Client.jsx b/src/app/templates/client/Client.jsx deleted file mode 100644 index f6ef2b9e1..000000000 --- a/src/app/templates/client/Client.jsx +++ /dev/null @@ -1,68 +0,0 @@ -import React, { useEffect, useRef } from 'react'; -import './Client.scss'; - -import ReusableContextMenu from '../../atoms/context-menu/ReusableContextMenu'; -import Windows from '../../organisms/pw/Windows'; -import Dialogs from '../../organisms/pw/Dialogs'; - -import navigation from '../../../client/state/navigation'; -import cons from '../../../client/state/cons'; - -import { ClientContent } from './ClientContent'; -import { useSetting } from '../../state/hooks/settings'; -import { settingsAtom } from '../../state/settings'; - -function SystemEmojiFeature() { - const [twitterEmoji] = useSetting(settingsAtom, 'twitterEmoji'); - - if (twitterEmoji) { - document.documentElement.style.setProperty('--font-emoji', 'Twemoji'); - } else { - document.documentElement.style.setProperty('--font-emoji', 'Twemoji_DISABLED'); - } - - return null; -} - -function Client() { - const classNameHidden = 'client__item-hidden'; - - const navWrapperRef = useRef(null); - const roomWrapperRef = useRef(null); - - function onRoomSelected() { - navWrapperRef.current?.classList.add(classNameHidden); - roomWrapperRef.current?.classList.remove(classNameHidden); - } - function onNavigationSelected() { - navWrapperRef.current?.classList.remove(classNameHidden); - roomWrapperRef.current?.classList.add(classNameHidden); - } - - useEffect(() => { - navigation.on(cons.events.navigation.ROOM_SELECTED, onRoomSelected); - navigation.on(cons.events.navigation.NAVIGATION_OPENED, onNavigationSelected); - - return () => { - navigation.removeListener(cons.events.navigation.ROOM_SELECTED, onRoomSelected); - navigation.removeListener(cons.events.navigation.NAVIGATION_OPENED, onNavigationSelected); - }; - }, []); - - return ( -
      - {/*
      - -
      */} -
      - -
      - - - - -
      - ); -} - -export default Client; diff --git a/src/app/templates/client/Client.scss b/src/app/templates/client/Client.scss deleted file mode 100644 index bad5fc93b..000000000 --- a/src/app/templates/client/Client.scss +++ /dev/null @@ -1,57 +0,0 @@ -@use '../../partials/screen'; - -.client-container { - display: flex; - height: 100%; - flex-grow: 1; -} - -.navigation__wrapper { - width: var(--navigation-width); - - @include screen.smallerThan(mobileBreakpoint) { - width: 100%; - } -} - -.room__wrapper { - flex: 1; - min-width: 0; -} - -@include screen.smallerThan(mobileBreakpoint) { - .client__item-hidden { - display: none; - } -} - -.loading-display { - position: absolute; - top: 0; - left: 0; - width: 100vw; - height: 100%; - - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; -} -.loading__message { - margin-top: var(--sp-normal); - max-width: 350px; - text-align: center; -} -.loading__appname { - position: absolute; - bottom: var(--sp-normal); -} -.loading__menu { - position: absolute; - top: var(--sp-extra-tight); - right: var(--sp-extra-tight); - cursor: pointer; - .context-menu__item .text { - margin: 0 !important; - } -} diff --git a/src/app/templates/client/ClientContent.jsx b/src/app/templates/client/ClientContent.jsx deleted file mode 100644 index cebe012c2..000000000 --- a/src/app/templates/client/ClientContent.jsx +++ /dev/null @@ -1,49 +0,0 @@ -import React, { useState, useEffect } from 'react'; - -import initMatrix from '../../../client/initMatrix'; -import cons from '../../../client/state/cons'; -import navigation from '../../../client/state/navigation'; -import { openNavigation } from '../../../client/action/navigation'; - -import Welcome from '../../organisms/welcome/Welcome'; -import { RoomBaseView } from '../../features/room/Room'; - -export function ClientContent() { - const [roomInfo, setRoomInfo] = useState({ - room: null, - eventId: null, - }); - - const mx = initMatrix.matrixClient; - - useEffect(() => { - const handleRoomSelected = (rId, pRoomId, eId) => { - roomInfo.roomTimeline?.removeInternalListeners(); - const r = mx.getRoom(rId); - if (r) { - setRoomInfo({ - room: r, - eventId: eId ?? null, - }); - } else { - setRoomInfo({ - room: null, - eventId: null, - }); - } - }; - - navigation.on(cons.events.navigation.ROOM_SELECTED, handleRoomSelected); - return () => { - navigation.removeListener(cons.events.navigation.ROOM_SELECTED, handleRoomSelected); - }; - }, [roomInfo, mx]); - - const { room, eventId } = roomInfo; - if (!room) { - setTimeout(() => openNavigation()); - return ; - } - - return ; -} diff --git a/src/app/utils/disposable.ts b/src/app/utils/disposable.ts index 7840fe494..744241546 100644 --- a/src/app/utils/disposable.ts +++ b/src/app/utils/disposable.ts @@ -1,8 +1,16 @@ -export type DisposeCallback = (...args: Q) => R; -export type DisposableContext

      = ( - ...args: P -) => DisposeCallback; +export type DisposeCallback = ( + ...args: DisposeArgs +) => DisposeReturn; +export type DisposableContext< + DisposableArgs extends unknown[] = [], + DisposeArgs extends unknown[] = [], + DisposeReturn = void +> = (...args: DisposableArgs) => DisposeCallback; -export const disposable =

      ( - context: DisposableContext +export const disposable = < + DisposableArgs extends unknown[], + DisposeArgs extends unknown[] = [], + DisposeReturn = void +>( + context: DisposableContext ) => context; diff --git a/src/app/utils/dom.ts b/src/app/utils/dom.ts index f39fe623a..1aea6754c 100644 --- a/src/app/utils/dom.ts +++ b/src/app/utils/dom.ts @@ -190,3 +190,9 @@ export const copyToClipboard = (text: string) => { copyInput.remove(); } }; + +export const setFavicon = (url: string): void => { + const favicon = document.querySelector('#favicon'); + if (!favicon) return; + favicon.setAttribute('href', url); +}; diff --git a/src/client/action/accountData.js b/src/client/action/accountData.js deleted file mode 100644 index 1fb49fbfe..000000000 --- a/src/client/action/accountData.js +++ /dev/null @@ -1,41 +0,0 @@ -import appDispatcher from '../dispatcher'; -import cons from '../state/cons'; - -/** - * @param {string | string[]} roomId - room id or array of them to add into shortcuts - */ -export function createSpaceShortcut(roomId) { - appDispatcher.dispatch({ - type: cons.actions.accountData.CREATE_SPACE_SHORTCUT, - roomId, - }); -} - -export function deleteSpaceShortcut(roomId) { - appDispatcher.dispatch({ - type: cons.actions.accountData.DELETE_SPACE_SHORTCUT, - roomId, - }); -} - -export function moveSpaceShortcut(roomId, toIndex) { - appDispatcher.dispatch({ - type: cons.actions.accountData.MOVE_SPACE_SHORTCUTS, - roomId, - toIndex, - }); -} - -export function categorizeSpace(roomId) { - appDispatcher.dispatch({ - type: cons.actions.accountData.CATEGORIZE_SPACE, - roomId, - }); -} - -export function unCategorizeSpace(roomId) { - appDispatcher.dispatch({ - type: cons.actions.accountData.UNCATEGORIZE_SPACE, - roomId, - }); -} diff --git a/src/client/action/auth.js b/src/client/action/auth.js deleted file mode 100644 index f04306b8f..000000000 --- a/src/client/action/auth.js +++ /dev/null @@ -1,104 +0,0 @@ -import * as sdk from 'matrix-js-sdk'; -import cons from '../state/cons'; - -function updateLocalStore(accessToken, deviceId, userId, baseUrl) { - localStorage.setItem(cons.secretKey.ACCESS_TOKEN, accessToken); - localStorage.setItem(cons.secretKey.DEVICE_ID, deviceId); - localStorage.setItem(cons.secretKey.USER_ID, userId); - localStorage.setItem(cons.secretKey.BASE_URL, baseUrl); -} - -function createTemporaryClient(baseUrl) { - return sdk.createClient({ baseUrl }); -} - -async function startSsoLogin(baseUrl, type, idpId) { - const client = createTemporaryClient(baseUrl); - localStorage.setItem(cons.secretKey.BASE_URL, client.baseUrl); - window.location.href = client.getSsoLoginUrl(window.location.href, type, idpId); -} - -async function login(baseUrl, username, email, password) { - const identifier = {}; - if (username) { - identifier.type = 'm.id.user'; - identifier.user = username; - } else if (email) { - identifier.type = 'm.id.thirdparty'; - identifier.medium = 'email'; - identifier.address = email; - } else throw new Error('Bad Input'); - - const client = createTemporaryClient(baseUrl); - const res = await client.login('m.login.password', { - identifier, - password, - initial_device_display_name: cons.DEVICE_DISPLAY_NAME, - }); - - const myBaseUrl = res?.well_known?.['m.homeserver']?.base_url || client.baseUrl; - updateLocalStore(res.access_token, res.device_id, res.user_id, myBaseUrl); -} - -async function loginWithToken(baseUrl, token) { - const client = createTemporaryClient(baseUrl); - - const res = await client.login('m.login.token', { - token, - initial_device_display_name: cons.DEVICE_DISPLAY_NAME, - }); - - const myBaseUrl = res?.well_known?.['m.homeserver']?.base_url || client.baseUrl; - updateLocalStore(res.access_token, res.device_id, res.user_id, myBaseUrl); -} - -// eslint-disable-next-line camelcase -async function verifyEmail(baseUrl, email, client_secret, send_attempt, next_link) { - const res = await fetch(`${baseUrl}/_matrix/client/r0/register/email/requestToken`, { - method: 'POST', - body: JSON.stringify({ - email, client_secret, send_attempt, next_link, - }), - headers: { - 'Content-Type': 'application/json; charset=utf-8', - }, - credentials: 'same-origin', - }); - const data = await res.json(); - return data; -} - -async function completeRegisterStage( - baseUrl, username, password, auth, -) { - const tempClient = createTemporaryClient(baseUrl); - - try { - const result = await tempClient.registerRequest({ - username, - password, - auth, - initial_device_display_name: cons.DEVICE_DISPLAY_NAME, - }); - const data = { completed: result.completed || [] }; - if (result.access_token) { - data.done = true; - updateLocalStore(result.access_token, result.device_id, result.user_id, baseUrl); - } - return data; - } catch (e) { - const result = e.data; - const data = { completed: result.completed || [] }; - if (result.access_token) { - data.done = true; - updateLocalStore(result.access_token, result.device_id, result.user_id, baseUrl); - } - return data; - } -} - -export { - updateLocalStore, createTemporaryClient, login, verifyEmail, - loginWithToken, startSsoLogin, - completeRegisterStage, -}; diff --git a/src/client/action/auth.ts b/src/client/action/auth.ts new file mode 100644 index 000000000..dbe9baac5 --- /dev/null +++ b/src/client/action/auth.ts @@ -0,0 +1,13 @@ +import cons from '../state/cons'; + +export function updateLocalStore( + accessToken: string, + deviceId: string, + userId: string, + baseUrl: string +) { + localStorage.setItem(cons.secretKey.ACCESS_TOKEN, accessToken); + localStorage.setItem(cons.secretKey.DEVICE_ID, deviceId); + localStorage.setItem(cons.secretKey.USER_ID, userId); + localStorage.setItem(cons.secretKey.BASE_URL, baseUrl); +} diff --git a/src/client/action/navigation.js b/src/client/action/navigation.js index e48e839b3..1967a463b 100644 --- a/src/client/action/navigation.js +++ b/src/client/action/navigation.js @@ -1,35 +1,6 @@ import appDispatcher from '../dispatcher'; import cons from '../state/cons'; -export function selectTab(tabId) { - appDispatcher.dispatch({ - type: cons.actions.navigation.SELECT_TAB, - tabId, - }); -} - -export function selectSpace(roomId) { - appDispatcher.dispatch({ - type: cons.actions.navigation.SELECT_SPACE, - roomId, - }); -} - -export function selectRoom(roomId, eventId) { - appDispatcher.dispatch({ - type: cons.actions.navigation.SELECT_ROOM, - roomId, - eventId, - }); -} - -// Open navigation on compact screen sizes -export function openNavigation() { - appDispatcher.dispatch({ - type: cons.actions.navigation.OPEN_NAVIGATION, - }); -} - export function openSpaceSettings(roomId, tabText) { appDispatcher.dispatch({ type: cons.actions.navigation.OPEN_SPACE_SETTINGS, @@ -38,13 +9,6 @@ export function openSpaceSettings(roomId, tabText) { }); } -export function openSpaceManage(roomId) { - appDispatcher.dispatch({ - type: cons.actions.navigation.OPEN_SPACE_MANAGE, - roomId, - }); -} - export function openSpaceAddExisting(roomId, spaces = false) { appDispatcher.dispatch({ type: cons.actions.navigation.OPEN_SPACE_ADDEXISTING, @@ -61,24 +25,6 @@ export function toggleRoomSettings(roomId, tabText) { }); } -export function openShortcutSpaces() { - appDispatcher.dispatch({ - type: cons.actions.navigation.OPEN_SHORTCUT_SPACES, - }); -} - -export function openInviteList() { - appDispatcher.dispatch({ - type: cons.actions.navigation.OPEN_INVITE_LIST, - }); -} - -export function openPublicRooms(searchTerm) { - appDispatcher.dispatch({ - type: cons.actions.navigation.OPEN_PUBLIC_ROOMS, - searchTerm, - }); -} export function openCreateRoom(isSpace = false, parentId = null) { appDispatcher.dispatch({ @@ -118,39 +64,6 @@ export function openSettings(tabText) { }); } -export function openEmojiBoard(cords, requestEmojiCallback) { - appDispatcher.dispatch({ - type: cons.actions.navigation.OPEN_EMOJIBOARD, - cords, - requestEmojiCallback, - }); -} - -export function openReadReceipts(roomId, userIds) { - appDispatcher.dispatch({ - type: cons.actions.navigation.OPEN_READRECEIPTS, - roomId, - userIds, - }); -} - -export function openViewSource(event) { - appDispatcher.dispatch({ - type: cons.actions.navigation.OPEN_VIEWSOURCE, - event, - }); -} - -export function replyTo(userId, eventId, body, formattedBody) { - appDispatcher.dispatch({ - type: cons.actions.navigation.CLICK_REPLY_TO, - userId, - eventId, - body, - formattedBody, - }); -} - export function openSearch(term) { appDispatcher.dispatch({ type: cons.actions.navigation.OPEN_SEARCH, diff --git a/src/client/action/notifications.js b/src/client/action/notifications.js index a869632a8..579c7c3cb 100644 --- a/src/client/action/notifications.js +++ b/src/client/action/notifications.js @@ -5,7 +5,6 @@ export async function markAsRead(roomId) { const mx = initMatrix.matrixClient; const room = mx.getRoom(roomId); if (!room) return; - initMatrix.notifications.deleteNoti(roomId); const timeline = room.getLiveTimeline().getEvents(); const readEventId = room.getEventReadUpTo(mx.getUserId()); diff --git a/src/client/action/room.js b/src/client/action/room.js index 996c26802..c2d114388 100644 --- a/src/client/action/room.js +++ b/src/client/action/room.js @@ -107,37 +107,12 @@ async function join(roomIdOrAlias, isDM = false, via = undefined) { const targetUserId = guessDMRoomTargetId(mx.getRoom(resultRoom.roomId), mx.getUserId()); await addRoomToMDirect(resultRoom.roomId, targetUserId); } - appDispatcher.dispatch({ - type: cons.actions.room.JOIN, - roomId: resultRoom.roomId, - isDM, - }); return resultRoom.roomId; } catch (e) { throw new Error(e); } } -/** - * - * @param {string} roomId - * @param {boolean} isDM - */ -async function leave(roomId) { - const mx = initMatrix.matrixClient; - const isDM = initMatrix.roomList.directs.has(roomId); - try { - await mx.leave(roomId); - appDispatcher.dispatch({ - type: cons.actions.room.LEAVE, - roomId, - isDM, - }); - } catch { - console.error('Unable to leave room.'); - } -} - async function create(options, isDM = false) { const mx = initMatrix.matrixClient; try { @@ -145,11 +120,6 @@ async function create(options, isDM = false) { if (isDM && typeof options.invite?.[0] === 'string') { await addRoomToMDirect(result.room_id, options.invite[0]); } - appDispatcher.dispatch({ - type: cons.actions.room.CREATE, - roomId: result.room_id, - isDM, - }); return result; } catch (e) { const errcodes = ['M_UNKNOWN', 'M_BAD_JSON', 'M_ROOM_IN_USE', 'M_INVALID_ROOM_STATE', 'M_UNSUPPORTED_ROOM_VERSION']; @@ -348,7 +318,7 @@ async function setMyRoomAvatar(roomId, mxc) { export { convertToDm, convertToRoom, - join, leave, + join, createDM, createRoom, invite, kick, ban, unban, ignore, unignore, diff --git a/src/client/action/roomTimeline.js b/src/client/action/roomTimeline.js deleted file mode 100644 index 41c62d4f9..000000000 --- a/src/client/action/roomTimeline.js +++ /dev/null @@ -1,34 +0,0 @@ -import initMatrix from '../initMatrix'; - -async function redactEvent(roomId, eventId, reason) { - const mx = initMatrix.matrixClient; - - try { - await mx.redactEvent(roomId, eventId, undefined, typeof reason === 'undefined' ? undefined : { reason }); - return true; - } catch (e) { - throw new Error(e); - } -} - -async function sendReaction(roomId, toEventId, reaction, shortcode) { - const mx = initMatrix.matrixClient; - const content = { - 'm.relates_to': { - event_id: toEventId, - key: reaction, - rel_type: 'm.annotation', - }, - }; - if (typeof shortcode === 'string') content.shortcode = shortcode; - try { - await mx.sendEvent(roomId, 'm.reaction', content); - } catch (e) { - throw new Error(e); - } -} - -export { - redactEvent, - sendReaction, -}; diff --git a/src/client/event/hotkeys.js b/src/client/event/hotkeys.js index 076d37941..856fcadc4 100644 --- a/src/client/event/hotkeys.js +++ b/src/client/event/hotkeys.js @@ -1,31 +1,5 @@ import { openSearch } from '../action/navigation'; import navigation from '../state/navigation'; -import { markAsRead } from '../action/notifications'; - -function shouldFocusMessageField(code) { - // do not focus on F keys - if (/^F\d+$/.test(code)) return false; - - // do not focus on numlock/scroll lock - if ( - code.metaKey - || code.startsWith('OS') - || code.startsWith('Meta') - || code.startsWith('Shift') - || code.startsWith('Alt') - || code.startsWith('Control') - || code.startsWith('Arrow') - || code === 'Tab' - || code === 'Space' - || code === 'Enter' - || code === 'NumLock' - || code === 'ScrollLock' - ) { - return false; - } - - return true; -} function listenKeyboard(event) { // Ctrl/Cmd + @@ -36,39 +10,6 @@ function listenKeyboard(event) { if (navigation.isRawModalVisible) return; openSearch(); } - - // focus message field on paste - if (event.key === 'v') { - if (navigation.isRawModalVisible) return; - const msgTextarea = document.getElementById('message-textarea'); - const { activeElement } = document; - if (activeElement !== msgTextarea - && ['input', 'textarea'].includes(activeElement.tagName.toLowerCase()) - ) return; - msgTextarea?.focus(); - } - } - - if (!event.ctrlKey && !event.altKey && !event.metaKey) { - if (navigation.isRawModalVisible) return; - - if (event.key === 'Escape') { - if (navigation.selectedRoomId) { - markAsRead(navigation.selectedRoomId); - return; - } - } - - if (['input', 'textarea'].includes(document.activeElement.tagName.toLowerCase())) { - return; - } - - // focus the text field on most keypresses - if (shouldFocusMessageField(event.code)) { - // press any key to focus and type in message field - const msgTextarea = document.getElementById('message-textarea'); - msgTextarea?.focus(); - } } } diff --git a/src/client/event/roomList.js b/src/client/event/roomList.js deleted file mode 100644 index 6592d67f5..000000000 --- a/src/client/event/roomList.js +++ /dev/null @@ -1,38 +0,0 @@ -import cons from '../state/cons'; -import navigation from '../state/navigation'; -import { selectTab, selectSpace, selectRoom } from '../action/navigation'; - -function initRoomListListener(roomList) { - const listenRoomLeave = (roomId) => { - const parents = roomList.roomIdToParents.get(roomId); - - if (parents) { - [...parents].forEach((pId) => { - const data = navigation.spaceToRoom.get(pId); - if (data?.roomId === roomId) { - navigation.spaceToRoom.delete(pId); - } - }); - } - - if (navigation.selectedRoomId === roomId) { - selectRoom(null); - } - - if (navigation.selectedSpacePath.includes(roomId)) { - const idIndex = navigation.selectedSpacePath.indexOf(roomId); - if (idIndex === 0) selectTab(cons.tabs.HOME); - else selectSpace(navigation.selectedSpacePath[idIndex - 1]); - } - - navigation.removeRecentRoom(roomId); - }; - - roomList.on(cons.events.roomList.ROOM_LEAVED, listenRoomLeave); - return () => { - roomList.removeListener(cons.events.roomList.ROOM_LEAVED, listenRoomLeave); - }; -} - -// eslint-disable-next-line import/prefer-default-export -export { initRoomListListener }; diff --git a/src/client/initMatrix.js b/src/client/initMatrix.js index 835982f81..0352ff363 100644 --- a/src/client/initMatrix.js +++ b/src/client/initMatrix.js @@ -4,12 +4,7 @@ import Olm from '@matrix-org/olm'; import { logger } from 'matrix-js-sdk/lib/logger'; import { getSecret } from './state/auth'; -import RoomList from './state/RoomList'; -import AccountData from './state/AccountData'; -import RoomsInput from './state/RoomsInput'; -import Notifications from './state/Notifications'; import { cryptoCallbacks } from './state/secretStorageKeys'; -import navigation from './state/navigation'; global.Olm = Olm; @@ -18,12 +13,6 @@ if (import.meta.env.PROD) { } class InitMatrix extends EventEmitter { - constructor() { - super(); - - navigation.initMatrix = this; - } - async init() { if (this.matrixClient || this.initializing) { console.warn('Client is already initialized!') @@ -84,17 +73,9 @@ class InitMatrix extends EventEmitter { PREPARED: (prevState) => { console.log('PREPARED state'); console.log('Previous state: ', prevState); - // TODO: remove global.initMatrix at end global.initMatrix = this; if (prevState === null) { - this.roomList = new RoomList(this.matrixClient); - this.accountData = new AccountData(this.roomList); - this.roomsInput = new RoomsInput(this.matrixClient, this.roomList); - this.notifications = new Notifications(this.roomList); this.emit('init_loading_finished'); - this.notifications._initNoti(); - } else { - this.notifications?._initNoti(); } }, RECONNECTING: () => { diff --git a/src/client/state/AccountData.js b/src/client/state/AccountData.js deleted file mode 100644 index 6fc811a39..000000000 --- a/src/client/state/AccountData.js +++ /dev/null @@ -1,144 +0,0 @@ -import EventEmitter from 'events'; -import appDispatcher from '../dispatcher'; -import cons from './cons'; - -class AccountData extends EventEmitter { - constructor(roomList) { - super(); - - this.matrixClient = roomList.matrixClient; - this.roomList = roomList; - this.spaces = roomList.spaces; - - this.spaceShortcut = new Set(); - this._populateSpaceShortcut(); - - this.categorizedSpaces = new Set(); - this._populateCategorizedSpaces(); - - this._listenEvents(); - - appDispatcher.register(this.accountActions.bind(this)); - } - - _getAccountData() { - return this.matrixClient.getAccountData(cons.IN_CINNY_SPACES)?.getContent() || {}; - } - - _populateSpaceShortcut() { - this.spaceShortcut.clear(); - const spacesContent = this._getAccountData(); - - if (spacesContent?.shortcut === undefined) return; - - spacesContent.shortcut.forEach((shortcut) => { - if (this.spaces.has(shortcut)) this.spaceShortcut.add(shortcut); - }); - if (spacesContent.shortcut.length !== this.spaceShortcut.size) { - // update shortcut list from account data if shortcut space doesn't exist. - // TODO: we can wait for sync to complete or else we may end up removing valid space id - this._updateSpaceShortcutData([...this.spaceShortcut]); - } - } - - _updateSpaceShortcutData(shortcutList) { - const spaceContent = this._getAccountData(); - spaceContent.shortcut = shortcutList; - this.matrixClient.setAccountData(cons.IN_CINNY_SPACES, spaceContent); - } - - _populateCategorizedSpaces() { - this.categorizedSpaces.clear(); - const spaceContent = this._getAccountData(); - - if (spaceContent?.categorized === undefined) return; - - spaceContent.categorized.forEach((spaceId) => { - if (this.spaces.has(spaceId)) this.categorizedSpaces.add(spaceId); - }); - if (spaceContent.categorized.length !== this.categorizedSpaces.size) { - // TODO: we can wait for sync to complete or else we may end up removing valid space id - this._updateCategorizedSpacesData([...this.categorizedSpaces]); - } - } - - _updateCategorizedSpacesData(categorizedSpaceList) { - const spaceContent = this._getAccountData(); - spaceContent.categorized = categorizedSpaceList; - this.matrixClient.setAccountData(cons.IN_CINNY_SPACES, spaceContent); - } - - accountActions(action) { - const actions = { - [cons.actions.accountData.CREATE_SPACE_SHORTCUT]: () => { - const addRoomId = (id) => { - if (this.spaceShortcut.has(id)) return; - this.spaceShortcut.add(id); - }; - if (Array.isArray(action.roomId)) { - action.roomId.forEach(addRoomId); - } else { - addRoomId(action.roomId); - } - this._updateSpaceShortcutData([...this.spaceShortcut]); - this.emit(cons.events.accountData.SPACE_SHORTCUT_UPDATED, action.roomId); - }, - [cons.actions.accountData.DELETE_SPACE_SHORTCUT]: () => { - if (!this.spaceShortcut.has(action.roomId)) return; - this.spaceShortcut.delete(action.roomId); - this._updateSpaceShortcutData([...this.spaceShortcut]); - this.emit(cons.events.accountData.SPACE_SHORTCUT_UPDATED, action.roomId); - }, - [cons.actions.accountData.MOVE_SPACE_SHORTCUTS]: () => { - const { roomId, toIndex } = action; - if (!this.spaceShortcut.has(roomId)) return; - this.spaceShortcut.delete(roomId); - const ssList = [...this.spaceShortcut]; - if (toIndex >= ssList.length) ssList.push(roomId); - else ssList.splice(toIndex, 0, roomId); - this.spaceShortcut = new Set(ssList); - this._updateSpaceShortcutData(ssList); - this.emit(cons.events.accountData.SPACE_SHORTCUT_UPDATED, roomId); - }, - [cons.actions.accountData.CATEGORIZE_SPACE]: () => { - if (this.categorizedSpaces.has(action.roomId)) return; - this.categorizedSpaces.add(action.roomId); - this._updateCategorizedSpacesData([...this.categorizedSpaces]); - this.emit(cons.events.accountData.CATEGORIZE_SPACE_UPDATED, action.roomId); - }, - [cons.actions.accountData.UNCATEGORIZE_SPACE]: () => { - if (!this.categorizedSpaces.has(action.roomId)) return; - this.categorizedSpaces.delete(action.roomId); - this._updateCategorizedSpacesData([...this.categorizedSpaces]); - this.emit(cons.events.accountData.CATEGORIZE_SPACE_UPDATED, action.roomId); - }, - }; - actions[action.type]?.(); - } - - _listenEvents() { - this.matrixClient.on('accountData', (event) => { - if (event.getType() !== cons.IN_CINNY_SPACES) return; - this._populateSpaceShortcut(); - this.emit(cons.events.accountData.SPACE_SHORTCUT_UPDATED); - this._populateCategorizedSpaces(); - this.emit(cons.events.accountData.CATEGORIZE_SPACE_UPDATED); - }); - - this.roomList.on(cons.events.roomList.ROOM_LEAVED, (roomId) => { - if (this.spaceShortcut.has(roomId)) { - // if deleted space has shortcut remove it. - this.spaceShortcut.delete(roomId); - this._updateSpaceShortcutData([...this.spaceShortcut]); - this.emit(cons.events.accountData.SPACE_SHORTCUT_UPDATED, roomId); - } - if (this.categorizedSpaces.has(roomId)) { - this.categorizedSpaces.delete(roomId); - this._updateCategorizedSpacesData([...this.categorizedSpaces]); - this.emit(cons.events.accountData.CATEGORIZE_SPACE_UPDATED, roomId); - } - }); - } -} - -export default AccountData; diff --git a/src/client/state/Notifications.js b/src/client/state/Notifications.js deleted file mode 100644 index 09fa240e7..000000000 --- a/src/client/state/Notifications.js +++ /dev/null @@ -1,412 +0,0 @@ -import EventEmitter from 'events'; -import renderAvatar from '../../app/atoms/avatar/render'; -import { cssColorMXID } from '../../util/colorMXID'; -import { selectRoom } from '../action/navigation'; -import cons from './cons'; -import navigation from './navigation'; -import settings from './settings'; -import { setFavicon } from '../../util/common'; - -import LogoSVG from '../../../public/res/svg/cinny.svg'; -import LogoUnreadSVG from '../../../public/res/svg/cinny-unread.svg'; -import LogoHighlightSVG from '../../../public/res/svg/cinny-highlight.svg'; -import { html, plain } from '../../util/markdown'; - -function isNotifEvent(mEvent) { - const eType = mEvent.getType(); - if (!cons.supportEventTypes.includes(eType)) return false; - if (eType === 'm.room.member') return false; - - if (mEvent.isRedacted()) return false; - if (mEvent.getRelation()?.rel_type === 'm.replace') return false; - - return true; -} - -function isMutedRule(rule) { - return rule.actions[0] === 'dont_notify' && rule.conditions[0].kind === 'event_match'; -} - -function findMutedRule(overrideRules, roomId) { - return overrideRules.find((rule) => ( - rule.rule_id === roomId - && isMutedRule(rule) - )); -} - -class Notifications extends EventEmitter { - constructor(roomList) { - super(); - - this.initialized = false; - this.favicon = LogoSVG; - this.matrixClient = roomList.matrixClient; - this.roomList = roomList; - - this.roomIdToNoti = new Map(); - this.roomIdToPopupNotis = new Map(); - this.eventIdToPopupNoti = new Map(); - - // this._initNoti(); - this._listenEvents(); - - // Ask for permission by default after loading - window.Notification?.requestPermission(); - } - - async _initNoti() { - this.initialized = false; - this.roomIdToNoti = new Map(); - - const addNoti = (roomId) => { - const room = this.matrixClient.getRoom(roomId); - if (this.getNotiType(room.roomId) === cons.notifs.MUTE) return; - if (this.doesRoomHaveUnread(room) === false) return; - - const total = room.getUnreadNotificationCount('total'); - const highlight = room.getUnreadNotificationCount('highlight'); - this._setNoti(room.roomId, total ?? 0, highlight ?? 0); - }; - [...this.roomList.rooms].forEach(addNoti); - [...this.roomList.directs].forEach(addNoti); - - this.initialized = true; - this._updateFavicon(); - } - - doesRoomHaveUnread(room) { - const userId = this.matrixClient.getUserId(); - const readUpToId = room.getEventReadUpTo(userId); - const liveEvents = room.getLiveTimeline().getEvents(); - - if (liveEvents[liveEvents.length - 1]?.getSender() === userId) { - return false; - } - - for (let i = liveEvents.length - 1; i >= 0; i -= 1) { - const event = liveEvents[i]; - if (event.getId() === readUpToId) return false; - if (isNotifEvent(event)) return true; - } - return true; - } - - getNotiType(roomId) { - const mx = this.matrixClient; - let pushRule; - try { - pushRule = mx.getRoomPushRule('global', roomId); - } catch { - pushRule = undefined; - } - - if (pushRule === undefined) { - const overrideRules = mx.getAccountData('m.push_rules')?.getContent()?.global?.override; - if (overrideRules === undefined) return cons.notifs.DEFAULT; - - const isMuted = findMutedRule(overrideRules, roomId); - - return isMuted ? cons.notifs.MUTE : cons.notifs.DEFAULT; - } - if (pushRule.actions[0] === 'notify') return cons.notifs.ALL_MESSAGES; - return cons.notifs.MENTIONS_AND_KEYWORDS; - } - - getNoti(roomId) { - return this.roomIdToNoti.get(roomId) || { total: 0, highlight: 0, from: null }; - } - - getTotalNoti(roomId) { - const { total } = this.getNoti(roomId); - return total; - } - - getHighlightNoti(roomId) { - const { highlight } = this.getNoti(roomId); - return highlight; - } - - getFromNoti(roomId) { - const { from } = this.getNoti(roomId); - return from; - } - - hasNoti(roomId) { - return this.roomIdToNoti.has(roomId); - } - - deleteNoti(roomId) { - if (this.hasNoti(roomId)) { - const noti = this.getNoti(roomId); - this._deleteNoti(roomId, noti.total, noti.highlight); - } - } - - async _updateFavicon() { - if (!this.initialized) return; - let unread = false; - let highlight = false; - [...this.roomIdToNoti.values()].find((noti) => { - if (!unread) { - unread = noti.total > 0 || noti.highlight > 0; - } - highlight = noti.highlight > 0; - if (unread && highlight) return true; - return false; - }); - let newFavicon = LogoSVG; - if (unread && !highlight) { - newFavicon = LogoUnreadSVG; - } - if (unread && highlight) { - newFavicon = LogoHighlightSVG; - } - if (newFavicon === this.favicon) return; - this.favicon = newFavicon; - setFavicon(this.favicon); - } - - _setNoti(roomId, total, highlight) { - const addNoti = (id, t, h, fromId) => { - const prevTotal = this.roomIdToNoti.get(id)?.total ?? null; - const noti = this.getNoti(id); - - noti.total += t; - noti.highlight += h; - - if (fromId) { - if (noti.from === null) noti.from = new Set(); - noti.from.add(fromId); - } - this.roomIdToNoti.set(id, noti); - this.emit(cons.events.notifications.NOTI_CHANGED, id, noti.total, prevTotal); - }; - - const noti = this.getNoti(roomId); - const addT = (highlight > total ? highlight : total) - noti.total; - const addH = highlight - noti.highlight; - if (addT < 0 || addH < 0) return; - - addNoti(roomId, addT, addH); - const allParentSpaces = this.roomList.getAllParentSpaces(roomId); - allParentSpaces.forEach((spaceId) => { - addNoti(spaceId, addT, addH, roomId); - }); - this._updateFavicon(); - } - - _deleteNoti(roomId, total, highlight) { - const removeNoti = (id, t, h, fromId) => { - if (this.roomIdToNoti.has(id) === false) return; - - const noti = this.getNoti(id); - const prevTotal = noti.total; - noti.total -= t; - noti.highlight -= h; - if (noti.total < 0) { - noti.total = 0; - noti.highlight = 0; - } - if (fromId && noti.from !== null) { - if (!this.hasNoti(fromId)) noti.from.delete(fromId); - } - if (noti.from === null || noti.from.size === 0) { - this.roomIdToNoti.delete(id); - this.emit(cons.events.notifications.FULL_READ, id); - this.emit(cons.events.notifications.NOTI_CHANGED, id, null, prevTotal); - } else { - this.roomIdToNoti.set(id, noti); - this.emit(cons.events.notifications.NOTI_CHANGED, id, noti.total, prevTotal); - } - }; - - removeNoti(roomId, total, highlight); - const allParentSpaces = this.roomList.getAllParentSpaces(roomId); - allParentSpaces.forEach((spaceId) => { - removeNoti(spaceId, total, highlight, roomId); - }); - this._updateFavicon(); - } - - async _displayPopupNoti(mEvent, room) { - if (!settings.showNotifications && !settings.isNotificationSounds) return; - - const actions = this.matrixClient.getPushActionsForEvent(mEvent); - if (!actions?.notify) return; - - if (navigation.selectedRoomId === room.roomId && document.hasFocus()) return; - - if (mEvent.isEncrypted()) { - await mEvent.attemptDecryption(this.matrixClient.crypto); - } - - if (settings.showNotifications) { - let title; - if (!mEvent.sender || room.name === mEvent.sender.name) { - title = room.name; - } else if (mEvent.sender) { - title = `${mEvent.sender.name} (${room.name})`; - } - - const iconSize = 36; - const icon = await renderAvatar({ - text: mEvent.sender.name, - bgColor: cssColorMXID(mEvent.getSender()), - imageSrc: mEvent.sender?.getAvatarUrl(this.matrixClient.baseUrl, iconSize, iconSize, 'crop'), - size: iconSize, - borderRadius: 8, - scale: 8, - }); - - const content = mEvent.getContent(); - - const state = { kind: 'notification', onlyPlain: true }; - let body; - if (content.format === 'org.matrix.custom.html') { - body = html(content.formatted_body, state); - } else { - body = plain(content.body, state); - } - - const noti = new window.Notification(title, { - body: body.plain, - icon, - tag: mEvent.getId(), - silent: settings.isNotificationSounds, - }); - if (settings.isNotificationSounds) { - noti.onshow = () => this._playNotiSound(); - } - noti.onclick = () => selectRoom(room.roomId, mEvent.getId()); - - this.eventIdToPopupNoti.set(mEvent.getId(), noti); - if (this.roomIdToPopupNotis.has(room.roomId)) { - this.roomIdToPopupNotis.get(room.roomId).push(noti); - } else { - this.roomIdToPopupNotis.set(room.roomId, [noti]); - } - } else { - this._playNotiSound(); - } - } - - _deletePopupNoti(eventId) { - this.eventIdToPopupNoti.get(eventId)?.close(); - this.eventIdToPopupNoti.delete(eventId); - } - - _deletePopupRoomNotis(roomId) { - this.roomIdToPopupNotis.get(roomId)?.forEach((n) => { - this.eventIdToPopupNoti.delete(n.tag); - n.close(); - }); - this.roomIdToPopupNotis.delete(roomId); - } - - _playNotiSound() { - if (!this._notiAudio) { - this._notiAudio = document.getElementById('notificationSound'); - } - this._notiAudio.play(); - } - - _playInviteSound() { - if (!this._inviteAudio) { - this._inviteAudio = document.getElementById('inviteSound'); - } - this._inviteAudio.play(); - } - - _listenEvents() { - this.matrixClient.on('Room.timeline', (mEvent, room) => { - if (mEvent.isRedaction()) this._deletePopupNoti(mEvent.event.redacts); - - if (room.isSpaceRoom()) return; - if (!isNotifEvent(mEvent)) return; - - const liveEvents = room.getLiveTimeline().getEvents(); - - const lastTimelineEvent = liveEvents[liveEvents.length - 1]; - if (lastTimelineEvent.getId() !== mEvent.getId()) return; - if (mEvent.getSender() === this.matrixClient.getUserId()) return; - - const total = room.getUnreadNotificationCount('total'); - const highlight = room.getUnreadNotificationCount('highlight'); - - if (this.getNotiType(room.roomId) === cons.notifs.MUTE) { - this.deleteNoti(room.roomId, total ?? 0, highlight ?? 0); - return; - } - - this._setNoti(room.roomId, total ?? 0, highlight ?? 0); - - if (this.matrixClient.getSyncState() === 'SYNCING') { - this._displayPopupNoti(mEvent, room); - } - }); - - this.matrixClient.on('accountData', (mEvent, oldMEvent) => { - if (mEvent.getType() === 'm.push_rules') { - const override = mEvent?.getContent()?.global?.override; - const oldOverride = oldMEvent?.getContent()?.global?.override; - if (!override || !oldOverride) return; - - const isMuteToggled = (rule, otherOverride) => { - const roomId = rule.rule_id; - const room = this.matrixClient.getRoom(roomId); - if (room === null) return false; - if (room.isSpaceRoom()) return false; - - const isMuted = isMutedRule(rule); - if (!isMuted) return false; - const isOtherMuted = findMutedRule(otherOverride, roomId); - if (isOtherMuted) return false; - return true; - }; - - const mutedRules = override.filter((rule) => isMuteToggled(rule, oldOverride)); - const unMutedRules = oldOverride.filter((rule) => isMuteToggled(rule, override)); - - mutedRules.forEach((rule) => { - this.emit(cons.events.notifications.MUTE_TOGGLED, rule.rule_id, true); - this.deleteNoti(rule.rule_id); - }); - unMutedRules.forEach((rule) => { - this.emit(cons.events.notifications.MUTE_TOGGLED, rule.rule_id, false); - const room = this.matrixClient.getRoom(rule.rule_id); - if (!this.doesRoomHaveUnread(room)) return; - const total = room.getUnreadNotificationCount('total'); - const highlight = room.getUnreadNotificationCount('highlight'); - this._setNoti(room.roomId, total ?? 0, highlight ?? 0); - }); - } - }); - - this.matrixClient.on('Room.receipt', (mEvent, room) => { - if (mEvent.getType() !== 'm.receipt' || room.isSpaceRoom()) return; - const content = mEvent.getContent(); - const userId = this.matrixClient.getUserId(); - - Object.keys(content).forEach((eventId) => { - Object.entries(content[eventId]).forEach(([receiptType, receipt]) => { - if (!cons.supportReceiptTypes.includes(receiptType)) return; - if (Object.keys(receipt || {}).includes(userId)) { - this.deleteNoti(room.roomId); - this._deletePopupRoomNotis(room.roomId); - } - }); - }); - }); - - this.matrixClient.on('Room.myMembership', (room, membership) => { - if (membership === 'leave' && this.hasNoti(room.roomId)) { - this.deleteNoti(room.roomId); - } - if (membership === 'invite') { - this._playInviteSound(); - } - }); - } -} - -export default Notifications; diff --git a/src/client/state/RoomList.js b/src/client/state/RoomList.js deleted file mode 100644 index fc137ae26..000000000 --- a/src/client/state/RoomList.js +++ /dev/null @@ -1,383 +0,0 @@ -import EventEmitter from 'events'; -import appDispatcher from '../dispatcher'; -import cons from './cons'; - -function isMEventSpaceChild(mEvent) { - return mEvent.getType() === 'm.space.child' && Object.keys(mEvent.getContent()).length > 0; -} - -/** - * @param {() => boolean} callback if return true wait will over else callback will be called again. - * @param {number} timeout timeout to callback - * @param {number} maxTry maximum callback try > 0. -1 means no limit - */ -async function waitFor(callback, timeout = 400, maxTry = -1) { - if (maxTry === 0) return false; - const isOver = async () => new Promise((resolve) => { - setTimeout(() => resolve(callback()), timeout); - }); - - if (await isOver()) return true; - return waitFor(callback, timeout, maxTry - 1); -} - -class RoomList extends EventEmitter { - constructor(matrixClient) { - super(); - this.matrixClient = matrixClient; - this.mDirects = this.getMDirects(); - - // Contains roomId to parent spaces roomId mapping of all spaces children. - // No matter if you have joined those children rooms or not. - this.roomIdToParents = new Map(); - - this.inviteDirects = new Set(); - this.inviteSpaces = new Set(); - this.inviteRooms = new Set(); - - this.directs = new Set(); - this.spaces = new Set(); - this.rooms = new Set(); - - this.processingRooms = new Map(); - - this._populateRooms(); - this._listenEvents(); - - appDispatcher.register(this.roomActions.bind(this)); - } - - isOrphan(roomId) { - return !this.roomIdToParents.has(roomId); - } - - getOrphanSpaces() { - return [...this.spaces].filter((roomId) => !this.roomIdToParents.has(roomId)); - } - - getOrphanRooms() { - return [...this.rooms].filter((roomId) => !this.roomIdToParents.has(roomId)); - } - - getOrphans() { - const rooms = [...this.spaces].concat([...this.rooms]); - return rooms.filter((roomId) => !this.roomIdToParents.has(roomId)); - } - - getSpaceChildren(roomId) { - const space = this.matrixClient.getRoom(roomId); - if (space === null) return null; - const mSpaceChild = space?.currentState.getStateEvents('m.space.child'); - - const children = []; - mSpaceChild.forEach((mEvent) => { - const childId = mEvent.event.state_key; - if (isMEventSpaceChild(mEvent)) children.push(childId); - }); - return children; - } - - getCategorizedSpaces(spaceIds) { - const categorized = new Map(); - - const categorizeSpace = (spaceId) => { - if (categorized.has(spaceId)) return; - const mappedChild = new Set(); - categorized.set(spaceId, mappedChild); - - const child = this.getSpaceChildren(spaceId); - - child.forEach((childId) => { - const room = this.matrixClient.getRoom(childId); - if (room === null || room.getMyMembership() !== 'join') return; - if (room.isSpaceRoom()) categorizeSpace(childId); - else mappedChild.add(childId); - }); - }; - spaceIds.forEach(categorizeSpace); - - return categorized; - } - - addToRoomIdToParents(roomId, parentRoomId) { - if (!this.roomIdToParents.has(roomId)) { - this.roomIdToParents.set(roomId, new Set()); - } - const parents = this.roomIdToParents.get(roomId); - parents.add(parentRoomId); - } - - removeFromRoomIdToParents(roomId, parentRoomId) { - if (!this.roomIdToParents.has(roomId)) return; - const parents = this.roomIdToParents.get(roomId); - parents.delete(parentRoomId); - if (parents.size === 0) this.roomIdToParents.delete(roomId); - } - - getAllParentSpaces(roomId) { - const allParents = new Set(); - - const addAllParentIds = (rId) => { - if (allParents.has(rId)) return; - allParents.add(rId); - - const parents = this.roomIdToParents.get(rId); - if (parents === undefined) return; - - parents.forEach((id) => addAllParentIds(id)); - }; - addAllParentIds(roomId); - allParents.delete(roomId); - return allParents; - } - - addToSpaces(roomId) { - this.spaces.add(roomId); - - const allParentSpaces = this.getAllParentSpaces(roomId); - const spaceChildren = this.getSpaceChildren(roomId); - spaceChildren?.forEach((childId) => { - if (allParentSpaces.has(childId)) return; - this.addToRoomIdToParents(childId, roomId); - }); - } - - deleteFromSpaces(roomId) { - this.spaces.delete(roomId); - - const spaceChildren = this.getSpaceChildren(roomId); - spaceChildren?.forEach((childId) => { - this.removeFromRoomIdToParents(childId, roomId); - }); - } - - roomActions(action) { - const addRoom = (roomId, isDM) => { - const myRoom = this.matrixClient.getRoom(roomId); - if (myRoom === null) return false; - - if (isDM) this.directs.add(roomId); - else if (myRoom.isSpaceRoom()) this.addToSpaces(roomId); - else this.rooms.add(roomId); - return true; - }; - const actions = { - [cons.actions.room.JOIN]: () => { - if (addRoom(action.roomId, action.isDM)) { - setTimeout(() => { - this.emit(cons.events.roomList.ROOM_JOINED, action.roomId); - this.emit(cons.events.roomList.ROOMLIST_UPDATED); - }, 100); - } else { - this.processingRooms.set(action.roomId, { - roomId: action.roomId, - isDM: action.isDM, - task: 'JOIN', - }); - } - }, - [cons.actions.room.CREATE]: () => { - if (addRoom(action.roomId, action.isDM)) { - setTimeout(() => { - this.emit(cons.events.roomList.ROOM_CREATED, action.roomId); - this.emit(cons.events.roomList.ROOM_JOINED, action.roomId); - this.emit(cons.events.roomList.ROOMLIST_UPDATED); - }, 100); - } else { - this.processingRooms.set(action.roomId, { - roomId: action.roomId, - isDM: action.isDM, - task: 'CREATE', - }); - } - }, - }; - actions[action.type]?.(); - } - - getMDirects() { - const mDirectsId = new Set(); - const mDirect = this.matrixClient - .getAccountData('m.direct') - ?.getContent(); - - if (typeof mDirect === 'undefined') return mDirectsId; - - Object.keys(mDirect).forEach((direct) => { - mDirect[direct].forEach((directId) => mDirectsId.add(directId)); - }); - - return mDirectsId; - } - - _populateRooms() { - this.directs.clear(); - this.roomIdToParents.clear(); - this.spaces.clear(); - this.rooms.clear(); - this.inviteDirects.clear(); - this.inviteSpaces.clear(); - this.inviteRooms.clear(); - this.matrixClient.getRooms().forEach((room) => { - const { roomId } = room; - - if (room.getMyMembership() === 'invite') { - if (this._isDMInvite(room)) this.inviteDirects.add(roomId); - else if (room.isSpaceRoom()) this.inviteSpaces.add(roomId); - else this.inviteRooms.add(roomId); - return; - } - - if (room.getMyMembership() !== 'join') return; - - if (this.mDirects.has(roomId)) this.directs.add(roomId); - else if (room.isSpaceRoom()) this.addToSpaces(roomId); - else this.rooms.add(roomId); - }); - } - - _isDMInvite(room) { - if (this.mDirects.has(room.roomId)) return true; - const me = room.getMember(this.matrixClient.getUserId()); - const myEventContent = me.events.member.getContent(); - return myEventContent.membership === 'invite' && myEventContent.is_direct; - } - - _listenEvents() { - // Update roomList when m.direct changes - this.matrixClient.on('accountData', (event) => { - if (event.getType() !== 'm.direct') return; - - const latestMDirects = this.getMDirects(); - - latestMDirects.forEach((directId) => { - if (this.mDirects.has(directId)) return; - this.mDirects.add(directId); - - const myRoom = this.matrixClient.getRoom(directId); - if (myRoom === null) return; - if (myRoom.getMyMembership() === 'join') { - this.directs.add(directId); - this.rooms.delete(directId); - this.emit(cons.events.roomList.ROOMLIST_UPDATED); - } - }); - - [...this.directs].forEach((directId) => { - if (latestMDirects.has(directId)) return; - this.mDirects.delete(directId); - - const myRoom = this.matrixClient.getRoom(directId); - if (myRoom === null) return; - if (myRoom.getMyMembership() === 'join') { - this.directs.delete(directId); - this.rooms.add(directId); - this.emit(cons.events.roomList.ROOMLIST_UPDATED); - } - }); - }); - - this.matrixClient.on('Room.name', (room) => { - this.emit(cons.events.roomList.ROOMLIST_UPDATED); - this.emit(cons.events.roomList.ROOM_PROFILE_UPDATED, room.roomId); - }); - - this.matrixClient.on('RoomState.events', (mEvent, state) => { - if (mEvent.getType() === 'm.space.child') { - const roomId = mEvent.event.room_id; - const childId = mEvent.event.state_key; - if (isMEventSpaceChild(mEvent)) { - const allParentSpaces = this.getAllParentSpaces(roomId); - // only add if it doesn't make a cycle - if (!allParentSpaces.has(childId)) { - this.addToRoomIdToParents(childId, roomId); - } - } else { - this.removeFromRoomIdToParents(childId, roomId); - } - this.emit(cons.events.roomList.ROOMLIST_UPDATED); - return; - } - if (mEvent.getType() === 'm.room.join_rules') { - this.emit(cons.events.roomList.ROOMLIST_UPDATED); - return; - } - if (['m.room.avatar', 'm.room.topic'].includes(mEvent.getType())) { - if (mEvent.getType() === 'm.room.avatar') { - this.emit(cons.events.roomList.ROOMLIST_UPDATED); - } - this.emit(cons.events.roomList.ROOM_PROFILE_UPDATED, state.roomId); - } - }); - - this.matrixClient.on('Room.myMembership', async (room, membership, prevMembership) => { - // room => prevMembership = null | invite | join | leave | kick | ban | unban - // room => membership = invite | join | leave | kick | ban | unban - const { roomId } = room; - const isRoomReady = () => this.matrixClient.getRoom(roomId) !== null; - if (['join', 'invite'].includes(membership) && isRoomReady() === false) { - if (await waitFor(isRoomReady, 200, 100) === false) return; - } - - if (membership === 'unban') return; - - if (membership === 'invite') { - if (this._isDMInvite(room)) this.inviteDirects.add(roomId); - else if (room.isSpaceRoom()) this.inviteSpaces.add(roomId); - else this.inviteRooms.add(roomId); - - this.emit(cons.events.roomList.INVITELIST_UPDATED, roomId); - return; - } - - if (prevMembership === 'invite') { - if (this.inviteDirects.has(roomId)) this.inviteDirects.delete(roomId); - else if (this.inviteSpaces.has(roomId)) this.inviteSpaces.delete(roomId); - else this.inviteRooms.delete(roomId); - - this.emit(cons.events.roomList.INVITELIST_UPDATED, roomId); - } - - if (['leave', 'kick', 'ban'].includes(membership)) { - if (this.directs.has(roomId)) this.directs.delete(roomId); - else if (this.spaces.has(roomId)) this.deleteFromSpaces(roomId); - else this.rooms.delete(roomId); - this.emit(cons.events.roomList.ROOM_LEAVED, roomId); - this.emit(cons.events.roomList.ROOMLIST_UPDATED); - return; - } - - // when user create room/DM OR accept room/dm invite from this client. - // we will update this.rooms/this.directs with user action - if (membership === 'join' && this.processingRooms.has(roomId)) { - const procRoomInfo = this.processingRooms.get(roomId); - - if (procRoomInfo.isDM) this.directs.add(roomId); - else if (room.isSpaceRoom()) this.addToSpaces(roomId); - else this.rooms.add(roomId); - - if (procRoomInfo.task === 'CREATE') this.emit(cons.events.roomList.ROOM_CREATED, roomId); - this.emit(cons.events.roomList.ROOM_JOINED, roomId); - this.emit(cons.events.roomList.ROOMLIST_UPDATED); - - this.processingRooms.delete(roomId); - return; - } - - if (this.mDirects.has(roomId) && membership === 'join') { - this.directs.add(roomId); - this.emit(cons.events.roomList.ROOM_JOINED, roomId); - this.emit(cons.events.roomList.ROOMLIST_UPDATED); - return; - } - - if (membership === 'join') { - if (room.isSpaceRoom()) this.addToSpaces(roomId); - else this.rooms.add(roomId); - this.emit(cons.events.roomList.ROOM_JOINED, roomId); - this.emit(cons.events.roomList.ROOMLIST_UPDATED); - } - }); - } -} -export default RoomList; diff --git a/src/client/state/RoomTimeline.js b/src/client/state/RoomTimeline.js deleted file mode 100644 index 57d91c141..000000000 --- a/src/client/state/RoomTimeline.js +++ /dev/null @@ -1,407 +0,0 @@ -import EventEmitter from 'events'; -import initMatrix from '../initMatrix'; -import cons from './cons'; - -import settings from './settings'; - -function isEdited(mEvent) { - return mEvent.getRelation()?.rel_type === 'm.replace'; -} - -function isReaction(mEvent) { - return mEvent.getType() === 'm.reaction'; -} - -function hideMemberEvents(mEvent) { - const content = mEvent.getContent(); - const prevContent = mEvent.getPrevContent(); - const { membership } = content; - if (settings.hideMembershipEvents) { - if (membership === 'invite' || membership === 'ban' || membership === 'leave') return true; - if (prevContent.membership !== 'join') return true; - } - if (settings.hideNickAvatarEvents) { - if (membership === 'join' && prevContent.membership === 'join') return true; - } - return false; -} - -function getRelateToId(mEvent) { - const relation = mEvent.getRelation(); - return relation && relation.event_id; -} - -function addToMap(myMap, mEvent) { - const relateToId = getRelateToId(mEvent); - if (relateToId === null) return null; - const mEventId = mEvent.getId(); - - if (typeof myMap.get(relateToId) === 'undefined') myMap.set(relateToId, []); - const mEvents = myMap.get(relateToId); - if (mEvents.find((ev) => ev.getId() === mEventId)) return mEvent; - mEvents.push(mEvent); - return mEvent; -} - -function getFirstLinkedTimeline(timeline) { - let tm = timeline; - while (tm.prevTimeline) { - tm = tm.prevTimeline; - } - return tm; -} -function getLastLinkedTimeline(timeline) { - let tm = timeline; - while (tm.nextTimeline) { - tm = tm.nextTimeline; - } - return tm; -} - -function iterateLinkedTimelines(timeline, backwards, callback) { - let tm = timeline; - while (tm) { - callback(tm); - if (backwards) tm = tm.prevTimeline; - else tm = tm.nextTimeline; - } -} - -function isTimelineLinked(tm1, tm2) { - let tm = getFirstLinkedTimeline(tm1); - while (tm) { - if (tm === tm2) return true; - tm = tm.nextTimeline; - } - return false; -} - -class RoomTimeline extends EventEmitter { - constructor(roomId) { - super(); - // These are local timelines - this.timeline = []; - this.editedTimeline = new Map(); - this.reactionTimeline = new Map(); - this.typingMembers = new Set(); - - this.matrixClient = initMatrix.matrixClient; - this.roomId = roomId; - this.room = this.matrixClient.getRoom(roomId); - - this.liveTimeline = this.room.getLiveTimeline(); - this.activeTimeline = this.liveTimeline; - - this.isOngoingPagination = false; - this.ongoingDecryptionCount = 0; - this.initialized = false; - - setTimeout(() => this.room.loadMembersIfNeeded()); - - // TODO: remove below line - window.selectedRoom = this; - } - - isServingLiveTimeline() { - return getLastLinkedTimeline(this.activeTimeline) === this.liveTimeline; - } - - canPaginateBackward() { - if (this.timeline[0]?.getType() === 'm.room.create') return false; - const tm = getFirstLinkedTimeline(this.activeTimeline); - return tm.getPaginationToken('b') !== null; - } - - canPaginateForward() { - return !this.isServingLiveTimeline(); - } - - isEncrypted() { - return this.matrixClient.isRoomEncrypted(this.roomId); - } - - clearLocalTimelines() { - this.timeline = []; - } - - addToTimeline(mEvent) { - if (mEvent.getType() === 'm.room.member' && hideMemberEvents(mEvent)) { - return; - } - if (mEvent.isRedacted()) return; - if (isReaction(mEvent)) { - addToMap(this.reactionTimeline, mEvent); - return; - } - if (!cons.supportEventTypes.includes(mEvent.getType())) return; - if (isEdited(mEvent)) { - addToMap(this.editedTimeline, mEvent); - return; - } - this.timeline.push(mEvent); - } - - _populateAllLinkedEvents(timeline) { - const firstTimeline = getFirstLinkedTimeline(timeline); - iterateLinkedTimelines(firstTimeline, false, (tm) => { - tm.getEvents().forEach((mEvent) => this.addToTimeline(mEvent)); - }); - } - - _populateTimelines() { - this.clearLocalTimelines(); - this._populateAllLinkedEvents(this.activeTimeline); - } - - async _reset() { - if (this.isEncrypted()) await this.decryptAllEventsOfTimeline(this.activeTimeline); - this._populateTimelines(); - if (!this.initialized) { - this.initialized = true; - this._listenEvents(); - } - } - - async loadLiveTimeline() { - this.activeTimeline = this.liveTimeline; - await this._reset(); - this.emit(cons.events.roomTimeline.READY, null); - return true; - } - - async loadEventTimeline(eventId) { - // we use first unfiltered EventTimelineSet for room pagination. - const timelineSet = this.getUnfilteredTimelineSet(); - try { - const eventTimeline = await this.matrixClient.getEventTimeline(timelineSet, eventId); - this.activeTimeline = eventTimeline; - await this._reset(); - this.emit(cons.events.roomTimeline.READY, eventId); - return true; - } catch { - return false; - } - } - - async paginateTimeline(backwards = false, limit = 30) { - if (this.initialized === false) return false; - if (this.isOngoingPagination) return false; - - this.isOngoingPagination = true; - - const timelineToPaginate = backwards - ? getFirstLinkedTimeline(this.activeTimeline) - : getLastLinkedTimeline(this.activeTimeline); - - if (timelineToPaginate.getPaginationToken(backwards ? 'b' : 'f') === null) { - this.emit(cons.events.roomTimeline.PAGINATED, backwards, 0); - this.isOngoingPagination = false; - return false; - } - - const oldSize = this.timeline.length; - try { - await this.matrixClient.paginateEventTimeline(timelineToPaginate, { backwards, limit }); - - if (this.isEncrypted()) await this.decryptAllEventsOfTimeline(this.activeTimeline); - this._populateTimelines(); - - const loaded = this.timeline.length - oldSize; - this.emit(cons.events.roomTimeline.PAGINATED, backwards, loaded); - this.isOngoingPagination = false; - return true; - } catch { - this.emit(cons.events.roomTimeline.PAGINATED, backwards, 0); - this.isOngoingPagination = false; - return false; - } - } - - decryptAllEventsOfTimeline(eventTimeline) { - const decryptionPromises = eventTimeline - .getEvents() - .filter((event) => event.isEncrypted() && !event.clearEvent) - .reverse() - .map((event) => event.attemptDecryption(this.matrixClient.crypto, { isRetry: true })); - - return Promise.allSettled(decryptionPromises); - } - - hasEventInTimeline(eventId, timeline = this.activeTimeline) { - const timelineSet = this.getUnfilteredTimelineSet(); - const eventTimeline = timelineSet.getTimelineForEvent(eventId); - if (!eventTimeline) return false; - return isTimelineLinked(eventTimeline, timeline); - } - - getUnfilteredTimelineSet() { - return this.room.getUnfilteredTimelineSet(); - } - - getEventReaders(mEvent) { - const liveEvents = this.liveTimeline.getEvents(); - const readers = []; - if (!mEvent) return []; - - for (let i = liveEvents.length - 1; i >= 0; i -= 1) { - readers.splice(readers.length, 0, ...this.room.getUsersReadUpTo(liveEvents[i])); - if (mEvent === liveEvents[i]) break; - } - - return [...new Set(readers)]; - } - - getLiveReaders() { - const liveEvents = this.liveTimeline.getEvents(); - const getLatestVisibleEvent = () => { - for (let i = liveEvents.length - 1; i >= 0; i -= 1) { - const mEvent = liveEvents[i]; - if (mEvent.getType() === 'm.room.member' && hideMemberEvents(mEvent)) { - // eslint-disable-next-line no-continue - continue; - } - if (!mEvent.isRedacted() - && !isReaction(mEvent) - && !isEdited(mEvent) - && cons.supportEventTypes.includes(mEvent.getType()) - ) return mEvent; - } - return liveEvents[liveEvents.length - 1]; - }; - - return this.getEventReaders(getLatestVisibleEvent()); - } - - getUnreadEventIndex(readUpToEventId) { - if (!this.hasEventInTimeline(readUpToEventId)) return -1; - - const readUpToEvent = this.findEventByIdInTimelineSet(readUpToEventId); - if (!readUpToEvent) return -1; - const rTs = readUpToEvent.getTs(); - - const tLength = this.timeline.length; - - for (let i = 0; i < tLength; i += 1) { - const mEvent = this.timeline[i]; - if (mEvent.getTs() > rTs) return i; - } - return -1; - } - - getReadUpToEventId() { - return this.room.getEventReadUpTo(this.matrixClient.getUserId()); - } - - getEventIndex(eventId) { - return this.timeline.findIndex((mEvent) => mEvent.getId() === eventId); - } - - findEventByIdInTimelineSet(eventId, eventTimelineSet = this.getUnfilteredTimelineSet()) { - return eventTimelineSet.findEventById(eventId); - } - - findEventById(eventId) { - return this.timeline[this.getEventIndex(eventId)] ?? null; - } - - deleteFromTimeline(eventId) { - const i = this.getEventIndex(eventId); - if (i === -1) return undefined; - return this.timeline.splice(i, 1)[0]; - } - - _listenEvents() { - this._listenRoomTimeline = (event, room, toStartOfTimeline, removed, data) => { - if (room.roomId !== this.roomId) return; - if (this.isOngoingPagination) return; - - // User is currently viewing the old events probably - // no need to add new event and emit changes. - // only add reactions and edited messages - if (this.isServingLiveTimeline() === false) { - if (!isReaction(event) && !isEdited(event)) return; - } - - // We only process live events here - if (!data.liveEvent) return; - - if (event.isEncrypted()) { - // We will add this event after it is being decrypted. - this.ongoingDecryptionCount += 1; - return; - } - - // FIXME: An unencrypted plain event can come - // while previous event is still decrypting - // and has not been added to timeline - // causing unordered timeline view. - - this.addToTimeline(event); - this.emit(cons.events.roomTimeline.EVENT, event); - }; - - this._listenDecryptEvent = (event) => { - if (event.getRoomId() !== this.roomId) return; - if (this.isOngoingPagination) return; - - // Not a live event. - // so we don't need to process it here - if (this.ongoingDecryptionCount === 0) return; - - if (this.ongoingDecryptionCount > 0) { - this.ongoingDecryptionCount -= 1; - } - this.addToTimeline(event); - this.emit(cons.events.roomTimeline.EVENT, event); - }; - - this._listenRedaction = (mEvent, room) => { - if (room.roomId !== this.roomId) return; - const rEvent = this.deleteFromTimeline(mEvent.event.redacts); - this.editedTimeline.delete(mEvent.event.redacts); - this.reactionTimeline.delete(mEvent.event.redacts); - this.emit(cons.events.roomTimeline.EVENT_REDACTED, rEvent, mEvent); - }; - - this._listenTypingEvent = (event, member) => { - if (member.roomId !== this.roomId) return; - - const isTyping = member.typing; - if (isTyping) this.typingMembers.add(member.userId); - else this.typingMembers.delete(member.userId); - this.emit(cons.events.roomTimeline.TYPING_MEMBERS_UPDATED, new Set([...this.typingMembers])); - }; - this._listenReciptEvent = (event, room) => { - // we only process receipt for latest message here. - if (room.roomId !== this.roomId) return; - const receiptContent = event.getContent(); - - const mEvents = this.liveTimeline.getEvents(); - const lastMEvent = mEvents[mEvents.length - 1]; - const lastEventId = lastMEvent.getId(); - const lastEventRecipt = receiptContent[lastEventId]; - - if (typeof lastEventRecipt === 'undefined') return; - if (lastEventRecipt['m.read']) { - this.emit(cons.events.roomTimeline.LIVE_RECEIPT); - } - }; - - this.matrixClient.on('Room.timeline', this._listenRoomTimeline); - this.matrixClient.on('Room.redaction', this._listenRedaction); - this.matrixClient.on('Event.decrypted', this._listenDecryptEvent); - this.matrixClient.on('RoomMember.typing', this._listenTypingEvent); - this.matrixClient.on('Room.receipt', this._listenReciptEvent); - } - - removeInternalListeners() { - if (!this.initialized) return; - this.matrixClient.removeListener('Room.timeline', this._listenRoomTimeline); - this.matrixClient.removeListener('Room.redaction', this._listenRedaction); - this.matrixClient.removeListener('Event.decrypted', this._listenDecryptEvent); - this.matrixClient.removeListener('RoomMember.typing', this._listenTypingEvent); - this.matrixClient.removeListener('Room.receipt', this._listenReciptEvent); - } -} - -export default RoomTimeline; diff --git a/src/client/state/RoomsHierarchy.js b/src/client/state/RoomsHierarchy.js deleted file mode 100644 index f3ffb1fcb..000000000 --- a/src/client/state/RoomsHierarchy.js +++ /dev/null @@ -1,49 +0,0 @@ -import { RoomHierarchy } from 'matrix-js-sdk/lib/room-hierarchy'; - -class RoomsHierarchy { - constructor(matrixClient, limit = 20, maxDepth = 1, suggestedOnly = false) { - this.matrixClient = matrixClient; - this._maxDepth = maxDepth; - this._suggestedOnly = suggestedOnly; - this._limit = limit; - - this.roomIdToHierarchy = new Map(); - } - - getHierarchy(roomId) { - return this.roomIdToHierarchy.get(roomId); - } - - removeHierarchy(roomId) { - return this.roomIdToHierarchy.delete(roomId); - } - - canLoadMore(roomId) { - const roomHierarchy = this.getHierarchy(roomId); - if (!roomHierarchy) return true; - return roomHierarchy.canLoadMore; - } - - async load(roomId, limit = this._limit) { - let roomHierarchy = this.getHierarchy(roomId); - - if (!roomHierarchy) { - roomHierarchy = new RoomHierarchy( - { roomId, client: this.matrixClient }, - limit, - this._maxDepth, - this._suggestedOnly, - ); - this.roomIdToHierarchy.set(roomId, roomHierarchy); - } - - try { - await roomHierarchy.load(limit); - return roomHierarchy.rooms; - } catch { - return roomHierarchy.rooms; - } - } -} - -export default RoomsHierarchy; diff --git a/src/client/state/RoomsInput.js b/src/client/state/RoomsInput.js deleted file mode 100644 index d1e0aedb7..000000000 --- a/src/client/state/RoomsInput.js +++ /dev/null @@ -1,423 +0,0 @@ -import EventEmitter from 'events'; -import encrypt from 'browser-encrypt-attachment'; -import { encode } from 'blurhash'; -import { getShortcodeToEmoji } from '../../app/organisms/emoji-board/custom-emoji'; -import { getBlobSafeMimeType } from '../../util/mimetypes'; -import { sanitizeText } from '../../util/sanitize'; -import cons from './cons'; -import settings from './settings'; -import { markdown, plain } from '../../util/markdown'; - -const blurhashField = 'xyz.amorgan.blurhash'; - -function encodeBlurhash(img) { - const canvas = document.createElement('canvas'); - canvas.width = 100; - canvas.height = 100; - const context = canvas.getContext('2d'); - context.drawImage(img, 0, 0, canvas.width, canvas.height); - const data = context.getImageData(0, 0, canvas.width, canvas.height); - return encode(data.data, data.width, data.height, 4, 4); -} - -function loadImage(url) { - return new Promise((resolve, reject) => { - const img = new Image(); - img.onload = () => resolve(img); - img.onerror = (err) => reject(err); - img.src = url; - }); -} - -function loadVideo(videoFile) { - return new Promise((resolve, reject) => { - const video = document.createElement('video'); - video.preload = 'metadata'; - video.playsInline = true; - video.muted = true; - - const reader = new FileReader(); - - reader.onload = (ev) => { - // Wait until we have enough data to thumbnail the first frame. - video.onloadeddata = async () => { - resolve(video); - video.pause(); - }; - video.onerror = (e) => { - reject(e); - }; - - video.src = ev.target.result; - video.load(); - video.play(); - }; - reader.onerror = (e) => { - reject(e); - }; - if (videoFile.type === 'video/quicktime') { - const quicktimeVideoFile = new File([videoFile], videoFile.name, { type: 'video/mp4' }); - reader.readAsDataURL(quicktimeVideoFile); - } else { - reader.readAsDataURL(videoFile); - } - }); -} -function getVideoThumbnail(video, width, height, mimeType) { - return new Promise((resolve) => { - const MAX_WIDTH = 800; - const MAX_HEIGHT = 600; - let targetWidth = width; - let targetHeight = height; - if (targetHeight > MAX_HEIGHT) { - targetWidth = Math.floor(targetWidth * (MAX_HEIGHT / targetHeight)); - targetHeight = MAX_HEIGHT; - } - if (targetWidth > MAX_WIDTH) { - targetHeight = Math.floor(targetHeight * (MAX_WIDTH / targetWidth)); - targetWidth = MAX_WIDTH; - } - - const canvas = document.createElement('canvas'); - canvas.width = targetWidth; - canvas.height = targetHeight; - const context = canvas.getContext('2d'); - context.drawImage(video, 0, 0, targetWidth, targetHeight); - - canvas.toBlob((thumbnail) => { - resolve({ - thumbnail, - info: { - w: targetWidth, - h: targetHeight, - mimetype: thumbnail.type, - size: thumbnail.size, - }, - }); - }, mimeType); - }); -} - -class RoomsInput extends EventEmitter { - constructor(mx, roomList) { - super(); - - this.matrixClient = mx; - this.roomList = roomList; - this.roomIdToInput = new Map(); - } - - cleanEmptyEntry(roomId) { - const input = this.getInput(roomId); - const isEmpty = typeof input.attachment === 'undefined' - && typeof input.replyTo === 'undefined' - && (typeof input.message === 'undefined' || input.message === ''); - if (isEmpty) { - this.roomIdToInput.delete(roomId); - } - } - - getInput(roomId) { - return this.roomIdToInput.get(roomId) || {}; - } - - setMessage(roomId, message) { - const input = this.getInput(roomId); - input.message = message; - this.roomIdToInput.set(roomId, input); - if (message === '') this.cleanEmptyEntry(roomId); - } - - getMessage(roomId) { - const input = this.getInput(roomId); - if (typeof input.message === 'undefined') return ''; - return input.message; - } - - setReplyTo(roomId, replyTo) { - const input = this.getInput(roomId); - input.replyTo = replyTo; - this.roomIdToInput.set(roomId, input); - } - - getReplyTo(roomId) { - const input = this.getInput(roomId); - if (typeof input.replyTo === 'undefined') return null; - return input.replyTo; - } - - cancelReplyTo(roomId) { - const input = this.getInput(roomId); - if (typeof input.replyTo === 'undefined') return; - delete input.replyTo; - this.roomIdToInput.set(roomId, input); - } - - setAttachment(roomId, file) { - const input = this.getInput(roomId); - input.attachment = { - file, - }; - this.roomIdToInput.set(roomId, input); - } - - getAttachment(roomId) { - const input = this.getInput(roomId); - if (typeof input.attachment === 'undefined') return null; - return input.attachment.file; - } - - cancelAttachment(roomId) { - const input = this.getInput(roomId); - if (typeof input.attachment === 'undefined') return; - - const { uploadingPromise } = input.attachment; - - if (uploadingPromise) { - this.matrixClient.cancelUpload(uploadingPromise); - delete input.attachment.uploadingPromise; - } - delete input.attachment; - delete input.isSending; - this.roomIdToInput.set(roomId, input); - this.emit(cons.events.roomsInput.ATTACHMENT_CANCELED, roomId); - } - - isSending(roomId) { - return this.roomIdToInput.get(roomId)?.isSending || false; - } - - getContent(roomId, options, message, reply, edit) { - const msgType = options?.msgType || 'm.text'; - const autoMarkdown = options?.autoMarkdown ?? true; - - const room = this.matrixClient.getRoom(roomId); - - const userNames = room.currentState.userIdsToDisplayNames; - const parentIds = this.roomList.getAllParentSpaces(room.roomId); - const parentRooms = [...parentIds].map((id) => this.matrixClient.getRoom(id)); - const emojis = getShortcodeToEmoji(this.matrixClient, [room, ...parentRooms]); - - const output = settings.isMarkdown && autoMarkdown ? markdown : plain; - const body = output(message, { userNames, emojis }); - - const content = { - body: body.plain, - msgtype: msgType, - }; - - if (!body.onlyPlain || reply) { - content.format = 'org.matrix.custom.html'; - content.formatted_body = body.html; - } - - if (edit) { - content['m.new_content'] = { ...content }; - content['m.relates_to'] = { - event_id: edit.getId(), - rel_type: 'm.replace', - }; - - const isReply = edit.getWireContent()['m.relates_to']?.['m.in_reply_to']; - if (isReply) { - content.format = 'org.matrix.custom.html'; - content.formatted_body = body.html; - } - - content.body = ` * ${content.body}`; - if (content.formatted_body) content.formatted_body = ` * ${content.formatted_body}`; - - if (isReply) { - const eBody = edit.getContent().body; - const replyHead = eBody.substring(0, eBody.indexOf('\n\n')); - if (replyHead) content.body = `${replyHead}\n\n${content.body}`; - - const eFBody = edit.getContent().formatted_body; - const fReplyHead = eFBody.substring(0, eFBody.indexOf('')); - if (fReplyHead) content.formatted_body = `${fReplyHead}${content.formatted_body}`; - } - } - - if (reply) { - content['m.relates_to'] = { - 'm.in_reply_to': { - event_id: reply.eventId, - }, - }; - - content.body = `> <${reply.userId}> ${reply.body.replace(/\n/g, '\n> ')}\n\n${content.body}`; - - const replyToLink = `In reply to`; - const userLink = `${sanitizeText(reply.userId)}`; - const fallback = `

      ${replyToLink}${userLink}
      ${reply.formattedBody || sanitizeText(reply.body)}
      `; - content.formatted_body = fallback + content.formatted_body; - } - - return content; - } - - async sendInput(roomId, options) { - const input = this.getInput(roomId); - input.isSending = true; - this.roomIdToInput.set(roomId, input); - if (input.attachment) { - await this.sendFile(roomId, input.attachment.file); - if (!this.isSending(roomId)) return; - } - - if (this.getMessage(roomId).trim() !== '') { - const content = this.getContent(roomId, options, input.message, input.replyTo); - this.matrixClient.sendMessage(roomId, content); - } - - if (this.isSending(roomId)) this.roomIdToInput.delete(roomId); - this.emit(cons.events.roomsInput.MESSAGE_SENT, roomId); - } - - async sendSticker(roomId, data) { - const { mxc: url, body, httpUrl } = data; - const info = {}; - - const img = new Image(); - img.src = httpUrl; - - try { - const res = await fetch(httpUrl); - const blob = await res.blob(); - info.w = img.width; - info.h = img.height; - info.mimetype = blob.type; - info.size = blob.size; - info.thumbnail_info = { ...info }; - info.thumbnail_url = url; - } catch { - // send sticker without info - } - - this.matrixClient.sendEvent(roomId, 'm.sticker', { - body, - url, - info, - }); - this.emit(cons.events.roomsInput.MESSAGE_SENT, roomId); - } - - async sendFile(roomId, file) { - const fileType = getBlobSafeMimeType(file.type).slice(0, file.type.indexOf('/')); - const info = { - mimetype: file.type, - size: file.size, - }; - const content = { info }; - let uploadData = null; - - if (fileType === 'image') { - const img = await loadImage(URL.createObjectURL(file)); - - info.w = img.width; - info.h = img.height; - info[blurhashField] = encodeBlurhash(img); - - content.msgtype = 'm.image'; - content.body = file.name || 'Image'; - } else if (fileType === 'video') { - content.msgtype = 'm.video'; - content.body = file.name || 'Video'; - - try { - const video = await loadVideo(file); - - info.w = video.videoWidth; - info.h = video.videoHeight; - info[blurhashField] = encodeBlurhash(video); - - const thumbnailData = await getVideoThumbnail(video, video.videoWidth, video.videoHeight, 'image/jpeg'); - const thumbnailUploadData = await this.uploadFile(roomId, thumbnailData.thumbnail); - info.thumbnail_info = thumbnailData.info; - if (this.matrixClient.isRoomEncrypted(roomId)) { - info.thumbnail_file = thumbnailUploadData.file; - } else { - info.thumbnail_url = thumbnailUploadData.url; - } - } catch (e) { - this.emit(cons.events.roomsInput.FILE_UPLOAD_CANCELED, roomId); - return; - } - } else if (fileType === 'audio') { - content.msgtype = 'm.audio'; - content.body = file.name || 'Audio'; - } else { - content.msgtype = 'm.file'; - content.body = file.name || 'File'; - } - - try { - uploadData = await this.uploadFile(roomId, file, (data) => { - // data have two properties: data.loaded, data.total - this.emit(cons.events.roomsInput.UPLOAD_PROGRESS_CHANGES, roomId, data); - }); - this.emit(cons.events.roomsInput.FILE_UPLOADED, roomId); - } catch (e) { - this.emit(cons.events.roomsInput.FILE_UPLOAD_CANCELED, roomId); - return; - } - if (this.matrixClient.isRoomEncrypted(roomId)) { - content.file = uploadData.file; - await this.matrixClient.sendMessage(roomId, content); - } else { - content.url = uploadData.url; - await this.matrixClient.sendMessage(roomId, content); - } - } - - async uploadFile(roomId, file, progressHandler) { - const isEncryptedRoom = this.matrixClient.isRoomEncrypted(roomId); - - let encryptInfo = null; - let encryptBlob = null; - - if (isEncryptedRoom) { - const dataBuffer = await file.arrayBuffer(); - if (typeof this.getInput(roomId).attachment === 'undefined') throw new Error('Attachment canceled'); - const encryptedResult = await encrypt.encryptAttachment(dataBuffer); - if (typeof this.getInput(roomId).attachment === 'undefined') throw new Error('Attachment canceled'); - encryptInfo = encryptedResult.info; - encryptBlob = new Blob([encryptedResult.data]); - } - - const uploadingPromise = this.matrixClient.uploadContent(isEncryptedRoom ? encryptBlob : file, { - // don't send filename if room is encrypted. - includeFilename: !isEncryptedRoom, - progressHandler, - }); - - const input = this.getInput(roomId); - input.attachment.uploadingPromise = uploadingPromise; - this.roomIdToInput.set(roomId, input); - - const { content_uri: url } = await uploadingPromise; - - delete input.attachment.uploadingPromise; - this.roomIdToInput.set(roomId, input); - - if (isEncryptedRoom) { - encryptInfo.url = url; - if (file.type) encryptInfo.mimetype = file.type; - return { file: encryptInfo }; - } - return { url }; - } - - async sendEditedMessage(roomId, mEvent, editedBody) { - const content = this.getContent( - roomId, - { msgType: mEvent.getWireContent().msgtype }, - editedBody, - null, - mEvent, - ); - this.matrixClient.sendMessage(roomId, content); - } -} - -export default RoomsInput; diff --git a/src/client/state/cons.js b/src/client/state/cons.js index 62c0cacc9..523e871a1 100644 --- a/src/client/state/cons.js +++ b/src/client/state/cons.js @@ -8,10 +8,6 @@ const cons = { }, DEVICE_DISPLAY_NAME: 'Cinny Web', IN_CINNY_SPACES: 'in.cinny.spaces', - tabs: { - HOME: 'home', - DIRECTS: 'dm', - }, supportEventTypes: [ 'm.room.create', 'm.room.message', @@ -37,43 +33,19 @@ const cons = { }, actions: { navigation: { - SELECT_TAB: 'SELECT_TAB', - SELECT_SPACE: 'SELECT_SPACE', - SELECT_ROOM: 'SELECT_ROOM', OPEN_SPACE_SETTINGS: 'OPEN_SPACE_SETTINGS', - OPEN_SPACE_MANAGE: 'OPEN_SPACE_MANAGE', OPEN_SPACE_ADDEXISTING: 'OPEN_SPACE_ADDEXISTING', TOGGLE_ROOM_SETTINGS: 'TOGGLE_ROOM_SETTINGS', - OPEN_SHORTCUT_SPACES: 'OPEN_SHORTCUT_SPACES', - OPEN_INVITE_LIST: 'OPEN_INVITE_LIST', - OPEN_PUBLIC_ROOMS: 'OPEN_PUBLIC_ROOMS', OPEN_CREATE_ROOM: 'OPEN_CREATE_ROOM', OPEN_JOIN_ALIAS: 'OPEN_JOIN_ALIAS', OPEN_INVITE_USER: 'OPEN_INVITE_USER', OPEN_PROFILE_VIEWER: 'OPEN_PROFILE_VIEWER', OPEN_SETTINGS: 'OPEN_SETTINGS', - OPEN_EMOJIBOARD: 'OPEN_EMOJIBOARD', - OPEN_READRECEIPTS: 'OPEN_READRECEIPTS', - OPEN_VIEWSOURCE: 'OPEN_VIEWSOURCE', - CLICK_REPLY_TO: 'CLICK_REPLY_TO', OPEN_SEARCH: 'OPEN_SEARCH', OPEN_REUSABLE_CONTEXT_MENU: 'OPEN_REUSABLE_CONTEXT_MENU', - OPEN_NAVIGATION: 'OPEN_NAVIGATION', OPEN_REUSABLE_DIALOG: 'OPEN_REUSABLE_DIALOG', OPEN_EMOJI_VERIFICATION: 'OPEN_EMOJI_VERIFICATION', }, - room: { - JOIN: 'JOIN', - LEAVE: 'LEAVE', - CREATE: 'CREATE', - }, - accountData: { - CREATE_SPACE_SHORTCUT: 'CREATE_SPACE_SHORTCUT', - DELETE_SPACE_SHORTCUT: 'DELETE_SPACE_SHORTCUT', - MOVE_SPACE_SHORTCUTS: 'MOVE_SPACE_SHORTCUTS', - CATEGORIZE_SPACE: 'CATEGORIZE_SPACE', - UNCATEGORIZE_SPACE: 'UNCATEGORIZE_SPACE', - }, settings: { TOGGLE_SYSTEM_THEME: 'TOGGLE_SYSTEM_THEME', TOGGLE_MARKDOWN: 'TOGGLE_MARKDOWN', @@ -86,66 +58,23 @@ const cons = { }, events: { navigation: { - TAB_SELECTED: 'TAB_SELECTED', - SPACE_SELECTED: 'SPACE_SELECTED', - ROOM_SELECTED: 'ROOM_SELECTED', SPACE_SETTINGS_OPENED: 'SPACE_SETTINGS_OPENED', - SPACE_MANAGE_OPENED: 'SPACE_MANAGE_OPENED', SPACE_ADDEXISTING_OPENED: 'SPACE_ADDEXISTING_OPENED', ROOM_SETTINGS_TOGGLED: 'ROOM_SETTINGS_TOGGLED', - SHORTCUT_SPACES_OPENED: 'SHORTCUT_SPACES_OPENED', - INVITE_LIST_OPENED: 'INVITE_LIST_OPENED', - PUBLIC_ROOMS_OPENED: 'PUBLIC_ROOMS_OPENED', CREATE_ROOM_OPENED: 'CREATE_ROOM_OPENED', JOIN_ALIAS_OPENED: 'JOIN_ALIAS_OPENED', INVITE_USER_OPENED: 'INVITE_USER_OPENED', SETTINGS_OPENED: 'SETTINGS_OPENED', - PROFILE_VIEWER_OPENED: 'PROFILE_VIEWER_OPENED', - EMOJIBOARD_OPENED: 'EMOJIBOARD_OPENED', - READRECEIPTS_OPENED: 'READRECEIPTS_OPENED', - VIEWSOURCE_OPENED: 'VIEWSOURCE_OPENED', - REPLY_TO_CLICKED: 'REPLY_TO_CLICKED', SEARCH_OPENED: 'SEARCH_OPENED', REUSABLE_CONTEXT_MENU_OPENED: 'REUSABLE_CONTEXT_MENU_OPENED', - NAVIGATION_OPENED: 'NAVIGATION_OPENED', REUSABLE_DIALOG_OPENED: 'REUSABLE_DIALOG_OPENED', EMOJI_VERIFICATION_OPENED: 'EMOJI_VERIFICATION_OPENED', }, - roomList: { - ROOMLIST_UPDATED: 'ROOMLIST_UPDATED', - INVITELIST_UPDATED: 'INVITELIST_UPDATED', - ROOM_JOINED: 'ROOM_JOINED', - ROOM_LEAVED: 'ROOM_LEAVED', - ROOM_CREATED: 'ROOM_CREATED', - ROOM_PROFILE_UPDATED: 'ROOM_PROFILE_UPDATED', - }, - accountData: { - SPACE_SHORTCUT_UPDATED: 'SPACE_SHORTCUT_UPDATED', - CATEGORIZE_SPACE_UPDATED: 'CATEGORIZE_SPACE_UPDATED', - }, notifications: { NOTI_CHANGED: 'NOTI_CHANGED', FULL_READ: 'FULL_READ', MUTE_TOGGLED: 'MUTE_TOGGLED', }, - roomTimeline: { - READY: 'READY', - EVENT: 'EVENT', - PAGINATED: 'PAGINATED', - TYPING_MEMBERS_UPDATED: 'TYPING_MEMBERS_UPDATED', - LIVE_RECEIPT: 'LIVE_RECEIPT', - EVENT_REDACTED: 'EVENT_REDACTED', - AT_BOTTOM: 'AT_BOTTOM', - SCROLL_TO_LIVE: 'SCROLL_TO_LIVE', - }, - roomsInput: { - MESSAGE_SENT: 'MESSAGE_SENT', - ATTACHMENT_SET: 'ATTACHMENT_SET', - FILE_UPLOADED: 'FILE_UPLOADED', - UPLOAD_PROGRESS_CHANGES: 'UPLOAD_PROGRESS_CHANGES', - FILE_UPLOAD_CANCELED: 'FILE_UPLOAD_CANCELED', - ATTACHMENT_CANCELED: 'ATTACHMENT_CANCELED', - }, settings: { SYSTEM_THEME_TOGGLED: 'SYSTEM_THEME_TOGGLED', MARKDOWN_TOGGLED: 'MARKDOWN_TOGGLED', diff --git a/src/client/state/navigation.js b/src/client/state/navigation.js index ddac4dda8..5f28f232f 100644 --- a/src/client/state/navigation.js +++ b/src/client/state/navigation.js @@ -5,268 +5,9 @@ import cons from './cons'; class Navigation extends EventEmitter { constructor() { super(); - // this will attached by initMatrix - this.initMatrix = {}; - - this.selectedTab = cons.tabs.HOME; - this.selectedSpaceId = null; - this.selectedSpacePath = [cons.tabs.HOME]; - - this.selectedRoomId = null; - this.recentRooms = []; - - this.spaceToRoom = new Map(); - this.rawModelStack = []; } - _addToSpacePath(roomId, asRoot) { - if (typeof roomId !== 'string') { - this.selectedSpacePath = [cons.tabs.HOME]; - return; - } - if (asRoot) { - this.selectedSpacePath = [roomId]; - return; - } - if (this.selectedSpacePath.includes(roomId)) { - const spIndex = this.selectedSpacePath.indexOf(roomId); - this.selectedSpacePath = this.selectedSpacePath.slice(0, spIndex + 1); - return; - } - this.selectedSpacePath.push(roomId); - } - - _mapRoomToSpace(roomId) { - const { roomList, accountData } = this.initMatrix; - if ( - this.selectedTab === cons.tabs.HOME - && roomList.rooms.has(roomId) - && !roomList.roomIdToParents.has(roomId) - ) { - this.spaceToRoom.set(cons.tabs.HOME, { - roomId, - timestamp: Date.now(), - }); - return; - } - if (this.selectedTab === cons.tabs.DIRECTS && roomList.directs.has(roomId)) { - this.spaceToRoom.set(cons.tabs.DIRECTS, { - roomId, - timestamp: Date.now(), - }); - return; - } - - const parents = roomList.roomIdToParents.get(roomId); - if (!parents) return; - if (parents.has(this.selectedSpaceId)) { - this.spaceToRoom.set(this.selectedSpaceId, { - roomId, - timestamp: Date.now(), - }); - } else if (accountData.categorizedSpaces.has(this.selectedSpaceId)) { - const categories = roomList.getCategorizedSpaces([this.selectedSpaceId]); - const parent = [...parents].find((pId) => categories.has(pId)); - if (parent) { - this.spaceToRoom.set(parent, { - roomId, - timestamp: Date.now(), - }); - } - } - } - - _selectRoom(roomId, eventId) { - const prevSelectedRoomId = this.selectedRoomId; - this.selectedRoomId = roomId; - if (prevSelectedRoomId !== roomId) this._mapRoomToSpace(roomId); - this.removeRecentRoom(prevSelectedRoomId); - this.addRecentRoom(prevSelectedRoomId); - this.removeRecentRoom(this.selectedRoomId); - this.emit( - cons.events.navigation.ROOM_SELECTED, - this.selectedRoomId, - prevSelectedRoomId, - eventId, - ); - } - - _selectTabWithRoom(roomId) { - const { roomList, accountData } = this.initMatrix; - const { categorizedSpaces } = accountData; - - if (roomList.isOrphan(roomId)) { - if (roomList.directs.has(roomId)) { - this._selectSpace(null, true, false); - this._selectTab(cons.tabs.DIRECTS, false); - return; - } - this._selectSpace(null, true, false); - this._selectTab(cons.tabs.HOME, false); - return; - } - - const parents = roomList.roomIdToParents.get(roomId); - - if (parents.has(this.selectedSpaceId)) { - return; - } - - if (categorizedSpaces.has(this.selectedSpaceId)) { - const categories = roomList.getCategorizedSpaces([this.selectedSpaceId]); - if ([...parents].find((pId) => categories.has(pId))) { - // No need to select tab - // As one of parent is child of selected categorized space. - return; - } - } - - const spaceInPath = [...this.selectedSpacePath].reverse().find((sId) => parents.has(sId)); - if (spaceInPath) { - this._selectSpace(spaceInPath, false, false); - return; - } - - if (roomList.directs.has(roomId)) { - this._selectSpace(null, true, false); - this._selectTab(cons.tabs.DIRECTS, false); - return; - } - - if (parents.size > 0) { - const sortedParents = [...parents].sort((p1, p2) => { - const t1 = this.spaceToRoom.get(p1)?.timestamp ?? 0; - const t2 = this.spaceToRoom.get(p2)?.timestamp ?? 0; - return t2 - t1; - }); - this._selectSpace(sortedParents[0], true, false); - this._selectTab(sortedParents[0], false); - } - } - - _getLatestActiveRoomId(roomIds) { - const mx = this.initMatrix.matrixClient; - - let ts = 0; - let roomId = null; - roomIds.forEach((childId) => { - const room = mx.getRoom(childId); - if (!room) return; - const newTs = room.getLastActiveTimestamp(); - if (newTs > ts) { - ts = newTs; - roomId = childId; - } - }); - return roomId; - } - - _getLatestSelectedRoomId(spaceIds) { - let ts = 0; - let roomId = null; - - spaceIds.forEach((sId) => { - const data = this.spaceToRoom.get(sId); - if (!data) return; - const newTs = data.timestamp; - if (newTs > ts) { - ts = newTs; - roomId = data.roomId; - } - }); - return roomId; - } - - _selectTab(tabId, selectRoom = true) { - this.selectedTab = tabId; - if (selectRoom) this._selectRoomWithTab(this.selectedTab); - this.emit(cons.events.navigation.TAB_SELECTED, this.selectedTab); - } - - _selectSpace(roomId, asRoot, selectRoom = true) { - this._addToSpacePath(roomId, asRoot); - this.selectedSpaceId = roomId; - if (!asRoot && selectRoom) this._selectRoomWithSpace(this.selectedSpaceId); - this.emit(cons.events.navigation.SPACE_SELECTED, this.selectedSpaceId); - } - - _selectRoomWithSpace(spaceId) { - if (!spaceId) return; - const { roomList, accountData, matrixClient } = this.initMatrix; - const { categorizedSpaces } = accountData; - - const data = this.spaceToRoom.get(spaceId); - if (data && !categorizedSpaces.has(spaceId)) { - this._selectRoom(data.roomId); - return; - } - - const children = []; - - if (categorizedSpaces.has(spaceId)) { - const categories = roomList.getCategorizedSpaces([spaceId]); - - const latestSelectedRoom = this._getLatestSelectedRoomId([...categories.keys()]); - - if (latestSelectedRoom) { - this._selectRoom(latestSelectedRoom); - return; - } - - categories?.forEach((categoryId) => { - categoryId?.forEach((childId) => { - children.push(childId); - }); - }); - } else { - roomList.getSpaceChildren(spaceId).forEach((id) => { - if (matrixClient.getRoom(id)?.isSpaceRoom() === false) { - children.push(id); - } - }); - } - - if (!children) { - this._selectRoom(null); - return; - } - - this._selectRoom(this._getLatestActiveRoomId(children)); - } - - _selectRoomWithTab(tabId) { - const { roomList } = this.initMatrix; - if (tabId === cons.tabs.HOME || tabId === cons.tabs.DIRECTS) { - const data = this.spaceToRoom.get(tabId); - if (data) { - this._selectRoom(data.roomId); - return; - } - const children = tabId === cons.tabs.HOME ? roomList.getOrphanRooms() : [...roomList.directs]; - this._selectRoom(this._getLatestActiveRoomId(children)); - return; - } - this._selectRoomWithSpace(tabId); - } - - removeRecentRoom(roomId) { - if (typeof roomId !== 'string') return; - const roomIdIndex = this.recentRooms.indexOf(roomId); - if (roomIdIndex >= 0) { - this.recentRooms.splice(roomIdIndex, 1); - } - } - - addRecentRoom(roomId) { - if (typeof roomId !== 'string') return; - - this.recentRooms.push(roomId); - if (this.recentRooms.length > 10) { - this.recentRooms.splice(0, 1); - } - } - get isRawModalVisible() { return this.rawModelStack.length > 0; } @@ -278,27 +19,9 @@ class Navigation extends EventEmitter { navigate(action) { const actions = { - [cons.actions.navigation.SELECT_TAB]: () => { - const roomId = ( - action.tabId !== cons.tabs.HOME && action.tabId !== cons.tabs.DIRECTS - ) ? action.tabId : null; - - this._selectSpace(roomId, true); - this._selectTab(action.tabId); - }, - [cons.actions.navigation.SELECT_SPACE]: () => { - this._selectSpace(action.roomId, false); - }, - [cons.actions.navigation.SELECT_ROOM]: () => { - if (action.roomId) this._selectTabWithRoom(action.roomId); - this._selectRoom(action.roomId, action.eventId); - }, [cons.actions.navigation.OPEN_SPACE_SETTINGS]: () => { this.emit(cons.events.navigation.SPACE_SETTINGS_OPENED, action.roomId, action.tabText); }, - [cons.actions.navigation.OPEN_SPACE_MANAGE]: () => { - this.emit(cons.events.navigation.SPACE_MANAGE_OPENED, action.roomId); - }, [cons.actions.navigation.OPEN_SPACE_ADDEXISTING]: () => { this.emit(cons.events.navigation.SPACE_ADDEXISTING_OPENED, action.roomId, action.spaces); }, @@ -309,15 +32,6 @@ class Navigation extends EventEmitter { action.tabText ); }, - [cons.actions.navigation.OPEN_SHORTCUT_SPACES]: () => { - this.emit(cons.events.navigation.SHORTCUT_SPACES_OPENED); - }, - [cons.actions.navigation.OPEN_INVITE_LIST]: () => { - this.emit(cons.events.navigation.INVITE_LIST_OPENED); - }, - [cons.actions.navigation.OPEN_PUBLIC_ROOMS]: () => { - this.emit(cons.events.navigation.PUBLIC_ROOMS_OPENED, action.searchTerm); - }, [cons.actions.navigation.OPEN_CREATE_ROOM]: () => { this.emit( cons.events.navigation.CREATE_ROOM_OPENED, @@ -340,38 +54,6 @@ class Navigation extends EventEmitter { [cons.actions.navigation.OPEN_SETTINGS]: () => { this.emit(cons.events.navigation.SETTINGS_OPENED, action.tabText); }, - [cons.actions.navigation.OPEN_NAVIGATION]: () => { - this.emit(cons.events.navigation.NAVIGATION_OPENED); - }, - [cons.actions.navigation.OPEN_EMOJIBOARD]: () => { - this.emit( - cons.events.navigation.EMOJIBOARD_OPENED, - action.cords, - action.requestEmojiCallback, - ); - }, - [cons.actions.navigation.OPEN_READRECEIPTS]: () => { - this.emit( - cons.events.navigation.READRECEIPTS_OPENED, - action.roomId, - action.userIds, - ); - }, - [cons.actions.navigation.OPEN_VIEWSOURCE]: () => { - this.emit( - cons.events.navigation.VIEWSOURCE_OPENED, - action.event, - ); - }, - [cons.actions.navigation.CLICK_REPLY_TO]: () => { - this.emit( - cons.events.navigation.REPLY_TO_CLICKED, - action.userId, - action.eventId, - action.body, - action.formattedBody, - ); - }, [cons.actions.navigation.OPEN_SEARCH]: () => { this.emit( cons.events.navigation.SEARCH_OPENED, diff --git a/src/util/Postie.js b/src/util/Postie.js deleted file mode 100644 index 73c8f9e81..000000000 --- a/src/util/Postie.js +++ /dev/null @@ -1,97 +0,0 @@ -class Postie { - constructor() { - this._topics = new Map(); - } - - _getSubscribers(topic) { - const subscribers = this._topics.get(topic); - if (subscribers === undefined) { - throw new Error(`Topic:"${topic}" doesn't exist.`); - } - return subscribers; - } - - _getInboxes(topic, address) { - const subscribers = this._getSubscribers(topic); - const inboxes = subscribers.get(address); - if (inboxes === undefined) { - throw new Error(`Inbox on topic:"${topic}" at address:"${address}" doesn't exist.`); - } - return inboxes; - } - - hasTopic(topic) { - return this._topics.get(topic) !== undefined; - } - - hasSubscriber(topic, address) { - const subscribers = this._getSubscribers(topic); - return subscribers.get(address) !== undefined; - } - - hasTopicAndSubscriber(topic, address) { - return (this.hasTopic(topic)) - ? this.hasSubscriber(topic, address) - : false; - } - - /** - * @param {string} topic - Subscription topic - * @param {string} address - Address of subscriber - * @param {function} inbox - The inbox function to receive post data - */ - subscribe(topic, address, inbox) { - if (typeof inbox !== 'function') { - throw new TypeError('Inbox must be a function.'); - } - - if (this._topics.has(topic) === false) { - this._topics.set(topic, new Map()); - } - const subscribers = this._topics.get(topic); - - const inboxes = subscribers.get(address) ?? new Set(); - inboxes.add(inbox); - subscribers.set(address, inboxes); - - return () => this.unsubscribe(topic, address, inbox); - } - - unsubscribe(topic, address, inbox) { - const subscribers = this._getSubscribers(topic); - if (!subscribers) throw new Error(`Unable to unsubscribe. Topic: "${topic}" doesn't exist.`); - - const inboxes = subscribers.get(address); - if (!inboxes) throw new Error(`Unable to unsubscribe. Subscriber on topic:"${topic}" at address:"${address}" doesn't exist`); - - if (!inboxes.delete(inbox)) throw new Error('Unable to unsubscribe. Inbox doesn\'t exist'); - - if (inboxes.size === 0) subscribers.delete(address); - if (subscribers.size === 0) this._topics.delete(topic); - } - - /** - * @param {string} topic - Subscription topic - * @param {string|string[]} address - Address of subscriber - * @param {*} data - Data to deliver to subscriber - */ - post(topic, address, data) { - const sendPost = (inboxes, addr) => { - if (inboxes === undefined) { - throw new Error(`Unable to post on topic:"${topic}" at address:"${addr}". Subscriber doesn't exist.`); - } - inboxes.forEach((inbox) => inbox(data)); - }; - - if (typeof address === 'string') { - sendPost(this._getInboxes(topic, address), address); - return; - } - const subscribers = this._getSubscribers(topic); - address.forEach((addr) => { - sendPost(subscribers.get(addr), addr); - }); - } -} - -export default Postie; diff --git a/src/util/colorMXID.js b/src/util/colorMXID.js index 4d303aae4..95600d29e 100644 --- a/src/util/colorMXID.js +++ b/src/util/colorMXID.js @@ -1,6 +1,6 @@ // https://github.com/cloudrac3r/cadencegq/blob/master/pug/mxid.pug -export function hashCode(str) { +function hashCode(str) { let hash = 0; let i; let chr; diff --git a/src/util/markdown.js b/src/util/markdown.js deleted file mode 100644 index c6c1a4900..000000000 --- a/src/util/markdown.js +++ /dev/null @@ -1,515 +0,0 @@ -/* eslint-disable no-param-reassign */ -/* eslint-disable no-use-before-define */ -import SimpleMarkdown from '@khanacademy/simple-markdown'; -import { idRegex, parseIdUri } from './common'; - -const { - defaultRules, parserFor, outputFor, anyScopeRegex, blockRegex, inlineRegex, - sanitizeText, sanitizeUrl, -} = SimpleMarkdown; - -function htmlTag(tagName, content, attributes, isClosed) { - let s = ''; - Object.entries(attributes || {}).forEach(([k, v]) => { - if (v !== undefined) { - s += ` ${sanitizeText(k)}`; - if (v !== null) s += `="${sanitizeText(v)}"`; - } - }); - - s = `<${tagName}${s}>`; - - if (isClosed === false) { - return s; - } - return `${s}${content}`; -} - -function mathHtml(wrap, node) { - return htmlTag(wrap, htmlTag('code', sanitizeText(node.content)), { 'data-mx-maths': node.content }); -} - -const emojiRegex = /^:([\w-]+):/; - -const plainRules = { - Array: { - ...defaultRules.Array, - plain: defaultRules.Array.html, - }, - userMention: { - order: defaultRules.em.order - 0.9, - match: inlineRegex(idRegex('@', undefined, '^')), - parse: (capture, _, state) => ({ - type: 'mention', - content: state.userNames[capture[1]] ? `@${state.userNames[capture[1]]}` : capture[1], - id: capture[1], - }), - }, - roomMention: { - order: defaultRules.em.order - 0.8, - match: inlineRegex(idRegex('#', undefined, '^')), - parse: (capture) => ({ type: 'mention', content: capture[1], id: capture[1] }), - }, - mention: { - plain: (node, _, state) => (state.kind === 'edit' ? node.id : node.content), - html: (node) => htmlTag('a', sanitizeText(node.content), { - href: `https://matrix.to/#/${encodeURIComponent(node.id)}`, - }), - }, - emoji: { - order: defaultRules.em.order - 0.1, - match: (source, state) => { - if (!state.inline) return null; - const capture = emojiRegex.exec(source); - if (!capture) return null; - const emoji = state.emojis.get(capture[1]); - if (emoji) return capture; - return null; - }, - parse: (capture, _, state) => ({ content: capture[1], emoji: state.emojis.get(capture[1]) }), - plain: ({ emoji }) => (emoji.mxc - ? `:${emoji.shortcode}:` - : emoji.unicode), - html: ({ emoji }) => (emoji.mxc - ? htmlTag('img', null, { - 'data-mx-emoticon': null, - src: emoji.mxc, - alt: `:${emoji.shortcode}:`, - title: `:${emoji.shortcode}:`, - height: 32, - }, false) - : emoji.unicode), - }, - newline: { - ...defaultRules.newline, - plain: () => '\n', - }, - paragraph: { - ...defaultRules.paragraph, - plain: (node, output, state) => `${output(node.content, state)}\n\n`, - html: (node, output, state) => htmlTag('p', output(node.content, state)), - }, - escape: { - ...defaultRules.escape, - plain: (node, output, state) => `\\${output(node.content, state)}`, - }, - br: { - ...defaultRules.br, - match: anyScopeRegex(/^ *\n/), - plain: () => '\n', - }, - text: { - ...defaultRules.text, - match: anyScopeRegex(/^[\s\S]+?(?=[^0-9A-Za-z\s\u00c0-\uffff]| *\n|\w+:\S|$)/), - plain: (node, _, state) => (state.kind === 'edit' - ? node.content.replace(/(\*|_|!\[|\[|\|\||\$\$?)/g, '\\$1') - : node.content), - }, -}; - -const markdownRules = { - ...defaultRules, - ...plainRules, - heading: { - ...defaultRules.heading, - match: blockRegex(/^ *(#{1,6})([^\n:]*?(?: [^\n]*?)?)#* *(?:\n *)*\n/), - plain: (node, output, state) => { - const out = output(node.content, state); - if (state.kind === 'edit' || state.kind === 'notification' || node.level > 2) { - return `${'#'.repeat(node.level)} ${out}\n\n`; - } - return `${out}\n${(node.level === 1 ? '=' : '-').repeat(out.length)}\n\n`; - }, - }, - hr: { - ...defaultRules.hr, - plain: () => '---\n\n', - }, - codeBlock: { - ...defaultRules.codeBlock, - plain: (node) => `\`\`\`${node.lang || ''}\n${node.content}\n\`\`\`\n`, - html: (node) => htmlTag('pre', htmlTag('code', sanitizeText(node.content), { - class: node.lang ? `language-${node.lang}` : undefined, - })), - }, - fence: { - ...defaultRules.fence, - match: blockRegex(/^ *(`{3,}|~{3,}) *(?:(\S+) *)?\n([\s\S]+?)\n?\1 *(?:\n *)*\n/), - }, - blockQuote: { - ...defaultRules.blockQuote, - plain: (node, output, state) => `> ${output(node.content, state).trim().replace(/\n/g, '\n> ')}\n\n`, - }, - list: { - ...defaultRules.list, - plain: (node, output, state) => { - const oldList = state._list; - state._list = true; - - let items = node.items.map((item, i) => { - const prefix = node.ordered ? `${node.start + i}. ` : '* '; - return prefix + output(item, state).replace(/\n/g, `\n${' '.repeat(prefix.length)}`); - }).join('\n'); - - state._list = oldList; - - if (!state._list) { - items += '\n\n'; - } - return items; - }, - }, - def: undefined, - table: { - ...defaultRules.table, - plain: (node, output, state) => { - const header = node.header.map((content) => output(content, state)); - - const colWidth = node.align.map((align) => { - switch (align) { - case 'left': - case 'right': - return 2; - case 'center': - return 3; - default: - return 1; - } - }); - header.forEach((s, i) => { - if (s.length > colWidth[i])colWidth[i] = s.length; - }); - - const cells = node.cells.map((row) => row.map((content, i) => { - const s = output(content, state); - if (colWidth[i] === undefined || s.length > colWidth[i]) { - colWidth[i] = s.length; - } - return s; - })); - - function pad(s, i) { - switch (node.align[i]) { - case 'right': - return s.padStart(colWidth[i]); - case 'center': - return s - .padStart(s.length + Math.floor((colWidth[i] - s.length) / 2)) - .padEnd(colWidth[i]); - default: - return s.padEnd(colWidth[i]); - } - } - - const line = colWidth.map((len, i) => { - switch (node.align[i]) { - case 'left': - return `:${'-'.repeat(len - 1)}`; - case 'center': - return `:${'-'.repeat(len - 2)}:`; - case 'right': - return `${'-'.repeat(len - 1)}:`; - default: - return '-'.repeat(len); - } - }); - - const table = [ - header.map(pad), - line, - ...cells.map((row) => row.map(pad))]; - - return table.map((row) => `| ${row.join(' | ')} |\n`).join(''); - }, - }, - displayMath: { - order: defaultRules.table.order + 0.1, - match: blockRegex(/^ *\$\$ *\n?([\s\S]+?)\n?\$\$ *(?:\n *)*\n/), - parse: (capture) => ({ content: capture[1] }), - plain: (node) => (node.content.includes('\n') - ? `$$\n${node.content}\n$$\n` - : `$$${node.content}$$\n`), - html: (node) => mathHtml('div', node), - }, - shrug: { - order: defaultRules.escape.order - 0.1, - match: inlineRegex(/^¯\\_\(ツ\)_\/¯/), - parse: (capture) => ({ type: 'text', content: capture[0] }), - }, - tableSeparator: { - ...defaultRules.tableSeparator, - plain: () => ' | ', - }, - link: { - ...defaultRules.link, - plain: (node, output, state) => { - const out = output(node.content, state); - const target = sanitizeUrl(node.target) || ''; - if (out !== target || node.title) { - return `[${out}](${target}${node.title ? ` "${node.title}"` : ''})`; - } - return out; - }, - html: (node, output, state) => { - const out = output(node.content, state); - const target = sanitizeUrl(node.target) || ''; - if (out !== target || node.title) { - return htmlTag('a', out, { - href: target, - title: node.title, - }); - } - return target; - }, - }, - image: { - ...defaultRules.image, - plain: (node) => `![${node.alt}](${sanitizeUrl(node.target) || ''}${node.title ? ` "${node.title}"` : ''})`, - html: (node) => htmlTag('img', '', { - src: sanitizeUrl(node.target) || '', - alt: node.alt, - title: node.title, - }, false), - }, - reflink: undefined, - refimage: undefined, - em: { - ...defaultRules.em, - plain: (node, output, state) => `_${output(node.content, state)}_`, - }, - strong: { - ...defaultRules.strong, - plain: (node, output, state) => `**${output(node.content, state)}**`, - }, - u: { - ...defaultRules.u, - plain: (node, output, state) => `__${output(node.content, state)}__`, - }, - del: { - ...defaultRules.del, - plain: (node, output, state) => `~~${output(node.content, state)}~~`, - }, - inlineCode: { - ...defaultRules.inlineCode, - match: inlineRegex(/^(`+)([^\n]*?[^`\n])\1(?!`)/), - plain: (node) => `\`${node.content}\``, - }, - spoiler: { - order: defaultRules.inlineCode.order + 0.1, - match: inlineRegex(/^\|\|([\s\S]+?)\|\|(?:\(([\s\S]+?)\))?/), - parse: (capture, parse, state) => ({ - content: parse(capture[1], state), - reason: capture[2], - }), - plain: (node, output, state) => { - const warning = `spoiler${node.reason ? `: ${node.reason}` : ''}`; - switch (state.kind) { - case 'edit': - return `||${output(node.content, state)}||${node.reason ? `(${node.reason})` : ''}`; - case 'notification': - return `<${warning}>`; - default: - return `[${warning}](${output(node.content, state)})`; - } - }, - html: (node, output, state) => htmlTag( - 'span', - output(node.content, state), - { 'data-mx-spoiler': node.reason || null }, - ), - }, - inlineMath: { - order: defaultRules.del.order + 0.2, - match: inlineRegex(/^\$(\S[\s\S]+?\S|\S)\$(?!\d)/), - parse: (capture) => ({ content: capture[1] }), - plain: (node) => `$${node.content}$`, - html: (node) => mathHtml('span', node), - }, -}; - -function mapElement(el) { - switch (el.tagName) { - case 'MX-REPLY': - return []; - - case 'P': - return [{ type: 'paragraph', content: mapChildren(el) }]; - case 'BR': - return [{ type: 'br' }]; - - case 'H1': - case 'H2': - case 'H3': - case 'H4': - case 'H5': - case 'H6': - return [{ type: 'heading', level: Number(el.tagName[1]), content: mapChildren(el) }]; - case 'HR': - return [{ type: 'hr' }]; - case 'PRE': { - let lang; - if (el.firstChild) { - Array.from(el.firstChild.classList).some((c) => { - const langPrefix = 'language-'; - if (c.startsWith(langPrefix)) { - lang = c.slice(langPrefix.length); - return true; - } - return false; - }); - } - return [{ type: 'codeBlock', lang, content: el.innerText }]; - } - case 'BLOCKQUOTE': - return [{ type: 'blockQuote', content: mapChildren(el) }]; - case 'UL': - return [{ type: 'list', items: Array.from(el.childNodes).map(mapNode) }]; - case 'OL': - return [{ - type: 'list', - ordered: true, - start: Number(el.getAttribute('start')), - items: Array.from(el.childNodes).map(mapNode), - }]; - case 'TABLE': { - const headerEl = Array.from(el.querySelector('thead > tr').childNodes); - const align = headerEl.map((childE) => childE.style['text-align']); - return [{ - type: 'table', - header: headerEl.map(mapChildren), - align, - cells: Array.from(el.querySelectorAll('tbody > tr')).map((rowEl) => Array.from(rowEl.childNodes).map((childEl, i) => { - if (align[i] === undefined) align[i] = childEl.style['text-align']; - return mapChildren(childEl); - })), - }]; - } - case 'A': { - const href = el.getAttribute('href'); - - const id = parseIdUri(href); - if (id) return [{ type: 'mention', content: el.innerText, id }]; - - return [{ - type: 'link', - target: el.getAttribute('href'), - title: el.getAttribute('title'), - content: mapChildren(el), - }]; - } - case 'IMG': { - const src = el.getAttribute('src'); - let title = el.getAttribute('title'); - if (el.hasAttribute('data-mx-emoticon')) { - if (title.length > 2 && title.startsWith(':') && title.endsWith(':')) { - title = title.slice(1, -1); - } - return [{ - type: 'emoji', - content: title, - emoji: { - mxc: src, - shortcode: title, - }, - }]; - } - - return [{ - type: 'image', - alt: el.getAttribute('alt'), - target: src, - title, - }]; - } - case 'EM': - case 'I': - return [{ type: 'em', content: mapChildren(el) }]; - case 'STRONG': - case 'B': - return [{ type: 'strong', content: mapChildren(el) }]; - case 'U': - return [{ type: 'u', content: mapChildren(el) }]; - case 'DEL': - case 'STRIKE': - return [{ type: 'del', content: mapChildren(el) }]; - case 'CODE': - return [{ type: 'inlineCode', content: el.innerText }]; - - case 'DIV': - if (el.hasAttribute('data-mx-maths')) { - return [{ type: 'displayMath', content: el.getAttribute('data-mx-maths') }]; - } - return mapChildren(el); - case 'SPAN': - if (el.hasAttribute('data-mx-spoiler')) { - return [{ type: 'spoiler', reason: el.getAttribute('data-mx-spoiler'), content: mapChildren(el) }]; - } - if (el.hasAttribute('data-mx-maths')) { - return [{ type: 'inlineMath', content: el.getAttribute('data-mx-maths') }]; - } - return mapChildren(el); - default: - return mapChildren(el); - } -} - -function mapNode(n) { - switch (n.nodeType) { - case Node.TEXT_NODE: - return [{ type: 'text', content: n.textContent }]; - case Node.ELEMENT_NODE: - return mapElement(n); - default: - return []; - } -} - -function mapChildren(n) { - return Array.from(n.childNodes).reduce((ast, childN) => { - ast.push(...mapNode(childN)); - return ast; - }, []); -} - -function render(content, state, plainOut, htmlOut) { - let c = content; - if (content.length === 1 && content[0].type === 'paragraph') { - c = c[0].content; - } - - const plainStr = plainOut(c, state).trim(); - if (state.onlyPlain) return { plain: plainStr }; - - const htmlStr = htmlOut(c, state); - - const plainHtml = htmlStr.replace(/
      /g, '\n').replace(/<\/p>

      /g, '\n\n').replace(/<\/?p>/g, ''); - const onlyPlain = sanitizeText(plainStr) === plainHtml; - - return { - onlyPlain, - plain: plainStr, - html: htmlStr, - }; -} - -const plainParser = parserFor(plainRules); -const plainPlainOut = outputFor(plainRules, 'plain'); -const plainHtmlOut = outputFor(plainRules, 'html'); - -const mdParser = parserFor(markdownRules); -const mdPlainOut = outputFor(markdownRules, 'plain'); -const mdHtmlOut = outputFor(markdownRules, 'html'); - -export function plain(source, state) { - return render(plainParser(source, state), state, plainPlainOut, plainHtmlOut); -} - -export function markdown(source, state) { - return render(mdParser(source, state), state, mdPlainOut, mdHtmlOut); -} - -export function html(source, state) { - const el = document.createElement('template'); - el.innerHTML = source; - return render(mapChildren(el.content), state, mdPlainOut, mdHtmlOut); -} diff --git a/src/util/matrixUtil.js b/src/util/matrixUtil.js index a776fb2be..74e56ec76 100644 --- a/src/util/matrixUtil.js +++ b/src/util/matrixUtil.js @@ -89,20 +89,6 @@ export function trimHTMLReply(html) { return html.slice(i + suffix.length); } -export function hasDMWith(userId) { - const mx = initMatrix.matrixClient; - const directIds = [...initMatrix.roomList.directs]; - - return directIds.find((roomId) => { - const dRoom = mx.getRoom(roomId); - const roomMembers = dRoom.getMembers(); - if (roomMembers.length <= 2 && dRoom.getMember(userId)) { - return true; - } - return false; - }); -} - export function joinRuleToIconSrc(joinRule, isSpace) { return ({ restricted: () => (isSpace ? SpaceIC : HashIC), diff --git a/src/util/mimetypes.js b/src/util/mimetypes.js deleted file mode 100644 index bf7efbce2..000000000 --- a/src/util/mimetypes.js +++ /dev/null @@ -1,39 +0,0 @@ -// https://github.com/matrix-org/matrix-react-sdk/blob/cd15e08fc285da42134817cce50de8011809cd53/src/utils/blobs.ts -export const ALLOWED_BLOB_MIMETYPES = [ - 'image/jpeg', - 'image/gif', - 'image/png', - 'image/apng', - 'image/webp', - 'image/avif', - - 'video/mp4', - 'video/webm', - 'video/ogg', - 'video/quicktime', - - 'audio/mp4', - 'audio/webm', - 'audio/aac', - 'audio/mpeg', - 'audio/ogg', - 'audio/wave', - 'audio/wav', - 'audio/x-wav', - 'audio/x-pn-wav', - 'audio/flac', - 'audio/x-flac', -]; - -export function getBlobSafeMimeType(mimetype) { - if (typeof mimetype !== 'string') return 'application/octet-stream'; - const [type] = mimetype.split(';'); - if (!ALLOWED_BLOB_MIMETYPES.includes(type)) { - return 'application/octet-stream'; - } - // Required for Chromium browsers - if (type === 'video/quicktime') { - return 'video/mp4'; - } - return type; -} diff --git a/src/util/sanitize.js b/src/util/sanitize.js deleted file mode 100644 index 3723a11b3..000000000 --- a/src/util/sanitize.js +++ /dev/null @@ -1,140 +0,0 @@ -import sanitizeHtml from 'sanitize-html'; - -const MAX_TAG_NESTING = 100; -let mx = null; - -const permittedHtmlTags = [ - 'font', 'del', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', - 'blockquote', 'p', 'a', 'ul', 'ol', 'sup', 'sub', - 'li', 'b', 'i', 'u', 'strong', 'em', 'strike', 's', 'code', - 'hr', 'br', 'div', 'table', 'thead', 'tbody', 'tr', 'th', - 'td', 'caption', 'pre', 'span', 'img', 'details', 'summary', -]; - -const urlSchemes = ['https', 'http', 'ftp', 'mailto', 'magnet']; - -const permittedTagToAttributes = { - font: ['style', 'data-mx-bg-color', 'data-mx-color', 'color'], - span: ['style', 'data-mx-bg-color', 'data-mx-color', 'data-mx-spoiler', 'data-mx-maths', 'data-mx-pill', 'data-mx-ping'], - div: ['data-mx-maths'], - a: ['name', 'target', 'href', 'rel'], - img: ['width', 'height', 'alt', 'title', 'src', 'data-mx-emoticon'], - ol: ['start'], - code: ['class'], -}; - -function transformFontTag(tagName, attribs) { - return { - tagName, - attribs: { - ...attribs, - style: `background-color: ${attribs['data-mx-bg-color']}; color: ${attribs['data-mx-color']}`, - }, - }; -} - -function transformSpanTag(tagName, attribs) { - return { - tagName, - attribs: { - ...attribs, - style: `background-color: ${attribs['data-mx-bg-color']}; color: ${attribs['data-mx-color']}`, - }, - }; -} - -function transformATag(tagName, attribs) { - const userLink = decodeURIComponent(attribs.href).match(/^https?:\/\/matrix.to\/#\/(@.+:.+)/); - if (userLink !== null) { - // convert user link to pill - const userId = userLink[1]; - const pill = { - tagName: 'span', - attribs: { - 'data-mx-pill': userId, - }, - }; - if (userId === mx?.getUserId()) { - pill.attribs['data-mx-ping'] = undefined; - } - return pill; - } - - const rex = /[\u{1f300}-\u{1f5ff}\u{1f900}-\u{1f9ff}\u{1f600}-\u{1f64f}\u{1f680}-\u{1f6ff}\u{2600}-\u{26ff}\u{2700}-\u{27bf}\u{1f1e6}-\u{1f1ff}\u{1f191}-\u{1f251}\u{1f004}\u{1f0cf}\u{1f170}-\u{1f171}\u{1f17e}-\u{1f17f}\u{1f18e}\u{3030}\u{2b50}\u{2b55}\u{2934}-\u{2935}\u{2b05}-\u{2b07}\u{2b1b}-\u{2b1c}\u{3297}\u{3299}\u{303d}\u{00a9}\u{00ae}\u{2122}\u{23f3}\u{24c2}\u{23e9}-\u{23ef}\u{25b6}\u{23f8}-\u{23fa}]/ug; - const newHref = attribs.href.replace(rex, (match) => `[e-${match.codePointAt(0).toString(16)}]`); - - return { - tagName, - attribs: { - ...attribs, - href: newHref, - rel: 'noopener', - target: '_blank', - }, - }; -} - -function transformImgTag(tagName, attribs) { - const { src } = attribs; - if (src.startsWith('mxc://') === false) { - return { - tagName: 'a', - attribs: { - href: src, - rel: 'noopener', - target: '_blank', - }, - text: attribs.alt || src, - }; - } - return { - tagName, - attribs: { - ...attribs, - src: mx?.mxcUrlToHttp(src), - }, - }; -} - -export function sanitizeCustomHtml(matrixClient, body) { - mx = matrixClient; - return sanitizeHtml(body, { - allowedTags: permittedHtmlTags, - allowedAttributes: permittedTagToAttributes, - disallowedTagsMode: 'discard', - allowedSchemes: urlSchemes, - allowedSchemesByTag: { - a: urlSchemes, - }, - allowedSchemesAppliedToAttributes: ['href'], - allowProtocolRelative: false, - allowedClasses: { - code: ['language-*'], - }, - allowedStyles: { - '*': { - color: [/^#(?:[0-9a-fA-F]{3}){1,2}$/], - 'background-color': [/^#(?:[0-9a-fA-F]{3}){1,2}$/], - }, - }, - transformTags: { - font: transformFontTag, - span: transformSpanTag, - a: transformATag, - img: transformImgTag, - }, - nonTextTags: ['style', 'script', 'textarea', 'option', 'noscript', 'mx-reply'], - nestingLimit: MAX_TAG_NESTING, - }); -} - -export function sanitizeText(body) { - const tagsToReplace = { - '&': '&', - '<': '<', - '>': '>', - '"': '"', - "'": ''', - }; - return body.replace(/[&<>'"]/g, (tag) => tagsToReplace[tag] || tag); -} diff --git a/src/util/twemojify.jsx b/src/util/twemojify.jsx deleted file mode 100644 index ad203a916..000000000 --- a/src/util/twemojify.jsx +++ /dev/null @@ -1,31 +0,0 @@ -/* eslint-disable import/prefer-default-export */ -import linkifyHtml from 'linkify-html'; -import parse from 'html-react-parser'; -import { sanitizeText } from './sanitize'; - -export const TWEMOJI_BASE_URL = 'https://cdn.jsdelivr.net/gh/twitter/twemoji@14.0.2/assets/'; - -/** - * @param {string} text - text to twemojify - * @param {object|undefined} opts - DEPRECATED - options for tweomoji.parse - * @param {boolean} [linkify=false] - convert links to html tags (default: false) - * @param {boolean} [sanitize=true] - sanitize html text (default: true) - * @param {boolean} [maths=false] - DEPRECATED - render maths (default: false) - * @returns React component - */ -export function twemojify(text, opts, linkify = false, sanitize = true) { - if (typeof text !== 'string') return text; - let content = text; - - if (sanitize) { - content = sanitizeText(content); - } - - if (linkify) { - content = linkifyHtml(content, { - target: '_blank', - rel: 'noreferrer noopener', - }); - } - return parse(content); -} From e058a9ae6cf3980617c635467db728b7f78ddaa7 Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Tue, 9 Jul 2024 18:20:33 +0530 Subject: [PATCH 1152/1531] fix notification, favicon and sound (#1802) --- src/app/pages/client/ClientNonUIFeatures.tsx | 26 ++++++++++++++------ 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/src/app/pages/client/ClientNonUIFeatures.tsx b/src/app/pages/client/ClientNonUIFeatures.tsx index 27d1ae40d..947764ca4 100644 --- a/src/app/pages/client/ClientNonUIFeatures.tsx +++ b/src/app/pages/client/ClientNonUIFeatures.tsx @@ -6,6 +6,8 @@ import { roomToUnreadAtom, unreadEqual, unreadInfoToUnread } from '../../state/r import LogoSVG from '../../../../public/res/svg/cinny.svg'; import LogoUnreadSVG from '../../../../public/res/svg/cinny-unread.svg'; import LogoHighlightSVG from '../../../../public/res/svg/cinny-highlight.svg'; +import NotificationSound from '../../../../public/sound/notification.ogg'; +import InviteSound from '../../../../public/sound/invite.ogg'; import { setFavicon } from '../../utils/dom'; import { useSetting } from '../../state/hooks/settings'; import { settingsAtom } from '../../state/settings'; @@ -28,14 +30,21 @@ function FaviconUpdater() { const roomToUnread = useAtomValue(roomToUnreadAtom); useEffect(() => { - if (roomToUnread.size === 0) { - setFavicon(LogoSVG); - } else { - const highlight = Array.from(roomToUnread.entries()).find( - ([, unread]) => unread.highlight > 0 - ); + let notification = false; + let highlight = false; + roomToUnread.forEach((unread) => { + if (unread.total > 0) { + notification = true; + } + if (unread.highlight > 0) { + highlight = true; + } + }); + if (notification) { setFavicon(highlight ? LogoHighlightSVG : LogoUnreadSVG); + } else { + setFavicon(LogoSVG); } }, [roomToUnread]); @@ -88,7 +97,7 @@ function InviteNotifications() { return ( // eslint-disable-next-line jsx-a11y/media-has-caption ); } @@ -168,6 +177,7 @@ function MessageNotifications() { const cachedUnreadInfo = unreadCacheRef.current.get(room.roomId); unreadCacheRef.current.set(room.roomId, unreadInfo); + if (unreadInfo.total === 0) return; if ( cachedUnreadInfo && unreadEqual(unreadInfoToUnread(cachedUnreadInfo), unreadInfoToUnread(unreadInfo)) @@ -210,7 +220,7 @@ function MessageNotifications() { return ( // eslint-disable-next-line jsx-a11y/media-has-caption ); } From 7c795b800d8ae9cd6892ee61cfdf95c955ce0cb3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 Jul 2024 23:23:18 +1000 Subject: [PATCH 1153/1531] Bump softprops/action-gh-release from 2.0.5 to 2.0.6 (#1785) Bumps [softprops/action-gh-release](https://github.com/softprops/action-gh-release) from 2.0.5 to 2.0.6. - [Release notes](https://github.com/softprops/action-gh-release/releases) - [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md) - [Commits](https://github.com/softprops/action-gh-release/compare/69320dbe05506a9a39fc8ae11030b214ec2d1f87...a74c6b72af54cfa997e81df42d94703d6313a2d0) --- updated-dependencies: - dependency-name: softprops/action-gh-release dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/prod-deploy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/prod-deploy.yml b/.github/workflows/prod-deploy.yml index 227b96c7b..46766e96d 100644 --- a/.github/workflows/prod-deploy.yml +++ b/.github/workflows/prod-deploy.yml @@ -52,7 +52,7 @@ jobs: gpg --export | xxd -p echo '${{ secrets.GNUPG_PASSPHRASE }}' | gpg --batch --yes --pinentry-mode loopback --passphrase-fd 0 --armor --detach-sign cinny-${{ steps.vars.outputs.tag }}.tar.gz - name: Upload tagged release - uses: softprops/action-gh-release@69320dbe05506a9a39fc8ae11030b214ec2d1f87 + uses: softprops/action-gh-release@a74c6b72af54cfa997e81df42d94703d6313a2d0 with: files: | cinny-${{ steps.vars.outputs.tag }}.tar.gz From 9db81d191380fe3a5bc88ef62a3b9235c0b462c5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 Jul 2024 23:23:56 +1000 Subject: [PATCH 1154/1531] Bump actions/upload-artifact from 4.3.3 to 4.3.4 (#1797) Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4.3.3 to 4.3.4. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/v4.3.3...v4.3.4) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build-pull-request.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-pull-request.yml b/.github/workflows/build-pull-request.yml index 95a9e8ef5..fd8741a2f 100644 --- a/.github/workflows/build-pull-request.yml +++ b/.github/workflows/build-pull-request.yml @@ -25,7 +25,7 @@ jobs: NODE_OPTIONS: '--max_old_space_size=4096' run: npm run build - name: Upload artifact - uses: actions/upload-artifact@v4.3.3 + uses: actions/upload-artifact@v4.3.4 with: name: preview path: dist @@ -33,7 +33,7 @@ jobs: - name: Save pr number run: echo ${PR_NUMBER} > ./pr.txt - name: Upload pr number - uses: actions/upload-artifact@v4.3.3 + uses: actions/upload-artifact@v4.3.4 with: name: pr path: ./pr.txt From f1668999a5af86f7705b76c13414127d968acc7a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 Jul 2024 23:24:56 +1000 Subject: [PATCH 1155/1531] Bump docker/setup-qemu-action from 3.0.0 to 3.1.0 (#1798) Bumps [docker/setup-qemu-action](https://github.com/docker/setup-qemu-action) from 3.0.0 to 3.1.0. - [Release notes](https://github.com/docker/setup-qemu-action/releases) - [Commits](https://github.com/docker/setup-qemu-action/compare/v3.0.0...v3.1.0) --- updated-dependencies: - dependency-name: docker/setup-qemu-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/prod-deploy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/prod-deploy.yml b/.github/workflows/prod-deploy.yml index 46766e96d..3dfa240b9 100644 --- a/.github/workflows/prod-deploy.yml +++ b/.github/workflows/prod-deploy.yml @@ -68,7 +68,7 @@ jobs: - name: Checkout repository uses: actions/checkout@v4.1.7 - name: Set up QEMU - uses: docker/setup-qemu-action@v3.0.0 + uses: docker/setup-qemu-action@v3.1.0 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3.3.0 - name: Login to Docker Hub From 65ad07087831d17f2d7117da833ca49a41f601df Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 Jul 2024 23:25:38 +1000 Subject: [PATCH 1156/1531] Bump docker/build-push-action from 6.0.0 to 6.3.0 (#1799) Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 6.0.0 to 6.3.0. - [Release notes](https://github.com/docker/build-push-action/releases) - [Commits](https://github.com/docker/build-push-action/compare/v6.0.0...v6.3.0) --- updated-dependencies: - dependency-name: docker/build-push-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/docker-pr.yml | 2 +- .github/workflows/prod-deploy.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docker-pr.yml b/.github/workflows/docker-pr.yml index a45917ba5..d47d2c2fe 100644 --- a/.github/workflows/docker-pr.yml +++ b/.github/workflows/docker-pr.yml @@ -13,7 +13,7 @@ jobs: - name: Checkout repository uses: actions/checkout@v4.1.7 - name: Build Docker image - uses: docker/build-push-action@v6.0.0 + uses: docker/build-push-action@v6.3.0 with: context: . push: false diff --git a/.github/workflows/prod-deploy.yml b/.github/workflows/prod-deploy.yml index 3dfa240b9..b1aeee741 100644 --- a/.github/workflows/prod-deploy.yml +++ b/.github/workflows/prod-deploy.yml @@ -90,7 +90,7 @@ jobs: ${{ secrets.DOCKER_USERNAME }}/cinny ghcr.io/${{ github.repository }} - name: Build and push Docker image - uses: docker/build-push-action@v6.0.0 + uses: docker/build-push-action@v6.3.0 with: context: . platforms: linux/amd64,linux/arm64 From fc2b5744f4f079a6d3fb3dc5f2c7a31b153a657b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 Jul 2024 23:36:45 +1000 Subject: [PATCH 1157/1531] Bump react-error-boundary from 4.0.10 to 4.0.13 (#1664) Bumps [react-error-boundary](https://github.com/bvaughn/react-error-boundary) from 4.0.10 to 4.0.13. - [Release notes](https://github.com/bvaughn/react-error-boundary/releases) - [Commits](https://github.com/bvaughn/react-error-boundary/compare/4.0.10...4.0.13) --- updated-dependencies: - dependency-name: react-error-boundary dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index ab70f0fbb..7174ee7a9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -52,7 +52,7 @@ "react-autosize-textarea": "7.1.0", "react-blurhash": "0.2.0", "react-dom": "18.2.0", - "react-error-boundary": "4.0.10", + "react-error-boundary": "4.0.13", "react-google-recaptcha": "2.1.0", "react-modal": "3.16.1", "react-range": "1.8.14", @@ -7678,9 +7678,9 @@ } }, "node_modules/react-error-boundary": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-4.0.10.tgz", - "integrity": "sha512-pvVKdi77j2OoPHo+p3rorgE43OjDWiqFkaqkJz8sJKK6uf/u8xtzuaVfj5qJ2JnDLIgF1De3zY5AJDijp+LVPA==", + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-4.0.13.tgz", + "integrity": "sha512-b6PwbdSv8XeOSYvjt8LpgpKrZ0yGdtZokYwkwV2wlcZbxgopHX/hgPl5VgpnoVOWd868n1hktM8Qm4b+02MiLQ==", "dependencies": { "@babel/runtime": "^7.12.5" }, diff --git a/package.json b/package.json index a4bf6f34b..6e573c99e 100644 --- a/package.json +++ b/package.json @@ -63,7 +63,7 @@ "react-autosize-textarea": "7.1.0", "react-blurhash": "0.2.0", "react-dom": "18.2.0", - "react-error-boundary": "4.0.10", + "react-error-boundary": "4.0.13", "react-google-recaptcha": "2.1.0", "react-modal": "3.16.1", "react-range": "1.8.14", From 4b461f87ff9a84a6a09628b71b52a1d7a855547d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 Jul 2024 23:40:46 +1000 Subject: [PATCH 1158/1531] Bump linkifyjs from 4.0.2 to 4.1.3 (#1672) Bumps [linkifyjs](https://github.com/Hypercontext/linkifyjs/tree/HEAD/packages/linkifyjs) from 4.0.2 to 4.1.3. - [Release notes](https://github.com/Hypercontext/linkifyjs/releases) - [Changelog](https://github.com/Hypercontext/linkifyjs/blob/main/CHANGELOG.md) - [Commits](https://github.com/Hypercontext/linkifyjs/commits/v4.1.3/packages/linkifyjs) --- updated-dependencies: - dependency-name: linkifyjs dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7174ee7a9..b38a3b02e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -41,7 +41,7 @@ "is-hotkey": "0.2.0", "jotai": "2.6.0", "linkify-react": "4.1.1", - "linkifyjs": "4.0.2", + "linkifyjs": "4.1.3", "matrix-js-sdk": "29.1.0", "millify": "6.1.0", "pdfjs-dist": "4.2.67", @@ -6771,9 +6771,9 @@ } }, "node_modules/linkifyjs": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/linkifyjs/-/linkifyjs-4.0.2.tgz", - "integrity": "sha512-/VSoCZiglX0VMsXmL5PN3lRg45M86lrD9PskdkA2abWaTKap1bIcJ11LS4EE55bcUl9ZOR4eZ792UtQ9E/5xLA==" + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/linkifyjs/-/linkifyjs-4.1.3.tgz", + "integrity": "sha512-auMesunaJ8yfkHvK4gfg1K0SaKX/6Wn9g2Aac/NwX+l5VdmFZzo/hdPGxEOETj+ryRa4/fiOPjeeKURSAJx1sg==" }, "node_modules/locate-path": { "version": "6.0.0", diff --git a/package.json b/package.json index 6e573c99e..54fb35b88 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,7 @@ "is-hotkey": "0.2.0", "jotai": "2.6.0", "linkify-react": "4.1.1", - "linkifyjs": "4.0.2", + "linkifyjs": "4.1.3", "matrix-js-sdk": "29.1.0", "millify": "6.1.0", "pdfjs-dist": "4.2.67", From 66478143dff36b10e8d236dd07c9507a2a7a7056 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 Jul 2024 23:43:53 +1000 Subject: [PATCH 1159/1531] Bump linkify-react from 4.1.1 to 4.1.3 (#1742) updated-dependencies: - dependency-name: linkify-react dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index b38a3b02e..a0075c55e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -40,7 +40,7 @@ "immer": "9.0.16", "is-hotkey": "0.2.0", "jotai": "2.6.0", - "linkify-react": "4.1.1", + "linkify-react": "4.1.3", "linkifyjs": "4.1.3", "matrix-js-sdk": "29.1.0", "millify": "6.1.0", @@ -6762,9 +6762,9 @@ } }, "node_modules/linkify-react": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/linkify-react/-/linkify-react-4.1.1.tgz", - "integrity": "sha512-2K9Y1cUdvq40dFWqCJ//X+WP19nlzIVITFGI93RjLnA0M7KbnxQ/ffC3AZIZaEIrLangF9Hjt3i0GQ9/anEG5A==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/linkify-react/-/linkify-react-4.1.3.tgz", + "integrity": "sha512-rhI3zM/fxn5BfRPHfi4r9N7zgac4vOIxub1wHIWXLA5ENTMs+BGaIaFO1D1PhmxgwhIKmJz3H7uCP0Dg5JwSlA==", "peerDependencies": { "linkifyjs": "^4.0.0", "react": ">= 15.0.0" diff --git a/package.json b/package.json index 54fb35b88..9670b9121 100644 --- a/package.json +++ b/package.json @@ -51,7 +51,7 @@ "immer": "9.0.16", "is-hotkey": "0.2.0", "jotai": "2.6.0", - "linkify-react": "4.1.1", + "linkify-react": "4.1.3", "linkifyjs": "4.1.3", "matrix-js-sdk": "29.1.0", "millify": "6.1.0", From e854b883940e07bf343d59a4c30cfd8a6f3e2e0b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 Jul 2024 23:49:06 +1000 Subject: [PATCH 1160/1531] Bump formik from 2.2.9 to 2.4.6 (#1715) Bumps [formik](https://github.com/jaredpalmer/formik) from 2.2.9 to 2.4.6. - [Release notes](https://github.com/jaredpalmer/formik/releases) - [Commits](https://github.com/jaredpalmer/formik/compare/formik@2.2.9...formik@2.4.6) --- updated-dependencies: - dependency-name: formik dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 35 ++++++++++++++++++++++++----------- package.json | 2 +- 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/package-lock.json b/package-lock.json index a0075c55e..e3701207f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -34,7 +34,7 @@ "flux": "4.0.3", "focus-trap-react": "10.0.2", "folds": "2.0.0", - "formik": "2.2.9", + "formik": "2.4.6", "html-dom-parser": "4.0.0", "html-react-parser": "4.2.0", "immer": "9.0.16", @@ -3237,6 +3237,15 @@ "integrity": "sha512-zv9kNf3keYegP5oThGLaPk8E081DFDuwfqjtiTzm6PoxChdJ1raSuADf2YGCVIyrSynLrgc8JWv296s7Q7pQSQ==", "dev": true }, + "node_modules/@types/hoist-non-react-statics": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.5.tgz", + "integrity": "sha512-SbcrWzkKBw2cdwRTwQAswfpB9g9LJWfjtUeW/jvNwbhC8cpmmNYVePa+ncbUe0rGTQ7G3Ff6mYUN2VMfLVr+Sg==", + "dependencies": { + "@types/react": "*", + "hoist-non-react-statics": "^3.3.0" + } + }, "node_modules/@types/is-hotkey": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/@types/is-hotkey/-/is-hotkey-0.1.7.tgz", @@ -3274,14 +3283,12 @@ "node_modules/@types/prop-types": { "version": "15.7.5", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", - "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==", - "dev": true + "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==" }, "node_modules/@types/react": { "version": "18.2.39", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.39.tgz", "integrity": "sha512-Oiw+ppED6IremMInLV4HXGbfbG6GyziY3kqAwJYOR0PNbkYDmLWQA3a95EhdSmamsvbkJN96ZNN+YD+fGjzSBA==", - "dev": true, "dependencies": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -3323,8 +3330,7 @@ "node_modules/@types/scheduler": { "version": "0.16.2", "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", - "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==", - "dev": true + "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==" }, "node_modules/@types/semver": { "version": "7.3.13", @@ -5727,9 +5733,9 @@ } }, "node_modules/formik": { - "version": "2.2.9", - "resolved": "https://registry.npmjs.org/formik/-/formik-2.2.9.tgz", - "integrity": "sha512-LQLcISMmf1r5at4/gyJigGn0gOwFbeEAlji+N9InZF6LIMXnFNkO42sCI8Jt84YZggpD4cPWObAZaxpEFtSzNA==", + "version": "2.4.6", + "resolved": "https://registry.npmjs.org/formik/-/formik-2.4.6.tgz", + "integrity": "sha512-A+2EI7U7aG296q2TLGvNapDNTZp1khVt5Vk0Q/fyfSROss0V/V6+txt2aJnwEos44IxTCW/LYAi/zgWzlevj+g==", "funding": [ { "type": "individual", @@ -5737,18 +5743,24 @@ } ], "dependencies": { + "@types/hoist-non-react-statics": "^3.3.1", "deepmerge": "^2.1.1", "hoist-non-react-statics": "^3.3.0", "lodash": "^4.17.21", "lodash-es": "^4.17.21", "react-fast-compare": "^2.0.1", "tiny-warning": "^1.0.2", - "tslib": "^1.10.0" + "tslib": "^2.0.0" }, "peerDependencies": { "react": ">=16.8.0" } }, + "node_modules/formik/node_modules/tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + }, "node_modules/fs-minipass": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", @@ -8548,7 +8560,8 @@ "node_modules/tslib": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true }, "node_modules/tsutils": { "version": "3.21.0", diff --git a/package.json b/package.json index 9670b9121..607cbcf71 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,7 @@ "flux": "4.0.3", "focus-trap-react": "10.0.2", "folds": "2.0.0", - "formik": "2.2.9", + "formik": "2.4.6", "html-dom-parser": "4.0.0", "html-react-parser": "4.2.0", "immer": "9.0.16", From 653ddd9f11ab8286549855ca71001f7b8440754d Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Wed, 10 Jul 2024 18:44:28 +0530 Subject: [PATCH 1161/1531] fix space lobby button shrink --- src/app/features/lobby/SpaceItem.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/features/lobby/SpaceItem.tsx b/src/app/features/lobby/SpaceItem.tsx index 4924f45b7..e9d9356a9 100644 --- a/src/app/features/lobby/SpaceItem.tsx +++ b/src/app/features/lobby/SpaceItem.tsx @@ -479,7 +479,7 @@ export const SpaceItemCard = as<'div', SpaceItemCardProps>( )} {canEditChild && ( - + {item.parentId === undefined && } From c52c4f7d32e1c23fe9c93a2e8e8ebcef78c0bcd9 Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Sun, 14 Jul 2024 19:51:19 +0530 Subject: [PATCH 1162/1531] fix crash when adding existing room to space (#1806) --- .../molecules/space-add-existing/SpaceAddExisting.jsx | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/app/molecules/space-add-existing/SpaceAddExisting.jsx b/src/app/molecules/space-add-existing/SpaceAddExisting.jsx index 3895ac756..2eb94a5c0 100644 --- a/src/app/molecules/space-add-existing/SpaceAddExisting.jsx +++ b/src/app/molecules/space-add-existing/SpaceAddExisting.jsx @@ -26,6 +26,7 @@ import { useStore } from '../../hooks/useStore'; import { roomToParentsAtom } from '../../state/room/roomToParents'; import { useDirects, useRooms, useSpaces } from '../../state/hooks/roomList'; import { allRoomsAtom } from '../../state/room-list/roomList'; +import { mDirectAtom } from '../../state/mDirectList'; function SpaceAddExistingContent({ roomId, spaces: onlySpaces }) { const mountStore = useStore(roomId); @@ -36,9 +37,10 @@ function SpaceAddExistingContent({ roomId, spaces: onlySpaces }) { const [searchIds, setSearchIds] = useState(null); const mx = initMatrix.matrixClient; const roomIdToParents = useAtomValue(roomToParentsAtom); + const mDirects = useAtomValue(mDirectAtom); const spaces = useSpaces(mx, allRoomsAtom); - const rooms = useRooms(mx, allRoomsAtom); - const directs = useDirects(mx, allRoomsAtom); + const rooms = useRooms(mx, allRoomsAtom, mDirects); + const directs = useDirects(mx, allRoomsAtom, mDirects); useEffect(() => { const roomIds = onlySpaces ? [...spaces] : [...rooms, ...directs]; @@ -152,9 +154,9 @@ function SpaceAddExistingContent({ roomId, spaces: onlySpaces }) { name={room.name} parentName={parents} roomId={rId} - imageSrc={directs.has(rId) ? imageSrc : null} + imageSrc={mDirects.has(rId) ? imageSrc : null} iconSrc={ - directs.has(rId) ? null : joinRuleToIconSrc(room.getJoinRule(), room.isSpaceRoom()) + mDirects.has(rId) ? null : joinRuleToIconSrc(room.getJoinRule(), room.isSpaceRoom()) } isUnread={false} notificationCount={0} From c4abe39375695bf0f643ec218fdd20e4e18f47bf Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Thu, 18 Jul 2024 18:50:20 +0530 Subject: [PATCH 1163/1531] Make hotkeys work again (#1819) --- src/app/components/Pdf-viewer/PdfViewer.tsx | 2 + src/app/components/UIAFlowOverlay.tsx | 3 +- src/app/components/editor/Editor.preview.tsx | 2 + src/app/components/editor/Toolbar.tsx | 2 + .../editor/autocomplete/AutocompleteMenu.tsx | 3 +- src/app/components/emoji-board/EmojiBoard.tsx | 3 +- .../leave-room-prompt/LeaveRoomPrompt.tsx | 2 + .../leave-space-prompt/LeaveSpacePrompt.tsx | 2 + .../message/content/FileContent.tsx | 3 + .../message/content/ImageContent.tsx | 2 + src/app/components/room-card/RoomCard.tsx | 4 +- src/app/features/lobby/HierarchyItemMenu.tsx | 2 + src/app/features/lobby/LobbyHeader.tsx | 2 + src/app/features/lobby/LobbyHero.tsx | 3 +- src/app/features/lobby/RoomItem.tsx | 3 +- src/app/features/lobby/SpaceItem.tsx | 3 + .../features/message-search/SearchFilters.tsx | 3 + src/app/features/room-nav/RoomNavItem.tsx | 2 + src/app/features/room/MembersDrawer.tsx | 3 + src/app/features/room/Room.tsx | 17 +++++- src/app/features/room/RoomView.tsx | 60 +++++++++++++++++-- src/app/features/room/RoomViewFollowing.tsx | 2 + src/app/features/room/RoomViewHeader.tsx | 3 + src/app/features/room/message/Message.tsx | 8 +++ src/app/features/room/message/Reactions.tsx | 2 + src/app/organisms/search/Search.jsx | 25 +++++++- src/app/pages/auth/ServerPicker.tsx | 2 + .../pages/auth/login/PasswordLoginForm.tsx | 2 + src/app/pages/client/ClientRoot.tsx | 2 - src/app/pages/client/direct/Direct.tsx | 2 + src/app/pages/client/explore/Explore.tsx | 2 + src/app/pages/client/explore/Server.tsx | 3 + src/app/pages/client/home/Home.tsx | 2 + src/app/pages/client/inbox/Invites.tsx | 3 +- src/app/pages/client/sidebar/DirectTab.tsx | 2 + src/app/pages/client/sidebar/HomeTab.tsx | 2 + src/app/pages/client/sidebar/SpaceTabs.tsx | 2 + src/app/pages/client/space/Space.tsx | 2 + src/app/utils/keyboard.ts | 5 ++ src/client/event/hotkeys.js | 24 -------- 40 files changed, 182 insertions(+), 39 deletions(-) delete mode 100644 src/client/event/hotkeys.js diff --git a/src/app/components/Pdf-viewer/PdfViewer.tsx b/src/app/components/Pdf-viewer/PdfViewer.tsx index a78c13f2a..9c7fd9804 100644 --- a/src/app/components/Pdf-viewer/PdfViewer.tsx +++ b/src/app/components/Pdf-viewer/PdfViewer.tsx @@ -26,6 +26,7 @@ import * as css from './PdfViewer.css'; import { AsyncStatus } from '../../hooks/useAsyncCallback'; import { useZoom } from '../../hooks/useZoom'; import { createPage, usePdfDocumentLoader, usePdfJSLoader } from '../../plugins/pdfjs-dist'; +import { stopPropagation } from '../../utils/keyboard'; export type PdfViewerProps = { name: string; @@ -201,6 +202,7 @@ export const PdfViewer = as<'div', PdfViewerProps>( initialFocus: false, onDeactivate: () => setJumpAnchor(undefined), clickOutsideDeactivates: true, + escapeDeactivates: stopPropagation, }} >

      diff --git a/src/app/components/UIAFlowOverlay.tsx b/src/app/components/UIAFlowOverlay.tsx index f788eb0fd..dc517b482 100644 --- a/src/app/components/UIAFlowOverlay.tsx +++ b/src/app/components/UIAFlowOverlay.tsx @@ -13,6 +13,7 @@ import { IconButton, } from 'folds'; import FocusTrap from 'focus-trap-react'; +import { stopPropagation } from '../utils/keyboard'; export type UIAFlowOverlayProps = { currentStep: number; @@ -28,7 +29,7 @@ export function UIAFlowOverlay({ }: UIAFlowOverlayProps) { return ( }> - + {children} diff --git a/src/app/components/editor/Editor.preview.tsx b/src/app/components/editor/Editor.preview.tsx index ad67dc127..b760dddcb 100644 --- a/src/app/components/editor/Editor.preview.tsx +++ b/src/app/components/editor/Editor.preview.tsx @@ -14,6 +14,7 @@ import { import { CustomEditor, useEditor } from './Editor'; import { Toolbar } from './Toolbar'; +import { stopPropagation } from '../../utils/keyboard'; export function EditorPreview() { const [open, setOpen] = useState(false); @@ -32,6 +33,7 @@ export function EditorPreview() { initialFocus: false, onDeactivate: () => setOpen(false), clickOutsideDeactivates: true, + escapeDeactivates: stopPropagation, }} > diff --git a/src/app/components/editor/Toolbar.tsx b/src/app/components/editor/Toolbar.tsx index 0c82855d3..e5c7d16e7 100644 --- a/src/app/components/editor/Toolbar.tsx +++ b/src/app/components/editor/Toolbar.tsx @@ -35,6 +35,7 @@ import { isMacOS } from '../../utils/user-agent'; import { KeySymbol } from '../../utils/key-symbol'; import { useSetting } from '../../state/hooks/settings'; import { settingsAtom } from '../../state/settings'; +import { stopPropagation } from '../../utils/keyboard'; function BtnTooltip({ text, shortCode }: { text: string; shortCode?: string }) { return ( @@ -151,6 +152,7 @@ export function HeadingBlockButton() { isKeyForward: (evt: KeyboardEvent) => evt.key === 'ArrowDown' || evt.key === 'ArrowRight', isKeyBackward: (evt: KeyboardEvent) => evt.key === 'ArrowUp' || evt.key === 'ArrowLeft', + escapeDeactivates: stopPropagation, }} > diff --git a/src/app/components/editor/autocomplete/AutocompleteMenu.tsx b/src/app/components/editor/autocomplete/AutocompleteMenu.tsx index fc4327daf..5d2d917ca 100644 --- a/src/app/components/editor/autocomplete/AutocompleteMenu.tsx +++ b/src/app/components/editor/autocomplete/AutocompleteMenu.tsx @@ -4,7 +4,7 @@ import { isKeyHotkey } from 'is-hotkey'; import { Header, Menu, Scroll, config } from 'folds'; import * as css from './AutocompleteMenu.css'; -import { preventScrollWithArrowKey } from '../../../utils/keyboard'; +import { preventScrollWithArrowKey, stopPropagation } from '../../../utils/keyboard'; type AutocompleteMenuProps = { requestClose: () => void; @@ -24,6 +24,7 @@ export function AutocompleteMenu({ headerContent, requestClose, children }: Auto allowOutsideClick: true, isKeyForward: (evt: KeyboardEvent) => isKeyHotkey('arrowdown', evt), isKeyBackward: (evt: KeyboardEvent) => isKeyHotkey('arrowup', evt), + escapeDeactivates: stopPropagation, }} > diff --git a/src/app/components/emoji-board/EmojiBoard.tsx b/src/app/components/emoji-board/EmojiBoard.tsx index 408ce85dd..53172efdf 100644 --- a/src/app/components/emoji-board/EmojiBoard.tsx +++ b/src/app/components/emoji-board/EmojiBoard.tsx @@ -37,7 +37,7 @@ import * as css from './EmojiBoard.css'; import { EmojiGroupId, IEmoji, IEmojiGroup, emojiGroups, emojis } from '../../plugins/emoji'; import { IEmojiGroupLabels, useEmojiGroupLabels } from './useEmojiGroupLabels'; import { IEmojiGroupIcons, useEmojiGroupIcons } from './useEmojiGroupIcons'; -import { preventScrollWithArrowKey } from '../../utils/keyboard'; +import { preventScrollWithArrowKey, stopPropagation } from '../../utils/keyboard'; import { useRelevantImagePacks } from '../../hooks/useImagePacks'; import { useMatrixClient } from '../../hooks/useMatrixClient'; import { useRecentEmoji } from '../../hooks/useRecentEmoji'; @@ -775,6 +775,7 @@ export function EmojiBoard({ !editableActiveElement() && isKeyHotkey(['arrowdown', 'arrowright'], evt), isKeyBackward: (evt: KeyboardEvent) => !editableActiveElement() && isKeyHotkey(['arrowup', 'arrowleft'], evt), + escapeDeactivates: stopPropagation, }} > diff --git a/src/app/components/leave-space-prompt/LeaveSpacePrompt.tsx b/src/app/components/leave-space-prompt/LeaveSpacePrompt.tsx index 1132b44df..8709b942c 100644 --- a/src/app/components/leave-space-prompt/LeaveSpacePrompt.tsx +++ b/src/app/components/leave-space-prompt/LeaveSpacePrompt.tsx @@ -19,6 +19,7 @@ import { import { MatrixError } from 'matrix-js-sdk'; import { useMatrixClient } from '../../hooks/useMatrixClient'; import { AsyncStatus, useAsyncCallback } from '../../hooks/useAsyncCallback'; +import { stopPropagation } from '../../utils/keyboard'; type LeaveSpacePromptProps = { roomId: string; @@ -52,6 +53,7 @@ export function LeaveSpacePrompt({ roomId, onDone, onCancel }: LeaveSpacePromptP initialFocus: false, onDeactivate: onCancel, clickOutsideDeactivates: true, + escapeDeactivates: stopPropagation, }} > diff --git a/src/app/components/message/content/FileContent.tsx b/src/app/components/message/content/FileContent.tsx index af064a32e..f09c1e076 100644 --- a/src/app/components/message/content/FileContent.tsx +++ b/src/app/components/message/content/FileContent.tsx @@ -29,6 +29,7 @@ import { mimeTypeToExt, } from '../../../utils/mimeTypes'; import * as css from './style.css'; +import { stopPropagation } from '../../../utils/keyboard'; const renderErrorButton = (retry: () => void, text: string) => ( setTextViewer(false), clickOutsideDeactivates: true, + escapeDeactivates: stopPropagation, }} > setPdfViewer(false), clickOutsideDeactivates: true, + escapeDeactivates: stopPropagation, }} > ( initialFocus: false, onDeactivate: () => setViewer(false), clickOutsideDeactivates: true, + escapeDeactivates: stopPropagation, }} > @@ -236,6 +237,7 @@ export const RoomCard = as<'div', RoomCardProps>( initialFocus: false, clickOutsideDeactivates: true, onDeactivate: closeTopic, + escapeDeactivates: stopPropagation, }} > {renderTopicViewer(roomName, roomTopic, closeTopic)} diff --git a/src/app/features/lobby/HierarchyItemMenu.tsx b/src/app/features/lobby/HierarchyItemMenu.tsx index 489bb9bad..30a4f632e 100644 --- a/src/app/features/lobby/HierarchyItemMenu.tsx +++ b/src/app/features/lobby/HierarchyItemMenu.tsx @@ -27,6 +27,7 @@ import { AsyncStatus, useAsyncCallback } from '../../hooks/useAsyncCallback'; import { UseStateProvider } from '../../components/UseStateProvider'; import { LeaveSpacePrompt } from '../../components/leave-space-prompt'; import { LeaveRoomPrompt } from '../../components/leave-room-prompt'; +import { stopPropagation } from '../../utils/keyboard'; type HierarchyItemWithParent = HierarchyItem & { parentId: string; @@ -227,6 +228,7 @@ export function HierarchyItemMenu({ clickOutsideDeactivates: true, isKeyForward: (evt: KeyboardEvent) => evt.key === 'ArrowDown', isKeyBackward: (evt: KeyboardEvent) => evt.key === 'ArrowUp', + escapeDeactivates: stopPropagation, }} > diff --git a/src/app/features/lobby/LobbyHeader.tsx b/src/app/features/lobby/LobbyHeader.tsx index a23faada8..e01d3ad50 100644 --- a/src/app/features/lobby/LobbyHeader.tsx +++ b/src/app/features/lobby/LobbyHeader.tsx @@ -30,6 +30,7 @@ import { openInviteUser, openSpaceSettings } from '../../../client/action/naviga import { IPowerLevels, usePowerLevelsAPI } from '../../hooks/usePowerLevels'; import { UseStateProvider } from '../../components/UseStateProvider'; import { LeaveSpacePrompt } from '../../components/leave-space-prompt'; +import { stopPropagation } from '../../utils/keyboard'; type LobbyMenuProps = { roomId: string; @@ -197,6 +198,7 @@ export function LobbyHeader({ showProfile, powerLevels }: LobbyHeaderProps) { clickOutsideDeactivates: true, isKeyForward: (evt: KeyboardEvent) => evt.key === 'ArrowDown', isKeyBackward: (evt: KeyboardEvent) => evt.key === 'ArrowUp', + escapeDeactivates: stopPropagation, }} > setViewTopic(false), + escapeDeactivates: stopPropagation, }} > setView(false), + escapeDeactivates: stopPropagation, }} > evt.key === 'ArrowDown', isKeyBackward: (evt: KeyboardEvent) => evt.key === 'ArrowUp', + escapeDeactivates: stopPropagation, }} > @@ -338,6 +340,7 @@ function AddSpaceButton({ item }: { item: HierarchyItem }) { clickOutsideDeactivates: true, isKeyForward: (evt: KeyboardEvent) => evt.key === 'ArrowDown', isKeyBackward: (evt: KeyboardEvent) => evt.key === 'ArrowUp', + escapeDeactivates: stopPropagation, }} > diff --git a/src/app/features/message-search/SearchFilters.tsx b/src/app/features/message-search/SearchFilters.tsx index 5de188d4e..929dd1e91 100644 --- a/src/app/features/message-search/SearchFilters.tsx +++ b/src/app/features/message-search/SearchFilters.tsx @@ -38,6 +38,7 @@ import { } from '../../hooks/useAsyncSearch'; import { DebounceOptions, useDebounce } from '../../hooks/useDebounce'; import { VirtualTile } from '../../components/virtualizer'; +import { stopPropagation } from '../../utils/keyboard'; type OrderButtonProps = { order?: string; @@ -66,6 +67,7 @@ function OrderButton({ order, onChange }: OrderButtonProps) { initialFocus: false, onDeactivate: () => setMenuAnchor(undefined), clickOutsideDeactivates: true, + escapeDeactivates: stopPropagation, }} > @@ -202,6 +204,7 @@ function SelectRoomButton({ roomList, selectedRooms, onChange }: SelectRoomButto initialFocus: false, onDeactivate: () => setMenuAnchor(undefined), clickOutsideDeactivates: true, + escapeDeactivates: stopPropagation, }} > diff --git a/src/app/features/room-nav/RoomNavItem.tsx b/src/app/features/room-nav/RoomNavItem.tsx index fce623750..8ecc81a31 100644 --- a/src/app/features/room-nav/RoomNavItem.tsx +++ b/src/app/features/room-nav/RoomNavItem.tsx @@ -36,6 +36,7 @@ import { LeaveRoomPrompt } from '../../components/leave-room-prompt'; import { useClientConfig } from '../../hooks/useClientConfig'; import { useRoomTypingMember } from '../../hooks/useRoomTypingMembers'; import { TypingIndicator } from '../../components/typing-indicator'; +import { stopPropagation } from '../../utils/keyboard'; type RoomNavItemMenuProps = { room: Room; @@ -269,6 +270,7 @@ export function RoomNavItem({ clickOutsideDeactivates: true, isKeyForward: (evt: KeyboardEvent) => evt.key === 'ArrowDown', isKeyBackward: (evt: KeyboardEvent) => evt.key === 'ArrowUp', + escapeDeactivates: stopPropagation, }} > m.membership === Membership.Join, @@ -300,6 +301,7 @@ export function MembersDrawer({ room }: MembersDrawerProps) { clickOutsideDeactivates: true, isKeyForward: (evt: KeyboardEvent) => evt.key === 'ArrowDown', isKeyBackward: (evt: KeyboardEvent) => evt.key === 'ArrowUp', + escapeDeactivates: stopPropagation, }} > @@ -358,6 +360,7 @@ export function MembersDrawer({ room }: MembersDrawerProps) { clickOutsideDeactivates: true, isKeyForward: (evt: KeyboardEvent) => evt.key === 'ArrowDown', isKeyBackward: (evt: KeyboardEvent) => evt.key === 'ArrowUp', + escapeDeactivates: stopPropagation, }} > diff --git a/src/app/features/room/Room.tsx b/src/app/features/room/Room.tsx index 764e9686f..fd578ec6c 100644 --- a/src/app/features/room/Room.tsx +++ b/src/app/features/room/Room.tsx @@ -1,6 +1,7 @@ -import React from 'react'; +import React, { useCallback } from 'react'; import { Box, Line } from 'folds'; import { useParams } from 'react-router-dom'; +import { isKeyHotkey } from 'is-hotkey'; import { RoomView } from './RoomView'; import { MembersDrawer } from './MembersDrawer'; import { ScreenSize, useScreenSizeContext } from '../../hooks/useScreenSize'; @@ -8,6 +9,8 @@ import { useSetting } from '../../state/hooks/settings'; import { settingsAtom } from '../../state/settings'; import { PowerLevelsContextProvider, usePowerLevels } from '../../hooks/usePowerLevels'; import { useRoom } from '../../hooks/useRoom'; +import { useKeyDown } from '../../hooks/useKeyDown'; +import { markAsRead } from '../../../client/action/notifications'; export function Room() { const { eventId } = useParams(); @@ -17,6 +20,18 @@ export function Room() { const screenSize = useScreenSizeContext(); const powerLevels = usePowerLevels(room); + useKeyDown( + window, + useCallback( + (evt) => { + if (isKeyHotkey('escape', evt)) { + markAsRead(room.roomId); + } + }, + [room.roomId] + ) + ); + return ( diff --git a/src/app/features/room/RoomView.tsx b/src/app/features/room/RoomView.tsx index fe145b37a..84162fcc1 100644 --- a/src/app/features/room/RoomView.tsx +++ b/src/app/features/room/RoomView.tsx @@ -1,7 +1,8 @@ -import React, { useRef } from 'react'; +import React, { useCallback, useRef } from 'react'; import { Box, Text, config } from 'folds'; import { EventType, Room } from 'matrix-js-sdk'; - +import { ReactEditor } from 'slate-react'; +import { isKeyHotkey } from 'is-hotkey'; import { useStateEvent } from '../../hooks/useStateEvent'; import { StateEvent } from '../../../types/matrix/room'; import { usePowerLevelsAPI, usePowerLevelsContext } from '../../hooks/usePowerLevels'; @@ -15,10 +16,42 @@ import { RoomInput } from './RoomInput'; import { RoomViewFollowing } from './RoomViewFollowing'; import { Page } from '../../components/page'; import { RoomViewHeader } from './RoomViewHeader'; +import { useKeyDown } from '../../hooks/useKeyDown'; +import { editableActiveElement } from '../../utils/dom'; +import navigation from '../../../client/state/navigation'; + +const shouldFocusMessageField = (evt: KeyboardEvent): boolean => { + const { code } = evt; + console.log(code); + if (evt.metaKey || evt.altKey || evt.ctrlKey) { + return false; + } + // do not focus on F keys + if (/^F\d+$/.test(code)) return false; + + // do not focus on numlock/scroll lock + if ( + code.startsWith('OS') || + code.startsWith('Meta') || + code.startsWith('Shift') || + code.startsWith('Alt') || + code.startsWith('Control') || + code.startsWith('Arrow') || + code === 'Tab' || + code === 'Space' || + code === 'Enter' || + code === 'NumLock' || + code === 'ScrollLock' + ) { + return false; + } + + return true; +}; export function RoomView({ room, eventId }: { room: Room; eventId?: string }) { - const roomInputRef = useRef(null); - const roomViewRef = useRef(null); + const roomInputRef = useRef(null); + const roomViewRef = useRef(null); const { roomId } = room; const editor = useEditor(); @@ -33,6 +66,25 @@ export function RoomView({ room, eventId }: { room: Room; eventId?: string }) { ? canSendEvent(EventType.RoomMessage, getPowerLevel(myUserId)) : false; + useKeyDown( + window, + useCallback( + (evt) => { + if (editableActiveElement()) return; + if ( + document.body.lastElementChild?.className !== 'ReactModalPortal' || + navigation.isRawModalVisible + ) { + return; + } + if (shouldFocusMessageField(evt) || isKeyHotkey('mod+v')) { + ReactEditor.focus(editor); + } + }, + [editor] + ) + ); + return ( diff --git a/src/app/features/room/RoomViewFollowing.tsx b/src/app/features/room/RoomViewFollowing.tsx index 2f7a583e3..58d3f64f5 100644 --- a/src/app/features/room/RoomViewFollowing.tsx +++ b/src/app/features/room/RoomViewFollowing.tsx @@ -22,6 +22,7 @@ import { useMatrixClient } from '../../hooks/useMatrixClient'; import { useRoomLatestRenderedEvent } from '../../hooks/useRoomLatestRenderedEvent'; import { useRoomEventReaders } from '../../hooks/useRoomEventReaders'; import { EventReaders } from '../../components/event-readers'; +import { stopPropagation } from '../../utils/keyboard'; export type RoomViewFollowingProps = { room: Room; @@ -50,6 +51,7 @@ export const RoomViewFollowing = as<'div', RoomViewFollowingProps>( initialFocus: false, onDeactivate: () => setOpen(false), clickOutsideDeactivates: true, + escapeDeactivates: stopPropagation, }} > diff --git a/src/app/features/room/RoomViewHeader.tsx b/src/app/features/room/RoomViewHeader.tsx index 61c730f7a..aa267c537 100644 --- a/src/app/features/room/RoomViewHeader.tsx +++ b/src/app/features/room/RoomViewHeader.tsx @@ -57,6 +57,7 @@ import { useRoomAvatar, useRoomName, useRoomTopic } from '../../hooks/useRoomMet import { mDirectAtom } from '../../state/mDirectList'; import { useClientConfig } from '../../hooks/useClientConfig'; import { ScreenSize, useScreenSizeContext } from '../../hooks/useScreenSize'; +import { stopPropagation } from '../../utils/keyboard'; type RoomMenuProps = { room: Room; @@ -240,6 +241,7 @@ export function RoomViewHeader() { initialFocus: false, clickOutsideDeactivates: true, onDeactivate: () => setViewTopic(false), + escapeDeactivates: stopPropagation, }} > evt.key === 'ArrowDown', isKeyBackward: (evt: KeyboardEvent) => evt.key === 'ArrowUp', + escapeDeactivates: stopPropagation, }} > void; @@ -148,6 +149,7 @@ export const MessageAllReactionItem = as< returnFocusOnDeactivate: false, onDeactivate: () => handleClose(), clickOutsideDeactivates: true, + escapeDeactivates: stopPropagation, }} > @@ -201,6 +203,7 @@ export const MessageReadReceiptItem = as< initialFocus: false, onDeactivate: handleClose, clickOutsideDeactivates: true, + escapeDeactivates: stopPropagation, }} > @@ -278,6 +281,7 @@ export const MessageSourceCodeItem = as< initialFocus: false, onDeactivate: handleClose, clickOutsideDeactivates: true, + escapeDeactivates: stopPropagation, }} > @@ -401,6 +405,7 @@ export const MessageDeleteItem = as< initialFocus: false, onDeactivate: handleClose, clickOutsideDeactivates: true, + escapeDeactivates: stopPropagation, }} > @@ -530,6 +535,7 @@ export const MessageReportItem = as< initialFocus: false, onDeactivate: handleClose, clickOutsideDeactivates: true, + escapeDeactivates: stopPropagation, }} > @@ -875,6 +881,7 @@ export const Message = as<'div', MessageProps>( clickOutsideDeactivates: true, isKeyForward: (evt: KeyboardEvent) => evt.key === 'ArrowDown', isKeyBackward: (evt: KeyboardEvent) => evt.key === 'ArrowUp', + escapeDeactivates: stopPropagation, }} > @@ -1089,6 +1096,7 @@ export const Event = as<'div', EventProps>( clickOutsideDeactivates: true, isKeyForward: (evt: KeyboardEvent) => evt.key === 'ArrowDown', isKeyBackward: (evt: KeyboardEvent) => evt.key === 'ArrowUp', + escapeDeactivates: stopPropagation, }} > diff --git a/src/app/features/room/message/Reactions.tsx b/src/app/features/room/message/Reactions.tsx index 728cf8107..a6d7f553b 100644 --- a/src/app/features/room/message/Reactions.tsx +++ b/src/app/features/room/message/Reactions.tsx @@ -21,6 +21,7 @@ import { Reaction, ReactionTooltipMsg } from '../../../components/message'; import { useRelations } from '../../../hooks/useRelations'; import * as css from './styles.css'; import { ReactionViewer } from '../reaction-viewer'; +import { stopPropagation } from '../../../utils/keyboard'; export type ReactionsProps = { room: Room; @@ -105,6 +106,7 @@ export const Reactions = as<'div', ReactionsProps>( returnFocusOnDeactivate: false, onDeactivate: () => setViewer(false), clickOutsideDeactivates: true, + escapeDeactivates: stopPropagation, }} > diff --git a/src/app/organisms/search/Search.jsx b/src/app/organisms/search/Search.jsx index c9d1d991f..0990a03fa 100644 --- a/src/app/organisms/search/Search.jsx +++ b/src/app/organisms/search/Search.jsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect, useRef } from 'react'; +import React, { useState, useEffect, useRef, useCallback } from 'react'; import { useAtomValue } from 'jotai'; import './Search.scss'; @@ -25,6 +25,8 @@ import { roomToUnreadAtom } from '../../state/room/roomToUnread'; import { roomToParentsAtom } from '../../state/room/roomToParents'; import { allRoomsAtom } from '../../state/room-list/roomList'; import { mDirectAtom } from '../../state/mDirectList'; +import { useKeyDown } from '../../hooks/useKeyDown'; +import { openSearch } from '../../../client/action/navigation'; function useVisiblityToggle(setResult) { const [isOpen, setIsOpen] = useState(false); @@ -49,6 +51,27 @@ function useVisiblityToggle(setResult) { } }, [isOpen]); + useKeyDown( + window, + useCallback((event) => { + // Ctrl/Cmd + + if (event.ctrlKey || event.metaKey) { + // open search modal + if (event.key === 'k') { + event.preventDefault(); + // means some menu or modal window is open + if ( + document.body.lastChild.className !== 'ReactModalPortal' || + navigation.isRawModalVisible + ) { + return; + } + openSearch(); + } + } + }, []) + ); + const requestClose = () => setIsOpen(false); return [isOpen, requestClose]; diff --git a/src/app/pages/auth/ServerPicker.tsx b/src/app/pages/auth/ServerPicker.tsx index 18201c98c..a2a78106c 100644 --- a/src/app/pages/auth/ServerPicker.tsx +++ b/src/app/pages/auth/ServerPicker.tsx @@ -22,6 +22,7 @@ import { import FocusTrap from 'focus-trap-react'; import { useDebounce } from '../../hooks/useDebounce'; +import { stopPropagation } from '../../utils/keyboard'; export function ServerPicker({ server, @@ -103,6 +104,7 @@ export function ServerPicker({ clickOutsideDeactivates: true, isKeyForward: (evt: KeyboardEvent) => evt.key === 'ArrowDown', isKeyBackward: (evt: KeyboardEvent) => evt.key === 'ArrowUp', + escapeDeactivates: stopPropagation, }} > diff --git a/src/app/pages/auth/login/PasswordLoginForm.tsx b/src/app/pages/auth/login/PasswordLoginForm.tsx index b9dd14b7a..087d384d5 100644 --- a/src/app/pages/auth/login/PasswordLoginForm.tsx +++ b/src/app/pages/auth/login/PasswordLoginForm.tsx @@ -36,6 +36,7 @@ import { import { PasswordInput } from '../../../components/password-input/PasswordInput'; import { FieldError } from '../FiledError'; import { getResetPasswordPath } from '../../pathUtils'; +import { stopPropagation } from '../../../utils/keyboard'; function UsernameHint({ server }: { server: string }) { const [anchor, setAnchor] = useState(); @@ -54,6 +55,7 @@ function UsernameHint({ server }: { server: string }) { initialFocus: false, onDeactivate: () => setAnchor(undefined), clickOutsideDeactivates: true, + escapeDeactivates: stopPropagation, }} > diff --git a/src/app/pages/client/ClientRoot.tsx b/src/app/pages/client/ClientRoot.tsx index 6a1dbcb16..c36adfc64 100644 --- a/src/app/pages/client/ClientRoot.tsx +++ b/src/app/pages/client/ClientRoot.tsx @@ -1,7 +1,6 @@ import { Box, Spinner, Text } from 'folds'; import React, { ReactNode, useEffect, useState } from 'react'; import initMatrix from '../../../client/initMatrix'; -import { initHotkeys } from '../../../client/event/hotkeys'; import { getSecret } from '../../../client/state/auth'; import { SplashScreen } from '../../components/splash-screen'; import { CapabilitiesAndMediaConfigLoader } from '../../components/CapabilitiesAndMediaConfigLoader'; @@ -47,7 +46,6 @@ export function ClientRoot({ children }: ClientRootProps) { useEffect(() => { const handleStart = () => { - initHotkeys(); setLoading(false); }; initMatrix.once('init_loading_finished', handleStart); diff --git a/src/app/pages/client/direct/Direct.tsx b/src/app/pages/client/direct/Direct.tsx index 673a5d9f1..c62ef1601 100644 --- a/src/app/pages/client/direct/Direct.tsx +++ b/src/app/pages/client/direct/Direct.tsx @@ -44,6 +44,7 @@ import { PageNav, PageNavContent, PageNavHeader } from '../../../components/page import { useClosedNavCategoriesAtom } from '../../../state/hooks/closedNavCategories'; import { useRoomsUnread } from '../../../state/hooks/unread'; import { markAsRead } from '../../../../client/action/notifications'; +import { stopPropagation } from '../../../utils/keyboard'; type DirectMenuProps = { requestClose: () => void; @@ -118,6 +119,7 @@ function DirectHeader() { clickOutsideDeactivates: true, isKeyForward: (evt: KeyboardEvent) => evt.key === 'ArrowDown', isKeyBackward: (evt: KeyboardEvent) => evt.key === 'ArrowUp', + escapeDeactivates: stopPropagation, }} > setMenuAnchor(undefined)} /> diff --git a/src/app/pages/client/explore/Explore.tsx b/src/app/pages/client/explore/Explore.tsx index 67f8dc3f1..420e1a169 100644 --- a/src/app/pages/client/explore/Explore.tsx +++ b/src/app/pages/client/explore/Explore.tsx @@ -36,6 +36,7 @@ import { getMxIdServer } from '../../../utils/matrix'; import { AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback'; import { useNavToActivePathMapper } from '../../../hooks/useNavToActivePathMapper'; import { PageNav, PageNavContent, PageNavHeader } from '../../../components/page'; +import { stopPropagation } from '../../../utils/keyboard'; export function AddServer() { const mx = useMatrixClient(); @@ -80,6 +81,7 @@ export function AddServer() { initialFocus: false, clickOutsideDeactivates: true, onDeactivate: () => setDialog(false), + escapeDeactivates: stopPropagation, }} > diff --git a/src/app/pages/client/explore/Server.tsx b/src/app/pages/client/explore/Server.tsx index 9fe4e78eb..1a81c225f 100644 --- a/src/app/pages/client/explore/Server.tsx +++ b/src/app/pages/client/explore/Server.tsx @@ -41,6 +41,7 @@ import * as css from './style.css'; import { allRoomsAtom } from '../../../state/room-list/roomList'; import { useRoomNavigate } from '../../../hooks/useRoomNavigate'; import { getMxIdServer } from '../../../utils/matrix'; +import { stopPropagation } from '../../../utils/keyboard'; const useServerSearchParams = (searchParams: URLSearchParams): ExploreServerPathSearchParams => useMemo( @@ -182,6 +183,7 @@ function ThirdPartyProtocolsSelector({ initialFocus: false, onDeactivate: () => setMenuAnchor(undefined), clickOutsideDeactivates: true, + escapeDeactivates: stopPropagation, }} > @@ -277,6 +279,7 @@ function LimitButton({ limit, onLimitChange }: LimitButtonProps) { initialFocus: false, onDeactivate: () => setMenuAnchor(undefined), clickOutsideDeactivates: true, + escapeDeactivates: stopPropagation, }} > diff --git a/src/app/pages/client/home/Home.tsx b/src/app/pages/client/home/Home.tsx index 33714191c..76034cfe0 100644 --- a/src/app/pages/client/home/Home.tsx +++ b/src/app/pages/client/home/Home.tsx @@ -47,6 +47,7 @@ import { PageNav, PageNavHeader, PageNavContent } from '../../../components/page import { useRoomsUnread } from '../../../state/hooks/unread'; import { markAsRead } from '../../../../client/action/notifications'; import { useClosedNavCategoriesAtom } from '../../../state/hooks/closedNavCategories'; +import { stopPropagation } from '../../../utils/keyboard'; type HomeMenuProps = { requestClose: () => void; @@ -121,6 +122,7 @@ function HomeHeader() { clickOutsideDeactivates: true, isKeyForward: (evt: KeyboardEvent) => evt.key === 'ArrowDown', isKeyBackward: (evt: KeyboardEvent) => evt.key === 'ArrowUp', + escapeDeactivates: stopPropagation, }} > setMenuAnchor(undefined)} /> diff --git a/src/app/pages/client/inbox/Invites.tsx b/src/app/pages/client/inbox/Invites.tsx index 91dc02910..06e5f6c6b 100644 --- a/src/app/pages/client/inbox/Invites.tsx +++ b/src/app/pages/client/inbox/Invites.tsx @@ -34,7 +34,7 @@ import { RoomAvatar } from '../../../components/room-avatar'; import { addRoomIdToMDirect, getMxIdLocalPart, guessDmRoomUserId } from '../../../utils/matrix'; import { Time } from '../../../components/message'; import { useElementSizeObserver } from '../../../hooks/useElementSizeObserver'; -import { onEnterOrSpace } from '../../../utils/keyboard'; +import { onEnterOrSpace, stopPropagation } from '../../../utils/keyboard'; import { RoomTopicViewer } from '../../../components/room-topic-viewer'; import { AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback'; import { useRoomNavigate } from '../../../hooks/useRoomNavigate'; @@ -140,6 +140,7 @@ function InviteCard({ room, userId, direct, compact, onNavigate }: InviteCardPro initialFocus: false, clickOutsideDeactivates: true, onDeactivate: closeTopic, + escapeDeactivates: stopPropagation, }} > void; @@ -120,6 +121,7 @@ export function DirectTab() { clickOutsideDeactivates: true, isKeyForward: (evt: KeyboardEvent) => evt.key === 'ArrowDown', isKeyBackward: (evt: KeyboardEvent) => evt.key === 'ArrowUp', + escapeDeactivates: stopPropagation, }} > setMenuAnchor(undefined)} /> diff --git a/src/app/pages/client/sidebar/HomeTab.tsx b/src/app/pages/client/sidebar/HomeTab.tsx index 0b5135cae..41f7c6489 100644 --- a/src/app/pages/client/sidebar/HomeTab.tsx +++ b/src/app/pages/client/sidebar/HomeTab.tsx @@ -23,6 +23,7 @@ import { ScreenSize, useScreenSizeContext } from '../../../hooks/useScreenSize'; import { useNavToActivePathAtom } from '../../../state/hooks/navToActivePath'; import { useHomeRooms } from '../home/useHomeRooms'; import { markAsRead } from '../../../../client/action/notifications'; +import { stopPropagation } from '../../../utils/keyboard'; type HomeMenuProps = { requestClose: () => void; @@ -122,6 +123,7 @@ export function HomeTab() { clickOutsideDeactivates: true, isKeyForward: (evt: KeyboardEvent) => evt.key === 'ArrowDown', isKeyBackward: (evt: KeyboardEvent) => evt.key === 'ArrowUp', + escapeDeactivates: stopPropagation, }} > setMenuAnchor(undefined)} /> diff --git a/src/app/pages/client/sidebar/SpaceTabs.tsx b/src/app/pages/client/sidebar/SpaceTabs.tsx index 99c04965f..8635a35fd 100644 --- a/src/app/pages/client/sidebar/SpaceTabs.tsx +++ b/src/app/pages/client/sidebar/SpaceTabs.tsx @@ -90,6 +90,7 @@ import { roomToUnreadAtom } from '../../../state/room/roomToUnread'; import { markAsRead } from '../../../../client/action/notifications'; import { copyToClipboard } from '../../../utils/dom'; import { openInviteUser, openSpaceSettings } from '../../../../client/action/navigation'; +import { stopPropagation } from '../../../utils/keyboard'; type SpaceMenuProps = { room: Room; @@ -463,6 +464,7 @@ function SpaceTab({ clickOutsideDeactivates: true, isKeyForward: (evt: KeyboardEvent) => evt.key === 'ArrowDown', isKeyBackward: (evt: KeyboardEvent) => evt.key === 'ArrowUp', + escapeDeactivates: stopPropagation, }} > evt.key === 'ArrowDown', isKeyBackward: (evt: KeyboardEvent) => evt.key === 'ArrowUp', + escapeDeactivates: stopPropagation, }} > setMenuAnchor(undefined)} /> diff --git a/src/app/utils/keyboard.ts b/src/app/utils/keyboard.ts index 8ec435d3d..da3fe8cb5 100644 --- a/src/app/utils/keyboard.ts +++ b/src/app/utils/keyboard.ts @@ -30,3 +30,8 @@ export const onEnterOrSpace = (callback: () => void) => (evt: KeyboardEventLike) callback(); } }; + +export const stopPropagation = (evt: KeyboardEvent): boolean => { + evt.stopPropagation(); + return true; +}; diff --git a/src/client/event/hotkeys.js b/src/client/event/hotkeys.js deleted file mode 100644 index 856fcadc4..000000000 --- a/src/client/event/hotkeys.js +++ /dev/null @@ -1,24 +0,0 @@ -import { openSearch } from '../action/navigation'; -import navigation from '../state/navigation'; - -function listenKeyboard(event) { - // Ctrl/Cmd + - if (event.ctrlKey || event.metaKey) { - // open search modal - if (event.key === 'k') { - event.preventDefault(); - if (navigation.isRawModalVisible) return; - openSearch(); - } - } -} - -function initHotkeys() { - document.body.addEventListener('keydown', listenKeyboard); -} - -function removeHotkeys() { - document.body.removeEventListener('keydown', listenKeyboard); -} - -export { initHotkeys, removeHotkeys }; From a1a822c5b64eb4e31edbf9cbd4bd12f3926f084b Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Thu, 18 Jul 2024 18:50:51 +0530 Subject: [PATCH 1164/1531] Fix selecting tombstone room opens replacement room (#1820) --- src/app/utils/matrix.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/app/utils/matrix.ts b/src/app/utils/matrix.ts index 55e16a95d..278bb46b6 100644 --- a/src/app/utils/matrix.ts +++ b/src/app/utils/matrix.ts @@ -14,6 +14,8 @@ import { } from 'matrix-js-sdk'; import { IImageInfo, IThumbnailContent, IVideoInfo } from '../../types/matrix/common'; import { AccountDataEvent } from '../../types/matrix/accountData'; +import { getStateEvent } from './room'; +import { StateEvent } from '../../types/matrix/room'; export const matchMxId = (id: string): RegExpMatchArray | null => id.match(/^([@!$+#])(\S+):(\S+)$/); @@ -42,8 +44,12 @@ export const parseMatrixToUrl = (url: string): [string | undefined, string | und export const getCanonicalAliasRoomId = (mx: MatrixClient, alias: string): string | undefined => mx.getRooms()?.find((room) => room.getCanonicalAlias() === alias)?.roomId; -export const getCanonicalAliasOrRoomId = (mx: MatrixClient, roomId: string): string => - mx.getRoom(roomId)?.getCanonicalAlias() || roomId; +export const getCanonicalAliasOrRoomId = (mx: MatrixClient, roomId: string): string => { + const room = mx.getRoom(roomId); + if (!room) return roomId; + if (getStateEvent(room, StateEvent.RoomTombstone) !== undefined) return roomId; + return room.getCanonicalAlias() || roomId; +}; export const getImageInfo = (img: HTMLImageElement, fileOrBlob: File | Blob): IImageInfo => { const info: IImageInfo = {}; From c243b6104c7c9ca98ff0b5b8bfdf3c32a98f5818 Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Sun, 21 Jul 2024 11:13:33 +0530 Subject: [PATCH 1165/1531] Update color theme to match with new design (#1821) * update silver theme * update unread badge style to look more slim * update nav item style to look less sharp * fix type focus message input typo * decrease navigation drawer width to bring main chat layout to little more center * increase sidebar width to make it less congested * fix sidebar item style * decrease dark theme contrast * improve dark theme * revert sidebar width change * add join with address option in home context menu * match legacy theme with latest themes --- src/app/atoms/button/Toggle.scss | 7 +- src/app/components/nav/NavItemContent.tsx | 2 +- src/app/components/nav/styles.css.ts | 3 +- src/app/components/page/style.css.ts | 2 +- .../components/unread-badge/UnreadBadge.tsx | 4 +- .../room-nav/RoomNavCategoryButton.tsx | 2 +- src/app/features/room/RoomView.tsx | 3 +- src/app/pages/client/home/Home.tsx | 15 ++ src/colors.css.ts | 162 +++++++++--------- src/index.scss | 142 +++++++++------ 10 files changed, 197 insertions(+), 145 deletions(-) diff --git a/src/app/atoms/button/Toggle.scss b/src/app/atoms/button/Toggle.scss index bc6d8a902..ef21f6cd6 100644 --- a/src/app/atoms/button/Toggle.scss +++ b/src/app/atoms/button/Toggle.scss @@ -22,8 +22,7 @@ height: 16px; background-color: var(--tc-surface-low); border-radius: calc(var(--bo-radius) / 2); - transition: transform 200ms ease-in-out, - opacity 200ms ease-in-out; + transition: transform 200ms ease-in-out, opacity 200ms ease-in-out; opacity: 0.6; } @@ -36,8 +35,8 @@ @include dir.prop(transform, var(--ltr), var(--rtl)); transform: translateX(calc(125%)); - background-color: white; + background-color: var(--bg-surface); opacity: 1; } } -} \ No newline at end of file +} diff --git a/src/app/components/nav/NavItemContent.tsx b/src/app/components/nav/NavItemContent.tsx index dcd0edfda..d6a5d1310 100644 --- a/src/app/components/nav/NavItemContent.tsx +++ b/src/app/components/nav/NavItemContent.tsx @@ -5,6 +5,6 @@ import * as css from './styles.css'; export const NavItemContent = as<'p', ComponentProps>( ({ className, ...props }, ref) => ( - + ) ); diff --git a/src/app/components/nav/styles.css.ts b/src/app/components/nav/styles.css.ts index 06710ddd6..48b2a4d34 100644 --- a/src/app/components/nav/styles.css.ts +++ b/src/app/components/nav/styles.css.ts @@ -52,7 +52,7 @@ const NavItemBase = style({ backgroundColor: Container, color: OnContainer, outline: 'none', - minHeight: toRem(38), + minHeight: toRem(36), selectors: { '&:hover, &:focus-visible': { @@ -111,6 +111,7 @@ export const NavItemContent = style({ flexGrow: 1, display: 'flex', alignItems: 'center', + fontWeight: config.fontWeight.W500, selectors: { '&:hover': { diff --git a/src/app/components/page/style.css.ts b/src/app/components/page/style.css.ts index 559d36666..4807a2271 100644 --- a/src/app/components/page/style.css.ts +++ b/src/app/components/page/style.css.ts @@ -2,7 +2,7 @@ import { style } from '@vanilla-extract/css'; import { DefaultReset, color, config, toRem } from 'folds'; export const PageNav = style({ - width: toRem(280), + width: toRem(256), }); export const PageNavHeader = style({ diff --git a/src/app/components/unread-badge/UnreadBadge.tsx b/src/app/components/unread-badge/UnreadBadge.tsx index f5dc09fe1..f8bfefa3c 100644 --- a/src/app/components/unread-badge/UnreadBadge.tsx +++ b/src/app/components/unread-badge/UnreadBadge.tsx @@ -22,9 +22,9 @@ export function UnreadBadge({ highlight, count }: UnreadBadgeProps) { 0 ? '400' : '200'} - fill={count > 0 ? 'Solid' : 'Soft'} + fill="Solid" radii="Pill" - outlined + outlined={false} > {count > 0 && ( diff --git a/src/app/features/room-nav/RoomNavCategoryButton.tsx b/src/app/features/room-nav/RoomNavCategoryButton.tsx index 7acbbe28d..3af8aeac8 100644 --- a/src/app/features/room-nav/RoomNavCategoryButton.tsx +++ b/src/app/features/room-nav/RoomNavCategoryButton.tsx @@ -19,7 +19,7 @@ export const RoomNavCategoryButton = as<'button', { closed?: boolean }>( {...props} ref={ref} > - + {children} diff --git a/src/app/features/room/RoomView.tsx b/src/app/features/room/RoomView.tsx index 84162fcc1..3eabd528a 100644 --- a/src/app/features/room/RoomView.tsx +++ b/src/app/features/room/RoomView.tsx @@ -22,7 +22,6 @@ import navigation from '../../../client/state/navigation'; const shouldFocusMessageField = (evt: KeyboardEvent): boolean => { const { code } = evt; - console.log(code); if (evt.metaKey || evt.altKey || evt.ctrlKey) { return false; } @@ -77,7 +76,7 @@ export function RoomView({ room, eventId }: { room: Room; eventId?: string }) { ) { return; } - if (shouldFocusMessageField(evt) || isKeyHotkey('mod+v')) { + if (shouldFocusMessageField(evt) || isKeyHotkey('mod+v', evt)) { ReactEditor.focus(editor); } }, diff --git a/src/app/pages/client/home/Home.tsx b/src/app/pages/client/home/Home.tsx index 76034cfe0..a06e108e9 100644 --- a/src/app/pages/client/home/Home.tsx +++ b/src/app/pages/client/home/Home.tsx @@ -62,6 +62,11 @@ const HomeMenu = forwardRef(({ requestClose }, re requestClose(); }; + const handleJoinAddress = () => { + openJoinAlias(); + requestClose(); + }; + return ( @@ -76,6 +81,16 @@ const HomeMenu = forwardRef(({ requestClose }, re Mark as Read + } + > + + Join with Address + + ); diff --git a/src/colors.css.ts b/src/colors.css.ts index 9b854bef7..c4f122d2a 100644 --- a/src/colors.css.ts +++ b/src/colors.css.ts @@ -3,92 +3,92 @@ import { color } from 'folds'; export const silverTheme = createTheme(color, { Background: { - Container: '#E6E6E6', - ContainerHover: '#DADADA', - ContainerActive: '#CECECE', - ContainerLine: '#C2C2C2', + Container: '#DEDEDE', + ContainerHover: '#D3D3D3', + ContainerActive: '#C7C7C7', + ContainerLine: '#BBBBBB', OnContainer: '#000000', }, Surface: { - Container: '#F2F2F2', - ContainerHover: '#E6E6E6', - ContainerActive: '#DADADA', - ContainerLine: '#CECECE', + Container: '#EAEAEA', + ContainerHover: '#DEDEDE', + ContainerActive: '#D3D3D3', + ContainerLine: '#C7C7C7', OnContainer: '#000000', }, SurfaceVariant: { - Container: '#E6E6E6', - ContainerHover: '#DADADA', - ContainerActive: '#CECECE', - ContainerLine: '#C2C2C2', + Container: '#DEDEDE', + ContainerHover: '#D3D3D3', + ContainerActive: '#C7C7C7', + ContainerLine: '#BBBBBB', OnContainer: '#000000', }, Primary: { - Main: '#1858D5', - MainHover: '#164FC0', - MainActive: '#144BB5', - MainLine: '#1346AA', + Main: '#1245A8', + MainHover: '#103E97', + MainActive: '#0F3B8F', + MainLine: '#0E3786', OnMain: '#FFFFFF', - Container: '#E8EEFB', - ContainerHover: '#DCE6F9', - ContainerActive: '#D1DEF7', - ContainerLine: '#C5D5F5', - OnContainer: '#113E95', + Container: '#C4D0E9', + ContainerHover: '#B8C7E5', + ContainerActive: '#ACBEE1', + ContainerLine: '#A0B5DC', + OnContainer: '#0D3076', }, Secondary: { Main: '#000000', - MainHover: '#0C0C0C', - MainActive: '#181818', - MainLine: '#303030', - OnMain: '#F2F2F2', - Container: '#CECECE', - ContainerHover: '#C2C2C2', - ContainerActive: '#B5B5B5', - ContainerLine: '#A9A9A9', + MainHover: '#171717', + MainActive: '#232323', + MainLine: '#2F2F2F', + OnMain: '#EAEAEA', + Container: '#C7C7C7', + ContainerHover: '#BBBBBB', + ContainerActive: '#AFAFAF', + ContainerLine: '#A4A4A4', OnContainer: '#0C0C0C', }, Success: { - Main: '#00844C', - MainHover: '#007744', - MainActive: '#007041', - MainLine: '#006A3D', + Main: '#017343', + MainHover: '#01683C', + MainActive: '#016239', + MainLine: '#015C36', OnMain: '#FFFFFF', - Container: '#E5F3ED', - ContainerHover: '#D9EDE4', - ContainerActive: '#CCE6DB', - ContainerLine: '#BFE0D2', - OnContainer: '#005C35', + Container: '#BFDCD0', + ContainerHover: '#B3D5C7', + ContainerActive: '#A6CEBD', + ContainerLine: '#99C7B4', + OnContainer: '#01512F', }, Warning: { - Main: '#A85400', - MainHover: '#974C00', - MainActive: '#8F4700', - MainLine: '#864300', + Main: '#864300', + MainHover: '#793C00', + MainActive: '#723900', + MainLine: '#6B3600', OnMain: '#FFFFFF', - Container: '#F6EEE5', - ContainerHover: '#F2E5D9', - ContainerActive: '#EEDDCC', - ContainerLine: '#E9D4BF', - OnContainer: '#763B00', + Container: '#E1D0BF', + ContainerHover: '#DBC7B2', + ContainerActive: '#D5BDA6', + ContainerLine: '#CFB499', + OnContainer: '#5E2F00', }, Critical: { - Main: '#C40E0E', - MainHover: '#AC0909', - MainActive: '#A60C0C', - MainLine: '#9C0B0B', + Main: '#9D0F0F', + MainHover: '#8D0E0E', + MainActive: '#850D0D', + MainLine: '#7E0C0C', OnMain: '#FFFFFF', - Container: '#F9E7E7', - ContainerHover: '#F6DBDB', - ContainerActive: '#F3CFCF', - ContainerLine: '#F0C3C3', - OnContainer: '#890A0A', + Container: '#E7C3C3', + ContainerHover: '#E2B7B7', + ContainerActive: '#DDABAB', + ContainerLine: '#D89F9F', + OnContainer: '#6E0B0B', }, Other: { @@ -100,27 +100,27 @@ export const silverTheme = createTheme(color, { const darkThemeData = { Background: { - Container: '#15171A', - ContainerHover: '#1F2326', - ContainerActive: '#2A2E33', - ContainerLine: '#343A40', - OnContainer: '#ffffff', + Container: '#1A1A1A', + ContainerHover: '#262626', + ContainerActive: '#333333', + ContainerLine: '#404040', + OnContainer: '#F2F2F2', }, Surface: { - Container: '#1F2326', - ContainerHover: '#2A2E33', - ContainerActive: '#343A40', - ContainerLine: '#3F464D', - OnContainer: '#ffffff', + Container: '#262626', + ContainerHover: '#333333', + ContainerActive: '#404040', + ContainerLine: '#4D4D4D', + OnContainer: '#F2F2F2', }, SurfaceVariant: { - Container: '#2A2E33', - ContainerHover: '#343A40', - ContainerActive: '#3F464D', - ContainerLine: '#495159', - OnContainer: '#ffffff', + Container: '#333333', + ContainerHover: '#404040', + ContainerActive: '#4D4D4D', + ContainerLine: '#595959', + OnContainer: '#F2F2F2', }, Primary: { @@ -137,16 +137,16 @@ const darkThemeData = { }, Secondary: { - Main: '#D1E8FF', - MainHover: '#BCD1E5', - MainActive: '#B2C5D9', - MainLine: '#A7BACC', - OnMain: '#15171A', - Container: '#343A40', - ContainerHover: '#3F464D', - ContainerActive: '#495159', - ContainerLine: '#545D66', - OnContainer: '#C7DCF2', + Main: '#FFFFFF', + MainHover: '#E5E5E5', + MainActive: '#D9D9D9', + MainLine: '#CCCCCC', + OnMain: '#1A1A1A', + Container: '#404040', + ContainerHover: '#4D4D4D', + ContainerActive: '#595959', + ContainerLine: '#666666', + OnContainer: '#F2F2F2', }, Success: { diff --git a/src/index.scss b/src/index.scss index 5290035bd..5903858ae 100644 --- a/src/index.scss +++ b/src/index.scss @@ -19,25 +19,25 @@ --bg-surface-active: rgba(0, 0, 0, 5%); --bg-surface-border: rgba(0, 0, 0, 6%); - --bg-primary: rgb(83, 110, 234); - --bg-primary-hover: rgba(83, 110, 234, 80%); - --bg-primary-active: rgba(83, 110, 234, 70%); - --bg-primary-border: rgba(83, 110, 234, 38%); + --bg-primary: rgb(18, 69, 168); + --bg-primary-hover: rgba(18, 69, 168, 80%); + --bg-primary-active: rgba(18, 69, 168, 70%); + --bg-primary-border: rgba(18, 69, 168, 38%); - --bg-positive: rgb(69, 184, 59); - --bg-positive-hover: rgba(69, 184, 59, 8%); - --bg-positive-active: rgba(69, 184, 59, 15%); - --bg-positive-border: rgba(69, 184, 59, 40%); + --bg-positive: rgb(1, 115, 67); + --bg-positive-hover: rgba(1, 115, 67, 8%); + --bg-positive-active: rgba(1, 115, 67, 15%); + --bg-positive-border: rgba(1, 115, 67, 40%); - --bg-caution: rgb(255, 179, 0); - --bg-caution-hover: rgba(255, 179, 0, 8%); - --bg-caution-active: rgba(255, 179, 0, 15%); - --bg-caution-border: rgba(255, 179, 0, 40%); + --bg-caution: rgb(134, 67, 0); + --bg-caution-hover: rgba(134, 67, 0, 8%); + --bg-caution-active: rgba(134, 67, 0, 15%); + --bg-caution-border: rgba(134, 67, 0, 40%); - --bg-danger: rgb(240, 71, 71); - --bg-danger-hover: rgba(240, 71, 71, 5%); - --bg-danger-active: rgba(240, 71, 71, 10%); - --bg-danger-border: rgba(240, 71, 71, 20%); + --bg-danger: rgb(157, 15, 15); + --bg-danger-hover: rgba(157, 15, 15, 5%); + --bg-danger-active: rgba(157, 15, 15, 10%); + --bg-danger-border: rgba(157, 15, 15, 20%); --bg-tooltip: #353535; --bg-badge: #989898; @@ -56,16 +56,16 @@ --tc-primary-low: rgba(255, 255, 255, 40%); --tc-positive-high: var(--bg-positive); - --tc-positive-normal: rgb(69, 184, 59, 80%); - --tc-positive-low: rgb(69, 184, 59, 60%); + --tc-positive-normal: rgb(1, 115, 67, 80%); + --tc-positive-low: rgb(1, 115, 67, 60%); --tc-caution-high: var(--bg-caution); - --tc-caution-normal: rgb(255, 179, 0, 80%); - --tc-caution-low: rgb(255, 179, 0, 60%); + --tc-caution-normal: rgb(134, 67, 0, 80%); + --tc-caution-low: rgb(134, 67, 0, 60%); --tc-danger-high: var(--bg-danger); - --tc-danger-normal: rgba(240, 71, 71, 88%); - --tc-danger-low: rgba(240, 71, 71, 60%); + --tc-danger-normal: rgba(157, 15, 15, 88%); + --tc-danger-low: rgba(157, 15, 15, 60%); --tc-code: #e62498; --tc-link: hsl(213deg 100% 45%); @@ -78,12 +78,12 @@ --ic-surface-low: #7c7c7c; --ic-primary-high: #ffffff; --ic-primary-normal: #ffffff; - --ic-positive-high: rgba(69, 184, 59); - --ic-positive-normal: rgba(69, 184, 59, 80%); - --ic-caution-high: rgba(255, 179, 0); - --ic-caution-normal: rgba(255, 179, 0, 80%); - --ic-danger-high: rgba(240, 71, 71); - --ic-danger-normal: rgba(240, 71, 71, 0.7); + --ic-positive-high: rgba(1, 115, 67); + --ic-positive-normal: rgba(1, 115, 67, 80%); + --ic-caution-high: rgba(134, 67, 0); + --ic-caution-normal: rgba(134, 67, 0, 80%); + --ic-danger-high: rgba(157, 15, 15); + --ic-danger-normal: rgba(157, 15, 15, 0.7); /* user mxid colors */ --mx-uc-1: hsl(208, 100%, 45%); @@ -210,20 +210,35 @@ .dark-theme, .butter-theme { /* background color | --bg-[background type]: value */ - --bg-surface: #1f2326; - --bg-surface-transparent: #1f232600; - --bg-surface-low: #15171a; - --bg-surface-low-transparent: #15171a00; - --bg-surface-extra-low: #15171a; - --bg-surface-extra-low-transparent: #15171a00; - --bg-surface-hover: #1f2326; - --bg-surface-active: #2a2e33; - --bg-surface-border: rgba(0, 0, 0, 20%); + --bg-surface: #262626; + --bg-surface-transparent: #26262600; + --bg-surface-low: #1a1a1a; + --bg-surface-low-transparent: #1a1a1a00; + --bg-surface-extra-low: #1a1a1a; + --bg-surface-extra-low-transparent: #1a1a1a00; + --bg-surface-hover: #333333; + --bg-surface-active: #404040; + --bg-surface-border: #404040; - --bg-primary: rgb(42, 98, 166); - --bg-primary-hover: rgba(42, 98, 166, 80%); - --bg-primary-active: rgba(42, 98, 166, 70%); - --bg-primary-border: rgba(42, 98, 166, 38%); + --bg-primary: rgb(189, 182, 236); + --bg-primary-hover: rgba(189, 182, 236, 0.8); + --bg-primary-active: rgba(189, 182, 236, 70%); + --bg-primary-border: rgba(189, 182, 236, 38%); + + --bg-positive: rgb(133, 224, 186); + --bg-positive-hover: rgba(133, 224, 186, 8%); + --bg-positive-active: rgba(133, 224, 186, 15%); + --bg-positive-border: rgba(133, 224, 186, 40%); + + --bg-caution: rgb(227, 186, 145); + --bg-caution-hover: rgba(227, 186, 145, 8%); + --bg-caution-active: rgba(227, 186, 145, 15%); + --bg-caution-border: rgba(227, 186, 145, 40%); + + --bg-danger: rgb(230, 157, 157); + --bg-danger-hover: rgba(230, 157, 157, 5%); + --bg-danger-active: rgba(230, 157, 157, 10%); + --bg-danger-border: rgba(230, 157, 157, 20%); --bg-tooltip: #000; --bg-badge: hsl(0, 0%, 75%); @@ -237,9 +252,21 @@ --tc-surface-normal-low: rgba(255, 255, 255, 60%); --tc-surface-low: rgba(255, 255, 255, 58%); - --tc-primary-high: #ffffff; - --tc-primary-normal: rgba(255, 255, 255, 0.68); - --tc-primary-low: rgba(255, 255, 255, 0.4); + --tc-primary-high: rgb(44, 40, 67); + --tc-primary-normal: rgba(44, 40, 67, 0.68); + --tc-primary-low: rgba(44, 40, 67, 0.4); + + --tc-positive-high: var(--bg-positive); + --tc-positive-normal: rgb(133, 224, 186, 80%); + --tc-positive-low: rgb(133, 224, 186, 60%); + + --tc-caution-high: var(--bg-caution); + --tc-caution-normal: rgb(227, 186, 145, 80%); + --tc-caution-low: rgb(227, 186, 145, 60%); + + --tc-danger-high: var(--bg-danger); + --tc-danger-normal: rgba(230, 157, 157, 88%); + --tc-danger-low: rgba(230, 157, 157, 60%); --tc-code: #e565b1; --tc-link: hsl(213deg 100% 80%); @@ -249,7 +276,15 @@ --ic-surface-high: rgb(255, 255, 255); --ic-surface-normal: rgba(255, 255, 255, 84%); --ic-surface-low: rgba(255, 255, 255, 64%); - --ic-primary-normal: #ffffff; + --ic-primary-high: var(--tc-primary-high); + --ic-primary-normal: var(--tc-primary-high); + --ic-primary-low: var(--tc-primary-high); + --ic-positive-high: rgba(133, 224, 186); + --ic-positive-normal: rgba(133, 224, 186, 80%); + --ic-caution-high: rgba(227, 186, 145); + --ic-caution-normal: rgba(227, 186, 145, 80%); + --ic-danger-high: rgba(230, 157, 157); + --ic-danger-normal: rgba(230, 157, 157, 0.7); --mx-uc-1: hsl(208, 100%, 75%); --mx-uc-2: hsl(301, 100%, 80%); @@ -296,17 +331,20 @@ .butter-theme { /* background color | --bg-[background type]: value */ - --bg-surface: hsl(64, 6%, 14%); - --bg-surface-transparent: hsla(64, 6%, 14%, 0); - --bg-surface-low: hsl(64, 6%, 10%); - --bg-surface-low-transparent: hsla(64, 6%, 10%, 0); - --bg-surface-extra-low: hsl(64, 6%, 8%); - --bg-surface-extra-low-transparent: hsla(64, 6%, 8%, 0); + --bg-surface: #262621; + --bg-surface-transparent: #26262100; + --bg-surface-low: #1a1916; + --bg-surface-low-transparent: #1a191600; + --bg-surface-extra-low: #1a1916; + --bg-surface-extra-low-transparent: #1a1916; + --bg-surface-hover: #33322c; + --bg-surface-active: #403f38; + --bg-surface-border: #403f38; --bg-badge: #c4c1ab; /* text color | --tc-[background type]-[priority]: value */ - --tc-surface-high: rgb(255, 251, 222, 94%); + --tc-surface-high: rgb(255, 251, 222); --tc-surface-normal: rgba(255, 251, 222, 94%); --tc-surface-normal-low: rgba(255, 251, 222, 60%); --tc-surface-low: rgba(255, 251, 222, 58%); From 021a2c0e2ed605339f7f1153fa421ac0a5bdddc3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 21 Jul 2024 15:43:58 +1000 Subject: [PATCH 1166/1531] Bump actions/setup-node from 4.0.2 to 4.0.3 (#1816) Bumps [actions/setup-node](https://github.com/actions/setup-node) from 4.0.2 to 4.0.3. - [Release notes](https://github.com/actions/setup-node/releases) - [Commits](https://github.com/actions/setup-node/compare/v4.0.2...v4.0.3) --- updated-dependencies: - dependency-name: actions/setup-node dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build-pull-request.yml | 2 +- .github/workflows/netlify-dev.yml | 2 +- .github/workflows/prod-deploy.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-pull-request.yml b/.github/workflows/build-pull-request.yml index fd8741a2f..67ae5f1e9 100644 --- a/.github/workflows/build-pull-request.yml +++ b/.github/workflows/build-pull-request.yml @@ -14,7 +14,7 @@ jobs: - name: Checkout repository uses: actions/checkout@v4.1.7 - name: Setup node - uses: actions/setup-node@v4.0.2 + uses: actions/setup-node@v4.0.3 with: node-version: 20.12.2 cache: 'npm' diff --git a/.github/workflows/netlify-dev.yml b/.github/workflows/netlify-dev.yml index 5a0ecbcab..71d34294d 100644 --- a/.github/workflows/netlify-dev.yml +++ b/.github/workflows/netlify-dev.yml @@ -13,7 +13,7 @@ jobs: - name: Checkout repository uses: actions/checkout@v4.1.7 - name: Setup node - uses: actions/setup-node@v4.0.2 + uses: actions/setup-node@v4.0.3 with: node-version: 20.12.2 cache: 'npm' diff --git a/.github/workflows/prod-deploy.yml b/.github/workflows/prod-deploy.yml index b1aeee741..9118be552 100644 --- a/.github/workflows/prod-deploy.yml +++ b/.github/workflows/prod-deploy.yml @@ -12,7 +12,7 @@ jobs: - name: Checkout repository uses: actions/checkout@v4.1.7 - name: Setup node - uses: actions/setup-node@v4.0.2 + uses: actions/setup-node@v4.0.3 with: node-version: 20.12.2 cache: 'npm' From fbe27d69c0b14620509686562b3c576247a2b4c2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 21 Jul 2024 15:44:27 +1000 Subject: [PATCH 1167/1531] Bump docker/build-push-action from 6.3.0 to 6.4.0 (#1815) Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 6.3.0 to 6.4.0. - [Release notes](https://github.com/docker/build-push-action/releases) - [Commits](https://github.com/docker/build-push-action/compare/v6.3.0...v6.4.0) --- updated-dependencies: - dependency-name: docker/build-push-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/docker-pr.yml | 2 +- .github/workflows/prod-deploy.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docker-pr.yml b/.github/workflows/docker-pr.yml index d47d2c2fe..fdeb237f2 100644 --- a/.github/workflows/docker-pr.yml +++ b/.github/workflows/docker-pr.yml @@ -13,7 +13,7 @@ jobs: - name: Checkout repository uses: actions/checkout@v4.1.7 - name: Build Docker image - uses: docker/build-push-action@v6.3.0 + uses: docker/build-push-action@v6.4.0 with: context: . push: false diff --git a/.github/workflows/prod-deploy.yml b/.github/workflows/prod-deploy.yml index 9118be552..a84662117 100644 --- a/.github/workflows/prod-deploy.yml +++ b/.github/workflows/prod-deploy.yml @@ -90,7 +90,7 @@ jobs: ${{ secrets.DOCKER_USERNAME }}/cinny ghcr.io/${{ github.repository }} - name: Build and push Docker image - uses: docker/build-push-action@v6.3.0 + uses: docker/build-push-action@v6.4.0 with: context: . platforms: linux/amd64,linux/arm64 From e046c59f7c5aa6385d4b9e0e4bc82aa3984502fc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 21 Jul 2024 15:44:43 +1000 Subject: [PATCH 1168/1531] Bump docker/setup-buildx-action from 3.3.0 to 3.4.0 (#1814) Bumps [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) from 3.3.0 to 3.4.0. - [Release notes](https://github.com/docker/setup-buildx-action/releases) - [Commits](https://github.com/docker/setup-buildx-action/compare/v3.3.0...v3.4.0) --- updated-dependencies: - dependency-name: docker/setup-buildx-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/prod-deploy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/prod-deploy.yml b/.github/workflows/prod-deploy.yml index a84662117..7bc82b42b 100644 --- a/.github/workflows/prod-deploy.yml +++ b/.github/workflows/prod-deploy.yml @@ -70,7 +70,7 @@ jobs: - name: Set up QEMU uses: docker/setup-qemu-action@v3.1.0 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3.3.0 + uses: docker/setup-buildx-action@v3.4.0 - name: Login to Docker Hub uses: docker/login-action@v3.2.0 with: From e2228a18c1533bbf8b7a3f82f8353ae65bc69a80 Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Mon, 22 Jul 2024 16:17:19 +0530 Subject: [PATCH 1169/1531] handle error in loading screen (#1823) * handle client boot error in loading screen * use sync state hook in client root * add loading screen options * removed extra condition in loading finish * add sync connection status bar --- src/app/features/room-nav/RoomNavItem.tsx | 2 +- src/app/features/room/Room.tsx | 4 +- src/app/features/room/RoomTimeline.tsx | 10 +- src/app/features/room/RoomTombstone.tsx | 46 ++--- src/app/features/room/RoomViewHeader.tsx | 2 +- src/app/hooks/useAccountData.js | 7 +- src/app/hooks/useCommands.ts | 28 +-- src/app/hooks/useCrossSigningStatus.js | 8 +- src/app/hooks/useDeviceList.js | 7 +- src/app/hooks/useSyncState.ts | 6 +- .../GlobalNotification.jsx | 4 +- .../global-notification/IgnoreUserList.jsx | 9 +- .../KeywordNotification.jsx | 4 +- src/app/molecules/image-pack/ImagePack.jsx | 37 ++-- .../molecules/image-pack/ImagePackUpload.jsx | 4 +- .../molecules/image-upload/ImageUpload.jsx | 7 +- .../ExportE2ERoomKeys.jsx | 5 +- .../ImportE2ERoomKeys.jsx | 5 +- .../molecules/room-aliases/RoomAliases.jsx | 14 +- src/app/molecules/room-emojis/RoomEmojis.jsx | 6 +- .../room-encryption/RoomEncryption.jsx | 4 +- .../RoomHistoryVisibility.jsx | 27 ++- .../molecules/room-members/RoomMembers.jsx | 10 +- .../room-notification/RoomNotification.jsx | 11 +- .../room-permissions/RoomPermissions.jsx | 8 +- .../molecules/room-profile/RoomProfile.jsx | 6 +- .../room-visibility/RoomVisibility.jsx | 15 +- .../space-add-existing/SpaceAddExisting.jsx | 8 +- src/app/organisms/create-room/CreateRoom.jsx | 10 +- .../emoji-verification/EmojiVerification.jsx | 14 +- src/app/organisms/invite-user/InviteUser.jsx | 8 +- src/app/organisms/join-alias/JoinAlias.jsx | 6 +- .../profile-editor/ProfileEditor.jsx | 6 +- .../profile-viewer/ProfileViewer.jsx | 46 ++--- src/app/organisms/room/RoomSettings.jsx | 7 +- src/app/organisms/search/Search.jsx | 16 +- src/app/organisms/settings/AuthRequest.jsx | 4 +- src/app/organisms/settings/CrossSigning.jsx | 4 +- src/app/organisms/settings/DeviceManage.jsx | 12 +- src/app/organisms/settings/KeyBackup.jsx | 14 +- .../settings/SecretStorageAccess.jsx | 13 +- src/app/organisms/settings/Settings.jsx | 12 +- .../space-settings/SpaceSettings.jsx | 5 +- src/app/pages/client/ClientLayout.tsx | 2 +- src/app/pages/client/ClientRoot.tsx | 181 ++++++++++++++++-- src/app/pages/client/SyncStatus.tsx | 87 +++++++++ src/app/pages/client/WelcomePage.tsx | 2 +- src/app/pages/client/direct/Direct.tsx | 3 +- src/app/pages/client/home/Home.tsx | 3 +- src/app/pages/client/inbox/Notifications.tsx | 2 +- src/app/pages/client/sidebar/DirectTab.tsx | 3 +- src/app/pages/client/sidebar/HomeTab.tsx | 3 +- src/app/pages/client/sidebar/SpaceTabs.tsx | 2 +- src/app/pages/client/space/Space.tsx | 2 +- .../{notifications.js => notifications.ts} | 8 +- src/client/action/room.js | 82 ++------ src/client/initMatrix.js | 128 ------------- src/client/initMatrix.ts | 70 +++++++ src/client/mx.ts | 7 - src/index.scss | 2 + src/util/matrixUtil.js | 24 +-- src/util/sort.js | 27 --- 62 files changed, 609 insertions(+), 510 deletions(-) create mode 100644 src/app/pages/client/SyncStatus.tsx rename src/client/action/{notifications.js => notifications.ts} (69%) delete mode 100644 src/client/initMatrix.js create mode 100644 src/client/initMatrix.ts delete mode 100644 src/client/mx.ts diff --git a/src/app/features/room-nav/RoomNavItem.tsx b/src/app/features/room-nav/RoomNavItem.tsx index 8ecc81a31..281c5b777 100644 --- a/src/app/features/room-nav/RoomNavItem.tsx +++ b/src/app/features/room-nav/RoomNavItem.tsx @@ -53,7 +53,7 @@ const RoomNavItemMenu = forwardRef( const canInvite = canDoAction('invite', getPowerLevel(mx.getUserId() ?? '')); const handleMarkAsRead = () => { - markAsRead(room.roomId); + markAsRead(mx, room.roomId); requestClose(); }; diff --git a/src/app/features/room/Room.tsx b/src/app/features/room/Room.tsx index fd578ec6c..19ac53e15 100644 --- a/src/app/features/room/Room.tsx +++ b/src/app/features/room/Room.tsx @@ -11,10 +11,12 @@ import { PowerLevelsContextProvider, usePowerLevels } from '../../hooks/usePower import { useRoom } from '../../hooks/useRoom'; import { useKeyDown } from '../../hooks/useKeyDown'; import { markAsRead } from '../../../client/action/notifications'; +import { useMatrixClient } from '../../hooks/useMatrixClient'; export function Room() { const { eventId } = useParams(); const room = useRoom(); + const mx = useMatrixClient(); const [isDrawer] = useSetting(settingsAtom, 'isPeopleDrawer'); const screenSize = useScreenSizeContext(); @@ -25,7 +27,7 @@ export function Room() { useCallback( (evt) => { if (isKeyHotkey('escape', evt)) { - markAsRead(room.roomId); + markAsRead(mx, room.roomId); } }, [room.roomId] diff --git a/src/app/features/room/RoomTimeline.tsx b/src/app/features/room/RoomTimeline.tsx index 14cdb56e8..b9bfb8434 100644 --- a/src/app/features/room/RoomTimeline.tsx +++ b/src/app/features/room/RoomTimeline.tsx @@ -597,7 +597,7 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli // so timeline can be updated with evt like: edits, reactions etc if (atBottomRef.current) { if (document.hasFocus() && (!unreadInfo || mEvt.getSender() === mx.getUserId())) { - requestAnimationFrame(() => markAsRead(mEvt.getRoomId())); + requestAnimationFrame(() => markAsRead(mx, mEvt.getRoomId())); } if (document.hasFocus()) { @@ -658,15 +658,15 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli const tryAutoMarkAsRead = useCallback(() => { if (!unreadInfo) { - requestAnimationFrame(() => markAsRead(room.roomId)); + requestAnimationFrame(() => markAsRead(mx, room.roomId)); return; } const evtTimeline = getEventTimeline(room, unreadInfo.readUptoEventId); const latestTimeline = evtTimeline && getFirstLinkedTimeline(evtTimeline, Direction.Forward); if (latestTimeline === room.getLiveTimeline()) { - requestAnimationFrame(() => markAsRead(room.roomId)); + requestAnimationFrame(() => markAsRead(mx, room.roomId)); } - }, [room, unreadInfo]); + }, [mx, room, unreadInfo]); const debounceSetAtBottom = useDebounce( useCallback((entry: IntersectionObserverEntry) => { @@ -832,7 +832,7 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli }; const handleMarkAsRead = () => { - markAsRead(room.roomId); + markAsRead(mx, room.roomId); }; const handleOpenReply: MouseEventHandler = useCallback( diff --git a/src/app/features/room/RoomTombstone.tsx b/src/app/features/room/RoomTombstone.tsx index bd8afdad8..e3f8251f4 100644 --- a/src/app/features/room/RoomTombstone.tsx +++ b/src/app/features/room/RoomTombstone.tsx @@ -40,28 +40,30 @@ export function RoomTombstone({ roomId, body, replacementRoomId }: RoomTombstone )} - {replacementRoom?.getMyMembership() === Membership.Join || - joinState.status === AsyncStatus.Success ? ( - - ) : ( - - )} + + {replacementRoom?.getMyMembership() === Membership.Join || + joinState.status === AsyncStatus.Success ? ( + + ) : ( + + )} + ); } diff --git a/src/app/features/room/RoomViewHeader.tsx b/src/app/features/room/RoomViewHeader.tsx index aa267c537..6750f9237 100644 --- a/src/app/features/room/RoomViewHeader.tsx +++ b/src/app/features/room/RoomViewHeader.tsx @@ -74,7 +74,7 @@ const RoomMenu = forwardRef( const canInvite = canDoAction('invite', getPowerLevel(mx.getUserId() ?? '')); const handleMarkAsRead = () => { - markAsRead(room.roomId); + markAsRead(mx, room.roomId); requestClose(); }; diff --git a/src/app/hooks/useAccountData.js b/src/app/hooks/useAccountData.js index ed654d977..43cc11ed7 100644 --- a/src/app/hooks/useAccountData.js +++ b/src/app/hooks/useAccountData.js @@ -1,10 +1,9 @@ /* eslint-disable import/prefer-default-export */ import { useState, useEffect } from 'react'; - -import initMatrix from '../../client/initMatrix'; +import { useMatrixClient } from './useMatrixClient'; export function useAccountData(eventType) { - const mx = initMatrix.matrixClient; + const mx = useMatrixClient(); const [event, setEvent] = useState(mx.getAccountData(eventType)); useEffect(() => { @@ -16,7 +15,7 @@ export function useAccountData(eventType) { return () => { mx.removeListener('accountData', handleChange); }; - }, [eventType]); + }, [mx, eventType]); return event; } diff --git a/src/app/hooks/useCommands.ts b/src/app/hooks/useCommands.ts index 3c8295149..182d13070 100644 --- a/src/app/hooks/useCommands.ts +++ b/src/app/hooks/useCommands.ts @@ -92,9 +92,9 @@ export const useCommands = (mx: MatrixClient, room: Room): CommandRecord => { return; } } - const devices = await Promise.all(userIds.map(hasDevices)); + const devices = await Promise.all(userIds.map(uid => hasDevices(mx, uid))); const isEncrypt = devices.every((hasDevice) => hasDevice); - const result = await roomActions.createDM(userIds, isEncrypt); + const result = await roomActions.createDM(mx, userIds, isEncrypt); navigateRoom(result.room_id); }, }, @@ -106,7 +106,7 @@ export const useCommands = (mx: MatrixClient, room: Room): CommandRecord => { const roomIds = rawIds.filter( (idOrAlias) => isRoomId(idOrAlias) || isRoomAlias(idOrAlias) ); - roomIds.map((id) => roomActions.join(id)); + roomIds.map((id) => roomActions.join(mx, id)); }, }, [Command.Leave]: { @@ -127,7 +127,7 @@ export const useCommands = (mx: MatrixClient, room: Room): CommandRecord => { description: 'Invite user to room. Example: /invite userId1 userId2 [-r reason]', exe: async (payload) => { const { users, reason } = parseUsersAndReason(payload); - users.map((id) => roomActions.invite(room.roomId, id, reason)); + users.map((id) => mx.invite(room.roomId, id, reason)); }, }, [Command.DisInvite]: { @@ -135,7 +135,7 @@ export const useCommands = (mx: MatrixClient, room: Room): CommandRecord => { description: 'Disinvite user to room. Example: /disinvite userId1 userId2 [-r reason]', exe: async (payload) => { const { users, reason } = parseUsersAndReason(payload); - users.map((id) => roomActions.kick(room.roomId, id, reason)); + users.map((id) => mx.kick(room.roomId, id, reason)); }, }, [Command.Kick]: { @@ -143,7 +143,7 @@ export const useCommands = (mx: MatrixClient, room: Room): CommandRecord => { description: 'Kick user from room. Example: /kick userId1 userId2 [-r reason]', exe: async (payload) => { const { users, reason } = parseUsersAndReason(payload); - users.map((id) => roomActions.kick(room.roomId, id, reason)); + users.map((id) => mx.kick(room.roomId, id, reason)); }, }, [Command.Ban]: { @@ -151,7 +151,7 @@ export const useCommands = (mx: MatrixClient, room: Room): CommandRecord => { description: 'Ban user from room. Example: /ban userId1 userId2 [-r reason]', exe: async (payload) => { const { users, reason } = parseUsersAndReason(payload); - users.map((id) => roomActions.ban(room.roomId, id, reason)); + users.map((id) => mx.ban(room.roomId, id, reason)); }, }, [Command.UnBan]: { @@ -160,7 +160,7 @@ export const useCommands = (mx: MatrixClient, room: Room): CommandRecord => { exe: async (payload) => { const rawIds = payload.split(' '); const users = rawIds.filter((id) => isUserId(id)); - users.map((id) => roomActions.unban(room.roomId, id)); + users.map((id) => mx.unban(room.roomId, id)); }, }, [Command.Ignore]: { @@ -169,7 +169,7 @@ export const useCommands = (mx: MatrixClient, room: Room): CommandRecord => { exe: async (payload) => { const rawIds = payload.split(' '); const userIds = rawIds.filter((id) => isUserId(id)); - if (userIds.length > 0) roomActions.ignore(userIds); + if (userIds.length > 0) roomActions.ignore(mx, userIds); }, }, [Command.UnIgnore]: { @@ -178,7 +178,7 @@ export const useCommands = (mx: MatrixClient, room: Room): CommandRecord => { exe: async (payload) => { const rawIds = payload.split(' '); const userIds = rawIds.filter((id) => isUserId(id)); - if (userIds.length > 0) roomActions.unignore(userIds); + if (userIds.length > 0) roomActions.unignore(mx, userIds); }, }, [Command.MyRoomNick]: { @@ -187,7 +187,7 @@ export const useCommands = (mx: MatrixClient, room: Room): CommandRecord => { exe: async (payload) => { const nick = payload.trim(); if (nick === '') return; - roomActions.setMyRoomNick(room.roomId, nick); + roomActions.setMyRoomNick(mx, room.roomId, nick); }, }, [Command.MyRoomAvatar]: { @@ -195,7 +195,7 @@ export const useCommands = (mx: MatrixClient, room: Room): CommandRecord => { description: 'Change profile picture in current room. Example /myroomavatar mxc://xyzabc', exe: async (payload) => { if (payload.match(/^mxc:\/\/\S+$/)) { - roomActions.setMyRoomAvatar(room.roomId, payload); + roomActions.setMyRoomAvatar(mx, room.roomId, payload); } }, }, @@ -203,14 +203,14 @@ export const useCommands = (mx: MatrixClient, room: Room): CommandRecord => { name: Command.ConvertToDm, description: 'Convert room to direct message', exe: async () => { - roomActions.convertToDm(room.roomId); + roomActions.convertToDm(mx, room.roomId); }, }, [Command.ConvertToRoom]: { name: Command.ConvertToRoom, description: 'Convert direct message to room', exe: async () => { - roomActions.convertToRoom(room.roomId); + roomActions.convertToRoom(mx, room.roomId); }, }, }), diff --git a/src/app/hooks/useCrossSigningStatus.js b/src/app/hooks/useCrossSigningStatus.js index 845c54629..990076e6b 100644 --- a/src/app/hooks/useCrossSigningStatus.js +++ b/src/app/hooks/useCrossSigningStatus.js @@ -1,12 +1,12 @@ /* eslint-disable import/prefer-default-export */ import { useState, useEffect } from 'react'; -import initMatrix from '../../client/initMatrix'; import { hasCrossSigningAccountData } from '../../util/matrixUtil'; +import { useMatrixClient } from './useMatrixClient'; export function useCrossSigningStatus() { - const mx = initMatrix.matrixClient; - const [isCSEnabled, setIsCSEnabled] = useState(hasCrossSigningAccountData()); + const mx = useMatrixClient(); + const [isCSEnabled, setIsCSEnabled] = useState(hasCrossSigningAccountData(mx)); useEffect(() => { if (isCSEnabled) return undefined; @@ -20,6 +20,6 @@ export function useCrossSigningStatus() { return () => { mx.removeListener('accountData', handleAccountData); }; - }, [isCSEnabled === false]); + }, [mx, isCSEnabled]); return isCSEnabled; } diff --git a/src/app/hooks/useDeviceList.js b/src/app/hooks/useDeviceList.js index 2cce0fe50..7daaad1f3 100644 --- a/src/app/hooks/useDeviceList.js +++ b/src/app/hooks/useDeviceList.js @@ -1,10 +1,9 @@ /* eslint-disable import/prefer-default-export */ import { useState, useEffect } from 'react'; - -import initMatrix from '../../client/initMatrix'; +import { useMatrixClient } from './useMatrixClient'; export function useDeviceList() { - const mx = initMatrix.matrixClient; + const mx = useMatrixClient(); const [deviceList, setDeviceList] = useState(null); useEffect(() => { @@ -27,6 +26,6 @@ export function useDeviceList() { mx.removeListener('crypto.devicesUpdated', handleDevicesUpdate); isMounted = false; }; - }, []); + }, [mx]); return deviceList; } diff --git a/src/app/hooks/useSyncState.ts b/src/app/hooks/useSyncState.ts index 4b2f41632..be8a6ef2f 100644 --- a/src/app/hooks/useSyncState.ts +++ b/src/app/hooks/useSyncState.ts @@ -2,13 +2,13 @@ import { ClientEvent, ClientEventHandlerMap, MatrixClient } from 'matrix-js-sdk' import { useEffect } from 'react'; export const useSyncState = ( - mx: MatrixClient, + mx: MatrixClient | undefined, onChange: ClientEventHandlerMap[ClientEvent.Sync] ): void => { useEffect(() => { - mx.on(ClientEvent.Sync, onChange); + mx?.on(ClientEvent.Sync, onChange); return () => { - mx.removeListener(ClientEvent.Sync, onChange); + mx?.removeListener(ClientEvent.Sync, onChange); }; }, [mx, onChange]); }; diff --git a/src/app/molecules/global-notification/GlobalNotification.jsx b/src/app/molecules/global-notification/GlobalNotification.jsx index 865582ce9..b115c9dcd 100644 --- a/src/app/molecules/global-notification/GlobalNotification.jsx +++ b/src/app/molecules/global-notification/GlobalNotification.jsx @@ -1,6 +1,5 @@ import React from 'react'; -import initMatrix from '../../../client/initMatrix'; import { openReusableContextMenu } from '../../../client/action/navigation'; import { getEventCords } from '../../../util/common'; @@ -14,6 +13,7 @@ import NotificationSelector from './NotificationSelector'; import ChevronBottomIC from '../../../../public/res/ic/outlined/chevron-bottom.svg'; import { useAccountData } from '../../hooks/useAccountData'; +import { useMatrixClient } from '../../hooks/useMatrixClient'; export const notifType = { ON: 'on', @@ -52,7 +52,7 @@ export function getTypeActions(type, highlightValue = false) { } function useGlobalNotif() { - const mx = initMatrix.matrixClient; + const mx = useMatrixClient(); const pushRules = useAccountData('m.push_rules')?.getContent(); const underride = pushRules?.global?.underride ?? []; const rulesToType = { diff --git a/src/app/molecules/global-notification/IgnoreUserList.jsx b/src/app/molecules/global-notification/IgnoreUserList.jsx index 87ee6272f..1b44a0417 100644 --- a/src/app/molecules/global-notification/IgnoreUserList.jsx +++ b/src/app/molecules/global-notification/IgnoreUserList.jsx @@ -1,7 +1,6 @@ import React from 'react'; import './IgnoreUserList.scss'; -import initMatrix from '../../../client/initMatrix'; import * as roomActions from '../../../client/action/room'; import Text from '../../atoms/text/Text'; @@ -14,10 +13,12 @@ import SettingTile from '../setting-tile/SettingTile'; import CrossIC from '../../../../public/res/ic/outlined/cross.svg'; import { useAccountData } from '../../hooks/useAccountData'; +import { useMatrixClient } from '../../hooks/useMatrixClient'; function IgnoreUserList() { useAccountData('m.ignored_user_list'); - const ignoredUsers = initMatrix.matrixClient.getIgnoredUsers(); + const mx = useMatrixClient(); + const ignoredUsers = mx.getIgnoredUsers(); const handleSubmit = (evt) => { evt.preventDefault(); @@ -26,7 +27,7 @@ function IgnoreUserList() { const userIds = value.split(' ').filter((v) => v.match(/^@\S+:\S+$/)); if (userIds.length === 0) return; ignoreInput.value = ''; - roomActions.ignore(userIds); + roomActions.ignore(mx, userIds); }; return ( @@ -49,7 +50,7 @@ function IgnoreUserList() { key={uId} text={uId} iconColor={CrossIC} - onClick={() => roomActions.unignore([uId])} + onClick={() => roomActions.unignore(mx, [uId])} /> ))}
      diff --git a/src/app/molecules/global-notification/KeywordNotification.jsx b/src/app/molecules/global-notification/KeywordNotification.jsx index 8484d41d1..7f7e4dead 100644 --- a/src/app/molecules/global-notification/KeywordNotification.jsx +++ b/src/app/molecules/global-notification/KeywordNotification.jsx @@ -1,7 +1,6 @@ import React from 'react'; import './KeywordNotification.scss'; -import initMatrix from '../../../client/initMatrix'; import { openReusableContextMenu } from '../../../client/action/navigation'; import { getEventCords } from '../../../util/common'; @@ -21,6 +20,7 @@ import { useAccountData } from '../../hooks/useAccountData'; import { notifType, typeToLabel, getActionType, getTypeActions, } from './GlobalNotification'; +import { useMatrixClient } from '../../hooks/useMatrixClient'; const DISPLAY_NAME = '.m.rule.contains_display_name'; const ROOM_PING = '.m.rule.roomnotif'; @@ -28,7 +28,7 @@ const USERNAME = '.m.rule.contains_user_name'; const KEYWORD = 'keyword'; function useKeywordNotif() { - const mx = initMatrix.matrixClient; + const mx = useMatrixClient(); const pushRules = useAccountData('m.push_rules')?.getContent(); const override = pushRules?.global?.override ?? []; const content = pushRules?.global?.content ?? []; diff --git a/src/app/molecules/image-pack/ImagePack.jsx b/src/app/molecules/image-pack/ImagePack.jsx index f88886c1b..51ffd0d35 100644 --- a/src/app/molecules/image-pack/ImagePack.jsx +++ b/src/app/molecules/image-pack/ImagePack.jsx @@ -4,7 +4,6 @@ import React, { import PropTypes from 'prop-types'; import './ImagePack.scss'; -import initMatrix from '../../../client/initMatrix'; import { openReusableDialog } from '../../../client/action/navigation'; import { suffixRename } from '../../../util/common'; @@ -19,6 +18,7 @@ import { confirmDialog } from '../confirm-dialog/ConfirmDialog'; import ImagePackProfile from './ImagePackProfile'; import ImagePackItem from './ImagePackItem'; import ImagePackUpload from './ImagePackUpload'; +import { useMatrixClient } from '../../hooks/useMatrixClient'; const renameImagePackItem = (shortcode) => new Promise((resolve) => { let isCompleted = false; @@ -63,8 +63,7 @@ function getUsage(usage) { return 'both'; } -function isGlobalPack(roomId, stateKey) { - const mx = initMatrix.matrixClient; +function isGlobalPack(mx, roomId, stateKey) { const globalContent = mx.getAccountData('im.ponies.emote_rooms')?.getContent(); if (typeof globalContent !== 'object') return false; @@ -75,13 +74,13 @@ function isGlobalPack(roomId, stateKey) { } function useRoomImagePack(roomId, stateKey) { - const mx = initMatrix.matrixClient; + const mx = useMatrixClient(); const room = mx.getRoom(roomId); - const packEvent = room.currentState.getStateEvents('im.ponies.room_emotes', stateKey); - const pack = useMemo(() => ( - ImagePackBuilder.parsePack(packEvent.getId(), packEvent.getContent()) - ), [room, stateKey]); + const pack = useMemo(() => { + const packEvent = room.currentState.getStateEvents('im.ponies.room_emotes', stateKey); + return ImagePackBuilder.parsePack(packEvent.getId(), packEvent.getContent()) + }, [room, stateKey]); const sendPackContent = (content) => { mx.sendStateEvent(roomId, 'im.ponies.room_emotes', content, stateKey); @@ -94,14 +93,14 @@ function useRoomImagePack(roomId, stateKey) { } function useUserImagePack() { - const mx = initMatrix.matrixClient; - const packEvent = mx.getAccountData('im.ponies.user_emotes'); - const pack = useMemo(() => ( - ImagePackBuilder.parsePack(mx.getUserId(), packEvent?.getContent() ?? { + const mx = useMatrixClient(); + const pack = useMemo(() => { + const packEvent = mx.getAccountData('im.ponies.user_emotes'); + return ImagePackBuilder.parsePack(mx.getUserId(), packEvent?.getContent() ?? { pack: { display_name: 'Personal' }, images: {}, }) - ), []); + }, [mx]); const sendPackContent = (content) => { mx.setAccountData('im.ponies.user_emotes', content); @@ -223,10 +222,10 @@ function removeGlobalImagePack(mx, roomId, stateKey) { } function ImagePack({ roomId, stateKey, handlePackDelete }) { - const mx = initMatrix.matrixClient; + const mx = useMatrixClient(); const room = mx.getRoom(roomId); const [viewMore, setViewMore] = useState(false); - const [isGlobal, setIsGlobal] = useState(isGlobalPack(roomId, stateKey)); + const [isGlobal, setIsGlobal] = useState(isGlobalPack(mx, roomId, stateKey)); const { pack, sendPackContent } = useRoomImagePack(roomId, stateKey); @@ -331,7 +330,7 @@ ImagePack.propTypes = { }; function ImagePackUser() { - const mx = initMatrix.matrixClient; + const mx = useMatrixClient(); const [viewMore, setViewMore] = useState(false); const { pack, sendPackContent } = useUserImagePack(); @@ -397,7 +396,7 @@ function ImagePackUser() { function useGlobalImagePack() { const [, forceUpdate] = useReducer((count) => count + 1, 0); - const mx = initMatrix.matrixClient; + const mx = useMatrixClient(); const roomIdToStateKeys = new Map(); const globalContent = mx.getAccountData('im.ponies.emote_rooms')?.getContent() ?? { rooms: {} }; @@ -419,13 +418,13 @@ function useGlobalImagePack() { return () => { mx.removeListener('accountData', handleEvent); }; - }, []); + }, [mx]); return roomIdToStateKeys; } function ImagePackGlobal() { - const mx = initMatrix.matrixClient; + const mx = useMatrixClient(); const roomIdToStateKeys = useGlobalImagePack(); const handleChange = (roomId, stateKey) => { diff --git a/src/app/molecules/image-pack/ImagePackUpload.jsx b/src/app/molecules/image-pack/ImagePackUpload.jsx index 6295de1ce..cdf2e13b6 100644 --- a/src/app/molecules/image-pack/ImagePackUpload.jsx +++ b/src/app/molecules/image-pack/ImagePackUpload.jsx @@ -2,7 +2,6 @@ import React, { useState, useRef } from 'react'; import PropTypes from 'prop-types'; import './ImagePackUpload.scss'; -import initMatrix from '../../../client/initMatrix'; import { scaleDownImage } from '../../../util/common'; import Text from '../../atoms/text/Text'; @@ -10,9 +9,10 @@ import Button from '../../atoms/button/Button'; import Input from '../../atoms/input/Input'; import IconButton from '../../atoms/button/IconButton'; import CirclePlusIC from '../../../../public/res/ic/outlined/circle-plus.svg'; +import { useMatrixClient } from '../../hooks/useMatrixClient'; function ImagePackUpload({ onUpload }) { - const mx = initMatrix.matrixClient; + const mx = useMatrixClient(); const inputRef = useRef(null); const shortcodeRef = useRef(null); const [imgFile, setImgFile] = useState(null); diff --git a/src/app/molecules/image-upload/ImageUpload.jsx b/src/app/molecules/image-upload/ImageUpload.jsx index 53fc7e161..5213381f8 100644 --- a/src/app/molecules/image-upload/ImageUpload.jsx +++ b/src/app/molecules/image-upload/ImageUpload.jsx @@ -2,7 +2,6 @@ import React, { useState, useRef } from 'react'; import PropTypes from 'prop-types'; import './ImageUpload.scss'; -import initMatrix from '../../../client/initMatrix'; import Text from '../../atoms/text/Text'; import Avatar from '../../atoms/avatar/Avatar'; @@ -10,6 +9,7 @@ import Spinner from '../../atoms/spinner/Spinner'; import RawIcon from '../../atoms/system-icons/RawIcon'; import PlusIC from '../../../../public/res/ic/outlined/plus.svg'; +import { useMatrixClient } from '../../hooks/useMatrixClient'; function ImageUpload({ text, bgColor, imageSrc, onUpload, onRequestRemove, @@ -17,12 +17,13 @@ function ImageUpload({ }) { const [uploadPromise, setUploadPromise] = useState(null); const uploadImageRef = useRef(null); + const mx = useMatrixClient(); async function uploadImage(e) { const file = e.target.files.item(0); if (file === null) return; try { - const uPromise = initMatrix.matrixClient.uploadContent(file); + const uPromise = mx.uploadContent(file); setUploadPromise(uPromise); const res = await uPromise; @@ -35,7 +36,7 @@ function ImageUpload({ } function cancelUpload() { - initMatrix.matrixClient.cancelUpload(uploadPromise); + mx.cancelUpload(uploadPromise); setUploadPromise(null); uploadImageRef.current.value = null; } diff --git a/src/app/molecules/import-export-e2e-room-keys/ExportE2ERoomKeys.jsx b/src/app/molecules/import-export-e2e-room-keys/ExportE2ERoomKeys.jsx index b7738a6a5..1ce7e78ad 100644 --- a/src/app/molecules/import-export-e2e-room-keys/ExportE2ERoomKeys.jsx +++ b/src/app/molecules/import-export-e2e-room-keys/ExportE2ERoomKeys.jsx @@ -3,7 +3,6 @@ import './ExportE2ERoomKeys.scss'; import FileSaver from 'file-saver'; -import initMatrix from '../../../client/initMatrix'; import cons from '../../../client/state/cons'; import { encryptMegolmKeyFile } from '../../../util/cryptE2ERoomKeys'; @@ -13,8 +12,10 @@ import Input from '../../atoms/input/Input'; import Spinner from '../../atoms/spinner/Spinner'; import { useStore } from '../../hooks/useStore'; +import { useMatrixClient } from '../../hooks/useMatrixClient'; function ExportE2ERoomKeys() { + const mx = useMatrixClient(); const isMountStore = useStore(); const [status, setStatus] = useState({ isOngoing: false, @@ -40,7 +41,7 @@ function ExportE2ERoomKeys() { type: cons.status.IN_FLIGHT, }); try { - const keys = await initMatrix.matrixClient.exportRoomKeys(); + const keys = await mx.exportRoomKeys(); if (isMountStore.getItem()) { setStatus({ isOngoing: true, diff --git a/src/app/molecules/import-export-e2e-room-keys/ImportE2ERoomKeys.jsx b/src/app/molecules/import-export-e2e-room-keys/ImportE2ERoomKeys.jsx index b5a44b0ea..9f0ab793e 100644 --- a/src/app/molecules/import-export-e2e-room-keys/ImportE2ERoomKeys.jsx +++ b/src/app/molecules/import-export-e2e-room-keys/ImportE2ERoomKeys.jsx @@ -1,7 +1,6 @@ import React, { useState, useEffect, useRef } from 'react'; import './ImportE2ERoomKeys.scss'; -import initMatrix from '../../../client/initMatrix'; import cons from '../../../client/state/cons'; import { decryptMegolmKeyFile } from '../../../util/cryptE2ERoomKeys'; @@ -14,8 +13,10 @@ import Spinner from '../../atoms/spinner/Spinner'; import CirclePlusIC from '../../../../public/res/ic/outlined/circle-plus.svg'; import { useStore } from '../../hooks/useStore'; +import { useMatrixClient } from '../../hooks/useMatrixClient'; function ImportE2ERoomKeys() { + const mx = useMatrixClient(); const isMountStore = useStore(); const [keyFile, setKeyFile] = useState(null); const [status, setStatus] = useState({ @@ -45,7 +46,7 @@ function ImportE2ERoomKeys() { type: cons.status.IN_FLIGHT, }); } - await initMatrix.matrixClient.importRoomKeys(JSON.parse(keys)); + await mx.importRoomKeys(JSON.parse(keys)); if (isMountStore.getItem()) { setStatus({ isOngoing: false, diff --git a/src/app/molecules/room-aliases/RoomAliases.jsx b/src/app/molecules/room-aliases/RoomAliases.jsx index d573f7d6a..876d063fa 100644 --- a/src/app/molecules/room-aliases/RoomAliases.jsx +++ b/src/app/molecules/room-aliases/RoomAliases.jsx @@ -2,7 +2,6 @@ import React, { useState, useEffect } from 'react'; import PropTypes from 'prop-types'; import './RoomAliases.scss'; -import initMatrix from '../../../client/initMatrix'; import cons from '../../../client/state/cons'; import { Debounce } from '../../../util/common'; import { isRoomAliasAvailable } from '../../../util/matrixUtil'; @@ -16,8 +15,10 @@ import { MenuHeader } from '../../atoms/context-menu/ContextMenu'; import SettingTile from '../setting-tile/SettingTile'; import { useStore } from '../../hooks/useStore'; +import { useMatrixClient } from '../../hooks/useMatrixClient'; function useValidate(hsString) { + const mx = useMatrixClient(); const [debounce] = useState(new Debounce()); const [validate, setValidate] = useState({ alias: null, status: cons.status.PRE_FLIGHT }); @@ -62,7 +63,7 @@ function useValidate(hsString) { msg: `validating ${alias}...`, }); - const isValid = await isRoomAliasAvailable(alias); + const isValid = await isRoomAliasAvailable(mx, alias); setValidate(() => { if (e.target.value !== value) { return { alias: null, status: cons.status.PRE_FLIGHT }; @@ -79,8 +80,7 @@ function useValidate(hsString) { return [validate, setValidateToDefault, handleAliasChange]; } -function getAliases(roomId) { - const mx = initMatrix.matrixClient; +function getAliases(mx, roomId) { const room = mx.getRoom(roomId); const main = room.getCanonicalAlias(); @@ -95,7 +95,7 @@ function getAliases(roomId) { } function RoomAliases({ roomId }) { - const mx = initMatrix.matrixClient; + const mx = useMatrixClient(); const room = mx.getRoom(roomId); const userId = mx.getUserId(); const hsString = userId.slice(userId.indexOf(':') + 1); @@ -103,7 +103,7 @@ function RoomAliases({ roomId }) { const isMountedStore = useStore(); const [isPublic, setIsPublic] = useState(false); const [isLocalVisible, setIsLocalVisible] = useState(false); - const [aliases, setAliases] = useState(getAliases(roomId)); + const [aliases, setAliases] = useState(getAliases(mx, roomId)); const [selectedAlias, setSelectedAlias] = useState(null); const [deleteAlias, setDeleteAlias] = useState(null); const [validate, setValidateToDefault, handleAliasChange] = useValidate(hsString); @@ -140,7 +140,7 @@ function RoomAliases({ roomId }) { return () => { isUnmounted = true; }; - }, [roomId]); + }, [mx, roomId]); const toggleDirectoryVisibility = () => { mx.setRoomDirectoryVisibility(roomId, isPublic ? 'private' : 'public'); diff --git a/src/app/molecules/room-emojis/RoomEmojis.jsx b/src/app/molecules/room-emojis/RoomEmojis.jsx index 94ae61074..da09ea864 100644 --- a/src/app/molecules/room-emojis/RoomEmojis.jsx +++ b/src/app/molecules/room-emojis/RoomEmojis.jsx @@ -2,7 +2,6 @@ import React, { useReducer, useEffect } from 'react'; import PropTypes from 'prop-types'; import './RoomEmojis.scss'; -import initMatrix from '../../../client/initMatrix'; import { suffixRename } from '../../../util/common'; import { MenuHeader } from '../../atoms/context-menu/ContextMenu'; @@ -10,9 +9,10 @@ import Text from '../../atoms/text/Text'; import Input from '../../atoms/input/Input'; import Button from '../../atoms/button/Button'; import ImagePack from '../image-pack/ImagePack'; +import { useMatrixClient } from '../../hooks/useMatrixClient'; function useRoomPacks(room) { - const mx = initMatrix.matrixClient; + const mx = useMatrixClient(); const [, forceUpdate] = useReducer((count) => count + 1, 0); const packEvents = room.currentState.getStateEvents('im.ponies.room_emotes'); @@ -75,7 +75,7 @@ function useRoomPacks(room) { } function RoomEmojis({ roomId }) { - const mx = initMatrix.matrixClient; + const mx = useMatrixClient(); const room = mx.getRoom(roomId); const { usablePacks, createPack, deletePack } = useRoomPacks(room); diff --git a/src/app/molecules/room-encryption/RoomEncryption.jsx b/src/app/molecules/room-encryption/RoomEncryption.jsx index 1657f3631..47250f472 100644 --- a/src/app/molecules/room-encryption/RoomEncryption.jsx +++ b/src/app/molecules/room-encryption/RoomEncryption.jsx @@ -2,16 +2,16 @@ import React, { useState } from 'react'; import PropTypes from 'prop-types'; import './RoomEncryption.scss'; -import initMatrix from '../../../client/initMatrix'; import Text from '../../atoms/text/Text'; import Toggle from '../../atoms/button/Toggle'; import SettingTile from '../setting-tile/SettingTile'; import { confirmDialog } from '../confirm-dialog/ConfirmDialog'; +import { useMatrixClient } from '../../hooks/useMatrixClient'; function RoomEncryption({ roomId }) { - const mx = initMatrix.matrixClient; + const mx = useMatrixClient(); const room = mx.getRoom(roomId); const encryptionEvents = room.currentState.getStateEvents('m.room.encryption'); const [isEncrypted, setIsEncrypted] = useState(encryptionEvents.length > 0); diff --git a/src/app/molecules/room-history-visibility/RoomHistoryVisibility.jsx b/src/app/molecules/room-history-visibility/RoomHistoryVisibility.jsx index d9dd9540f..c897cb358 100644 --- a/src/app/molecules/room-history-visibility/RoomHistoryVisibility.jsx +++ b/src/app/molecules/room-history-visibility/RoomHistoryVisibility.jsx @@ -2,11 +2,11 @@ import React, { useState, useEffect, useCallback } from 'react'; import PropTypes from 'prop-types'; import './RoomHistoryVisibility.scss'; -import initMatrix from '../../../client/initMatrix'; import Text from '../../atoms/text/Text'; import RadioButton from '../../atoms/button/RadioButton'; import { MenuItem } from '../../atoms/context-menu/ContextMenu'; +import { useMatrixClient } from '../../hooks/useMatrixClient'; const visibility = { WORLD_READABLE: 'world_readable', @@ -33,38 +33,33 @@ const items = [{ type: visibility.JOINED, }]; -function setHistoryVisibility(roomId, type) { - const mx = initMatrix.matrixClient; - - return mx.sendStateEvent( - roomId, 'm.room.history_visibility', - { - history_visibility: type, - }, - ); -} function useVisibility(roomId) { - const mx = initMatrix.matrixClient; + const mx = useMatrixClient(); const room = mx.getRoom(roomId); const [activeType, setActiveType] = useState(room.getHistoryVisibility()); useEffect(() => { setActiveType(room.getHistoryVisibility()); - }, [roomId]); + }, [room]); const setVisibility = useCallback((item) => { if (item.type === activeType.type) return; setActiveType(item.type); - setHistoryVisibility(roomId, item.type); - }, [activeType, roomId]); + mx.sendStateEvent( + roomId, 'm.room.history_visibility', + { + history_visibility: item.type, + }, + ); + }, [mx, activeType, roomId]); return [activeType, setVisibility]; } function RoomHistoryVisibility({ roomId }) { const [activeType, setVisibility] = useVisibility(roomId); - const mx = initMatrix.matrixClient; + const mx = useMatrixClient(); const userId = mx.getUserId(); const room = mx.getRoom(roomId); const { currentState } = room; diff --git a/src/app/molecules/room-members/RoomMembers.jsx b/src/app/molecules/room-members/RoomMembers.jsx index f931f9dde..a3928fb7d 100644 --- a/src/app/molecules/room-members/RoomMembers.jsx +++ b/src/app/molecules/room-members/RoomMembers.jsx @@ -4,7 +4,6 @@ import React, { import PropTypes from 'prop-types'; import './RoomMembers.scss'; -import initMatrix from '../../../client/initMatrix'; import colorMXID from '../../../util/colorMXID'; import { openProfileViewer } from '../../../client/action/navigation'; import { getUsernameOfRoomMember, getPowerLabel } from '../../../util/matrixUtil'; @@ -17,11 +16,11 @@ import Input from '../../atoms/input/Input'; import { MenuHeader } from '../../atoms/context-menu/ContextMenu'; import SegmentedControls from '../../atoms/segmented-controls/SegmentedControls'; import PeopleSelector from '../people-selector/PeopleSelector'; +import { useMatrixClient } from '../../hooks/useMatrixClient'; const PER_PAGE_MEMBER = 50; -function normalizeMembers(members) { - const mx = initMatrix.matrixClient; +function normalizeMembers(mx, members) { return members.map((member) => ({ userId: member.userId, name: getUsernameOfRoomMember(member), @@ -33,7 +32,7 @@ function normalizeMembers(members) { } function useMemberOfMembership(roomId, membership) { - const mx = initMatrix.matrixClient; + const mx = useMatrixClient(); const room = mx.getRoom(roomId); const [members, setMembers] = useState([]); @@ -45,6 +44,7 @@ function useMemberOfMembership(roomId, membership) { if (isLoadingMembers) return; if (event && event?.getRoomId() !== roomId) return; const memberOfMembership = normalizeMembers( + mx, room.getMembersWithMembership(membership) .sort(memberByAtoZ).sort(memberByPowerLevel), ); @@ -66,7 +66,7 @@ function useMemberOfMembership(roomId, membership) { mx.removeListener('RoomMember.membership', updateMemberList); mx.removeListener('RoomMember.powerLevel', updateMemberList); }; - }, [membership]); + }, [mx, membership]); return [members]; } diff --git a/src/app/molecules/room-notification/RoomNotification.jsx b/src/app/molecules/room-notification/RoomNotification.jsx index 821ea5084..db9707083 100644 --- a/src/app/molecules/room-notification/RoomNotification.jsx +++ b/src/app/molecules/room-notification/RoomNotification.jsx @@ -2,7 +2,6 @@ import React, { useState, useEffect, useCallback } from 'react'; import PropTypes from 'prop-types'; import './RoomNotification.scss'; -import initMatrix from '../../../client/initMatrix'; import cons from '../../../client/state/cons'; import Text from '../../atoms/text/Text'; @@ -14,6 +13,7 @@ import BellRingIC from '../../../../public/res/ic/outlined/bell-ring.svg'; import BellPingIC from '../../../../public/res/ic/outlined/bell-ping.svg'; import BellOffIC from '../../../../public/res/ic/outlined/bell-off.svg'; import { getNotificationType } from '../../utils/room'; +import { useMatrixClient } from '../../hooks/useMatrixClient'; const items = [ { @@ -38,8 +38,7 @@ const items = [ }, ]; -function setRoomNotifType(roomId, newType) { - const mx = initMatrix.matrixClient; +function setRoomNotifType(mx, roomId, newType) { let roomPushRule; try { roomPushRule = mx.getRoomPushRule('global', roomId); @@ -108,7 +107,7 @@ function setRoomNotifType(roomId, newType) { } function useNotifications(roomId) { - const mx = initMatrix.matrixClient; + const mx = useMatrixClient(); const [activeType, setActiveType] = useState(getNotificationType(mx, roomId)); useEffect(() => { setActiveType(getNotificationType(mx, roomId)); @@ -118,9 +117,9 @@ function useNotifications(roomId) { (item) => { if (item.type === activeType.type) return; setActiveType(item.type); - setRoomNotifType(roomId, item.type); + setRoomNotifType(mx, roomId, item.type); }, - [activeType, roomId] + [mx, activeType, roomId] ); return [activeType, setNotification]; } diff --git a/src/app/molecules/room-permissions/RoomPermissions.jsx b/src/app/molecules/room-permissions/RoomPermissions.jsx index da8720cdd..f8cd048f5 100644 --- a/src/app/molecules/room-permissions/RoomPermissions.jsx +++ b/src/app/molecules/room-permissions/RoomPermissions.jsx @@ -2,7 +2,6 @@ import React, { useEffect } from 'react'; import PropTypes from 'prop-types'; import './RoomPermissions.scss'; -import initMatrix from '../../../client/initMatrix'; import { getPowerLabel } from '../../../util/matrixUtil'; import { openReusableContextMenu } from '../../../client/action/navigation'; import { getEventCords } from '../../../util/common'; @@ -16,6 +15,7 @@ import SettingTile from '../setting-tile/SettingTile'; import ChevronBottomIC from '../../../../public/res/ic/outlined/chevron-bottom.svg'; import { useForceUpdate } from '../../hooks/useForceUpdate'; +import { useMatrixClient } from '../../hooks/useMatrixClient'; const permissionsInfo = { users_default: { @@ -157,7 +157,7 @@ const spacePermsGroups = { function useRoomStateUpdate(roomId) { const [, forceUpdate] = useForceUpdate(); - const mx = initMatrix.matrixClient; + const mx = useMatrixClient(); useEffect(() => { const handleStateEvent = (event) => { @@ -169,12 +169,12 @@ function useRoomStateUpdate(roomId) { return () => { mx.removeListener('RoomState.events', handleStateEvent); }; - }, [roomId]); + }, [mx, roomId]); } function RoomPermissions({ roomId }) { useRoomStateUpdate(roomId); - const mx = initMatrix.matrixClient; + const mx = useMatrixClient(); const room = mx.getRoom(roomId); const pLEvent = room.currentState.getStateEvents('m.room.power_levels')[0]; const permissions = pLEvent.getContent(); diff --git a/src/app/molecules/room-profile/RoomProfile.jsx b/src/app/molecules/room-profile/RoomProfile.jsx index 15273ebfd..da8ce755a 100644 --- a/src/app/molecules/room-profile/RoomProfile.jsx +++ b/src/app/molecules/room-profile/RoomProfile.jsx @@ -4,7 +4,6 @@ import { useAtomValue } from 'jotai'; import Linkify from 'linkify-react'; import './RoomProfile.scss'; -import initMatrix from '../../../client/initMatrix'; import cons from '../../../client/state/cons'; import colorMXID from '../../../util/colorMXID'; @@ -22,6 +21,7 @@ import { useForceUpdate } from '../../hooks/useForceUpdate'; import { confirmDialog } from '../confirm-dialog/ConfirmDialog'; import { mDirectAtom } from '../../state/mDirectList'; import { LINKIFY_OPTS } from '../../plugins/react-custom-html-parser'; +import { useMatrixClient } from '../../hooks/useMatrixClient'; function RoomProfile({ roomId }) { const isMountStore = useStore(); @@ -32,7 +32,7 @@ function RoomProfile({ roomId }) { type: cons.status.PRE_FLIGHT, }); - const mx = initMatrix.matrixClient; + const mx = useMatrixClient(); const mDirects = useAtomValue(mDirectAtom); const isDM = mDirects.has(roomId); let avatarSrc = mx.getRoom(roomId).getAvatarUrl(mx.baseUrl, 36, 36, 'crop'); @@ -67,7 +67,7 @@ function RoomProfile({ roomId }) { }); setIsEditing(false); }; - }, [roomId]); + }, [mx, roomId]); const handleOnSubmit = async (e) => { e.preventDefault(); diff --git a/src/app/molecules/room-visibility/RoomVisibility.jsx b/src/app/molecules/room-visibility/RoomVisibility.jsx index a5e8e2d08..6579513a8 100644 --- a/src/app/molecules/room-visibility/RoomVisibility.jsx +++ b/src/app/molecules/room-visibility/RoomVisibility.jsx @@ -2,7 +2,6 @@ import React, { useState, useEffect, useCallback } from 'react'; import PropTypes from 'prop-types'; import './RoomVisibility.scss'; -import initMatrix from '../../../client/initMatrix'; import Text from '../../atoms/text/Text'; import RadioButton from '../../atoms/button/RadioButton'; @@ -14,6 +13,7 @@ import HashGlobeIC from '../../../../public/res/ic/outlined/hash-globe.svg'; import SpaceIC from '../../../../public/res/ic/outlined/space.svg'; import SpaceLockIC from '../../../../public/res/ic/outlined/space-lock.svg'; import SpaceGlobeIC from '../../../../public/res/ic/outlined/space-globe.svg'; +import { useMatrixClient } from '../../hooks/useMatrixClient'; const visibility = { INVITE: 'invite', @@ -21,8 +21,7 @@ const visibility = { PUBLIC: 'public', }; -function setJoinRule(roomId, type) { - const mx = initMatrix.matrixClient; +function setJoinRule(mx, roomId, type) { let allow; if (type === visibility.RESTRICTED) { const { currentState } = mx.getRoom(roomId); @@ -46,26 +45,26 @@ function setJoinRule(roomId, type) { } function useVisibility(roomId) { - const mx = initMatrix.matrixClient; + const mx = useMatrixClient(); const room = mx.getRoom(roomId); const [activeType, setActiveType] = useState(room.getJoinRule()); useEffect(() => { setActiveType(room.getJoinRule()); - }, [roomId]); + }, [room]); const setNotification = useCallback((item) => { if (item.type === activeType.type) return; setActiveType(item.type); - setJoinRule(roomId, item.type); - }, [activeType, roomId]); + setJoinRule(mx, roomId, item.type); + }, [mx, activeType, roomId]); return [activeType, setNotification]; } function RoomVisibility({ roomId }) { const [activeType, setVisibility] = useVisibility(roomId); - const mx = initMatrix.matrixClient; + const mx = useMatrixClient(); const room = mx.getRoom(roomId); const isSpace = room.isSpaceRoom(); const { currentState } = room; diff --git a/src/app/molecules/space-add-existing/SpaceAddExisting.jsx b/src/app/molecules/space-add-existing/SpaceAddExisting.jsx index 2eb94a5c0..ff338f3f8 100644 --- a/src/app/molecules/space-add-existing/SpaceAddExisting.jsx +++ b/src/app/molecules/space-add-existing/SpaceAddExisting.jsx @@ -3,7 +3,6 @@ import PropTypes from 'prop-types'; import { useAtomValue } from 'jotai'; import './SpaceAddExisting.scss'; -import initMatrix from '../../../client/initMatrix'; import cons from '../../../client/state/cons'; import navigation from '../../../client/state/navigation'; import { joinRuleToIconSrc, getIdServer, genRoomVia } from '../../../util/matrixUtil'; @@ -27,6 +26,7 @@ import { roomToParentsAtom } from '../../state/room/roomToParents'; import { useDirects, useRooms, useSpaces } from '../../state/hooks/roomList'; import { allRoomsAtom } from '../../state/room-list/roomList'; import { mDirectAtom } from '../../state/mDirectList'; +import { useMatrixClient } from '../../hooks/useMatrixClient'; function SpaceAddExistingContent({ roomId, spaces: onlySpaces }) { const mountStore = useStore(roomId); @@ -35,7 +35,7 @@ function SpaceAddExistingContent({ roomId, spaces: onlySpaces }) { const [allRoomIds, setAllRoomIds] = useState([]); const [selected, setSelected] = useState([]); const [searchIds, setSearchIds] = useState(null); - const mx = initMatrix.matrixClient; + const mx = useMatrixClient(); const roomIdToParents = useAtomValue(roomToParentsAtom); const mDirects = useAtomValue(mDirectAtom); const spaces = useSpaces(mx, allRoomsAtom); @@ -48,7 +48,7 @@ function SpaceAddExistingContent({ roomId, spaces: onlySpaces }) { (rId) => rId !== roomId && !roomIdToParents.get(rId)?.has(roomId) ); setAllRoomIds(allIds); - }, [roomId, onlySpaces]); + }, [spaces, rooms, directs, roomIdToParents, roomId, onlySpaces]); const toggleSelection = (rId) => { if (process !== null) return; @@ -215,7 +215,7 @@ function useVisibilityToggle() { function SpaceAddExisting() { const [data, requestClose] = useVisibilityToggle(); - const mx = initMatrix.matrixClient; + const mx = useMatrixClient(); const room = mx.getRoom(data?.roomId); return ( diff --git a/src/app/organisms/create-room/CreateRoom.jsx b/src/app/organisms/create-room/CreateRoom.jsx index ff00cca19..04b2faebe 100644 --- a/src/app/organisms/create-room/CreateRoom.jsx +++ b/src/app/organisms/create-room/CreateRoom.jsx @@ -2,7 +2,6 @@ import React, { useState, useEffect, useRef } from 'react'; import PropTypes from 'prop-types'; import './CreateRoom.scss'; -import initMatrix from '../../../client/initMatrix'; import cons from '../../../client/state/cons'; import navigation from '../../../client/state/navigation'; import { openReusableContextMenu } from '../../../client/action/navigation'; @@ -32,6 +31,7 @@ import SpaceGlobeIC from '../../../../public/res/ic/outlined/space-globe.svg'; import ChevronBottomIC from '../../../../public/res/ic/outlined/chevron-bottom.svg'; import CrossIC from '../../../../public/res/ic/outlined/cross.svg'; import { useRoomNavigate } from '../../hooks/useRoomNavigate'; +import { useMatrixClient } from '../../hooks/useMatrixClient'; function CreateRoomContent({ isSpace, parentId, onRequestClose }) { const [joinRule, setJoinRule] = useState(parentId ? 'restricted' : 'invite'); @@ -46,7 +46,7 @@ function CreateRoomContent({ isSpace, parentId, onRequestClose }) { const addressRef = useRef(null); - const mx = initMatrix.matrixClient; + const mx = useMatrixClient(); const userHs = getIdServer(mx.getUserId()); const handleSubmit = async (evt) => { @@ -69,7 +69,7 @@ function CreateRoomContent({ isSpace, parentId, onRequestClose }) { const powerLevel = roleIndex === 1 ? 101 : undefined; try { - const data = await roomActions.createRoom({ + const data = await roomActions.createRoom(mx, { name, topic, joinRule, @@ -113,7 +113,7 @@ function CreateRoomContent({ isSpace, parentId, onRequestClose }) { if (roomAlias === '') return; const roomAddress = `#${roomAlias}:${userHs}`; - if (await isRoomAliasAvailable(roomAddress)) { + if (await isRoomAliasAvailable(mx, roomAddress)) { setIsValidAddress(true); } else { setIsValidAddress(false); @@ -278,7 +278,7 @@ function useWindowToggle() { function CreateRoom() { const [create, onRequestClose] = useWindowToggle(); const { isSpace, parentId } = create ?? {}; - const mx = initMatrix.matrixClient; + const mx = useMatrixClient(); const room = mx.getRoom(parentId); return ( diff --git a/src/app/organisms/emoji-verification/EmojiVerification.jsx b/src/app/organisms/emoji-verification/EmojiVerification.jsx index 1b543c052..21be477f2 100644 --- a/src/app/organisms/emoji-verification/EmojiVerification.jsx +++ b/src/app/organisms/emoji-verification/EmojiVerification.jsx @@ -3,7 +3,6 @@ import React, { useState, useEffect } from 'react'; import PropTypes from 'prop-types'; import './EmojiVerification.scss'; -import initMatrix from '../../../client/initMatrix'; import cons from '../../../client/state/cons'; import navigation from '../../../client/state/navigation'; import { hasPrivateKey } from '../../../client/state/secretStorageKeys'; @@ -18,23 +17,24 @@ import Dialog from '../../molecules/dialog/Dialog'; import CrossIC from '../../../../public/res/ic/outlined/cross.svg'; import { useStore } from '../../hooks/useStore'; import { accessSecretStorage } from '../settings/SecretStorageAccess'; +import { useMatrixClient } from '../../hooks/useMatrixClient'; function EmojiVerificationContent({ data, requestClose }) { const [sas, setSas] = useState(null); const [process, setProcess] = useState(false); const { request, targetDevice } = data; - const mx = initMatrix.matrixClient; + const mx = useMatrixClient(); const mountStore = useStore(); const beginStore = useStore(); const beginVerification = async () => { if ( - isCrossVerified(mx.deviceId) && + isCrossVerified(mx, mx.deviceId) && (mx.getCrossSigningId() === null || (await mx.crypto.crossSigningInfo.isStoredInKeyCache('self_signing')) === false) ) { - if (!hasPrivateKey(getDefaultSSKey())) { - const keyData = await accessSecretStorage('Emoji verification'); + if (!hasPrivateKey(getDefaultSSKey(mx))) { + const keyData = await accessSecretStorage(mx, 'Emoji verification'); if (!keyData) { request.cancel(); return; @@ -158,7 +158,7 @@ EmojiVerificationContent.propTypes = { function useVisibilityToggle() { const [data, setData] = useState(null); - const mx = initMatrix.matrixClient; + const mx = useMatrixClient(); useEffect(() => { const handleOpen = (request, targetDevice) => { @@ -170,7 +170,7 @@ function useVisibilityToggle() { navigation.removeListener(cons.events.navigation.EMOJI_VERIFICATION_OPENED, handleOpen); mx.removeListener('crypto.verification.request', handleOpen); }; - }, []); + }, [mx]); const requestClose = () => setData(null); diff --git a/src/app/organisms/invite-user/InviteUser.jsx b/src/app/organisms/invite-user/InviteUser.jsx index 10f55f9f6..284be72e1 100644 --- a/src/app/organisms/invite-user/InviteUser.jsx +++ b/src/app/organisms/invite-user/InviteUser.jsx @@ -2,7 +2,6 @@ import React, { useState, useEffect, useRef } from 'react'; import PropTypes from 'prop-types'; import './InviteUser.scss'; -import initMatrix from '../../../client/initMatrix'; import * as roomActions from '../../../client/action/room'; import { hasDevices } from '../../../util/matrixUtil'; @@ -18,6 +17,7 @@ import CrossIC from '../../../../public/res/ic/outlined/cross.svg'; import UserIC from '../../../../public/res/ic/outlined/user.svg'; import { useRoomNavigate } from '../../hooks/useRoomNavigate'; import { getDMRoomFor } from '../../utils/matrix'; +import { useMatrixClient } from '../../hooks/useMatrixClient'; function InviteUser({ isOpen, roomId, searchTerm, onRequestClose }) { const [isSearching, updateIsSearching] = useState(false); @@ -34,7 +34,7 @@ function InviteUser({ isOpen, roomId, searchTerm, onRequestClose }) { const usernameRef = useRef(null); - const mx = initMatrix.matrixClient; + const mx = useMatrixClient(); const { navigateRoom } = useRoomNavigate(); function getMapCopy(myMap) { @@ -118,7 +118,7 @@ function InviteUser({ isOpen, roomId, searchTerm, onRequestClose }) { procUserError.delete(userId); updateUserProcError(getMapCopy(procUserError)); - const result = await roomActions.createDM(userId, await hasDevices(userId)); + const result = await roomActions.createDM(mx, userId, await hasDevices(mx, userId)); roomIdToUserId.set(result.room_id, userId); updateRoomIdToUserId(getMapCopy(roomIdToUserId)); onDMCreated(result.room_id); @@ -137,7 +137,7 @@ function InviteUser({ isOpen, roomId, searchTerm, onRequestClose }) { procUserError.delete(userId); updateUserProcError(getMapCopy(procUserError)); - await roomActions.invite(roomId, userId); + await mx.invite(roomId, userId); invitedUserIds.add(userId); updateInvitedUserIds(new Set(Array.from(invitedUserIds))); diff --git a/src/app/organisms/join-alias/JoinAlias.jsx b/src/app/organisms/join-alias/JoinAlias.jsx index 9fa5542df..99cf6e6ee 100644 --- a/src/app/organisms/join-alias/JoinAlias.jsx +++ b/src/app/organisms/join-alias/JoinAlias.jsx @@ -2,7 +2,6 @@ import React, { useState, useEffect } from 'react'; import PropTypes from 'prop-types'; import './JoinAlias.scss'; -import initMatrix from '../../../client/initMatrix'; import cons from '../../../client/state/cons'; import navigation from '../../../client/state/navigation'; import { join } from '../../../client/action/room'; @@ -18,6 +17,7 @@ import CrossIC from '../../../../public/res/ic/outlined/cross.svg'; import { useStore } from '../../hooks/useStore'; import { useRoomNavigate } from '../../hooks/useRoomNavigate'; +import { useMatrixClient } from '../../hooks/useMatrixClient'; const ALIAS_OR_ID_REG = /^[#|!].+:.+\..+$/; @@ -25,7 +25,7 @@ function JoinAliasContent({ term, requestClose }) { const [process, setProcess] = useState(false); const [error, setError] = useState(undefined); - const mx = initMatrix.matrixClient; + const mx = useMatrixClient(); const mountStore = useStore(); const { navigateRoom } = useRoomNavigate(); @@ -63,7 +63,7 @@ function JoinAliasContent({ term, requestClose }) { } } try { - const roomId = await join(alias, false, via); + const roomId = await join(mx, alias, false, via); if (!mountStore.getItem()) return; openRoom(roomId); } catch { diff --git a/src/app/organisms/profile-editor/ProfileEditor.jsx b/src/app/organisms/profile-editor/ProfileEditor.jsx index c21c82fa4..957093557 100644 --- a/src/app/organisms/profile-editor/ProfileEditor.jsx +++ b/src/app/organisms/profile-editor/ProfileEditor.jsx @@ -1,7 +1,6 @@ import React, { useState, useEffect, useRef } from 'react'; import PropTypes from 'prop-types'; -import initMatrix from '../../../client/initMatrix'; import colorMXID from '../../../util/colorMXID'; import Text from '../../atoms/text/Text'; @@ -14,10 +13,11 @@ import PencilIC from '../../../../public/res/ic/outlined/pencil.svg'; import { confirmDialog } from '../../molecules/confirm-dialog/ConfirmDialog'; import './ProfileEditor.scss'; +import { useMatrixClient } from '../../hooks/useMatrixClient'; function ProfileEditor({ userId }) { const [isEditing, setIsEditing] = useState(false); - const mx = initMatrix.matrixClient; + const mx = useMatrixClient(); const user = mx.getUser(mx.getUserId()); const displayNameRef = useRef(null); @@ -37,7 +37,7 @@ function ProfileEditor({ userId }) { return () => { isMounted = false; }; - }, [userId]); + }, [mx, userId]); const handleAvatarUpload = async (url) => { if (url === null) { diff --git a/src/app/organisms/profile-viewer/ProfileViewer.jsx b/src/app/organisms/profile-viewer/ProfileViewer.jsx index b19c9c867..b4ab74730 100644 --- a/src/app/organisms/profile-viewer/ProfileViewer.jsx +++ b/src/app/organisms/profile-viewer/ProfileViewer.jsx @@ -2,7 +2,6 @@ import React, { useState, useEffect, useRef } from 'react'; import PropTypes from 'prop-types'; import './ProfileViewer.scss'; -import initMatrix from '../../../client/initMatrix'; import cons from '../../../client/state/cons'; import navigation from '../../../client/state/navigation'; import { openReusableContextMenu } from '../../../client/action/navigation'; @@ -36,9 +35,10 @@ import { useForceUpdate } from '../../hooks/useForceUpdate'; import { confirmDialog } from '../../molecules/confirm-dialog/ConfirmDialog'; import { useRoomNavigate } from '../../hooks/useRoomNavigate'; import { getDMRoomFor } from '../../utils/matrix'; +import { useMatrixClient } from '../../hooks/useMatrixClient'; function ModerationTools({ roomId, userId }) { - const mx = initMatrix.matrixClient; + const mx = useMatrixClient(); const room = mx.getRoom(roomId); const roomMember = room.getMember(userId); @@ -56,13 +56,13 @@ function ModerationTools({ roomId, userId }) { const handleKick = (e) => { e.preventDefault(); const kickReason = e.target.elements['kick-reason']?.value.trim(); - roomActions.kick(roomId, userId, kickReason !== '' ? kickReason : undefined); + mx.kick(roomId, userId, kickReason !== '' ? kickReason : undefined); }; const handleBan = (e) => { e.preventDefault(); const banReason = e.target.elements['ban-reason']?.value.trim(); - roomActions.ban(roomId, userId, banReason !== '' ? banReason : undefined); + mx.ban(roomId, userId, banReason !== '' ? banReason : undefined); }; return ( @@ -90,7 +90,7 @@ ModerationTools.propTypes = { function SessionInfo({ userId }) { const [devices, setDevices] = useState(null); const [isVisible, setIsVisible] = useState(false); - const mx = initMatrix.matrixClient; + const mx = useMatrixClient(); useEffect(() => { let isUnmounted = false; @@ -111,7 +111,7 @@ function SessionInfo({ userId }) { return () => { isUnmounted = true; }; - }, [userId]); + }, [mx, userId]); function renderSessionChips() { if (!isVisible) return null; @@ -139,7 +139,7 @@ function SessionInfo({ userId }) { > {`View ${ devices?.length > 0 - ? `${devices.length} ${devices.length == 1 ? 'session' : 'sessions'}` + ? `${devices.length} ${devices.length === 1 ? 'session' : 'sessions'}` : 'sessions' }`} @@ -155,10 +155,10 @@ SessionInfo.propTypes = { function ProfileFooter({ roomId, userId, onRequestClose }) { const [isCreatingDM, setIsCreatingDM] = useState(false); const [isIgnoring, setIsIgnoring] = useState(false); - const [isUserIgnored, setIsUserIgnored] = useState(initMatrix.matrixClient.isUserIgnored(userId)); + const mx = useMatrixClient(); + const [isUserIgnored, setIsUserIgnored] = useState(mx.isUserIgnored(userId)); const isMountedRef = useRef(true); - const mx = initMatrix.matrixClient; const { navigateRoom } = useRoomNavigate(); const room = mx.getRoom(roomId); const member = room.getMember(userId); @@ -182,10 +182,10 @@ function ProfileFooter({ roomId, userId, onRequestClose }) { }; useEffect(() => { - setIsUserIgnored(initMatrix.matrixClient.isUserIgnored(userId)); + setIsUserIgnored(mx.isUserIgnored(userId)); setIsIgnoring(false); setIsInviting(false); - }, [userId]); + }, [mx, userId]); const openDM = async () => { // Check and open if user already have a DM with userId. @@ -199,7 +199,7 @@ function ProfileFooter({ roomId, userId, onRequestClose }) { // Create new DM try { setIsCreatingDM(true); - const result = await roomActions.createDM(userId, await hasDevices(userId)); + const result = await roomActions.createDM(mx, userId, await hasDevices(mx, userId)); onCreated(result.room_id); } catch { if (isMountedRef.current === false) return; @@ -213,9 +213,9 @@ function ProfileFooter({ roomId, userId, onRequestClose }) { try { setIsIgnoring(true); if (isIgnored) { - await roomActions.unignore([userId]); + await roomActions.unignore(mx, [userId]); } else { - await roomActions.ignore([userId]); + await roomActions.ignore(mx, [userId]); } if (isMountedRef.current === false) return; @@ -230,9 +230,9 @@ function ProfileFooter({ roomId, userId, onRequestClose }) { try { setIsInviting(true); let isInviteSent = false; - if (isInvited) await roomActions.kick(roomId, userId); + if (isInvited) await mx.kick(roomId, userId); else { - await roomActions.invite(roomId, userId); + await mx.invite(roomId, userId); isInviteSent = true; } if (isMountedRef.current === false) return; @@ -249,7 +249,7 @@ function ProfileFooter({ roomId, userId, onRequestClose }) { {isCreatingDM ? 'Creating room...' : 'Message'} {isBanned && canIKick && ( - )} @@ -306,7 +306,7 @@ function useToggleDialog() { } function useRerenderOnProfileChange(roomId, userId) { - const mx = initMatrix.matrixClient; + const mx = useMatrixClient(); const [, forceUpdate] = useForceUpdate(); useEffect(() => { const handleProfileChange = (mEvent, member) => { @@ -323,19 +323,19 @@ function useRerenderOnProfileChange(roomId, userId) { mx.removeListener('RoomMember.powerLevel', handleProfileChange); mx.removeListener('RoomMember.membership', handleProfileChange); }; - }, [roomId, userId]); + }, [mx, roomId, userId]); } function ProfileViewer() { const [isOpen, roomId, userId, closeDialog, handleAfterClose] = useToggleDialog(); useRerenderOnProfileChange(roomId, userId); - const mx = initMatrix.matrixClient; + const mx = useMatrixClient(); const room = mx.getRoom(roomId); const renderProfile = () => { const roomMember = room.getMember(userId); - const username = roomMember ? getUsernameOfRoomMember(roomMember) : getUsername(userId); + const username = roomMember ? getUsernameOfRoomMember(roomMember) : getUsername(mx, userId); const avatarMxc = roomMember?.getMxcAvatarUrl?.() || mx.getUser(userId)?.avatarUrl; const avatarUrl = avatarMxc && avatarMxc !== 'null' ? mx.mxcUrlToHttp(avatarMxc, 80, 80, 'crop') : null; @@ -364,9 +364,9 @@ function ProfileViewer() { 'caution' ); if (!isConfirmed) return; - roomActions.setPowerLevel(roomId, userId, newPowerLevel); + roomActions.setPowerLevel(mx, roomId, userId, newPowerLevel); } else { - roomActions.setPowerLevel(roomId, userId, newPowerLevel); + roomActions.setPowerLevel(mx, roomId, userId, newPowerLevel); } }; diff --git a/src/app/organisms/room/RoomSettings.jsx b/src/app/organisms/room/RoomSettings.jsx index 2b8f28e66..69f977b29 100644 --- a/src/app/organisms/room/RoomSettings.jsx +++ b/src/app/organisms/room/RoomSettings.jsx @@ -2,7 +2,6 @@ import React, { useState, useEffect } from 'react'; import PropTypes from 'prop-types'; import './RoomSettings.scss'; -import initMatrix from '../../../client/initMatrix'; import cons from '../../../client/state/cons'; import navigation from '../../../client/state/navigation'; @@ -30,6 +29,7 @@ import CrossIC from '../../../../public/res/ic/outlined/cross.svg'; import { confirmDialog } from '../../molecules/confirm-dialog/ConfirmDialog'; import PopupWindow from '../../molecules/popup-window/PopupWindow'; import IconButton from '../../atoms/button/IconButton'; +import { useMatrixClient } from '../../hooks/useMatrixClient'; const tabText = { GENERAL: 'General', @@ -68,7 +68,7 @@ const tabItems = [ ]; function GeneralSettings({ roomId }) { - const mx = initMatrix.matrixClient; + const mx = useMatrixClient(); const room = mx.getRoom(roomId); return ( @@ -155,7 +155,8 @@ function RoomSettings() { const [window, requestClose] = useWindowToggle(setSelectedTab); const isOpen = window !== null; const roomId = window?.roomId; - const room = initMatrix.matrixClient.getRoom(roomId); + const mx = useMatrixClient(); + const room = mx.getRoom(roomId); const handleTabChange = (tabItem) => { setSelectedTab(tabItem); diff --git a/src/app/organisms/search/Search.jsx b/src/app/organisms/search/Search.jsx index 0990a03fa..ebdac3962 100644 --- a/src/app/organisms/search/Search.jsx +++ b/src/app/organisms/search/Search.jsx @@ -2,12 +2,10 @@ import React, { useState, useEffect, useRef, useCallback } from 'react'; import { useAtomValue } from 'jotai'; import './Search.scss'; -import initMatrix from '../../../client/initMatrix'; import cons from '../../../client/state/cons'; import navigation from '../../../client/state/navigation'; import AsyncSearch from '../../../util/AsyncSearch'; import { joinRuleToIconSrc } from '../../../util/matrixUtil'; -import { roomIdByActivity } from '../../../util/sort'; import Text from '../../atoms/text/Text'; import RawIcon from '../../atoms/system-icons/RawIcon'; @@ -27,6 +25,8 @@ import { allRoomsAtom } from '../../state/room-list/roomList'; import { mDirectAtom } from '../../state/mDirectList'; import { useKeyDown } from '../../hooks/useKeyDown'; import { openSearch } from '../../../client/action/navigation'; +import { useMatrixClient } from '../../hooks/useMatrixClient'; +import { factoryRoomIdByActivity } from '../../utils/sort'; function useVisiblityToggle(setResult) { const [isOpen, setIsOpen] = useState(false); @@ -77,9 +77,7 @@ function useVisiblityToggle(setResult) { return [isOpen, requestClose]; } -function mapRoomIds(roomIds, directs, roomIdToParents) { - const mx = initMatrix.matrixClient; - +function mapRoomIds(mx, roomIds, directs, roomIdToParents) { return roomIds.map((roomId) => { const room = mx.getRoom(roomId); const parentSet = roomIdToParents.get(roomId); @@ -107,7 +105,7 @@ function Search() { const [asyncSearch] = useState(new AsyncSearch()); const [isOpen, requestClose] = useVisiblityToggle(setResult); const searchRef = useRef(null); - const mx = initMatrix.matrixClient; + const mx = useMatrixClient(); const { navigateRoom, navigateSpace } = useRoomNavigate(); const mDirects = useAtomValue(mDirectAtom); const spaces = useSpaces(mx, allRoomsAtom); @@ -141,8 +139,8 @@ function Search() { ids = [...rooms].concat([...directs], [...spaces]); } - ids.sort(roomIdByActivity); - const mappedIds = mapRoomIds(ids, directs, roomToParents); + ids.sort(factoryRoomIdByActivity(mx)); + const mappedIds = mapRoomIds(mx, ids, directs, roomToParents); asyncSearch.setup(mappedIds, { keys: 'name', isContain: true, limit: 20 }); if (prefix) handleSearchResults(mappedIds, prefix); else asyncSearch.search(term); @@ -150,7 +148,7 @@ function Search() { const loadRecentRooms = () => { const recentRooms = []; - handleSearchResults(mapRoomIds(recentRooms, directs, roomToParents).reverse()); + handleSearchResults(mapRoomIds(mx, recentRooms, directs, roomToParents).reverse()); }; const handleAfterOpen = () => { diff --git a/src/app/organisms/settings/AuthRequest.jsx b/src/app/organisms/settings/AuthRequest.jsx index ca07c2a22..f897f83c2 100644 --- a/src/app/organisms/settings/AuthRequest.jsx +++ b/src/app/organisms/settings/AuthRequest.jsx @@ -2,7 +2,6 @@ import React, { useState } from 'react'; import PropTypes from 'prop-types'; import './AuthRequest.scss'; -import initMatrix from '../../../client/initMatrix'; import { openReusableDialog } from '../../../client/action/navigation'; import Text from '../../atoms/text/Text'; @@ -11,6 +10,7 @@ import Input from '../../atoms/input/Input'; import Spinner from '../../atoms/spinner/Spinner'; import { useStore } from '../../hooks/useStore'; +import { getSecret } from '../../../client/state/auth'; let lastUsedPassword; const getAuthId = (password) => ({ @@ -18,7 +18,7 @@ const getAuthId = (password) => ({ password, identifier: { type: 'm.id.user', - user: initMatrix.matrixClient.getUserId(), + user: getSecret().userId, }, }); diff --git a/src/app/organisms/settings/CrossSigning.jsx b/src/app/organisms/settings/CrossSigning.jsx index 9d848d5ae..b993e32f8 100644 --- a/src/app/organisms/settings/CrossSigning.jsx +++ b/src/app/organisms/settings/CrossSigning.jsx @@ -4,7 +4,6 @@ import './CrossSigning.scss'; import FileSaver from 'file-saver'; import { Formik } from 'formik'; -import initMatrix from '../../../client/initMatrix'; import { openReusableDialog } from '../../../client/action/navigation'; import { copyToClipboard } from '../../../util/common'; import { clearSecretStorageKeys } from '../../../client/state/secretStorageKeys'; @@ -17,6 +16,7 @@ import SettingTile from '../../molecules/setting-tile/SettingTile'; import { authRequest } from './AuthRequest'; import { useCrossSigningStatus } from '../../hooks/useCrossSigningStatus'; +import { useMatrixClient } from '../../hooks/useMatrixClient'; const failedDialog = () => { const renderFailure = (requestClose) => ( @@ -73,9 +73,9 @@ const securityKeyDialog = (key) => { function CrossSigningSetup() { const initialValues = { phrase: '', confirmPhrase: '' }; const [genWithPhrase, setGenWithPhrase] = useState(undefined); + const mx = useMatrixClient(); const setup = async (securityPhrase = undefined) => { - const mx = initMatrix.matrixClient; setGenWithPhrase(typeof securityPhrase === 'string'); const recoveryKey = await mx.createRecoveryKeyFromPassphrase(securityPhrase); clearSecretStorageKeys(); diff --git a/src/app/organisms/settings/DeviceManage.jsx b/src/app/organisms/settings/DeviceManage.jsx index 4a4f141cd..9fa8273e7 100644 --- a/src/app/organisms/settings/DeviceManage.jsx +++ b/src/app/organisms/settings/DeviceManage.jsx @@ -2,7 +2,6 @@ import React, { useState, useEffect } from 'react'; import './DeviceManage.scss'; import dateFormat from 'dateformat'; -import initMatrix from '../../../client/initMatrix'; import { isCrossVerified } from '../../../util/matrixUtil'; import { openReusableDialog, openEmojiVerification } from '../../../client/action/navigation'; @@ -26,6 +25,7 @@ import { useStore } from '../../hooks/useStore'; import { useDeviceList } from '../../hooks/useDeviceList'; import { useCrossSigningStatus } from '../../hooks/useCrossSigningStatus'; import { accessSecretStorage } from './SecretStorageAccess'; +import { useMatrixClient } from '../../hooks/useMatrixClient'; const promptDeviceName = async (deviceName) => new Promise((resolve) => { let isCompleted = false; @@ -63,14 +63,14 @@ const promptDeviceName = async (deviceName) => new Promise((resolve) => { function DeviceManage() { const TRUNCATED_COUNT = 4; - const mx = initMatrix.matrixClient; + const mx = useMatrixClient(); const isCSEnabled = useCrossSigningStatus(); const deviceList = useDeviceList(); const [processing, setProcessing] = useState([]); const [truncated, setTruncated] = useState(true); const mountStore = useStore(); mountStore.setItem(true); - const isMeVerified = isCrossVerified(mx.deviceId); + const isMeVerified = isCrossVerified(mx, mx.deviceId); useEffect(() => { setProcessing([]); @@ -130,7 +130,7 @@ function DeviceManage() { }; const verifyWithKey = async (device) => { - const keyData = await accessSecretStorage('Session verification'); + const keyData = await accessSecretStorage(mx, 'Session verification'); if (!keyData) return; addToProcessing(device); await mx.checkOwnCrossSigningTrust(); @@ -191,7 +191,7 @@ function DeviceManage() { )} {isCurrentDevice && ( - {`Session Key: ${initMatrix.matrixClient.getDeviceEd25519Key().match(/.{1,4}/g).join(' ')}`} + {`Session Key: ${mx.getDeviceEd25519Key().match(/.{1,4}/g).join(' ')}`} )} @@ -204,7 +204,7 @@ function DeviceManage() { const verified = []; const noEncryption = []; deviceList.sort((a, b) => b.last_seen_ts - a.last_seen_ts).forEach((device) => { - const isVerified = isCrossVerified(device.device_id); + const isVerified = isCrossVerified(mx, device.device_id); if (isVerified === true) { verified.push(device); } else if (isVerified === false) { diff --git a/src/app/organisms/settings/KeyBackup.jsx b/src/app/organisms/settings/KeyBackup.jsx index b4f2125e2..47be511a3 100644 --- a/src/app/organisms/settings/KeyBackup.jsx +++ b/src/app/organisms/settings/KeyBackup.jsx @@ -3,7 +3,6 @@ import React, { useState, useEffect } from 'react'; import PropTypes from 'prop-types'; import './KeyBackup.scss'; -import initMatrix from '../../../client/initMatrix'; import { openReusableDialog } from '../../../client/action/navigation'; import { deletePrivateKey } from '../../../client/state/secretStorageKeys'; @@ -22,10 +21,11 @@ import DownloadIC from '../../../../public/res/ic/outlined/download.svg'; import { useStore } from '../../hooks/useStore'; import { useCrossSigningStatus } from '../../hooks/useCrossSigningStatus'; +import { useMatrixClient } from '../../hooks/useMatrixClient'; function CreateKeyBackupDialog({ keyData }) { const [done, setDone] = useState(false); - const mx = initMatrix.matrixClient; + const mx = useMatrixClient(); const mountStore = useStore(); const doBackup = async () => { @@ -80,7 +80,7 @@ CreateKeyBackupDialog.propTypes = { function RestoreKeyBackupDialog({ keyData }) { const [status, setStatus] = useState(false); - const mx = initMatrix.matrixClient; + const mx = useMatrixClient(); const mountStore = useStore(); const restoreBackup = async () => { @@ -150,7 +150,7 @@ RestoreKeyBackupDialog.propTypes = { function DeleteKeyBackupDialog({ requestClose }) { const [isDeleting, setIsDeleting] = useState(false); - const mx = initMatrix.matrixClient; + const mx = useMatrixClient(); const mountStore = useStore(); const deleteBackup = async () => { @@ -187,7 +187,7 @@ DeleteKeyBackupDialog.propTypes = { }; function KeyBackup() { - const mx = initMatrix.matrixClient; + const mx = useMatrixClient(); const isCSEnabled = useCrossSigningStatus(); const [keyBackup, setKeyBackup] = useState(undefined); const mountStore = useStore(); @@ -215,7 +215,7 @@ function KeyBackup() { }, [isCSEnabled]); const openCreateKeyBackup = async () => { - const keyData = await accessSecretStorage('Create Key Backup'); + const keyData = await accessSecretStorage(mx, 'Create Key Backup'); if (keyData === null) return; openReusableDialog( @@ -228,7 +228,7 @@ function KeyBackup() { }; const openRestoreKeyBackup = async () => { - const keyData = await accessSecretStorage('Restore Key Backup'); + const keyData = await accessSecretStorage(mx, 'Restore Key Backup'); if (keyData === null) return; openReusableDialog( diff --git a/src/app/organisms/settings/SecretStorageAccess.jsx b/src/app/organisms/settings/SecretStorageAccess.jsx index e4fceb078..02882a41c 100644 --- a/src/app/organisms/settings/SecretStorageAccess.jsx +++ b/src/app/organisms/settings/SecretStorageAccess.jsx @@ -3,7 +3,6 @@ import PropTypes from 'prop-types'; import './SecretStorageAccess.scss'; import { deriveKey } from 'matrix-js-sdk/lib/crypto/key_passphrase'; -import initMatrix from '../../../client/initMatrix'; import { openReusableDialog } from '../../../client/action/navigation'; import { getDefaultSSKey, getSSKeyInfo } from '../../../util/matrixUtil'; import { storePrivateKey, hasPrivateKey, getPrivateKey } from '../../../client/state/secretStorageKeys'; @@ -14,11 +13,12 @@ import Input from '../../atoms/input/Input'; import Spinner from '../../atoms/spinner/Spinner'; import { useStore } from '../../hooks/useStore'; +import { useMatrixClient } from '../../hooks/useMatrixClient'; function SecretStorageAccess({ onComplete }) { - const mx = initMatrix.matrixClient; - const sSKeyId = getDefaultSSKey(); - const sSKeyInfo = getSSKeyInfo(sSKeyId); + const mx = useMatrixClient(); + const sSKeyId = getDefaultSSKey(mx); + const sSKeyInfo = getSSKeyInfo(mx, sSKeyId); const isPassphrase = !!sSKeyInfo.passphrase; const [withPhrase, setWithPhrase] = useState(isPassphrase); const [process, setProcess] = useState(false); @@ -98,12 +98,13 @@ SecretStorageAccess.propTypes = { }; /** + * @param {MatrixClient} mx Matrix client * @param {string} title Title of secret storage access dialog * @returns {Promise} resolve to keyData or null */ -export const accessSecretStorage = (title) => new Promise((resolve) => { +export const accessSecretStorage = (mx, title) => new Promise((resolve) => { let isCompleted = false; - const defaultSSKey = getDefaultSSKey(); + const defaultSSKey = getDefaultSSKey(mx); if (hasPrivateKey(defaultSSKey)) { resolve({ keyId: defaultSSKey, privateKey: getPrivateKey(defaultSSKey) }); return; diff --git a/src/app/organisms/settings/Settings.jsx b/src/app/organisms/settings/Settings.jsx index 47abb45c0..f2951b812 100644 --- a/src/app/organisms/settings/Settings.jsx +++ b/src/app/organisms/settings/Settings.jsx @@ -1,7 +1,7 @@ import React, { useState, useEffect } from 'react'; import './Settings.scss'; -import initMatrix from '../../../client/initMatrix'; +import { clearCacheAndReload, logoutClient } from '../../../client/initMatrix'; import cons from '../../../client/state/cons'; import settings from '../../../client/state/settings'; import navigation from '../../../client/state/navigation'; @@ -47,6 +47,7 @@ import { useSetting } from '../../state/hooks/settings'; import { settingsAtom } from '../../state/settings'; import { isMacOS } from '../../utils/user-agent'; import { KeySymbol } from '../../utils/key-symbol'; +import { useMatrixClient } from '../../hooks/useMatrixClient'; function AppearanceSection() { const [, updateState] = useState({}); @@ -332,6 +333,8 @@ function SecuritySection() { } function AboutSection() { + const mx = useMatrixClient(); + return (
      @@ -348,7 +351,7 @@ function AboutSection() {
      - +
      @@ -437,11 +440,12 @@ function useWindowToggle(setSelectedTab) { function Settings() { const [selectedTab, setSelectedTab] = useState(tabItems[0]); const [isOpen, requestClose] = useWindowToggle(setSelectedTab); + const mx = useMatrixClient(); const handleTabChange = (tabItem) => setSelectedTab(tabItem); const handleLogout = async () => { if (await confirmDialog('Logout', 'Are you sure that you want to logout your session?', 'Logout', 'danger')) { - initMatrix.logout(); + logoutClient(mx); } }; @@ -462,7 +466,7 @@ function Settings() { > {isOpen && (
      - + tab.text === selectedTab.text)} diff --git a/src/app/organisms/space-settings/SpaceSettings.jsx b/src/app/organisms/space-settings/SpaceSettings.jsx index ff6c18632..9f2069d47 100644 --- a/src/app/organisms/space-settings/SpaceSettings.jsx +++ b/src/app/organisms/space-settings/SpaceSettings.jsx @@ -2,7 +2,6 @@ import React, { useState, useEffect } from 'react'; import PropTypes from 'prop-types'; import './SpaceSettings.scss'; -import initMatrix from '../../../client/initMatrix'; import cons from '../../../client/state/cons'; import navigation from '../../../client/state/navigation'; @@ -59,8 +58,8 @@ const tabItems = [ ]; function GeneralSettings({ roomId }) { - const roomName = initMatrix.matrixClient.getRoom(roomId)?.name; const mx = useMatrixClient(); + const roomName = mx.getRoom(roomId)?.name; return ( <> @@ -124,7 +123,7 @@ function SpaceSettings() { const isOpen = window !== null; const roomId = window?.roomId; - const mx = initMatrix.matrixClient; + const mx = useMatrixClient(); const room = mx.getRoom(roomId); const handleTabChange = (tabItem) => { diff --git a/src/app/pages/client/ClientLayout.tsx b/src/app/pages/client/ClientLayout.tsx index 208d12e48..4a077ba6a 100644 --- a/src/app/pages/client/ClientLayout.tsx +++ b/src/app/pages/client/ClientLayout.tsx @@ -7,7 +7,7 @@ type ClientLayoutProps = { }; export function ClientLayout({ nav, children }: ClientLayoutProps) { return ( - + {nav} {children} diff --git a/src/app/pages/client/ClientRoot.tsx b/src/app/pages/client/ClientRoot.tsx index c36adfc64..a590e0bc5 100644 --- a/src/app/pages/client/ClientRoot.tsx +++ b/src/app/pages/client/ClientRoot.tsx @@ -1,6 +1,27 @@ -import { Box, Spinner, Text } from 'folds'; -import React, { ReactNode, useEffect, useState } from 'react'; -import initMatrix from '../../../client/initMatrix'; +import { + Box, + Button, + config, + Dialog, + Icon, + IconButton, + Icons, + Menu, + MenuItem, + PopOut, + RectCords, + Spinner, + Text, +} from 'folds'; +import { HttpApiEvent, HttpApiEventHandlerMap, MatrixClient } from 'matrix-js-sdk'; +import FocusTrap from 'focus-trap-react'; +import React, { MouseEventHandler, ReactNode, useCallback, useEffect, useState } from 'react'; +import { + clearCacheAndReload, + initClient, + logoutClient, + startClient, +} from '../../../client/initMatrix'; import { getSecret } from '../../../client/state/auth'; import { SplashScreen } from '../../components/splash-screen'; import { CapabilitiesAndMediaConfigLoader } from '../../components/CapabilitiesAndMediaConfigLoader'; @@ -13,6 +34,10 @@ import Dialogs from '../../organisms/pw/Dialogs'; import ReusableContextMenu from '../../atoms/context-menu/ReusableContextMenu'; import { useSetting } from '../../state/hooks/settings'; import { settingsAtom } from '../../state/settings'; +import { AsyncStatus, useAsyncCallback } from '../../hooks/useAsyncCallback'; +import { useSyncState } from '../../hooks/useSyncState'; +import { stopPropagation } from '../../utils/keyboard'; +import { SyncStatus } from './SyncStatus'; function SystemEmojiFeature() { const [twitterEmoji] = useSetting(settingsAtom, 'twitterEmoji'); @@ -37,6 +62,89 @@ function ClientRootLoading() { ); } +function ClientRootOptions({ mx }: { mx: MatrixClient }) { + const [menuAnchor, setMenuAnchor] = useState(); + + const handleToggle: MouseEventHandler = (evt) => { + const cords = evt.currentTarget.getBoundingClientRect(); + setMenuAnchor((currentState) => { + if (currentState) return undefined; + return cords; + }); + }; + + return ( + + + setMenuAnchor(undefined), + clickOutsideDeactivates: true, + isKeyForward: (evt: KeyboardEvent) => evt.key === 'ArrowDown', + isKeyBackward: (evt: KeyboardEvent) => evt.key === 'ArrowUp', + escapeDeactivates: stopPropagation, + }} + > + + + clearCacheAndReload(mx)} size="300" radii="300"> + + Clear Cache and Reload + + + logoutClient(mx)} + size="300" + radii="300" + variant="Critical" + fill="None" + > + + Logout + + + + + + } + /> + + ); +} + +const useLogoutListener = (mx?: MatrixClient) => { + useEffect(() => { + const handleLogout: HttpApiEventHandlerMap[HttpApiEvent.SessionLoggedOut] = async () => { + mx?.stopClient(); + await mx?.clearStores(); + window.localStorage.clear(); + window.location.reload(); + }; + + mx?.on(HttpApiEvent.SessionLoggedOut, handleLogout); + return () => { + mx?.removeListener(HttpApiEvent.SessionLoggedOut, handleLogout); + }; + }, [mx]); +}; + type ClientRootProps = { children: ReactNode; }; @@ -44,30 +152,71 @@ export function ClientRoot({ children }: ClientRootProps) { const [loading, setLoading] = useState(true); const { baseUrl } = getSecret(); + const [loadState, loadMatrix] = useAsyncCallback( + useCallback(() => initClient(getSecret() as any), []) + ); + const mx = loadState.status === AsyncStatus.Success ? loadState.data : undefined; + const [startState, startMatrix] = useAsyncCallback( + useCallback((m) => startClient(m), []) + ); + + useLogoutListener(mx); + useEffect(() => { - const handleStart = () => { - setLoading(false); - }; - initMatrix.once('init_loading_finished', handleStart); - if (!initMatrix.matrixClient) initMatrix.init(); - return () => { - initMatrix.removeListener('init_loading_finished', handleStart); - }; - }, []); + if (loadState.status === AsyncStatus.Idle) { + loadMatrix(); + } + }, [loadState, loadMatrix]); + + useEffect(() => { + if (mx && !mx.clientRunning) { + startMatrix(mx); + } + }, [mx, startMatrix]); + + useSyncState( + mx, + useCallback((state) => { + if (state === 'PREPARED') { + setLoading(false); + } + }, []) + ); return ( - {loading ? ( + {mx && } + {loading && mx && } + {(loadState.status === AsyncStatus.Error || startState.status === AsyncStatus.Error) && ( + + + + + {loadState.status === AsyncStatus.Error && ( + {`Failed to load. ${loadState.error.message}`} + )} + {startState.status === AsyncStatus.Error && ( + {`Failed to load. ${startState.error.message}`} + )} + + + + + + )} + {loading || !mx ? ( ) : ( - + {(capabilities, mediaConfig) => ( {children} - - {/* TODO: remove these components after navigation refactor */} diff --git a/src/app/pages/client/SyncStatus.tsx b/src/app/pages/client/SyncStatus.tsx new file mode 100644 index 000000000..9cd4b0b2d --- /dev/null +++ b/src/app/pages/client/SyncStatus.tsx @@ -0,0 +1,87 @@ +import { MatrixClient, SyncState } from 'matrix-js-sdk'; +import React, { useCallback, useState } from 'react'; +import { Box, config, Line, Text } from 'folds'; +import { useSyncState } from '../../hooks/useSyncState'; +import { ContainerColor } from '../../styles/ContainerColor.css'; + +type StateData = { + current: SyncState | null; + previous: SyncState | null | undefined; +}; + +type SyncStatusProps = { + mx: MatrixClient; +}; +export function SyncStatus({ mx }: SyncStatusProps) { + const [stateData, setStateData] = useState({ + current: null, + previous: undefined, + }); + + useSyncState( + mx, + useCallback((current, previous) => { + setStateData((s) => { + if (s.current === current && s.previous === previous) { + return s; + } + return { current, previous }; + }); + }, []) + ); + + if ( + (stateData.current === SyncState.Prepared || + stateData.current === SyncState.Syncing || + stateData.current === SyncState.Catchup) && + stateData.previous !== SyncState.Syncing + ) { + return ( + + + Connecting... + + + + ); + } + + if (stateData.current === SyncState.Reconnecting) { + return ( + + + Connection Lost! Reconnecting... + + + + ); + } + + if (stateData.current === SyncState.Error) { + return ( + + + Connection Lost! + + + + ); + } + + return null; +} diff --git a/src/app/pages/client/WelcomePage.tsx b/src/app/pages/client/WelcomePage.tsx index 2486625f6..5040d15f5 100644 --- a/src/app/pages/client/WelcomePage.tsx +++ b/src/app/pages/client/WelcomePage.tsx @@ -18,7 +18,7 @@ export function WelcomePage() { title="Welcome to Cinny" subTitle={ - Yet anothor matrix client.{' '} + Yet another matrix client.{' '} void; }; const DirectMenu = forwardRef(({ requestClose }, ref) => { + const mx = useMatrixClient(); const orphanRooms = useDirectRooms(); const unread = useRoomsUnread(orphanRooms, roomToUnreadAtom); const handleMarkAsRead = () => { if (!unread) return; - orphanRooms.forEach((rId) => markAsRead(rId)); + orphanRooms.forEach((rId) => markAsRead(mx, rId)); requestClose(); }; diff --git a/src/app/pages/client/home/Home.tsx b/src/app/pages/client/home/Home.tsx index a06e108e9..f9923f462 100644 --- a/src/app/pages/client/home/Home.tsx +++ b/src/app/pages/client/home/Home.tsx @@ -55,10 +55,11 @@ type HomeMenuProps = { const HomeMenu = forwardRef(({ requestClose }, ref) => { const orphanRooms = useHomeRooms(); const unread = useRoomsUnread(orphanRooms, roomToUnreadAtom); + const mx = useMatrixClient(); const handleMarkAsRead = () => { if (!unread) return; - orphanRooms.forEach((rId) => markAsRead(rId)); + orphanRooms.forEach((rId) => markAsRead(mx, rId)); requestClose(); }; diff --git a/src/app/pages/client/inbox/Notifications.tsx b/src/app/pages/client/inbox/Notifications.tsx index 8b9d1847c..a01ecb8e0 100644 --- a/src/app/pages/client/inbox/Notifications.tsx +++ b/src/app/pages/client/inbox/Notifications.tsx @@ -356,7 +356,7 @@ function RoomNotificationsGroupComp({ onOpen(room.roomId, eventId); }; const handleMarkAsRead = () => { - markAsRead(room.roomId); + markAsRead(mx, room.roomId); }; return ( diff --git a/src/app/pages/client/sidebar/DirectTab.tsx b/src/app/pages/client/sidebar/DirectTab.tsx index 0beb17d85..849fc3656 100644 --- a/src/app/pages/client/sidebar/DirectTab.tsx +++ b/src/app/pages/client/sidebar/DirectTab.tsx @@ -30,10 +30,11 @@ type DirectMenuProps = { const DirectMenu = forwardRef(({ requestClose }, ref) => { const orphanRooms = useDirectRooms(); const unread = useRoomsUnread(orphanRooms, roomToUnreadAtom); + const mx = useMatrixClient(); const handleMarkAsRead = () => { if (!unread) return; - orphanRooms.forEach((rId) => markAsRead(rId)); + orphanRooms.forEach((rId) => markAsRead(mx, rId)); requestClose(); }; diff --git a/src/app/pages/client/sidebar/HomeTab.tsx b/src/app/pages/client/sidebar/HomeTab.tsx index 41f7c6489..dcb0a4986 100644 --- a/src/app/pages/client/sidebar/HomeTab.tsx +++ b/src/app/pages/client/sidebar/HomeTab.tsx @@ -31,10 +31,11 @@ type HomeMenuProps = { const HomeMenu = forwardRef(({ requestClose }, ref) => { const orphanRooms = useHomeRooms(); const unread = useRoomsUnread(orphanRooms, roomToUnreadAtom); + const mx = useMatrixClient(); const handleMarkAsRead = () => { if (!unread) return; - orphanRooms.forEach((rId) => markAsRead(rId)); + orphanRooms.forEach((rId) => markAsRead(mx, rId)); requestClose(); }; diff --git a/src/app/pages/client/sidebar/SpaceTabs.tsx b/src/app/pages/client/sidebar/SpaceTabs.tsx index 8635a35fd..7b3e61e78 100644 --- a/src/app/pages/client/sidebar/SpaceTabs.tsx +++ b/src/app/pages/client/sidebar/SpaceTabs.tsx @@ -114,7 +114,7 @@ const SpaceMenu = forwardRef( const unread = useRoomsUnread(allChild, roomToUnreadAtom); const handleMarkAsRead = () => { - allChild.forEach((childRoomId) => markAsRead(childRoomId)); + allChild.forEach((childRoomId) => markAsRead(mx, childRoomId)); requestClose(); }; diff --git a/src/app/pages/client/space/Space.tsx b/src/app/pages/client/space/Space.tsx index e947373bd..e280c603e 100644 --- a/src/app/pages/client/space/Space.tsx +++ b/src/app/pages/client/space/Space.tsx @@ -95,7 +95,7 @@ const SpaceMenu = forwardRef(({ room, requestClo const unread = useRoomsUnread(allChild, roomToUnreadAtom); const handleMarkAsRead = () => { - allChild.forEach((childRoomId) => markAsRead(childRoomId)); + allChild.forEach((childRoomId) => markAsRead(mx, childRoomId)); requestClose(); }; diff --git a/src/client/action/notifications.js b/src/client/action/notifications.ts similarity index 69% rename from src/client/action/notifications.js rename to src/client/action/notifications.ts index 579c7c3cb..17ea1ed61 100644 --- a/src/client/action/notifications.js +++ b/src/client/action/notifications.ts @@ -1,13 +1,11 @@ -import initMatrix from '../initMatrix'; +import { MatrixClient } from "matrix-js-sdk"; -// eslint-disable-next-line import/prefer-default-export -export async function markAsRead(roomId) { - const mx = initMatrix.matrixClient; +export async function markAsRead(mx: MatrixClient, roomId: string) { const room = mx.getRoom(roomId); if (!room) return; const timeline = room.getLiveTimeline().getEvents(); - const readEventId = room.getEventReadUpTo(mx.getUserId()); + const readEventId = room.getEventReadUpTo(mx.getUserId()!); const getLatestValidEvent = () => { for (let i = timeline.length - 1; i >= 0; i -= 1) { diff --git a/src/client/action/room.js b/src/client/action/room.js index c2d114388..cd4995b90 100644 --- a/src/client/action/room.js +++ b/src/client/action/room.js @@ -1,16 +1,13 @@ -import initMatrix from '../initMatrix'; -import appDispatcher from '../dispatcher'; -import cons from '../state/cons'; import { getIdServer } from '../../util/matrixUtil'; /** * https://github.com/matrix-org/matrix-react-sdk/blob/1e6c6e9d800890c732d60429449bc280de01a647/src/Rooms.js#L73 + * @param {MatrixClient} mx Matrix client * @param {string} roomId Id of room to add * @param {string} userId User id to which dm || undefined to remove * @returns {Promise} A promise */ -function addRoomToMDirect(roomId, userId) { - const mx = initMatrix.matrixClient; +function addRoomToMDirect(mx, roomId, userId) { const mDirectsEvent = mx.getAccountData('m.direct'); let userIdToRoomIds = {}; @@ -79,24 +76,22 @@ function guessDMRoomTargetId(room, myUserId) { return oldestMember.userId; } -function convertToDm(roomId) { - const mx = initMatrix.matrixClient; +function convertToDm(mx, roomId) { const room = mx.getRoom(roomId); - return addRoomToMDirect(roomId, guessDMRoomTargetId(room, mx.getUserId())); + return addRoomToMDirect(mx, roomId, guessDMRoomTargetId(room, mx.getUserId())); } -function convertToRoom(roomId) { - return addRoomToMDirect(roomId, undefined); +function convertToRoom(mx, roomId) { + return addRoomToMDirect(mx, roomId, undefined); } /** - * + * @param {MatrixClient} mx * @param {string} roomId * @param {boolean} isDM * @param {string[]} via */ -async function join(roomIdOrAlias, isDM = false, via = undefined) { - const mx = initMatrix.matrixClient; +async function join(mx, roomIdOrAlias, isDM = false, via = undefined) { const roomIdParts = roomIdOrAlias.split(':'); const viaServers = via || [roomIdParts[1]]; @@ -105,7 +100,7 @@ async function join(roomIdOrAlias, isDM = false, via = undefined) { if (isDM) { const targetUserId = guessDMRoomTargetId(mx.getRoom(resultRoom.roomId), mx.getUserId()); - await addRoomToMDirect(resultRoom.roomId, targetUserId); + await addRoomToMDirect(mx, resultRoom.roomId, targetUserId); } return resultRoom.roomId; } catch (e) { @@ -113,12 +108,11 @@ async function join(roomIdOrAlias, isDM = false, via = undefined) { } } -async function create(options, isDM = false) { - const mx = initMatrix.matrixClient; +async function create(mx, options, isDM = false) { try { const result = await mx.createRoom(options); if (isDM && typeof options.invite?.[0] === 'string') { - await addRoomToMDirect(result.room_id, options.invite[0]); + await addRoomToMDirect(mx, result.room_id, options.invite[0]); } return result; } catch (e) { @@ -130,7 +124,7 @@ async function create(options, isDM = false) { } } -async function createDM(userIdOrIds, isEncrypted = true) { +async function createDM(mx, userIdOrIds, isEncrypted = true) { const options = { is_direct: true, invite: Array.isArray(userIdOrIds) ? userIdOrIds : [userIdOrIds], @@ -148,11 +142,11 @@ async function createDM(userIdOrIds, isEncrypted = true) { }); } - const result = await create(options, true); + const result = await create(mx, options, true); return result; } -async function createRoom(opts) { +async function createRoom(mx, opts) { // joinRule: 'public' | 'invite' | 'restricted' const { name, topic, joinRule } = opts; const alias = opts.alias ?? undefined; @@ -162,7 +156,6 @@ async function createRoom(opts) { const powerLevel = opts.powerLevel ?? undefined; const blockFederation = opts.blockFederation ?? false; - const mx = initMatrix.matrixClient; const visibility = joinRule === 'public' ? 'public' : 'private'; const options = { creation_content: undefined, @@ -225,7 +218,7 @@ async function createRoom(opts) { }); } - const result = await create(options); + const result = await create(mx, options); if (parentId) { await mx.sendStateEvent(parentId, 'm.space.child', { @@ -238,51 +231,19 @@ async function createRoom(opts) { return result; } -async function invite(roomId, userId, reason) { - const mx = initMatrix.matrixClient; - - const result = await mx.invite(roomId, userId, undefined, reason); - return result; -} - -async function kick(roomId, userId, reason) { - const mx = initMatrix.matrixClient; - - const result = await mx.kick(roomId, userId, reason); - return result; -} - -async function ban(roomId, userId, reason) { - const mx = initMatrix.matrixClient; - - const result = await mx.ban(roomId, userId, reason); - return result; -} - -async function unban(roomId, userId) { - const mx = initMatrix.matrixClient; - - const result = await mx.unban(roomId, userId); - return result; -} - -async function ignore(userIds) { - const mx = initMatrix.matrixClient; +async function ignore(mx, userIds) { let ignoredUsers = mx.getIgnoredUsers().concat(userIds); ignoredUsers = [...new Set(ignoredUsers)]; await mx.setIgnoredUsers(ignoredUsers); } -async function unignore(userIds) { - const mx = initMatrix.matrixClient; - +async function unignore(mx, userIds) { const ignoredUsers = mx.getIgnoredUsers(); await mx.setIgnoredUsers(ignoredUsers.filter((id) => !userIds.includes(id))); } -async function setPowerLevel(roomId, userId, powerLevel) { - const mx = initMatrix.matrixClient; +async function setPowerLevel(mx, roomId, userId, powerLevel) { const room = mx.getRoom(roomId); const powerlevelEvent = room.currentState.getStateEvents('m.room.power_levels')[0]; @@ -291,8 +252,7 @@ async function setPowerLevel(roomId, userId, powerLevel) { return result; } -async function setMyRoomNick(roomId, nick) { - const mx = initMatrix.matrixClient; +async function setMyRoomNick(mx, roomId, nick) { const room = mx.getRoom(roomId); const mEvent = room.currentState.getStateEvents('m.room.member', mx.getUserId()); const content = mEvent?.getContent(); @@ -303,8 +263,7 @@ async function setMyRoomNick(roomId, nick) { }, mx.getUserId()); } -async function setMyRoomAvatar(roomId, mxc) { - const mx = initMatrix.matrixClient; +async function setMyRoomAvatar(mx, roomId, mxc) { const room = mx.getRoom(roomId); const mEvent = room.currentState.getStateEvents('m.room.member', mx.getUserId()); const content = mEvent?.getContent(); @@ -320,7 +279,6 @@ export { convertToRoom, join, createDM, createRoom, - invite, kick, ban, unban, ignore, unignore, setPowerLevel, setMyRoomNick, setMyRoomAvatar, diff --git a/src/client/initMatrix.js b/src/client/initMatrix.js deleted file mode 100644 index 0352ff363..000000000 --- a/src/client/initMatrix.js +++ /dev/null @@ -1,128 +0,0 @@ -import EventEmitter from 'events'; -import * as sdk from 'matrix-js-sdk'; -import Olm from '@matrix-org/olm'; -import { logger } from 'matrix-js-sdk/lib/logger'; - -import { getSecret } from './state/auth'; -import { cryptoCallbacks } from './state/secretStorageKeys'; - -global.Olm = Olm; - -if (import.meta.env.PROD) { - logger.disableAll(); -} - -class InitMatrix extends EventEmitter { - async init() { - if (this.matrixClient || this.initializing) { - console.warn('Client is already initialized!') - return; - } - this.initializing = true; - - try { - await this.startClient(); - this.setupSync(); - this.listenEvents(); - this.initializing = false; - } catch { - this.initializing = false; - } - } - - async startClient() { - const indexedDBStore = new sdk.IndexedDBStore({ - indexedDB: global.indexedDB, - localStorage: global.localStorage, - dbName: 'web-sync-store', - }); - await indexedDBStore.startup(); - const secret = getSecret(); - - this.matrixClient = sdk.createClient({ - baseUrl: secret.baseUrl, - accessToken: secret.accessToken, - userId: secret.userId, - store: indexedDBStore, - cryptoStore: new sdk.IndexedDBCryptoStore(global.indexedDB, 'crypto-store'), - deviceId: secret.deviceId, - timelineSupport: true, - cryptoCallbacks, - verificationMethods: [ - 'm.sas.v1', - ], - }); - - await this.matrixClient.initCrypto(); - - await this.matrixClient.startClient({ - lazyLoadMembers: true, - }); - this.matrixClient.setGlobalErrorOnUnknownDevices(false); - this.matrixClient.setMaxListeners(50); - } - - setupSync() { - const sync = { - NULL: () => { - console.log('NULL state'); - }, - SYNCING: () => { - console.log('SYNCING state'); - }, - PREPARED: (prevState) => { - console.log('PREPARED state'); - console.log('Previous state: ', prevState); - global.initMatrix = this; - if (prevState === null) { - this.emit('init_loading_finished'); - } - }, - RECONNECTING: () => { - console.log('RECONNECTING state'); - }, - CATCHUP: () => { - console.log('CATCHUP state'); - }, - ERROR: () => { - console.log('ERROR state'); - }, - STOPPED: () => { - console.log('STOPPED state'); - }, - }; - this.matrixClient.on('sync', (state, prevState) => sync[state](prevState)); - } - - listenEvents() { - this.matrixClient.on('Session.logged_out', async () => { - this.matrixClient.stopClient(); - await this.matrixClient.clearStores(); - window.localStorage.clear(); - window.location.reload(); - }); - } - - async logout() { - this.matrixClient.stopClient(); - try { - await this.matrixClient.logout(); - } catch { - // ignore if failed to logout - } - await this.matrixClient.clearStores(); - window.localStorage.clear(); - window.location.reload(); - } - - clearCacheAndReload() { - this.matrixClient.stopClient(); - this.matrixClient.store.deleteAllData().then(() => { - window.location.reload(); - }); - } -} - -const initMatrix = new InitMatrix(); - -export default initMatrix; diff --git a/src/client/initMatrix.ts b/src/client/initMatrix.ts new file mode 100644 index 000000000..5a156ad88 --- /dev/null +++ b/src/client/initMatrix.ts @@ -0,0 +1,70 @@ +import { createClient, MatrixClient, IndexedDBStore, IndexedDBCryptoStore } from 'matrix-js-sdk'; +import Olm from '@matrix-org/olm'; +import { logger } from 'matrix-js-sdk/lib/logger'; + +import { cryptoCallbacks } from './state/secretStorageKeys'; + +global.Olm = Olm; + +if (import.meta.env.PROD) { + logger.disableAll(); +} + +type Session = { + baseUrl: string; + accessToken: string; + userId: string; + deviceId: string; +}; + +export const initClient = async (session: Session): Promise => { + const indexedDBStore = new IndexedDBStore({ + indexedDB: global.indexedDB, + localStorage: global.localStorage, + dbName: 'web-sync-store', + }); + await indexedDBStore.startup(); + + const mx = createClient({ + baseUrl: session.baseUrl, + accessToken: session.accessToken, + userId: session.userId, + store: indexedDBStore, + cryptoStore: new IndexedDBCryptoStore(global.indexedDB, 'crypto-store'), + deviceId: session.deviceId, + timelineSupport: true, + cryptoCallbacks: cryptoCallbacks as any, + verificationMethods: ['m.sas.v1'], + }); + + await mx.initCrypto(); + + mx.setGlobalErrorOnUnknownDevices(false); + mx.setMaxListeners(50); + + return mx; +}; + +export const startClient = async (mx: MatrixClient) => { + await mx.startClient({ + lazyLoadMembers: true, + }); +}; + +export const clearCacheAndReload = async (mx: MatrixClient) => { + mx.stopClient(); + await mx.store.deleteAllData(); + window.location.reload(); +}; + +export const logoutClient = async (mx: MatrixClient) => { + mx.stopClient(); + try { + await mx.logout(); + } catch { + // ignore if failed to logout + } + await mx.clearStores(); + window.localStorage.clear(); + window.location.reload(); +}; diff --git a/src/client/mx.ts b/src/client/mx.ts deleted file mode 100644 index 30909458b..000000000 --- a/src/client/mx.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { MatrixClient } from 'matrix-js-sdk'; -import initMatrix from './initMatrix'; - -export const mx = (): MatrixClient => { - if (!initMatrix.matrixClient) console.error('Matrix client is used before initialization!'); - return initMatrix.matrixClient!; -}; diff --git a/src/index.scss b/src/index.scss index 5903858ae..1c223051d 100644 --- a/src/index.scss +++ b/src/index.scss @@ -409,6 +409,8 @@ body { #root { width: 100%; height: 100%; + display: flex; + flex-direction: column; } *, diff --git a/src/util/matrixUtil.js b/src/util/matrixUtil.js index 74e56ec76..e4fd40c39 100644 --- a/src/util/matrixUtil.js +++ b/src/util/matrixUtil.js @@ -1,5 +1,3 @@ -import initMatrix from '../client/initMatrix'; - import HashIC from '../../public/res/ic/outlined/hash.svg'; import HashGlobeIC from '../../public/res/ic/outlined/hash-globe.svg'; import HashLockIC from '../../public/res/ic/outlined/hash-lock.svg'; @@ -24,8 +22,7 @@ export async function getBaseUrl(servername) { } } -export function getUsername(userId) { - const mx = initMatrix.matrixClient; +export function getUsername(mx, userId) { const user = mx.getUser(userId); if (user === null) return userId; let username = user.displayName; @@ -39,9 +36,9 @@ export function getUsernameOfRoomMember(roomMember) { return roomMember.name || roomMember.userId; } -export async function isRoomAliasAvailable(alias) { +export async function isRoomAliasAvailable(mx, alias) { try { - const result = await initMatrix.matrixClient.getRoomIdForAlias(alias); + const result = await mx.getRoomIdForAlias(alias); if (result.room_id) return false; return false; } catch (e) { @@ -159,9 +156,8 @@ export function genRoomVia(room) { return via.concat(mostPop3.slice(0, 2)); } -export function isCrossVerified(deviceId) { +export function isCrossVerified(mx, deviceId) { try { - const mx = initMatrix.matrixClient; const crossSignInfo = mx.getStoredCrossSigningForUser(mx.getUserId()); const deviceInfo = mx.getStoredDevice(mx.getUserId(), deviceId); const deviceTrust = crossSignInfo.checkDeviceTrust(crossSignInfo, deviceInfo, false, true); @@ -172,14 +168,12 @@ export function isCrossVerified(deviceId) { } } -export function hasCrossSigningAccountData() { - const mx = initMatrix.matrixClient; +export function hasCrossSigningAccountData(mx) { const masterKeyData = mx.getAccountData('m.cross_signing.master'); return !!masterKeyData; } -export function getDefaultSSKey() { - const mx = initMatrix.matrixClient; +export function getDefaultSSKey(mx) { try { return mx.getAccountData('m.secret_storage.default_key').getContent().key; } catch { @@ -187,8 +181,7 @@ export function getDefaultSSKey() { } } -export function getSSKeyInfo(key) { - const mx = initMatrix.matrixClient; +export function getSSKeyInfo(mx, key) { try { return mx.getAccountData(`m.secret_storage.key.${key}`).getContent(); } catch { @@ -196,8 +189,7 @@ export function getSSKeyInfo(key) { } } -export async function hasDevices(userId) { - const mx = initMatrix.matrixClient; +export async function hasDevices(mx, userId) { try { const usersDeviceMap = await mx.downloadKeys([userId, mx.getUserId()]); return Object.values(usersDeviceMap) diff --git a/src/util/sort.js b/src/util/sort.js index f9a0b7908..cc73cf577 100644 --- a/src/util/sort.js +++ b/src/util/sort.js @@ -1,30 +1,3 @@ -import initMatrix from '../client/initMatrix'; - -export function roomIdByActivity(id1, id2) { - const room1 = initMatrix.matrixClient.getRoom(id1); - const room2 = initMatrix.matrixClient.getRoom(id2); - - return room2.getLastActiveTimestamp() - room1.getLastActiveTimestamp(); -} - -export function roomIdByAtoZ(aId, bId) { - let aName = initMatrix.matrixClient.getRoom(aId).name; - let bName = initMatrix.matrixClient.getRoom(bId).name; - - // remove "#" from the room name - // To ignore it in sorting - aName = aName.replace(/#/g, ''); - bName = bName.replace(/#/g, ''); - - if (aName.toLowerCase() < bName.toLowerCase()) { - return -1; - } - if (aName.toLowerCase() > bName.toLowerCase()) { - return 1; - } - return 0; -} - export function memberByAtoZ(m1, m2) { const aName = m1.name; const bName = m2.name; From e6d6b0349ebb07b713a54acd6b4eed5abc8bbde9 Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Tue, 23 Jul 2024 10:44:32 +0530 Subject: [PATCH 1170/1531] Fix unread reset and notification settings (#1824) * reset unread with client sync state change * fix notification toggle setting not working * revert formatOnSave vscode setting --- .eslintrc.cjs | 8 ++++ src/app/hooks/usePermission.js | 28 -------------- src/app/hooks/usePermission.ts | 30 +++++++++++++++ src/app/organisms/settings/Settings.jsx | 29 ++++++++------- src/app/pages/client/ClientNonUIFeatures.tsx | 5 ++- src/app/state/room/roomToUnread.ts | 7 +++- src/client/action/settings.js | 12 ------ src/client/state/cons.js | 4 -- src/client/state/settings.js | 39 -------------------- 9 files changed, 62 insertions(+), 100 deletions(-) delete mode 100644 src/app/hooks/usePermission.js create mode 100644 src/app/hooks/usePermission.ts diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 36101fbe5..9d5a27d90 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -61,4 +61,12 @@ module.exports = { "@typescript-eslint/no-unused-vars": "error", "@typescript-eslint/no-shadow": "error" }, + overrides: [ + { + files: ['*.ts'], + rules: { + 'no-undef': 'off', + }, + }, + ], }; diff --git a/src/app/hooks/usePermission.js b/src/app/hooks/usePermission.js deleted file mode 100644 index 5dc760781..000000000 --- a/src/app/hooks/usePermission.js +++ /dev/null @@ -1,28 +0,0 @@ -/* eslint-disable import/prefer-default-export */ - -import { useEffect, useState } from 'react'; - -export function usePermission(name, initial) { - const [state, setState] = useState(initial); - - useEffect(() => { - let descriptor; - - const update = () => setState(descriptor.state); - - if (navigator.permissions?.query) { - navigator.permissions.query({ name }).then((_descriptor) => { - descriptor = _descriptor; - - update(); - descriptor.addEventListener('change', update); - }); - } - - return () => { - if (descriptor) descriptor.removeEventListener('change', update); - }; - }, []); - - return [state, setState]; -} diff --git a/src/app/hooks/usePermission.ts b/src/app/hooks/usePermission.ts new file mode 100644 index 000000000..5a3ec9f6b --- /dev/null +++ b/src/app/hooks/usePermission.ts @@ -0,0 +1,30 @@ +import { useEffect, useState } from "react"; + +export function usePermissionState(name: PermissionName, initialValue: PermissionState = 'prompt') { + const [permissionState, setPermissionState] = useState(initialValue); + + useEffect(() => { + let permissionStatus: PermissionStatus; + + function handlePermissionChange(this: PermissionStatus) { + setPermissionState(this.state); + } + + navigator.permissions + .query({ name }) + .then((permStatus: PermissionStatus) => { + permissionStatus = permStatus; + handlePermissionChange.apply(permStatus); + permStatus.addEventListener("change", handlePermissionChange); + }) + .catch(() => { + // Silence error since FF doesn't support microphone permission + }); + + return () => { + permissionStatus?.removeEventListener("change", handlePermissionChange); + }; + }, [name]); + + return permissionState; +} \ No newline at end of file diff --git a/src/app/organisms/settings/Settings.jsx b/src/app/organisms/settings/Settings.jsx index f2951b812..779931df3 100644 --- a/src/app/organisms/settings/Settings.jsx +++ b/src/app/organisms/settings/Settings.jsx @@ -7,9 +7,8 @@ import settings from '../../../client/state/settings'; import navigation from '../../../client/state/navigation'; import { toggleSystemTheme, - toggleNotifications, toggleNotificationSounds, } from '../../../client/action/settings'; -import { usePermission } from '../../hooks/usePermission'; +import { usePermissionState } from '../../hooks/usePermission'; import Text from '../../atoms/text/Text'; import IconButton from '../../atoms/button/IconButton'; @@ -230,23 +229,25 @@ function AppearanceSection() { } function NotificationsSection() { - const [permission, setPermission] = usePermission('notifications', window.Notification?.permission); - - const [, updateState] = useState({}); + const notifPermission = usePermissionState('notifications', window.Notification?.permission ?? "denied"); + const [showNotifications, setShowNotifications] = useSetting(settingsAtom, 'showNotifications') + const [isNotificationSounds, setIsNotificationSounds] = useSetting(settingsAtom, 'isNotificationSounds') const renderOptions = () => { if (window.Notification === undefined) { return Not supported in this browser.; } - if (permission === 'granted') { + if (notifPermission === 'denied') { + return Permission Denied + } + + if (notifPermission === 'granted') { return ( { - toggleNotifications(); - setPermission(window.Notification?.permission); - updateState({}); + setShowNotifications(!showNotifications); }} /> ); @@ -255,7 +256,9 @@ function NotificationsSection() { return ( @@ -275,8 +278,8 @@ function NotificationsSection() { title="Notification Sound" options={( { toggleNotificationSounds(); updateState({}); }} + isActive={isNotificationSounds} + onToggle={() => setIsNotificationSounds(!isNotificationSounds)} /> )} content={Play sound when new messages arrive.} diff --git a/src/app/pages/client/ClientNonUIFeatures.tsx b/src/app/pages/client/ClientNonUIFeatures.tsx index 947764ca4..5f557aa72 100644 --- a/src/app/pages/client/ClientNonUIFeatures.tsx +++ b/src/app/pages/client/ClientNonUIFeatures.tsx @@ -58,6 +58,7 @@ function InviteNotifications() { const mx = useMatrixClient(); const navigate = useNavigate(); + const [showNotifications] = useSetting(settingsAtom, 'showNotifications'); const [notificationSound] = useSetting(settingsAtom, 'isNotificationSounds'); const notify = useCallback( @@ -84,7 +85,7 @@ function InviteNotifications() { useEffect(() => { if (invites.length > perviousInviteLen && mx.getSyncState() === 'SYNCING') { - if (Notification.permission === 'granted') { + if (showNotifications && Notification.permission === 'granted') { notify(invites.length - perviousInviteLen); } @@ -92,7 +93,7 @@ function InviteNotifications() { playSound(); } } - }, [mx, invites, perviousInviteLen, notificationSound, notify, playSound]); + }, [mx, invites, perviousInviteLen, showNotifications, notificationSound, notify, playSound]); return ( // eslint-disable-next-line jsx-a11y/media-has-caption diff --git a/src/app/state/room/roomToUnread.ts b/src/app/state/room/roomToUnread.ts index 5a009405e..8cb9d9584 100644 --- a/src/app/state/room/roomToUnread.ts +++ b/src/app/state/room/roomToUnread.ts @@ -185,8 +185,11 @@ export const useBindRoomToUnreadAtom = ( useSyncState( mx, useCallback( - (state) => { - if (state === SyncState.Prepared) { + (state, prevState) => { + if ( + (state === SyncState.Prepared && prevState === null) || + (state === SyncState.Syncing && prevState !== SyncState.Syncing) + ) { setUnreadAtom({ type: 'RESET', unreadInfos: getUnreadInfos(mx), diff --git a/src/client/action/settings.js b/src/client/action/settings.js index 7b539c8d7..e849702b8 100644 --- a/src/client/action/settings.js +++ b/src/client/action/settings.js @@ -30,15 +30,3 @@ export function toggleNickAvatarEvents() { type: cons.actions.settings.TOGGLE_NICKAVATAR_EVENT, }); } - -export function toggleNotifications() { - appDispatcher.dispatch({ - type: cons.actions.settings.TOGGLE_NOTIFICATIONS, - }); -} - -export function toggleNotificationSounds() { - appDispatcher.dispatch({ - type: cons.actions.settings.TOGGLE_NOTIFICATION_SOUNDS, - }); -} diff --git a/src/client/state/cons.js b/src/client/state/cons.js index 523e871a1..353ce47d9 100644 --- a/src/client/state/cons.js +++ b/src/client/state/cons.js @@ -52,8 +52,6 @@ const cons = { TOGGLE_PEOPLE_DRAWER: 'TOGGLE_PEOPLE_DRAWER', TOGGLE_MEMBERSHIP_EVENT: 'TOGGLE_MEMBERSHIP_EVENT', TOGGLE_NICKAVATAR_EVENT: 'TOGGLE_NICKAVATAR_EVENT', - TOGGLE_NOTIFICATIONS: 'TOGGLE_NOTIFICATIONS', - TOGGLE_NOTIFICATION_SOUNDS: 'TOGGLE_NOTIFICATION_SOUNDS', }, }, events: { @@ -81,8 +79,6 @@ const cons = { PEOPLE_DRAWER_TOGGLED: 'PEOPLE_DRAWER_TOGGLED', MEMBERSHIP_EVENTS_TOGGLED: 'MEMBERSHIP_EVENTS_TOGGLED', NICKAVATAR_EVENTS_TOGGLED: 'NICKAVATAR_EVENTS_TOGGLED', - NOTIFICATIONS_TOGGLED: 'NOTIFICATIONS_TOGGLED', - NOTIFICATION_SOUNDS_TOGGLED: 'NOTIFICATION_SOUNDS_TOGGLED', }, }, }; diff --git a/src/client/state/settings.js b/src/client/state/settings.js index d39b2ca10..bf9562cc7 100644 --- a/src/client/state/settings.js +++ b/src/client/state/settings.js @@ -33,8 +33,6 @@ class Settings extends EventEmitter { this.isPeopleDrawer = this.getIsPeopleDrawer(); this.hideMembershipEvents = this.getHideMembershipEvents(); this.hideNickAvatarEvents = this.getHideNickAvatarEvents(); - this._showNotifications = this.getShowNotifications(); - this.isNotificationSounds = this.getIsNotificationSounds(); this.darkModeQueryList = window.matchMedia('(prefers-color-scheme: dark)'); @@ -137,29 +135,6 @@ class Settings extends EventEmitter { return settings.isPeopleDrawer; } - get showNotifications() { - if (window.Notification?.permission !== 'granted') return false; - return this._showNotifications; - } - - getShowNotifications() { - if (typeof this._showNotifications === 'boolean') return this._showNotifications; - - const settings = getSettings(); - if (settings === null) return true; - if (typeof settings.showNotifications === 'undefined') return true; - return settings.showNotifications; - } - - getIsNotificationSounds() { - if (typeof this.isNotificationSounds === 'boolean') return this.isNotificationSounds; - - const settings = getSettings(); - if (settings === null) return true; - if (typeof settings.isNotificationSounds === 'undefined') return true; - return settings.isNotificationSounds; - } - setter(action) { const actions = { [cons.actions.settings.TOGGLE_SYSTEM_THEME]: () => { @@ -185,20 +160,6 @@ class Settings extends EventEmitter { setSettings('hideNickAvatarEvents', this.hideNickAvatarEvents); this.emit(cons.events.settings.NICKAVATAR_EVENTS_TOGGLED, this.hideNickAvatarEvents); }, - [cons.actions.settings.TOGGLE_NOTIFICATIONS]: async () => { - if (window.Notification?.permission !== 'granted') { - this._showNotifications = false; - } else { - this._showNotifications = !this._showNotifications; - } - setSettings('showNotifications', this._showNotifications); - this.emit(cons.events.settings.NOTIFICATIONS_TOGGLED, this._showNotifications); - }, - [cons.actions.settings.TOGGLE_NOTIFICATION_SOUNDS]: () => { - this.isNotificationSounds = !this.isNotificationSounds; - setSettings('isNotificationSounds', this.isNotificationSounds); - this.emit(cons.events.settings.NOTIFICATION_SOUNDS_TOGGLED, this.isNotificationSounds); - }, }; actions[action.type]?.(); From a32c8bf2282947c7fc61558e1a54700652cf0e64 Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Tue, 23 Jul 2024 10:45:17 +0530 Subject: [PATCH 1171/1531] Load room member even when member drawer is closed (#1825) --- src/app/features/lobby/Lobby.tsx | 4 +++- src/app/features/room/MembersDrawer.tsx | 5 ++--- src/app/features/room/Room.tsx | 6 ++++-- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/app/features/lobby/Lobby.tsx b/src/app/features/lobby/Lobby.tsx index 62df2769a..c96372350 100644 --- a/src/app/features/lobby/Lobby.tsx +++ b/src/app/features/lobby/Lobby.tsx @@ -47,6 +47,7 @@ import { import { useOrphanSpaces } from '../../state/hooks/roomList'; import { roomToParentsAtom } from '../../state/room/roomToParents'; import { AccountDataEvent } from '../../../types/matrix/accountData'; +import { useRoomMembers } from '../../hooks/useRoomMembers'; export function Lobby() { const navigate = useNavigate(); @@ -57,6 +58,7 @@ export function Lobby() { const space = useSpace(); const spacePowerLevels = usePowerLevels(space); const lex = useMemo(() => new ASCIILexicalTable(' '.charCodeAt(0), '~'.charCodeAt(0), 6), []); + const members = useRoomMembers(mx, space.roomId); const scrollRef = useRef(null); const heroSectionRef = useRef(null); @@ -519,7 +521,7 @@ export function Lobby() { {screenSize === ScreenSize.Desktop && isDrawer && ( <> - + )} diff --git a/src/app/features/room/MembersDrawer.tsx b/src/app/features/room/MembersDrawer.tsx index 70a9aa348..15d074121 100644 --- a/src/app/features/room/MembersDrawer.tsx +++ b/src/app/features/room/MembersDrawer.tsx @@ -35,7 +35,6 @@ import classNames from 'classnames'; import { openProfileViewer } from '../../../client/action/navigation'; import * as css from './MembersDrawer.css'; -import { useRoomMembers } from '../../hooks/useRoomMembers'; import { useMatrixClient } from '../../hooks/useMatrixClient'; import { Membership } from '../../../types/matrix/room'; import { UseStateProvider } from '../../components/UseStateProvider'; @@ -168,13 +167,13 @@ const getRoomMemberStr: SearchItemStrGetter = (m, query) => type MembersDrawerProps = { room: Room; + members: RoomMember[]; }; -export function MembersDrawer({ room }: MembersDrawerProps) { +export function MembersDrawer({ room, members }: MembersDrawerProps) { const mx = useMatrixClient(); const scrollRef = useRef(null); const searchInputRef = useRef(null); const scrollTopAnchorRef = useRef(null); - const members = useRoomMembers(mx, room.roomId); const getPowerLevelTag = usePowerLevelTags(); const fetchingMembers = members.length < room.getJoinedMemberCount(); const setPeopleDrawer = useSetSetting(settingsAtom, 'isPeopleDrawer'); diff --git a/src/app/features/room/Room.tsx b/src/app/features/room/Room.tsx index 19ac53e15..ee3e70274 100644 --- a/src/app/features/room/Room.tsx +++ b/src/app/features/room/Room.tsx @@ -12,6 +12,7 @@ import { useRoom } from '../../hooks/useRoom'; import { useKeyDown } from '../../hooks/useKeyDown'; import { markAsRead } from '../../../client/action/notifications'; import { useMatrixClient } from '../../hooks/useMatrixClient'; +import { useRoomMembers } from '../../hooks/useRoomMembers'; export function Room() { const { eventId } = useParams(); @@ -21,6 +22,7 @@ export function Room() { const [isDrawer] = useSetting(settingsAtom, 'isPeopleDrawer'); const screenSize = useScreenSizeContext(); const powerLevels = usePowerLevels(room); + const members = useRoomMembers(mx, room.roomId); useKeyDown( window, @@ -30,7 +32,7 @@ export function Room() { markAsRead(mx, room.roomId); } }, - [room.roomId] + [mx, room.roomId] ) ); @@ -41,7 +43,7 @@ export function Room() { {screenSize === ScreenSize.Desktop && isDrawer && ( <> - + )} From cc4c222975eadbb382e591e79b37fdc56c479ee9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 23 Jul 2024 15:15:51 +1000 Subject: [PATCH 1172/1531] Bump docker/build-push-action from 6.4.0 to 6.5.0 (#1834) Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 6.4.0 to 6.5.0. - [Release notes](https://github.com/docker/build-push-action/releases) - [Commits](https://github.com/docker/build-push-action/compare/v6.4.0...v6.5.0) --- updated-dependencies: - dependency-name: docker/build-push-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/docker-pr.yml | 2 +- .github/workflows/prod-deploy.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docker-pr.yml b/.github/workflows/docker-pr.yml index fdeb237f2..7b1e2abd4 100644 --- a/.github/workflows/docker-pr.yml +++ b/.github/workflows/docker-pr.yml @@ -13,7 +13,7 @@ jobs: - name: Checkout repository uses: actions/checkout@v4.1.7 - name: Build Docker image - uses: docker/build-push-action@v6.4.0 + uses: docker/build-push-action@v6.5.0 with: context: . push: false diff --git a/.github/workflows/prod-deploy.yml b/.github/workflows/prod-deploy.yml index 7bc82b42b..304444813 100644 --- a/.github/workflows/prod-deploy.yml +++ b/.github/workflows/prod-deploy.yml @@ -90,7 +90,7 @@ jobs: ${{ secrets.DOCKER_USERNAME }}/cinny ghcr.io/${{ github.repository }} - name: Build and push Docker image - uses: docker/build-push-action@v6.4.0 + uses: docker/build-push-action@v6.5.0 with: context: . platforms: linux/amd64,linux/arm64 From ab73225f00d0ad97cb5af4d3c5761032e003a222 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 23 Jul 2024 15:16:16 +1000 Subject: [PATCH 1173/1531] Bump softprops/action-gh-release from 2.0.6 to 2.0.8 (#1833) Bumps [softprops/action-gh-release](https://github.com/softprops/action-gh-release) from 2.0.6 to 2.0.8. - [Release notes](https://github.com/softprops/action-gh-release/releases) - [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md) - [Commits](https://github.com/softprops/action-gh-release/compare/a74c6b72af54cfa997e81df42d94703d6313a2d0...c062e08bd532815e2082a85e87e3ef29c3e6d191) --- updated-dependencies: - dependency-name: softprops/action-gh-release dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/prod-deploy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/prod-deploy.yml b/.github/workflows/prod-deploy.yml index 304444813..434607340 100644 --- a/.github/workflows/prod-deploy.yml +++ b/.github/workflows/prod-deploy.yml @@ -52,7 +52,7 @@ jobs: gpg --export | xxd -p echo '${{ secrets.GNUPG_PASSPHRASE }}' | gpg --batch --yes --pinentry-mode loopback --passphrase-fd 0 --armor --detach-sign cinny-${{ steps.vars.outputs.tag }}.tar.gz - name: Upload tagged release - uses: softprops/action-gh-release@a74c6b72af54cfa997e81df42d94703d6313a2d0 + uses: softprops/action-gh-release@c062e08bd532815e2082a85e87e3ef29c3e6d191 with: files: | cinny-${{ steps.vars.outputs.tag }}.tar.gz From 98a378ad8a1d53bf326235c0666348b38a8c07b1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 23 Jul 2024 15:16:38 +1000 Subject: [PATCH 1174/1531] Bump docker/setup-buildx-action from 3.4.0 to 3.5.0 (#1832) Bumps [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) from 3.4.0 to 3.5.0. - [Release notes](https://github.com/docker/setup-buildx-action/releases) - [Commits](https://github.com/docker/setup-buildx-action/compare/v3.4.0...v3.5.0) --- updated-dependencies: - dependency-name: docker/setup-buildx-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/prod-deploy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/prod-deploy.yml b/.github/workflows/prod-deploy.yml index 434607340..76c6ffc16 100644 --- a/.github/workflows/prod-deploy.yml +++ b/.github/workflows/prod-deploy.yml @@ -70,7 +70,7 @@ jobs: - name: Set up QEMU uses: docker/setup-qemu-action@v3.1.0 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3.4.0 + uses: docker/setup-buildx-action@v3.5.0 - name: Login to Docker Hub uses: docker/login-action@v3.2.0 with: From da536c8c3f192cef653d072eebd43c90799ffe33 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 23 Jul 2024 15:16:56 +1000 Subject: [PATCH 1175/1531] Bump docker/login-action from 3.2.0 to 3.3.0 (#1831) Bumps [docker/login-action](https://github.com/docker/login-action) from 3.2.0 to 3.3.0. - [Release notes](https://github.com/docker/login-action/releases) - [Commits](https://github.com/docker/login-action/compare/v3.2.0...v3.3.0) --- updated-dependencies: - dependency-name: docker/login-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/prod-deploy.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/prod-deploy.yml b/.github/workflows/prod-deploy.yml index 76c6ffc16..bee0035d0 100644 --- a/.github/workflows/prod-deploy.yml +++ b/.github/workflows/prod-deploy.yml @@ -72,12 +72,12 @@ jobs: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3.5.0 - name: Login to Docker Hub - uses: docker/login-action@v3.2.0 + uses: docker/login-action@v3.3.0 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} - name: Login to the Container registry - uses: docker/login-action@v3.2.0 + uses: docker/login-action@v3.3.0 with: registry: ghcr.io username: ${{ github.actor }} From 3110505b21247ca6586e23efeceef8fb27ac2323 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 23 Jul 2024 15:17:12 +1000 Subject: [PATCH 1176/1531] Bump docker/setup-qemu-action from 3.1.0 to 3.2.0 (#1830) Bumps [docker/setup-qemu-action](https://github.com/docker/setup-qemu-action) from 3.1.0 to 3.2.0. - [Release notes](https://github.com/docker/setup-qemu-action/releases) - [Commits](https://github.com/docker/setup-qemu-action/compare/v3.1.0...v3.2.0) --- updated-dependencies: - dependency-name: docker/setup-qemu-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/prod-deploy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/prod-deploy.yml b/.github/workflows/prod-deploy.yml index bee0035d0..a0a70d13d 100644 --- a/.github/workflows/prod-deploy.yml +++ b/.github/workflows/prod-deploy.yml @@ -68,7 +68,7 @@ jobs: - name: Checkout repository uses: actions/checkout@v4.1.7 - name: Set up QEMU - uses: docker/setup-qemu-action@v3.1.0 + uses: docker/setup-qemu-action@v3.2.0 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3.5.0 - name: Login to Docker Hub From b387370aaf96c7bb6fae4c4aafcd364afa0f7856 Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Tue, 23 Jul 2024 19:22:53 +0530 Subject: [PATCH 1177/1531] Add setting for page zoom (#1835) * add setting for page zoom * parse integer in zoom change listener * fix zoom input width * fix null gets saved as page zoom --- src/app/organisms/settings/Settings.jsx | 451 +++++++++++++------ src/app/pages/client/ClientNonUIFeatures.tsx | 26 ++ src/app/pages/client/ClientRoot.tsx | 17 +- src/app/state/settings.ts | 2 + 4 files changed, 341 insertions(+), 155 deletions(-) diff --git a/src/app/organisms/settings/Settings.jsx b/src/app/organisms/settings/Settings.jsx index 779931df3..6329a57fe 100644 --- a/src/app/organisms/settings/Settings.jsx +++ b/src/app/organisms/settings/Settings.jsx @@ -1,13 +1,13 @@ import React, { useState, useEffect } from 'react'; +import { Input, toRem } from 'folds'; +import { isKeyHotkey } from 'is-hotkey'; import './Settings.scss'; import { clearCacheAndReload, logoutClient } from '../../../client/initMatrix'; import cons from '../../../client/state/cons'; import settings from '../../../client/state/settings'; import navigation from '../../../client/state/navigation'; -import { - toggleSystemTheme, -} from '../../../client/action/settings'; +import { toggleSystemTheme } from '../../../client/action/settings'; import { usePermissionState } from '../../hooks/usePermission'; import Text from '../../atoms/text/Text'; @@ -55,14 +55,41 @@ function AppearanceSection() { const [messageLayout, setMessageLayout] = useSetting(settingsAtom, 'messageLayout'); const [messageSpacing, setMessageSpacing] = useSetting(settingsAtom, 'messageSpacing'); const [twitterEmoji, setTwitterEmoji] = useSetting(settingsAtom, 'twitterEmoji'); + const [pageZoom, setPageZoom] = useSetting(settingsAtom, 'pageZoom'); const [isMarkdown, setIsMarkdown] = useSetting(settingsAtom, 'isMarkdown'); - const [hideMembershipEvents, setHideMembershipEvents] = useSetting(settingsAtom, 'hideMembershipEvents'); - const [hideNickAvatarEvents, setHideNickAvatarEvents] = useSetting(settingsAtom, 'hideNickAvatarEvents'); + const [hideMembershipEvents, setHideMembershipEvents] = useSetting( + settingsAtom, + 'hideMembershipEvents' + ); + const [hideNickAvatarEvents, setHideNickAvatarEvents] = useSetting( + settingsAtom, + 'hideNickAvatarEvents' + ); const [mediaAutoLoad, setMediaAutoLoad] = useSetting(settingsAtom, 'mediaAutoLoad'); const [urlPreview, setUrlPreview] = useSetting(settingsAtom, 'urlPreview'); const [encUrlPreview, setEncUrlPreview] = useSetting(settingsAtom, 'encUrlPreview'); const [showHiddenEvents, setShowHiddenEvents] = useSetting(settingsAtom, 'showHiddenEvents'); - const spacings = ['0', '100', '200', '300', '400', '500'] + const spacings = ['0', '100', '200', '300', '400', '500']; + + const [currentZoom, setCurrentZoom] = useState(`${pageZoom}`); + + const handleZoomChange = (evt) => { + setCurrentZoom(evt.target.value); + }; + + const handleZoomEnter = (evt) => { + if (isKeyHotkey('escape', evt)) { + evt.stopPropagation(); + setCurrentZoom(pageZoom); + } + if (isKeyHotkey('enter', evt)) { + const newZoom = parseInt(evt.target.value, 10); + if (Number.isNaN(newZoom)) return; + const safeZoom = Math.max(Math.min(newZoom, 150), 75); + setPageZoom(safeZoom); + setCurrentZoom(safeZoom); + } + }; return (
      @@ -70,17 +97,20 @@ function AppearanceSection() { Theme { toggleSystemTheme(); updateState({}); }} + onToggle={() => { + toggleSystemTheme(); + updateState({}); + }} /> - )} + } content={Use light or dark mode based on the system settings.} /> - )} + } /> setTwitterEmoji(!twitterEmoji)} - /> - )} + options={ + setTwitterEmoji(!twitterEmoji)} /> + } content={Use Twitter emoji instead of system emoji.} /> + %} + /> + } + content={ + + Change page zoom to scale user interface between 75% to 150%. Default: 100% + + } + />
      Room messages @@ -114,113 +164,106 @@ function AppearanceSection() { title="Message Layout" content={ setMessageLayout(index)} - /> + selected={messageLayout} + segments={[{ text: 'Modern' }, { text: 'Compact' }, { text: 'Bubble' }]} + onSelect={(index) => setMessageLayout(index)} + /> } /> s === messageSpacing)} - segments={[ - { text: 'No' }, - { text: 'XXS' }, - { text: 'XS' }, - { text: 'S' }, - { text: 'M' }, - { text: 'L' }, - ]} - onSelect={(index) => { - setMessageSpacing(spacings[index]) - }} - /> + selected={spacings.findIndex((s) => s === messageSpacing)} + segments={[ + { text: 'No' }, + { text: 'XXS' }, + { text: 'XS' }, + { text: 'S' }, + { text: 'M' }, + { text: 'L' }, + ]} + onSelect={(index) => { + setMessageSpacing(spacings[index]); + }} + /> } /> setEnterForNewline(!enterForNewline) } + onToggle={() => setEnterForNewline(!enterForNewline)} /> - )} - content={{`Use ${isMacOS() ? KeySymbol.Command : 'Ctrl'} + ENTER to send message and ENTER for newline.`}} + } + content={ + {`Use ${ + isMacOS() ? KeySymbol.Command : 'Ctrl' + } + ENTER to send message and ENTER for newline.`} + } /> setIsMarkdown(!isMarkdown) } - /> - )} + options={ setIsMarkdown(!isMarkdown)} />} content={Format messages with markdown syntax before sending.} /> setHideMembershipEvents(!hideMembershipEvents)} /> - )} - content={Hide membership change messages from room timeline. (Join, Leave, Invite, Kick and Ban)} + } + content={ + + Hide membership change messages from room timeline. (Join, Leave, Invite, Kick and + Ban) + + } /> setHideNickAvatarEvents(!hideNickAvatarEvents)} /> - )} - content={Hide nick and avatar change messages from room timeline.} + } + content={ + Hide nick and avatar change messages from room timeline. + } /> setMediaAutoLoad(!mediaAutoLoad)} - /> - )} - content={Prevent images and videos from auto loading to save bandwidth.} + options={ + setMediaAutoLoad(!mediaAutoLoad)} /> + } + content={ + Prevent images and videos from auto loading to save bandwidth. + } /> setUrlPreview(!urlPreview)} - /> - )} + options={ setUrlPreview(!urlPreview)} />} content={Show url preview for link in messages.} /> setEncUrlPreview(!encUrlPreview)} - /> - )} + options={ + setEncUrlPreview(!encUrlPreview)} /> + } content={Show url preview for link in encrypted messages.} /> setShowHiddenEvents(!showHiddenEvents)} /> - )} + } content={Show hidden state and message events.} />
      @@ -229,19 +272,29 @@ function AppearanceSection() { } function NotificationsSection() { - const notifPermission = usePermissionState('notifications', window.Notification?.permission ?? "denied"); - const [showNotifications, setShowNotifications] = useSetting(settingsAtom, 'showNotifications') - const [isNotificationSounds, setIsNotificationSounds] = useSetting(settingsAtom, 'isNotificationSounds') + const notifPermission = usePermissionState( + 'notifications', + window.Notification?.permission ?? 'denied' + ); + const [showNotifications, setShowNotifications] = useSetting(settingsAtom, 'showNotifications'); + const [isNotificationSounds, setIsNotificationSounds] = useSetting( + settingsAtom, + 'isNotificationSounds' + ); const renderOptions = () => { if (window.Notification === undefined) { - return Not supported in this browser.; + return ( + + Not supported in this browser. + + ); } if (notifPermission === 'denied') { - return Permission Denied + return Permission Denied; } - + if (notifPermission === 'granted') { return ( window.Notification.requestPermission().then(() => { - setShowNotifications(window.Notification?.permission === 'granted'); - })} + onClick={() => + window.Notification.requestPermission().then(() => { + setShowNotifications(window.Notification?.permission === 'granted'); + }) + } > Request permission @@ -276,12 +331,12 @@ function NotificationsSection() { /> setIsNotificationSounds(!isNotificationSounds)} /> - )} + } content={Play sound when new messages arrive.} />
      @@ -295,8 +350,12 @@ function NotificationsSection() { function EmojiSection() { return ( <> -
      -
      +
      + +
      +
      + +
      ); } @@ -314,21 +373,29 @@ function SecuritySection() { Export/Import encryption keys - Export end-to-end encryption room keys to decrypt old messages in other session. In order to encrypt keys you need to set a password, which will be used while importing. + + Export end-to-end encryption room keys to decrypt old messages in other session. In + order to encrypt keys you need to set a password, which will be used while + importing. + - )} + } /> - {'To decrypt older messages, Export E2EE room keys from Element (Settings > Security & Privacy > Encryption > Cryptography) and import them here. Imported keys are encrypted so you\'ll have to enter the password you set in order to decrypt it.'} + + { + "To decrypt older messages, Export E2EE room keys from Element (Settings > Security & Privacy > Encryption > Cryptography) and import them here. Imported keys are encrypted so you'll have to enter the password you set in order to decrypt it." + } + - )} + } />
      @@ -337,7 +404,7 @@ function SecuritySection() { function AboutSection() { const mx = useMatrixClient(); - + return (
      @@ -347,14 +414,21 @@ function AboutSection() {
      Cinny - {`v${cons.version}`} + {`v${cons.version}`} Yet another matrix client
      - + - +
      @@ -364,20 +438,104 @@ function AboutSection() {
      @@ -393,32 +551,38 @@ export const tabText = { SECURITY: 'Security', ABOUT: 'About', }; -const tabItems = [{ - text: tabText.APPEARANCE, - iconSrc: SunIC, - disabled: false, - render: () => , -}, { - text: tabText.NOTIFICATIONS, - iconSrc: BellIC, - disabled: false, - render: () => , -}, { - text: tabText.EMOJI, - iconSrc: EmojiIC, - disabled: false, - render: () => , -}, { - text: tabText.SECURITY, - iconSrc: LockIC, - disabled: false, - render: () => , -}, { - text: tabText.ABOUT, - iconSrc: InfoIC, - disabled: false, - render: () => , -}]; +const tabItems = [ + { + text: tabText.APPEARANCE, + iconSrc: SunIC, + disabled: false, + render: () => , + }, + { + text: tabText.NOTIFICATIONS, + iconSrc: BellIC, + disabled: false, + render: () => , + }, + { + text: tabText.EMOJI, + iconSrc: EmojiIC, + disabled: false, + render: () => , + }, + { + text: tabText.SECURITY, + iconSrc: LockIC, + disabled: false, + render: () => , + }, + { + text: tabText.ABOUT, + iconSrc: InfoIC, + disabled: false, + render: () => , + }, +]; function useWindowToggle(setSelectedTab) { const [isOpen, setIsOpen] = useState(false); @@ -447,7 +611,14 @@ function Settings() { const handleTabChange = (tabItem) => setSelectedTab(tabItem); const handleLogout = async () => { - if (await confirmDialog('Logout', 'Are you sure that you want to logout your session?', 'Logout', 'danger')) { + if ( + await confirmDialog( + 'Logout', + 'Are you sure that you want to logout your session?', + 'Logout', + 'danger' + ) + ) { logoutClient(mx); } }; @@ -456,15 +627,19 @@ function Settings() { Settings} - contentOptions={( + title={ + + Settings + + } + contentOptions={ <> - )} + } onRequestClose={requestClose} > {isOpen && ( @@ -475,9 +650,7 @@ function Settings() { defaultSelected={tabItems.findIndex((tab) => tab.text === selectedTab.text)} onSelect={handleTabChange} /> -
      - { selectedTab.render() } -
      +
      {selectedTab.render()}
      )} diff --git a/src/app/pages/client/ClientNonUIFeatures.tsx b/src/app/pages/client/ClientNonUIFeatures.tsx index 5f557aa72..845fceb3f 100644 --- a/src/app/pages/client/ClientNonUIFeatures.tsx +++ b/src/app/pages/client/ClientNonUIFeatures.tsx @@ -26,6 +26,30 @@ import { getMxIdLocalPart } from '../../utils/matrix'; import { useSelectedRoom } from '../../hooks/router/useSelectedRoom'; import { useInboxNotificationsSelected } from '../../hooks/router/useInbox'; +function SystemEmojiFeature() { + const [twitterEmoji] = useSetting(settingsAtom, 'twitterEmoji'); + + if (twitterEmoji) { + document.documentElement.style.setProperty('--font-emoji', 'Twemoji'); + } else { + document.documentElement.style.setProperty('--font-emoji', 'Twemoji_DISABLED'); + } + + return null; +} + +function PageZoomFeature() { + const [pageZoom] = useSetting(settingsAtom, 'pageZoom'); + + if (pageZoom === 100) { + document.documentElement.style.removeProperty('font-size'); + } else { + document.documentElement.style.setProperty('font-size', `calc(1em * ${pageZoom / 100})`); + } + + return null; +} + function FaviconUpdater() { const roomToUnread = useAtomValue(roomToUnreadAtom); @@ -233,6 +257,8 @@ type ClientNonUIFeaturesProps = { export function ClientNonUIFeatures({ children }: ClientNonUIFeaturesProps) { return ( <> + + diff --git a/src/app/pages/client/ClientRoot.tsx b/src/app/pages/client/ClientRoot.tsx index a590e0bc5..f30bf63a5 100644 --- a/src/app/pages/client/ClientRoot.tsx +++ b/src/app/pages/client/ClientRoot.tsx @@ -32,25 +32,11 @@ import { SpecVersions } from './SpecVersions'; import Windows from '../../organisms/pw/Windows'; import Dialogs from '../../organisms/pw/Dialogs'; import ReusableContextMenu from '../../atoms/context-menu/ReusableContextMenu'; -import { useSetting } from '../../state/hooks/settings'; -import { settingsAtom } from '../../state/settings'; import { AsyncStatus, useAsyncCallback } from '../../hooks/useAsyncCallback'; import { useSyncState } from '../../hooks/useSyncState'; import { stopPropagation } from '../../utils/keyboard'; import { SyncStatus } from './SyncStatus'; -function SystemEmojiFeature() { - const [twitterEmoji] = useSetting(settingsAtom, 'twitterEmoji'); - - if (twitterEmoji) { - document.documentElement.style.setProperty('--font-emoji', 'Twemoji'); - } else { - document.documentElement.style.setProperty('--font-emoji', 'Twemoji_DISABLED'); - } - - return null; -} - function ClientRootLoading() { return ( @@ -198,7 +184,7 @@ export function ClientRoot({ children }: ClientRootProps) { {startState.status === AsyncStatus.Error && ( {`Failed to load. ${startState.error.message}`} )} -
      - ); - } -); + return ( + + + } + radii="300" + disabled={!unread} + > + + Mark as Read + + + + + + } + radii="300" + disabled={!canInvite} + > + + Invite + + + } + radii="300" + > + + Copy Link + + + } + radii="300" + > + + Room Settings + + + + + + + {(promptLeave, setPromptLeave) => ( + <> + setPromptLeave(true)} + variant="Critical" + fill="None" + size="300" + after={} + radii="300" + aria-pressed={promptLeave} + > + + Leave Room + + + {promptLeave && ( + setPromptLeave(false)} + /> + )} + + )} + + + + ); +}); export function RoomViewHeader() { const navigate = useNavigate(); @@ -195,8 +187,6 @@ export function RoomViewHeader() { const avatarUrl = avatarMxc ? mx.mxcUrlToHttp(avatarMxc, 96, 96, 'crop') ?? undefined : undefined; const setPeopleDrawer = useSetSetting(settingsAtom, 'isPeopleDrawer'); - const location = useLocation(); - const currentPath = joinPathComponent(location); const handleSearchClick = () => { const searchParams: _SearchPathSearchParams = { @@ -336,11 +326,7 @@ export function RoomViewHeader() { escapeDeactivates: stopPropagation, }} > - setMenuAnchor(undefined)} - /> + setMenuAnchor(undefined)} /> } /> diff --git a/src/app/features/room/message/Message.tsx b/src/app/features/room/message/Message.tsx index 6db366ac4..d8b2b3e56 100644 --- a/src/app/features/room/message/Message.tsx +++ b/src/app/features/room/message/Message.tsx @@ -51,7 +51,7 @@ import { getMemberAvatarMxc, getMemberDisplayName, } from '../../../utils/room'; -import { getCanonicalAliasOrRoomId, getMxIdLocalPart } from '../../../utils/matrix'; +import { getCanonicalAliasOrRoomId, getMxIdLocalPart, isRoomAlias } from '../../../utils/matrix'; import { MessageLayout, MessageSpacing } from '../../../state/settings'; import { useMatrixClient } from '../../../hooks/useMatrixClient'; import { useRecentEmoji } from '../../../hooks/useRecentEmoji'; @@ -63,18 +63,10 @@ import { EmojiBoard } from '../../../components/emoji-board'; import { ReactionViewer } from '../reaction-viewer'; import { MessageEditor } from './MessageEditor'; import { UserAvatar } from '../../../components/user-avatar'; -import { useSpaceOptionally } from '../../../hooks/useSpace'; -import { useDirectSelected } from '../../../hooks/router/useDirectSelected'; -import { - getDirectRoomPath, - getHomeRoomPath, - getOriginBaseUrl, - getSpaceRoomPath, - withOriginBaseUrl, -} from '../../../pages/pathUtils'; import { copyToClipboard } from '../../../utils/dom'; -import { useClientConfig } from '../../../hooks/useClientConfig'; import { stopPropagation } from '../../../utils/keyboard'; +import { getMatrixToRoomEvent } from '../../../plugins/matrix-to'; +import { getViaServers } from '../../../plugins/via-servers'; export type ReactionHandler = (keyOrMxc: string, shortcode: string) => void; @@ -321,23 +313,13 @@ export const MessageCopyLinkItem = as< } >(({ room, mEvent, onClose, ...props }, ref) => { const mx = useMatrixClient(); - const { hashRouter } = useClientConfig(); - const space = useSpaceOptionally(); - const directSelected = useDirectSelected(); const handleCopy = () => { const roomIdOrAlias = getCanonicalAliasOrRoomId(mx, room.roomId); - let eventPath = getHomeRoomPath(roomIdOrAlias, mEvent.getId()); - if (space) { - eventPath = getSpaceRoomPath( - getCanonicalAliasOrRoomId(mx, space.roomId), - roomIdOrAlias, - mEvent.getId() - ); - } else if (directSelected) { - eventPath = getDirectRoomPath(roomIdOrAlias, mEvent.getId()); - } - copyToClipboard(withOriginBaseUrl(getOriginBaseUrl(hashRouter), eventPath)); + const eventId = mEvent.getId(); + const viaServers = isRoomAlias(roomIdOrAlias) ? undefined : getViaServers(room); + if (!eventId) return; + copyToClipboard(getMatrixToRoomEvent(roomIdOrAlias, eventId, viaServers)); onClose?.(); }; diff --git a/src/app/hooks/router/useSearchParamsViaServers.ts b/src/app/hooks/router/useSearchParamsViaServers.ts new file mode 100644 index 000000000..0b1b2db7d --- /dev/null +++ b/src/app/hooks/router/useSearchParamsViaServers.ts @@ -0,0 +1,14 @@ +import { useMemo } from 'react'; +import { useSearchParams } from 'react-router-dom'; +import { getRoomSearchParams } from '../../pages/pathSearchParam'; +import { decodeSearchParamValueArray } from '../../pages/pathUtils'; + +export const useSearchParamsViaServers = (): string[] | undefined => { + const [searchParams] = useSearchParams(); + const roomSearchParams = useMemo(() => getRoomSearchParams(searchParams), [searchParams]); + const viaServers = roomSearchParams.viaServers + ? decodeSearchParamValueArray(roomSearchParams.viaServers) + : undefined; + + return viaServers; +}; diff --git a/src/app/hooks/useMentionClickHandler.ts b/src/app/hooks/useMentionClickHandler.ts new file mode 100644 index 000000000..f8f4bf545 --- /dev/null +++ b/src/app/hooks/useMentionClickHandler.ts @@ -0,0 +1,43 @@ +import { ReactEventHandler, useCallback } from 'react'; +import { useNavigate } from 'react-router-dom'; +import { useRoomNavigate } from './useRoomNavigate'; +import { useMatrixClient } from './useMatrixClient'; +import { isRoomId, isUserId } from '../utils/matrix'; +import { openProfileViewer } from '../../client/action/navigation'; +import { getHomeRoomPath, withSearchParam } from '../pages/pathUtils'; +import { _RoomSearchParams } from '../pages/paths'; + +export const useMentionClickHandler = (roomId: string): ReactEventHandler => { + const mx = useMatrixClient(); + const { navigateRoom, navigateSpace } = useRoomNavigate(); + const navigate = useNavigate(); + + const handleClick: ReactEventHandler = useCallback( + (evt) => { + evt.preventDefault(); + const target = evt.currentTarget; + const mentionId = target.getAttribute('data-mention-id'); + if (typeof mentionId !== 'string') return; + + if (isUserId(mentionId)) { + openProfileViewer(mentionId, roomId); + return; + } + + const eventId = target.getAttribute('data-mention-event-id') || undefined; + if (isRoomId(mentionId) && mx.getRoom(mentionId)) { + if (mx.getRoom(mentionId)?.isSpaceRoom()) navigateSpace(mentionId); + else navigateRoom(mentionId, eventId); + return; + } + + const viaServers = target.getAttribute('data-mention-via') || undefined; + const path = getHomeRoomPath(mentionId, eventId); + + navigate(viaServers ? withSearchParam<_RoomSearchParams>(path, { viaServers }) : path); + }, + [mx, navigate, navigateRoom, navigateSpace, roomId] + ); + + return handleClick; +}; diff --git a/src/app/hooks/useRoomNavigate.ts b/src/app/hooks/useRoomNavigate.ts index 55528e7ee..0f9f365cd 100644 --- a/src/app/hooks/useRoomNavigate.ts +++ b/src/app/hooks/useRoomNavigate.ts @@ -1,5 +1,5 @@ import { useCallback } from 'react'; -import { useNavigate } from 'react-router-dom'; +import { NavigateOptions, useNavigate } from 'react-router-dom'; import { useAtomValue } from 'jotai'; import { getCanonicalAliasOrRoomId } from '../utils/matrix'; import { @@ -12,12 +12,14 @@ import { useMatrixClient } from './useMatrixClient'; import { getOrphanParents } from '../utils/room'; import { roomToParentsAtom } from '../state/room/roomToParents'; import { mDirectAtom } from '../state/mDirectList'; +import { useSelectedSpace } from './router/useSelectedSpace'; export const useRoomNavigate = () => { const navigate = useNavigate(); const mx = useMatrixClient(); const roomToParents = useAtomValue(roomToParentsAtom); const mDirects = useAtomValue(mDirectAtom); + const spaceSelectedId = useSelectedSpace(); const navigateSpace = useCallback( (roomId: string) => { @@ -28,24 +30,29 @@ export const useRoomNavigate = () => { ); const navigateRoom = useCallback( - (roomId: string, eventId?: string) => { + (roomId: string, eventId?: string, opts?: NavigateOptions) => { const roomIdOrAlias = getCanonicalAliasOrRoomId(mx, roomId); const orphanParents = getOrphanParents(roomToParents, roomId); if (orphanParents.length > 0) { - const pSpaceIdOrAlias = getCanonicalAliasOrRoomId(mx, orphanParents[0]); - navigate(getSpaceRoomPath(pSpaceIdOrAlias, roomIdOrAlias, eventId)); + const pSpaceIdOrAlias = getCanonicalAliasOrRoomId( + mx, + spaceSelectedId && orphanParents.includes(spaceSelectedId) + ? spaceSelectedId + : orphanParents[0] + ); + navigate(getSpaceRoomPath(pSpaceIdOrAlias, roomIdOrAlias, eventId), opts); return; } if (mDirects.has(roomId)) { - navigate(getDirectRoomPath(roomIdOrAlias, eventId)); + navigate(getDirectRoomPath(roomIdOrAlias, eventId), opts); return; } - navigate(getHomeRoomPath(roomIdOrAlias, eventId)); + navigate(getHomeRoomPath(roomIdOrAlias, eventId), opts); }, - [mx, navigate, roomToParents, mDirects] + [mx, navigate, spaceSelectedId, roomToParents, mDirects] ); return { diff --git a/src/app/hooks/useSpoilerClickHandler.ts b/src/app/hooks/useSpoilerClickHandler.ts new file mode 100644 index 000000000..b21011880 --- /dev/null +++ b/src/app/hooks/useSpoilerClickHandler.ts @@ -0,0 +1,14 @@ +import { ReactEventHandler, useCallback } from 'react'; + +export const useSpoilerClickHandler = (): ReactEventHandler => { + const handleClick: ReactEventHandler = useCallback((evt) => { + const target = evt.currentTarget; + if (target.getAttribute('aria-pressed') === 'true') { + evt.stopPropagation(); + target.setAttribute('aria-pressed', 'false'); + target.style.cursor = 'initial'; + } + }, []); + + return handleClick; +}; diff --git a/src/app/molecules/space-add-existing/SpaceAddExisting.jsx b/src/app/molecules/space-add-existing/SpaceAddExisting.jsx index ff338f3f8..83b967bcb 100644 --- a/src/app/molecules/space-add-existing/SpaceAddExisting.jsx +++ b/src/app/molecules/space-add-existing/SpaceAddExisting.jsx @@ -5,7 +5,7 @@ import './SpaceAddExisting.scss'; import cons from '../../../client/state/cons'; import navigation from '../../../client/state/navigation'; -import { joinRuleToIconSrc, getIdServer, genRoomVia } from '../../../util/matrixUtil'; +import { joinRuleToIconSrc, getIdServer } from '../../../util/matrixUtil'; import { Debounce } from '../../../util/common'; import Text from '../../atoms/text/Text'; @@ -27,6 +27,7 @@ import { useDirects, useRooms, useSpaces } from '../../state/hooks/roomList'; import { allRoomsAtom } from '../../state/room-list/roomList'; import { mDirectAtom } from '../../state/mDirectList'; import { useMatrixClient } from '../../hooks/useMatrixClient'; +import { getViaServers } from '../../plugins/via-servers'; function SpaceAddExistingContent({ roomId, spaces: onlySpaces }) { const mountStore = useStore(roomId); @@ -69,7 +70,7 @@ function SpaceAddExistingContent({ roomId, spaces: onlySpaces }) { const promises = selected.map((rId) => { const room = mx.getRoom(rId); - const via = genRoomVia(room); + const via = getViaServers(room); if (via.length === 0) { via.push(getIdServer(rId)); } diff --git a/src/app/pages/Router.tsx b/src/app/pages/Router.tsx index 7d0f4fdeb..88fa99325 100644 --- a/src/app/pages/Router.tsx +++ b/src/app/pages/Router.tsx @@ -41,7 +41,7 @@ import { } from './pathUtils'; import { ClientBindAtoms, ClientLayout, ClientRoot } from './client'; import { Home, HomeRouteRoomProvider, HomeSearch } from './client/home'; -import { Direct, DirectRouteRoomProvider } from './client/direct'; +import { Direct, DirectCreate, DirectRouteRoomProvider } from './client/direct'; import { RouteSpaceProvider, Space, SpaceRouteRoomProvider, SpaceSearch } from './client/space'; import { Explore, FeaturedRooms, PublicRooms } from './client/explore'; import { Notifications, Inbox, Invites } from './client/inbox'; @@ -160,7 +160,7 @@ export const createRouter = (clientConfig: ClientConfig, screenSize: ScreenSize) } > {mobile ? null : } />} - create

      } /> + } /> { + if (userId) { + const room = getDMRoomFor(mx, userId); + const { roomId } = room ?? {}; + if (roomId && directs.includes(roomId)) { + navigate(getDirectRoomPath(roomId), { replace: true }); + } else { + openInviteUser(undefined, userId); + } + } else { + navigate(getDirectPath(), { replace: true }); + } + }, [mx, navigate, directs, userId]); + + return ; +} diff --git a/src/app/pages/client/direct/RoomProvider.tsx b/src/app/pages/client/direct/RoomProvider.tsx index c78a8f44e..ca45aa19c 100644 --- a/src/app/pages/client/direct/RoomProvider.tsx +++ b/src/app/pages/client/direct/RoomProvider.tsx @@ -10,12 +10,12 @@ export function DirectRouteRoomProvider({ children }: { children: ReactNode }) { const mx = useMatrixClient(); const rooms = useDirectRooms(); - const { roomIdOrAlias } = useParams(); + const { roomIdOrAlias, eventId } = useParams(); const roomId = useSelectedRoom(); const room = mx.getRoom(roomId); if (!room || !rooms.includes(room.roomId)) { - return ; + return ; } return ( diff --git a/src/app/pages/client/direct/index.ts b/src/app/pages/client/direct/index.ts index 36f44d63e..d247bbc03 100644 --- a/src/app/pages/client/direct/index.ts +++ b/src/app/pages/client/direct/index.ts @@ -1,2 +1,3 @@ export * from './Direct'; export * from './RoomProvider'; +export * from './DirectCreate'; diff --git a/src/app/pages/client/home/RoomProvider.tsx b/src/app/pages/client/home/RoomProvider.tsx index 282cee7dd..aa14d1531 100644 --- a/src/app/pages/client/home/RoomProvider.tsx +++ b/src/app/pages/client/home/RoomProvider.tsx @@ -5,17 +5,25 @@ import { RoomProvider } from '../../../hooks/useRoom'; import { useMatrixClient } from '../../../hooks/useMatrixClient'; import { JoinBeforeNavigate } from '../../../features/join-before-navigate'; import { useHomeRooms } from './useHomeRooms'; +import { useSearchParamsViaServers } from '../../../hooks/router/useSearchParamsViaServers'; export function HomeRouteRoomProvider({ children }: { children: ReactNode }) { const mx = useMatrixClient(); const rooms = useHomeRooms(); - const { roomIdOrAlias } = useParams(); + const { roomIdOrAlias, eventId } = useParams(); + const viaServers = useSearchParamsViaServers(); const roomId = useSelectedRoom(); const room = mx.getRoom(roomId); if (!room || !rooms.includes(room.roomId)) { - return ; + return ( + + ); } return ( diff --git a/src/app/pages/client/inbox/Notifications.tsx b/src/app/pages/client/inbox/Notifications.tsx index a01ecb8e0..3425b5194 100644 --- a/src/app/pages/client/inbox/Notifications.tsx +++ b/src/app/pages/client/inbox/Notifications.tsx @@ -24,9 +24,10 @@ import { } from 'matrix-js-sdk'; import { useVirtualizer } from '@tanstack/react-virtual'; import { HTMLReactParserOptions } from 'html-react-parser'; +import { Opts as LinkifyOpts } from 'linkifyjs'; import { Page, PageContent, PageContentCenter, PageHeader } from '../../../components/page'; import { useMatrixClient } from '../../../hooks/useMatrixClient'; -import { getMxIdLocalPart, isRoomId, isUserId } from '../../../utils/matrix'; +import { getMxIdLocalPart } from '../../../utils/matrix'; import { InboxNotificationsPathSearchParams } from '../../paths'; import { AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback'; import { SequenceCard } from '../../../components/sequence-card'; @@ -52,8 +53,13 @@ import { Username, } from '../../../components/message'; import colorMXID from '../../../../util/colorMXID'; -import { getReactCustomHtmlParser } from '../../../plugins/react-custom-html-parser'; -import { openJoinAlias, openProfileViewer } from '../../../../client/action/navigation'; +import { + factoryRenderLinkifyWithMention, + getReactCustomHtmlParser, + LINKIFY_OPTS, + makeMentionCustomProps, + renderMatrixMention, +} from '../../../plugins/react-custom-html-parser'; import { RenderMessageContent } from '../../../components/RenderMessageContent'; import { useSetting } from '../../../state/hooks/settings'; import { settingsAtom } from '../../../state/settings'; @@ -70,6 +76,8 @@ import { ContainerColor } from '../../../styles/ContainerColor.css'; import { VirtualTile } from '../../../components/virtualizer'; import { UserAvatar } from '../../../components/user-avatar'; import { EncryptedContent } from '../../../features/room/message'; +import { useMentionClickHandler } from '../../../hooks/useMentionClickHandler'; +import { useSpoilerClickHandler } from '../../../hooks/useSpoilerClickHandler'; type RoomNotificationsGroup = { roomId: string; @@ -181,36 +189,26 @@ function RoomNotificationsGroupComp({ }: RoomNotificationsGroupProps) { const mx = useMatrixClient(); const unread = useRoomUnread(room.roomId, roomToUnreadAtom); - const { navigateRoom, navigateSpace } = useRoomNavigate(); + const mentionClickHandler = useMentionClickHandler(room.roomId); + const spoilerClickHandler = useSpoilerClickHandler(); + const linkifyOpts = useMemo( + () => ({ + ...LINKIFY_OPTS, + render: factoryRenderLinkifyWithMention((href) => + renderMatrixMention(mx, room.roomId, href, makeMentionCustomProps(mentionClickHandler)) + ), + }), + [mx, room, mentionClickHandler] + ); const htmlReactParserOptions = useMemo( () => - getReactCustomHtmlParser(mx, room, { - handleSpoilerClick: (evt) => { - const target = evt.currentTarget; - if (target.getAttribute('aria-pressed') === 'true') { - evt.stopPropagation(); - target.setAttribute('aria-pressed', 'false'); - target.style.cursor = 'initial'; - } - }, - handleMentionClick: (evt) => { - const target = evt.currentTarget; - const mentionId = target.getAttribute('data-mention-id'); - if (typeof mentionId !== 'string') return; - if (isUserId(mentionId)) { - openProfileViewer(mentionId, room.roomId); - return; - } - if (isRoomId(mentionId) && mx.getRoom(mentionId)) { - if (mx.getRoom(mentionId)?.isSpaceRoom()) navigateSpace(mentionId); - else navigateRoom(mentionId); - return; - } - openJoinAlias(mentionId); - }, + getReactCustomHtmlParser(mx, room.roomId, { + linkifyOpts, + handleSpoilerClick: spoilerClickHandler, + handleMentionClick: mentionClickHandler, }), - [mx, room, navigateRoom, navigateSpace] + [mx, room, linkifyOpts, mentionClickHandler, spoilerClickHandler] ); const renderMatrixEvent = useMatrixEventRenderer<[IRoomEvent, string, GetContentCallback]>( @@ -229,6 +227,7 @@ function RoomNotificationsGroupComp({ mediaAutoLoad={mediaAutoLoad} urlPreview={urlPreview} htmlReactParserOptions={htmlReactParserOptions} + linkifyOpts={linkifyOpts} outlineAttachment /> ); @@ -287,6 +286,7 @@ function RoomNotificationsGroupComp({ mediaAutoLoad={mediaAutoLoad} urlPreview={urlPreview} htmlReactParserOptions={htmlReactParserOptions} + linkifyOpts={linkifyOpts} /> ); } diff --git a/src/app/pages/client/sidebar/SpaceTabs.tsx b/src/app/pages/client/sidebar/SpaceTabs.tsx index 7b3e61e78..f14976fbc 100644 --- a/src/app/pages/client/sidebar/SpaceTabs.tsx +++ b/src/app/pages/client/sidebar/SpaceTabs.tsx @@ -47,13 +47,7 @@ import { import { useMatrixClient } from '../../../hooks/useMatrixClient'; import { roomToParentsAtom } from '../../../state/room/roomToParents'; import { allRoomsAtom } from '../../../state/room-list/roomList'; -import { - getOriginBaseUrl, - getSpaceLobbyPath, - getSpacePath, - joinPathComponent, - withOriginBaseUrl, -} from '../../pathUtils'; +import { getSpaceLobbyPath, getSpacePath, joinPathComponent } from '../../pathUtils'; import { SidebarAvatar, SidebarItem, @@ -67,7 +61,7 @@ import { import { RoomUnreadProvider, RoomsUnreadProvider } from '../../../components/RoomUnreadProvider'; import { useSelectedSpace } from '../../../hooks/router/useSelectedSpace'; import { UnreadBadge } from '../../../components/unread-badge'; -import { getCanonicalAliasOrRoomId } from '../../../utils/matrix'; +import { getCanonicalAliasOrRoomId, isRoomAlias } from '../../../utils/matrix'; import { RoomAvatar } from '../../../components/room-avatar'; import { nameInitials, randomStr } from '../../../utils/common'; import { @@ -83,7 +77,6 @@ import { AccountDataEvent } from '../../../../types/matrix/accountData'; import { ScreenSize, useScreenSizeContext } from '../../../hooks/useScreenSize'; import { useNavToActivePathAtom } from '../../../state/hooks/navToActivePath'; import { useOpenedSidebarFolderAtom } from '../../../state/hooks/openedSidebarFolder'; -import { useClientConfig } from '../../../hooks/useClientConfig'; import { usePowerLevels, usePowerLevelsAPI } from '../../../hooks/usePowerLevels'; import { useRoomsUnread } from '../../../state/hooks/unread'; import { roomToUnreadAtom } from '../../../state/room/roomToUnread'; @@ -91,6 +84,8 @@ import { markAsRead } from '../../../../client/action/notifications'; import { copyToClipboard } from '../../../utils/dom'; import { openInviteUser, openSpaceSettings } from '../../../../client/action/navigation'; import { stopPropagation } from '../../../utils/keyboard'; +import { getMatrixToRoom } from '../../../plugins/matrix-to'; +import { getViaServers } from '../../../plugins/via-servers'; type SpaceMenuProps = { room: Room; @@ -100,7 +95,6 @@ type SpaceMenuProps = { const SpaceMenu = forwardRef( ({ room, requestClose, onUnpin }, ref) => { const mx = useMatrixClient(); - const { hashRouter } = useClientConfig(); const roomToParents = useAtomValue(roomToParentsAtom); const powerLevels = usePowerLevels(room); const { getPowerLevel, canDoAction } = usePowerLevelsAPI(powerLevels); @@ -124,8 +118,9 @@ const SpaceMenu = forwardRef( }; const handleCopyLink = () => { - const spacePath = getSpacePath(getCanonicalAliasOrRoomId(mx, room.roomId)); - copyToClipboard(withOriginBaseUrl(getOriginBaseUrl(hashRouter), spacePath)); + const roomIdOrAlias = getCanonicalAliasOrRoomId(mx, room.roomId); + const viaServers = isRoomAlias(roomIdOrAlias) ? undefined : getViaServers(room); + copyToClipboard(getMatrixToRoom(roomIdOrAlias, viaServers)); requestClose(); }; diff --git a/src/app/pages/client/space/RoomProvider.tsx b/src/app/pages/client/space/RoomProvider.tsx index 1105e220a..0f13f9336 100644 --- a/src/app/pages/client/space/RoomProvider.tsx +++ b/src/app/pages/client/space/RoomProvider.tsx @@ -9,6 +9,7 @@ import { useSpace } from '../../../hooks/useSpace'; import { getAllParents } from '../../../utils/room'; import { roomToParentsAtom } from '../../../state/room/roomToParents'; import { allRoomsAtom } from '../../../state/room-list/roomList'; +import { useSearchParamsViaServers } from '../../../hooks/router/useSearchParamsViaServers'; export function SpaceRouteRoomProvider({ children }: { children: ReactNode }) { const mx = useMatrixClient(); @@ -16,7 +17,8 @@ export function SpaceRouteRoomProvider({ children }: { children: ReactNode }) { const roomToParents = useAtomValue(roomToParentsAtom); const allRooms = useAtomValue(allRoomsAtom); - const { roomIdOrAlias } = useParams(); + const { roomIdOrAlias, eventId } = useParams(); + const viaServers = useSearchParamsViaServers(); const roomId = useSelectedRoom(); const room = mx.getRoom(roomId); @@ -26,7 +28,13 @@ export function SpaceRouteRoomProvider({ children }: { children: ReactNode }) { !allRooms.includes(room.roomId) || !getAllParents(roomToParents, room.roomId).has(space.roomId) ) { - return ; + return ( + + ); } return ( diff --git a/src/app/pages/client/space/Space.tsx b/src/app/pages/client/space/Space.tsx index e280c603e..d3dc0be7f 100644 --- a/src/app/pages/client/space/Space.tsx +++ b/src/app/pages/client/space/Space.tsx @@ -34,15 +34,8 @@ import { NavItemContent, NavLink, } from '../../../components/nav'; -import { - getOriginBaseUrl, - getSpaceLobbyPath, - getSpacePath, - getSpaceRoomPath, - getSpaceSearchPath, - withOriginBaseUrl, -} from '../../pathUtils'; -import { getCanonicalAliasOrRoomId } from '../../../utils/matrix'; +import { getSpaceLobbyPath, getSpaceRoomPath, getSpaceSearchPath } from '../../pathUtils'; +import { getCanonicalAliasOrRoomId, isRoomAlias } from '../../../utils/matrix'; import { useSelectedRoom } from '../../../hooks/router/useSelectedRoom'; import { useSpaceLobbySelected, @@ -69,11 +62,12 @@ import { useRoomsUnread } from '../../../state/hooks/unread'; import { UseStateProvider } from '../../../components/UseStateProvider'; import { LeaveSpacePrompt } from '../../../components/leave-space-prompt'; import { copyToClipboard } from '../../../utils/dom'; -import { useClientConfig } from '../../../hooks/useClientConfig'; import { useClosedNavCategoriesAtom } from '../../../state/hooks/closedNavCategories'; import { useStateEvent } from '../../../hooks/useStateEvent'; import { StateEvent } from '../../../../types/matrix/room'; import { stopPropagation } from '../../../utils/keyboard'; +import { getMatrixToRoom } from '../../../plugins/matrix-to'; +import { getViaServers } from '../../../plugins/via-servers'; type SpaceMenuProps = { room: Room; @@ -81,7 +75,6 @@ type SpaceMenuProps = { }; const SpaceMenu = forwardRef(({ room, requestClose }, ref) => { const mx = useMatrixClient(); - const { hashRouter } = useClientConfig(); const roomToParents = useAtomValue(roomToParentsAtom); const powerLevels = usePowerLevels(room); const { getPowerLevel, canDoAction } = usePowerLevelsAPI(powerLevels); @@ -100,8 +93,9 @@ const SpaceMenu = forwardRef(({ room, requestClo }; const handleCopyLink = () => { - const spacePath = getSpacePath(getCanonicalAliasOrRoomId(mx, room.roomId)); - copyToClipboard(withOriginBaseUrl(getOriginBaseUrl(hashRouter), spacePath)); + const roomIdOrAlias = getCanonicalAliasOrRoomId(mx, room.roomId); + const viaServers = isRoomAlias(roomIdOrAlias) ? undefined : getViaServers(room); + copyToClipboard(getMatrixToRoom(roomIdOrAlias, viaServers)); requestClose(); }; diff --git a/src/app/pages/client/space/SpaceProvider.tsx b/src/app/pages/client/space/SpaceProvider.tsx index 530fc3cca..2e0f79a22 100644 --- a/src/app/pages/client/space/SpaceProvider.tsx +++ b/src/app/pages/client/space/SpaceProvider.tsx @@ -6,6 +6,7 @@ import { allRoomsAtom } from '../../../state/room-list/roomList'; import { useSelectedSpace } from '../../../hooks/router/useSelectedSpace'; import { SpaceProvider } from '../../../hooks/useSpace'; import { JoinBeforeNavigate } from '../../../features/join-before-navigate'; +import { useSearchParamsViaServers } from '../../../hooks/router/useSearchParamsViaServers'; type RouteSpaceProviderProps = { children: ReactNode; @@ -13,13 +14,15 @@ type RouteSpaceProviderProps = { export function RouteSpaceProvider({ children }: RouteSpaceProviderProps) { const mx = useMatrixClient(); const joinedSpaces = useSpaces(mx, allRoomsAtom); + const { spaceIdOrAlias } = useParams(); + const viaServers = useSearchParamsViaServers(); const selectedSpaceId = useSelectedSpace(); const space = mx.getRoom(selectedSpaceId); if (!space || !joinedSpaces.includes(space.roomId)) { - return ; + return ; } return ( diff --git a/src/app/pages/pathSearchParam.ts b/src/app/pages/pathSearchParam.ts new file mode 100644 index 000000000..8e4c93e5e --- /dev/null +++ b/src/app/pages/pathSearchParam.ts @@ -0,0 +1,13 @@ +import { _RoomSearchParams, DirectCreateSearchParams } from './paths'; + +type SearchParamsGetter = (searchParams: URLSearchParams) => T; + +export const getRoomSearchParams: SearchParamsGetter<_RoomSearchParams> = (searchParams) => ({ + viaServers: searchParams.get('viaServers') ?? undefined, +}); + +export const getDirectCreateSearchParams: SearchParamsGetter = ( + searchParams +) => ({ + userId: searchParams.get('userId') ?? undefined, +}); diff --git a/src/app/pages/paths.ts b/src/app/pages/paths.ts index fd3266e93..57750383a 100644 --- a/src/app/pages/paths.ts +++ b/src/app/pages/paths.ts @@ -35,6 +35,11 @@ export type _SearchPathSearchParams = { senders?: string; }; export const _SEARCH_PATH = 'search/'; + +export type _RoomSearchParams = { + /* comma separated string of servers */ + viaServers?: string; +}; export const _ROOM_PATH = ':roomIdOrAlias/:eventId?/'; export const HOME_PATH = '/home/'; @@ -44,6 +49,9 @@ export const HOME_SEARCH_PATH = `/home/${_SEARCH_PATH}`; export const HOME_ROOM_PATH = `/home/${_ROOM_PATH}`; export const DIRECT_PATH = '/direct/'; +export type DirectCreateSearchParams = { + userId?: string; +}; export const DIRECT_CREATE_PATH = `/direct/${_CREATE_PATH}`; export const DIRECT_ROOM_PATH = `/direct/${_ROOM_PATH}`; diff --git a/src/app/plugins/matrix-to.ts b/src/app/plugins/matrix-to.ts new file mode 100644 index 000000000..c9df0a876 --- /dev/null +++ b/src/app/plugins/matrix-to.ts @@ -0,0 +1,84 @@ +const MATRIX_TO_BASE = 'https://matrix.to'; + +export const getMatrixToUser = (userId: string): string => `${MATRIX_TO_BASE}/#/${userId}`; + +const withViaServers = (fragment: string, viaServers: string[]): string => + `${fragment}?${viaServers.map((server) => `via=${server}`).join('&')}`; + +export const getMatrixToRoom = (roomIdOrAlias: string, viaServers?: string[]): string => { + let fragment = roomIdOrAlias; + + if (Array.isArray(viaServers) && viaServers.length > 0) { + fragment = withViaServers(fragment, viaServers); + } + + return `${MATRIX_TO_BASE}/#/${fragment}`; +}; + +export const getMatrixToRoomEvent = ( + roomIdOrAlias: string, + eventId: string, + viaServers?: string[] +): string => { + let fragment = `${roomIdOrAlias}/${eventId}`; + + if (Array.isArray(viaServers) && viaServers.length > 0) { + fragment = withViaServers(fragment, viaServers); + } + + return `${MATRIX_TO_BASE}/#/${fragment}`; +}; + +export type MatrixToRoom = { + roomIdOrAlias: string; + viaServers?: string[]; +}; + +export type MatrixToRoomEvent = MatrixToRoom & { + eventId: string; +}; + +const MATRIX_TO = /^https?:\/\/matrix\.to\S*$/; +export const testMatrixTo = (href: string): boolean => MATRIX_TO.test(href); + +const MATRIX_TO_USER = /^https?:\/\/matrix\.to\/#\/(@[^:\s]+:[^?/\s]+)\/?$/; +const MATRIX_TO_ROOM = /^https?:\/\/matrix\.to\/#\/([#!][^:\s]+:[^?/\s]+)\/?(\?[\S]*)?$/; +const MATRIX_TO_ROOM_EVENT = + /^https?:\/\/matrix\.to\/#\/([#!][^:\s]+:[^?/\s]+)\/(\$[^?/\s]+)\/?(\?[\S]*)?$/; + +export const parseMatrixToUser = (href: string): string | undefined => { + const match = href.match(MATRIX_TO_USER); + if (!match) return undefined; + const userId = match[1]; + return userId; +}; + +export const parseMatrixToRoom = (href: string): MatrixToRoom | undefined => { + const match = href.match(MATRIX_TO_ROOM); + if (!match) return undefined; + + const roomIdOrAlias = match[1]; + const viaSearchStr = match[2]; + const viaServers = new URLSearchParams(viaSearchStr).getAll('via'); + + return { + roomIdOrAlias, + viaServers: viaServers.length === 0 ? undefined : viaServers, + }; +}; + +export const parseMatrixToRoomEvent = (href: string): MatrixToRoomEvent | undefined => { + const match = href.match(MATRIX_TO_ROOM_EVENT); + if (!match) return undefined; + + const roomIdOrAlias = match[1]; + const eventId = match[2]; + const viaSearchStr = match[3]; + const viaServers = new URLSearchParams(viaSearchStr).getAll('via'); + + return { + roomIdOrAlias, + eventId, + viaServers: viaServers.length === 0 ? undefined : viaServers, + }; +}; diff --git a/src/app/plugins/react-custom-html-parser.tsx b/src/app/plugins/react-custom-html-parser.tsx index a8086687a..167043745 100644 --- a/src/app/plugins/react-custom-html-parser.tsx +++ b/src/app/plugins/react-custom-html-parser.tsx @@ -1,5 +1,5 @@ /* eslint-disable jsx-a11y/alt-text */ -import React, { ReactEventHandler, Suspense, lazy } from 'react'; +import React, { ComponentPropsWithoutRef, ReactEventHandler, Suspense, lazy } from 'react'; import { Element, Text as DOMText, @@ -7,18 +7,25 @@ import { attributesToProps, domToReact, } from 'html-react-parser'; -import { MatrixClient, Room } from 'matrix-js-sdk'; +import { MatrixClient } from 'matrix-js-sdk'; import classNames from 'classnames'; import { Scroll, Text } from 'folds'; -import { Opts as LinkifyOpts } from 'linkifyjs'; +import { IntermediateRepresentation, Opts as LinkifyOpts, OptFn } from 'linkifyjs'; import Linkify from 'linkify-react'; import { ErrorBoundary } from 'react-error-boundary'; import * as css from '../styles/CustomHtml.css'; -import { getMxIdLocalPart, getCanonicalAliasRoomId } from '../utils/matrix'; +import { getMxIdLocalPart, getCanonicalAliasRoomId, isRoomAlias } from '../utils/matrix'; import { getMemberDisplayName } from '../utils/room'; import { EMOJI_PATTERN, URL_NEG_LB } from '../utils/regex'; import { getHexcodeForEmoji, getShortcodeFor } from './emoji'; import { findAndReplace } from '../utils/findAndReplace'; +import { + parseMatrixToRoom, + parseMatrixToRoomEvent, + parseMatrixToUser, + testMatrixTo, +} from './matrix-to'; +import { onEnterOrSpace } from '../utils/keyboard'; const ReactPrism = lazy(() => import('./react-prism/ReactPrism')); @@ -35,6 +42,108 @@ export const LINKIFY_OPTS: LinkifyOpts = { ignoreTags: ['span'], }; +export const makeMentionCustomProps = ( + handleMentionClick?: ReactEventHandler +): ComponentPropsWithoutRef<'a'> => ({ + style: { cursor: 'pointer' }, + target: '_blank', + rel: 'noreferrer noopener', + role: 'link', + tabIndex: handleMentionClick ? 0 : -1, + onKeyDown: handleMentionClick ? onEnterOrSpace(handleMentionClick) : undefined, + onClick: handleMentionClick, +}); + +export const renderMatrixMention = ( + mx: MatrixClient, + currentRoomId: string | undefined, + href: string, + customProps: ComponentPropsWithoutRef<'a'> +) => { + const userId = parseMatrixToUser(href); + if (userId) { + const currentRoom = mx.getRoom(currentRoomId); + + return ( + + {`@${ + (currentRoom && getMemberDisplayName(currentRoom, userId)) ?? getMxIdLocalPart(userId) + }`} + + ); + } + + const matrixToRoom = parseMatrixToRoom(href); + if (matrixToRoom) { + const { roomIdOrAlias, viaServers } = matrixToRoom; + const mentionRoom = mx.getRoom( + isRoomAlias(roomIdOrAlias) ? getCanonicalAliasRoomId(mx, roomIdOrAlias) : roomIdOrAlias + ); + + return ( + + {mentionRoom ? `#${mentionRoom.name}` : roomIdOrAlias} + + ); + } + + const matrixToRoomEvent = parseMatrixToRoomEvent(href); + if (matrixToRoomEvent) { + const { roomIdOrAlias, eventId, viaServers } = matrixToRoomEvent; + const mentionRoom = mx.getRoom( + isRoomAlias(roomIdOrAlias) ? getCanonicalAliasRoomId(mx, roomIdOrAlias) : roomIdOrAlias + ); + + return ( + + Message: {mentionRoom ? `#${mentionRoom.name}` : roomIdOrAlias} + + ); + } + + return undefined; +}; + +export const factoryRenderLinkifyWithMention = ( + mentionRender: (href: string) => JSX.Element | undefined +): OptFn<(ir: IntermediateRepresentation) => any> => { + const render: OptFn<(ir: IntermediateRepresentation) => any> = ({ + tagName, + attributes, + content, + }) => { + if (tagName === 'a' && testMatrixTo(decodeURIComponent(attributes.href))) { + const mention = mentionRender(decodeURIComponent(attributes.href)); + if (mention) return mention; + } + + return {content}; + }; + return render; +}; + export const scaleSystemEmoji = (text: string): (string | JSX.Element)[] => findAndReplace( text, @@ -76,8 +185,9 @@ export const highlightText = ( export const getReactCustomHtmlParser = ( mx: MatrixClient, - room: Room, + roomId: string | undefined, params: { + linkifyOpts: LinkifyOpts; highlightRegex?: RegExp; handleSpoilerClick?: ReactEventHandler; handleMentionClick?: ReactEventHandler; @@ -215,54 +325,14 @@ export const getReactCustomHtmlParser = ( } } - if (name === 'a') { - const mention = decodeURIComponent(props.href).match( - /^https?:\/\/matrix.to\/#\/((@|#|!).+:[^?/]+)/ + if (name === 'a' && testMatrixTo(decodeURIComponent(props.href))) { + const mention = renderMatrixMention( + mx, + roomId, + decodeURIComponent(props.href), + makeMentionCustomProps(params.handleMentionClick) ); - if (mention) { - // convert mention link to pill - const mentionId = mention[1]; - const mentionPrefix = mention[2]; - if (mentionPrefix === '#' || mentionPrefix === '!') { - const mentionRoom = mx.getRoom( - mentionPrefix === '#' ? getCanonicalAliasRoomId(mx, mentionId) : mentionId - ); - - return ( - - {domToReact(children, opts)} - - ); - } - if (mentionPrefix === '@') - return ( - - {`@${getMemberDisplayName(room, mentionId) ?? getMxIdLocalPart(mentionId)}`} - - ); - } + if (mention) return mention; } if (name === 'span' && 'data-mx-spoiler' in props) { @@ -316,7 +386,7 @@ export const getReactCustomHtmlParser = ( } if (linkify) { - return {jsx}; + return {jsx}; } return jsx; } diff --git a/src/app/plugins/via-servers.ts b/src/app/plugins/via-servers.ts new file mode 100644 index 000000000..75470999f --- /dev/null +++ b/src/app/plugins/via-servers.ts @@ -0,0 +1,65 @@ +import { Room } from 'matrix-js-sdk'; +import { IPowerLevels } from '../hooks/usePowerLevels'; +import { getMxIdServer } from '../utils/matrix'; +import { StateEvent } from '../../types/matrix/room'; +import { getStateEvent } from '../utils/room'; + +export const getViaServers = (room: Room): string[] => { + const getHighestPowerUserId = (): string | undefined => { + const powerLevels = getStateEvent(room, StateEvent.RoomPowerLevels)?.getContent(); + + if (!powerLevels) return undefined; + const userIdToPower = powerLevels.users; + if (!userIdToPower) return undefined; + let powerUserId: string | undefined; + + Object.keys(userIdToPower).forEach((userId) => { + if (userIdToPower[userId] <= (powerLevels.users_default ?? 0)) return; + + if (!powerUserId) { + powerUserId = userId; + return; + } + if (userIdToPower[userId] > userIdToPower[powerUserId]) { + powerUserId = userId; + } + }); + return powerUserId; + }; + + const getServerToPopulation = (): Record => { + const members = room.getMembers(); + const serverToPop: Record = {}; + + members?.forEach((member) => { + const { userId } = member; + const server = getMxIdServer(userId); + if (!server) return; + const serverPop = serverToPop[server]; + if (serverPop === undefined) { + serverToPop[server] = 1; + return; + } + serverToPop[server] = serverPop + 1; + }); + + return serverToPop; + }; + + const via: string[] = []; + const userId = getHighestPowerUserId(); + if (userId) { + const server = getMxIdServer(userId); + if (server) via.push(server); + } + const serverToPop = getServerToPopulation(); + const sortedServers = Object.keys(serverToPop).sort( + (svrA, svrB) => serverToPop[svrB] - serverToPop[svrA] + ); + const mostPop3 = sortedServers.slice(0, 3); + if (via.length === 0) return mostPop3; + if (mostPop3.includes(via[0])) { + mostPop3.splice(mostPop3.indexOf(via[0]), 1); + } + return via.concat(mostPop3.slice(0, 2)); +}; diff --git a/src/app/utils/keyboard.ts b/src/app/utils/keyboard.ts index da3fe8cb5..46a951ffc 100644 --- a/src/app/utils/keyboard.ts +++ b/src/app/utils/keyboard.ts @@ -24,12 +24,14 @@ export const preventScrollWithArrowKey: KeyboardEventHandler = (evt) => { } }; -export const onEnterOrSpace = (callback: () => void) => (evt: KeyboardEventLike) => { - if (isKeyHotkey('enter', evt) || isKeyHotkey('space', evt)) { - evt.preventDefault(); - callback(); - } -}; +export const onEnterOrSpace = + (callback: (evt: T) => void) => + (evt: KeyboardEventLike) => { + if (isKeyHotkey('enter', evt) || isKeyHotkey('space', evt)) { + evt.preventDefault(); + callback(evt as T); + } + }; export const stopPropagation = (evt: KeyboardEvent): boolean => { evt.stopPropagation(); diff --git a/src/app/utils/matrix.ts b/src/app/utils/matrix.ts index 278bb46b6..f837ed459 100644 --- a/src/app/utils/matrix.ts +++ b/src/app/utils/matrix.ts @@ -32,15 +32,6 @@ export const isRoomId = (id: string): boolean => validMxId(id) && id.startsWith( export const isRoomAlias = (id: string): boolean => validMxId(id) && id.startsWith('#'); -export const parseMatrixToUrl = (url: string): [string | undefined, string | undefined] => { - const href = decodeURIComponent(url); - - const match = href.match(/^https?:\/\/matrix.to\/#\/([@!$+#]\S+:[^\\?|^\s|^\\/]+)(\?(via=\S+))?/); - if (!match) return [undefined, undefined]; - const [, g1AsMxId, , g3AsVia] = match; - return [g1AsMxId, g3AsVia]; -}; - export const getCanonicalAliasRoomId = (mx: MatrixClient, alias: string): string | undefined => mx.getRooms()?.find((room) => room.getCanonicalAlias() === alias)?.roomId; diff --git a/src/util/matrixUtil.js b/src/util/matrixUtil.js index e4fd40c39..9f1d94212 100644 --- a/src/util/matrixUtil.js +++ b/src/util/matrixUtil.js @@ -95,67 +95,11 @@ export function joinRuleToIconSrc(joinRule, isSpace) { }[joinRule]?.() || null); } -// NOTE: it gives userId with minimum power level 50; -function getHighestPowerUserId(room) { - const userIdToPower = room.currentState.getStateEvents('m.room.power_levels', '')?.getContent().users; - let powerUserId = null; - if (!userIdToPower) return powerUserId; - - Object.keys(userIdToPower).forEach((userId) => { - if (userIdToPower[userId] < 50) return; - if (powerUserId === null) { - powerUserId = userId; - return; - } - if (userIdToPower[userId] > userIdToPower[powerUserId]) { - powerUserId = userId; - } - }); - return powerUserId; -} - export function getIdServer(userId) { const idParts = userId.split(':'); return idParts[1]; } -export function getServerToPopulation(room) { - const members = room.getMembers(); - const serverToPop = {}; - - members?.forEach((member) => { - const { userId } = member; - const server = getIdServer(userId); - const serverPop = serverToPop[server]; - if (serverPop === undefined) { - serverToPop[server] = 1; - return; - } - serverToPop[server] = serverPop + 1; - }); - - return serverToPop; -} - -export function genRoomVia(room) { - const via = []; - const userId = getHighestPowerUserId(room); - if (userId) { - const server = getIdServer(userId); - if (server) via.push(server); - } - const serverToPop = getServerToPopulation(room); - const sortedServers = Object.keys(serverToPop).sort( - (svrA, svrB) => serverToPop[svrB] - serverToPop[svrA], - ); - const mostPop3 = sortedServers.slice(0, 3); - if (via.length === 0) return mostPop3; - if (mostPop3.includes(via[0])) { - mostPop3.splice(mostPop3.indexOf(via[0]), 1); - } - return via.concat(mostPop3.slice(0, 2)); -} - export function isCrossVerified(mx, deviceId) { try { const crossSignInfo = mx.getStoredCrossSigningForUser(mx.getUserId()); From e54bb2e42377c49e7179f6b59669592186281eff Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Tue, 30 Jul 2024 17:49:51 +0530 Subject: [PATCH 1184/1531] fix tombstone replacement room open previous room (#1856) --- src/app/utils/matrix.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/app/utils/matrix.ts b/src/app/utils/matrix.ts index f837ed459..8613f36ab 100644 --- a/src/app/utils/matrix.ts +++ b/src/app/utils/matrix.ts @@ -33,7 +33,13 @@ export const isRoomId = (id: string): boolean => validMxId(id) && id.startsWith( export const isRoomAlias = (id: string): boolean => validMxId(id) && id.startsWith('#'); export const getCanonicalAliasRoomId = (mx: MatrixClient, alias: string): string | undefined => - mx.getRooms()?.find((room) => room.getCanonicalAlias() === alias)?.roomId; + mx + .getRooms() + ?.find( + (room) => + room.getCanonicalAlias() === alias && + getStateEvent(room, StateEvent.RoomTombstone) === undefined + )?.roomId; export const getCanonicalAliasOrRoomId = (mx: MatrixClient, roomId: string): string => { const room = mx.getRoom(roomId); From a8f5a6c2f4eef681cd3d271b3d072ba8912fa8e0 Mon Sep 17 00:00:00 2001 From: Krishan <33421343+kfiven@users.noreply.github.com> Date: Thu, 1 Aug 2024 23:42:45 +1000 Subject: [PATCH 1185/1531] update self deploy instructions after react router (#1859) * update self deploy instructions after react router * List the alternative * docs to deploy on subdir --- README.md | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 5b54f7aed..79e8ccc93 100644 --- a/README.md +++ b/README.md @@ -19,22 +19,24 @@ A Matrix client focusing primarily on simple, elegant and secure interface. The ## Getting started -Web app is available at https://app.cinny.in and gets updated on each new release. The `dev` branch is continuously deployed at https://dev.cinny.in but keep in mind that it could have things broken. +* Web app is available at https://app.cinny.in and gets updated on each new release. The `dev` branch is continuously deployed at https://dev.cinny.in but keep in mind that it could have things broken. -You can also download our desktop app from [cinny-desktop repository](https://github.com/cinnyapp/cinny-desktop). +* You can also download our desktop app from [cinny-desktop repository](https://github.com/cinnyapp/cinny-desktop). -To host Cinny on your own, download tarball of the app from [GitHub release](https://github.com/cinnyapp/cinny/releases/latest). +* To host Cinny on your own, download tarball of the app from [GitHub release](https://github.com/cinnyapp/cinny/releases/latest). You can serve the application with a webserver of your choice by simply copying `dist/` directory to the webroot. -To set default Homeserver on login and register page, place a customized [`config.json`](config.json) in webroot of your choice. +To set default Homeserver on login, register and Explore Community page, place a customized [`config.json`](config.json) in webroot of your choice. +You will also need to setup redirects to serve the assests. An example setting of redirects for netlify is done in [`netlify.toml`](netlify.toml). You can also set `hashRouter.enabled = true` in [`config.json`](config.json) if you have trouble setting redirects. +To deploy on subdirectory, you need to rebuild the app youself after updating the `base` path in [`build.confg.ts`](build.confg.ts). For example, if you want to deploy on `https://cinny.in/app`, then change `base: '/app'`. -Alternatively you can just pull the [DockerHub image](https://hub.docker.com/r/ajbura/cinny) by: -``` -docker pull ajbura/cinny -``` -or [ghcr image](https://github.com/cinnyapp/cinny/pkgs/container/cinny) by: -``` -docker pull ghcr.io/cinnyapp/cinny:latest -``` +* Alternatively you can just pull the [DockerHub image](https://hub.docker.com/r/ajbura/cinny) by: + ``` + docker pull ajbura/cinny + ``` + or [ghcr image](https://github.com/cinnyapp/cinny/pkgs/container/cinny) by: + ``` + docker pull ghcr.io/cinnyapp/cinny:latest + ```
      PGP Public Key to verify tarball From c62050445bb1f5ceb790871353c46d231322d037 Mon Sep 17 00:00:00 2001 From: Krishan <33421343+kfiven@users.noreply.github.com> Date: Thu, 1 Aug 2024 23:45:22 +1000 Subject: [PATCH 1186/1531] Fix typo in readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 79e8ccc93..5cee6fa2e 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ A Matrix client focusing primarily on simple, elegant and secure interface. The You can serve the application with a webserver of your choice by simply copying `dist/` directory to the webroot. To set default Homeserver on login, register and Explore Community page, place a customized [`config.json`](config.json) in webroot of your choice. You will also need to setup redirects to serve the assests. An example setting of redirects for netlify is done in [`netlify.toml`](netlify.toml). You can also set `hashRouter.enabled = true` in [`config.json`](config.json) if you have trouble setting redirects. -To deploy on subdirectory, you need to rebuild the app youself after updating the `base` path in [`build.confg.ts`](build.confg.ts). For example, if you want to deploy on `https://cinny.in/app`, then change `base: '/app'`. +To deploy on subdirectory, you need to rebuild the app youself after updating the `base` path in [`build.config.ts`](build.config.ts). For example, if you want to deploy on `https://cinny.in/app`, then change `base: '/app'`. * Alternatively you can just pull the [DockerHub image](https://hub.docker.com/r/ajbura/cinny) by: ``` From 9cb5c70d5174332eb306b3792a97f9ee7c126ace Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Sat, 3 Aug 2024 19:17:53 +0530 Subject: [PATCH 1187/1531] add back btn for mobile view (#1861) --- src/app/components/BackRouteHandler.tsx | 86 +++++++++++++++ src/app/components/page/Page.tsx | 20 ++-- src/app/components/page/style.css.ts | 19 +++- .../JoinBeforeNavigate.tsx | 28 +++-- src/app/features/lobby/LobbyHeader.tsx | 101 ++++++++++++------ src/app/features/room/RoomViewHeader.tsx | 40 +++++-- src/app/pages/client/explore/Featured.tsx | 19 +++- src/app/pages/client/explore/Server.tsx | 36 +++++-- src/app/pages/client/home/Search.tsx | 31 ++++-- src/app/pages/client/inbox/Invites.tsx | 30 ++++-- src/app/pages/client/inbox/Notifications.tsx | 29 +++-- src/app/pages/client/space/Search.tsx | 31 ++++-- 12 files changed, 370 insertions(+), 100 deletions(-) create mode 100644 src/app/components/BackRouteHandler.tsx diff --git a/src/app/components/BackRouteHandler.tsx b/src/app/components/BackRouteHandler.tsx new file mode 100644 index 000000000..fa3d75929 --- /dev/null +++ b/src/app/components/BackRouteHandler.tsx @@ -0,0 +1,86 @@ +import { ReactNode, useCallback } from 'react'; +import { matchPath, useLocation, useNavigate } from 'react-router-dom'; +import { + getDirectPath, + getExplorePath, + getHomePath, + getInboxPath, + getSpacePath, +} from '../pages/pathUtils'; +import { DIRECT_PATH, EXPLORE_PATH, HOME_PATH, INBOX_PATH, SPACE_PATH } from '../pages/paths'; + +type BackRouteHandlerProps = { + children: (onBack: () => void) => ReactNode; +}; +export function BackRouteHandler({ children }: BackRouteHandlerProps) { + const navigate = useNavigate(); + const location = useLocation(); + + const goBack = useCallback(() => { + if ( + matchPath( + { + path: HOME_PATH, + caseSensitive: true, + end: false, + }, + location.pathname + ) + ) { + navigate(getHomePath()); + return; + } + if ( + matchPath( + { + path: DIRECT_PATH, + caseSensitive: true, + end: false, + }, + location.pathname + ) + ) { + navigate(getDirectPath()); + return; + } + const spaceMatch = matchPath( + { + path: SPACE_PATH, + caseSensitive: true, + end: false, + }, + location.pathname + ); + if (spaceMatch?.params.spaceIdOrAlias) { + navigate(getSpacePath(spaceMatch.params.spaceIdOrAlias)); + return; + } + if ( + matchPath( + { + path: EXPLORE_PATH, + caseSensitive: true, + end: false, + }, + location.pathname + ) + ) { + navigate(getExplorePath()); + return; + } + if ( + matchPath( + { + path: INBOX_PATH, + caseSensitive: true, + end: false, + }, + location.pathname + ) + ) { + navigate(getInboxPath()); + } + }, [navigate, location]); + + return children(goBack); +} diff --git a/src/app/components/page/Page.tsx b/src/app/components/page/Page.tsx index 4ccb1ec0d..a8b9ea044 100644 --- a/src/app/components/page/Page.tsx +++ b/src/app/components/page/Page.tsx @@ -87,15 +87,17 @@ export const Page = as<'div'>(({ className, ...props }, ref) => ( /> )); -export const PageHeader = as<'div'>(({ className, ...props }, ref) => ( -
      -)); +export const PageHeader = as<'div', css.PageHeaderVariants>( + ({ className, balance, ...props }, ref) => ( +
      + ) +); export const PageContent = as<'div'>(({ className, ...props }, ref) => (
      diff --git a/src/app/components/page/style.css.ts b/src/app/components/page/style.css.ts index 4807a2271..23f2da494 100644 --- a/src/app/components/page/style.css.ts +++ b/src/app/components/page/style.css.ts @@ -1,4 +1,5 @@ import { style } from '@vanilla-extract/css'; +import { recipe, RecipeVariants } from '@vanilla-extract/recipes'; import { DefaultReset, color, config, toRem } from 'folds'; export const PageNav = style({ @@ -33,11 +34,21 @@ export const PageNavContent = style({ paddingBottom: config.space.S700, }); -export const PageHeader = style({ - paddingLeft: config.space.S400, - paddingRight: config.space.S200, - borderBottomWidth: config.borderWidth.B300, +export const PageHeader = recipe({ + base: { + paddingLeft: config.space.S400, + paddingRight: config.space.S200, + borderBottomWidth: config.borderWidth.B300, + }, + variants: { + balance: { + true: { + paddingLeft: config.space.S200, + }, + }, + }, }); +export type PageHeaderVariants = RecipeVariants; export const PageContent = style([ DefaultReset, diff --git a/src/app/features/join-before-navigate/JoinBeforeNavigate.tsx b/src/app/features/join-before-navigate/JoinBeforeNavigate.tsx index 1cec65992..028cd560e 100644 --- a/src/app/features/join-before-navigate/JoinBeforeNavigate.tsx +++ b/src/app/features/join-before-navigate/JoinBeforeNavigate.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { Box, Scroll, Text, toRem } from 'folds'; +import { Box, Icon, IconButton, Icons, Scroll, Text, toRem } from 'folds'; import { useAtomValue } from 'jotai'; import { RoomCard } from '../../components/room-card'; import { RoomTopicViewer } from '../../components/room-topic-viewer'; @@ -8,6 +8,8 @@ import { RoomSummaryLoader } from '../../components/RoomSummaryLoader'; import { useRoomNavigate } from '../../hooks/useRoomNavigate'; import { useMatrixClient } from '../../hooks/useMatrixClient'; import { allRoomsAtom } from '../../state/room-list/roomList'; +import { ScreenSize, useScreenSizeContext } from '../../hooks/useScreenSize'; +import { BackRouteHandler } from '../../components/BackRouteHandler'; type JoinBeforeNavigateProps = { roomIdOrAlias: string; eventId?: string; viaServers?: string[] }; export function JoinBeforeNavigate({ @@ -18,6 +20,7 @@ export function JoinBeforeNavigate({ const mx = useMatrixClient(); const allRooms = useAtomValue(allRoomsAtom); const { navigateRoom, navigateSpace } = useRoomNavigate(); + const screenSize = useScreenSizeContext(); const handleView = (roomId: string) => { if (mx.getRoom(roomId)?.isSpaceRoom()) { @@ -29,11 +32,24 @@ export function JoinBeforeNavigate({ return ( - - - - {roomIdOrAlias} - + + + + {screenSize === ScreenSize.Mobile && ( + + {(onBack) => ( + + + + )} + + )} + + + + {roomIdOrAlias} + + diff --git a/src/app/features/lobby/LobbyHeader.tsx b/src/app/features/lobby/LobbyHeader.tsx index e01d3ad50..fa415bd2c 100644 --- a/src/app/features/lobby/LobbyHeader.tsx +++ b/src/app/features/lobby/LobbyHeader.tsx @@ -31,6 +31,8 @@ import { IPowerLevels, usePowerLevelsAPI } from '../../hooks/usePowerLevels'; import { UseStateProvider } from '../../components/UseStateProvider'; import { LeaveSpacePrompt } from '../../components/leave-space-prompt'; import { stopPropagation } from '../../utils/keyboard'; +import { ScreenSize, useScreenSizeContext } from '../../hooks/useScreenSize'; +import { BackRouteHandler } from '../../components/BackRouteHandler'; type LobbyMenuProps = { roomId: string; @@ -123,6 +125,7 @@ export function LobbyHeader({ showProfile, powerLevels }: LobbyHeaderProps) { const space = useSpace(); const setPeopleDrawer = useSetSetting(settingsAtom, 'isPeopleDrawer'); const [menuAnchor, setMenuAnchor] = useState(); + const screenSize = useScreenSizeContext(); const name = useRoomName(space); const avatarMxc = useRoomAvatar(space); @@ -133,42 +136,72 @@ export function LobbyHeader({ showProfile, powerLevels }: LobbyHeaderProps) { }; return ( - + - - - {showProfile && ( - <> - - {nameInitials(name)}} - /> - - - {name} - - + {screenSize === ScreenSize.Mobile ? ( + <> + + + {(onBack) => ( + + + + )} + + + + {showProfile && ( + + {name} + + )} + + + ) : ( + <> + + + {showProfile && ( + <> + + {nameInitials(name)}} + /> + + + {name} + + + )} + + + )} + + {screenSize !== ScreenSize.Mobile && ( + + Members + + } + > + {(triggerRef) => ( + setPeopleDrawer((drawer) => !drawer)}> + + + )} + )} - - - - Members - - } - > - {(triggerRef) => ( - setPeopleDrawer((drawer) => !drawer)}> - - - )} - + + {screenSize === ScreenSize.Mobile && ( + + {(onBack) => ( + + + + + + )} + + )} - - ( - - )} - /> - + {screenSize !== ScreenSize.Mobile && ( + + ( + + )} + /> + + )} {name} diff --git a/src/app/pages/client/explore/Featured.tsx b/src/app/pages/client/explore/Featured.tsx index 4838127f5..f056cbb5c 100644 --- a/src/app/pages/client/explore/Featured.tsx +++ b/src/app/pages/client/explore/Featured.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { Box, Icon, Icons, Scroll, Text } from 'folds'; +import { Box, Icon, IconButton, Icons, Scroll, Text } from 'folds'; import { useAtomValue } from 'jotai'; import { useClientConfig } from '../../../hooks/useClientConfig'; import { RoomCard, RoomCardGrid } from '../../../components/room-card'; @@ -9,21 +9,38 @@ import { Page, PageContent, PageContentCenter, + PageHeader, PageHero, PageHeroSection, } from '../../../components/page'; import { RoomTopicViewer } from '../../../components/room-topic-viewer'; import * as css from './style.css'; import { useRoomNavigate } from '../../../hooks/useRoomNavigate'; +import { ScreenSize, useScreenSizeContext } from '../../../hooks/useScreenSize'; +import { BackRouteHandler } from '../../../components/BackRouteHandler'; export function FeaturedRooms() { const { featuredCommunities } = useClientConfig(); const { rooms, spaces } = featuredCommunities ?? {}; const allRooms = useAtomValue(allRoomsAtom); + const screenSize = useScreenSizeContext(); const { navigateSpace, navigateRoom } = useRoomNavigate(); return ( + {screenSize === ScreenSize.Mobile && ( + + + + {(onBack) => ( + + + + )} + + + + )} diff --git a/src/app/pages/client/explore/Server.tsx b/src/app/pages/client/explore/Server.tsx index 1a81c225f..1f493df17 100644 --- a/src/app/pages/client/explore/Server.tsx +++ b/src/app/pages/client/explore/Server.tsx @@ -13,6 +13,7 @@ import { Button, Chip, Icon, + IconButton, Icons, Input, Line, @@ -42,6 +43,8 @@ import { allRoomsAtom } from '../../../state/room-list/roomList'; import { useRoomNavigate } from '../../../hooks/useRoomNavigate'; import { getMxIdServer } from '../../../utils/matrix'; import { stopPropagation } from '../../../utils/keyboard'; +import { ScreenSize, useScreenSizeContext } from '../../../hooks/useScreenSize'; +import { BackRouteHandler } from '../../../components/BackRouteHandler'; const useServerSearchParams = (searchParams: URLSearchParams): ExploreServerPathSearchParams => useMemo( @@ -344,6 +347,7 @@ export function PublicRooms() { const userServer = userId && getMxIdServer(userId); const allRooms = useAtomValue(allRoomsAtom); const { navigateSpace, navigateRoom } = useRoomNavigate(); + const screenSize = useScreenSizeContext(); const [searchParams] = useSearchParams(); const serverSearchParams = useServerSearchParams(searchParams); @@ -466,7 +470,7 @@ export function PublicRooms() { return ( - + {isSearch ? ( <> @@ -482,20 +486,34 @@ export function PublicRooms() { - + {screenSize !== ScreenSize.Mobile && } Search - + ) : ( - - - - {server} - - + <> + + {screenSize === ScreenSize.Mobile && ( + + {(onBack) => ( + + + + )} + + )} + + + {screenSize !== ScreenSize.Mobile && } + + {server} + + + + )} diff --git a/src/app/pages/client/home/Search.tsx b/src/app/pages/client/home/Search.tsx index af7b1eb9a..d5ddfb778 100644 --- a/src/app/pages/client/home/Search.tsx +++ b/src/app/pages/client/home/Search.tsx @@ -1,21 +1,38 @@ import React, { useRef } from 'react'; -import { Box, Icon, Icons, Text, Scroll } from 'folds'; +import { Box, Icon, Icons, Text, Scroll, IconButton } from 'folds'; import { Page, PageContent, PageContentCenter, PageHeader } from '../../../components/page'; import { MessageSearch } from '../../../features/message-search'; import { useHomeRooms } from './useHomeRooms'; +import { ScreenSize, useScreenSizeContext } from '../../../hooks/useScreenSize'; +import { BackRouteHandler } from '../../../components/BackRouteHandler'; export function HomeSearch() { const scrollRef = useRef(null); const rooms = useHomeRooms(); + const screenSize = useScreenSizeContext(); return ( - - - - - Message Search - + + + + {screenSize === ScreenSize.Mobile && ( + + {(onBack) => ( + + + + )} + + )} + + + {screenSize !== ScreenSize.Mobile && } + + Message Search + + + diff --git a/src/app/pages/client/inbox/Invites.tsx b/src/app/pages/client/inbox/Invites.tsx index 06e5f6c6b..18993081b 100644 --- a/src/app/pages/client/inbox/Invites.tsx +++ b/src/app/pages/client/inbox/Invites.tsx @@ -4,6 +4,7 @@ import { Box, Button, Icon, + IconButton, Icons, Overlay, OverlayBackdrop, @@ -39,6 +40,8 @@ import { RoomTopicViewer } from '../../../components/room-topic-viewer'; import { AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback'; import { useRoomNavigate } from '../../../hooks/useRoomNavigate'; import { useRoomTopic } from '../../../hooks/useRoomMeta'; +import { ScreenSize, useScreenSizeContext } from '../../../hooks/useScreenSize'; +import { BackRouteHandler } from '../../../components/BackRouteHandler'; const COMPACT_CARD_WIDTH = 548; @@ -205,6 +208,7 @@ export function Invites() { useCallback(() => containerRef.current, []), useCallback((width) => setCompact(width <= COMPACT_CARD_WIDTH), []) ); + const screenSize = useScreenSizeContext(); const { navigateRoom, navigateSpace } = useRoomNavigate(); @@ -225,12 +229,26 @@ export function Invites() { return ( - - - - - Invitations - + + + + {screenSize === ScreenSize.Mobile && ( + + {(onBack) => ( + + + + )} + + )} + + + {screenSize !== ScreenSize.Mobile && } + + Invitations + + + diff --git a/src/app/pages/client/inbox/Notifications.tsx b/src/app/pages/client/inbox/Notifications.tsx index 3425b5194..6a8160d86 100644 --- a/src/app/pages/client/inbox/Notifications.tsx +++ b/src/app/pages/client/inbox/Notifications.tsx @@ -78,6 +78,8 @@ import { UserAvatar } from '../../../components/user-avatar'; import { EncryptedContent } from '../../../features/room/message'; import { useMentionClickHandler } from '../../../hooks/useMentionClickHandler'; import { useSpoilerClickHandler } from '../../../hooks/useSpoilerClickHandler'; +import { ScreenSize, useScreenSizeContext } from '../../../hooks/useScreenSize'; +import { BackRouteHandler } from '../../../components/BackRouteHandler'; type RoomNotificationsGroup = { roomId: string; @@ -484,6 +486,7 @@ export function Notifications() { const mx = useMatrixClient(); const [mediaAutoLoad] = useSetting(settingsAtom, 'mediaAutoLoad'); const [urlPreview] = useSetting(settingsAtom, 'urlPreview'); + const screenSize = useScreenSizeContext(); const { navigateRoom } = useRoomNavigate(); const [searchParams, setSearchParams] = useSearchParams(); @@ -549,12 +552,26 @@ export function Notifications() { return ( - - - - - Notification Messages - + + + + {screenSize === ScreenSize.Mobile && ( + + {(onBack) => ( + + + + )} + + )} + + + {screenSize !== ScreenSize.Mobile && } + + Notification Messages + + + diff --git a/src/app/pages/client/space/Search.tsx b/src/app/pages/client/space/Search.tsx index 6e7ac57d4..017262b5b 100644 --- a/src/app/pages/client/space/Search.tsx +++ b/src/app/pages/client/space/Search.tsx @@ -1,5 +1,5 @@ import React, { useRef } from 'react'; -import { Box, Icon, Icons, Text, Scroll } from 'folds'; +import { Box, Icon, Icons, Text, Scroll, IconButton } from 'folds'; import { useAtomValue } from 'jotai'; import { Page, PageContent, PageContentCenter, PageHeader } from '../../../components/page'; import { MessageSearch } from '../../../features/message-search'; @@ -9,11 +9,14 @@ import { allRoomsAtom } from '../../../state/room-list/roomList'; import { mDirectAtom } from '../../../state/mDirectList'; import { roomToParentsAtom } from '../../../state/room/roomToParents'; import { useMatrixClient } from '../../../hooks/useMatrixClient'; +import { ScreenSize, useScreenSizeContext } from '../../../hooks/useScreenSize'; +import { BackRouteHandler } from '../../../components/BackRouteHandler'; export function SpaceSearch() { const mx = useMatrixClient(); const scrollRef = useRef(null); const space = useSpace(); + const screenSize = useScreenSizeContext(); const mDirects = useAtomValue(mDirectAtom); const roomToParents = useAtomValue(roomToParentsAtom); @@ -25,12 +28,26 @@ export function SpaceSearch() { return ( - - - - - Message Search - + + + + {screenSize === ScreenSize.Mobile && ( + + {(onBack) => ( + + + + )} + + )} + + + {screenSize !== ScreenSize.Mobile && } + + Message Search + + + From 681287c46ae6aab6c3a3697a8a062acbebc519c9 Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Sun, 4 Aug 2024 09:49:37 +0530 Subject: [PATCH 1188/1531] show unverified tab indicator on sidebar (#1862) --- src/app/hooks/useDeviceList.js | 31 ----------- src/app/hooks/useDeviceList.ts | 35 +++++++++++++ src/app/pages/client/SidebarNav.tsx | 12 ++++- .../pages/client/sidebar/UnverifiedTab.css.ts | 24 +++++++++ .../pages/client/sidebar/UnverifiedTab.tsx | 51 +++++++++++++++++++ src/app/pages/client/sidebar/index.ts | 1 + src/util/matrixUtil.js | 2 +- 7 files changed, 123 insertions(+), 33 deletions(-) delete mode 100644 src/app/hooks/useDeviceList.js create mode 100644 src/app/hooks/useDeviceList.ts create mode 100644 src/app/pages/client/sidebar/UnverifiedTab.css.ts create mode 100644 src/app/pages/client/sidebar/UnverifiedTab.tsx diff --git a/src/app/hooks/useDeviceList.js b/src/app/hooks/useDeviceList.js deleted file mode 100644 index 7daaad1f3..000000000 --- a/src/app/hooks/useDeviceList.js +++ /dev/null @@ -1,31 +0,0 @@ -/* eslint-disable import/prefer-default-export */ -import { useState, useEffect } from 'react'; -import { useMatrixClient } from './useMatrixClient'; - -export function useDeviceList() { - const mx = useMatrixClient(); - const [deviceList, setDeviceList] = useState(null); - - useEffect(() => { - let isMounted = true; - - const updateDevices = () => mx.getDevices().then((data) => { - if (!isMounted) return; - setDeviceList(data.devices || []); - }); - updateDevices(); - - const handleDevicesUpdate = (users) => { - if (users.includes(mx.getUserId())) { - updateDevices(); - } - }; - - mx.on('crypto.devicesUpdated', handleDevicesUpdate); - return () => { - mx.removeListener('crypto.devicesUpdated', handleDevicesUpdate); - isMounted = false; - }; - }, [mx]); - return deviceList; -} diff --git a/src/app/hooks/useDeviceList.ts b/src/app/hooks/useDeviceList.ts new file mode 100644 index 000000000..daec7cbe6 --- /dev/null +++ b/src/app/hooks/useDeviceList.ts @@ -0,0 +1,35 @@ +/* eslint-disable import/prefer-default-export */ +import { useState, useEffect } from 'react'; +import { CryptoEvent, IMyDevice } from 'matrix-js-sdk'; +import { CryptoEventHandlerMap } from 'matrix-js-sdk/lib/crypto'; +import { useMatrixClient } from './useMatrixClient'; + +export function useDeviceList() { + const mx = useMatrixClient(); + const [deviceList, setDeviceList] = useState(null); + + useEffect(() => { + let isMounted = true; + + const updateDevices = () => + mx.getDevices().then((data) => { + if (!isMounted) return; + setDeviceList(data.devices || []); + }); + updateDevices(); + + const handleDevicesUpdate: CryptoEventHandlerMap[CryptoEvent.DevicesUpdated] = (users) => { + const userId = mx.getUserId(); + if (userId && users.includes(userId)) { + updateDevices(); + } + }; + + mx.on(CryptoEvent.DevicesUpdated, handleDevicesUpdate); + return () => { + mx.removeListener(CryptoEvent.DevicesUpdated, handleDevicesUpdate); + isMounted = false; + }; + }, [mx]); + return deviceList; +} diff --git a/src/app/pages/client/SidebarNav.tsx b/src/app/pages/client/SidebarNav.tsx index fb6bd7422..110e46940 100644 --- a/src/app/pages/client/SidebarNav.tsx +++ b/src/app/pages/client/SidebarNav.tsx @@ -10,7 +10,15 @@ import { SidebarItemTooltip, SidebarItem, } from '../../components/sidebar'; -import { DirectTab, HomeTab, SpaceTabs, InboxTab, ExploreTab, UserTab } from './sidebar'; +import { + DirectTab, + HomeTab, + SpaceTabs, + InboxTab, + ExploreTab, + UserTab, + UnverifiedTab, +} from './sidebar'; import { openCreateRoom, openSearch } from '../../../client/action/navigation'; export function SidebarNav() { @@ -65,6 +73,8 @@ export function SidebarNav() { + + diff --git a/src/app/pages/client/sidebar/UnverifiedTab.css.ts b/src/app/pages/client/sidebar/UnverifiedTab.css.ts new file mode 100644 index 000000000..e8fe8c51b --- /dev/null +++ b/src/app/pages/client/sidebar/UnverifiedTab.css.ts @@ -0,0 +1,24 @@ +import { keyframes, style } from '@vanilla-extract/css'; +import { color, toRem } from 'folds'; + +const pushRight = keyframes({ + from: { + transform: `translateX(${toRem(2)}) scale(1)`, + }, + to: { + transform: 'translateX(0) scale(1)', + }, +}); + +export const UnverifiedTab = style({ + animationName: pushRight, + animationDuration: '400ms', + animationIterationCount: 30, + animationDirection: 'alternate', +}); + +export const UnverifiedAvatar = style({ + backgroundColor: color.Critical.Container, + color: color.Critical.OnContainer, + borderColor: color.Critical.ContainerLine, +}); diff --git a/src/app/pages/client/sidebar/UnverifiedTab.tsx b/src/app/pages/client/sidebar/UnverifiedTab.tsx new file mode 100644 index 000000000..402ffc2b8 --- /dev/null +++ b/src/app/pages/client/sidebar/UnverifiedTab.tsx @@ -0,0 +1,51 @@ +import React from 'react'; +import { Badge, color, Icon, Icons, Text } from 'folds'; +import { openSettings } from '../../../../client/action/navigation'; +import { isCrossVerified } from '../../../../util/matrixUtil'; +import { + SidebarAvatar, + SidebarItem, + SidebarItemBadge, + SidebarItemTooltip, +} from '../../../components/sidebar'; +import { useDeviceList } from '../../../hooks/useDeviceList'; +import { tabText } from '../../../organisms/settings/Settings'; +import { useMatrixClient } from '../../../hooks/useMatrixClient'; +import * as css from './UnverifiedTab.css'; + +export function UnverifiedTab() { + const mx = useMatrixClient(); + const deviceList = useDeviceList(); + console.log(deviceList); + const unverified = deviceList?.filter( + (device) => isCrossVerified(mx, device.device_id) === false + ); + console.log(unverified); + + if (!unverified?.length) return null; + + return ( + + + {(triggerRef) => ( + openSettings(tabText.SECURITY)} + > + + + )} + + + + + {unverified.length} + + + + + ); +} diff --git a/src/app/pages/client/sidebar/index.ts b/src/app/pages/client/sidebar/index.ts index 63c5d4bb6..5da8780b1 100644 --- a/src/app/pages/client/sidebar/index.ts +++ b/src/app/pages/client/sidebar/index.ts @@ -4,3 +4,4 @@ export * from './SpaceTabs'; export * from './InboxTab'; export * from './ExploreTab'; export * from './UserTab'; +export * from './UnverifiedTab'; diff --git a/src/util/matrixUtil.js b/src/util/matrixUtil.js index 9f1d94212..7664c3a40 100644 --- a/src/util/matrixUtil.js +++ b/src/util/matrixUtil.js @@ -106,7 +106,7 @@ export function isCrossVerified(mx, deviceId) { const deviceInfo = mx.getStoredDevice(mx.getUserId(), deviceId); const deviceTrust = crossSignInfo.checkDeviceTrust(crossSignInfo, deviceInfo, false, true); return deviceTrust.isCrossSigningVerified(); - } catch { + } catch (e) { // device does not support encryption return null; } From 96222de5bc521ed212d4b63d6a25925fce500c80 Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Sun, 4 Aug 2024 11:06:42 +0530 Subject: [PATCH 1189/1531] fix page up/down button not working (#1863) --- src/app/features/room/Room.tsx | 3 ++- src/app/features/room/RoomView.tsx | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/app/features/room/Room.tsx b/src/app/features/room/Room.tsx index ee3e70274..a4ec71651 100644 --- a/src/app/features/room/Room.tsx +++ b/src/app/features/room/Room.tsx @@ -13,6 +13,7 @@ import { useKeyDown } from '../../hooks/useKeyDown'; import { markAsRead } from '../../../client/action/notifications'; import { useMatrixClient } from '../../hooks/useMatrixClient'; import { useRoomMembers } from '../../hooks/useRoomMembers'; +import { editableActiveElement } from '../../utils/dom'; export function Room() { const { eventId } = useParams(); @@ -28,7 +29,7 @@ export function Room() { window, useCallback( (evt) => { - if (isKeyHotkey('escape', evt)) { + if (isKeyHotkey('escape', evt) && !editableActiveElement()) { markAsRead(mx, room.roomId); } }, diff --git a/src/app/features/room/RoomView.tsx b/src/app/features/room/RoomView.tsx index 3eabd528a..250afc930 100644 --- a/src/app/features/room/RoomView.tsx +++ b/src/app/features/room/RoomView.tsx @@ -25,6 +25,7 @@ const shouldFocusMessageField = (evt: KeyboardEvent): boolean => { if (evt.metaKey || evt.altKey || evt.ctrlKey) { return false; } + // do not focus on F keys if (/^F\d+$/.test(code)) return false; @@ -36,6 +37,9 @@ const shouldFocusMessageField = (evt: KeyboardEvent): boolean => { code.startsWith('Alt') || code.startsWith('Control') || code.startsWith('Arrow') || + code.startsWith('Page') || + code.startsWith('End') || + code.startsWith('Home') || code === 'Tab' || code === 'Space' || code === 'Enter' || From 8ed78d48fb05c2066ce3eaa317922a99a80110db Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Sun, 4 Aug 2024 11:07:28 +0530 Subject: [PATCH 1190/1531] fix notification not working for selected room (#1864) --- src/app/pages/client/ClientNonUIFeatures.tsx | 8 ++++---- src/app/pages/client/sidebar/UnverifiedTab.tsx | 2 -- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/app/pages/client/ClientNonUIFeatures.tsx b/src/app/pages/client/ClientNonUIFeatures.tsx index 845fceb3f..ffe33e9af 100644 --- a/src/app/pages/client/ClientNonUIFeatures.tsx +++ b/src/app/pages/client/ClientNonUIFeatures.tsx @@ -183,17 +183,17 @@ function MessageNotifications() { removed, data ) => { + if (mx.getSyncState() !== 'SYNCING') return; + if (document.hasFocus() && (selectedRoomId === room?.roomId || notificationSelected)) return; if ( - mx.getSyncState() !== 'SYNCING' || - selectedRoomId === room?.roomId || - notificationSelected || !room || !data.liveEvent || room.isSpaceRoom() || !isNotificationEvent(mEvent) || getNotificationType(mx, room.roomId) === NotificationType.Mute - ) + ) { return; + } const sender = mEvent.getSender(); const eventId = mEvent.getId(); diff --git a/src/app/pages/client/sidebar/UnverifiedTab.tsx b/src/app/pages/client/sidebar/UnverifiedTab.tsx index 402ffc2b8..919c4a708 100644 --- a/src/app/pages/client/sidebar/UnverifiedTab.tsx +++ b/src/app/pages/client/sidebar/UnverifiedTab.tsx @@ -16,11 +16,9 @@ import * as css from './UnverifiedTab.css'; export function UnverifiedTab() { const mx = useMatrixClient(); const deviceList = useDeviceList(); - console.log(deviceList); const unverified = deviceList?.filter( (device) => isCrossVerified(mx, device.device_id) === false ); - console.log(unverified); if (!unverified?.length) return null; From 581211f13e20c87fbfef6410ddf57a13c7a0b49a Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Sun, 4 Aug 2024 11:08:20 +0530 Subject: [PATCH 1191/1531] fix crash when decoding malformed urls (#1865) --- src/app/components/editor/input.ts | 3 ++- src/app/components/url-preview/UrlPreviewCard.tsx | 3 ++- src/app/pages/auth/AuthLayout.tsx | 5 +++-- src/app/plugins/react-custom-html-parser.tsx | 9 +++++---- src/app/utils/dom.ts | 8 ++++++++ 5 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/app/components/editor/input.ts b/src/app/components/editor/input.ts index 29e5bd6a2..20c56ed31 100644 --- a/src/app/components/editor/input.ts +++ b/src/app/components/editor/input.ts @@ -25,6 +25,7 @@ import { parseMatrixToUser, testMatrixTo, } from '../../plugins/matrix-to'; +import { tryDecodeURIComponent } from '../../utils/dom'; const markNodeToType: Record = { b: MarkType.Bold, @@ -73,7 +74,7 @@ const elementToInlineNode = (node: Element): MentionElement | EmoticonElement | return createEmoticonElement(src, alt || 'Unknown Emoji'); } if (node.name === 'a') { - const href = decodeURIComponent(node.attribs.href); + const href = tryDecodeURIComponent(node.attribs.href); if (typeof href !== 'string') return undefined; if (testMatrixTo(href)) { const userMention = parseMatrixToUser(href); diff --git a/src/app/components/url-preview/UrlPreviewCard.tsx b/src/app/components/url-preview/UrlPreviewCard.tsx index fc9229faf..07c25f8a1 100644 --- a/src/app/components/url-preview/UrlPreviewCard.tsx +++ b/src/app/components/url-preview/UrlPreviewCard.tsx @@ -9,6 +9,7 @@ import { useIntersectionObserver, } from '../../hooks/useIntersectionObserver'; import * as css from './UrlPreviewCard.css'; +import { tryDecodeURIComponent } from '../../utils/dom'; const linkStyles = { color: color.Success.Main }; @@ -43,7 +44,7 @@ export const UrlPreviewCard = as<'div', { url: string; ts: number }>( priority="300" > {typeof prev['og:site_name'] === 'string' && `${prev['og:site_name']} | `} - {decodeURIComponent(url)} + {tryDecodeURIComponent(url)} {prev['og:title']} diff --git a/src/app/pages/auth/AuthLayout.tsx b/src/app/pages/auth/AuthLayout.tsx index 2ea941420..3943f42d1 100644 --- a/src/app/pages/auth/AuthLayout.tsx +++ b/src/app/pages/auth/AuthLayout.tsx @@ -29,6 +29,7 @@ import { AutoDiscoveryInfoProvider } from '../../hooks/useAutoDiscoveryInfo'; import { AuthFlowsLoader } from '../../components/AuthFlowsLoader'; import { AuthFlowsProvider } from '../../hooks/useAuthFlows'; import { AuthServerProvider } from '../../hooks/useAuthServer'; +import { tryDecodeURIComponent } from '../../utils/dom'; const currentAuthPath = (pathname: string): string => { if (matchPath(LOGIN_PATH, pathname)) { @@ -72,7 +73,7 @@ export function AuthLayout() { const clientConfig = useClientConfig(); const defaultServer = clientDefaultServer(clientConfig); - let server: string = urlEncodedServer ? decodeURIComponent(urlEncodedServer) : defaultServer; + let server: string = urlEncodedServer ? tryDecodeURIComponent(urlEncodedServer) : defaultServer; if (!clientAllowedServer(clientConfig, server)) { server = defaultServer; @@ -94,7 +95,7 @@ export function AuthLayout() { // if server is mismatches with path server, update path useEffect(() => { - if (!urlEncodedServer || decodeURIComponent(urlEncodedServer) !== server) { + if (!urlEncodedServer || tryDecodeURIComponent(urlEncodedServer) !== server) { navigate( generatePath(currentAuthPath(location.pathname), { server: encodeURIComponent(server), diff --git a/src/app/plugins/react-custom-html-parser.tsx b/src/app/plugins/react-custom-html-parser.tsx index 167043745..95e2f3342 100644 --- a/src/app/plugins/react-custom-html-parser.tsx +++ b/src/app/plugins/react-custom-html-parser.tsx @@ -26,6 +26,7 @@ import { testMatrixTo, } from './matrix-to'; import { onEnterOrSpace } from '../utils/keyboard'; +import { tryDecodeURIComponent } from '../utils/dom'; const ReactPrism = lazy(() => import('./react-prism/ReactPrism')); @@ -134,8 +135,8 @@ export const factoryRenderLinkifyWithMention = ( attributes, content, }) => { - if (tagName === 'a' && testMatrixTo(decodeURIComponent(attributes.href))) { - const mention = mentionRender(decodeURIComponent(attributes.href)); + if (tagName === 'a' && testMatrixTo(tryDecodeURIComponent(attributes.href))) { + const mention = mentionRender(tryDecodeURIComponent(attributes.href)); if (mention) return mention; } @@ -325,11 +326,11 @@ export const getReactCustomHtmlParser = ( } } - if (name === 'a' && testMatrixTo(decodeURIComponent(props.href))) { + if (name === 'a' && testMatrixTo(tryDecodeURIComponent(props.href))) { const mention = renderMatrixMention( mx, roomId, - decodeURIComponent(props.href), + tryDecodeURIComponent(props.href), makeMentionCustomProps(params.handleMentionClick) ); if (mention) return mention; diff --git a/src/app/utils/dom.ts b/src/app/utils/dom.ts index 1aea6754c..ab4b8e65c 100644 --- a/src/app/utils/dom.ts +++ b/src/app/utils/dom.ts @@ -196,3 +196,11 @@ export const setFavicon = (url: string): void => { if (!favicon) return; favicon.setAttribute('href', url); }; + +export const tryDecodeURIComponent = (encodedURIComponent: string): string => { + try { + return decodeURIComponent(encodedURIComponent); + } catch { + return encodedURIComponent; + } +}; From cfe893f358785c9bea2c3bdd6402079fad1fcc3e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 4 Aug 2024 15:38:47 +1000 Subject: [PATCH 1192/1531] Bump docker/setup-buildx-action from 3.5.0 to 3.6.1 (#1850) Bumps [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) from 3.5.0 to 3.6.1. - [Release notes](https://github.com/docker/setup-buildx-action/releases) - [Commits](https://github.com/docker/setup-buildx-action/compare/v3.5.0...v3.6.1) --- updated-dependencies: - dependency-name: docker/setup-buildx-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/prod-deploy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/prod-deploy.yml b/.github/workflows/prod-deploy.yml index a0a70d13d..24a1be01c 100644 --- a/.github/workflows/prod-deploy.yml +++ b/.github/workflows/prod-deploy.yml @@ -70,7 +70,7 @@ jobs: - name: Set up QEMU uses: docker/setup-qemu-action@v3.2.0 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3.5.0 + uses: docker/setup-buildx-action@v3.6.1 - name: Login to Docker Hub uses: docker/login-action@v3.3.0 with: From cabfdd47b5bf1c9a12c6d30a9c28fed6d6682fb9 Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Sun, 4 Aug 2024 11:34:11 +0530 Subject: [PATCH 1193/1531] fix type to focus not working after room switch (#1866) --- src/app/features/room/RoomInput.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/app/features/room/RoomInput.tsx b/src/app/features/room/RoomInput.tsx index 2728a54c8..8375d2f75 100644 --- a/src/app/features/room/RoomInput.tsx +++ b/src/app/features/room/RoomInput.tsx @@ -186,9 +186,8 @@ export const RoomInput = forwardRef( Transforms.insertFragment(editor, msgDraft); }, [editor, msgDraft]); - useEffect(() => { - if (!mobileOrTablet()) ReactEditor.focus(editor); - return () => { + useEffect( + () => () => { if (!isEmptyEditor(editor)) { const parsedDraft = JSON.parse(JSON.stringify(editor.children)); setMsgDraft(parsedDraft); @@ -197,8 +196,9 @@ export const RoomInput = forwardRef( } resetEditor(editor); resetEditorHistory(editor); - }; - }, [roomId, editor, setMsgDraft]); + }, + [roomId, editor, setMsgDraft] + ); const handleRemoveUpload = useCallback( (upload: TUploadContent | TUploadContent[]) => { From e68c56b334107862ab2eec5635c11c40c050f00b Mon Sep 17 00:00:00 2001 From: Krishan <33421343+kfiven@users.noreply.github.com> Date: Sun, 4 Aug 2024 20:15:10 +1000 Subject: [PATCH 1194/1531] Release v4.1.0 (#1867) --- package-lock.json | 4 ++-- package.json | 2 +- src/app/pages/auth/AuthFooter.tsx | 2 +- src/app/pages/client/WelcomePage.tsx | 2 +- src/client/state/cons.js | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8b00ff078..f5aca0e7a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "cinny", - "version": "4.0.3", + "version": "4.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "cinny", - "version": "4.0.3", + "version": "4.1.0", "license": "AGPL-3.0-only", "dependencies": { "@atlaskit/pragmatic-drag-and-drop": "1.1.6", diff --git a/package.json b/package.json index d06b96019..dc4a040b7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cinny", - "version": "4.0.3", + "version": "4.1.0", "description": "Yet another matrix client", "main": "index.js", "type": "module", diff --git a/src/app/pages/auth/AuthFooter.tsx b/src/app/pages/auth/AuthFooter.tsx index 4483ec15b..b6e94d2f8 100644 --- a/src/app/pages/auth/AuthFooter.tsx +++ b/src/app/pages/auth/AuthFooter.tsx @@ -15,7 +15,7 @@ export function AuthFooter() { target="_blank" rel="noreferrer" > - v4.0.3 + v4.1.0 Twitter diff --git a/src/app/pages/client/WelcomePage.tsx b/src/app/pages/client/WelcomePage.tsx index 8cf6b9ffc..1e146a04b 100644 --- a/src/app/pages/client/WelcomePage.tsx +++ b/src/app/pages/client/WelcomePage.tsx @@ -24,7 +24,7 @@ export function WelcomePage() { target="_blank" rel="noreferrer noopener" > - v4.0.3 + v4.1.0 } diff --git a/src/client/state/cons.js b/src/client/state/cons.js index 157d4a625..f7f65db24 100644 --- a/src/client/state/cons.js +++ b/src/client/state/cons.js @@ -1,5 +1,5 @@ const cons = { - version: '4.0.3', + version: '4.1.0', secretKey: { ACCESS_TOKEN: 'cinny_access_token', DEVICE_ID: 'cinny_device_id', From b4ce8a7cab727c51327c9434ef4bdd765fd7778b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 14 Aug 2024 23:21:11 +1000 Subject: [PATCH 1195/1531] Bump docker/build-push-action from 6.5.0 to 6.6.1 (#1891) Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 6.5.0 to 6.6.1. - [Release notes](https://github.com/docker/build-push-action/releases) - [Commits](https://github.com/docker/build-push-action/compare/v6.5.0...v6.6.1) --- updated-dependencies: - dependency-name: docker/build-push-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/docker-pr.yml | 2 +- .github/workflows/prod-deploy.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docker-pr.yml b/.github/workflows/docker-pr.yml index 7b1e2abd4..827ca66e5 100644 --- a/.github/workflows/docker-pr.yml +++ b/.github/workflows/docker-pr.yml @@ -13,7 +13,7 @@ jobs: - name: Checkout repository uses: actions/checkout@v4.1.7 - name: Build Docker image - uses: docker/build-push-action@v6.5.0 + uses: docker/build-push-action@v6.6.1 with: context: . push: false diff --git a/.github/workflows/prod-deploy.yml b/.github/workflows/prod-deploy.yml index 24a1be01c..d340cb77b 100644 --- a/.github/workflows/prod-deploy.yml +++ b/.github/workflows/prod-deploy.yml @@ -90,7 +90,7 @@ jobs: ${{ secrets.DOCKER_USERNAME }}/cinny ghcr.io/${{ github.repository }} - name: Build and push Docker image - uses: docker/build-push-action@v6.5.0 + uses: docker/build-push-action@v6.6.1 with: context: . platforms: linux/amd64,linux/arm64 From ac1797344c0b8d0ded6019f33f0c9f17973de746 Mon Sep 17 00:00:00 2001 From: aceArt-GmbH <33117017+aceArt-GmbH@users.noreply.github.com> Date: Wed, 14 Aug 2024 15:29:34 +0200 Subject: [PATCH 1196/1531] Add translation support using i18next (#1576) Co-authored-by: Ajay Bura <32841439+ajbura@users.noreply.github.com> --- package-lock.json | 134 +++++++++++++++++++++++-- package.json | 4 + public/locales/de.json | 7 ++ public/locales/en.json | 7 ++ src/app/features/room/RoomTimeline.tsx | 4 +- src/app/i18n.ts | 31 ++++++ src/index.tsx | 3 + vite.config.js | 4 + 8 files changed, 184 insertions(+), 10 deletions(-) create mode 100644 public/locales/de.json create mode 100644 public/locales/en.json create mode 100644 src/app/i18n.ts diff --git a/package-lock.json b/package-lock.json index f5aca0e7a..061d3ded0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -37,6 +37,9 @@ "formik": "2.4.6", "html-dom-parser": "4.0.0", "html-react-parser": "4.2.0", + "i18next": "23.12.2", + "i18next-browser-languagedetector": "8.0.0", + "i18next-http-backend": "2.5.2", "immer": "9.0.16", "is-hotkey": "0.2.0", "jotai": "2.6.0", @@ -54,6 +57,7 @@ "react-dom": "18.2.0", "react-error-boundary": "4.0.13", "react-google-recaptcha": "2.1.0", + "react-i18next": "15.0.0", "react-modal": "3.16.1", "react-range": "1.8.14", "react-router-dom": "6.20.0", @@ -438,11 +442,12 @@ } }, "node_modules/@babel/runtime": { - "version": "7.20.6", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.6.tgz", - "integrity": "sha512-Q+8MqP7TiHMWzSfwiJwXCjyf4GYA4Dgw3emg/7xmwsdLJOZUp+nMqcOwOzzYheuM1rhDu8FSj2l0aoMygEuXuA==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.0.tgz", + "integrity": "sha512-7dRy4DwXwtzBrPbZflqxnvfxLF8kdZXPkhymtDeFoFqE6ldzjQFgYTtYIFARcLEYDrqfBfYcZt1WqFxRoyC9Rw==", + "license": "MIT", "dependencies": { - "regenerator-runtime": "^0.13.11" + "regenerator-runtime": "^0.14.0" }, "engines": { "node": ">=6.9.0" @@ -467,11 +472,6 @@ "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", "dev": true }, - "node_modules/@babel/runtime/node_modules/regenerator-runtime": { - "version": "0.13.11", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" - }, "node_modules/@babel/template": { "version": "7.22.15", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", @@ -6146,6 +6146,15 @@ "entities": "^4.5.0" } }, + "node_modules/html-parse-stringify": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz", + "integrity": "sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==", + "license": "MIT", + "dependencies": { + "void-elements": "3.1.0" + } + }, "node_modules/html-react-parser": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/html-react-parser/-/html-react-parser-4.2.0.tgz", @@ -6191,6 +6200,76 @@ "node": ">= 6" } }, + "node_modules/i18next": { + "version": "23.12.2", + "resolved": "https://registry.npmjs.org/i18next/-/i18next-23.12.2.tgz", + "integrity": "sha512-XIeh5V+bi8SJSWGL3jqbTEBW5oD6rbP5L+E7dVQh1MNTxxYef0x15rhJVcRb7oiuq4jLtgy2SD8eFlf6P2cmqg==", + "funding": [ + { + "type": "individual", + "url": "https://locize.com" + }, + { + "type": "individual", + "url": "https://locize.com/i18next.html" + }, + { + "type": "individual", + "url": "https://www.i18next.com/how-to/faq#i18next-is-awesome.-how-can-i-support-the-project" + } + ], + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.23.2" + } + }, + "node_modules/i18next-browser-languagedetector": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/i18next-browser-languagedetector/-/i18next-browser-languagedetector-8.0.0.tgz", + "integrity": "sha512-zhXdJXTTCoG39QsrOCiOabnWj2jecouOqbchu3EfhtSHxIB5Uugnm9JaizenOy39h7ne3+fLikIjeW88+rgszw==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.23.2" + } + }, + "node_modules/i18next-http-backend": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/i18next-http-backend/-/i18next-http-backend-2.5.2.tgz", + "integrity": "sha512-+K8HbDfrvc1/2X8jpb7RLhI9ZxBDpx3xogYkQwGKlWAUXLSEGXzgdt3EcUjLlBCdMwdQY+K+EUF6oh8oB6rwHw==", + "license": "MIT", + "dependencies": { + "cross-fetch": "4.0.0" + } + }, + "node_modules/i18next-http-backend/node_modules/cross-fetch": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.0.0.tgz", + "integrity": "sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==", + "license": "MIT", + "dependencies": { + "node-fetch": "^2.6.12" + } + }, + "node_modules/i18next-http-backend/node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, "node_modules/ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", @@ -7717,6 +7796,28 @@ "react": ">=16.4.1" } }, + "node_modules/react-i18next": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-15.0.0.tgz", + "integrity": "sha512-2O3IgF4zivg57Q6p6i+ChDgJ371IDcEWbuWC6gvoh5NbkDMs0Q+O7RPr4v61+Se32E0V+LmtwePAeqWZW0bi6g==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.24.8", + "html-parse-stringify": "^3.0.1" + }, + "peerDependencies": { + "i18next": ">= 23.2.3", + "react": ">= 16.8.0" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + }, + "react-native": { + "optional": true + } + } + }, "node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", @@ -7824,6 +7925,12 @@ "node": ">=8.10.0" } }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "license": "MIT" + }, "node_modules/regexp.prototype.flags": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", @@ -9294,6 +9401,15 @@ "@esbuild/win32-x64": "0.19.12" } }, + "node_modules/void-elements": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz", + "integrity": "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/warning": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", diff --git a/package.json b/package.json index dc4a040b7..8c66068bc 100644 --- a/package.json +++ b/package.json @@ -48,6 +48,9 @@ "formik": "2.4.6", "html-dom-parser": "4.0.0", "html-react-parser": "4.2.0", + "i18next": "23.12.2", + "i18next-browser-languagedetector": "8.0.0", + "i18next-http-backend": "2.5.2", "immer": "9.0.16", "is-hotkey": "0.2.0", "jotai": "2.6.0", @@ -65,6 +68,7 @@ "react-dom": "18.2.0", "react-error-boundary": "4.0.13", "react-google-recaptcha": "2.1.0", + "react-i18next": "15.0.0", "react-modal": "3.16.1", "react-range": "1.8.14", "react-router-dom": "6.20.0", diff --git a/public/locales/de.json b/public/locales/de.json new file mode 100644 index 000000000..43a37160e --- /dev/null +++ b/public/locales/de.json @@ -0,0 +1,7 @@ +{ + "Organisms": { + "RoomCommon": { + "changed_room_name": " hat den Raum Name geändert" + } + } +} diff --git a/public/locales/en.json b/public/locales/en.json new file mode 100644 index 000000000..7a2534b8f --- /dev/null +++ b/public/locales/en.json @@ -0,0 +1,7 @@ +{ + "Organisms": { + "RoomCommon": { + "changed_room_name": " changed room name" + } + } +} diff --git a/src/app/features/room/RoomTimeline.tsx b/src/app/features/room/RoomTimeline.tsx index 6e5037038..84ce8af18 100644 --- a/src/app/features/room/RoomTimeline.tsx +++ b/src/app/features/room/RoomTimeline.tsx @@ -46,6 +46,7 @@ import { } from 'folds'; import { isKeyHotkey } from 'is-hotkey'; import { Opts as LinkifyOpts } from 'linkifyjs'; +import { useTranslation } from 'react-i18next'; import { decryptFile, eventWithShortcode, @@ -958,6 +959,7 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli }, [editor] ); + const { t } = useTranslation(); const renderMatrixEvent = useMatrixEventRenderer< [string, MatrixEvent, number, EventTimelineSet, boolean] @@ -1273,7 +1275,7 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli {senderName} - {' changed room name'} + {t('Organisms.RoomCommon.changed_room_name')} } diff --git a/src/app/i18n.ts b/src/app/i18n.ts new file mode 100644 index 000000000..9e83805d3 --- /dev/null +++ b/src/app/i18n.ts @@ -0,0 +1,31 @@ +import i18n from 'i18next'; +import LanguageDetector from 'i18next-browser-languagedetector'; +import Backend, { HttpBackendOptions } from 'i18next-http-backend'; +import { initReactI18next } from 'react-i18next'; +import { trimTrailingSlash } from './utils/common'; + +i18n + // i18next-http-backend + // loads translations from your server + // https://github.com/i18next/i18next-http-backend + .use(Backend) + // detect user language + // learn more: https://github.com/i18next/i18next-browser-languageDetector + .use(LanguageDetector) + // pass the i18n instance to react-i18next. + .use(initReactI18next) + // init i18next + // for all options read: https://www.i18next.com/overview/configuration-options + .init({ + debug: false, + fallbackLng: 'en', + interpolation: { + escapeValue: false, // not needed for react as it escapes by default + }, + load: 'languageOnly', + backend: { + loadPath: `${trimTrailingSlash(import.meta.env.BASE_URL)}/public/locales/{{lng}}.json`, + }, + }); + +export default i18n; diff --git a/src/index.tsx b/src/index.tsx index 1d8642037..a289ed1cc 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -14,6 +14,9 @@ import settings from './client/state/settings'; import App from './app/pages/App'; +// import i18n (needs to be bundled ;)) +import './app/i18n'; + document.body.classList.add(configClass, varsClass); settings.applyTheme(); diff --git a/vite.config.js b/vite.config.js index 1255f81c4..7b5ec2509 100644 --- a/vite.config.js +++ b/vite.config.js @@ -35,6 +35,10 @@ const copyFiles = { src: 'public/res/android', dest: 'public/', }, + { + src: 'public/locales', + dest: 'public/', + }, ], }; From 7e7bee8f48229a7ebac0c64d5f4f744d81eca202 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 14 Aug 2024 23:38:35 +1000 Subject: [PATCH 1197/1531] Bump actions/upload-artifact from 4.3.4 to 4.3.6 (#1890) Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4.3.4 to 4.3.6. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/v4.3.4...v4.3.6) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build-pull-request.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-pull-request.yml b/.github/workflows/build-pull-request.yml index 67ae5f1e9..ae1097be0 100644 --- a/.github/workflows/build-pull-request.yml +++ b/.github/workflows/build-pull-request.yml @@ -25,7 +25,7 @@ jobs: NODE_OPTIONS: '--max_old_space_size=4096' run: npm run build - name: Upload artifact - uses: actions/upload-artifact@v4.3.4 + uses: actions/upload-artifact@v4.3.6 with: name: preview path: dist @@ -33,7 +33,7 @@ jobs: - name: Save pr number run: echo ${PR_NUMBER} > ./pr.txt - name: Upload pr number - uses: actions/upload-artifact@v4.3.4 + uses: actions/upload-artifact@v4.3.6 with: name: pr path: ./pr.txt From 830d05e217fd6640c219d4eb419895ca8669e111 Mon Sep 17 00:00:00 2001 From: greentore <117551249+greentore@users.noreply.github.com> Date: Thu, 15 Aug 2024 16:52:32 +0200 Subject: [PATCH 1198/1531] Add basic `m.thread` support (#1349) * Add basic `m.thread` support * Fix types * Update to v4 * Fix auto formatting mess * Add threaded reply indicators * Fix reply overflow * Fix replying to edited threaded replies * Add thread indicator to room input * Fix editing encrypted events * Use `toRem` function for converting units --------- Co-authored-by: Ajay Bura <32841439+ajbura@users.noreply.github.com> --- src/app/components/message/Reply.css.ts | 19 +++++ src/app/components/message/Reply.tsx | 81 +++++++++++-------- .../message-search/SearchResultGroup.tsx | 16 ++-- src/app/features/room/RoomInput.tsx | 40 +++++---- src/app/features/room/RoomTimeline.tsx | 33 ++++---- src/app/pages/client/inbox/Notifications.tsx | 13 +-- src/app/state/room/roomInputDrafts.ts | 4 +- src/app/utils/room.ts | 19 +++-- 8 files changed, 140 insertions(+), 85 deletions(-) diff --git a/src/app/components/message/Reply.css.ts b/src/app/components/message/Reply.css.ts index 014a2840a..067993914 100644 --- a/src/app/components/message/Reply.css.ts +++ b/src/app/components/message/Reply.css.ts @@ -5,6 +5,25 @@ export const ReplyBend = style({ flexShrink: 0, }); +export const ThreadIndicator = style({ + opacity: config.opacity.P300, + gap: toRem(2), + + selectors: { + 'button&': { + cursor: 'pointer', + }, + ':hover&': { + opacity: config.opacity.P500, + }, + }, +}); + +export const ThreadIndicatorIcon = style({ + width: toRem(14), + height: toRem(14), +}); + export const Reply = style({ marginBottom: toRem(1), minWidth: 0, diff --git a/src/app/components/message/Reply.tsx b/src/app/components/message/Reply.tsx index 85383cdb5..82a9d9198 100644 --- a/src/app/components/message/Reply.tsx +++ b/src/app/components/message/Reply.tsx @@ -1,7 +1,7 @@ import { Box, Icon, Icons, Text, as, color, toRem } from 'folds'; import { EventTimelineSet, MatrixClient, MatrixEvent, Room } from 'matrix-js-sdk'; import { CryptoBackend } from 'matrix-js-sdk/lib/common-crypto/CryptoBackend'; -import React, { ReactNode, useEffect, useMemo, useState } from 'react'; +import React, { MouseEventHandler, ReactNode, useEffect, useMemo, useState } from 'react'; import to from 'await-to-js'; import classNames from 'classnames'; import colorMXID from '../../../util/colorMXID'; @@ -22,6 +22,7 @@ export const ReplyLayout = as<'div', ReplyLayoutProps>( ( ) ); +export const ThreadIndicator = as<'div'>(({ ...props }, ref) => ( + + + Threaded reply + +)); + type ReplyProps = { mx: MatrixClient; room: Room; - timelineSet?: EventTimelineSet; - eventId: string; + timelineSet?: EventTimelineSet | undefined; + replyEventId: string; + threadRootId?: string | undefined; + onClick?: MouseEventHandler | undefined; }; -export const Reply = as<'div', ReplyProps>(({ mx, room, timelineSet, eventId, ...props }, ref) => { +export const Reply = as<'div', ReplyProps>((_, ref) => { + const { mx, room, timelineSet, replyEventId, threadRootId, onClick, ...props } = _; const [replyEvent, setReplyEvent] = useState( - timelineSet?.findEventById(eventId) + timelineSet?.findEventById(replyEventId) ); const placeholderWidth = useMemo(() => randomNumberBetween(40, 400), []); @@ -62,7 +73,7 @@ export const Reply = as<'div', ReplyProps>(({ mx, room, timelineSet, eventId, .. useEffect(() => { let disposed = false; const loadEvent = async () => { - const [err, evt] = await to(mx.fetchRoomEvent(room.roomId, eventId)); + const [err, evt] = await to(mx.fetchRoomEvent(room.roomId, replyEventId)); const mEvent = new MatrixEvent(evt); if (disposed) return; if (err) { @@ -78,37 +89,43 @@ export const Reply = as<'div', ReplyProps>(({ mx, room, timelineSet, eventId, .. return () => { disposed = true; }; - }, [replyEvent, mx, room, eventId]); + }, [replyEvent, mx, room, replyEventId]); const badEncryption = replyEvent?.getContent().msgtype === 'm.bad.encrypted'; const bodyJSX = body ? scaleSystemEmoji(trimReplyFromBody(body)) : fallbackBody; return ( - - {getMemberDisplayName(room, sender) ?? getMxIdLocalPart(sender)} - - ) - } - {...props} - ref={ref} - > - {replyEvent !== undefined ? ( - - {badEncryption ? : bodyJSX} - - ) : ( - + + {threadRootId && ( + )} - + + {getMemberDisplayName(room, sender) ?? getMxIdLocalPart(sender)} + + ) + } + data-event-id={replyEventId} + onClick={onClick} + > + {replyEvent !== undefined ? ( + + {badEncryption ? : bodyJSX} + + ) : ( + + )} + + ); }); diff --git a/src/app/features/message-search/SearchResultGroup.tsx b/src/app/features/message-search/SearchResultGroup.tsx index 2b2a816a5..84ba3a763 100644 --- a/src/app/features/message-search/SearchResultGroup.tsx +++ b/src/app/features/message-search/SearchResultGroup.tsx @@ -148,7 +148,7 @@ export function SearchResultGroup({ } ); - const handleOpenClick: MouseEventHandler = (evt) => { + const handleOpenClick: MouseEventHandler = (evt) => { const eventId = evt.currentTarget.getAttribute('data-event-id'); if (!eventId) return; onOpen(room.roomId, eventId); @@ -183,15 +183,16 @@ export function SearchResultGroup({ event.sender; const senderAvatarMxc = getMemberAvatarMxc(room, event.sender); + const relation = event.content['m.relates_to']; const mainEventId = - event.content['m.relates_to']?.rel_type === RelationType.Replace - ? event.content['m.relates_to'].event_id - : event.event_id; + relation?.rel_type === RelationType.Replace ? relation.event_id : event.event_id; const getContent = (() => event.content['m.new_content'] ?? event.content) as GetContentCallback; - const replyEventId = event.content['m.relates_to']?.['m.in_reply_to']?.event_id; + const replyEventId = relation?.['m.in_reply_to']?.event_id; + const threadRootId = + relation?.rel_type === RelationType.Thread ? relation.event_id : undefined; return ( {replyEventId && ( )} diff --git a/src/app/features/room/RoomInput.tsx b/src/app/features/room/RoomInput.tsx index 8375d2f75..3c78ff3e6 100644 --- a/src/app/features/room/RoomInput.tsx +++ b/src/app/features/room/RoomInput.tsx @@ -10,7 +10,7 @@ import React, { } from 'react'; import { useAtom, useAtomValue } from 'jotai'; import { isKeyHotkey } from 'is-hotkey'; -import { EventType, IContent, MsgType, Room } from 'matrix-js-sdk'; +import { EventType, IContent, MsgType, RelationType, Room } from 'matrix-js-sdk'; import { ReactEditor } from 'slate-react'; import { Transforms, Editor } from 'slate'; import { @@ -106,7 +106,7 @@ import { CommandAutocomplete } from './CommandAutocomplete'; import { Command, SHRUG, useCommands } from '../../hooks/useCommands'; import { mobileOrTablet } from '../../utils/user-agent'; import { useElementSizeObserver } from '../../hooks/useElementSizeObserver'; -import { ReplyLayout } from '../../components/message'; +import { ReplyLayout, ThreadIndicator } from '../../components/message'; import { roomToParentsAtom } from '../../state/room/roomToParents'; interface RoomInputProps { @@ -310,6 +310,11 @@ export const RoomInput = forwardRef( event_id: replyDraft.eventId, }, }; + if (replyDraft.relation?.rel_type === RelationType.Thread) { + content['m.relates_to'].event_id = replyDraft.relation.event_id; + content['m.relates_to'].rel_type = RelationType.Thread; + content['m.relates_to'].is_falling_back = false; + } } mx.sendMessage(roomId, content); resetEditor(editor); @@ -489,22 +494,25 @@ export const RoomInput = forwardRef( > - + {replyDraft.relation?.rel_type === RelationType.Thread && } + + + {getMemberDisplayName(room, replyDraft.userId) ?? + getMxIdLocalPart(replyDraft.userId) ?? + replyDraft.userId} + + + } + > - - {getMemberDisplayName(room, replyDraft.userId) ?? - getMxIdLocalPart(replyDraft.userId) ?? - replyDraft.userId} - + {trimReplyFromBody(replyDraft.body)} - } - > - - {trimReplyFromBody(replyDraft.body)} - - + +
      ) diff --git a/src/app/features/room/RoomTimeline.tsx b/src/app/features/room/RoomTimeline.tsx index 84ce8af18..01ba14f5c 100644 --- a/src/app/features/room/RoomTimeline.tsx +++ b/src/app/features/room/RoomTimeline.tsx @@ -16,6 +16,7 @@ import { EventTimeline, EventTimelineSet, EventTimelineSetHandlerMap, + IContent, IEncryptedFile, MatrixClient, MatrixEvent, @@ -837,13 +838,13 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli markAsRead(mx, room.roomId); }; - const handleOpenReply: MouseEventHandler = useCallback( + const handleOpenReply: MouseEventHandler = useCallback( async (evt) => { - const replyId = evt.currentTarget.getAttribute('data-reply-id'); - if (typeof replyId !== 'string') return; - const replyTimeline = getEventTimeline(room, replyId); + const targetId = evt.currentTarget.getAttribute('data-event-id'); + if (!targetId) return; + const replyTimeline = getEventTimeline(room, targetId); const absoluteIndex = - replyTimeline && getEventIdAbsoluteIndex(timeline.linkedTimelines, replyTimeline, replyId); + replyTimeline && getEventIdAbsoluteIndex(timeline.linkedTimelines, replyTimeline, targetId); if (typeof absoluteIndex === 'number') { scrollToItem(absoluteIndex, { @@ -858,7 +859,7 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli }); } else { setTimeline(getEmptyTimeline()); - loadEventTimeline(replyId); + loadEventTimeline(targetId); } }, [room, timeline, scrollToItem, loadEventTimeline] @@ -909,8 +910,9 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli const replyEvt = room.findEventById(replyId); if (!replyEvt) return; const editedReply = getEditedEvent(replyId, replyEvt, room.getUnfilteredTimelineSet()); - const { body, formatted_body: formattedBody }: Record = - editedReply?.getContent()['m.new_content'] ?? replyEvt.getContent(); + const content: IContent = editedReply?.getContent()['m.new_content'] ?? replyEvt.getContent(); + const { body, formatted_body: formattedBody } = content; + const { 'm.relates_to': relation } = replyEvt.getOriginalContent(); const senderId = replyEvt.getSender(); if (senderId && typeof body === 'string') { setReplyDraft({ @@ -918,6 +920,7 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli eventId: replyId, body, formattedBody, + relation, }); setTimeout(() => ReactEditor.focus(editor), 100); } @@ -969,7 +972,7 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli const reactionRelations = getEventReactions(timelineSet, mEventId); const reactions = reactionRelations && reactionRelations.getSortedAnnotationsByKey(); const hasReactions = reactions && reactions.length > 0; - const { replyEventId } = mEvent; + const { replyEventId, threadRootId } = mEvent; const highlighted = focusItem?.index === item && focusItem.highlight; const editedEvent = getEditedEvent(mEventId, mEvent, timelineSet); @@ -1004,12 +1007,11 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli reply={ replyEventId && ( ) @@ -1050,7 +1052,7 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli const reactionRelations = getEventReactions(timelineSet, mEventId); const reactions = reactionRelations && reactionRelations.getSortedAnnotationsByKey(); const hasReactions = reactions && reactions.length > 0; - const { replyEventId } = mEvent; + const { replyEventId, threadRootId } = mEvent; const highlighted = focusItem?.index === item && focusItem.highlight; return ( @@ -1077,12 +1079,11 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli reply={ replyEventId && ( ) diff --git a/src/app/pages/client/inbox/Notifications.tsx b/src/app/pages/client/inbox/Notifications.tsx index 6a8160d86..aa8782161 100644 --- a/src/app/pages/client/inbox/Notifications.tsx +++ b/src/app/pages/client/inbox/Notifications.tsx @@ -20,6 +20,7 @@ import { IRoomEvent, JoinRule, Method, + RelationType, Room, } from 'matrix-js-sdk'; import { useVirtualizer } from '@tanstack/react-virtual'; @@ -352,7 +353,7 @@ function RoomNotificationsGroupComp({ } ); - const handleOpenClick: MouseEventHandler = (evt) => { + const handleOpenClick: MouseEventHandler = (evt) => { const eventId = evt.currentTarget.getAttribute('data-event-id'); if (!eventId) return; onOpen(room.roomId, eventId); @@ -403,7 +404,10 @@ function RoomNotificationsGroupComp({ const senderAvatarMxc = getMemberAvatarMxc(room, event.sender); const getContent = (() => event.content) as GetContentCallback; - const replyEventId = event.content['m.relates_to']?.['m.in_reply_to']?.event_id; + const relation = event.content['m.relates_to']; + const replyEventId = relation?.['m.in_reply_to']?.event_id; + const threadRootId = + relation?.rel_type === RelationType.Thread ? relation.event_id : undefined; return ( {replyEventId && ( )} diff --git a/src/app/state/room/roomInputDrafts.ts b/src/app/state/room/roomInputDrafts.ts index 60b42fdb7..33bd06076 100644 --- a/src/app/state/room/roomInputDrafts.ts +++ b/src/app/state/room/roomInputDrafts.ts @@ -2,6 +2,7 @@ import { atom } from 'jotai'; import { atomFamily } from 'jotai/utils'; import { Descendant } from 'slate'; import { EncryptedAttachmentInfo } from 'browser-encrypt-attachment'; +import { IEventRelation } from 'matrix-js-sdk'; import { TListAtom, createListAtom } from '../list'; import { createUploadAtomFamily } from '../upload'; import { TUploadContent } from '../../utils/matrix'; @@ -39,7 +40,8 @@ export type IReplyDraft = { userId: string; eventId: string; body: string; - formattedBody?: string; + formattedBody?: string | undefined; + relation?: IEventRelation | undefined; }; const createReplyDraftAtom = () => atom(undefined); export type TReplyDraftAtom = ReturnType; diff --git a/src/app/utils/room.ts b/src/app/utils/room.ts index 750dd6ca7..8cf33a8ff 100644 --- a/src/app/utils/room.ts +++ b/src/app/utils/room.ts @@ -389,13 +389,18 @@ export const getEditedEvent = ( return edits && getLatestEdit(mEvent, edits.getRelations()); }; -export const canEditEvent = (mx: MatrixClient, mEvent: MatrixEvent) => - mEvent.getSender() === mx.getUserId() && - !mEvent.isRelation() && - mEvent.getType() === MessageEvent.RoomMessage && - (mEvent.getContent().msgtype === MsgType.Text || - mEvent.getContent().msgtype === MsgType.Emote || - mEvent.getContent().msgtype === MsgType.Notice); +export const canEditEvent = (mx: MatrixClient, mEvent: MatrixEvent) => { + const content = mEvent.getContent(); + const relationType = content['m.relates_to']?.rel_type; + return ( + mEvent.getSender() === mx.getUserId() && + (!relationType || relationType === RelationType.Thread) && + mEvent.getType() === MessageEvent.RoomMessage && + (content.msgtype === MsgType.Text || + content.msgtype === MsgType.Emote || + content.msgtype === MsgType.Notice) + ); +}; export const getLatestEditableEvt = ( timeline: EventTimeline, From 16be69c104f760e491e36684a48492ef661cd01b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 21 Aug 2024 00:21:25 +1000 Subject: [PATCH 1199/1531] Bump docker/build-push-action from 6.6.1 to 6.7.0 (#1906) Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 6.6.1 to 6.7.0. - [Release notes](https://github.com/docker/build-push-action/releases) - [Commits](https://github.com/docker/build-push-action/compare/v6.6.1...v6.7.0) --- updated-dependencies: - dependency-name: docker/build-push-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/docker-pr.yml | 2 +- .github/workflows/prod-deploy.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docker-pr.yml b/.github/workflows/docker-pr.yml index 827ca66e5..7c67c27a7 100644 --- a/.github/workflows/docker-pr.yml +++ b/.github/workflows/docker-pr.yml @@ -13,7 +13,7 @@ jobs: - name: Checkout repository uses: actions/checkout@v4.1.7 - name: Build Docker image - uses: docker/build-push-action@v6.6.1 + uses: docker/build-push-action@v6.7.0 with: context: . push: false diff --git a/.github/workflows/prod-deploy.yml b/.github/workflows/prod-deploy.yml index d340cb77b..f8f13a7e5 100644 --- a/.github/workflows/prod-deploy.yml +++ b/.github/workflows/prod-deploy.yml @@ -90,7 +90,7 @@ jobs: ${{ secrets.DOCKER_USERNAME }}/cinny ghcr.io/${{ github.repository }} - name: Build and push Docker image - uses: docker/build-push-action@v6.6.1 + uses: docker/build-push-action@v6.7.0 with: context: . platforms: linux/amd64,linux/arm64 From bdba0332e1494c8a71be3d0fe6837238f3d967d5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 21 Aug 2024 00:22:26 +1000 Subject: [PATCH 1200/1531] Bump cla-assistant/github-action from 2.4.0 to 2.5.1 (#1905) Bumps [cla-assistant/github-action](https://github.com/cla-assistant/github-action) from 2.4.0 to 2.5.1. - [Release notes](https://github.com/cla-assistant/github-action/releases) - [Commits](https://github.com/cla-assistant/github-action/compare/v2.4.0...v2.5.1) --- updated-dependencies: - dependency-name: cla-assistant/github-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/cla.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cla.yml b/.github/workflows/cla.yml index 2ad3d1456..655134278 100644 --- a/.github/workflows/cla.yml +++ b/.github/workflows/cla.yml @@ -12,7 +12,7 @@ jobs: - name: 'CLA Assistant' if: (github.event.comment.body == 'recheck' || github.event.comment.body == 'I have read the CLA Document and I hereby sign the CLA') || github.event_name == 'pull_request_target' # Beta Release - uses: cla-assistant/github-action@v2.4.0 + uses: cla-assistant/github-action@v2.5.1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # the below token should have repo scope and must be manually added by you in the repository's secret From 22b7f6dd7d211b9d66b0ff8e237eade9eb473b6e Mon Sep 17 00:00:00 2001 From: Krishan <33421343+kfiven@users.noreply.github.com> Date: Wed, 21 Aug 2024 20:13:40 +1000 Subject: [PATCH 1201/1531] Create Code of Conduct (#1908) --- CODE_OF_CONDUCT.md | 128 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 CODE_OF_CONDUCT.md diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 000000000..f1ef5d468 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,128 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, religion, or sexual identity +and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +* Focusing on what is best not just for us as individuals, but for the + overall community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or + advances of any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email + address, without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at +cinnyapp@gmail.com. +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series +of actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or +permanent ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within +the community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.0, available at +https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. + +Community Impact Guidelines were inspired by [Mozilla's code of conduct +enforcement ladder](https://github.com/mozilla/diversity). + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see the FAQ at +https://www.contributor-covenant.org/faq. Translations are available at +https://www.contributor-covenant.org/translations. From 5c9ee1a988eedf8efa34b7065164f10018002009 Mon Sep 17 00:00:00 2001 From: utf <25370216+utf-4096@users.noreply.github.com> Date: Fri, 23 Aug 2024 12:56:03 +0200 Subject: [PATCH 1202/1531] Fix IPv6 support for the Docker container (#1884) * Fix `docker-nginx.conf` indentation * Listen on IPv4 and IPv6 inside Docker --- docker-nginx.conf | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/docker-nginx.conf b/docker-nginx.conf index 6994b8c85..efe21fac8 100644 --- a/docker-nginx.conf +++ b/docker-nginx.conf @@ -1,8 +1,11 @@ server { - location / { - root /usr/share/nginx/html; + listen 80; + listen [::]:80; - rewrite ^/config.json$ /config.json break; + location / { + root /usr/share/nginx/html; + + rewrite ^/config.json$ /config.json break; rewrite ^/manifest.json$ /manifest.json break; rewrite ^.*/olm.wasm$ /olm.wasm break; @@ -12,5 +15,5 @@ server { rewrite ^/assets/(.*)$ /assets/$1 break; rewrite ^(.+)$ /index.html break; - } -} \ No newline at end of file + } +} From 043012e809a262a9453f1c81dddee183407ddf01 Mon Sep 17 00:00:00 2001 From: Dylan Hackworth Date: Sat, 7 Sep 2024 08:08:16 -0500 Subject: [PATCH 1203/1531] pressing up to edit should take you to end of line (#1928) --- src/app/features/room/RoomTimeline.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/app/features/room/RoomTimeline.tsx b/src/app/features/room/RoomTimeline.tsx index 01ba14f5c..d86ea4d96 100644 --- a/src/app/features/room/RoomTimeline.tsx +++ b/src/app/features/room/RoomTimeline.tsx @@ -726,6 +726,7 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli const editableEvtId = editableEvt?.getId(); if (!editableEvtId) return; setEditId(editableEvtId); + evt.preventDefault() } }, [mx, room, editor] From c6a8fb1117d2ec52545d96f8a2fa7e291d8aada5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=9C=E5=9D=82=E9=9B=85?= <23130178+ShadowRZ@users.noreply.github.com> Date: Sat, 7 Sep 2024 21:45:55 +0800 Subject: [PATCH 1204/1531] Add authenticated media support (#1930) * chore: Bump matrix-js-sdk to 34.4.0 * feat: Authenticated media support * chore: Use Vite PWA for service worker support * fix: Fix Vite PWA SW entry point Forget this. :P * fix: Also add Nginx rewrite for sw.js * fix: Correct Nginx rewrite * fix: Add Netlify redirect for sw.js Otherwise the generic SPA rewrite to index.html would take effect, breaking Service Worker. * fix: Account for subpath when regisering service worker * chore: Correct types --- .npmrc | 3 +- contrib/nginx/cinny.domain.tld.conf | 1 + docker-nginx.conf | 1 + netlify.toml | 7 +- package-lock.json | 3365 +++++++++++++++-- package.json | 6 +- src/app/components/editor/Elements.tsx | 6 +- .../autocomplete/EmoticonAutocomplete.tsx | 6 +- .../autocomplete/UserMentionAutocomplete.tsx | 6 +- src/app/components/emoji-board/EmojiBoard.tsx | 115 +- .../components/event-readers/EventReaders.tsx | 8 +- src/app/components/message/Reaction.tsx | 8 +- .../message/content/AudioContent.tsx | 8 +- .../message/content/FileContent.tsx | 20 +- .../message/content/ImageContent.tsx | 8 +- .../message/content/ThumbnailContent.tsx | 8 +- .../message/content/VideoContent.tsx | 8 +- src/app/components/room-card/RoomCard.tsx | 9 +- src/app/components/room-intro/RoomIntro.tsx | 7 +- .../components/url-preview/UrlPreviewCard.tsx | 6 +- src/app/features/lobby/LobbyHeader.tsx | 6 +- src/app/features/lobby/LobbyHero.tsx | 6 +- src/app/features/lobby/RoomItem.tsx | 10 +- src/app/features/lobby/SpaceItem.tsx | 10 +- .../message-search/SearchResultGroup.tsx | 12 +- src/app/features/room-nav/RoomNavItem.tsx | 5 +- src/app/features/room/MembersDrawer.tsx | 18 +- src/app/features/room/RoomInput.tsx | 7 +- src/app/features/room/RoomTimeline.tsx | 43 +- src/app/features/room/RoomViewHeader.tsx | 7 +- src/app/features/room/message/Message.tsx | 93 +- src/app/features/room/message/Reactions.tsx | 4 + .../room/reaction-viewer/ReactionViewer.tsx | 14 +- src/app/pages/client/ClientNonUIFeatures.tsx | 7 +- src/app/pages/client/inbox/Invites.tsx | 5 +- src/app/pages/client/inbox/Notifications.tsx | 12 +- src/app/pages/client/sidebar/SpaceTabs.tsx | 40 +- src/app/pages/client/sidebar/UserTab.tsx | 7 +- src/app/plugins/react-custom-html-parser.tsx | 10 +- src/app/utils/matrix.ts | 20 + src/app/utils/room.ts | 22 +- src/client/initMatrix.ts | 2 +- src/index.tsx | 18 + src/sw.ts | 43 + tsconfig.json | 3 +- vite.config.js | 19 +- 46 files changed, 3562 insertions(+), 487 deletions(-) create mode 100644 src/sw.ts diff --git a/.npmrc b/.npmrc index 8833acbad..e28ce002f 100644 --- a/.npmrc +++ b/.npmrc @@ -1,3 +1,2 @@ legacy-peer-deps=true -save-exact=true -@matrix-org:registry=https://gitlab.matrix.org/api/v4/projects/27/packages/npm/ \ No newline at end of file +save-exact=true \ No newline at end of file diff --git a/contrib/nginx/cinny.domain.tld.conf b/contrib/nginx/cinny.domain.tld.conf index 360302c0b..0ba70f7ee 100644 --- a/contrib/nginx/cinny.domain.tld.conf +++ b/contrib/nginx/cinny.domain.tld.conf @@ -24,6 +24,7 @@ server { rewrite ^/manifest.json$ /manifest.json break; rewrite ^.*/olm.wasm$ /olm.wasm break; + rewrite ^/sw.js$ /sw.js break; rewrite ^/pdf.worker.min.js$ /pdf.worker.min.js break; rewrite ^/public/(.*)$ /public/$1 break; diff --git a/docker-nginx.conf b/docker-nginx.conf index efe21fac8..fca107466 100644 --- a/docker-nginx.conf +++ b/docker-nginx.conf @@ -9,6 +9,7 @@ server { rewrite ^/manifest.json$ /manifest.json break; rewrite ^.*/olm.wasm$ /olm.wasm break; + rewrite ^/sw.js$ /sw.js break; rewrite ^/pdf.worker.min.js$ /pdf.worker.min.js break; rewrite ^/public/(.*)$ /public/$1 break; diff --git a/netlify.toml b/netlify.toml index d79aa91c3..1b192beca 100644 --- a/netlify.toml +++ b/netlify.toml @@ -7,7 +7,12 @@ from = "/manifest.json" to = "/manifest.json" status = 200 - + +[[redirects]] + from = "/sw.js" + to = "/sw.js" + status = 200 + [[redirects]] from = "*/olm.wasm" to = "/olm.wasm" diff --git a/package-lock.json b/package-lock.json index 061d3ded0..1dcff435b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,7 +13,7 @@ "@atlaskit/pragmatic-drag-and-drop-auto-scroll": "1.3.0", "@atlaskit/pragmatic-drag-and-drop-hitbox": "1.0.3", "@fontsource/inter": "4.5.14", - "@matrix-org/olm": "3.2.14", + "@matrix-org/olm": "3.2.15", "@tanstack/react-query": "5.24.1", "@tanstack/react-query-devtools": "5.24.1", "@tanstack/react-virtual": "3.2.0", @@ -45,7 +45,7 @@ "jotai": "2.6.0", "linkify-react": "4.1.3", "linkifyjs": "4.1.3", - "matrix-js-sdk": "29.1.0", + "matrix-js-sdk": "34.4.0", "millify": "6.1.0", "pdfjs-dist": "4.2.67", "prismjs": "1.29.0", @@ -79,6 +79,7 @@ "@types/react-dom": "18.2.17", "@types/react-google-recaptcha": "2.1.8", "@types/sanitize-html": "2.9.0", + "@types/serviceworker": "0.0.95", "@types/ua-parser-js": "0.7.36", "@typescript-eslint/eslint-plugin": "5.46.1", "@typescript-eslint/parser": "5.46.1", @@ -95,6 +96,7 @@ "sass": "1.56.2", "typescript": "4.9.4", "vite": "5.0.13", + "vite-plugin-pwa": "0.20.5", "vite-plugin-static-copy": "1.0.4", "vite-plugin-top-level-await": "1.4.1" }, @@ -114,6 +116,24 @@ "node": ">=6.0.0" } }, + "node_modules/@apideck/better-ajv-errors": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@apideck/better-ajv-errors/-/better-ajv-errors-0.3.6.tgz", + "integrity": "sha512-P+ZygBLZtkp0qqOAJJVX4oX/sFo5JR3eBWwwuqHHhK0GIgQOKWrAfiAaWX0aArHkRWHMuggFEgAZNxVPwPZYaA==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-schema": "^0.4.0", + "jsonpointer": "^5.0.0", + "leven": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "ajv": ">=8" + } + }, "node_modules/@atlaskit/pragmatic-drag-and-drop": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/@atlaskit/pragmatic-drag-and-drop/-/pragmatic-drag-and-drop-1.1.6.tgz", @@ -143,40 +163,43 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.4.tgz", - "integrity": "sha512-r1IONyb6Ia+jYR2vvIDhdWdlTGhqbBoFqLTQidzZ4kepUFH15ejXvFHxCVbtl7BOXIudsIubf4E81xeA3h3IXA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", + "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", + "license": "MIT", "dependencies": { - "@babel/highlight": "^7.23.4", - "chalk": "^2.4.2" + "@babel/highlight": "^7.24.7", + "picocolors": "^1.0.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/compat-data": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.3.tgz", - "integrity": "sha512-BmR4bWbDIoFJmJ9z2cZ8Gmm2MXgEDgjdWgpKmKWUt54UGFJdlj31ECtbaDvCG/qVdG3AQ1SfpZEs01lUFbzLOQ==", + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.4.tgz", + "integrity": "sha512-+LGRog6RAsCJrrrg/IO6LGmpphNe5DiK30dGjCoxxeGv49B10/3XYGxPsAwrDlMFcFEvdAUavDT8r9k/hSyQqQ==", + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.3.tgz", - "integrity": "sha512-Jg+msLuNuCJDyBvFv5+OKOUjWMZgd85bKjbICd3zWrKAo+bJ49HJufi7CQE0q0uR8NGyO6xkCACScNqyjHSZew==", + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.25.2.tgz", + "integrity": "sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==", + "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.22.13", - "@babel/generator": "^7.23.3", - "@babel/helper-compilation-targets": "^7.22.15", - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helpers": "^7.23.2", - "@babel/parser": "^7.23.3", - "@babel/template": "^7.22.15", - "@babel/traverse": "^7.23.3", - "@babel/types": "^7.23.3", + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.25.0", + "@babel/helper-compilation-targets": "^7.25.2", + "@babel/helper-module-transforms": "^7.25.2", + "@babel/helpers": "^7.25.0", + "@babel/parser": "^7.25.0", + "@babel/template": "^7.25.0", + "@babel/traverse": "^7.25.2", + "@babel/types": "^7.25.2", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -192,13 +215,14 @@ } }, "node_modules/@babel/generator": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.4.tgz", - "integrity": "sha512-esuS49Cga3HcThFNebGhlgsrVLkvhqvYDTzgjfFFlHJcIfLe5jFmRRfCQ1KuBfc4Jrtn3ndLgKWAKjBE+IraYQ==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.6.tgz", + "integrity": "sha512-VPC82gr1seXOpkjAAKoLhP50vx4vGNlF4msF64dSFq1P8RfB+QAuJWGHPXXPc8QyfVWwwB/TNNU4+ayZmHNbZw==", + "license": "MIT", "dependencies": { - "@babel/types": "^7.23.4", - "@jridgewell/gen-mapping": "^0.3.2", - "@jridgewell/trace-mapping": "^0.3.17", + "@babel/types": "^7.25.6", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^2.5.1" }, "engines": { @@ -206,26 +230,55 @@ } }, "node_modules/@babel/generator/node_modules/@jridgewell/gen-mapping": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", - "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "license": "MIT", "dependencies": { - "@jridgewell/set-array": "^1.0.1", + "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/trace-mapping": "^0.3.24" }, "engines": { "node": ">=6.0.0" } }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz", - "integrity": "sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==", + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz", + "integrity": "sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==", + "dev": true, + "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.22.9", - "@babel/helper-validator-option": "^7.22.15", - "browserslist": "^4.21.9", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.24.7.tgz", + "integrity": "sha512-xZeCVVdwb4MsDBkkyZ64tReWYrLRHlMN72vP7Bdm3OUOuyFZExhsHUUnuWnm2/XOlAJzR0LfPpB56WXZn0X/lA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.2.tgz", + "integrity": "sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw==", + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.25.2", + "@babel/helper-validator-option": "^7.24.8", + "browserslist": "^4.23.1", "lru-cache": "^5.1.1", "semver": "^6.3.1" }, @@ -237,6 +290,7 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "license": "ISC", "dependencies": { "yallist": "^3.0.2" } @@ -244,60 +298,23 @@ "node_modules/@babel/helper-compilation-targets/node_modules/yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "license": "ISC" }, - "node_modules/@babel/helper-environment-visitor": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", - "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-function-name": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", - "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.4.tgz", + "integrity": "sha512-ro/bFs3/84MDgDmMwbcHgDa8/E6J3QKNTk4xJJnVeFtGE+tL0K26E3pNxhYz2b67fJpt7Aphw5XcploKXuCvCQ==", + "dev": true, + "license": "MIT", "dependencies": { - "@babel/template": "^7.22.15", - "@babel/types": "^7.23.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", - "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-imports": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", - "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", - "dependencies": { - "@babel/types": "^7.22.15" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", - "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", - "dependencies": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-module-imports": "^7.22.15", - "@babel/helper-simple-access": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/helper-validator-identifier": "^7.22.20" + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-member-expression-to-functions": "^7.24.8", + "@babel/helper-optimise-call-expression": "^7.24.7", + "@babel/helper-replace-supers": "^7.25.0", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", + "@babel/traverse": "^7.25.4", + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" @@ -306,90 +323,249 @@ "@babel/core": "^7.0.0" } }, - "node_modules/@babel/helper-plugin-utils": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", - "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.25.2.tgz", + "integrity": "sha512-+wqVGP+DFmqwFD3EH6TMTfUNeqDehV3E/dl+Sd54eaXqm17tEUNbEIn4sVivVowbvUpOtIGxdo3GoXyDH9N/9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "regexpu-core": "^5.3.1", + "semver": "^6.3.1" + }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "node_modules/@babel/helper-simple-access": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", - "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.2.tgz", + "integrity": "sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ==", + "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.22.5" + "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-plugin-utils": "^7.22.5", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.8.tgz", + "integrity": "sha512-LABppdt+Lp/RlBxqrh4qgf1oEH/WxdzQNDJIu5gC/W1GyvPVrOBiItmmM8wan2fm4oYqFuFfkXmlGpLQhPY8CA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.24.8", + "@babel/types": "^7.24.8" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", - "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "node_modules/@babel/helper-module-imports": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", + "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", + "license": "MIT", "dependencies": { - "@babel/types": "^7.22.5" + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.25.2.tgz", + "integrity": "sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-simple-access": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7", + "@babel/traverse": "^7.25.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.24.7.tgz", + "integrity": "sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz", + "integrity": "sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.25.0.tgz", + "integrity": "sha512-NhavI2eWEIz/H9dbrG0TuOicDhNexze43i5z7lEqwYm0WEZVTwnPpA0EafUTP7+6/W79HWIP2cTe3Z5NiSTVpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-wrap-function": "^7.25.0", + "@babel/traverse": "^7.25.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.25.0.tgz", + "integrity": "sha512-q688zIvQVYtZu+i2PsdIu/uWGRpfxzr5WESsfpShfZECkO+d2o+WROWezCi/Q6kJ0tfPa5+pUGUlfx2HhrA3Bg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-member-expression-to-functions": "^7.24.8", + "@babel/helper-optimise-call-expression": "^7.24.7", + "@babel/traverse": "^7.25.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", + "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.24.7.tgz", + "integrity": "sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-string-parser": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", - "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz", + "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==", + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", - "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz", - "integrity": "sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz", + "integrity": "sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.25.0.tgz", + "integrity": "sha512-s6Q1ebqutSiZnEjaofc/UKDyC4SbzV5n5SrA2Gq8UawLycr3i04f1dX4OzoQVnexm6aOCh37SQNYlJ/8Ku+PMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.25.0", + "@babel/traverse": "^7.25.0", + "@babel/types": "^7.25.0" + }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.4.tgz", - "integrity": "sha512-HfcMizYz10cr3h29VqyfGL6ZWIjTwWfvYBMsBVGwpcbhNGe3wQ1ZXZRPzZoAHhd9OqHadHqjQ89iVKINXnbzuw==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.6.tgz", + "integrity": "sha512-Xg0tn4HcfTijTwfDwYlvVCl43V6h4KyVVX2aEm4qdO/PC6L2YvzLHFdmxhoeSA3eslcE6+ZVXHgWwopXYLNq4Q==", + "license": "MIT", "dependencies": { - "@babel/template": "^7.22.15", - "@babel/traverse": "^7.23.4", - "@babel/types": "^7.23.4" + "@babel/template": "^7.25.0", + "@babel/types": "^7.25.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", - "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", + "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", + "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.22.20", + "@babel/helper-validator-identifier": "^7.24.7", "chalk": "^2.4.2", - "js-tokens": "^4.0.0" + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/parser": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.4.tgz", - "integrity": "sha512-vf3Xna6UEprW+7t6EtOmFpHNAuxw3xqPZghy+brsnusscJRW5BMUzzHZc5ICjULee81WeUV2jjakG09MDglJXQ==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.6.tgz", + "integrity": "sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.25.6" + }, "bin": { "parser": "bin/babel-parser.js" }, @@ -397,6 +573,339 @@ "node": ">=6.0.0" } }, + "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { + "version": "7.25.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.3.tgz", + "integrity": "sha512-wUrcsxZg6rqBXG05HG1FPYgsP6EvwF4WpBbxIpWIIYnH8wG0gzx3yZY3dtEHas4sTAOGkbTsc9EGPxwff8lRoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/traverse": "^7.25.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.25.0.tgz", + "integrity": "sha512-Bm4bH2qsX880b/3ziJ8KD711LT7z4u8CFudmjqle65AZj/HNUFhEf90dqYv6O86buWvSBmeQDjv0Tn2aF/bIBA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.25.0.tgz", + "integrity": "sha512-lXwdNZtTmeVOOFtwM/WDe7yg1PL8sYhRk/XH0FzbR2HDQ0xC+EnQ/JHeoMYSavtU115tnUk0q9CDyq8si+LMAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.24.7.tgz", + "integrity": "sha512-+izXIbke1T33mY4MSNnrqhPXDz01WYhEf3yF5NbnUtkiNnm+XBZJl3kNfoK6NKmYlz/D07+l2GWVK/QfDkNCuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", + "@babel/plugin-transform-optional-chaining": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.25.0.tgz", + "integrity": "sha512-tggFrk1AIShG/RUQbEwt2Tr/E+ObkfwrPjR6BjbRvsx24+PSjK8zrq0GWPNCjo8qpRx4DuJzlcvWJqlm+0h3kw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/traverse": "^7.25.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.0-placeholder-for-preset-env.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-export-namespace-from": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", + "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-assertions": { + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.25.6.tgz", + "integrity": "sha512-aABl0jHw9bZ2karQ/uUD6XP4u0SG22SJrOHFoL6XB1R7dTovOP4TzTlsxOYC5yQ1pdscVK2JTUnF6QL3ARoAiQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.25.6.tgz", + "integrity": "sha512-sXaDXaJN9SNLymBdlWFA+bjzBhFD617ZaFiY13dGt7TVslVvVgA6fkZOP7Ki3IGElC45lwHdOTrCtKZGVAWeLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/plugin-syntax-typescript": { "version": "7.20.0", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.20.0.tgz", @@ -411,6 +920,676 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-syntax-unicode-sets-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", + "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.24.7.tgz", + "integrity": "sha512-Dt9LQs6iEY++gXUwY03DNFat5C2NbO48jj+j/bSAz6b3HgPs39qcPiYt77fDObIcFwj3/C2ICX9YMwGflUoSHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-generator-functions": { + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.4.tgz", + "integrity": "sha512-jz8cV2XDDTqjKPwVPJBIjORVEmSGYhdRa8e5k5+vN+uwcjSrSxUaebBRa4ko1jqNF2uxyg8G6XYk30Jv285xzg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/helper-remap-async-to-generator": "^7.25.0", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/traverse": "^7.25.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.24.7.tgz", + "integrity": "sha512-SQY01PcJfmQ+4Ash7NE+rpbLFbmqA2GPIgqzxfFTL4t1FKRq4zTms/7htKpoCUI9OcFYgzqfmCdH53s6/jn5fA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-remap-async-to-generator": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.24.7.tgz", + "integrity": "sha512-yO7RAz6EsVQDaBH18IDJcMB1HnrUn2FJ/Jslc/WtPPWcjhpUJXU/rjbwmluzp7v/ZzWcEhTMXELnnsz8djWDwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.25.0.tgz", + "integrity": "sha512-yBQjYoOjXlFv9nlXb3f1casSHOZkWr29NX+zChVanLg5Nc157CrbEX9D7hxxtTpuFy7Q0YzmmWfJxzvps4kXrQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-properties": { + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.25.4.tgz", + "integrity": "sha512-nZeZHyCWPfjkdU5pA/uHiTaDAFUEqkpzf1YoQT2NeSynCGYq9rxfyI3XpQbfx/a0hSnFH6TGlEXvae5Vi7GD8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.25.4", + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-static-block": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.24.7.tgz", + "integrity": "sha512-HMXK3WbBPpZQufbMG4B46A90PkuuhN9vBCb5T8+VAHqvAqvcLi+2cKoukcpmUYkszLhScU3l1iudhrks3DggRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-class-static-block": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, + "node_modules/@babel/plugin-transform-classes": { + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.4.tgz", + "integrity": "sha512-oexUfaQle2pF/b6E0dwsxQtAol9TLSO88kQvym6HHBWFliV2lGdrPieX+WgMRLSJDVzdYywk7jXbLPuO2KLTLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-compilation-targets": "^7.25.2", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/helper-replace-supers": "^7.25.0", + "@babel/traverse": "^7.25.4", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.24.7.tgz", + "integrity": "sha512-25cS7v+707Gu6Ds2oY6tCkUwsJ9YIDbggd9+cu9jzzDgiNq7hR/8dkzxWfKWnTic26vsI3EsCXNd4iEB6e8esQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/template": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.8.tgz", + "integrity": "sha512-36e87mfY8TnRxc7yc6M9g9gOB7rKgSahqkIKwLpz4Ppk2+zC2Cy1is0uwtuSG6AE4zlTOUa+7JGz9jCJGLqQFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.24.7.tgz", + "integrity": "sha512-ZOA3W+1RRTSWvyqcMJDLqbchh7U4NRGqwRfFSVbOLS/ePIP4vHB5e8T8eXcuqyN1QkgKyj5wuW0lcS85v4CrSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.24.7.tgz", + "integrity": "sha512-JdYfXyCRihAe46jUIliuL2/s0x0wObgwwiGxw/UbgJBr20gQBThrokO4nYKgWkD7uBaqM7+9x5TU7NkExZJyzw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.25.0.tgz", + "integrity": "sha512-YLpb4LlYSc3sCUa35un84poXoraOiQucUTTu8X1j18JV+gNa8E0nyUf/CjZ171IRGr4jEguF+vzJU66QZhn29g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.0", + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-dynamic-import": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.24.7.tgz", + "integrity": "sha512-sc3X26PhZQDb3JhORmakcbvkeInvxz+A8oda99lj7J60QRuPZvNAk9wQlTBS1ZynelDrDmTU4pw1tyc5d5ZMUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.24.7.tgz", + "integrity": "sha512-Rqe/vSc9OYgDajNIK35u7ot+KeCoetqQYFXM4Epf7M7ez3lWlOjrDjrwMei6caCVhfdw+mIKD4cgdGNy5JQotQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-export-namespace-from": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.24.7.tgz", + "integrity": "sha512-v0K9uNYsPL3oXZ/7F9NNIbAj2jv1whUEtyA6aujhekLs56R++JDQuzRcP2/z4WX5Vg/c5lE9uWZA0/iUoFhLTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.24.7.tgz", + "integrity": "sha512-wo9ogrDG1ITTTBsy46oGiN1dS9A7MROBTcYsfS8DtsImMkHk9JXJ3EWQM6X2SUw4x80uGPlwj0o00Uoc6nEE3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.25.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.25.1.tgz", + "integrity": "sha512-TVVJVdW9RKMNgJJlLtHsKDTydjZAbwIsn6ySBPQaEAUU5+gVvlJt/9nRmqVbsV/IBanRjzWoaAQKLoamWVOUuA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.24.8", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/traverse": "^7.25.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-json-strings": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.24.7.tgz", + "integrity": "sha512-2yFnBGDvRuxAaE/f0vfBKvtnvvqU8tGpMHqMNpTN2oWMKIR3NqFkjaAgGwawhqK/pIN2T3XdjGPdaG0vDhOBGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-json-strings": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-literals": { + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.25.2.tgz", + "integrity": "sha512-HQI+HcTbm9ur3Z2DkO+jgESMAMcYLuN/A7NRw9juzxAezN9AvqvUTnpKP/9kkYANz6u7dFlAyOu44ejuGySlfw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-logical-assignment-operators": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.24.7.tgz", + "integrity": "sha512-4D2tpwlQ1odXmTEIFWy9ELJcZHqrStlzK/dAOWYyxX3zT0iXQB6banjgeOJQXzEc4S0E0a5A+hahxPaEFYftsw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.24.7.tgz", + "integrity": "sha512-T/hRC1uqrzXMKLQ6UCwMT85S3EvqaBXDGf0FaMf4446Qx9vKwlghvee0+uuZcDUCZU5RuNi4781UQ7R308zzBw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.24.7.tgz", + "integrity": "sha512-9+pB1qxV3vs/8Hdmz/CulFB8w2tuu6EB94JZFsjdqxQokwGa9Unap7Bo2gGBGIvPmDIVvQrom7r5m/TCDMURhg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.8.tgz", + "integrity": "sha512-WHsk9H8XxRs3JXKWFiqtQebdh9b/pTk4EgueygFzYlTKAg0Ud985mSevdNjdXdFBATSKVJGQXP1tv6aGbssLKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.24.8", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/helper-simple-access": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.25.0.tgz", + "integrity": "sha512-YPJfjQPDXxyQWg/0+jHKj1llnY5f/R6a0p/vP4lPymxLu7Lvl4k2WMitqi08yxwQcCVUUdG9LCUj4TNEgAp3Jw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.25.0", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/helper-validator-identifier": "^7.24.7", + "@babel/traverse": "^7.25.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.24.7.tgz", + "integrity": "sha512-3aytQvqJ/h9z4g8AsKPLvD4Zqi2qT+L3j7XoFFu1XBlZWEl2/1kWnhmAbxpLgPrHSY0M6UA02jyTiwUVtiKR6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.24.7.tgz", + "integrity": "sha512-/jr7h/EWeJtk1U/uz2jlsCioHkZk1JJZVcc8oQsJ1dUlaJD83f4/6Zeh2aHt9BIFokHIsSeDfhUmju0+1GPd6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.24.7.tgz", + "integrity": "sha512-RNKwfRIXg4Ls/8mMTza5oPF5RkOW8Wy/WgMAp1/F1yZ8mMbtwXW+HDoJiOsagWrAhI5f57Vncrmr9XeT4CVapA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.24.7.tgz", + "integrity": "sha512-Ts7xQVk1OEocqzm8rHMXHlxvsfZ0cEF2yomUqpKENHWMF4zKk175Y4q8H5knJes6PgYad50uuRmt3UJuhBw8pQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-numeric-separator": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.24.7.tgz", + "integrity": "sha512-e6q1TiVUzvH9KRvicuxdBTUj4AdKSRwzIyFFnfnezpCfP2/7Qmbb8qbU2j7GODbl4JMkblitCQjKYUaX/qkkwA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-rest-spread": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.7.tgz", + "integrity": "sha512-4QrHAr0aXQCEFni2q4DqKLD31n2DL+RxcwnNjDFkSG0eNQ/xCavnRkfCUjsyqGC2OviNJvZOF/mQqZBw7i2C5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.24.7.tgz", + "integrity": "sha512-A/vVLwN6lBrMFmMDmPPz0jnE6ZGx7Jq7d6sT/Ev4H65RER6pZ+kczlf1DthF5N0qaPHBsI7UXiE8Zy66nmAovg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-replace-supers": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-catch-binding": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.24.7.tgz", + "integrity": "sha512-uLEndKqP5BfBbC/5jTwPxLh9kqPWWgzN/f8w6UwAIirAEqiIVJWWY312X72Eub09g5KF9+Zn7+hT7sDxmhRuKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.8.tgz", + "integrity": "sha512-5cTOLSMs9eypEy8JUVvIKOu6NgvbJMnpG62VpIHrTmROdQ+L5mDAaI40g25k5vXti55JWNX5jCkq3HZxXBQANw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.7.tgz", + "integrity": "sha512-yGWW5Rr+sQOhK0Ot8hjDJuxU3XLRQGflvT4lhlSY0DFvdb3TwKaY26CJzHtYllU0vT9j58hc37ndFPsqT1SrzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-methods": { + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.25.4.tgz", + "integrity": "sha512-ao8BG7E2b/URaUQGqN3Tlsg+M3KlHY6rJ1O1gXAEUnZoyNQnvKyH87Kfg+FoxSeyWUB8ISZZsC91C44ZuBFytw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.25.4", + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-property-in-object": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.24.7.tgz", + "integrity": "sha512-9z76mxwnwFxMyxZWEgdgECQglF2Q7cFLm0kMf8pGwt+GSJsY0cONKj/UuO4bOH0w/uAel3ekS4ra5CEAyJRmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-create-class-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.24.7.tgz", + "integrity": "sha512-EMi4MLQSHfd2nrCqQEWxFdha2gBCqU4ZcCng4WBGZ5CJL4bBRW0ptdqqDdeirGZcpALazVVNJqRmsO8/+oNCBA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/plugin-transform-react-jsx-self": { "version": "7.23.3", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.23.3.tgz", @@ -441,6 +1620,307 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.24.7.tgz", + "integrity": "sha512-lq3fvXPdimDrlg6LWBoqj+r/DEWgONuwjuOuQCSYgRroXDH/IdM1C0IZf59fL5cHLpjEH/O6opIRBbqv7ELnuA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "regenerator-transform": "^0.15.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.24.7.tgz", + "integrity": "sha512-0DUq0pHcPKbjFZCfTss/pGkYMfy3vFWydkUBd9r0GHpIyfs2eCDENvqadMycRS9wZCXR41wucAfJHJmwA0UmoQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.24.7.tgz", + "integrity": "sha512-KsDsevZMDsigzbA09+vacnLpmPH4aWjcZjXdyFKGzpplxhbeB4wYtury3vglQkg6KM/xEPKt73eCjPPf1PgXBA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-spread": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.24.7.tgz", + "integrity": "sha512-x96oO0I09dgMDxJaANcRyD4ellXFLLiWhuwDxKZX5g2rWP1bTPkBSwCYv96VDXVT1bD9aPj8tppr5ITIh8hBng==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.24.7.tgz", + "integrity": "sha512-kHPSIJc9v24zEml5geKg9Mjx5ULpfncj0wRpYtxbvKyTtHCYDkVE3aHQ03FrpEo4gEe2vrJJS1Y9CJTaThA52g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.24.7.tgz", + "integrity": "sha512-AfDTQmClklHCOLxtGoP7HkeMw56k1/bTQjwsfhL6pppo/M4TOBSq+jjBUBLmV/4oeFg4GWMavIl44ZeCtmmZTw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.8.tgz", + "integrity": "sha512-adNTUpDCVnmAE58VEqKlAA6ZBlNkMnWD0ZcW76lyNFN3MJniyGFZfNwERVk8Ap56MCnXztmDr19T4mPTztcuaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.24.7.tgz", + "integrity": "sha512-U3ap1gm5+4edc2Q/P+9VrBNhGkfnf+8ZqppY71Bo/pzZmXhhLdqgaUl6cuB07O1+AQJtCLfaOmswiNbSQ9ivhw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-property-regex": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.24.7.tgz", + "integrity": "sha512-uH2O4OV5M9FZYQrwc7NdVmMxQJOCCzFeYudlZSzUAHRFeOujQefa92E74TQDVskNHCzOXoigEuoyzHDhaEaK5w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.24.7.tgz", + "integrity": "sha512-hlQ96MBZSAXUq7ltkjtu3FJCCSMx/j629ns3hA3pXnBXjanNP0LHi+JpPeA81zaWgVK1VGH95Xuy7u0RyQ8kMg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-sets-regex": { + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.25.4.tgz", + "integrity": "sha512-qesBxiWkgN1Q+31xUE9RcMk79eOXXDCv6tfyGMRSs4RGlioSg2WVyQAm07k726cSE56pa+Kb0y9epX2qaXzTvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.2", + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/preset-env": { + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.25.4.tgz", + "integrity": "sha512-W9Gyo+KmcxjGahtt3t9fb14vFRWvPpu5pT6GBlovAK6BTBcxgjfVMSQCfJl4oi35ODrxP6xx2Wr8LNST57Mraw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.25.4", + "@babel/helper-compilation-targets": "^7.25.2", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/helper-validator-option": "^7.24.8", + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.25.3", + "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.25.0", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.25.0", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.24.7", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.25.0", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3", + "@babel/plugin-syntax-import-assertions": "^7.24.7", + "@babel/plugin-syntax-import-attributes": "^7.24.7", + "@babel/plugin-syntax-import-meta": "^7.10.4", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5", + "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.24.7", + "@babel/plugin-transform-async-generator-functions": "^7.25.4", + "@babel/plugin-transform-async-to-generator": "^7.24.7", + "@babel/plugin-transform-block-scoped-functions": "^7.24.7", + "@babel/plugin-transform-block-scoping": "^7.25.0", + "@babel/plugin-transform-class-properties": "^7.25.4", + "@babel/plugin-transform-class-static-block": "^7.24.7", + "@babel/plugin-transform-classes": "^7.25.4", + "@babel/plugin-transform-computed-properties": "^7.24.7", + "@babel/plugin-transform-destructuring": "^7.24.8", + "@babel/plugin-transform-dotall-regex": "^7.24.7", + "@babel/plugin-transform-duplicate-keys": "^7.24.7", + "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.25.0", + "@babel/plugin-transform-dynamic-import": "^7.24.7", + "@babel/plugin-transform-exponentiation-operator": "^7.24.7", + "@babel/plugin-transform-export-namespace-from": "^7.24.7", + "@babel/plugin-transform-for-of": "^7.24.7", + "@babel/plugin-transform-function-name": "^7.25.1", + "@babel/plugin-transform-json-strings": "^7.24.7", + "@babel/plugin-transform-literals": "^7.25.2", + "@babel/plugin-transform-logical-assignment-operators": "^7.24.7", + "@babel/plugin-transform-member-expression-literals": "^7.24.7", + "@babel/plugin-transform-modules-amd": "^7.24.7", + "@babel/plugin-transform-modules-commonjs": "^7.24.8", + "@babel/plugin-transform-modules-systemjs": "^7.25.0", + "@babel/plugin-transform-modules-umd": "^7.24.7", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.24.7", + "@babel/plugin-transform-new-target": "^7.24.7", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.24.7", + "@babel/plugin-transform-numeric-separator": "^7.24.7", + "@babel/plugin-transform-object-rest-spread": "^7.24.7", + "@babel/plugin-transform-object-super": "^7.24.7", + "@babel/plugin-transform-optional-catch-binding": "^7.24.7", + "@babel/plugin-transform-optional-chaining": "^7.24.8", + "@babel/plugin-transform-parameters": "^7.24.7", + "@babel/plugin-transform-private-methods": "^7.25.4", + "@babel/plugin-transform-private-property-in-object": "^7.24.7", + "@babel/plugin-transform-property-literals": "^7.24.7", + "@babel/plugin-transform-regenerator": "^7.24.7", + "@babel/plugin-transform-reserved-words": "^7.24.7", + "@babel/plugin-transform-shorthand-properties": "^7.24.7", + "@babel/plugin-transform-spread": "^7.24.7", + "@babel/plugin-transform-sticky-regex": "^7.24.7", + "@babel/plugin-transform-template-literals": "^7.24.7", + "@babel/plugin-transform-typeof-symbol": "^7.24.8", + "@babel/plugin-transform-unicode-escapes": "^7.24.7", + "@babel/plugin-transform-unicode-property-regex": "^7.24.7", + "@babel/plugin-transform-unicode-regex": "^7.24.7", + "@babel/plugin-transform-unicode-sets-regex": "^7.25.4", + "@babel/preset-modules": "0.1.6-no-external-plugins", + "babel-plugin-polyfill-corejs2": "^0.4.10", + "babel-plugin-polyfill-corejs3": "^0.10.6", + "babel-plugin-polyfill-regenerator": "^0.6.1", + "core-js-compat": "^3.37.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-modules": { + "version": "0.1.6-no-external-plugins", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", + "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==", + "dev": true, + "license": "MIT" + }, "node_modules/@babel/runtime": { "version": "7.25.0", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.0.tgz", @@ -473,32 +1953,31 @@ "dev": true }, "node_modules/@babel/template": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", - "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.0.tgz", + "integrity": "sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==", + "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.22.13", - "@babel/parser": "^7.22.15", - "@babel/types": "^7.22.15" + "@babel/code-frame": "^7.24.7", + "@babel/parser": "^7.25.0", + "@babel/types": "^7.25.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.4.tgz", - "integrity": "sha512-IYM8wSUwunWTB6tFC2dkKZhxbIjHoWemdK+3f8/wq8aKhbUscxD5MX72ubd90fxvFknaLPeGw5ycU84V1obHJg==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.6.tgz", + "integrity": "sha512-9Vrcx5ZW6UwK5tvqsj0nGpp/XzqthkT0dqIc9g1AdtygFToNtTF67XzYS//dm+SAK9cp3B9R4ZO/46p63SCjlQ==", + "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.23.4", - "@babel/generator": "^7.23.4", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.23.4", - "@babel/types": "^7.23.4", - "debug": "^4.1.0", + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.25.6", + "@babel/parser": "^7.25.6", + "@babel/template": "^7.25.0", + "@babel/types": "^7.25.6", + "debug": "^4.3.1", "globals": "^11.1.0" }, "engines": { @@ -506,12 +1985,13 @@ } }, "node_modules/@babel/types": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.4.tgz", - "integrity": "sha512-7uIFwVYpoplT5jp/kVv6EF93VaJ8H+Yn5IczYiaAi98ajzjfoZfslet/e0sLh+wVBjb2qqIut1b0S26VSafsSQ==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.6.tgz", + "integrity": "sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==", + "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.23.4", - "@babel/helper-validator-identifier": "^7.22.20", + "@babel/helper-string-parser": "^7.24.8", + "@babel/helper-validator-identifier": "^7.24.7", "to-fast-properties": "^2.0.0" }, "engines": { @@ -1077,9 +2557,36 @@ } }, "node_modules/@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", + "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "node_modules/@jridgewell/source-map/node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, "engines": { "node": ">=6.0.0" } @@ -1090,12 +2597,13 @@ "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.17", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", - "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "license": "MIT", "dependencies": { - "@jridgewell/resolve-uri": "3.1.0", - "@jridgewell/sourcemap-codec": "1.4.14" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, "node_modules/@juggle/resize-observer": { @@ -1139,17 +2647,19 @@ } }, "node_modules/@matrix-org/matrix-sdk-crypto-wasm": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@matrix-org/matrix-sdk-crypto-wasm/-/matrix-sdk-crypto-wasm-2.2.0.tgz", - "integrity": "sha512-txmvaTiZpVV0/kWCRcE7tZvRESCEc1ynLJDVh9OUsFlaXfl13c7qdD3E6IJEJ8YiPMIn+PHogdfBZsO84reaMg==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@matrix-org/matrix-sdk-crypto-wasm/-/matrix-sdk-crypto-wasm-7.0.0.tgz", + "integrity": "sha512-MOencXiW/gI5MuTtCNsuojjwT5DXCrjMqv9xOslJC9h2tPdLFFFMGr58dY5Lis4DRd9MRWcgrGowUIHOqieWTA==", + "license": "Apache-2.0", "engines": { "node": ">= 10" } }, "node_modules/@matrix-org/olm": { - "version": "3.2.14", - "resolved": "https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.14.tgz", - "integrity": "sha1-rNlsAKiB0PRi4fl6Vsc3QsjbyYQ=" + "version": "3.2.15", + "resolved": "https://registry.npmjs.org/@matrix-org/olm/-/olm-3.2.15.tgz", + "integrity": "sha512-S7lOrndAK9/8qOtaTq/WhttJC/o4GAzdfK0MUPpo8ApzsJEC0QjtwrkC3KBXdFP1cD1MXi/mlKR7aaoVMKgs6Q==", + "license": "Apache-2.0" }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", @@ -2608,6 +4118,55 @@ "node": ">=14.0.0" } }, + "node_modules/@rollup/plugin-babel": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", + "integrity": "sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.10.4", + "@rollup/pluginutils": "^3.1.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0", + "@types/babel__core": "^7.1.9", + "rollup": "^1.20.0||^2.0.0" + }, + "peerDependenciesMeta": { + "@types/babel__core": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-babel/node_modules/@rollup/pluginutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", + "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "0.0.39", + "estree-walker": "^1.0.1", + "picomatch": "^2.2.2" + }, + "engines": { + "node": ">= 8.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0" + } + }, + "node_modules/@rollup/plugin-babel/node_modules/@types/estree": { + "version": "0.0.39", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", + "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", + "dev": true, + "license": "MIT" + }, "node_modules/@rollup/plugin-inject": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/@rollup/plugin-inject/-/plugin-inject-5.0.3.tgz", @@ -2636,6 +4195,114 @@ "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", "dev": true }, + "node_modules/@rollup/plugin-node-resolve": { + "version": "15.2.3", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.2.3.tgz", + "integrity": "sha512-j/lym8nf5E21LwBT4Df1VD6hRO2L2iwUeUmP7litikRsVp1H6NWx20NEp0Y7su+7XGc476GnXXc4kFeZNGmaSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^5.0.1", + "@types/resolve": "1.20.2", + "deepmerge": "^4.2.2", + "is-builtin-module": "^3.2.1", + "is-module": "^1.0.0", + "resolve": "^1.22.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^2.78.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-node-resolve/node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@rollup/plugin-replace": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-2.4.2.tgz", + "integrity": "sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^3.1.0", + "magic-string": "^0.25.7" + }, + "peerDependencies": { + "rollup": "^1.20.0 || ^2.0.0" + } + }, + "node_modules/@rollup/plugin-replace/node_modules/@rollup/pluginutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", + "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "0.0.39", + "estree-walker": "^1.0.1", + "picomatch": "^2.2.2" + }, + "engines": { + "node": ">= 8.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0" + } + }, + "node_modules/@rollup/plugin-replace/node_modules/@types/estree": { + "version": "0.0.39", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", + "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rollup/plugin-replace/node_modules/magic-string": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", + "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "sourcemap-codec": "^1.4.8" + } + }, + "node_modules/@rollup/plugin-terser": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/@rollup/plugin-terser/-/plugin-terser-0.4.4.tgz", + "integrity": "sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==", + "dev": true, + "license": "MIT", + "dependencies": { + "serialize-javascript": "^6.0.1", + "smob": "^1.0.0", + "terser": "^5.17.4" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, "node_modules/@rollup/plugin-virtual": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/@rollup/plugin-virtual/-/plugin-virtual-3.0.2.tgz", @@ -2867,6 +4534,29 @@ "win32" ] }, + "node_modules/@surma/rollup-plugin-off-main-thread": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.3.tgz", + "integrity": "sha512-lR8q/9W7hZpMWweNiAKU7NQerBnzQQLvi8qnTDU/fxItPhtZVMbPV3lbCwjhIlNBe9Bbr5V+KHshvWmVSG9cxQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "ejs": "^3.1.6", + "json5": "^2.2.0", + "magic-string": "^0.25.0", + "string.prototype.matchall": "^4.0.6" + } + }, + "node_modules/@surma/rollup-plugin-off-main-thread/node_modules/magic-string": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", + "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "sourcemap-codec": "^1.4.8" + } + }, "node_modules/@swc/core": { "version": "1.5.5", "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.5.5.tgz", @@ -3227,9 +4917,10 @@ "dev": true }, "node_modules/@types/events": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.2.tgz", - "integrity": "sha512-v4Mr60wJuF069iZZCdY5DKhfj0l6eXNJtbSM/oMDNdRLoBEUsktmKnswkz0X3OAic5W8Qy/YU6owKE4A66Y46A==" + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.3.tgz", + "integrity": "sha512-trOc4AAUThEz9hapPtSd7wf5tiQKvTtu5b371UxXdTuqzIh0ArcRspRP0i0Viu+LXstIQ1z96t1nsPxT9ol01g==", + "license": "MIT" }, "node_modules/@types/file-saver": { "version": "2.0.5", @@ -3313,6 +5004,13 @@ "@types/react": "*" } }, + "node_modules/@types/resolve": { + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", + "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/retry": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", @@ -3338,6 +5036,20 @@ "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==", "dev": true }, + "node_modules/@types/serviceworker": { + "version": "0.0.95", + "resolved": "https://registry.npmjs.org/@types/serviceworker/-/serviceworker-0.0.95.tgz", + "integrity": "sha512-Zw7kLIehLvaXf/9RnxAUiYyHmYC5pfvIJD3b1uSPkZGzp+OVmXgmPzVW5fbhYHKcqkeGzsv89uGm+JmMCAPa8Q==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/@types/trusted-types": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", + "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/ua-parser-js": { "version": "0.7.36", "resolved": "https://registry.npmjs.org/@types/ua-parser-js/-/ua-parser-js-0.7.36.tgz", @@ -3766,10 +5478,11 @@ "optional": true }, "node_modules/acorn": { - "version": "8.8.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", - "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", "dev": true, + "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -3836,6 +5549,7 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "license": "MIT", "dependencies": { "color-convert": "^1.9.0" }, @@ -4041,6 +5755,23 @@ "integrity": "sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==", "dev": true }, + "node_modules/async": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", + "dev": true, + "license": "MIT" + }, + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 4.0.0" + } + }, "node_modules/autosize": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/autosize/-/autosize-4.0.4.tgz", @@ -4084,6 +5815,48 @@ "integrity": "sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA==", "dev": true }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.4.11", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.11.tgz", + "integrity": "sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.22.6", + "@babel/helper-define-polyfill-provider": "^0.6.2", + "semver": "^6.3.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.10.6", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.6.tgz", + "integrity": "sha512-b37+KR2i/khY5sKmWNVQAnitvquQbNdWy6lJdsr0kmquCKEEUgMKK4SboVM3HtfnZilfjr4MMQ7vY58FVWDtIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.2", + "core-js-compat": "^3.38.0" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.2.tgz", + "integrity": "sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -4091,9 +5864,10 @@ "devOptional": true }, "node_modules/base-x": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-4.0.0.tgz", - "integrity": "sha512-FuwxlW4H5kh37X/oW59pwTzzTKRzfrrQwhmyspRM7swOEZcHtDZSCt45U6oKgtuFE+WYPblePMVIPR4RZrh/hw==" + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-5.0.0.tgz", + "integrity": "sha512-sMW3VGSX1QWVFA6l8U62MLKz29rRfpTlYdCqLdpLo1/Yd4zZwSbnUaDfciIAowAqvq7YFnWq9hrhdg1KYgc1lQ==", + "license": "MIT" }, "node_modules/base64-js": { "version": "1.5.1", @@ -4162,9 +5936,9 @@ "integrity": "sha512-L7siI766UCH6+arP9yT5wpA5AFxnmGbKiGSsxEVACl1tE0pvDJeQvMmbY2UmJiuffrr0ZJ2+U6Om46wQBqh1Lw==" }, "node_modules/browserslist": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.1.tgz", - "integrity": "sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==", + "version": "4.23.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.3.tgz", + "integrity": "sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==", "funding": [ { "type": "opencollective", @@ -4179,11 +5953,12 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001541", - "electron-to-chromium": "^1.4.535", - "node-releases": "^2.0.13", - "update-browserslist-db": "^1.0.13" + "caniuse-lite": "^1.0.30001646", + "electron-to-chromium": "^1.5.4", + "node-releases": "^2.0.18", + "update-browserslist-db": "^1.1.0" }, "bin": { "browserslist": "cli.js" @@ -4193,11 +5968,12 @@ } }, "node_modules/bs58": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/bs58/-/bs58-5.0.0.tgz", - "integrity": "sha512-r+ihvQJvahgYT50JD05dyJNKlmmSlMoOGwn1lCcEzanPglg7TxYjioQUYehQ9mAR/+hOSd2jRc/Z2y5UxBymvQ==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-6.0.0.tgz", + "integrity": "sha512-PD0wEnEYg6ijszw/u8s+iI3H17cTymlrwkKhDhPZq+Sokl3AU4htyBFTjAeNAlCCmg0f53g6ih3jATyCKftTfw==", + "license": "MIT", "dependencies": { - "base-x": "^4.0.0" + "base-x": "^5.0.0" } }, "node_modules/buffer": { @@ -4224,6 +6000,26 @@ "ieee754": "^1.2.1" } }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/builtin-modules": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", + "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/call-bind": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", @@ -4253,9 +6049,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001565", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001565.tgz", - "integrity": "sha512-xrE//a3O7TP0vaJ8ikzkD2c2NgcVUvsEe2IvFTntV4Yd1Z9FVzh+gW+enX96L0psrbaFMcVcH2l90xNuGDWc8w==", + "version": "1.0.30001658", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001658.tgz", + "integrity": "sha512-N2YVqWbJELVdrnsW5p+apoQyYt51aBMSsBZki1XZEfeBCexcM/sf4xiAHcXQBkuOwJBXtWF7aW1sYX6tKebPHw==", "funding": [ { "type": "opencollective", @@ -4269,7 +6065,8 @@ "type": "github", "url": "https://github.com/sponsors/ai" } - ] + ], + "license": "CC-BY-4.0" }, "node_modules/canvas": { "version": "2.11.2", @@ -4290,6 +6087,7 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "license": "MIT", "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -4377,6 +6175,7 @@ "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "license": "MIT", "dependencies": { "color-name": "1.1.3" } @@ -4384,7 +6183,8 @@ "node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "license": "MIT" }, "node_modules/color-support": { "version": "1.1.3", @@ -4395,6 +6195,23 @@ "color-support": "bin.js" } }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/common-tags": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz", + "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4.0.0" + } + }, "node_modules/compute-scroll-into-view": { "version": "1.0.20", "resolved": "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-1.0.20.tgz", @@ -4436,6 +6253,20 @@ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==" }, + "node_modules/core-js-compat": { + "version": "3.38.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.38.1.tgz", + "integrity": "sha512-JRH6gfXxGmrzF3tZ57lFx97YARxCXPaMzPo6jELZhv88pBH5VXpQ+y0znKGlFnzuaihqhLbefxSJxWJMPtfDzw==", + "dev": true, + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, "node_modules/core-js-pure": { "version": "3.26.1", "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.26.1.tgz", @@ -4469,10 +6300,15 @@ "node": ">= 8" } }, - "node_modules/crypto-js": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz", - "integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==" + "node_modules/crypto-random-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", + "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } }, "node_modules/css-what": { "version": "5.1.0", @@ -4572,11 +6408,12 @@ "integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==" }, "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "license": "MIT", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -4754,10 +6591,27 @@ "url": "https://github.com/fb55/domutils?sponsor=1" } }, + "node_modules/ejs": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", + "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "jake": "^10.8.5" + }, + "bin": { + "ejs": "bin/cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/electron-to-chromium": { - "version": "1.4.596", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.596.tgz", - "integrity": "sha512-zW3zbZ40Icb2BCWjm47nxwcFGYlIgdXkAx85XDO7cyky9J4QQfq8t0W19/TLZqq3JPQXtlv8BPIGmfa9Jb4scg==" + "version": "1.5.16", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.16.tgz", + "integrity": "sha512-2gQpi2WYobXmz2q23FrOBYTLcI1O/P4heW3eqX+ldmPVDQELRqhiebV380EhlGG12NtnX1qbK/FHpN0ba+7bLA==", + "license": "ISC" }, "node_modules/emoji-regex": { "version": "9.2.2", @@ -4967,9 +6821,10 @@ } }, "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", "engines": { "node": ">=6" } @@ -4978,6 +6833,7 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "license": "MIT", "engines": { "node": ">=0.8.0" } @@ -5481,6 +7337,13 @@ "node": ">=4.0" } }, + "node_modules/estree-walker": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", + "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", + "dev": true, + "license": "MIT" + }, "node_modules/esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", @@ -5505,6 +7368,7 @@ "version": "3.3.0", "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "license": "MIT", "engines": { "node": ">=0.8.x" } @@ -5560,6 +7424,13 @@ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, + "node_modules/fast-uri": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.1.tgz", + "integrity": "sha512-MWipKbbYiYI0UC7cl8m/i/IWTqfC8YXsqjzybjddLsFjStroQzsHXkc73JutMvBiXmOvapk+axIl79ig5t55Bw==", + "dev": true, + "license": "MIT" + }, "node_modules/fastq": { "version": "1.14.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.14.0.tgz", @@ -5614,6 +7485,21 @@ "node": "*" } }, + "node_modules/fdir": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.3.0.tgz", + "integrity": "sha512-QOnuT+BOtivR77wYvCWHfGt9s4Pz1VIMbD463vegT5MLqNXy8rYFT/lPVEqf/bhYeT6qmqrNHhsX+rWwe3rOCQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, "node_modules/file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -5631,6 +7517,39 @@ "resolved": "https://registry.npmjs.org/file-saver/-/file-saver-2.0.5.tgz", "integrity": "sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA==" }, + "node_modules/filelist": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", + "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "minimatch": "^5.0.1" + } + }, + "node_modules/filelist/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/filelist/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -5761,6 +7680,22 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, + "node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/fs-minipass": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", @@ -5896,6 +7831,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-own-enumerable-property-symbols": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", + "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==", + "dev": true, + "license": "ISC" + }, "node_modules/get-symbol-description": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", @@ -5949,6 +7891,7 @@ "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "license": "MIT", "engines": { "node": ">=4" } @@ -6038,6 +7981,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "license": "MIT", "engines": { "node": ">=4" } @@ -6270,6 +8214,13 @@ } } }, + "node_modules/idb": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz", + "integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==", + "dev": true, + "license": "ISC" + }, "node_modules/ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", @@ -6446,6 +8397,22 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-builtin-module": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", + "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", + "dev": true, + "license": "MIT", + "dependencies": { + "builtin-modules": "^3.3.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-callable": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", @@ -6534,6 +8501,13 @@ "resolved": "https://registry.npmjs.org/is-hotkey/-/is-hotkey-0.2.0.tgz", "integrity": "sha512-UknnZK4RakDmTgz4PI1wIph5yxSs/mvChWs9ifnlXsKuXgWmOkY/hAE0H/k2MIqH0RlRye0i1oC07MCRSD28Mw==" }, + "node_modules/is-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", + "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==", + "dev": true, + "license": "MIT" + }, "node_modules/is-negative-zero": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", @@ -6570,6 +8544,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/is-path-inside": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", @@ -6603,6 +8587,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", + "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/is-shared-array-buffer": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", @@ -6618,6 +8612,19 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-string": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", @@ -6687,6 +8694,101 @@ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, + "node_modules/jake": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.2.tgz", + "integrity": "sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "async": "^3.2.3", + "chalk": "^4.0.2", + "filelist": "^1.0.4", + "minimatch": "^3.1.2" + }, + "bin": { + "jake": "bin/cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jake/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jake/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jake/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jake/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/jake/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jake/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/javascript-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/javascript-stringify/-/javascript-stringify-2.1.0.tgz", @@ -6743,6 +8845,7 @@ "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "license": "MIT", "bin": { "jsesc": "bin/jsesc" }, @@ -6750,6 +8853,13 @@ "node": ">=4" } }, + "node_modules/json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", + "dev": true, + "license": "(AFL-2.1 OR BSD-3-Clause)" + }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -6773,6 +8883,29 @@ "node": ">=6" } }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonpointer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", + "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/jsx-ast-utils": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.3.tgz", @@ -6787,9 +8920,13 @@ } }, "node_modules/jwt-decode": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-3.1.2.tgz", - "integrity": "sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A==" + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-4.0.0.tgz", + "integrity": "sha512-+KJGIyHgkGuIq3IEBNftfhW/LfWhXUIY6OmyVWjliu5KH1y0fw7VQ8YndE2O4qZdMSd9SqbnC8GOcZEy0Om7sA==", + "license": "MIT", + "engines": { + "node": ">=18" + } }, "node_modules/language-subtag-registry": { "version": "0.3.22", @@ -6820,6 +8957,16 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -6890,12 +9037,26 @@ "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", + "dev": true, + "license": "MIT" + }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, + "node_modules/lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==", + "dev": true, + "license": "MIT" + }, "node_modules/loglevel": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.8.1.tgz", @@ -6964,33 +9125,49 @@ "integrity": "sha512-1QEOsXO+bhyCroIe2/A5OwaxHvBm7EsSQ46DEDn8RBIfQwN5HWBpFvyWWR4QY0KHPPnnJdI99wgRiAl7Ad5qaA==" }, "node_modules/matrix-js-sdk": { - "version": "29.1.0", - "resolved": "https://registry.npmjs.org/matrix-js-sdk/-/matrix-js-sdk-29.1.0.tgz", - "integrity": "sha512-nF+ACFioDltGCf2KFfXK7QoJ70Ytnzm4Jse2UI+BDXeR9WCjtKefXJtboN2rmU4MFmLCTHcnBTmu6yig67YUqw==", + "version": "34.4.0", + "resolved": "https://registry.npmjs.org/matrix-js-sdk/-/matrix-js-sdk-34.4.0.tgz", + "integrity": "sha512-bI5xJZS3/qhjPQqQL5HhOQ1iBvnHxiqhS2zgzk9SarEuXiH08wbVl9gAAuDqOYE3miNGs4WQQJ19MoaUEOnNwg==", + "license": "Apache-2.0", "dependencies": { "@babel/runtime": "^7.12.5", - "@matrix-org/matrix-sdk-crypto-wasm": "^2.0.0", + "@matrix-org/matrix-sdk-crypto-wasm": "^7.0.0", + "@matrix-org/olm": "3.2.15", "another-json": "^0.2.0", - "bs58": "^5.0.0", + "bs58": "^6.0.0", "content-type": "^1.0.4", - "jwt-decode": "^3.1.2", + "jwt-decode": "^4.0.0", "loglevel": "^1.7.1", "matrix-events-sdk": "0.0.1", - "matrix-widget-api": "^1.6.0", - "oidc-client-ts": "^2.2.4", + "matrix-widget-api": "^1.8.2", + "oidc-client-ts": "^3.0.1", "p-retry": "4", "sdp-transform": "^2.14.1", "unhomoglyph": "^1.0.6", - "uuid": "9" + "uuid": "10" }, "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" + } + }, + "node_modules/matrix-js-sdk/node_modules/uuid": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz", + "integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" } }, "node_modules/matrix-widget-api": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/matrix-widget-api/-/matrix-widget-api-1.6.0.tgz", - "integrity": "sha512-VXIJyAZ/WnBmT4C7ePqevgMYGneKMCP/0JuCOqntSsaNlCRHJvwvTxmqUU+ufOpzIF5gYNyIrAjbgrEbK3iqJQ==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/matrix-widget-api/-/matrix-widget-api-1.9.0.tgz", + "integrity": "sha512-au8mqralNDqrEvaVAkU37bXOb8I9SCe+ACdPk11QWw58FKstVq31q2wRz+qWA6J+42KJ6s1DggWbG/S3fEs3jw==", + "license": "Apache-2.0", "dependencies": { "@types/events": "^3.0.0", "events": "^3.2.0" @@ -7117,9 +9294,10 @@ } }, "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" }, "node_modules/nan": { "version": "2.17.0", @@ -7176,9 +9354,10 @@ } }, "node_modules/node-releases": { - "version": "2.0.13", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", - "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==" + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", + "license": "MIT" }, "node_modules/nopt": { "version": "5.0.0", @@ -7337,15 +9516,15 @@ } }, "node_modules/oidc-client-ts": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/oidc-client-ts/-/oidc-client-ts-2.4.0.tgz", - "integrity": "sha512-WijhkTrlXK2VvgGoakWJiBdfIsVGz6CFzgjNNqZU1hPKV2kyeEaJgLs7RwuiSp2WhLfWBQuLvr2SxVlZnk3N1w==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/oidc-client-ts/-/oidc-client-ts-3.0.1.tgz", + "integrity": "sha512-xX8unZNtmtw3sOz4FPSqDhkLFnxCDsdo2qhFEH2opgWnF/iXMFoYdBQzkwCxAZVgt3FT3DnuBY3k80EZHT0RYg==", + "license": "Apache-2.0", "dependencies": { - "crypto-js": "^4.2.0", - "jwt-decode": "^3.1.2" + "jwt-decode": "^4.0.0" }, "engines": { - "node": ">=12.13.0" + "node": ">=18" } }, "node_modules/once": { @@ -7499,9 +9678,10 @@ } }, "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", + "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==", + "license": "ISC" }, "node_modules/picomatch": { "version": "2.3.1", @@ -7603,6 +9783,19 @@ "url": "https://github.com/prettier/prettier?sponsor=1" } }, + "node_modules/pretty-bytes": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-6.1.1.tgz", + "integrity": "sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/prismjs": { "version": "1.29.0", "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz", @@ -7663,6 +9856,16 @@ "resolved": "https://registry.npmjs.org/raf-schd/-/raf-schd-4.0.3.tgz", "integrity": "sha512-tQkJl2GRWh83ui2DiPTJz9wEiMN20syf+5oKfB03yYP7ioZcJwsIK8FjrtLwH1m7C7e+Tt2yYBlrOpdT+dyeIQ==" }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, "node_modules/react": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", @@ -7925,12 +10128,42 @@ "node": ">=8.10.0" } }, + "node_modules/regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", + "dev": true, + "license": "MIT" + }, + "node_modules/regenerate-unicode-properties": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz", + "integrity": "sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/regenerator-runtime": { "version": "0.14.1", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", "license": "MIT" }, + "node_modules/regenerator-transform": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", + "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.8.4" + } + }, "node_modules/regexp.prototype.flags": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", @@ -7961,6 +10194,46 @@ "url": "https://github.com/sponsors/mysticatea" } }, + "node_modules/regexpu-core": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", + "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/regjsgen": "^0.8.0", + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.1.0", + "regjsparser": "^0.9.1", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regjsparser": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", + "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "jsesc": "~0.5.0" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/regjsparser/node_modules/jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + } + }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -7969,6 +10242,16 @@ "node": ">=0.10.0" } }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/require-like": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/require-like/-/require-like-0.1.2.tgz", @@ -8110,6 +10393,7 @@ "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "devOptional": true, "funding": [ { "type": "github", @@ -8123,8 +10407,7 @@ "type": "consulting", "url": "https://feross.org/support" } - ], - "optional": true + ] }, "node_modules/safe-regex-test": { "version": "1.0.3", @@ -8224,6 +10507,16 @@ "semver": "bin/semver.js" } }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "randombytes": "^2.1.0" + } + }, "node_modules/set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", @@ -8395,6 +10688,26 @@ "resolved": "https://registry.npmjs.org/is-hotkey/-/is-hotkey-0.1.8.tgz", "integrity": "sha512-qs3NZ1INIS+H+yeo7cD9pDfwYV/jqRh1JG9S9zYrNudkoUQg7OL7ziXqRKu+InFjUIDoP2o6HIkLYMh1pcWgyQ==" }, + "node_modules/smob": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/smob/-/smob-1.5.0.tgz", + "integrity": "sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig==", + "dev": true, + "license": "MIT" + }, + "node_modules/source-map": { + "version": "0.8.0-beta.0", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz", + "integrity": "sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "whatwg-url": "^7.0.0" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/source-map-js": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", @@ -8403,6 +10716,64 @@ "node": ">=0.10.0" } }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map/node_modules/tr46": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", + "integrity": "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==", + "dev": true, + "license": "MIT", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/source-map/node_modules/webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/source-map/node_modules/whatwg-url": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", + "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", + "dev": true, + "license": "MIT", + "dependencies": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + }, + "node_modules/sourcemap-codec": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", + "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", + "deprecated": "Please use @jridgewell/sourcemap-codec instead", + "dev": true, + "license": "MIT" + }, "node_modules/string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -8498,6 +10869,21 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/stringify-object": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", + "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "get-own-enumerable-property-symbols": "^3.0.0", + "is-obj": "^1.0.1", + "is-regexp": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -8518,6 +10904,16 @@ "node": ">=4" } }, + "node_modules/strip-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-comments/-/strip-comments-2.0.1.tgz", + "integrity": "sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -8550,6 +10946,7 @@ "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "license": "MIT", "dependencies": { "has-flag": "^3.0.0" }, @@ -8591,6 +10988,67 @@ "node": ">=10" } }, + "node_modules/temp-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz", + "integrity": "sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/tempy": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tempy/-/tempy-0.6.0.tgz", + "integrity": "sha512-G13vtMYPT/J8A4X2SjdtBTphZlrp1gKv6hZiOjw14RCWg6GbHuQBGtjlx75xLbYV/wEc0D7G5K4rxKP/cXk8Bw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-stream": "^2.0.0", + "temp-dir": "^2.0.0", + "type-fest": "^0.16.0", + "unique-string": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/tempy/node_modules/type-fest": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.16.0.tgz", + "integrity": "sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/terser": { + "version": "5.31.6", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.6.tgz", + "integrity": "sha512-PQ4DAriWzKj+qgehQ7LK5bQqCFNMmlhjR2PFFLuqGCpuCAauxemVBWwWOxo3UIwWQx8+Pr61Df++r76wDmkQBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -8607,6 +11065,33 @@ "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" }, + "node_modules/tinyglobby": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.5.tgz", + "integrity": "sha512-Dlqgt6h0QkoHttG53/WGADNh9QhcjCAIZMTERAVhdpmIBEejSuLI9ZmGKWzB7tweBjlk30+s/ofi4SLmBeTYhw==", + "dev": true, + "license": "ISC", + "dependencies": { + "fdir": "^6.2.0", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/tippy.js": { "version": "6.3.7", "resolved": "https://registry.npmjs.org/tippy.js/-/tippy.js-6.3.7.tgz", @@ -8833,10 +11318,88 @@ "resolved": "https://registry.npmjs.org/unhomoglyph/-/unhomoglyph-1.0.6.tgz", "integrity": "sha512-7uvcWI3hWshSADBu4JpnyYbTVc7YlhF5GDW/oPD5AxIxl34k4wXR3WDkPnzLxkN32LiTCTKMQLtKVZiwki3zGg==" }, + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", + "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-value-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", + "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", + "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unique-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", + "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", + "dev": true, + "license": "MIT", + "dependencies": { + "crypto-random-string": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/upath": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", + "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4", + "yarn": "*" + } + }, "node_modules/update-browserslist-db": { - "version": "1.0.13", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", - "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", + "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", "funding": [ { "type": "opencollective", @@ -8851,9 +11414,10 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" + "escalade": "^3.1.2", + "picocolors": "^1.0.1" }, "bin": { "update-browserslist-db": "cli.js" @@ -8881,6 +11445,7 @@ "version": "9.0.1", "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "dev": true, "funding": [ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" @@ -8944,6 +11509,37 @@ } } }, + "node_modules/vite-plugin-pwa": { + "version": "0.20.5", + "resolved": "https://registry.npmjs.org/vite-plugin-pwa/-/vite-plugin-pwa-0.20.5.tgz", + "integrity": "sha512-aweuI/6G6n4C5Inn0vwHumElU/UEpNuO+9iZzwPZGTCH87TeZ6YFMrEY6ZUBQdIHHlhTsbMDryFARcSuOdsz9Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.3.6", + "pretty-bytes": "^6.1.1", + "tinyglobby": "^0.2.0", + "workbox-build": "^7.1.0", + "workbox-window": "^7.1.0" + }, + "engines": { + "node": ">=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vite-pwa/assets-generator": "^0.2.6", + "vite": "^3.1.0 || ^4.0.0 || ^5.0.0", + "workbox-build": "^7.1.0", + "workbox-window": "^7.1.0" + }, + "peerDependenciesMeta": { + "@vite-pwa/assets-generator": { + "optional": true + } + } + }, "node_modules/vite-plugin-static-copy": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/vite-plugin-static-copy/-/vite-plugin-static-copy-1.0.4.tgz", @@ -8976,27 +11572,6 @@ "node": ">=14.14" } }, - "node_modules/vite-plugin-static-copy/node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/vite-plugin-static-copy/node_modules/universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true, - "engines": { - "node": ">= 10.0.0" - } - }, "node_modules/vite-plugin-top-level-await": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/vite-plugin-top-level-await/-/vite-plugin-top-level-await-1.4.1.tgz", @@ -9500,6 +12075,266 @@ "node": ">=0.10.0" } }, + "node_modules/workbox-background-sync": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-7.1.0.tgz", + "integrity": "sha512-rMbgrzueVWDFcEq1610YyDW71z0oAXLfdRHRQcKw4SGihkfOK0JUEvqWHFwA6rJ+6TClnMIn7KQI5PNN1XQXwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "idb": "^7.0.1", + "workbox-core": "7.1.0" + } + }, + "node_modules/workbox-broadcast-update": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/workbox-broadcast-update/-/workbox-broadcast-update-7.1.0.tgz", + "integrity": "sha512-O36hIfhjej/c5ar95pO67k1GQw0/bw5tKP7CERNgK+JdxBANQhDmIuOXZTNvwb2IHBx9hj2kxvcDyRIh5nzOgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "workbox-core": "7.1.0" + } + }, + "node_modules/workbox-build": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/workbox-build/-/workbox-build-7.1.1.tgz", + "integrity": "sha512-WdkVdC70VMpf5NBCtNbiwdSZeKVuhTEd5PV3mAwpTQCGAB5XbOny1P9egEgNdetv4srAMmMKjvBk4RD58LpooA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@apideck/better-ajv-errors": "^0.3.1", + "@babel/core": "^7.24.4", + "@babel/preset-env": "^7.11.0", + "@babel/runtime": "^7.11.2", + "@rollup/plugin-babel": "^5.2.0", + "@rollup/plugin-node-resolve": "^15.2.3", + "@rollup/plugin-replace": "^2.4.1", + "@rollup/plugin-terser": "^0.4.3", + "@surma/rollup-plugin-off-main-thread": "^2.2.3", + "ajv": "^8.6.0", + "common-tags": "^1.8.0", + "fast-json-stable-stringify": "^2.1.0", + "fs-extra": "^9.0.1", + "glob": "^7.1.6", + "lodash": "^4.17.20", + "pretty-bytes": "^5.3.0", + "rollup": "^2.43.1", + "source-map": "^0.8.0-beta.0", + "stringify-object": "^3.3.0", + "strip-comments": "^2.0.1", + "tempy": "^0.6.0", + "upath": "^1.2.0", + "workbox-background-sync": "7.1.0", + "workbox-broadcast-update": "7.1.0", + "workbox-cacheable-response": "7.1.0", + "workbox-core": "7.1.0", + "workbox-expiration": "7.1.0", + "workbox-google-analytics": "7.1.0", + "workbox-navigation-preload": "7.1.0", + "workbox-precaching": "7.1.0", + "workbox-range-requests": "7.1.0", + "workbox-recipes": "7.1.0", + "workbox-routing": "7.1.0", + "workbox-strategies": "7.1.0", + "workbox-streams": "7.1.0", + "workbox-sw": "7.1.0", + "workbox-window": "7.1.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/workbox-build/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/workbox-build/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, + "node_modules/workbox-build/node_modules/pretty-bytes": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", + "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/workbox-build/node_modules/rollup": { + "version": "2.79.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz", + "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==", + "dev": true, + "license": "MIT", + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=10.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/workbox-cacheable-response": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-7.1.0.tgz", + "integrity": "sha512-iwsLBll8Hvua3xCuBB9h92+/e0wdsmSVgR2ZlvcfjepZWwhd3osumQB3x9o7flj+FehtWM2VHbZn8UJeBXXo6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "workbox-core": "7.1.0" + } + }, + "node_modules/workbox-core": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-7.1.0.tgz", + "integrity": "sha512-5KB4KOY8rtL31nEF7BfvU7FMzKT4B5TkbYa2tzkS+Peqj0gayMT9SytSFtNzlrvMaWgv6y/yvP9C0IbpFjV30Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/workbox-expiration": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-7.1.0.tgz", + "integrity": "sha512-m5DcMY+A63rJlPTbbBNtpJ20i3enkyOtSgYfv/l8h+D6YbbNiA0zKEkCUaMsdDlxggla1oOfRkyqTvl5Ni5KQQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "idb": "^7.0.1", + "workbox-core": "7.1.0" + } + }, + "node_modules/workbox-google-analytics": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-7.1.0.tgz", + "integrity": "sha512-FvE53kBQHfVTcZyczeBVRexhh7JTkyQ8HAvbVY6mXd2n2A7Oyz/9fIwnY406ZcDhvE4NFfKGjW56N4gBiqkrew==", + "dev": true, + "license": "MIT", + "dependencies": { + "workbox-background-sync": "7.1.0", + "workbox-core": "7.1.0", + "workbox-routing": "7.1.0", + "workbox-strategies": "7.1.0" + } + }, + "node_modules/workbox-navigation-preload": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-7.1.0.tgz", + "integrity": "sha512-4wyAbo0vNI/X0uWNJhCMKxnPanNyhybsReMGN9QUpaePLTiDpKxPqFxl4oUmBNddPwIXug01eTSLVIFXimRG/A==", + "dev": true, + "license": "MIT", + "dependencies": { + "workbox-core": "7.1.0" + } + }, + "node_modules/workbox-precaching": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-7.1.0.tgz", + "integrity": "sha512-LyxzQts+UEpgtmfnolo0hHdNjoB7EoRWcF7EDslt+lQGd0lW4iTvvSe3v5JiIckQSB5KTW5xiCqjFviRKPj1zA==", + "dev": true, + "license": "MIT", + "dependencies": { + "workbox-core": "7.1.0", + "workbox-routing": "7.1.0", + "workbox-strategies": "7.1.0" + } + }, + "node_modules/workbox-range-requests": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-7.1.0.tgz", + "integrity": "sha512-m7+O4EHolNs5yb/79CrnwPR/g/PRzMFYEdo01LqwixVnc/sbzNSvKz0d04OE3aMRel1CwAAZQheRsqGDwATgPQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "workbox-core": "7.1.0" + } + }, + "node_modules/workbox-recipes": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/workbox-recipes/-/workbox-recipes-7.1.0.tgz", + "integrity": "sha512-NRrk4ycFN9BHXJB6WrKiRX3W3w75YNrNrzSX9cEZgFB5ubeGoO8s/SDmOYVrFYp9HMw6sh1Pm3eAY/1gVS8YLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "workbox-cacheable-response": "7.1.0", + "workbox-core": "7.1.0", + "workbox-expiration": "7.1.0", + "workbox-precaching": "7.1.0", + "workbox-routing": "7.1.0", + "workbox-strategies": "7.1.0" + } + }, + "node_modules/workbox-routing": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-7.1.0.tgz", + "integrity": "sha512-oOYk+kLriUY2QyHkIilxUlVcFqwduLJB7oRZIENbqPGeBP/3TWHYNNdmGNhz1dvKuw7aqvJ7CQxn27/jprlTdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "workbox-core": "7.1.0" + } + }, + "node_modules/workbox-strategies": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-7.1.0.tgz", + "integrity": "sha512-/UracPiGhUNehGjRm/tLUQ+9PtWmCbRufWtV0tNrALuf+HZ4F7cmObSEK+E4/Bx1p8Syx2tM+pkIrvtyetdlew==", + "dev": true, + "license": "MIT", + "dependencies": { + "workbox-core": "7.1.0" + } + }, + "node_modules/workbox-streams": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/workbox-streams/-/workbox-streams-7.1.0.tgz", + "integrity": "sha512-WyHAVxRXBMfysM8ORwiZnI98wvGWTVAq/lOyBjf00pXFvG0mNaVz4Ji+u+fKa/mf1i2SnTfikoYKto4ihHeS6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "workbox-core": "7.1.0", + "workbox-routing": "7.1.0" + } + }, + "node_modules/workbox-sw": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/workbox-sw/-/workbox-sw-7.1.0.tgz", + "integrity": "sha512-Hml/9+/njUXBglv3dtZ9WBKHI235AQJyLBV1G7EFmh4/mUdSQuXui80RtjDeVRrXnm/6QWgRUEHG3/YBVbxtsA==", + "dev": true, + "license": "MIT" + }, + "node_modules/workbox-window": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/workbox-window/-/workbox-window-7.1.0.tgz", + "integrity": "sha512-ZHeROyqR+AS5UPzholQRDttLFqGMwP0Np8MKWAdyxsDETxq3qOAyXvqessc3GniohG6e0mAqSQyKOHmT8zPF7g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/trusted-types": "^2.0.2", + "workbox-core": "7.1.0" + } + }, "node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", @@ -9611,4 +12446,4 @@ } } } -} +} \ No newline at end of file diff --git a/package.json b/package.json index 8c66068bc..09efccb74 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "@atlaskit/pragmatic-drag-and-drop-auto-scroll": "1.3.0", "@atlaskit/pragmatic-drag-and-drop-hitbox": "1.0.3", "@fontsource/inter": "4.5.14", - "@matrix-org/olm": "3.2.14", + "@matrix-org/olm": "3.2.15", "@tanstack/react-query": "5.24.1", "@tanstack/react-query-devtools": "5.24.1", "@tanstack/react-virtual": "3.2.0", @@ -56,7 +56,7 @@ "jotai": "2.6.0", "linkify-react": "4.1.3", "linkifyjs": "4.1.3", - "matrix-js-sdk": "29.1.0", + "matrix-js-sdk": "34.4.0", "millify": "6.1.0", "pdfjs-dist": "4.2.67", "prismjs": "1.29.0", @@ -90,6 +90,7 @@ "@types/react-dom": "18.2.17", "@types/react-google-recaptcha": "2.1.8", "@types/sanitize-html": "2.9.0", + "@types/serviceworker": "0.0.95", "@types/ua-parser-js": "0.7.36", "@typescript-eslint/eslint-plugin": "5.46.1", "@typescript-eslint/parser": "5.46.1", @@ -106,6 +107,7 @@ "sass": "1.56.2", "typescript": "4.9.4", "vite": "5.0.13", + "vite-plugin-pwa": "0.20.5", "vite-plugin-static-copy": "1.0.4", "vite-plugin-top-level-await": "1.4.1" } diff --git a/src/app/components/editor/Elements.tsx b/src/app/components/editor/Elements.tsx index c4767ab92..aee50ac80 100644 --- a/src/app/components/editor/Elements.tsx +++ b/src/app/components/editor/Elements.tsx @@ -13,6 +13,8 @@ import { CommandElement, EmoticonElement, LinkElement, MentionElement } from './ import { useMatrixClient } from '../../hooks/useMatrixClient'; import { getBeginCommand } from './utils'; import { BlockType } from './types'; +import { mxcUrlToHttp } from '../../utils/matrix'; +import { useSpecVersions } from '../../hooks/useSpecVersions'; // Put this at the start and end of an inline component to work around this Chromium bug: // https://bugs.chromium.org/p/chromium/issues/detail?id=1249405 @@ -76,6 +78,8 @@ function RenderEmoticonElement({ children, }: { element: EmoticonElement } & RenderElementProps) { const mx = useMatrixClient(); + const { versions } = useSpecVersions(); + const useAuthentication = versions.includes('v1.11'); const selected = useSelected(); const focused = useFocused(); @@ -90,7 +94,7 @@ function RenderEmoticonElement({ {element.key.startsWith('mxc://') ? ( {element.shortcode} ) : ( diff --git a/src/app/components/editor/autocomplete/EmoticonAutocomplete.tsx b/src/app/components/editor/autocomplete/EmoticonAutocomplete.tsx index bc98667ea..b77ae746f 100644 --- a/src/app/components/editor/autocomplete/EmoticonAutocomplete.tsx +++ b/src/app/components/editor/autocomplete/EmoticonAutocomplete.tsx @@ -18,6 +18,8 @@ import { useRelevantImagePacks } from '../../../hooks/useImagePacks'; import { IEmoji, emojis } from '../../../plugins/emoji'; import { ExtendedPackImage, PackUsage } from '../../../plugins/custom-emoji'; import { useKeyDown } from '../../../hooks/useKeyDown'; +import { mxcUrlToHttp } from '../../../utils/matrix'; +import { useSpecVersions } from '../../../hooks/useSpecVersions'; type EmoticonCompleteHandler = (key: string, shortcode: string) => void; @@ -48,6 +50,8 @@ export function EmoticonAutocomplete({ requestClose, }: EmoticonAutocompleteProps) { const mx = useMatrixClient(); + const { versions } = useSpecVersions(); + const useAuthentication = versions.includes('v1.11'); const imagePacks = useRelevantImagePacks(mx, PackUsage.Emoticon, imagePackRooms); const recentEmoji = useRecentEmoji(mx, 20); @@ -103,7 +107,7 @@ export function EmoticonAutocomplete({ diff --git a/src/app/components/editor/autocomplete/UserMentionAutocomplete.tsx b/src/app/components/editor/autocomplete/UserMentionAutocomplete.tsx index 642ce50a3..05d303a2a 100644 --- a/src/app/components/editor/autocomplete/UserMentionAutocomplete.tsx +++ b/src/app/components/editor/autocomplete/UserMentionAutocomplete.tsx @@ -18,6 +18,7 @@ import { useKeyDown } from '../../../hooks/useKeyDown'; import { getMxIdLocalPart, getMxIdServer, validMxId } from '../../../utils/matrix'; import { getMemberDisplayName, getMemberSearchStr } from '../../../utils/room'; import { UserAvatar } from '../../user-avatar'; +import { useSpecVersions } from '../../../hooks/useSpecVersions'; type MentionAutoCompleteHandler = (userId: string, name: string) => void; @@ -84,6 +85,8 @@ export function UserMentionAutocomplete({ requestClose, }: UserMentionAutocompleteProps) { const mx = useMatrixClient(); + const { versions } = useSpecVersions(); + const useAuthentication = versions.includes('v1.11'); const roomId: string = room.roomId!; const roomAliasOrId = room.getCanonicalAlias() || roomId; const members = useRoomMembers(mx, roomId); @@ -143,7 +146,8 @@ export function UserMentionAutocomplete({ /> ) : ( autoCompleteMembers.map((roomMember) => { - const avatarUrl = roomMember.getAvatarUrl(mx.baseUrl, 32, 32, 'crop', undefined, false); + const avatarMxcUrl = roomMember.getMxcAvatarUrl(); + const avatarUrl = avatarMxcUrl ? mx.mxcUrlToHttp(avatarMxcUrl, 32, 32, 'crop', undefined, false, useAuthentication) : undefined; return ( void; + useAuthentication?: boolean; }) { const activeGroupId = useAtomValue(activeGroupIdAtom); return ( @@ -381,7 +384,7 @@ function ImagePackSidebarStack({ height: toRem(24), objectFit: 'contain', }} - src={mx.mxcUrlToHttp(pack.getPackAvatarUrl(usage) ?? '') || pack.avatarUrl} + src={mxcUrlToHttp(mx, pack.getPackAvatarUrl(usage) ?? '', useAuthentication) || pack.avatarUrl} alt={label || 'Unknown Pack'} /> @@ -453,68 +456,70 @@ export function SearchEmojiGroup({ label, id, emojis: searchResult, + useAuthentication, }: { mx: MatrixClient; tab: EmojiBoardTab; label: string; id: string; emojis: Array; + useAuthentication?: boolean; }) { return ( {tab === EmojiBoardTab.Emoji ? searchResult.map((emoji) => - 'unicode' in emoji ? ( - - {emoji.unicode} - - ) : ( - - {emoji.body - - ) + 'unicode' in emoji ? ( + + {emoji.unicode} + + ) : ( + + {emoji.body + ) + ) : searchResult.map((emoji) => - 'unicode' in emoji ? null : ( - - {emoji.body - - ) - )} + 'unicode' in emoji ? null : ( + + {emoji.body + + ) + )} ); } export const CustomEmojiGroups = memo( - ({ mx, groups }: { mx: MatrixClient; groups: ImagePack[] }) => ( + ({ mx, groups, useAuthentication }: { mx: MatrixClient; groups: ImagePack[]; useAuthentication?: boolean }) => ( <> {groups.map((pack) => ( @@ -530,7 +535,7 @@ export const CustomEmojiGroups = memo( loading="lazy" className={css.CustomEmojiImg} alt={image.body || image.shortcode} - src={mx.mxcUrlToHttp(image.url) ?? image.url} + src={mxcUrlToHttp(mx, image.url, useAuthentication) ?? image.url} /> ))} @@ -540,7 +545,7 @@ export const CustomEmojiGroups = memo( ) ); -export const StickerGroups = memo(({ mx, groups }: { mx: MatrixClient; groups: ImagePack[] }) => ( +export const StickerGroups = memo(({ mx, groups, useAuthentication }: { mx: MatrixClient; groups: ImagePack[]; useAuthentication?: boolean }) => ( <> {groups.length === 0 && ( ))} @@ -645,6 +650,8 @@ export function EmojiBoard({ const setActiveGroupId = useSetAtom(activeGroupIdAtom); const mx = useMatrixClient(); + const { versions } = useSpecVersions(); + const useAuthentication = versions.includes('v1.11'); const emojiGroupLabels = useEmojiGroupLabels(); const emojiGroupIcons = useEmojiGroupIcons(); const imagePacks = useRelevantImagePacks(mx, usage, imagePackRooms); @@ -729,14 +736,14 @@ export function EmojiBoard({ } else if (emojiInfo.type === EmojiType.CustomEmoji && emojiPreviewRef.current) { const img = document.createElement('img'); img.className = css.CustomEmojiImg; - img.setAttribute('src', mx.mxcUrlToHttp(emojiInfo.data) || emojiInfo.data); + img.setAttribute('src', mxcUrlToHttp(mx, emojiInfo.data, useAuthentication) || emojiInfo.data); img.setAttribute('alt', emojiInfo.shortcode); emojiPreviewRef.current.textContent = ''; emojiPreviewRef.current.appendChild(img); } emojiPreviewTextRef.current.textContent = `:${emojiInfo.shortcode}:`; }, - [mx] + [mx, useAuthentication] ); const throttleEmojiHover = useThrottle(handleEmojiPreview, { @@ -829,6 +836,7 @@ export function EmojiBoard({ usage={usage} packs={imagePacks} onItemClick={handleScrollToGroup} + useAuthentication={useAuthentication} /> )} {emojiTab && ( @@ -890,13 +898,14 @@ export function EmojiBoard({ id={SEARCH_GROUP_ID} label={result.items.length ? 'Search Results' : 'No Results found'} emojis={result.items} + useAuthentication={useAuthentication} /> )} {emojiTab && recentEmojis.length > 0 && ( )} - {emojiTab && } - {stickerTab && } + {emojiTab && } + {stickerTab && } {emojiTab && } diff --git a/src/app/components/event-readers/EventReaders.tsx b/src/app/components/event-readers/EventReaders.tsx index 08e24a52b..a6163b8b0 100644 --- a/src/app/components/event-readers/EventReaders.tsx +++ b/src/app/components/event-readers/EventReaders.tsx @@ -21,6 +21,7 @@ import * as css from './EventReaders.css'; import { useMatrixClient } from '../../hooks/useMatrixClient'; import { openProfileViewer } from '../../../client/action/navigation'; import { UserAvatar } from '../user-avatar'; +import { useSpecVersions } from '../../hooks/useSpecVersions'; export type EventReadersProps = { room: Room; @@ -30,6 +31,8 @@ export type EventReadersProps = { export const EventReaders = as<'div', EventReadersProps>( ({ className, room, eventId, requestClose, ...props }, ref) => { const mx = useMatrixClient(); + const { versions } = useSpecVersions(); + const useAuthentication = versions.includes('v1.11'); const latestEventReaders = useRoomEventReaders(room, eventId); const getName = (userId: string) => @@ -55,9 +58,10 @@ export const EventReaders = as<'div', EventReadersProps>( {latestEventReaders.map((readerId) => { const name = getName(readerId); - const avatarUrl = room + const avatarMxcUrl = room .getMember(readerId) - ?.getAvatarUrl(mx.baseUrl, 100, 100, 'crop', undefined, false); + ?.getMxcAvatarUrl(); + const avatarUrl = avatarMxcUrl ? mx.mxcUrlToHttp(avatarMxcUrl, 100, 100, 'crop', undefined, false, useAuthentication) : undefined; return ( (({ className, mx, count, reaction, ...props }, ref) => ( +>(({ className, mx, count, reaction, useAuthentication, ...props }, ref) => ( ) : ( diff --git a/src/app/components/message/content/AudioContent.tsx b/src/app/components/message/content/AudioContent.tsx index 34777cc47..38fa95158 100644 --- a/src/app/components/message/content/AudioContent.tsx +++ b/src/app/components/message/content/AudioContent.tsx @@ -17,6 +17,8 @@ import { } from '../../../hooks/media'; import { useThrottle } from '../../../hooks/useThrottle'; import { secondsToMinutesAndSeconds } from '../../../utils/common'; +import { mxcUrlToHttp } from '../../../utils/matrix'; +import { useSpecVersions } from '../../../hooks/useSpecVersions'; const PLAY_TIME_THROTTLE_OPS = { wait: 500, @@ -44,11 +46,13 @@ export function AudioContent({ renderMediaControl, }: AudioContentProps) { const mx = useMatrixClient(); + const { versions } = useSpecVersions(); + const useAuthentication = versions.includes('v1.11'); const [srcState, loadSrc] = useAsyncCallback( useCallback( - () => getFileSrcUrl(mx.mxcUrlToHttp(url) ?? '', mimeType, encInfo), - [mx, url, mimeType, encInfo] + () => getFileSrcUrl(mxcUrlToHttp(mx, url, useAuthentication) ?? '', mimeType, encInfo), + [mx, url, useAuthentication, mimeType, encInfo] ) ); diff --git a/src/app/components/message/content/FileContent.tsx b/src/app/components/message/content/FileContent.tsx index f09c1e076..379d14563 100644 --- a/src/app/components/message/content/FileContent.tsx +++ b/src/app/components/message/content/FileContent.tsx @@ -30,6 +30,8 @@ import { } from '../../../utils/mimeTypes'; import * as css from './style.css'; import { stopPropagation } from '../../../utils/keyboard'; +import { mxcUrlToHttp } from '../../../utils/matrix'; +import { useSpecVersions } from '../../../hooks/useSpecVersions'; const renderErrorButton = (retry: () => void, text: string) => ( getFileSrcUrl(mx.mxcUrlToHttp(url) ?? '', mimeType, encInfo), - [mx, url, mimeType, encInfo] + () => getFileSrcUrl(mxcUrlToHttp(mx, url, useAuthentication) ?? '', mimeType, encInfo), + [mx, url, useAuthentication, mimeType, encInfo] ); const [textState, loadText] = useAsyncCallback( @@ -166,14 +170,16 @@ export type ReadPdfFileProps = { }; export function ReadPdfFile({ body, mimeType, url, encInfo, renderViewer }: ReadPdfFileProps) { const mx = useMatrixClient(); + const { versions } = useSpecVersions(); + const useAuthentication = versions.includes('v1.11'); const [pdfViewer, setPdfViewer] = useState(false); const [pdfState, loadPdf] = useAsyncCallback( useCallback(async () => { - const httpUrl = await getFileSrcUrl(mx.mxcUrlToHttp(url) ?? '', mimeType, encInfo); + const httpUrl = await getFileSrcUrl(mxcUrlToHttp(mx, url, useAuthentication) ?? '', mimeType, encInfo); setPdfViewer(true); return httpUrl; - }, [mx, url, mimeType, encInfo]) + }, [mx, url, useAuthentication, mimeType, encInfo]) ); return ( @@ -240,13 +246,15 @@ export type DownloadFileProps = { }; export function DownloadFile({ body, mimeType, url, info, encInfo }: DownloadFileProps) { const mx = useMatrixClient(); + const { versions } = useSpecVersions(); + const useAuthentication = versions.includes('v1.11'); const [downloadState, download] = useAsyncCallback( useCallback(async () => { - const httpUrl = await getFileSrcUrl(mx.mxcUrlToHttp(url) ?? '', mimeType, encInfo); + const httpUrl = await getFileSrcUrl(mxcUrlToHttp(mx, url, useAuthentication) ?? '', mimeType, encInfo); FileSaver.saveAs(httpUrl, body); return httpUrl; - }, [mx, url, mimeType, encInfo, body]) + }, [mx, url, useAuthentication, mimeType, encInfo, body]) ); return downloadState.status === AsyncStatus.Error ? ( diff --git a/src/app/components/message/content/ImageContent.tsx b/src/app/components/message/content/ImageContent.tsx index 90c46354e..798c60c55 100644 --- a/src/app/components/message/content/ImageContent.tsx +++ b/src/app/components/message/content/ImageContent.tsx @@ -27,6 +27,8 @@ import * as css from './style.css'; import { bytesToSize } from '../../../utils/common'; import { FALLBACK_MIMETYPE } from '../../../utils/mimeTypes'; import { stopPropagation } from '../../../utils/keyboard'; +import { mxcUrlToHttp } from '../../../utils/matrix'; +import { useSpecVersions } from '../../../hooks/useSpecVersions'; type RenderViewerProps = { src: string; @@ -69,6 +71,8 @@ export const ImageContent = as<'div', ImageContentProps>( ref ) => { const mx = useMatrixClient(); + const { versions } = useSpecVersions(); + const useAuthentication = versions.includes('v1.11'); const blurHash = info?.[MATRIX_BLUR_HASH_PROPERTY_NAME]; const [load, setLoad] = useState(false); @@ -77,8 +81,8 @@ export const ImageContent = as<'div', ImageContentProps>( const [srcState, loadSrc] = useAsyncCallback( useCallback( - () => getFileSrcUrl(mx.mxcUrlToHttp(url) ?? '', mimeType || FALLBACK_MIMETYPE, encInfo), - [mx, url, mimeType, encInfo] + () => getFileSrcUrl(mxcUrlToHttp(mx, url, useAuthentication) ?? '', mimeType || FALLBACK_MIMETYPE, encInfo), + [mx, url, useAuthentication, mimeType, encInfo] ) ); diff --git a/src/app/components/message/content/ThumbnailContent.tsx b/src/app/components/message/content/ThumbnailContent.tsx index 9d940f3a7..4324376d1 100644 --- a/src/app/components/message/content/ThumbnailContent.tsx +++ b/src/app/components/message/content/ThumbnailContent.tsx @@ -3,6 +3,8 @@ import { IThumbnailContent } from '../../../../types/matrix/common'; import { useMatrixClient } from '../../../hooks/useMatrixClient'; import { AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback'; import { getFileSrcUrl } from './util'; +import { mxcUrlToHttp } from '../../../utils/matrix'; +import { useSpecVersions } from '../../../hooks/useSpecVersions'; export type ThumbnailContentProps = { info: IThumbnailContent; @@ -10,6 +12,8 @@ export type ThumbnailContentProps = { }; export function ThumbnailContent({ info, renderImage }: ThumbnailContentProps) { const mx = useMatrixClient(); + const { versions } = useSpecVersions(); + const useAuthentication = versions.includes('v1.11'); const [thumbSrcState, loadThumbSrc] = useAsyncCallback( useCallback(() => { @@ -19,11 +23,11 @@ export function ThumbnailContent({ info, renderImage }: ThumbnailContentProps) { throw new Error('Failed to load thumbnail'); } return getFileSrcUrl( - mx.mxcUrlToHttp(thumbMxcUrl) ?? '', + mxcUrlToHttp(mx, thumbMxcUrl, useAuthentication) ?? '', thumbInfo.mimetype, info.thumbnail_file ); - }, [mx, info]) + }, [mx, info, useAuthentication]) ); useEffect(() => { diff --git a/src/app/components/message/content/VideoContent.tsx b/src/app/components/message/content/VideoContent.tsx index b08512a4a..e83e4595d 100644 --- a/src/app/components/message/content/VideoContent.tsx +++ b/src/app/components/message/content/VideoContent.tsx @@ -25,6 +25,8 @@ import { AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback'; import { getFileSrcUrl } from './util'; import { bytesToSize } from '../../../../util/common'; import { millisecondsToMinutesAndSeconds } from '../../../utils/common'; +import { mxcUrlToHttp } from '../../../utils/matrix'; +import { useSpecVersions } from '../../../hooks/useSpecVersions'; type RenderVideoProps = { title: string; @@ -61,6 +63,8 @@ export const VideoContent = as<'div', VideoContentProps>( ref ) => { const mx = useMatrixClient(); + const { versions } = useSpecVersions(); + const useAuthentication = versions.includes('v1.11'); const blurHash = info.thumbnail_info?.[MATRIX_BLUR_HASH_PROPERTY_NAME]; const [load, setLoad] = useState(false); @@ -68,8 +72,8 @@ export const VideoContent = as<'div', VideoContentProps>( const [srcState, loadSrc] = useAsyncCallback( useCallback( - () => getFileSrcUrl(mx.mxcUrlToHttp(url) ?? '', mimeType, encInfo), - [mx, url, mimeType, encInfo] + () => getFileSrcUrl(mxcUrlToHttp(mx, url, useAuthentication) ?? '', mimeType, encInfo), + [mx, url, useAuthentication, mimeType, encInfo] ) ); diff --git a/src/app/components/room-card/RoomCard.tsx b/src/app/components/room-card/RoomCard.tsx index 2bb10e3c3..1ca7813f0 100644 --- a/src/app/components/room-card/RoomCard.tsx +++ b/src/app/components/room-card/RoomCard.tsx @@ -21,7 +21,7 @@ import classNames from 'classnames'; import FocusTrap from 'focus-trap-react'; import * as css from './style.css'; import { RoomAvatar } from '../room-avatar'; -import { getMxIdLocalPart } from '../../utils/matrix'; +import { getMxIdLocalPart, mxcUrlToHttp } from '../../utils/matrix'; import { nameInitials } from '../../utils/common'; import { millify } from '../../plugins/millify'; import { useMatrixClient } from '../../hooks/useMatrixClient'; @@ -32,6 +32,7 @@ import { useJoinedRoomId } from '../../hooks/useJoinedRoomId'; import { useElementSizeObserver } from '../../hooks/useElementSizeObserver'; import { getRoomAvatarUrl, getStateEvent } from '../../utils/room'; import { useStateEventCallback } from '../../hooks/useStateEventCallback'; +import { useSpecVersions } from '../../hooks/useSpecVersions'; type GridColumnCount = '1' | '2' | '3'; const getGridColumnCount = (gridWidth: number): GridColumnCount => { @@ -161,6 +162,8 @@ export const RoomCard = as<'div', RoomCardProps>( ref ) => { const mx = useMatrixClient(); + const { versions } = useSpecVersions(); + const useAuthentication = versions.includes('v1.11'); const joinedRoomId = useJoinedRoomId(allRooms, roomIdOrAlias); const joinedRoom = mx.getRoom(joinedRoomId); const [topicEvent, setTopicEvent] = useState(() => @@ -171,8 +174,8 @@ export const RoomCard = as<'div', RoomCardProps>( const fallbackTopic = roomIdOrAlias; const avatar = joinedRoom - ? getRoomAvatarUrl(mx, joinedRoom, 96) - : avatarUrl && mx.mxcUrlToHttp(avatarUrl, 96, 96, 'crop'); + ? getRoomAvatarUrl(mx, joinedRoom, 96, useAuthentication) + : avatarUrl && mxcUrlToHttp(mx, avatarUrl, useAuthentication, 96, 96, 'crop'); const roomName = joinedRoom?.name || name || fallbackName; const roomTopic = diff --git a/src/app/components/room-intro/RoomIntro.tsx b/src/app/components/room-intro/RoomIntro.tsx index 0fed123d3..28be5daf7 100644 --- a/src/app/components/room-intro/RoomIntro.tsx +++ b/src/app/components/room-intro/RoomIntro.tsx @@ -6,7 +6,7 @@ import { openInviteUser } from '../../../client/action/navigation'; import { IRoomCreateContent, Membership, StateEvent } from '../../../types/matrix/room'; import { getMemberDisplayName, getStateEvent } from '../../utils/room'; import { useMatrixClient } from '../../hooks/useMatrixClient'; -import { getMxIdLocalPart } from '../../utils/matrix'; +import { getMxIdLocalPart, mxcUrlToHttp } from '../../utils/matrix'; import { AsyncStatus, useAsyncCallback } from '../../hooks/useAsyncCallback'; import { timeDayMonthYear, timeHourMinute } from '../../utils/time'; import { useRoomNavigate } from '../../hooks/useRoomNavigate'; @@ -14,6 +14,7 @@ import { RoomAvatar } from '../room-avatar'; import { nameInitials } from '../../utils/common'; import { useRoomAvatar, useRoomName, useRoomTopic } from '../../hooks/useRoomMeta'; import { mDirectAtom } from '../../state/mDirectList'; +import { useSpecVersions } from '../../hooks/useSpecVersions'; export type RoomIntroProps = { room: Room; @@ -21,6 +22,8 @@ export type RoomIntroProps = { export const RoomIntro = as<'div', RoomIntroProps>(({ room, ...props }, ref) => { const mx = useMatrixClient(); + const { versions } = useSpecVersions(); + const useAuthentication = versions.includes('v1.11'); const { navigateRoom } = useRoomNavigate(); const mDirects = useAtomValue(mDirectAtom); @@ -28,7 +31,7 @@ export const RoomIntro = as<'div', RoomIntroProps>(({ room, ...props }, ref) => const avatarMxc = useRoomAvatar(room, mDirects.has(room.roomId)); const name = useRoomName(room); const topic = useRoomTopic(room); - const avatarHttpUrl = avatarMxc ? mx.mxcUrlToHttp(avatarMxc) : undefined; + const avatarHttpUrl = avatarMxc ? mxcUrlToHttp(mx, avatarMxc, useAuthentication) : undefined; const createContent = createEvent?.getContent(); const ts = createEvent?.getTs(); diff --git a/src/app/components/url-preview/UrlPreviewCard.tsx b/src/app/components/url-preview/UrlPreviewCard.tsx index 07c25f8a1..c33b98504 100644 --- a/src/app/components/url-preview/UrlPreviewCard.tsx +++ b/src/app/components/url-preview/UrlPreviewCard.tsx @@ -10,12 +10,16 @@ import { } from '../../hooks/useIntersectionObserver'; import * as css from './UrlPreviewCard.css'; import { tryDecodeURIComponent } from '../../utils/dom'; +import { mxcUrlToHttp } from '../../utils/matrix'; +import { useSpecVersions } from '../../hooks/useSpecVersions'; const linkStyles = { color: color.Success.Main }; export const UrlPreviewCard = as<'div', { url: string; ts: number }>( ({ url, ts, ...props }, ref) => { const mx = useMatrixClient(); + const { versions } = useSpecVersions(); + const useAuthentication = versions.includes('v1.11'); const [previewStatus, loadPreview] = useAsyncCallback( useCallback(() => mx.getUrlPreview(url, ts), [url, ts, mx]) ); @@ -27,7 +31,7 @@ export const UrlPreviewCard = as<'div', { url: string; ts: number }>( if (previewStatus.status === AsyncStatus.Error) return null; const renderContent = (prev: IPreviewUrlResponse) => { - const imgUrl = mx.mxcUrlToHttp(prev['og:image'] || '', 256, 256, 'scale', false); + const imgUrl = mxcUrlToHttp(mx, prev['og:image'] || '', useAuthentication, 256, 256, 'scale', false); return ( <> diff --git a/src/app/features/lobby/LobbyHeader.tsx b/src/app/features/lobby/LobbyHeader.tsx index fa415bd2c..ed5373b38 100644 --- a/src/app/features/lobby/LobbyHeader.tsx +++ b/src/app/features/lobby/LobbyHeader.tsx @@ -33,6 +33,8 @@ import { LeaveSpacePrompt } from '../../components/leave-space-prompt'; import { stopPropagation } from '../../utils/keyboard'; import { ScreenSize, useScreenSizeContext } from '../../hooks/useScreenSize'; import { BackRouteHandler } from '../../components/BackRouteHandler'; +import { mxcUrlToHttp } from '../../utils/matrix'; +import { useSpecVersions } from '../../hooks/useSpecVersions'; type LobbyMenuProps = { roomId: string; @@ -122,6 +124,8 @@ type LobbyHeaderProps = { }; export function LobbyHeader({ showProfile, powerLevels }: LobbyHeaderProps) { const mx = useMatrixClient(); + const { versions } = useSpecVersions(); + const useAuthentication = versions.includes('v1.11'); const space = useSpace(); const setPeopleDrawer = useSetSetting(settingsAtom, 'isPeopleDrawer'); const [menuAnchor, setMenuAnchor] = useState(); @@ -129,7 +133,7 @@ export function LobbyHeader({ showProfile, powerLevels }: LobbyHeaderProps) { const name = useRoomName(space); const avatarMxc = useRoomAvatar(space); - const avatarUrl = avatarMxc ? mx.mxcUrlToHttp(avatarMxc, 96, 96, 'crop') ?? undefined : undefined; + const avatarUrl = avatarMxc ? mxcUrlToHttp(mx, avatarMxc, useAuthentication, 96, 96, 'crop') ?? undefined : undefined; const handleOpenMenu: MouseEventHandler = (evt) => { setMenuAnchor(evt.currentTarget.getBoundingClientRect()); diff --git a/src/app/features/lobby/LobbyHero.tsx b/src/app/features/lobby/LobbyHero.tsx index a2b31e8fb..e652fd919 100644 --- a/src/app/features/lobby/LobbyHero.tsx +++ b/src/app/features/lobby/LobbyHero.tsx @@ -11,15 +11,19 @@ import { RoomTopicViewer } from '../../components/room-topic-viewer'; import * as css from './LobbyHero.css'; import { PageHero } from '../../components/page'; import { onEnterOrSpace, stopPropagation } from '../../utils/keyboard'; +import { mxcUrlToHttp } from '../../utils/matrix'; +import { useSpecVersions } from '../../hooks/useSpecVersions'; export function LobbyHero() { const mx = useMatrixClient(); + const { versions } = useSpecVersions(); + const useAuthentication = versions.includes('v1.11'); const space = useSpace(); const name = useRoomName(space); const topic = useRoomTopic(space); const avatarMxc = useRoomAvatar(space); - const avatarUrl = avatarMxc ? mx.mxcUrlToHttp(avatarMxc, 96, 96, 'crop') ?? undefined : undefined; + const avatarUrl = avatarMxc ? mxcUrlToHttp(mx, avatarMxc, useAuthentication, 96, 96, 'crop') ?? undefined : undefined; return ( ( ref ) => { const mx = useMatrixClient(); + const { versions } = useSpecVersions(); + const useAuthentication = versions.includes('v1.11'); const { roomId, content } = item; const room = getRoom(roomId); const targetRef = useRef(null); @@ -364,7 +368,7 @@ export const RoomItemCard = as<'div', RoomItemCardProps>( name={localSummary.name} topic={localSummary.topic} avatarUrl={ - dm ? getDirectRoomAvatarUrl(mx, room, 96) : getRoomAvatarUrl(mx, room, 96) + dm ? getDirectRoomAvatarUrl(mx, room, 96, useAuthentication) : getRoomAvatarUrl(mx, room, 96, useAuthentication) } memberCount={localSummary.memberCount} suggested={content.suggested} @@ -418,8 +422,8 @@ export const RoomItemCard = as<'div', RoomItemCardProps>( topic={summaryState.data.topic} avatarUrl={ summaryState.data?.avatar_url - ? mx.mxcUrlToHttp(summaryState.data.avatar_url, 96, 96, 'crop') ?? - undefined + ? mxcUrlToHttp(mx, summaryState.data.avatar_url, useAuthentication, 96, 96, 'crop') ?? + undefined : undefined } memberCount={summaryState.data.num_joined_members} diff --git a/src/app/features/lobby/SpaceItem.tsx b/src/app/features/lobby/SpaceItem.tsx index 04f7e2cce..3e3c32141 100644 --- a/src/app/features/lobby/SpaceItem.tsx +++ b/src/app/features/lobby/SpaceItem.tsx @@ -35,6 +35,8 @@ import { ErrorCode } from '../../cs-errorcode'; import { useDraggableItem } from './DnD'; import { openCreateRoom, openSpaceAddExisting } from '../../../client/action/navigation'; import { stopPropagation } from '../../utils/keyboard'; +import { mxcUrlToHttp } from '../../utils/matrix'; +import { useSpecVersions } from '../../hooks/useSpecVersions'; function SpaceProfileLoading() { return ( @@ -408,6 +410,8 @@ export const SpaceItemCard = as<'div', SpaceItemCardProps>( ref ) => { const mx = useMatrixClient(); + const { versions } = useSpecVersions(); + const useAuthentication = versions.includes('v1.11'); const { roomId, content } = item; const space = getRoom(roomId); const targetRef = useRef(null); @@ -432,7 +436,7 @@ export const SpaceItemCard = as<'div', SpaceItemCardProps>( ( name={summaryState.data.name || summaryState.data.canonical_alias || roomId} avatarUrl={ summaryState.data?.avatar_url - ? mx.mxcUrlToHttp(summaryState.data.avatar_url, 96, 96, 'crop') ?? - undefined + ? mxcUrlToHttp(mx, summaryState.data.avatar_url, useAuthentication, 96, 96, 'crop') ?? + undefined : undefined } suggested={content.suggested} diff --git a/src/app/features/message-search/SearchResultGroup.tsx b/src/app/features/message-search/SearchResultGroup.tsx index 84ba3a763..a3a67eda8 100644 --- a/src/app/features/message-search/SearchResultGroup.tsx +++ b/src/app/features/message-search/SearchResultGroup.tsx @@ -13,7 +13,7 @@ import { makeMentionCustomProps, renderMatrixMention, } from '../../plugins/react-custom-html-parser'; -import { getMxIdLocalPart } from '../../utils/matrix'; +import { getMxIdLocalPart, mxcUrlToHttp } from '../../utils/matrix'; import { useMatrixEventRenderer } from '../../hooks/useMatrixEventRenderer'; import { GetContentCallback, MessageEvent, StateEvent } from '../../../types/matrix/room'; import { @@ -38,6 +38,7 @@ import { SequenceCard } from '../../components/sequence-card'; import { UserAvatar } from '../../components/user-avatar'; import { useMentionClickHandler } from '../../hooks/useMentionClickHandler'; import { useSpoilerClickHandler } from '../../hooks/useSpoilerClickHandler'; +import { useSpecVersions } from '../../hooks/useSpecVersions'; type SearchResultGroupProps = { room: Room; @@ -56,6 +57,8 @@ export function SearchResultGroup({ onOpen, }: SearchResultGroupProps) { const mx = useMatrixClient(); + const { versions } = useSpecVersions(); + const useAuthentication = versions.includes('v1.11'); const highlightRegex = useMemo(() => makeHighlightRegex(highlights), [highlights]); const mentionClickHandler = useMentionClickHandler(room.roomId); @@ -75,10 +78,11 @@ export function SearchResultGroup({ getReactCustomHtmlParser(mx, room.roomId, { linkifyOpts, highlightRegex, + useAuthentication, handleSpoilerClick: spoilerClickHandler, handleMentionClick: mentionClickHandler, }), - [mx, room, linkifyOpts, highlightRegex, mentionClickHandler, spoilerClickHandler] + [mx, room, linkifyOpts, highlightRegex, mentionClickHandler, spoilerClickHandler, useAuthentication] ); const renderMatrixEvent = useMatrixEventRenderer<[IEventWithRoomId, string, GetContentCallback]>( @@ -161,7 +165,7 @@ export function SearchResultGroup({ ( @@ -209,7 +213,7 @@ export function SearchResultGroup({ userId={event.sender} src={ senderAvatarMxc - ? mx.mxcUrlToHttp(senderAvatarMxc, 48, 48, 'crop') ?? undefined + ? mxcUrlToHttp(mx, senderAvatarMxc, useAuthentication, 48, 48, 'crop') ?? undefined : undefined } alt={displayName} diff --git a/src/app/features/room-nav/RoomNavItem.tsx b/src/app/features/room-nav/RoomNavItem.tsx index aa7b468ef..c525ab2ab 100644 --- a/src/app/features/room-nav/RoomNavItem.tsx +++ b/src/app/features/room-nav/RoomNavItem.tsx @@ -38,6 +38,7 @@ import { stopPropagation } from '../../utils/keyboard'; import { getMatrixToRoom } from '../../plugins/matrix-to'; import { getCanonicalAliasOrRoomId, isRoomAlias } from '../../utils/matrix'; import { getViaServers } from '../../plugins/via-servers'; +import { useSpecVersions } from '../../hooks/useSpecVersions'; type RoomNavItemMenuProps = { room: Room; @@ -175,6 +176,8 @@ export function RoomNavItem({ linkPath, }: RoomNavItemProps) { const mx = useMatrixClient(); + const { versions } = useSpecVersions(); + const useAuthentication = versions.includes('v1.11'); const [hover, setHover] = useState(false); const { hoverProps } = useHover({ onHoverChange: setHover }); const { focusWithinProps } = useFocusWithin({ onFocusWithinChange: setHover }); @@ -217,7 +220,7 @@ export function RoomNavItem({ ( diff --git a/src/app/features/room/MembersDrawer.tsx b/src/app/features/room/MembersDrawer.tsx index 15d074121..1b538ffc1 100644 --- a/src/app/features/room/MembersDrawer.tsx +++ b/src/app/features/room/MembersDrawer.tsx @@ -55,6 +55,7 @@ import { ScrollTopContainer } from '../../components/scroll-top-container'; import { UserAvatar } from '../../components/user-avatar'; import { useRoomTypingMember } from '../../hooks/useRoomTypingMembers'; import { stopPropagation } from '../../utils/keyboard'; +import { useSpecVersions } from '../../hooks/useSpecVersions'; export const MembershipFilters = { filterJoined: (m: RoomMember) => m.membership === Membership.Join, @@ -171,6 +172,8 @@ type MembersDrawerProps = { }; export function MembersDrawer({ room, members }: MembersDrawerProps) { const mx = useMatrixClient(); + const { versions } = useSpecVersions(); + const useAuthentication = versions.includes('v1.11'); const scrollRef = useRef(null); const searchInputRef = useRef(null); const scrollTopAnchorRef = useRef(null); @@ -426,9 +429,8 @@ export function MembersDrawer({ room, members }: MembersDrawerProps) { }} after={} > - {`${result.items.length || 'No'} ${ - result.items.length === 1 ? 'Result' : 'Results' - }`} + {`${result.items.length || 'No'} ${result.items.length === 1 ? 'Result' : 'Results' + }`} ) } @@ -483,14 +485,16 @@ export function MembersDrawer({ room, members }: MembersDrawerProps) { const member = tagOrMember; const name = getName(member); - const avatarUrl = member.getAvatarUrl( - mx.baseUrl, + const avatarMxcUrl = member.getMxcAvatarUrl(); + const avatarUrl = avatarMxcUrl ? mx.mxcUrlToHttp( + avatarMxcUrl, 100, 100, 'crop', undefined, - false - ); + false, + useAuthentication + ) : undefined; return ( ( ({ editor, fileDropContainerRef, roomId, room }, ref) => { const mx = useMatrixClient(); + const { versions } = useSpecVersions(); + const useAuthentication = versions.includes('v1.11'); const [enterForNewline] = useSetting(settingsAtom, 'enterForNewline'); const [isMarkdown] = useSetting(settingsAtom, 'isMarkdown'); const commands = useCommands(mx, room); @@ -366,7 +369,7 @@ export const RoomInput = forwardRef( }; const handleStickerSelect = async (mxc: string, shortcode: string, label: string) => { - const stickerUrl = mx.mxcUrlToHttp(mxc); + const stickerUrl = mxcUrlToHttp(mx, mxc, useAuthentication); if (!stickerUrl) return; const info = await getImageInfo( diff --git a/src/app/features/room/RoomTimeline.tsx b/src/app/features/room/RoomTimeline.tsx index d86ea4d96..c47cb35b7 100644 --- a/src/app/features/room/RoomTimeline.tsx +++ b/src/app/features/room/RoomTimeline.tsx @@ -122,6 +122,7 @@ import { roomToUnreadAtom } from '../../state/room/roomToUnread'; import { useMentionClickHandler } from '../../hooks/useMentionClickHandler'; import { useSpoilerClickHandler } from '../../hooks/useSpoilerClickHandler'; import { useRoomNavigate } from '../../hooks/useRoomNavigate'; +import { useSpecVersions } from '../../hooks/useSpecVersions'; const TimelineFloat = as<'div', css.TimelineFloatVariants>( ({ position, className, ...props }, ref) => ( @@ -310,9 +311,9 @@ const useTimelinePagination = ( range: offsetRange > 0 ? { - start: currentTimeline.range.start + offsetRange, - end: currentTimeline.range.end + offsetRange, - } + start: currentTimeline.range.start + offsetRange, + end: currentTimeline.range.end + offsetRange, + } : { ...currentTimeline.range }, })); }; @@ -331,7 +332,7 @@ const useTimelinePagination = ( if ( !paginationToken && getTimelinesEventsCount(lTimelines) !== - getTimelinesEventsCount(getLinkedTimelines(timelineToPaginate)) + getTimelinesEventsCount(getLinkedTimelines(timelineToPaginate)) ) { recalibratePagination(lTimelines, timelinesEventsCount, backwards); return; @@ -437,6 +438,8 @@ const getRoomUnreadInfo = (room: Room, scrollTo = false) => { export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimelineProps) { const mx = useMatrixClient(); + const { versions } = useSpecVersions(); + const useAuthentication = versions.includes('v1.11'); const encryptedRoom = mx.isRoomEncrypted(room.roomId); const [messageLayout] = useSetting(settingsAtom, 'messageLayout'); const [messageSpacing] = useSetting(settingsAtom, 'messageSpacing'); @@ -490,10 +493,10 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli const [focusItem, setFocusItem] = useState< | { - index: number; - scrollTo: boolean; - highlight: boolean; - } + index: number; + scrollTo: boolean; + highlight: boolean; + } | undefined >(); const alive = useAlive(); @@ -511,10 +514,11 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli () => getReactCustomHtmlParser(mx, room.roomId, { linkifyOpts, + useAuthentication, handleSpoilerClick: spoilerClickHandler, handleMentionClick: mentionClickHandler, }), - [mx, room, linkifyOpts, spoilerClickHandler, mentionClickHandler] + [mx, room, linkifyOpts, spoilerClickHandler, mentionClickHandler, useAuthentication] ); const parseMemberEvent = useMemberEventParser(); @@ -1466,14 +1470,14 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli const eventJSX = reactionOrEditEvent(mEvent) ? null : renderMatrixEvent( - mEvent.getType(), - typeof mEvent.getStateKey() === 'string', - mEventId, - mEvent, - item, - timelineSet, - collapsed - ); + mEvent.getType(), + typeof mEvent.getStateKey() === 'string', + mEventId, + mEvent, + item, + timelineSet, + collapsed + ); prevEvent = mEvent; isPrevRendered = !!eventJSX; @@ -1555,9 +1559,8 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli {!canPaginateBack && rangeAtStart && getItems().length > 0 && (
      diff --git a/src/app/features/room/RoomViewHeader.tsx b/src/app/features/room/RoomViewHeader.tsx index 0b8ef74ea..eaa90970c 100644 --- a/src/app/features/room/RoomViewHeader.tsx +++ b/src/app/features/room/RoomViewHeader.tsx @@ -36,7 +36,7 @@ import { useSetSetting } from '../../state/hooks/settings'; import { settingsAtom } from '../../state/settings'; import { useSpaceOptionally } from '../../hooks/useSpace'; import { getHomeSearchPath, getSpaceSearchPath, withSearchParam } from '../../pages/pathUtils'; -import { getCanonicalAliasOrRoomId, isRoomAlias } from '../../utils/matrix'; +import { getCanonicalAliasOrRoomId, isRoomAlias, mxcUrlToHttp } from '../../utils/matrix'; import { _SearchPathSearchParams } from '../../pages/paths'; import * as css from './RoomViewHeader.css'; import { useRoomUnread } from '../../state/hooks/unread'; @@ -53,6 +53,7 @@ import { stopPropagation } from '../../utils/keyboard'; import { getMatrixToRoom } from '../../plugins/matrix-to'; import { getViaServers } from '../../plugins/via-servers'; import { BackRouteHandler } from '../../components/BackRouteHandler'; +import { useSpecVersions } from '../../hooks/useSpecVersions'; type RoomMenuProps = { room: Room; @@ -174,6 +175,8 @@ const RoomMenu = forwardRef(({ room, requestClose export function RoomViewHeader() { const navigate = useNavigate(); const mx = useMatrixClient(); + const { versions } = useSpecVersions(); + const useAuthentication = versions.includes('v1.11'); const screenSize = useScreenSizeContext(); const room = useRoom(); const space = useSpaceOptionally(); @@ -185,7 +188,7 @@ export function RoomViewHeader() { const avatarMxc = useRoomAvatar(room, mDirects.has(room.roomId)); const name = useRoomName(room); const topic = useRoomTopic(room); - const avatarUrl = avatarMxc ? mx.mxcUrlToHttp(avatarMxc, 96, 96, 'crop') ?? undefined : undefined; + const avatarUrl = avatarMxc ? mxcUrlToHttp(mx, avatarMxc, useAuthentication, 96, 96, 'crop') ?? undefined : undefined; const setPeopleDrawer = useSetSetting(settingsAtom, 'isPeopleDrawer'); diff --git a/src/app/features/room/message/Message.tsx b/src/app/features/room/message/Message.tsx index d8b2b3e56..94a5825c4 100644 --- a/src/app/features/room/message/Message.tsx +++ b/src/app/features/room/message/Message.tsx @@ -51,7 +51,7 @@ import { getMemberAvatarMxc, getMemberDisplayName, } from '../../../utils/room'; -import { getCanonicalAliasOrRoomId, getMxIdLocalPart, isRoomAlias } from '../../../utils/matrix'; +import { getCanonicalAliasOrRoomId, getMxIdLocalPart, isRoomAlias, mxcUrlToHttp } from '../../../utils/matrix'; import { MessageLayout, MessageSpacing } from '../../../state/settings'; import { useMatrixClient } from '../../../hooks/useMatrixClient'; import { useRecentEmoji } from '../../../hooks/useRecentEmoji'; @@ -67,6 +67,7 @@ import { copyToClipboard } from '../../../utils/dom'; import { stopPropagation } from '../../../utils/keyboard'; import { getMatrixToRoomEvent } from '../../../plugins/matrix-to'; import { getViaServers } from '../../../plugins/via-servers'; +import { useSpecVersions } from '../../../hooks/useSpecVersions'; export type ReactionHandler = (keyOrMxc: string, shortcode: string) => void; @@ -234,9 +235,9 @@ export const MessageSourceCodeItem = as< const getContent = (evt: MatrixEvent) => evt.isEncrypted() ? { - [`<== DECRYPTED_EVENT ==>`]: evt.getEffectiveEvent(), - [`<== ORIGINAL_EVENT ==>`]: evt.event, - } + [`<== DECRYPTED_EVENT ==>`]: evt.getEffectiveEvent(), + [`<== ORIGINAL_EVENT ==>`]: evt.event, + } : evt.event; const getText = (): string => { @@ -650,6 +651,8 @@ export const Message = as<'div', MessageProps>( ref ) => { const mx = useMatrixClient(); + const { versions } = useSpecVersions(); + const useAuthentication = versions.includes('v1.11'); const senderId = mEvent.getSender() ?? ''; const [hover, setHover] = useState(false); const { hoverProps } = useHover({ onHoverChange: setHover }); @@ -709,7 +712,7 @@ export const Message = as<'div', MessageProps>( userId={senderId} src={ senderAvatarMxc - ? mx.mxcUrlToHttp(senderAvatarMxc, 48, 48, 'crop') ?? undefined + ? mxcUrlToHttp(mx, senderAvatarMxc, useAuthentication, 48, 48, 'crop') ?? undefined : undefined } alt={senderDisplayName} @@ -950,26 +953,26 @@ export const Message = as<'div', MessageProps>( {((!mEvent.isRedacted() && canDelete) || mEvent.getSender() !== mx.getUserId()) && ( - <> - - - {!mEvent.isRedacted() && canDelete && ( - - )} - {mEvent.getSender() !== mx.getUserId() && ( - - )} - - - )} + <> + + + {!mEvent.isRedacted() && canDelete && ( + + )} + {mEvent.getSender() !== mx.getUserId() && ( + + )} + + + )}
      } @@ -1093,26 +1096,26 @@ export const Event = as<'div', EventProps>( {((!mEvent.isRedacted() && canDelete && !stateEvent) || (mEvent.getSender() !== mx.getUserId() && !stateEvent)) && ( - <> - - - {!mEvent.isRedacted() && canDelete && ( - - )} - {mEvent.getSender() !== mx.getUserId() && ( - - )} - - - )} + <> + + + {!mEvent.isRedacted() && canDelete && ( + + )} + {mEvent.getSender() !== mx.getUserId() && ( + + )} + + + )} } diff --git a/src/app/features/room/message/Reactions.tsx b/src/app/features/room/message/Reactions.tsx index a6d7f553b..258ab6292 100644 --- a/src/app/features/room/message/Reactions.tsx +++ b/src/app/features/room/message/Reactions.tsx @@ -22,6 +22,7 @@ import { useRelations } from '../../../hooks/useRelations'; import * as css from './styles.css'; import { ReactionViewer } from '../reaction-viewer'; import { stopPropagation } from '../../../utils/keyboard'; +import { useSpecVersions } from '../../../hooks/useSpecVersions'; export type ReactionsProps = { room: Room; @@ -33,6 +34,8 @@ export type ReactionsProps = { export const Reactions = as<'div', ReactionsProps>( ({ className, room, relations, mEventId, canSendReaction, onReactionToggle, ...props }, ref) => { const mx = useMatrixClient(); + const { versions } = useSpecVersions(); + const useAuthentication = versions.includes('v1.11'); const [viewer, setViewer] = useState(false); const myUserId = mx.getUserId(); const reactions = useRelations( @@ -86,6 +89,7 @@ export const Reactions = as<'div', ReactionsProps>( onClick={canSendReaction ? () => onReactionToggle(mEventId, key) : undefined} onContextMenu={handleViewReaction} aria-disabled={!canSendReaction} + useAuthentication={useAuthentication} /> )} diff --git a/src/app/features/room/reaction-viewer/ReactionViewer.tsx b/src/app/features/room/reaction-viewer/ReactionViewer.tsx index 1c1b79a78..9e166a9ed 100644 --- a/src/app/features/room/reaction-viewer/ReactionViewer.tsx +++ b/src/app/features/room/reaction-viewer/ReactionViewer.tsx @@ -25,6 +25,7 @@ import { useRelations } from '../../../hooks/useRelations'; import { Reaction } from '../../../components/message'; import { getHexcodeForEmoji, getShortcodeFor } from '../../../plugins/emoji'; import { UserAvatar } from '../../../components/user-avatar'; +import { useSpecVersions } from '../../../hooks/useSpecVersions'; export type ReactionViewerProps = { room: Room; @@ -35,6 +36,8 @@ export type ReactionViewerProps = { export const ReactionViewer = as<'div', ReactionViewerProps>( ({ className, room, initialKey, relations, requestClose, ...props }, ref) => { const mx = useMatrixClient(); + const { versions } = useSpecVersions(); + const useAuthentication = versions.includes('v1.11'); const reactions = useRelations( relations, useCallback((rel) => [...(rel.getSortedAnnotationsByKey() ?? [])], []) @@ -81,6 +84,7 @@ export const ReactionViewer = as<'div', ReactionViewerProps>( count={evts.size} aria-selected={key === selectedKey} onClick={() => setSelectedKey(key)} + useAuthentication={useAuthentication} /> ); })} @@ -107,14 +111,16 @@ export const ReactionViewer = as<'div', ReactionViewerProps>( const member = room.getMember(senderId); const name = (member ? getName(member) : getMxIdLocalPart(senderId)) ?? senderId; - const avatarUrl = member?.getAvatarUrl( - mx.baseUrl, + const avatarMxcUrl = member?.getMxcAvatarUrl(); + const avatarUrl = avatarMxcUrl ? mx.mxcUrlToHttp( + avatarMxcUrl, 100, 100, 'crop', undefined, - false - ); + false, + useAuthentication + ) : undefined; return ( (); const unreadCacheRef = useRef>(new Map()); const mx = useMatrixClient(); + const { versions } = useSpecVersions(); + const useAuthentication = versions.includes('v1.11'); const [showNotifications] = useSetting(settingsAtom, 'showNotifications'); const [notificationSound] = useSetting(settingsAtom, 'isNotificationSounds'); @@ -216,7 +219,7 @@ function MessageNotifications() { notify({ roomName: room.name ?? 'Unknown', roomAvatar: avatarMxc - ? mx.mxcUrlToHttp(avatarMxc, 96, 96, 'crop') ?? undefined + ? mxcUrlToHttp(mx, avatarMxc, useAuthentication, 96, 96, 'crop') ?? undefined : undefined, username: getMemberDisplayName(room, sender) ?? getMxIdLocalPart(sender) ?? sender, roomId: room.roomId, diff --git a/src/app/pages/client/inbox/Invites.tsx b/src/app/pages/client/inbox/Invites.tsx index 18993081b..12ca65bbc 100644 --- a/src/app/pages/client/inbox/Invites.tsx +++ b/src/app/pages/client/inbox/Invites.tsx @@ -42,6 +42,7 @@ import { useRoomNavigate } from '../../../hooks/useRoomNavigate'; import { useRoomTopic } from '../../../hooks/useRoomMeta'; import { ScreenSize, useScreenSizeContext } from '../../../hooks/useScreenSize'; import { BackRouteHandler } from '../../../components/BackRouteHandler'; +import { useSpecVersions } from '../../../hooks/useSpecVersions'; const COMPACT_CARD_WIDTH = 548; @@ -54,6 +55,8 @@ type InviteCardProps = { }; function InviteCard({ room, userId, direct, compact, onNavigate }: InviteCardProps) { const mx = useMatrixClient(); + const { versions } = useSpecVersions(); + const useAuthentication = versions.includes('v1.11'); const roomName = room.name || room.getCanonicalAlias() || room.roomId; const member = room.getMember(userId); const memberEvent = member?.events.member; @@ -110,7 +113,7 @@ function InviteCard({ room, userId, direct, compact, onNavigate }: InviteCardPro ( diff --git a/src/app/pages/client/inbox/Notifications.tsx b/src/app/pages/client/inbox/Notifications.tsx index aa8782161..95f9b9ff9 100644 --- a/src/app/pages/client/inbox/Notifications.tsx +++ b/src/app/pages/client/inbox/Notifications.tsx @@ -28,7 +28,7 @@ import { HTMLReactParserOptions } from 'html-react-parser'; import { Opts as LinkifyOpts } from 'linkifyjs'; import { Page, PageContent, PageContentCenter, PageHeader } from '../../../components/page'; import { useMatrixClient } from '../../../hooks/useMatrixClient'; -import { getMxIdLocalPart } from '../../../utils/matrix'; +import { getMxIdLocalPart, mxcUrlToHttp } from '../../../utils/matrix'; import { InboxNotificationsPathSearchParams } from '../../paths'; import { AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback'; import { SequenceCard } from '../../../components/sequence-card'; @@ -81,6 +81,7 @@ import { useMentionClickHandler } from '../../../hooks/useMentionClickHandler'; import { useSpoilerClickHandler } from '../../../hooks/useSpoilerClickHandler'; import { ScreenSize, useScreenSizeContext } from '../../../hooks/useScreenSize'; import { BackRouteHandler } from '../../../components/BackRouteHandler'; +import { useSpecVersions } from '../../../hooks/useSpecVersions'; type RoomNotificationsGroup = { roomId: string; @@ -191,6 +192,8 @@ function RoomNotificationsGroupComp({ onOpen, }: RoomNotificationsGroupProps) { const mx = useMatrixClient(); + const { versions } = useSpecVersions(); + const useAuthentication = versions.includes('v1.11'); const unread = useRoomUnread(room.roomId, roomToUnreadAtom); const mentionClickHandler = useMentionClickHandler(room.roomId); const spoilerClickHandler = useSpoilerClickHandler(); @@ -208,10 +211,11 @@ function RoomNotificationsGroupComp({ () => getReactCustomHtmlParser(mx, room.roomId, { linkifyOpts, + useAuthentication, handleSpoilerClick: spoilerClickHandler, handleMentionClick: mentionClickHandler, }), - [mx, room, linkifyOpts, mentionClickHandler, spoilerClickHandler] + [mx, room, linkifyOpts, mentionClickHandler, spoilerClickHandler, useAuthentication] ); const renderMatrixEvent = useMatrixEventRenderer<[IRoomEvent, string, GetContentCallback]>( @@ -369,7 +373,7 @@ function RoomNotificationsGroupComp({ ( @@ -424,7 +428,7 @@ function RoomNotificationsGroupComp({ userId={event.sender} src={ senderAvatarMxc - ? mx.mxcUrlToHttp(senderAvatarMxc, 48, 48, 'crop') ?? undefined + ? mxcUrlToHttp(mx, senderAvatarMxc, useAuthentication, 48, 48, 'crop') ?? undefined : undefined } alt={displayName} diff --git a/src/app/pages/client/sidebar/SpaceTabs.tsx b/src/app/pages/client/sidebar/SpaceTabs.tsx index f14976fbc..d63bb24d1 100644 --- a/src/app/pages/client/sidebar/SpaceTabs.tsx +++ b/src/app/pages/client/sidebar/SpaceTabs.tsx @@ -86,6 +86,8 @@ import { openInviteUser, openSpaceSettings } from '../../../../client/action/nav import { stopPropagation } from '../../../utils/keyboard'; import { getMatrixToRoom } from '../../../plugins/matrix-to'; import { getViaServers } from '../../../plugins/via-servers'; +import { getRoomAvatarUrl } from '../../../utils/room'; +import { useSpecVersions } from '../../../hooks/useSpecVersions'; type SpaceMenuProps = { room: Room; @@ -225,18 +227,18 @@ const useDraggableItem = ( return !target ? undefined : draggable({ - element: target, - dragHandle, - getInitialData: () => ({ item }), - onDragStart: () => { - setDragging(true); - onDragging?.(item); - }, - onDrop: () => { - setDragging(false); - onDragging?.(undefined); - }, - }); + element: target, + dragHandle, + getInitialData: () => ({ item }), + onDragStart: () => { + setDragging(true); + onDragging?.(item); + }, + onDrop: () => { + setDragging(false); + onDragging?.(undefined); + }, + }); }, [targetRef, dragHandleRef, item, onDragging]); return dragging; @@ -379,15 +381,17 @@ function SpaceTab({ onUnpin, }: SpaceTabProps) { const mx = useMatrixClient(); + const { versions } = useSpecVersions(); + const useAuthentication = versions.includes('v1.11'); const targetRef = useRef(null); const spaceDraggable: SidebarDraggable = useMemo( () => folder ? { - folder, - spaceId: space.roomId, - } + folder, + spaceId: space.roomId, + } : space.roomId, [folder, space] ); @@ -431,7 +435,7 @@ function SpaceTab({ > ( {nameInitials(space.name, 2)} @@ -524,6 +528,8 @@ function ClosedSpaceFolder({ disabled, }: ClosedSpaceFolderProps) { const mx = useMatrixClient(); + const { versions } = useSpecVersions(); + const useAuthentication = versions.includes('v1.11'); const handlerRef = useRef(null); const spaceDraggable: FolderDraggable = useMemo(() => ({ folder }), [folder]); @@ -556,7 +562,7 @@ function ClosedSpaceFolder({ ( diff --git a/src/app/pages/client/sidebar/UserTab.tsx b/src/app/pages/client/sidebar/UserTab.tsx index 89c035bba..09b3f251d 100644 --- a/src/app/pages/client/sidebar/UserTab.tsx +++ b/src/app/pages/client/sidebar/UserTab.tsx @@ -5,8 +5,9 @@ import { SidebarItem, SidebarItemTooltip, SidebarAvatar } from '../../../compone import { openSettings } from '../../../../client/action/navigation'; import { UserAvatar } from '../../../components/user-avatar'; import { useMatrixClient } from '../../../hooks/useMatrixClient'; -import { getMxIdLocalPart } from '../../../utils/matrix'; +import { getMxIdLocalPart, mxcUrlToHttp } from '../../../utils/matrix'; import { nameInitials } from '../../../utils/common'; +import { useSpecVersions } from '../../../hooks/useSpecVersions'; type UserProfile = { avatar_url?: string; @@ -14,12 +15,14 @@ type UserProfile = { }; export function UserTab() { const mx = useMatrixClient(); + const { versions } = useSpecVersions(); + const useAuthentication = versions.includes('v1.11'); const userId = mx.getUserId()!; const [profile, setProfile] = useState({}); const displayName = profile.displayname ?? getMxIdLocalPart(userId) ?? userId; const avatarUrl = profile.avatar_url - ? mx.mxcUrlToHttp(profile.avatar_url, 96, 96, 'crop') ?? undefined + ? mxcUrlToHttp(mx, profile.avatar_url, useAuthentication, 96, 96, 'crop') ?? undefined : undefined; useEffect(() => { diff --git a/src/app/plugins/react-custom-html-parser.tsx b/src/app/plugins/react-custom-html-parser.tsx index 95e2f3342..ab333704b 100644 --- a/src/app/plugins/react-custom-html-parser.tsx +++ b/src/app/plugins/react-custom-html-parser.tsx @@ -14,7 +14,7 @@ import { IntermediateRepresentation, Opts as LinkifyOpts, OptFn } from 'linkifyj import Linkify from 'linkify-react'; import { ErrorBoundary } from 'react-error-boundary'; import * as css from '../styles/CustomHtml.css'; -import { getMxIdLocalPart, getCanonicalAliasRoomId, isRoomAlias } from '../utils/matrix'; +import { getMxIdLocalPart, getCanonicalAliasRoomId, isRoomAlias, mxcUrlToHttp } from '../utils/matrix'; import { getMemberDisplayName } from '../utils/room'; import { EMOJI_PATTERN, URL_NEG_LB } from '../utils/regex'; import { getHexcodeForEmoji, getShortcodeFor } from './emoji'; @@ -72,9 +72,8 @@ export const renderMatrixMention = ( className={css.Mention({ highlight: mx.getUserId() === userId })} data-mention-id={userId} > - {`@${ - (currentRoom && getMemberDisplayName(currentRoom, userId)) ?? getMxIdLocalPart(userId) - }`} + {`@${(currentRoom && getMemberDisplayName(currentRoom, userId)) ?? getMxIdLocalPart(userId) + }`} ); } @@ -192,6 +191,7 @@ export const getReactCustomHtmlParser = ( highlightRegex?: RegExp; handleSpoilerClick?: ReactEventHandler; handleMentionClick?: ReactEventHandler; + useAuthentication?: boolean; } ): HTMLReactParserOptions => { const opts: HTMLReactParserOptions = { @@ -354,7 +354,7 @@ export const getReactCustomHtmlParser = ( } if (name === 'img') { - const htmlSrc = mx.mxcUrlToHttp(props.src); + const htmlSrc = mxcUrlToHttp(mx, props.src, params.useAuthentication); if (htmlSrc && props.src.startsWith('mxc://') === false) { return ( diff --git a/src/app/utils/matrix.ts b/src/app/utils/matrix.ts index 8613f36ab..65a1080bc 100644 --- a/src/app/utils/matrix.ts +++ b/src/app/utils/matrix.ts @@ -253,3 +253,23 @@ export const removeRoomIdFromMDirect = async (mx: MatrixClient, roomId: string): await mx.setAccountData(AccountDataEvent.Direct, userIdToRoomIds); }; + +export const mxcUrlToHttp = ( + mx: MatrixClient, + mxcUrl: string, + useAuthentication?: boolean, + width?: number, + height?: number, + resizeMethod?: string, + allowDirectLinks?: boolean, + allowRedirects?: boolean +): string | null => + mx.mxcUrlToHttp( + mxcUrl, + width, + height, + resizeMethod, + allowDirectLinks, + allowRedirects, + useAuthentication + ); diff --git a/src/app/utils/room.ts b/src/app/utils/room.ts index 8cf33a8ff..5f4615a6e 100644 --- a/src/app/utils/room.ts +++ b/src/app/utils/room.ts @@ -273,16 +273,26 @@ export const joinRuleToIconSrc = ( export const getRoomAvatarUrl = ( mx: MatrixClient, room: Room, - size: 32 | 96 = 32 -): string | undefined => room.getAvatarUrl(mx.baseUrl, size, size, 'crop') ?? undefined; + size: 32 | 96 = 32, + useAuthentication = false +): string | undefined => { + const mxcUrl = room.getMxcAvatarUrl(); + return mxcUrl + ? mx.mxcUrlToHttp(mxcUrl, size, size, 'crop', undefined, false, useAuthentication) ?? undefined + : undefined; +}; export const getDirectRoomAvatarUrl = ( mx: MatrixClient, room: Room, - size: 32 | 96 = 32 -): string | undefined => - room.getAvatarFallbackMember()?.getAvatarUrl(mx.baseUrl, size, size, 'crop', undefined, false) ?? - undefined; + size: 32 | 96 = 32, + useAuthentication = false +): string | undefined => { + const mxcUrl = room.getAvatarFallbackMember()?.getMxcAvatarUrl(); + return mxcUrl + ? mx.mxcUrlToHttp(mxcUrl, size, size, 'crop', undefined, false, useAuthentication) ?? undefined + : undefined; +}; export const trimReplyFromBody = (body: string): string => { const match = body.match(/^> <.+?> .+\n(>.*\n)*?\n/m); diff --git a/src/client/initMatrix.ts b/src/client/initMatrix.ts index 5a156ad88..52e8317e4 100644 --- a/src/client/initMatrix.ts +++ b/src/client/initMatrix.ts @@ -23,7 +23,6 @@ export const initClient = async (session: Session): Promise => { localStorage: global.localStorage, dbName: 'web-sync-store', }); - await indexedDBStore.startup(); const mx = createClient({ baseUrl: session.baseUrl, @@ -38,6 +37,7 @@ export const initClient = async (session: Session): Promise => { }); await mx.initCrypto(); + await indexedDBStore.startup(); mx.setGlobalErrorOnUnknownDevices(false); mx.setMaxListeners(50); diff --git a/src/index.tsx b/src/index.tsx index a289ed1cc..58ecc42ac 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -12,6 +12,7 @@ import './index.scss'; import settings from './client/state/settings'; +import { trimTrailingSlash } from './app/utils/common'; import App from './app/pages/App'; // import i18n (needs to be bundled ;)) @@ -20,6 +21,23 @@ import './app/i18n'; document.body.classList.add(configClass, varsClass); settings.applyTheme(); +// Register Service Worker +if ('serviceWorker' in navigator) { + navigator.serviceWorker.register( + import.meta.env.MODE === 'production' ? `${trimTrailingSlash(import.meta.env.BASE_URL)}/sw.js` : '/dev-sw.js?dev-sw' + ) + navigator.serviceWorker.addEventListener('message', (event) => { + if (event.data?.type === 'token' && event.data?.responseKey) { + // Get the token for SW. + const token = localStorage.getItem('cinny_access_token'); + event.source!.postMessage({ + responseKey: event.data.responseKey, + token, + }) + } + }) +} + const mountApp = () => { const rootContainer = document.getElementById('root'); diff --git a/src/sw.ts b/src/sw.ts new file mode 100644 index 000000000..119539174 --- /dev/null +++ b/src/sw.ts @@ -0,0 +1,43 @@ +async function askForAccessToken(client: Client): Promise { + return new Promise((resolve) => { + const responseKey = Math.random().toString(36); + const listener = (event: ExtendableMessageEvent) => { + if (event.data.responseKey !== responseKey) return; + resolve(event.data.token); + self.removeEventListener('message', listener); + }; + self.addEventListener('message', listener); + client.postMessage({ responseKey, type: 'token' }); + }); +} + +function fetchConfig(token?: string): RequestInit | undefined { + if (!token) return undefined; + + return { + headers: { + Authorization: `Bearer ${token}`, + }, + }; +} + +self.addEventListener('fetch', (event: FetchEvent) => { + const { url, method } = event.request; + if (method !== 'GET') return; + if ( + !url.includes('/_matrix/client/v1/media/download') && + !url.includes('/_matrix/client/v1/media/thumbnail') + ) { + return; + } + event.respondWith( + (async (): Promise => { + const client = await clients.get(event.clientId); + let token: string | undefined; + if (client) token = await askForAccessToken(client); + + // eslint-disable-next-line consistent-return + return fetch(url, fetchConfig(token)); + })() + ); +}); diff --git a/tsconfig.json b/tsconfig.json index 60ff18538..7608e5578 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -10,7 +10,8 @@ "moduleResolution": "Node", "resolveJsonModule": true, "outDir": "dist", - "skipLibCheck": true + "skipLibCheck": true, + "lib": ["ES2016", "DOM"] }, "exclude": ["node_modules", "dist"], "include": ["src"] diff --git a/vite.config.js b/vite.config.js index 7b5ec2509..e629c7512 100644 --- a/vite.config.js +++ b/vite.config.js @@ -6,6 +6,7 @@ import { vanillaExtractPlugin } from '@vanilla-extract/vite-plugin'; import { NodeGlobalsPolyfillPlugin } from '@esbuild-plugins/node-globals-polyfill'; import inject from '@rollup/plugin-inject'; import topLevelAwait from 'vite-plugin-top-level-await'; +import { VitePWA } from 'vite-plugin-pwa'; import buildConfig from './build.config'; const copyFiles = { @@ -50,11 +51,11 @@ export default defineConfig({ port: 8080, host: true, proxy: { - "^\\/.*?\\/olm\\.wasm$": { + '^\\/.*?\\/olm\\.wasm$': { target: 'http://localhost:8080', - rewrite: () => '/olm.wasm' - } - } + rewrite: () => '/olm.wasm', + }, + }, }, plugins: [ topLevelAwait({ @@ -67,6 +68,16 @@ export default defineConfig({ vanillaExtractPlugin(), wasm(), react(), + VitePWA({ + srcDir: 'src', + filename: 'sw.ts', + strategies: 'injectManifest', + injectRegister: false, + manifest: false, + injectManifest: { + injectionPoint: undefined, + }, + }), ], optimizeDeps: { esbuildOptions: { From 09444f9e08bd4ab3452480f1016721cf81b4807d Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Sun, 8 Sep 2024 22:51:43 +1000 Subject: [PATCH 1205/1531] fix sso login without identity providers (#1934) --- src/app/hooks/useParsedLoginFlows.ts | 16 ++-- src/app/pages/auth/SSOLogin.tsx | 110 +++++++++++++---------- src/app/pages/auth/login/Login.tsx | 4 +- src/app/pages/auth/register/Register.tsx | 5 +- 4 files changed, 72 insertions(+), 63 deletions(-) diff --git a/src/app/hooks/useParsedLoginFlows.ts b/src/app/hooks/useParsedLoginFlows.ts index 14ecfb9dd..088a514ee 100644 --- a/src/app/hooks/useParsedLoginFlows.ts +++ b/src/app/hooks/useParsedLoginFlows.ts @@ -1,16 +1,10 @@ import { useMemo } from 'react'; import { ILoginFlow, IPasswordFlow, ISSOFlow, LoginFlow } from 'matrix-js-sdk/lib/@types/auth'; -import { WithRequiredProp } from '../../types/utils'; -export type Required_SSOFlow = WithRequiredProp; -export const getSSOFlow = (loginFlows: LoginFlow[]): Required_SSOFlow | undefined => - loginFlows.find( - (flow) => - (flow.type === 'm.login.sso' || flow.type === 'm.login.cas') && - 'identity_providers' in flow && - Array.isArray(flow.identity_providers) && - flow.identity_providers.length > 0 - ) as Required_SSOFlow | undefined; +export const getSSOFlow = (loginFlows: LoginFlow[]): ISSOFlow | undefined => + loginFlows.find((flow) => flow.type === 'm.login.sso' || flow.type === 'm.login.cas') as + | ISSOFlow + | undefined; export const getPasswordFlow = (loginFlows: LoginFlow[]): IPasswordFlow | undefined => loginFlows.find((flow) => flow.type === 'm.login.password') as IPasswordFlow; @@ -22,7 +16,7 @@ export const getTokenFlow = (loginFlows: LoginFlow[]): LoginFlow | undefined => export type ParsedLoginFlows = { password?: LoginFlow; token?: LoginFlow; - sso?: Required_SSOFlow; + sso?: ISSOFlow; }; export const useParsedLoginFlows = (loginFlows: LoginFlow[]) => { const parsedFlow: ParsedLoginFlows = useMemo( diff --git a/src/app/pages/auth/SSOLogin.tsx b/src/app/pages/auth/SSOLogin.tsx index 0d3d917f1..d0cdaeb68 100644 --- a/src/app/pages/auth/SSOLogin.tsx +++ b/src/app/pages/auth/SSOLogin.tsx @@ -4,69 +4,89 @@ import React, { useMemo } from 'react'; import { useAutoDiscoveryInfo } from '../../hooks/useAutoDiscoveryInfo'; type SSOLoginProps = { - providers: IIdentityProvider[]; - asIcons?: boolean; + providers?: IIdentityProvider[]; redirectUrl: string; + saveScreenSpace?: boolean; }; -export function SSOLogin({ providers, redirectUrl, asIcons }: SSOLoginProps) { +export function SSOLogin({ providers, redirectUrl, saveScreenSpace }: SSOLoginProps) { const discovery = useAutoDiscoveryInfo(); const baseUrl = discovery['m.homeserver'].base_url; const mx = useMemo(() => createClient({ baseUrl }), [baseUrl]); - const getSSOIdUrl = (ssoId: string): string => mx.getSsoLoginUrl(redirectUrl, 'sso', ssoId); + const getSSOIdUrl = (ssoId?: string): string => mx.getSsoLoginUrl(redirectUrl, 'sso', ssoId); - const anyAsBtn = providers.find( - (provider) => !provider.icon || !mx.mxcUrlToHttp(provider.icon, 96, 96, 'crop', false) - ); + const withoutIcon = providers + ? providers.find( + (provider) => !provider.icon || !mx.mxcUrlToHttp(provider.icon, 96, 96, 'crop', false) + ) + : true; + + const renderAsIcons = withoutIcon ? false : saveScreenSpace && providers && providers.length > 2; return ( - {providers.map((provider) => { - const { id, name, icon } = provider; - const iconUrl = icon && mx.mxcUrlToHttp(icon, 96, 96, 'crop', false); + {providers ? ( + providers.map((provider) => { + const { id, name, icon } = provider; + const iconUrl = icon && mx.mxcUrlToHttp(icon, 96, 96, 'crop', false); - const buttonTitle = `Continue with ${name}`; + const buttonTitle = `Continue with ${name}`; + + if (renderAsIcons) { + return ( + + + + ); + } - if (!anyAsBtn && iconUrl && asIcons) { return ( - + + + ) + } > - - + + {buttonTitle} + + ); - } - - return ( - - ); - })} + }) + ) : ( + + )} ); } diff --git a/src/app/pages/auth/login/Login.tsx b/src/app/pages/auth/login/Login.tsx index e1689d1e4..6b9f1223c 100644 --- a/src/app/pages/auth/login/Login.tsx +++ b/src/app/pages/auth/login/Login.tsx @@ -76,9 +76,7 @@ export function Login() { 2 - } + saveScreenSpace={parsedFlows.password !== undefined} /> diff --git a/src/app/pages/auth/register/Register.tsx b/src/app/pages/auth/register/Register.tsx index c859d0e54..d2986d701 100644 --- a/src/app/pages/auth/register/Register.tsx +++ b/src/app/pages/auth/register/Register.tsx @@ -83,10 +83,7 @@ export function Register() { 2 - } + saveScreenSpace={registerFlows.status === RegisterFlowStatus.FlowRequired} /> From 388f606ad2a1c52a51bcfa422341f83149138035 Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Sun, 8 Sep 2024 22:53:17 +1000 Subject: [PATCH 1206/1531] fix escape to mark as read (#1935) --- src/app/features/room/Room.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/app/features/room/Room.tsx b/src/app/features/room/Room.tsx index a4ec71651..ee3e70274 100644 --- a/src/app/features/room/Room.tsx +++ b/src/app/features/room/Room.tsx @@ -13,7 +13,6 @@ import { useKeyDown } from '../../hooks/useKeyDown'; import { markAsRead } from '../../../client/action/notifications'; import { useMatrixClient } from '../../hooks/useMatrixClient'; import { useRoomMembers } from '../../hooks/useRoomMembers'; -import { editableActiveElement } from '../../utils/dom'; export function Room() { const { eventId } = useParams(); @@ -29,7 +28,7 @@ export function Room() { window, useCallback( (evt) => { - if (isKeyHotkey('escape', evt) && !editableActiveElement()) { + if (isKeyHotkey('escape', evt)) { markAsRead(mx, room.roomId); } }, From 4dfce32730137c319c646d24293216a31d39da43 Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Sun, 8 Sep 2024 22:53:59 +1000 Subject: [PATCH 1207/1531] fix mention url is encoded wrong (#1936) --- src/app/components/editor/output.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/components/editor/output.ts b/src/app/components/editor/output.ts index 864aee3d2..d6136d99d 100644 --- a/src/app/components/editor/output.ts +++ b/src/app/components/editor/output.ts @@ -62,7 +62,7 @@ const elementToCustomHtml = (node: CustomElement, children: string): string => { } const matrixTo = `https://matrix.to/#/${fragment}`; - return `${sanitizeText(node.name)}`; + return `${sanitizeText(node.name)}`; } case BlockType.Emoticon: return node.key.startsWith('mxc://') @@ -71,7 +71,7 @@ const elementToCustomHtml = (node: CustomElement, children: string): string => { )}" title="${sanitizeText(node.shortcode)}" height="32" />` : sanitizeText(node.key); case BlockType.Link: - return `${node.children}`; + return `${node.children}`; case BlockType.Command: return `/${sanitizeText(node.command)}`; default: From 96df1401535ccea14eae18937ac4a1cf0503e46e Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Mon, 9 Sep 2024 18:45:20 +1000 Subject: [PATCH 1208/1531] Improve-auth-media (#1933) * fix set power level broken after sdk update * add media authentication hook * fix service worker types * fix service worker not working in dev mode * fix env mode check when registering sw --- package-lock.json | 11 +---------- package.json | 1 - src/app/components/editor/Elements.tsx | 5 ++--- .../editor/autocomplete/EmoticonAutocomplete.tsx | 5 ++--- .../autocomplete/UserMentionAutocomplete.tsx | 9 +++++---- src/app/components/emoji-board/EmojiBoard.tsx | 5 ++--- src/app/components/event-readers/EventReaders.tsx | 5 ++--- .../components/message/content/AudioContent.tsx | 5 ++--- .../components/message/content/FileContent.tsx | 11 ++++------- .../components/message/content/ImageContent.tsx | 5 ++--- .../message/content/ThumbnailContent.tsx | 5 ++--- .../components/message/content/VideoContent.tsx | 5 ++--- src/app/components/room-card/RoomCard.tsx | 5 ++--- src/app/components/room-intro/RoomIntro.tsx | 5 ++--- src/app/components/url-preview/UrlPreviewCard.tsx | 5 ++--- src/app/features/lobby/LobbyHeader.tsx | 5 ++--- src/app/features/lobby/LobbyHero.tsx | 5 ++--- src/app/features/lobby/RoomItem.tsx | 5 ++--- src/app/features/lobby/SpaceItem.tsx | 5 ++--- .../features/message-search/SearchResultGroup.tsx | 5 ++--- src/app/features/room-nav/RoomNavItem.tsx | 5 ++--- src/app/features/room/MembersDrawer.tsx | 5 ++--- src/app/features/room/RoomInput.tsx | 5 ++--- src/app/features/room/RoomTimeline.tsx | 5 ++--- src/app/features/room/RoomViewHeader.tsx | 5 ++--- src/app/features/room/message/Message.tsx | 5 ++--- src/app/features/room/message/Reactions.tsx | 5 ++--- .../room/reaction-viewer/ReactionViewer.tsx | 5 ++--- src/app/hooks/useMediaAuthentication.ts | 10 ++++++++++ src/app/pages/client/ClientNonUIFeatures.tsx | 6 +++--- src/app/pages/client/inbox/Invites.tsx | 5 ++--- src/app/pages/client/inbox/Notifications.tsx | 5 ++--- src/app/pages/client/sidebar/SpaceTabs.tsx | 8 +++----- src/app/pages/client/sidebar/UserTab.tsx | 5 ++--- src/client/action/room.js | 6 +----- src/index.tsx | 15 +++++++++------ src/sw.ts | 8 ++++++-- vite.config.js | 4 ++++ 38 files changed, 100 insertions(+), 124 deletions(-) create mode 100644 src/app/hooks/useMediaAuthentication.ts diff --git a/package-lock.json b/package-lock.json index 1dcff435b..9c4520ae8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -79,7 +79,6 @@ "@types/react-dom": "18.2.17", "@types/react-google-recaptcha": "2.1.8", "@types/sanitize-html": "2.9.0", - "@types/serviceworker": "0.0.95", "@types/ua-parser-js": "0.7.36", "@typescript-eslint/eslint-plugin": "5.46.1", "@typescript-eslint/parser": "5.46.1", @@ -5036,13 +5035,6 @@ "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==", "dev": true }, - "node_modules/@types/serviceworker": { - "version": "0.0.95", - "resolved": "https://registry.npmjs.org/@types/serviceworker/-/serviceworker-0.0.95.tgz", - "integrity": "sha512-Zw7kLIehLvaXf/9RnxAUiYyHmYC5pfvIJD3b1uSPkZGzp+OVmXgmPzVW5fbhYHKcqkeGzsv89uGm+JmMCAPa8Q==", - "dev": true, - "license": "Apache-2.0" - }, "node_modules/@types/trusted-types": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", @@ -11514,7 +11506,6 @@ "resolved": "https://registry.npmjs.org/vite-plugin-pwa/-/vite-plugin-pwa-0.20.5.tgz", "integrity": "sha512-aweuI/6G6n4C5Inn0vwHumElU/UEpNuO+9iZzwPZGTCH87TeZ6YFMrEY6ZUBQdIHHlhTsbMDryFARcSuOdsz9Q==", "dev": true, - "license": "MIT", "dependencies": { "debug": "^4.3.6", "pretty-bytes": "^6.1.1", @@ -12446,4 +12437,4 @@ } } } -} \ No newline at end of file +} diff --git a/package.json b/package.json index 09efccb74..ecc52c8b9 100644 --- a/package.json +++ b/package.json @@ -90,7 +90,6 @@ "@types/react-dom": "18.2.17", "@types/react-google-recaptcha": "2.1.8", "@types/sanitize-html": "2.9.0", - "@types/serviceworker": "0.0.95", "@types/ua-parser-js": "0.7.36", "@typescript-eslint/eslint-plugin": "5.46.1", "@typescript-eslint/parser": "5.46.1", diff --git a/src/app/components/editor/Elements.tsx b/src/app/components/editor/Elements.tsx index aee50ac80..a7438ecdf 100644 --- a/src/app/components/editor/Elements.tsx +++ b/src/app/components/editor/Elements.tsx @@ -14,7 +14,7 @@ import { useMatrixClient } from '../../hooks/useMatrixClient'; import { getBeginCommand } from './utils'; import { BlockType } from './types'; import { mxcUrlToHttp } from '../../utils/matrix'; -import { useSpecVersions } from '../../hooks/useSpecVersions'; +import { useMediaAuthentication } from '../../hooks/useMediaAuthentication'; // Put this at the start and end of an inline component to work around this Chromium bug: // https://bugs.chromium.org/p/chromium/issues/detail?id=1249405 @@ -78,8 +78,7 @@ function RenderEmoticonElement({ children, }: { element: EmoticonElement } & RenderElementProps) { const mx = useMatrixClient(); - const { versions } = useSpecVersions(); - const useAuthentication = versions.includes('v1.11'); + const useAuthentication = useMediaAuthentication(); const selected = useSelected(); const focused = useFocused(); diff --git a/src/app/components/editor/autocomplete/EmoticonAutocomplete.tsx b/src/app/components/editor/autocomplete/EmoticonAutocomplete.tsx index b77ae746f..9722c7954 100644 --- a/src/app/components/editor/autocomplete/EmoticonAutocomplete.tsx +++ b/src/app/components/editor/autocomplete/EmoticonAutocomplete.tsx @@ -19,7 +19,7 @@ import { IEmoji, emojis } from '../../../plugins/emoji'; import { ExtendedPackImage, PackUsage } from '../../../plugins/custom-emoji'; import { useKeyDown } from '../../../hooks/useKeyDown'; import { mxcUrlToHttp } from '../../../utils/matrix'; -import { useSpecVersions } from '../../../hooks/useSpecVersions'; +import { useMediaAuthentication } from '../../../hooks/useMediaAuthentication'; type EmoticonCompleteHandler = (key: string, shortcode: string) => void; @@ -50,8 +50,7 @@ export function EmoticonAutocomplete({ requestClose, }: EmoticonAutocompleteProps) { const mx = useMatrixClient(); - const { versions } = useSpecVersions(); - const useAuthentication = versions.includes('v1.11'); + const useAuthentication = useMediaAuthentication(); const imagePacks = useRelevantImagePacks(mx, PackUsage.Emoticon, imagePackRooms); const recentEmoji = useRecentEmoji(mx, 20); diff --git a/src/app/components/editor/autocomplete/UserMentionAutocomplete.tsx b/src/app/components/editor/autocomplete/UserMentionAutocomplete.tsx index 05d303a2a..7794bcd12 100644 --- a/src/app/components/editor/autocomplete/UserMentionAutocomplete.tsx +++ b/src/app/components/editor/autocomplete/UserMentionAutocomplete.tsx @@ -18,7 +18,7 @@ import { useKeyDown } from '../../../hooks/useKeyDown'; import { getMxIdLocalPart, getMxIdServer, validMxId } from '../../../utils/matrix'; import { getMemberDisplayName, getMemberSearchStr } from '../../../utils/room'; import { UserAvatar } from '../../user-avatar'; -import { useSpecVersions } from '../../../hooks/useSpecVersions'; +import { useMediaAuthentication } from '../../../hooks/useMediaAuthentication'; type MentionAutoCompleteHandler = (userId: string, name: string) => void; @@ -85,8 +85,7 @@ export function UserMentionAutocomplete({ requestClose, }: UserMentionAutocompleteProps) { const mx = useMatrixClient(); - const { versions } = useSpecVersions(); - const useAuthentication = versions.includes('v1.11'); + const useAuthentication = useMediaAuthentication(); const roomId: string = room.roomId!; const roomAliasOrId = room.getCanonicalAlias() || roomId; const members = useRoomMembers(mx, roomId); @@ -147,7 +146,9 @@ export function UserMentionAutocomplete({ ) : ( autoCompleteMembers.map((roomMember) => { const avatarMxcUrl = roomMember.getMxcAvatarUrl(); - const avatarUrl = avatarMxcUrl ? mx.mxcUrlToHttp(avatarMxcUrl, 32, 32, 'crop', undefined, false, useAuthentication) : undefined; + const avatarUrl = avatarMxcUrl + ? mx.mxcUrlToHttp(avatarMxcUrl, 32, 32, 'crop', undefined, false, useAuthentication) + : undefined; return ( ( ({ className, room, eventId, requestClose, ...props }, ref) => { const mx = useMatrixClient(); - const { versions } = useSpecVersions(); - const useAuthentication = versions.includes('v1.11'); + const useAuthentication = useMediaAuthentication(); const latestEventReaders = useRoomEventReaders(room, eventId); const getName = (userId: string) => diff --git a/src/app/components/message/content/AudioContent.tsx b/src/app/components/message/content/AudioContent.tsx index 38fa95158..b426654fb 100644 --- a/src/app/components/message/content/AudioContent.tsx +++ b/src/app/components/message/content/AudioContent.tsx @@ -18,7 +18,7 @@ import { import { useThrottle } from '../../../hooks/useThrottle'; import { secondsToMinutesAndSeconds } from '../../../utils/common'; import { mxcUrlToHttp } from '../../../utils/matrix'; -import { useSpecVersions } from '../../../hooks/useSpecVersions'; +import { useMediaAuthentication } from '../../../hooks/useMediaAuthentication'; const PLAY_TIME_THROTTLE_OPS = { wait: 500, @@ -46,8 +46,7 @@ export function AudioContent({ renderMediaControl, }: AudioContentProps) { const mx = useMatrixClient(); - const { versions } = useSpecVersions(); - const useAuthentication = versions.includes('v1.11'); + const useAuthentication = useMediaAuthentication(); const [srcState, loadSrc] = useAsyncCallback( useCallback( diff --git a/src/app/components/message/content/FileContent.tsx b/src/app/components/message/content/FileContent.tsx index 379d14563..62b8c56dd 100644 --- a/src/app/components/message/content/FileContent.tsx +++ b/src/app/components/message/content/FileContent.tsx @@ -31,7 +31,7 @@ import { import * as css from './style.css'; import { stopPropagation } from '../../../utils/keyboard'; import { mxcUrlToHttp } from '../../../utils/matrix'; -import { useSpecVersions } from '../../../hooks/useSpecVersions'; +import { useMediaAuthentication } from '../../../hooks/useMediaAuthentication'; const renderErrorButton = (retry: () => void, text: string) => ( { diff --git a/src/app/components/message/content/ImageContent.tsx b/src/app/components/message/content/ImageContent.tsx index 798c60c55..d0a31c39c 100644 --- a/src/app/components/message/content/ImageContent.tsx +++ b/src/app/components/message/content/ImageContent.tsx @@ -28,7 +28,7 @@ import { bytesToSize } from '../../../utils/common'; import { FALLBACK_MIMETYPE } from '../../../utils/mimeTypes'; import { stopPropagation } from '../../../utils/keyboard'; import { mxcUrlToHttp } from '../../../utils/matrix'; -import { useSpecVersions } from '../../../hooks/useSpecVersions'; +import { useMediaAuthentication } from '../../../hooks/useMediaAuthentication'; type RenderViewerProps = { src: string; @@ -71,8 +71,7 @@ export const ImageContent = as<'div', ImageContentProps>( ref ) => { const mx = useMatrixClient(); - const { versions } = useSpecVersions(); - const useAuthentication = versions.includes('v1.11'); + const useAuthentication = useMediaAuthentication(); const blurHash = info?.[MATRIX_BLUR_HASH_PROPERTY_NAME]; const [load, setLoad] = useState(false); diff --git a/src/app/components/message/content/ThumbnailContent.tsx b/src/app/components/message/content/ThumbnailContent.tsx index 4324376d1..b667e57eb 100644 --- a/src/app/components/message/content/ThumbnailContent.tsx +++ b/src/app/components/message/content/ThumbnailContent.tsx @@ -4,7 +4,7 @@ import { useMatrixClient } from '../../../hooks/useMatrixClient'; import { AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback'; import { getFileSrcUrl } from './util'; import { mxcUrlToHttp } from '../../../utils/matrix'; -import { useSpecVersions } from '../../../hooks/useSpecVersions'; +import { useMediaAuthentication } from '../../../hooks/useMediaAuthentication'; export type ThumbnailContentProps = { info: IThumbnailContent; @@ -12,8 +12,7 @@ export type ThumbnailContentProps = { }; export function ThumbnailContent({ info, renderImage }: ThumbnailContentProps) { const mx = useMatrixClient(); - const { versions } = useSpecVersions(); - const useAuthentication = versions.includes('v1.11'); + const useAuthentication = useMediaAuthentication(); const [thumbSrcState, loadThumbSrc] = useAsyncCallback( useCallback(() => { diff --git a/src/app/components/message/content/VideoContent.tsx b/src/app/components/message/content/VideoContent.tsx index e83e4595d..46f82fae5 100644 --- a/src/app/components/message/content/VideoContent.tsx +++ b/src/app/components/message/content/VideoContent.tsx @@ -26,7 +26,7 @@ import { getFileSrcUrl } from './util'; import { bytesToSize } from '../../../../util/common'; import { millisecondsToMinutesAndSeconds } from '../../../utils/common'; import { mxcUrlToHttp } from '../../../utils/matrix'; -import { useSpecVersions } from '../../../hooks/useSpecVersions'; +import { useMediaAuthentication } from '../../../hooks/useMediaAuthentication'; type RenderVideoProps = { title: string; @@ -63,8 +63,7 @@ export const VideoContent = as<'div', VideoContentProps>( ref ) => { const mx = useMatrixClient(); - const { versions } = useSpecVersions(); - const useAuthentication = versions.includes('v1.11'); + const useAuthentication = useMediaAuthentication(); const blurHash = info.thumbnail_info?.[MATRIX_BLUR_HASH_PROPERTY_NAME]; const [load, setLoad] = useState(false); diff --git a/src/app/components/room-card/RoomCard.tsx b/src/app/components/room-card/RoomCard.tsx index 1ca7813f0..34a7e24b5 100644 --- a/src/app/components/room-card/RoomCard.tsx +++ b/src/app/components/room-card/RoomCard.tsx @@ -32,7 +32,7 @@ import { useJoinedRoomId } from '../../hooks/useJoinedRoomId'; import { useElementSizeObserver } from '../../hooks/useElementSizeObserver'; import { getRoomAvatarUrl, getStateEvent } from '../../utils/room'; import { useStateEventCallback } from '../../hooks/useStateEventCallback'; -import { useSpecVersions } from '../../hooks/useSpecVersions'; +import { useMediaAuthentication } from '../../hooks/useMediaAuthentication'; type GridColumnCount = '1' | '2' | '3'; const getGridColumnCount = (gridWidth: number): GridColumnCount => { @@ -162,8 +162,7 @@ export const RoomCard = as<'div', RoomCardProps>( ref ) => { const mx = useMatrixClient(); - const { versions } = useSpecVersions(); - const useAuthentication = versions.includes('v1.11'); + const useAuthentication = useMediaAuthentication(); const joinedRoomId = useJoinedRoomId(allRooms, roomIdOrAlias); const joinedRoom = mx.getRoom(joinedRoomId); const [topicEvent, setTopicEvent] = useState(() => diff --git a/src/app/components/room-intro/RoomIntro.tsx b/src/app/components/room-intro/RoomIntro.tsx index 28be5daf7..9e1a4f12f 100644 --- a/src/app/components/room-intro/RoomIntro.tsx +++ b/src/app/components/room-intro/RoomIntro.tsx @@ -14,7 +14,7 @@ import { RoomAvatar } from '../room-avatar'; import { nameInitials } from '../../utils/common'; import { useRoomAvatar, useRoomName, useRoomTopic } from '../../hooks/useRoomMeta'; import { mDirectAtom } from '../../state/mDirectList'; -import { useSpecVersions } from '../../hooks/useSpecVersions'; +import { useMediaAuthentication } from '../../hooks/useMediaAuthentication'; export type RoomIntroProps = { room: Room; @@ -22,8 +22,7 @@ export type RoomIntroProps = { export const RoomIntro = as<'div', RoomIntroProps>(({ room, ...props }, ref) => { const mx = useMatrixClient(); - const { versions } = useSpecVersions(); - const useAuthentication = versions.includes('v1.11'); + const useAuthentication = useMediaAuthentication(); const { navigateRoom } = useRoomNavigate(); const mDirects = useAtomValue(mDirectAtom); diff --git a/src/app/components/url-preview/UrlPreviewCard.tsx b/src/app/components/url-preview/UrlPreviewCard.tsx index c33b98504..2a51969a6 100644 --- a/src/app/components/url-preview/UrlPreviewCard.tsx +++ b/src/app/components/url-preview/UrlPreviewCard.tsx @@ -11,15 +11,14 @@ import { import * as css from './UrlPreviewCard.css'; import { tryDecodeURIComponent } from '../../utils/dom'; import { mxcUrlToHttp } from '../../utils/matrix'; -import { useSpecVersions } from '../../hooks/useSpecVersions'; +import { useMediaAuthentication } from '../../hooks/useMediaAuthentication'; const linkStyles = { color: color.Success.Main }; export const UrlPreviewCard = as<'div', { url: string; ts: number }>( ({ url, ts, ...props }, ref) => { const mx = useMatrixClient(); - const { versions } = useSpecVersions(); - const useAuthentication = versions.includes('v1.11'); + const useAuthentication = useMediaAuthentication(); const [previewStatus, loadPreview] = useAsyncCallback( useCallback(() => mx.getUrlPreview(url, ts), [url, ts, mx]) ); diff --git a/src/app/features/lobby/LobbyHeader.tsx b/src/app/features/lobby/LobbyHeader.tsx index ed5373b38..6ef0044ba 100644 --- a/src/app/features/lobby/LobbyHeader.tsx +++ b/src/app/features/lobby/LobbyHeader.tsx @@ -34,7 +34,7 @@ import { stopPropagation } from '../../utils/keyboard'; import { ScreenSize, useScreenSizeContext } from '../../hooks/useScreenSize'; import { BackRouteHandler } from '../../components/BackRouteHandler'; import { mxcUrlToHttp } from '../../utils/matrix'; -import { useSpecVersions } from '../../hooks/useSpecVersions'; +import { useMediaAuthentication } from '../../hooks/useMediaAuthentication'; type LobbyMenuProps = { roomId: string; @@ -124,8 +124,7 @@ type LobbyHeaderProps = { }; export function LobbyHeader({ showProfile, powerLevels }: LobbyHeaderProps) { const mx = useMatrixClient(); - const { versions } = useSpecVersions(); - const useAuthentication = versions.includes('v1.11'); + const useAuthentication = useMediaAuthentication(); const space = useSpace(); const setPeopleDrawer = useSetSetting(settingsAtom, 'isPeopleDrawer'); const [menuAnchor, setMenuAnchor] = useState(); diff --git a/src/app/features/lobby/LobbyHero.tsx b/src/app/features/lobby/LobbyHero.tsx index e652fd919..1cd0b8e26 100644 --- a/src/app/features/lobby/LobbyHero.tsx +++ b/src/app/features/lobby/LobbyHero.tsx @@ -12,12 +12,11 @@ import * as css from './LobbyHero.css'; import { PageHero } from '../../components/page'; import { onEnterOrSpace, stopPropagation } from '../../utils/keyboard'; import { mxcUrlToHttp } from '../../utils/matrix'; -import { useSpecVersions } from '../../hooks/useSpecVersions'; +import { useMediaAuthentication } from '../../hooks/useMediaAuthentication'; export function LobbyHero() { const mx = useMatrixClient(); - const { versions } = useSpecVersions(); - const useAuthentication = versions.includes('v1.11'); + const useAuthentication = useMediaAuthentication(); const space = useSpace(); const name = useRoomName(space); diff --git a/src/app/features/lobby/RoomItem.tsx b/src/app/features/lobby/RoomItem.tsx index 14852b3dd..f8db3991e 100644 --- a/src/app/features/lobby/RoomItem.tsx +++ b/src/app/features/lobby/RoomItem.tsx @@ -40,7 +40,7 @@ import { ErrorCode } from '../../cs-errorcode'; import { getDirectRoomAvatarUrl, getRoomAvatarUrl } from '../../utils/room'; import { ItemDraggableTarget, useDraggableItem } from './DnD'; import { mxcUrlToHttp } from '../../utils/matrix'; -import { useSpecVersions } from '../../hooks/useSpecVersions'; +import { useMediaAuthentication } from '../../hooks/useMediaAuthentication'; type RoomJoinButtonProps = { roomId: string; @@ -336,8 +336,7 @@ export const RoomItemCard = as<'div', RoomItemCardProps>( ref ) => { const mx = useMatrixClient(); - const { versions } = useSpecVersions(); - const useAuthentication = versions.includes('v1.11'); + const useAuthentication = useMediaAuthentication(); const { roomId, content } = item; const room = getRoom(roomId); const targetRef = useRef(null); diff --git a/src/app/features/lobby/SpaceItem.tsx b/src/app/features/lobby/SpaceItem.tsx index 3e3c32141..deaf9ba58 100644 --- a/src/app/features/lobby/SpaceItem.tsx +++ b/src/app/features/lobby/SpaceItem.tsx @@ -36,7 +36,7 @@ import { useDraggableItem } from './DnD'; import { openCreateRoom, openSpaceAddExisting } from '../../../client/action/navigation'; import { stopPropagation } from '../../utils/keyboard'; import { mxcUrlToHttp } from '../../utils/matrix'; -import { useSpecVersions } from '../../hooks/useSpecVersions'; +import { useMediaAuthentication } from '../../hooks/useMediaAuthentication'; function SpaceProfileLoading() { return ( @@ -410,8 +410,7 @@ export const SpaceItemCard = as<'div', SpaceItemCardProps>( ref ) => { const mx = useMatrixClient(); - const { versions } = useSpecVersions(); - const useAuthentication = versions.includes('v1.11'); + const useAuthentication = useMediaAuthentication(); const { roomId, content } = item; const space = getRoom(roomId); const targetRef = useRef(null); diff --git a/src/app/features/message-search/SearchResultGroup.tsx b/src/app/features/message-search/SearchResultGroup.tsx index a3a67eda8..29fce7bfa 100644 --- a/src/app/features/message-search/SearchResultGroup.tsx +++ b/src/app/features/message-search/SearchResultGroup.tsx @@ -38,7 +38,7 @@ import { SequenceCard } from '../../components/sequence-card'; import { UserAvatar } from '../../components/user-avatar'; import { useMentionClickHandler } from '../../hooks/useMentionClickHandler'; import { useSpoilerClickHandler } from '../../hooks/useSpoilerClickHandler'; -import { useSpecVersions } from '../../hooks/useSpecVersions'; +import { useMediaAuthentication } from '../../hooks/useMediaAuthentication'; type SearchResultGroupProps = { room: Room; @@ -57,8 +57,7 @@ export function SearchResultGroup({ onOpen, }: SearchResultGroupProps) { const mx = useMatrixClient(); - const { versions } = useSpecVersions(); - const useAuthentication = versions.includes('v1.11'); + const useAuthentication = useMediaAuthentication(); const highlightRegex = useMemo(() => makeHighlightRegex(highlights), [highlights]); const mentionClickHandler = useMentionClickHandler(room.roomId); diff --git a/src/app/features/room-nav/RoomNavItem.tsx b/src/app/features/room-nav/RoomNavItem.tsx index c525ab2ab..19d04f35c 100644 --- a/src/app/features/room-nav/RoomNavItem.tsx +++ b/src/app/features/room-nav/RoomNavItem.tsx @@ -38,7 +38,7 @@ import { stopPropagation } from '../../utils/keyboard'; import { getMatrixToRoom } from '../../plugins/matrix-to'; import { getCanonicalAliasOrRoomId, isRoomAlias } from '../../utils/matrix'; import { getViaServers } from '../../plugins/via-servers'; -import { useSpecVersions } from '../../hooks/useSpecVersions'; +import { useMediaAuthentication } from '../../hooks/useMediaAuthentication'; type RoomNavItemMenuProps = { room: Room; @@ -176,8 +176,7 @@ export function RoomNavItem({ linkPath, }: RoomNavItemProps) { const mx = useMatrixClient(); - const { versions } = useSpecVersions(); - const useAuthentication = versions.includes('v1.11'); + const useAuthentication = useMediaAuthentication(); const [hover, setHover] = useState(false); const { hoverProps } = useHover({ onHoverChange: setHover }); const { focusWithinProps } = useFocusWithin({ onFocusWithinChange: setHover }); diff --git a/src/app/features/room/MembersDrawer.tsx b/src/app/features/room/MembersDrawer.tsx index 1b538ffc1..a4305e456 100644 --- a/src/app/features/room/MembersDrawer.tsx +++ b/src/app/features/room/MembersDrawer.tsx @@ -55,7 +55,7 @@ import { ScrollTopContainer } from '../../components/scroll-top-container'; import { UserAvatar } from '../../components/user-avatar'; import { useRoomTypingMember } from '../../hooks/useRoomTypingMembers'; import { stopPropagation } from '../../utils/keyboard'; -import { useSpecVersions } from '../../hooks/useSpecVersions'; +import { useMediaAuthentication } from '../../hooks/useMediaAuthentication'; export const MembershipFilters = { filterJoined: (m: RoomMember) => m.membership === Membership.Join, @@ -172,8 +172,7 @@ type MembersDrawerProps = { }; export function MembersDrawer({ room, members }: MembersDrawerProps) { const mx = useMatrixClient(); - const { versions } = useSpecVersions(); - const useAuthentication = versions.includes('v1.11'); + const useAuthentication = useMediaAuthentication(); const scrollRef = useRef(null); const searchInputRef = useRef(null); const scrollTopAnchorRef = useRef(null); diff --git a/src/app/features/room/RoomInput.tsx b/src/app/features/room/RoomInput.tsx index 03bc96558..8fcfbc972 100644 --- a/src/app/features/room/RoomInput.tsx +++ b/src/app/features/room/RoomInput.tsx @@ -108,7 +108,7 @@ import { mobileOrTablet } from '../../utils/user-agent'; import { useElementSizeObserver } from '../../hooks/useElementSizeObserver'; import { ReplyLayout, ThreadIndicator } from '../../components/message'; import { roomToParentsAtom } from '../../state/room/roomToParents'; -import { useSpecVersions } from '../../hooks/useSpecVersions'; +import { useMediaAuthentication } from '../../hooks/useMediaAuthentication'; interface RoomInputProps { editor: Editor; @@ -119,8 +119,7 @@ interface RoomInputProps { export const RoomInput = forwardRef( ({ editor, fileDropContainerRef, roomId, room }, ref) => { const mx = useMatrixClient(); - const { versions } = useSpecVersions(); - const useAuthentication = versions.includes('v1.11'); + const useAuthentication = useMediaAuthentication(); const [enterForNewline] = useSetting(settingsAtom, 'enterForNewline'); const [isMarkdown] = useSetting(settingsAtom, 'isMarkdown'); const commands = useCommands(mx, room); diff --git a/src/app/features/room/RoomTimeline.tsx b/src/app/features/room/RoomTimeline.tsx index c47cb35b7..34f54868d 100644 --- a/src/app/features/room/RoomTimeline.tsx +++ b/src/app/features/room/RoomTimeline.tsx @@ -122,7 +122,7 @@ import { roomToUnreadAtom } from '../../state/room/roomToUnread'; import { useMentionClickHandler } from '../../hooks/useMentionClickHandler'; import { useSpoilerClickHandler } from '../../hooks/useSpoilerClickHandler'; import { useRoomNavigate } from '../../hooks/useRoomNavigate'; -import { useSpecVersions } from '../../hooks/useSpecVersions'; +import { useMediaAuthentication } from '../../hooks/useMediaAuthentication'; const TimelineFloat = as<'div', css.TimelineFloatVariants>( ({ position, className, ...props }, ref) => ( @@ -438,8 +438,7 @@ const getRoomUnreadInfo = (room: Room, scrollTo = false) => { export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimelineProps) { const mx = useMatrixClient(); - const { versions } = useSpecVersions(); - const useAuthentication = versions.includes('v1.11'); + const useAuthentication = useMediaAuthentication(); const encryptedRoom = mx.isRoomEncrypted(room.roomId); const [messageLayout] = useSetting(settingsAtom, 'messageLayout'); const [messageSpacing] = useSetting(settingsAtom, 'messageSpacing'); diff --git a/src/app/features/room/RoomViewHeader.tsx b/src/app/features/room/RoomViewHeader.tsx index eaa90970c..ae80deb6e 100644 --- a/src/app/features/room/RoomViewHeader.tsx +++ b/src/app/features/room/RoomViewHeader.tsx @@ -53,7 +53,7 @@ import { stopPropagation } from '../../utils/keyboard'; import { getMatrixToRoom } from '../../plugins/matrix-to'; import { getViaServers } from '../../plugins/via-servers'; import { BackRouteHandler } from '../../components/BackRouteHandler'; -import { useSpecVersions } from '../../hooks/useSpecVersions'; +import { useMediaAuthentication } from '../../hooks/useMediaAuthentication'; type RoomMenuProps = { room: Room; @@ -175,8 +175,7 @@ const RoomMenu = forwardRef(({ room, requestClose export function RoomViewHeader() { const navigate = useNavigate(); const mx = useMatrixClient(); - const { versions } = useSpecVersions(); - const useAuthentication = versions.includes('v1.11'); + const useAuthentication = useMediaAuthentication(); const screenSize = useScreenSizeContext(); const room = useRoom(); const space = useSpaceOptionally(); diff --git a/src/app/features/room/message/Message.tsx b/src/app/features/room/message/Message.tsx index 94a5825c4..e9a2d7973 100644 --- a/src/app/features/room/message/Message.tsx +++ b/src/app/features/room/message/Message.tsx @@ -67,7 +67,7 @@ import { copyToClipboard } from '../../../utils/dom'; import { stopPropagation } from '../../../utils/keyboard'; import { getMatrixToRoomEvent } from '../../../plugins/matrix-to'; import { getViaServers } from '../../../plugins/via-servers'; -import { useSpecVersions } from '../../../hooks/useSpecVersions'; +import { useMediaAuthentication } from '../../../hooks/useMediaAuthentication'; export type ReactionHandler = (keyOrMxc: string, shortcode: string) => void; @@ -651,8 +651,7 @@ export const Message = as<'div', MessageProps>( ref ) => { const mx = useMatrixClient(); - const { versions } = useSpecVersions(); - const useAuthentication = versions.includes('v1.11'); + const useAuthentication = useMediaAuthentication(); const senderId = mEvent.getSender() ?? ''; const [hover, setHover] = useState(false); const { hoverProps } = useHover({ onHoverChange: setHover }); diff --git a/src/app/features/room/message/Reactions.tsx b/src/app/features/room/message/Reactions.tsx index 258ab6292..f0f308bbc 100644 --- a/src/app/features/room/message/Reactions.tsx +++ b/src/app/features/room/message/Reactions.tsx @@ -22,7 +22,7 @@ import { useRelations } from '../../../hooks/useRelations'; import * as css from './styles.css'; import { ReactionViewer } from '../reaction-viewer'; import { stopPropagation } from '../../../utils/keyboard'; -import { useSpecVersions } from '../../../hooks/useSpecVersions'; +import { useMediaAuthentication } from '../../../hooks/useMediaAuthentication'; export type ReactionsProps = { room: Room; @@ -34,8 +34,7 @@ export type ReactionsProps = { export const Reactions = as<'div', ReactionsProps>( ({ className, room, relations, mEventId, canSendReaction, onReactionToggle, ...props }, ref) => { const mx = useMatrixClient(); - const { versions } = useSpecVersions(); - const useAuthentication = versions.includes('v1.11'); + const useAuthentication = useMediaAuthentication(); const [viewer, setViewer] = useState(false); const myUserId = mx.getUserId(); const reactions = useRelations( diff --git a/src/app/features/room/reaction-viewer/ReactionViewer.tsx b/src/app/features/room/reaction-viewer/ReactionViewer.tsx index 9e166a9ed..d4b39845f 100644 --- a/src/app/features/room/reaction-viewer/ReactionViewer.tsx +++ b/src/app/features/room/reaction-viewer/ReactionViewer.tsx @@ -25,7 +25,7 @@ import { useRelations } from '../../../hooks/useRelations'; import { Reaction } from '../../../components/message'; import { getHexcodeForEmoji, getShortcodeFor } from '../../../plugins/emoji'; import { UserAvatar } from '../../../components/user-avatar'; -import { useSpecVersions } from '../../../hooks/useSpecVersions'; +import { useMediaAuthentication } from '../../../hooks/useMediaAuthentication'; export type ReactionViewerProps = { room: Room; @@ -36,8 +36,7 @@ export type ReactionViewerProps = { export const ReactionViewer = as<'div', ReactionViewerProps>( ({ className, room, initialKey, relations, requestClose, ...props }, ref) => { const mx = useMatrixClient(); - const { versions } = useSpecVersions(); - const useAuthentication = versions.includes('v1.11'); + const useAuthentication = useMediaAuthentication(); const reactions = useRelations( relations, useCallback((rel) => [...(rel.getSortedAnnotationsByKey() ?? [])], []) diff --git a/src/app/hooks/useMediaAuthentication.ts b/src/app/hooks/useMediaAuthentication.ts new file mode 100644 index 000000000..04b25e193 --- /dev/null +++ b/src/app/hooks/useMediaAuthentication.ts @@ -0,0 +1,10 @@ +import { useSpecVersions } from './useSpecVersions'; + +export const useMediaAuthentication = (): boolean => { + const { versions } = useSpecVersions(); + + // Media authentication is introduced in spec version 1.11 + const authenticatedMedia = versions.includes('v1.11'); + + return authenticatedMedia; +}; diff --git a/src/app/pages/client/ClientNonUIFeatures.tsx b/src/app/pages/client/ClientNonUIFeatures.tsx index 9f3f129bb..8678e6194 100644 --- a/src/app/pages/client/ClientNonUIFeatures.tsx +++ b/src/app/pages/client/ClientNonUIFeatures.tsx @@ -25,7 +25,7 @@ import { NotificationType, UnreadInfo } from '../../../types/matrix/room'; import { getMxIdLocalPart, mxcUrlToHttp } from '../../utils/matrix'; import { useSelectedRoom } from '../../hooks/router/useSelectedRoom'; import { useInboxNotificationsSelected } from '../../hooks/router/useInbox'; -import { useSpecVersions } from '../../hooks/useSpecVersions'; +import { useMediaAuthentication } from '../../hooks/useMediaAuthentication'; function SystemEmojiFeature() { const [twitterEmoji] = useSetting(settingsAtom, 'twitterEmoji'); @@ -133,8 +133,7 @@ function MessageNotifications() { const notifRef = useRef(); const unreadCacheRef = useRef>(new Map()); const mx = useMatrixClient(); - const { versions } = useSpecVersions(); - const useAuthentication = versions.includes('v1.11'); + const useAuthentication = useMediaAuthentication(); const [showNotifications] = useSetting(settingsAtom, 'showNotifications'); const [notificationSound] = useSetting(settingsAtom, 'isNotificationSounds'); @@ -243,6 +242,7 @@ function MessageNotifications() { playSound, notify, selectedRoomId, + useAuthentication, ]); return ( diff --git a/src/app/pages/client/inbox/Invites.tsx b/src/app/pages/client/inbox/Invites.tsx index 12ca65bbc..8dcfa1c20 100644 --- a/src/app/pages/client/inbox/Invites.tsx +++ b/src/app/pages/client/inbox/Invites.tsx @@ -42,7 +42,7 @@ import { useRoomNavigate } from '../../../hooks/useRoomNavigate'; import { useRoomTopic } from '../../../hooks/useRoomMeta'; import { ScreenSize, useScreenSizeContext } from '../../../hooks/useScreenSize'; import { BackRouteHandler } from '../../../components/BackRouteHandler'; -import { useSpecVersions } from '../../../hooks/useSpecVersions'; +import { useMediaAuthentication } from '../../../hooks/useMediaAuthentication'; const COMPACT_CARD_WIDTH = 548; @@ -55,8 +55,7 @@ type InviteCardProps = { }; function InviteCard({ room, userId, direct, compact, onNavigate }: InviteCardProps) { const mx = useMatrixClient(); - const { versions } = useSpecVersions(); - const useAuthentication = versions.includes('v1.11'); + const useAuthentication = useMediaAuthentication(); const roomName = room.name || room.getCanonicalAlias() || room.roomId; const member = room.getMember(userId); const memberEvent = member?.events.member; diff --git a/src/app/pages/client/inbox/Notifications.tsx b/src/app/pages/client/inbox/Notifications.tsx index 95f9b9ff9..64eabc995 100644 --- a/src/app/pages/client/inbox/Notifications.tsx +++ b/src/app/pages/client/inbox/Notifications.tsx @@ -81,7 +81,7 @@ import { useMentionClickHandler } from '../../../hooks/useMentionClickHandler'; import { useSpoilerClickHandler } from '../../../hooks/useSpoilerClickHandler'; import { ScreenSize, useScreenSizeContext } from '../../../hooks/useScreenSize'; import { BackRouteHandler } from '../../../components/BackRouteHandler'; -import { useSpecVersions } from '../../../hooks/useSpecVersions'; +import { useMediaAuthentication } from '../../../hooks/useMediaAuthentication'; type RoomNotificationsGroup = { roomId: string; @@ -192,8 +192,7 @@ function RoomNotificationsGroupComp({ onOpen, }: RoomNotificationsGroupProps) { const mx = useMatrixClient(); - const { versions } = useSpecVersions(); - const useAuthentication = versions.includes('v1.11'); + const useAuthentication = useMediaAuthentication(); const unread = useRoomUnread(room.roomId, roomToUnreadAtom); const mentionClickHandler = useMentionClickHandler(room.roomId); const spoilerClickHandler = useSpoilerClickHandler(); diff --git a/src/app/pages/client/sidebar/SpaceTabs.tsx b/src/app/pages/client/sidebar/SpaceTabs.tsx index d63bb24d1..343afae47 100644 --- a/src/app/pages/client/sidebar/SpaceTabs.tsx +++ b/src/app/pages/client/sidebar/SpaceTabs.tsx @@ -87,7 +87,7 @@ import { stopPropagation } from '../../../utils/keyboard'; import { getMatrixToRoom } from '../../../plugins/matrix-to'; import { getViaServers } from '../../../plugins/via-servers'; import { getRoomAvatarUrl } from '../../../utils/room'; -import { useSpecVersions } from '../../../hooks/useSpecVersions'; +import { useMediaAuthentication } from '../../../hooks/useMediaAuthentication'; type SpaceMenuProps = { room: Room; @@ -381,8 +381,7 @@ function SpaceTab({ onUnpin, }: SpaceTabProps) { const mx = useMatrixClient(); - const { versions } = useSpecVersions(); - const useAuthentication = versions.includes('v1.11'); + const useAuthentication = useMediaAuthentication(); const targetRef = useRef(null); const spaceDraggable: SidebarDraggable = useMemo( @@ -528,8 +527,7 @@ function ClosedSpaceFolder({ disabled, }: ClosedSpaceFolderProps) { const mx = useMatrixClient(); - const { versions } = useSpecVersions(); - const useAuthentication = versions.includes('v1.11'); + const useAuthentication = useMediaAuthentication(); const handlerRef = useRef(null); const spaceDraggable: FolderDraggable = useMemo(() => ({ folder }), [folder]); diff --git a/src/app/pages/client/sidebar/UserTab.tsx b/src/app/pages/client/sidebar/UserTab.tsx index 09b3f251d..5e6c82aba 100644 --- a/src/app/pages/client/sidebar/UserTab.tsx +++ b/src/app/pages/client/sidebar/UserTab.tsx @@ -7,7 +7,7 @@ import { UserAvatar } from '../../../components/user-avatar'; import { useMatrixClient } from '../../../hooks/useMatrixClient'; import { getMxIdLocalPart, mxcUrlToHttp } from '../../../utils/matrix'; import { nameInitials } from '../../../utils/common'; -import { useSpecVersions } from '../../../hooks/useSpecVersions'; +import { useMediaAuthentication } from '../../../hooks/useMediaAuthentication'; type UserProfile = { avatar_url?: string; @@ -15,8 +15,7 @@ type UserProfile = { }; export function UserTab() { const mx = useMatrixClient(); - const { versions } = useSpecVersions(); - const useAuthentication = versions.includes('v1.11'); + const useAuthentication = useMediaAuthentication(); const userId = mx.getUserId()!; const [profile, setProfile] = useState({}); diff --git a/src/client/action/room.js b/src/client/action/room.js index cd4995b90..48ae7c476 100644 --- a/src/client/action/room.js +++ b/src/client/action/room.js @@ -244,11 +244,7 @@ async function unignore(mx, userIds) { } async function setPowerLevel(mx, roomId, userId, powerLevel) { - const room = mx.getRoom(roomId); - - const powerlevelEvent = room.currentState.getStateEvents('m.room.power_levels')[0]; - - const result = await mx.setPowerLevel(roomId, userId, powerLevel, powerlevelEvent); + const result = await mx.setPowerLevel(roomId, userId, powerLevel); return result; } diff --git a/src/index.tsx b/src/index.tsx index 58ecc42ac..805847f19 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -23,19 +23,22 @@ settings.applyTheme(); // Register Service Worker if ('serviceWorker' in navigator) { - navigator.serviceWorker.register( - import.meta.env.MODE === 'production' ? `${trimTrailingSlash(import.meta.env.BASE_URL)}/sw.js` : '/dev-sw.js?dev-sw' - ) + const swUrl = + import.meta.env.MODE === 'production' + ? `${trimTrailingSlash(import.meta.env.BASE_URL)}/sw.js` + : `/dev-sw.js?dev-sw`; + + navigator.serviceWorker.register(swUrl); navigator.serviceWorker.addEventListener('message', (event) => { if (event.data?.type === 'token' && event.data?.responseKey) { // Get the token for SW. - const token = localStorage.getItem('cinny_access_token'); + const token = localStorage.getItem('cinny_access_token') ?? undefined; event.source!.postMessage({ responseKey: event.data.responseKey, token, - }) + }); } - }) + }); } const mountApp = () => { diff --git a/src/sw.ts b/src/sw.ts index 119539174..11f7f8b25 100644 --- a/src/sw.ts +++ b/src/sw.ts @@ -1,3 +1,8 @@ +/// + +export type {}; +declare const self: ServiceWorkerGlobalScope; + async function askForAccessToken(client: Client): Promise { return new Promise((resolve) => { const responseKey = Math.random().toString(36); @@ -32,11 +37,10 @@ self.addEventListener('fetch', (event: FetchEvent) => { } event.respondWith( (async (): Promise => { - const client = await clients.get(event.clientId); + const client = await self.clients.get(event.clientId); let token: string | undefined; if (client) token = await askForAccessToken(client); - // eslint-disable-next-line consistent-return return fetch(url, fetchConfig(token)); })() ); diff --git a/vite.config.js b/vite.config.js index e629c7512..2771538c3 100644 --- a/vite.config.js +++ b/vite.config.js @@ -77,6 +77,10 @@ export default defineConfig({ injectManifest: { injectionPoint: undefined, }, + devOptions: { + enabled: true, + type: 'module' + } }), ], optimizeDeps: { From 5482f8e72e72ba1323d5991454c9c36b608d6256 Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Mon, 9 Sep 2024 20:51:52 +1000 Subject: [PATCH 1209/1531] render matrix room and event link content (#1938) --- src/app/plugins/react-custom-html-parser.tsx | 31 +++++++++++++++----- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/src/app/plugins/react-custom-html-parser.tsx b/src/app/plugins/react-custom-html-parser.tsx index ab333704b..6a4d05306 100644 --- a/src/app/plugins/react-custom-html-parser.tsx +++ b/src/app/plugins/react-custom-html-parser.tsx @@ -14,7 +14,12 @@ import { IntermediateRepresentation, Opts as LinkifyOpts, OptFn } from 'linkifyj import Linkify from 'linkify-react'; import { ErrorBoundary } from 'react-error-boundary'; import * as css from '../styles/CustomHtml.css'; -import { getMxIdLocalPart, getCanonicalAliasRoomId, isRoomAlias, mxcUrlToHttp } from '../utils/matrix'; +import { + getMxIdLocalPart, + getCanonicalAliasRoomId, + isRoomAlias, + mxcUrlToHttp, +} from '../utils/matrix'; import { getMemberDisplayName } from '../utils/room'; import { EMOJI_PATTERN, URL_NEG_LB } from '../utils/regex'; import { getHexcodeForEmoji, getShortcodeFor } from './emoji'; @@ -44,7 +49,8 @@ export const LINKIFY_OPTS: LinkifyOpts = { }; export const makeMentionCustomProps = ( - handleMentionClick?: ReactEventHandler + handleMentionClick?: ReactEventHandler, + content?: string ): ComponentPropsWithoutRef<'a'> => ({ style: { cursor: 'pointer' }, target: '_blank', @@ -53,6 +59,7 @@ export const makeMentionCustomProps = ( tabIndex: handleMentionClick ? 0 : -1, onKeyDown: handleMentionClick ? onEnterOrSpace(handleMentionClick) : undefined, onClick: handleMentionClick, + children: content, }); export const renderMatrixMention = ( @@ -72,8 +79,9 @@ export const renderMatrixMention = ( className={css.Mention({ highlight: mx.getUserId() === userId })} data-mention-id={userId} > - {`@${(currentRoom && getMemberDisplayName(currentRoom, userId)) ?? getMxIdLocalPart(userId) - }`} + {`@${ + (currentRoom && getMemberDisplayName(currentRoom, userId)) ?? getMxIdLocalPart(userId) + }`} ); } @@ -85,6 +93,8 @@ export const renderMatrixMention = ( isRoomAlias(roomIdOrAlias) ? getCanonicalAliasRoomId(mx, roomIdOrAlias) : roomIdOrAlias ); + const fallbackContent = mentionRoom ? `#${mentionRoom.name}` : roomIdOrAlias; + return ( - {mentionRoom ? `#${mentionRoom.name}` : roomIdOrAlias} + {customProps.children ? customProps.children : fallbackContent} ); } @@ -118,7 +128,9 @@ export const renderMatrixMention = ( data-mention-event-id={eventId} data-mention-via={viaServers?.join(',')} > - Message: {mentionRoom ? `#${mentionRoom.name}` : roomIdOrAlias} + {customProps.children + ? customProps.children + : `Message: ${mentionRoom ? `#${mentionRoom.name}` : roomIdOrAlias}`} ); } @@ -327,12 +339,17 @@ export const getReactCustomHtmlParser = ( } if (name === 'a' && testMatrixTo(tryDecodeURIComponent(props.href))) { + const content = children.find((child) => !(child instanceof DOMText)) + ? undefined + : children.map((c) => (c instanceof DOMText ? c.data : '')).join(); + const mention = renderMatrixMention( mx, roomId, tryDecodeURIComponent(props.href), - makeMentionCustomProps(params.handleMentionClick) + makeMentionCustomProps(params.handleMentionClick, content) ); + if (mention) return mention; } From f2c31d29a287f6d2cf9e92be1a1b7ba312a3034c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=9C=E5=9D=82=E9=9B=85?= <23130178+ShadowRZ@users.noreply.github.com> Date: Wed, 11 Sep 2024 13:13:15 +0800 Subject: [PATCH 1210/1531] fix: Fix video and audio loading with authenicated media (#1946) Appeareantly Firefox (and maybe Chrome) won't let service workers take over requests from